【three.js练习程序】创建简单物理场景
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ceshi</title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<script src="./build/three.js"></script>
<script src="./examples/js/libs/ammo.js"></script>
<script src="./examples/js/controls/OrbitControls.js"></script>
</head>
<body>
<div id="ThreeJs">
</div>
<script>
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);
</script>
</html>

【three.js练习程序】创建简单物理场景的更多相关文章
- 【three.js练习程序】创建简单物理地形
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 基于Babylon.js编写宇宙飞船模拟程序1——程序基础结构、物理引擎使用、三维罗盘
计划做一个宇宙飞船模拟程序,首先做一些技术准备. 可以访问https://ljzc002.github.io/test/Spacetest/HTML/PAGE/spacetestwp2.html查看测 ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- 使用Visual Studio 2010 创建简单的Silverlight应用程序
使用Visual Studio 2010 创建简单的Silverlight应用程序 Silverlight是创建动态的引人的RIAs(Rich Internet Application)的新方法.这里 ...
- 在 Web 应用中创建 Node.js 应用程序
本分步指南将通过 Azure Web 应用帮助您启动并运行示例 Node.JS 应用程序.除 Node.JS 外,Azure Web 应用还支持其他语言,如 PHP..NET.Node.JS.Pyth ...
- 用chrome的snippets片段功能创建页面js外挂程序,从控制台创建js小脚本
用chrome的snippets片段功能创建页面js外挂程序,从控制台创建js小脚本 Chrome的snippets是小脚本,还可以创作并在Chrome DevTools的来源面板中执行.可以访问和从 ...
- 用简单的 Node.js 后台程序浅析 HTTP 请求与响应
用简单的 Node.js 后台程序浅析 HTTP 请求与响应 本文写于 2020 年 1 月 18 日 我们来看两种方式发送 HTTP 请求,一种呢,是命令行的 curl 命令:一种呢是直接在浏览器的 ...
- Socket创建简单服务器和客户端程序
使用Socket编程创建简单服务器和客户端 要知道的 Socket-AddressFamily, SocketType, ProtocolType https://blog.csdn.net/weix ...
- 高效使用 JavaScript 闭包,避免 Node.js 应用程序中的内存泄漏
在 Node.js 中,广泛采用不同形式的闭包来支持 Node 的异步和事件驱动编程模型.通过很好地理解闭包,您可以确保所开发应用程序的功能正确性.稳定性和可伸缩性. 闭包是一种将数据与处理数据的代码 ...
随机推荐
- django2笔记:路由path语法
django2笔记:路由path语法 9月23,Django 发布了2.0a1版本,这是一个 feature freeze 版本,如果没有什么意外的话,2.0正式版不会再增加新的功能了.按照以往的规律 ...
- hexo 静态页面生成后页面打不开的问题
我这里的原因是4000端口被占用了 *** hexo入门指南教程: 官方文档 用Hexo 3 搭建github blog 做一款hexo主题(进阶) 坑 1 要安装node和git 2 别忘了安装he ...
- Android入门学习总结
1.Manifest.xml是程序运行时读取的文件,是核心的配置文件:也是从中读取Activity 2.主要的代码文件存放在MainActivity.java,里面固定会有onCreate函数会通过s ...
- MVC源码分析 - Action查找和过滤器的执行时机
接着上一篇, 在创建好Controller之后, 有一个 this.ExecuteCore()方法, 这部分是执行的. 那么里面具体做了些什么呢? //ControllerBaseprotected ...
- setup&hold
setup time:建立时间,也就是在时钟上升沿到来前,数据需要稳定的时间.hold time:保持时间,指的是在时钟上升沿到来后,数据还需要保持的时间.实际上设置setup time和hold t ...
- Ice简介+Qt代码示例
1.ICE是什么? ICE是ZEROC的开源通信协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通信引擎,是一个面向对象的中间件,它封装并 ...
- 数据结构与算法(周鹏-未出版)-第六章 树-6.5 Huffman 树
6.5 Huffman 树 Huffman 树又称最优树,可以用来构造最优编码,用于信息传输.数据压缩等方面,是一类有着广泛应用的二叉树. 6.5.1 二叉编码树 在计算机系统中,符号数据在处理之前首 ...
- .37-浅析webpack源码之事件流make(4)
赶紧完结这个系列咯,webpack4都已经出正式版了. 之前的代码搜索到js文件的对应loader,并添加到了对象中返回,流程如下: this.plugin("factory", ...
- 在MVC应用程序中使用jQuery的验证
呵呵,觉得很久没有写博客了,均是工作忙于公司的ERP系统,这是正确的,因为这才是真正的工作. 今天想写点在MVC应用程序中,使用jQuery来验证.在进行之前,还是先回看一下<MVC会员注册&g ...
- SQL Server复制入门(二)----复制的几种模式
简介 本系列文章的上一篇对复制是什么做了一个概述.本篇文章根据发布服务器,分发服务器和订阅服务器的组织方式和复制类型来讲述常用复制的几种模式. 模式的选择 选择复制的模式取决于多个方面.首先需要考虑具 ...