Skip to content

Commit

Permalink
Merge pull request #202 from CesiumGS/animation-samples
Browse files Browse the repository at this point in the history
Add animation samples
  • Loading branch information
YVin3D committed Jul 22, 2020
2 parents 5930415 + 356ea11 commit b433bf4
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 20 deletions.
20 changes: 20 additions & 0 deletions samples-generator/bin/3d-tiles-samples-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
compositeRegion,
east,
gzip,
instancesAnimatedUri,
instancesBoxLocal,
instancesGeometricError,
instancesLength,
Expand Down Expand Up @@ -151,6 +152,7 @@ var promises = [
createBatchedExpiration(),
createBatchedWithVertexColors(),
createBatchedWithContentDataUri(),
createBatchedAnimated(),
// Point Cloud
createPointCloudRGB(),
createPointCloudRGBA(),
Expand Down Expand Up @@ -188,6 +190,7 @@ var promises = [
createInstancedRedMaterial(),
createInstancedWithBatchIds(),
createInstancedTextured(),
createInstancedAnimated(),
// Composite
createComposite(),
createCompositeOfComposite(),
Expand Down Expand Up @@ -525,6 +528,12 @@ function createBatchedWithContentDataUri() {
});
}

function createBatchedAnimated() {
return saveBatchedTileset('BatchedAnimated', {
animated: true
});
}

