2025-03-11 08:25:45 +00:00
|
|
|
|
<!--********************************************************************
|
|
|
|
|
* by jiawanlong
|
|
|
|
|
*********************************************************************-->
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8" />
|
2025-03-19 03:00:22 +00:00
|
|
|
|
<link rel="stylesheet" href="./../../libs/cesium/Cesium1.72/Widgets/widgets.css" />
|
|
|
|
|
<script type="text/javascript" src="./../../libs/cesium/Cesium1.72/Cesium.js"></script>
|
2025-03-11 08:25:45 +00:00
|
|
|
|
<script src="./ammolibs/ammo/ammo.js"></script>
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
<body style="
|
|
|
|
|
margin: 0;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
background: #fff;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
">
|
|
|
|
|
<div id="cesiumContainer" style="margin: 0 auto; width: 100%; height: 100%"></div>
|
|
|
|
|
<div class="infoview">
|
|
|
|
|
操作提示:鼠标左键单击进行发射
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script src="./ammolibs/three/three.min.js"></script>
|
|
|
|
|
<script src="./ammolibs/ammo/ex/ConvexObjectBreaker.js"></script>
|
|
|
|
|
<script src="./ammolibs/ammo/ex/QuickHull.js"></script>
|
|
|
|
|
<script src="./ammolibs/ammo/ex/geometries/ConvexGeometry.js"></script>
|
|
|
|
|
<script src="./ammolibs/meshVisualizer/CesiumMeshVisualizer.js"></script>
|
|
|
|
|
<script>
|
|
|
|
|
|
2025-05-18 11:30:00 +00:00
|
|
|
|
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjM2EzNGJmNy02N2RmLTQ0MDMtYjI2MS1hZTJiMTIwZGYwMTYiLCJpZCI6MzA0MzEyLCJpYXQiOjE3NDc3MjM3MTV9.ePQNhuoVuDsi_z00lTm5W26wyW1Adcr1AWetGM6WSXI'
|
2025-03-11 08:25:45 +00:00
|
|
|
|
|
|
|
|
|
const viewer = new Cesium.Viewer('cesiumContainer', {});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var homePosition = [114.40184, 30.46331, 50]; //初始位置
|
|
|
|
|
look(homePosition[0], homePosition[1], homePosition[2]);
|
|
|
|
|
viewer.scene.debugShowFramesPerSecond = true; //查看帧率
|
|
|
|
|
|
|
|
|
|
MeshVisualizer = Cesium.MeshVisualizer;
|
|
|
|
|
Mesh = Cesium.Mesh;
|
|
|
|
|
MeshMaterial = Cesium.MeshMaterial;
|
|
|
|
|
FramebufferTexture = Cesium.FramebufferTexture;
|
|
|
|
|
GeometryUtils = Cesium.GeometryUtils;
|
|
|
|
|
MeshPhongMaterial = Cesium.MeshPhongMaterial;
|
|
|
|
|
BasicMeshMaterial = Cesium.BasicMeshMaterial;
|
|
|
|
|
LOD = Cesium.LOD;
|
|
|
|
|
|
|
|
|
|
var center = Cesium.Cartesian3.fromDegrees(homePosition[0], homePosition[1], 10);
|
|
|
|
|
var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
|
|
|
|
|
|
|
|
|
|
var meshVisualizer = new MeshVisualizer({
|
|
|
|
|
modelMatrix: modelMatrix,
|
|
|
|
|
up: {
|
|
|
|
|
y: 1
|
|
|
|
|
},
|
|
|
|
|
referenceAxisParameter: {
|
|
|
|
|
length: 100,
|
|
|
|
|
width: 0.05,
|
|
|
|
|
headLength: 2,
|
|
|
|
|
headWidth: 0.1
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
viewer.scene.primitives.add(meshVisualizer);
|
|
|
|
|
meshVisualizer.showReference = true; //显示坐标轴
|
|
|
|
|
|
|
|
|
|
function createRandomColor() {
|
|
|
|
|
return Cesium.Color.fromRandom({
|
|
|
|
|
alpha: 1
|
|
|
|
|
}) //fromRgba(Math.floor(Math.random() * (1 << 24)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createMaterial() {
|
|
|
|
|
return new MeshPhongMaterial({
|
|
|
|
|
defaultColor: createRandomColor(),
|
|
|
|
|
side: MeshMaterial.Sides.DOUBLE,
|
|
|
|
|
translucent: false
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Cesium.Cartesian3.prototype.set = function (x, y, z) {
|
|
|
|
|
this.x = x;
|
|
|
|
|
this.y = y;
|
|
|
|
|
this.z = z;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
Cesium.Cartesian2.prototype.set = function (x, y) {
|
|
|
|
|
this.x = x;
|
|
|
|
|
this.y = y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Cesium.Quaternion.prototype.set = function (x, y, z, w) {
|
|
|
|
|
this.x = x;
|
|
|
|
|
this.y = y;
|
|
|
|
|
this.z = z;
|
|
|
|
|
this.w = w;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ammo().then(function () {
|
|
|
|
|
// Graphics variables
|
|
|
|
|
var clickRequest = false;
|
|
|
|
|
var mouseCoords = new Cesium.Cartesian2();
|
|
|
|
|
var ballMaterial = createMaterial();
|
|
|
|
|
var pos = new Cesium.Cartesian3();
|
|
|
|
|
var quat = new Cesium.Quaternion();
|
|
|
|
|
|
|
|
|
|
// Physics variables
|
|
|
|
|
var gravityConstant = -9.8;
|
|
|
|
|
var collisionConfiguration;
|
|
|
|
|
var dispatcher;
|
|
|
|
|
var broadphase;
|
|
|
|
|
var solver;
|
|
|
|
|
var physicsWorld;
|
|
|
|
|
var rigidBodies = [];
|
|
|
|
|
var softBodies = [];
|
|
|
|
|
var margin = 0.05;
|
|
|
|
|
var hinge;
|
|
|
|
|
var transformAux1 = new Ammo.btTransform();
|
|
|
|
|
var softBodyHelpers = new Ammo.btSoftBodyHelpers();
|
|
|
|
|
var armMovement = 0;
|
|
|
|
|
var ray = new Cesium.Ray();
|
|
|
|
|
|
|
|
|
|
function initPhysics() {
|
|
|
|
|
// Physics configuration
|
|
|
|
|
collisionConfiguration = new Ammo.btSoftBodyRigidBodyCollisionConfiguration();
|
|
|
|
|
dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);
|
|
|
|
|
broadphase = new Ammo.btDbvtBroadphase();
|
|
|
|
|
solver = new Ammo.btSequentialImpulseConstraintSolver();
|
|
|
|
|
softBodySolver = new Ammo.btDefaultSoftBodySolver();
|
|
|
|
|
physicsWorld = new Ammo.btSoftRigidDynamicsWorld(dispatcher, broadphase, solver,
|
|
|
|
|
collisionConfiguration,
|
|
|
|
|
softBodySolver);
|
|
|
|
|
physicsWorld.setGravity(new Ammo.btVector3(0, gravityConstant, 0));
|
|
|
|
|
physicsWorld.getWorldInfo().set_m_gravity(new Ammo.btVector3(0, gravityConstant, 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createObjects() {
|
|
|
|
|
// Ground
|
|
|
|
|
pos.set(0, -0.5, 0);
|
|
|
|
|
quat.set(0, 0, 0, 1);
|
|
|
|
|
var ground = createParalellepiped(40, 1, 40, 0, pos, quat,
|
|
|
|
|
new MeshPhongMaterial({
|
|
|
|
|
defaultColor: "rgb(200,200,200)",
|
|
|
|
|
side: MeshMaterial.Sides.DOUBLE,
|
|
|
|
|
translucent: false
|
|
|
|
|
}));
|
|
|
|
|
GeometryUtils.computeVertexNormals(ground.geometry);
|
|
|
|
|
|
|
|
|
|
// Create soft volumes
|
|
|
|
|
var volumeMass = 15;
|
|
|
|
|
|
|
|
|
|
var sphereGeometry = new THREE.SphereBufferGeometry(1.5, 40, 25);
|
|
|
|
|
sphereGeometry.translate(5, 5, 0);
|
|
|
|
|
createSoftVolume(sphereGeometry, volumeMass, 250);
|
|
|
|
|
|
|
|
|
|
var boxGeometry = new THREE.BufferGeometry().fromGeometry(new THREE.BoxGeometry(1, 1, 5, 4, 4, 20));
|
|
|
|
|
boxGeometry.translate(-2, 5, 0);
|
|
|
|
|
createSoftVolume(boxGeometry, volumeMass, 120);
|
|
|
|
|
|
|
|
|
|
// Ramp
|
|
|
|
|
pos.set(3, 1, 0);
|
|
|
|
|
Cesium.Quaternion.fromAxisAngle(new Cesium.Cartesian3(0, 0, 1), 30 * Math.PI / 180, quat);
|
|
|
|
|
var obstacle = createParalellepiped(10, 1, 4, 0, pos, quat, new MeshPhongMaterial({
|
|
|
|
|
defaultColor: "rgb(28,28,28)",
|
|
|
|
|
side: MeshMaterial.Sides.DOUBLE,
|
|
|
|
|
translucent: false
|
|
|
|
|
}));
|
|
|
|
|
GeometryUtils.computeVertexNormals(obstacle.geometry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function processGeometry(bufGeometry) {
|
|
|
|
|
// Obtain a Geometry
|
|
|
|
|
var geometry = new THREE.Geometry().fromBufferGeometry(bufGeometry);
|
|
|
|
|
|
|
|
|
|
// Merge the vertices so the triangle soup is converted to indexed triangles
|
|
|
|
|
var vertsDiff = geometry.mergeVertices();
|
|
|
|
|
|
|
|
|
|
// Convert again to BufferGeometry, indexed
|
|
|
|
|
var indexedBufferGeom = createIndexedBufferGeometryFromGeometry(geometry);
|
|
|
|
|
|
|
|
|
|
// Create index arrays mapping the indexed vertices to bufGeometry vertices
|
|
|
|
|
mapIndices(bufGeometry, indexedBufferGeom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createIndexedBufferGeometryFromGeometry(geometry) {
|
|
|
|
|
var numVertices = geometry.vertices.length;
|
|
|
|
|
var numFaces = geometry.faces.length;
|
|
|
|
|
|
|
|
|
|
var bufferGeom = new THREE.BufferGeometry();
|
|
|
|
|
var vertices = new Float32Array(numVertices * 3);
|
|
|
|
|
var indices = new(numFaces * 3 > 65535 ? Uint32Array : Uint16Array)(numFaces * 3);
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < numVertices; i++) {
|
|
|
|
|
var p = geometry.vertices[i];
|
|
|
|
|
var i3 = i * 3;
|
|
|
|
|
vertices[i3] = p.x;
|
|
|
|
|
vertices[i3 + 1] = p.y;
|
|
|
|
|
vertices[i3 + 2] = p.z;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < numFaces; i++) {
|
|
|
|
|
var f = geometry.faces[i];
|
|
|
|
|
var i3 = i * 3;
|
|
|
|
|
indices[i3] = f.a;
|
|
|
|
|
indices[i3 + 1] = f.b;
|
|
|
|
|
indices[i3 + 2] = f.c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bufferGeom.setIndex(new THREE.BufferAttribute(indices, 1));
|
|
|
|
|
bufferGeom.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
|
|
|
|
|
return bufferGeom;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isEqual(x1, y1, z1, x2, y2, z2) {
|
|
|
|
|
var delta = 0.000001;
|
|
|
|
|
return Math.abs(x2 - x1) < delta &&
|
|
|
|
|
Math.abs(y2 - y1) < delta &&
|
|
|
|
|
Math.abs(z2 - z1) < delta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function mapIndices(bufGeometry, indexedBufferGeom) {
|
|
|
|
|
// Creates ammoVertices, ammoIndices and ammoIndexAssociation in bufGeometry
|
|
|
|
|
var vertices = bufGeometry.attributes.position.array;
|
|
|
|
|
var idxVertices = indexedBufferGeom.attributes.position.array;
|
|
|
|
|
var indices = indexedBufferGeom.index.array;
|
|
|
|
|
|
|
|
|
|
var numIdxVertices = idxVertices.length / 3;
|
|
|
|
|
var numVertices = vertices.length / 3;
|
|
|
|
|
|
|
|
|
|
bufGeometry.ammoVertices = idxVertices;
|
|
|
|
|
bufGeometry.ammoIndices = indices;
|
|
|
|
|
bufGeometry.ammoIndexAssociation = [];
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < numIdxVertices; i++) {
|
|
|
|
|
var association = [];
|
|
|
|
|
bufGeometry.ammoIndexAssociation.push(association);
|
|
|
|
|
|
|
|
|
|
var i3 = i * 3;
|
|
|
|
|
for (var j = 0; j < numVertices; j++) {
|
|
|
|
|
var j3 = j * 3;
|
|
|
|
|
if (isEqual(idxVertices[i3], idxVertices[i3 + 1], idxVertices[i3 + 2],
|
|
|
|
|
vertices[j3], vertices[j3 + 1], vertices[j3 + 2])) {
|
|
|
|
|
association.push(j3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createSoftVolume(bufferGeom, mass, pressure) {
|
|
|
|
|
processGeometry(bufferGeom);
|
|
|
|
|
|
|
|
|
|
var volume = new Mesh(bufferGeom, new BasicMeshMaterial({
|
|
|
|
|
uniforms: {
|
|
|
|
|
diffuseColorMap: "images/visualization/ammo/colors.png"
|
|
|
|
|
},
|
|
|
|
|
translucent: false
|
|
|
|
|
}));
|
|
|
|
|
volume.geometry.ammoIndexAssociation = bufferGeom.ammoIndexAssociation;
|
|
|
|
|
|
|
|
|
|
meshVisualizer.add(volume);
|
|
|
|
|
|
|
|
|
|
// Volume physic object
|
|
|
|
|
var volumeSoftBody = softBodyHelpers.CreateFromTriMesh(
|
|
|
|
|
physicsWorld.getWorldInfo(),
|
|
|
|
|
bufferGeom.ammoVertices,
|
|
|
|
|
bufferGeom.ammoIndices,
|
|
|
|
|
bufferGeom.ammoIndices.length / 3,
|
|
|
|
|
true);
|
|
|
|
|
|
|
|
|
|
var sbConfig = volumeSoftBody.get_m_cfg();
|
|
|
|
|
sbConfig.set_viterations(40);
|
|
|
|
|
sbConfig.set_piterations(40);
|
|
|
|
|
|
|
|
|
|
// Soft-soft and soft-rigid collisions
|
|
|
|
|
sbConfig.set_collisions(0x11);
|
|
|
|
|
|
|
|
|
|
// Friction
|
|
|
|
|
sbConfig.set_kDF(0.1);
|
|
|
|
|
// Damping
|
|
|
|
|
sbConfig.set_kDP(0.01);
|
|
|
|
|
// Pressure
|
|
|
|
|
sbConfig.set_kPR(pressure);
|
|
|
|
|
// Stiffness
|
|
|
|
|
volumeSoftBody.get_m_materials().at(0).set_m_kLST(0.9);
|
|
|
|
|
volumeSoftBody.get_m_materials().at(0).set_m_kAST(0.9);
|
|
|
|
|
|
|
|
|
|
volumeSoftBody.setTotalMass(mass, false)
|
|
|
|
|
Ammo.castObject(volumeSoftBody, Ammo.btCollisionObject).getCollisionShape().setMargin(margin);
|
|
|
|
|
physicsWorld.addSoftBody(volumeSoftBody, 1, -1);
|
|
|
|
|
volume.physicsBody = volumeSoftBody;
|
|
|
|
|
|
|
|
|
|
// Disable deactivation
|
|
|
|
|
volumeSoftBody.setActivationState(4);
|
|
|
|
|
|
|
|
|
|
softBodies.push(volume);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createParalellepiped(sx, sy, sz, mass, pos, quat, material) {
|
|
|
|
|
var box = Cesium.BoxGeometry.fromDimensions({
|
|
|
|
|
dimensions: new Cesium.Cartesian3(sx, sy, sz),
|
|
|
|
|
vertexFormat: new Cesium.VertexFormat({
|
|
|
|
|
position: true,
|
|
|
|
|
normal: true
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var threeObject = new Mesh(box, material);
|
|
|
|
|
var shape = new Ammo.btBoxShape(new Ammo.btVector3(sx * 0.5, sy * 0.5, sz * 0.5));
|
|
|
|
|
shape.setMargin(margin);
|
|
|
|
|
|
|
|
|
|
createRigidBody(threeObject, shape, mass, pos, quat);
|
|
|
|
|
return threeObject;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createRigidBody(threeObject, physicsShape, mass, pos, quat) {
|
|
|
|
|
Cesium.Cartesian3.clone(pos, threeObject.position);
|
|
|
|
|
if (!threeObject.quaternion) threeObject.quaternion = new Cesium.Quaternion();
|
|
|
|
|
Cesium.Quaternion.clone(quat, threeObject.quaternion);
|
|
|
|
|
|
|
|
|
|
var transform = new Ammo.btTransform();
|
|
|
|
|
transform.setIdentity();
|
|
|
|
|
transform.setOrigin(new Ammo.btVector3(pos.x, pos.y, pos.z));
|
|
|
|
|
transform.setRotation(new Ammo.btQuaternion(quat.x, quat.y, quat.z, quat.w));
|
|
|
|
|
var motionState = new Ammo.btDefaultMotionState(transform);
|
|
|
|
|
|
|
|
|
|
var localInertia = new Ammo.btVector3(0, 0, 0);
|
|
|
|
|
physicsShape.calculateLocalInertia(mass, localInertia);
|
|
|
|
|
|
|
|
|
|
var rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, physicsShape, localInertia);
|
|
|
|
|
var body = new Ammo.btRigidBody(rbInfo);
|
|
|
|
|
|
|
|
|
|
threeObject.physicsBody = body;
|
|
|
|
|
|
|
|
|
|
meshVisualizer.add(threeObject);
|
|
|
|
|
|
|
|
|
|
if (mass > 0) {
|
|
|
|
|
rigidBodies.push(threeObject);
|
|
|
|
|
|
|
|
|
|
// Disable deactivation
|
|
|
|
|
body.setActivationState(4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
physicsWorld.addRigidBody(body);
|
|
|
|
|
return body;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function updatePhysics(deltaTime) {
|
|
|
|
|
try {
|
|
|
|
|
// Step world
|
|
|
|
|
physicsWorld.stepSimulation(deltaTime, 10);
|
|
|
|
|
|
|
|
|
|
// Update soft volumes
|
|
|
|
|
for (var i = 0, il = softBodies.length; i < il; i++) {
|
|
|
|
|
var volume = softBodies[i];
|
|
|
|
|
var geometry = volume.geometry;
|
|
|
|
|
var softBody = volume.physicsBody;
|
|
|
|
|
var volumePositions = geometry.attributes.position.values;
|
|
|
|
|
var volumeNormals = geometry.attributes.normal.values;
|
|
|
|
|
var association = geometry.ammoIndexAssociation;
|
|
|
|
|
var numVerts = association.length;
|
|
|
|
|
var nodes = softBody.get_m_nodes();
|
|
|
|
|
for (var j = 0; j < numVerts; j++) {
|
|
|
|
|
var node = nodes.at(j);
|
|
|
|
|
var nodePos = node.get_m_x();
|
|
|
|
|
var x = nodePos.x();
|
|
|
|
|
var y = nodePos.y();
|
|
|
|
|
var z = nodePos.z();
|
|
|
|
|
var nodeNormal = node.get_m_n();
|
|
|
|
|
var nx = nodeNormal.x();
|
|
|
|
|
var ny = nodeNormal.y();
|
|
|
|
|
var nz = nodeNormal.z();
|
|
|
|
|
var assocVertex = association[j];
|
|
|
|
|
|
|
|
|
|
for (var k = 0, kl = assocVertex.length; k < kl; k++) {
|
|
|
|
|
var indexVertex = assocVertex[k];
|
|
|
|
|
volumePositions[indexVertex] = x;
|
|
|
|
|
volumeNormals[indexVertex] = nx;
|
|
|
|
|
indexVertex++;
|
|
|
|
|
volumePositions[indexVertex] = y;
|
|
|
|
|
volumeNormals[indexVertex] = ny;
|
|
|
|
|
indexVertex++;
|
|
|
|
|
volumePositions[indexVertex] = z;
|
|
|
|
|
volumeNormals[indexVertex] = nz;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
geometry.attributes.position.needsUpdate = true;
|
|
|
|
|
geometry.attributes.normal.needsUpdate = true;
|
|
|
|
|
volume.modelMatrixNeedsUpdate = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update rigid bodies
|
|
|
|
|
for (var i = 0, il = rigidBodies.length; i < il; i++) {
|
|
|
|
|
var objThree = rigidBodies[i];
|
|
|
|
|
var objPhys = objThree.physicsBody;
|
|
|
|
|
var ms = objPhys.getMotionState();
|
|
|
|
|
if (ms) {
|
|
|
|
|
ms.getWorldTransform(transformAux1);
|
|
|
|
|
var p = transformAux1.getOrigin();
|
|
|
|
|
var q = transformAux1.getRotation();
|
|
|
|
|
objThree.position.set(p.x(), p.y(), p.z());
|
|
|
|
|
objThree.quaternion.set(q.x(), q.y(), q.z(), q.w());
|
|
|
|
|
objThree.modelMatrixNeedsUpdate = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
meshVisualizer.beforeUpdate.removeEventListener(update);
|
|
|
|
|
console.log("崩溃了兄弟,你这是神马操作");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var start = false;
|
|
|
|
|
var init = false;
|
|
|
|
|
var startTime = new Date();
|
|
|
|
|
var rayDir = new Cesium.Cartesian3();
|
|
|
|
|
var maxDistance = 100; //发射点与射线和局部场景的交点的距离不能太远,过远会撕碎软体进而碎片过多时导致ammo物理引擎崩溃
|
|
|
|
|
|
|
|
|
|
function initInput() {
|
|
|
|
|
var scene = viewer.scene;
|
|
|
|
|
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
|
|
|
|
|
var lastMesh = null;
|
|
|
|
|
handler.setInputAction(function (movement) {
|
|
|
|
|
if (!clickRequest) {
|
|
|
|
|
Cesium.Cartesian2.clone(movement.position, mouseCoords);
|
|
|
|
|
clickRequest = true;
|
|
|
|
|
}
|
|
|
|
|
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function processClick() {
|
|
|
|
|
if (clickRequest) {
|
|
|
|
|
meshVisualizer.getPickRay(mouseCoords, ray);
|
|
|
|
|
if (!ray) {
|
|
|
|
|
clickRequest = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Creates a ball
|
|
|
|
|
var ballMass = 3;
|
|
|
|
|
var ballRadius = 0.4;
|
|
|
|
|
var ball = new Mesh(new THREE.SphereGeometry(ballRadius, 18, 16), ballMaterial);
|
|
|
|
|
|
|
|
|
|
var ballShape = new Ammo.btSphereShape(ballRadius);
|
|
|
|
|
ballShape.setMargin(margin);
|
|
|
|
|
|
|
|
|
|
Cesium.Cartesian3.clone(ray.direction, rayDir);
|
|
|
|
|
Cesium.Cartesian3.subtract(ray.origin, ray.direction, pos);
|
|
|
|
|
|
|
|
|
|
quat.set(0, 0, 0, 1);
|
|
|
|
|
var ballBody = createRigidBody(ball, ballShape, ballMass, pos, quat);
|
|
|
|
|
ballBody.setFriction(0.5);
|
|
|
|
|
|
|
|
|
|
Cesium.Cartesian3.normalize(rayDir, rayDir);
|
|
|
|
|
Cesium.Cartesian3.multiplyByScalar(rayDir, 30, rayDir);
|
|
|
|
|
console.log(rayDir);
|
|
|
|
|
ballBody.setLinearVelocity(new Ammo.btVector3(rayDir.x, rayDir.y, rayDir.z));
|
|
|
|
|
|
|
|
|
|
clickRequest = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function update(frameState) {
|
|
|
|
|
var deltaTime = (new Date() - startTime) / 1000.0;
|
|
|
|
|
updatePhysics(deltaTime);
|
|
|
|
|
processClick();
|
|
|
|
|
startTime = new Date();
|
|
|
|
|
}
|
|
|
|
|
setTimeout(function () {
|
|
|
|
|
if (!init) {
|
|
|
|
|
// - Init -
|
|
|
|
|
initPhysics();
|
|
|
|
|
createObjects();
|
|
|
|
|
initInput();
|
|
|
|
|
|
|
|
|
|
init = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!start) {
|
|
|
|
|
meshVisualizer.beforeUpdate.addEventListener(update);
|
|
|
|
|
start = true;
|
|
|
|
|
} else {
|
|
|
|
|
meshVisualizer.beforeUpdate.removeEventListener(update);
|
|
|
|
|
start = false;
|
|
|
|
|
}
|
|
|
|
|
}, 1000 * 3);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function look(lon, lat, offset) {
|
|
|
|
|
var center = Cesium.Cartesian3.fromDegrees(lon, lat);
|
|
|
|
|
var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);
|
|
|
|
|
|
|
|
|
|
// View in east-north-up frame
|
|
|
|
|
var camera = viewer.camera;
|
|
|
|
|
camera.constrainedAxis = Cesium.Cartesian3.UNIT_Z;
|
|
|
|
|
camera.lookAtTransform(transform, new Cesium.Cartesian3(-offset, -offset, offset));
|
|
|
|
|
setTimeout(function () {
|
|
|
|
|
camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
|
|
|
|
|
}, 100)
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
</body>
|
|
|
|
|
|
|
|
|
|
</html>
|