Cesium快速上手2-Model图元使用讲解
Model示例讲解
http://localhost:8080/Apps/Sandcastle/index.html?src=development%2F3D%20Models.html&label=Development
关于primitives
model = scene.primitives.add(Cesium.Model.fromGltf({
url : url,
modelMatrix : modelMatrix,
minimumPixelSize : 128
}));
createModel具体使用
function createModel(url, height, heading, pitch, roll) {
height = Cesium.defaultValue(height, 0.0);
heading = Cesium.defaultValue(heading, 0.0);
pitch = Cesium.defaultValue(pitch, 0.0);
roll = Cesium.defaultValue(roll, 0.0);
//确定模型的翻转
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const origin = Cesium.Cartesian3.fromDegrees(
-123.0744619,
44.0503706,
height
);
const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
origin,
hpr
);
// 先移除所有的模型
scene.primitives.removeAll(); // Remove previous model
// 加载模型
model = scene.primitives.add(
Cesium.Model.fromGltf({
url: url,
modelMatrix: modelMatrix,
minimumPixelSize: 128,
})
);
//模型准备完毕后
model.readyPromise
.then(function (model) {
model.color = Cesium.Color.fromAlpha(
getColor(viewModel.color),
Number(viewModel.alpha)
);
model.colorBlendMode = getColorBlendMode(
viewModel.colorBlendMode
);
model.colorBlendAmount = viewModel.colorBlendAmount;
// Play and loop all animations at half-speed
model.activeAnimations.addAll({
multiplier: 0.5,
loop: Cesium.ModelAnimationLoop.REPEAT,
});
//确定相机
const camera = viewer.camera;
// Zoom to model
const controller = scene.screenSpaceCameraController;
const r =
2.0 *
Math.max(model.boundingSphere.radius, camera.frustum.near);
controller.minimumZoomDistance = r * 0.5;
const center = Cesium.Matrix4.multiplyByPoint(
model.modelMatrix,
model.boundingSphere.center,
new Cesium.Cartesian3()
);
const heading = Cesium.Math.toRadians(230.0);
const pitch = Cesium.Math.toRadians(-20.0);
//相机指向模型
camera.lookAt(
center,
new Cesium.HeadingPitchRange(heading, pitch, r * 2.0)
);
})
.catch(function (error) {
window.alert(error);
});
}
ScreenSpaceEventHandler事件
设置事件,当鼠标移入到模型的时候,触发,事件类型 ScreenSpaceEventType
const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function (movement) {
const pick = scene.pick(movement.endPosition);
if (
Cesium.defined(pick) &&
Cesium.defined(pick.node) &&
Cesium.defined(pick.mesh)
) {
// Output glTF node and mesh under the mouse.
console.log(`node: ${pick.node.name}. mesh: ${pick.mesh.name}`);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
Model子节点控制
每一个模型,都应该是由很多节点组合而成,对于每一个节点都应该有旋转,平移,缩放功能
// this can be changed to any glTF model
const modelUrl = "../../SampleData/models/CesiumMan/Cesium_Man.glb";
const viewModel = {
nodeName: undefined,
showTranslation: false,
showRotation: false,
showScale: false,
transformations: {},
};
Cesium.knockout.track(viewModel);
// transformation is a computed property returning the values storage for the current node name
Cesium.knockout.defineProperty(
viewModel,
"transformation",
function () {
const transformations = viewModel.transformations;
const nodeName = viewModel.nodeName;
if (!Cesium.defined(transformations[nodeName])) {
transformations[nodeName] = {
translationX: 0.0,
translationY: 0.0,
translationZ: 0.0,
rotationHeading: 0.0,
rotationPitch: 0.0,
rotationRoll: 0.0,
scaleX: 1.0,
scaleY: 1.0,
scaleZ: 1.0,
};
Cesium.knockout.track(transformations[nodeName]);
}
return transformations[nodeName];
}
);
// these writable computed properties produce individual values for use in the UI
[
"translationX",
"translationY",
"translationZ",
"rotationHeading",
"rotationPitch",
"rotationRoll",
"scaleX",
"scaleY",
"scaleZ",
].forEach(function (p) {
Cesium.knockout.defineProperty(viewModel, p, {
get: function () {
return viewModel.transformation[p];
},
set: function (value) {
// coerce values to number
viewModel.transformation[p] = +value;
},
});
});
// these computed properties return each element of the transform
Cesium.knockout.defineProperty(viewModel, "translation", function () {
return new Cesium.Cartesian3(
viewModel.translationX,
viewModel.translationY,
viewModel.translationZ
);
});
Cesium.knockout.defineProperty(viewModel, "rotation", function () {
const hpr = new Cesium.HeadingPitchRoll(
viewModel.rotationHeading,
viewModel.rotationPitch,
viewModel.rotationRoll
);
return Cesium.Quaternion.fromHeadingPitchRoll(hpr);
});
Cesium.knockout.defineProperty(viewModel, "scale", function () {
return new Cesium.Cartesian3(
viewModel.scaleX,
viewModel.scaleY,
viewModel.scaleZ
);
});
// this computed property combines the above properties into a single matrix to be applied to the node
Cesium.knockout.defineProperty(viewModel, "matrix", function () {
return Cesium.Matrix4.fromTranslationQuaternionRotationScale(
viewModel.translation,
viewModel.rotation,
viewModel.scale
);
});
const toolbar = document.getElementById("toolbar");
Cesium.knockout.applyBindings(viewModel, toolbar);
const viewer = new Cesium.Viewer("cesiumContainer");
const scene = viewer.scene;
const height = 250000.0;
const origin = Cesium.Cartesian3.fromDegrees(
-123.0744619,
44.0503706,
height
);
const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
origin,
new Cesium.HeadingPitchRoll()
);
const model = scene.primitives.add(
Cesium.Model.fromGltf({
url: modelUrl,
modelMatrix: modelMatrix,
minimumPixelSize: 128,
})
);
model.readyPromise
.then(function (model) {
const camera = viewer.camera;
// Zoom to model
const controller = scene.screenSpaceCameraController;
const r =
2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);
controller.minimumZoomDistance = r * 0.5;
const center = Cesium.Matrix4.multiplyByPoint(
model.modelMatrix,
model.boundingSphere.center,
new Cesium.Cartesian3()
);
const heading = Cesium.Math.toRadians(230.0);
const pitch = Cesium.Math.toRadians(-20.0);
camera.lookAt(
center,
new Cesium.HeadingPitchRange(heading, pitch, r * 2.0)
);
// enumerate nodes and add options
const options = Object.keys(model._runtime.nodesByName).map(
function (nodeName) {
return {
text: nodeName,
onselect: function () {
viewModel.nodeName = nodeName;
},
};
}
);
options[0].onselect();
Sandcastle.addToolbarMenu(options);
// respond to viewmodel changes by applying the computed matrix
Cesium.knockout
.getObservable(viewModel, "matrix")
.subscribe(function (newValue) {
const node = model.getNode(viewModel.nodeName);
if (!Cesium.defined(node.originalMatrix)) {
node.originalMatrix = node.matrix.clone();
}
node.matrix = Cesium.Matrix4.multiply(
node.originalMatrix,
newValue,
new Cesium.Matrix4()
);
});
})
.catch(function (error) {
window.alert(error);
});