html 场景创建,【three.js练习程序】创建简单物理场景

ceshi

body {

margin: 0;

overflow: hidden;

}

var camera, controls, scene, renderer;

var clock = new THREE.Clock();

// 物理引擎相关变量

var gravityConstant = -9.8;

var collisionConfiguration;

var dispatcher;

var broadphase;

var solver;

var physicsWorld;

var rigidBodies = [];

var margin = 0.05;

var transformAux1 = new Ammo.btTransform();

var time = 0;

init();

animate();

function init() {

initGraphics();

initPhysics();

createObjects();

}

function initGraphics() {

// three.js基本场景配置

camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 2000);

camera.position.x = 30;

camera.position.y = 30;

camera.position.z = 30;

controls = new THREE.OrbitControls(camera);

controls.target.y = 2;

renderer = new THREE.WebGLRenderer();

renderer.setClearColor(new THREE.Color("#bfd1e5"));

renderer.shadowMapEnabled = true;

renderer.setSize(window.innerWidth, window.innerHeight);

// 场景

scene = new THREE.Scene();

// 环境光

var ambientLight = new THREE.AmbientLight(0x404040);

scene.add(ambientLight);

// 线性光

var light = new THREE.DirectionalLight(0xffffff, 1);

light.position.set(-20, 20, 10);

light.castShadow = true;

var d = 50;

light.shadow.camera.left = -d;

light.shadow.camera.right = d;

light.shadow.camera.top = d;

light.shadow.camera.bottom = -d;

light.shadow.camera.near = 2;

light.shadow.camera.far = 50;

light.shadow.mapSize.x = 1024;

light.shadow.mapSize.y = 1024;

scene.add(light);

var axes = new THREE.AxisHelper(50); //创建三轴表示

scene.add(axes);

// 添加窗口大小变化监听

window.addEventListener('resize', onWindowResize, false);

}

function onWindowResize() {

camera.aspect = window.innerWidth / window.innerHeight;

camera.updateProjectionMatrix();

renderer.setSize(window.innerWidth, window.innerHeight);

}

function initPhysics() {

// bullet基本场景配置

collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();

dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);

broadphase = new Ammo.btDbvtBroadphase();

solver = new Ammo.btSequentialImpulseConstraintSolver();

physicsWorld = new Ammo.btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);

physicsWorld.setGravity(new Ammo.btVector3(0, gravityConstant, 0));

}

function createObjects() {

var pos = new THREE.Vector3();

var quat = new THREE.Quaternion();

//创建地面

pos.set(0, 0, 0);

quat.set(0, 0, 0, 1);

var ground = createParallellepiped(40, 1, 40, 0, pos, quat, new THREE.MeshPhongMaterial({ color: 0xffffff }));

ground.castShadow = true; // 开启投影

ground.receiveShadow = true; // 接受阴影(可以在表面上显示阴影)

//创建50个小球

for (var i = 0; i < 50; i++) {

var ballMass = 1.2;

var ballRadius = 0.5;

var ball = new THREE.Mesh(new THREE.SphereGeometry(ballRadius, 20, 20), createRendomColorObjectMeatrial());

ball.castShadow = true;

ball.receiveShadow = true;

var ballShape = new Ammo.btSphereShape(ballRadius);

ballShape.setMargin(margin);

pos.set(Math.random() + 10, 2 * (i + 1), Math.random() - 10);

quat.set(0, 0, 0, 1);

createRigidBody(ball, ballShape, ballMass, pos, quat);

ball.userData.physicsBody.setFriction(1.5);

}

//创建50个方块

for (var i = 0; i < 50; i++) {

pos.set(Math.random() - 10, 2 * (i + 1), Math.random() + 10);

quat.set(0, 0, 0, 1);

createParallellepiped(1, 1, 1, 1, pos, quat, createRendomColorObjectMeatrial());

}

}

function createRendomColorObjectMeatrial() {

var color = Math.floor(Math.random() * (1 << 24));

return new THREE.MeshPhongMaterial({ color: color });

}

function createParallellepiped(sx, sy, sz, mass, pos, quat, material) {

var threeObject = new THREE.Mesh(new THREE.BoxGeometry(sx, sy, sz, 1, 1, 1), material);

threeObject.castShadow = true;

threeObject.receiveShadow = true;

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) {

threeObject.position.copy(pos);

threeObject.quaternion.copy(quat);

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.userData.physicsBody = body;

scene.add(threeObject);

if (mass > 0) {

rigidBodies.push(threeObject);

body.setActivationState(4);

}

physicsWorld.addRigidBody(body);

return body;

}

function animate() {

requestAnimationFrame(animate);

var deltaTime = clock.getDelta();

updatePhysics(deltaTime);

controls.update(deltaTime);

renderer.render(scene, camera);

time += deltaTime;

}

function updatePhysics(deltaTime) {

physicsWorld.stepSimulation(deltaTime);

// 更新物体位置

for (var i = 0, iL = rigidBodies.length; i < iL; i++) {

var objThree = rigidBodies[i];

var objPhys = objThree.userData.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());

}

}

}

document.getElementById("ThreeJs").appendChild(renderer.domElement);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值