function createPointCloudRGB() {
var tileOptions = {
colorMode: 'rgb'
Expand Down Expand Up @@ -941,6 +950,17 @@ function createInstancedTextured() {
return saveInstancedTileset('InstancedTextured', tileOptions);
}

function createInstancedAnimated() {
if (argv['3d-tiles-next']) {
return Bluebird.resolve();
}

var tileOptions = {
uri: instancesAnimatedUri
};
return saveInstancedTileset('InstancedAnimated', tileOptions);
}

function createComposite() {
if (argv['3d-tiles-next']) {
return Bluebird.resolve();
Expand Down
Binary file added samples-generator/data/animated_box.glb
Binary file not shown.
1 change: 1 addition & 0 deletions samples-generator/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export const instancesTileWidth = tileWidth;
export const instancesUri = 'data/box.glb'; // Model's center is at the origin (and for below)
export const instancesRedUri = 'data/red_box.glb';
export const instancesTexturedUri = 'data/textured_box.glb';
export const instancesAnimatedUri = 'data/animated_box.glb';
export const instancesModelSize = 20.0;
export const instancesHeight = instancesModelSize + 10.0; // Just a little extra padding at the top for aiding Cesium tests
export const instancesTransform = wgs84Transform(
Expand Down
5 changes: 4 additions & 1 deletion samples-generator/lib/createBuildingsTile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var batchTableJsonAndBinary;
* @param {Boolean} [options.relativeToCenter=false] Set mesh positions relative to center.
* @param {Number[]} [options.rtcCenterPosition] If defined, sets RTC_CENTER attribute in the feature table.
* @param {Boolean} [options.useVertexColors=false] Bake materials as vertex colors.
* @param {Boolean} [options.animated=false] Whether to include glTF animations.
* @param {Boolean} [options.deprecated1=false] Save the b3dm with the deprecated 20-byte header and the glTF with the BATCHID semantic.
* @param {Boolean} [options.deprecated2=false] Save the b3dm with the deprecated 24-byte header and the glTF with the BATCHID semantic.
*
Expand All @@ -57,6 +58,7 @@ export function createBuildingsTile(options) {
var tileTransform = defaultValue(options.transform, Matrix4.IDENTITY);
var use3dTilesNext = defaultValue(options.use3dTilesNext, false);
var useGlb = defaultValue(options.useGlb, false);
var animated = defaultValue(options.animated, false);

var relativeToCenter = options.relativeToCenter;
var rtcCenterPosition = options.rtcCenterPosition;
Expand Down Expand Up @@ -125,7 +127,8 @@ export function createBuildingsTile(options) {
relativeToCenter: relativeToCenter,
deprecated: deprecated1 || deprecated2,
use3dTilesNext: use3dTilesNext,
featureTableJson: featureTableJson
featureTableJson: featureTableJson,
animated: animated
};

var gltf = createGltf(gltfOptions);
Expand Down
174 changes: 155 additions & 19 deletions samples-generator/lib/createGltf.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var sizeOfFloat32 = 4;
* @param {Boolean} [options.relativeToCenter=false] Set mesh positions relative to center.
* @param {Boolean} [options.deprecated=false] Save the glTF with the old BATCHID semantic.
* @param {Boolean} [options.use3dTilesNext=false] Modify the GLTF to name batch ids with a numerical suffix
* @param {Boolean} [options.animated=false] Whether to include glTF animations.
* @todo options.use3dTilesNext will be deprecated soon, all 3dtilesnext logic
* will go into a dedicated class.
*
Expand All @@ -31,6 +32,7 @@ function createGltf(options) {
var useBatchIds = defaultValue(options.useBatchIds, true);
var relativeToCenter = defaultValue(options.relativeToCenter, false);
var deprecated = defaultValue(options.deprecated, false);
var animated = defaultValue(options.animated, false);

var mesh = options.mesh;
var positions = mesh.positions;
Expand All @@ -54,6 +56,7 @@ function createGltf(options) {
var rootMatrix = [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1];

var i;
var j;
var view;
var material;
var viewsLength = views.length;
Expand Down Expand Up @@ -124,11 +127,41 @@ function createGltf(options) {
for (i = 0; i < indicesLength; ++i) {
indexBuffer.writeUInt16LE(indices[i], i * sizeOfUint16);
}
indexBuffer = getBufferPadded(indexBuffer);

var translations = [
[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[0.0, 0.0, 0.0]
];
var times = [0.0, 0.5, 1.0];
var keyframesLength = translations.length;

var animationBuffer = Buffer.alloc(0);
var translationsBuffer = Buffer.alloc(0);
var timesBuffer = Buffer.alloc(0);

if (animated) {
translationsBuffer = Buffer.alloc(keyframesLength * 3 * sizeOfFloat32);
timesBuffer = Buffer.alloc(keyframesLength * sizeOfFloat32);

for (i = 0; i < keyframesLength; ++i) {
for (j = 0; j < 3; ++j) {
var index = i * keyframesLength + j;
translationsBuffer.writeFloatLE(translations[i][j], index * sizeOfFloat32);
}
}
for (i = 0; i < keyframesLength; ++i) {
timesBuffer.writeFloatLE(times[i], i * sizeOfFloat32);
}

animationBuffer = getBufferPadded(Buffer.concat([translationsBuffer, timesBuffer]));
}

var vertexCount = mesh.vertexCount;

var vertexBuffer = getBufferPadded(Buffer.concat([positionsBuffer, normalsBuffer, uvsBuffer, vertexColorsBuffer, batchIdsBuffer]));
var buffer = getBufferPadded(Buffer.concat([vertexBuffer, indexBuffer]));
var buffer = getBufferPadded(Buffer.concat([vertexBuffer, indexBuffer, animationBuffer]));
var bufferUri = 'data:application/octet-stream;base64,' + buffer.toString('base64');
var byteLength = buffer.byteLength;

Expand All @@ -147,6 +180,8 @@ function createGltf(options) {
var vertexColorsBufferViewIndex = (useVertexColors) ? bufferViewIndex++ : 0;
var batchIdsBufferViewIndex = (useBatchIds) ? bufferViewIndex++ : 0;
var indexBufferViewIndex = bufferViewIndex++;
var translationsBufferViewIndex = (animated) ? bufferViewIndex++ : 0;
var timesBufferViewIndex = (animated) ? bufferViewIndex++ : 0;

var byteOffset = 0;
var positionsBufferByteOffset = byteOffset;
Expand All @@ -165,6 +200,12 @@ function createGltf(options) {
var indexBufferByteOffset = byteOffset;
byteOffset += indexBuffer.length;

// Start animation buffer at the padded byte offset
var translationsByteOffset = vertexBuffer.length + indexBuffer.length;
byteOffset += translationsBuffer.length;
var timesByteOffset = byteOffset;
byteOffset += timesByteOffset;

for (i = 0; i < viewsLength; ++i) {
view = views[i];
material = view.material;
Expand Down Expand Up @@ -312,7 +353,28 @@ function createGltf(options) {
});
}

var accessors = vertexAccessors.concat(indexAccessors);
var animationAccessors = [];

if (animated) {
animationAccessors.push({
bufferView : translationsBufferViewIndex,
byteOffset : 0,
componentType: 5126, // FLOAT,
count : keyframesLength,
type : 'VEC3',
});
animationAccessors.push({
bufferView : timesBufferViewIndex,
byteOffset : 0,
componentType: 5126, // FLOAT,
count : keyframesLength,
type : 'SCALAR',
min: [times[0]],
max: [times[keyframesLength - 1]]
});
}

var accessors = vertexAccessors.concat(indexAccessors, animationAccessors);

var bufferViews = [
{
Expand Down Expand Up @@ -363,8 +425,98 @@ function createGltf(options) {
target : 34963 // ELEMENT_ARRAY_BUFFER
});

if (animated) {
bufferViews.push({
buffer: 0,
byteLength : translationsBuffer.length,
byteOffset : translationsByteOffset
});
bufferViews.push({
buffer: 0,
byteLength : timesBuffer.length,
byteOffset : timesByteOffset
});
}

var hasRTC = use3dTilesNext && defined(options.featureTableJson) && defined(options.featureTableJson.RTC_CENTER);
var nodes;
var animationNode;

if (animated && hasRTC) {
nodes = [
{
matrix : rootMatrix,
children : [1]
},
{
name : 'RTC_CENTER',
translation : options.featureTableJson.RTC_CENTER,
children : [2]
},
{
mesh : 0
}
];
animationNode = 2;
} else if (animated) {
nodes = [
{
matrix : rootMatrix,
children : [1]
},
{
mesh : 0
}
];
animationNode = 1;
} else if (hasRTC) {
nodes = [
{
matrix : rootMatrix,
children : [1]
},
{
name : 'RTC_CENTER',
translation : options.featureTableJson.RTC_CENTER,
mesh : 0
}
];
} else {
nodes = [
{
matrix : rootMatrix,
mesh : 0
}
];
}

var animations;
if (animated) {
animations = [
{
channels : [
{
sampler : 0,
target : {
node : animationNode,
path : 'translation'
}
}
],
samplers : [
{
input : timesBufferViewIndex,
interpolation : 'LINEAR',
output : translationsBufferViewIndex
}
]
}
];
}

var gltf = {
accessors : accessors,
animations : animations,
asset : {
generator : '3d-tiles-samples-generator',
version : '2.0'
Expand All @@ -381,13 +533,7 @@ function createGltf(options) {
primitives : primitives
}
],
nodes : [
{
matrix : rootMatrix,
mesh : 0,
name : 'rootNode'
}
],
nodes : nodes,
samplers : samplers,
scene : 0,
scenes : [{
Expand All @@ -396,15 +542,5 @@ function createGltf(options) {
textures : textures
};

if (use3dTilesNext && defined(options.featureTableJson) && defined(options.featureTableJson.RTC_CENTER)) {
delete gltf.nodes[0].mesh;
gltf.nodes[0].children = [1];
gltf.nodes.push({
name : 'RTC_CENTER',
translation : options.featureTableJson.RTC_CENTER,
mesh : 0
});
}

return gltf;
}

0 comments on commit b433bf4

Please sign in to comment.