2
votes

I am working on a demo where a user can select a few variations of a house and a chimney model (and others). Any house can be combined with any chimney. The chimney has a fixed position on the house, but both can be dynamically scaled.

This means that the "world" position of the chimney is dependent upon the position and scale of the house.

How would one go about creating this functionality within Cesium with glTF models? Does glTF support nodes that can have another glTF model in it? Or do I have to use the modelMatrixes of Cesium to achieve the desired functionality?

Any pointers would be greatly appreciated.

2

2 Answers

1
votes

I don't know if it's possible to walk the glTF model structure and extract a subset of the geometry into another model, or at least apply different transformations to a branch of the model geometry. I doubt, however, this is possible because of the way glTF models are highly optimized. Don't take this as a final answer as I don't know Cesium well enough.

At this time, I'm resolving this by separating geometry earlier in the asset pipeline, and loading separate models, each centered on their own local coordinate system. I manually keep track of the coordinates and orientation of one object relative to the other, and do calculations manually.

var house = createModel("house", 'house/hull-lp.glb');
var chimney = createModel("chimney", 'models/chimney.glb');

And to position the chimney, something in the lines of...

var chimneyRelativePosition = new Cesium.Cartesian3(0, 10, 0);  // The position of the chimney relative to the origin of the house
var chimneyRelativePositionScaled = Cesium.Cartesian3.multiplyByScalar(chimneyRelativePosition, houseScaleFactor, chimneyRelativePositionScaled);
var localCoords = Cesium.Matrix3.fromQuaternion(house.orientation.getValue(), new Cesium.Matrix3());
var chimneyPosition = Cesium.Matrix3.multiplyByVector(localCoords, chimneyRelativePositionScaled, new Cesium.Cartesian3());

chimney.position = chimneyPosition;

Edit: glTF is designed to preserve node hierarchy, so the format allows it. I don't know how however how to manipulate nodes and their transformations :(.

1
votes

Check the article at https://cesiumjs.org/2014/10/13/youbeQ-Moving-from-Google-Earth-to-Cesium/, it contains information about manipulating model hierarchies in Cesium.

Example:

var node = model.getNode('wheel_front_right');

var translationArray = model.gltf.nodes[node.id].translation;
var translation = new Cesium.Cartesian3(translationArray[0], translationArray[1], translationArray[2]);

node.matrix = Transforms.headingPitchRollToFixedFrame(translation, heading, tilt, roll);