odejs
Version:
3D physics engine
325 lines (283 loc) • 11 kB
HTML
<html>
<head>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="../lib/libode.js"></script>
<script src="assets/Rabbit.js"></script>
<title>ODE.js - HeightMap</title>
<style>
html, body {
overflow: hidden;
width : 100%;
height : 100%;
margin : 0;
padding : 0;
}
#renderCanvas {
width : 100%;
height : 100%;
touch-action: none;
}
#bottom {
font-family: Monospace;
color: #fff;
font-size:2em;
position: absolute;
bottom: 15px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
#help {
font-family: Monospace;
color: #fff;
font-size:1em;
position: absolute;
top : 60px;
left: 0px;
width : 300px
z-index: 100;
display:block;
}
#github {
position: absolute;
top : 0px;
right: 0px;
z-index: 100;
}
</style>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<!--<div id="bottom">press H key to display/hide help</div>-->
<pre id="help">
To drop object prees key :
B for box
S for sphere
C for capsule
Y for Cylinder
M for Mesh
</pre>
<a id="github" href="https://github.com/Ricku34/ODE.js"><img src="assets/forkme.png"/></A>
<script>
window.addEventListener('DOMContentLoaded', function(){
ODE.readyPromise.then(function() {
var world = new ODE.World();
var space = new ODE.Space.Hash();
var contactgroup = new ODE.Joint.Group(10000);
world.setGravity (0,-5,0);
world.CFM = 1e-5;
world.ContactMaxCorrectingVel = 0.1;
world.ContactSurfaceLayer = 0.001;
var meshData = ODE.Geom.createTriMeshData(Rabbit.Vertices, Rabbit.Indices);
var RigidBodies = [];
// get the canvas DOM element
var canvas = document.getElementById('renderCanvas');
// load the 3D engine
var engine = new BABYLON.Engine(canvas, true);
// createScene function that creates and return the scene
var createScene = function(){
// create a basic BJS Scene object
var scene = new BABYLON.Scene(engine);
// create a FreeCamera, and set its position to (x:0, y:5, z:-10)
var camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0, 20,-10), scene);
// target the camera to scene origin
camera.setTarget(BABYLON.Vector3.Zero());
// attach the camera to the canvas
camera.attachControl(canvas, false);
// create a basic light, aiming 0,1,0 - meaning, to the sky
var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0,1,0), scene);
// create a built-in "ground" shape; its constructor takes the same 5 params as the sphere's one
// Ground
var ground = BABYLON.Mesh.CreateGroundFromHeightMap("ground", "assets/heightMap.png", 100, 100, 100, 0, 10, scene, false);
var groundMaterial = new BABYLON.StandardMaterial("ground", scene);
groundMaterial.diffuseTexture = new BABYLON.Texture("assets/ground.jpg", scene);
groundMaterial.diffuseTexture.uScale = 6;
groundMaterial.diffuseTexture.vScale = 6;
groundMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
//ground.position.y = -2.05;
ground.material = groundMaterial;
var heightData = ODE.Geom.createHeightfieldData(
function(x,y) {
return ground.getHeightAtCoordinates((x/512)*100 - 50, (y/512)*100 - 50);
},100, 100,512,512,1,0,0,0);
heightData.setBounds(0, 10);
space.createHeightfield(heightData,0);
// return the created scene
return scene;
}
// call the createScene function
var scene = createScene();
// run the render loop
engine.runRenderLoop(function(){
space.collide(function(g1,g2)
{
var b1 = g1.getBody();
var b2 = g2.getBody();
if (b1 && b2 && ODE.Body.areConnected (b1,b2))
return;
ODE.Geom.collide(g1,g2,8,function(contact)
{
contact.surface.mode = ODE.Contact.Mode.Bounce;
contact.surface.mu = 250;
contact.surface.bounce = 0.3;
contact.surface.bounce_vel = 0.05;
var c = world.createContactJoint(contactgroup,contact);
c.attach(b1,b2);
});
})
world.step(0.05);
contactgroup.empty(contactgroup);
RigidBodies.forEach(function(mesh)
{
var p = mesh.body.getPosition();
mesh.position.x = p[0];
mesh.position.y = p[1];
mesh.position.z = p[2];
var q = mesh.body.getQuaternion().getArray();
mesh.rotationQuaternion = new BABYLON.Quaternion(q[1],q[2],q[3],q[0]);
})
scene.render();
});
document.addEventListener('keypress',
function( evt )
{
var t = 0,k = evt.code;
var GeomTypes = [ ODE.Geom.Types.TriMesh, ODE.Geom.Types.Box, ODE.Geom.Types.Capsule, ODE.Geom.Types.Cylinder ,ODE.Geom.Types.Sphere];
if( k=="KeyR")
{
t = GeomTypes[Math.round(Math.random()*(GeomTypes.length-1))];
}
else if( k=="KeyB")
{
t = ODE.Geom.Types.Box;
}
else if( k=="KeyS")
{
t = ODE.Geom.Types.Sphere;
}
else if( k=="KeyC")
{
t = ODE.Geom.Types.Capsule;
}
else if( k=='KeyY')
{
t = ODE.Geom.Types.Cylinder;
}
else if( k=='KeyM' || k=="Semicolon")
{
t = ODE.Geom.Types.TriMesh;
}
switch(t)
{
case ODE.Geom.Types.TriMesh :
var mesh = new BABYLON.Mesh('body'+RigidBodies.length, scene);
mesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, Rabbit.Vertices, true);
mesh.setIndices(Rabbit.Indices);
mesh.material = new BABYLON.StandardMaterial("Mat"+RigidBodies.length, scene);
//mesh.material.wireframe = true;
mesh.material.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());
var size = mesh.getBoundingInfo().boundingBox.extendSize;
mesh.body = world.createBody();
mesh.body.setPosition((Math.random()*2-1)*5,20,(Math.random()*2-1)*5);
mesh.body.getQuaternion().fromAxisAndAngle(Math.random()*2.0-1.0,Math.random()*2.0-1.0,Math.random()*2.0-1.0,Math.random()*10.0-5.0);
var mass = new ODE.Mass();
mass.setBox(5,size.x, size.y, size.z);
mass.adjust (1);
mesh.body.setMass(mass);
mass.destroy();
mesh.odegeom = space.createTriMesh(meshData);
mesh.odegeom.setBody(mesh.body);
RigidBodies.push(mesh);
break;
case ODE.Geom.Types.Box :
var lx=2 + Math.random()*4,ly=1 + Math.random()*5,lz=1 + Math.random()*3;
var mesh = BABYLON.Mesh.CreateBox('body'+RigidBodies.length,1,scene);
mesh.material = new BABYLON.StandardMaterial("Mat"+RigidBodies.length, scene);
mesh.material.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());
mesh.scaling.x = lx;
mesh.scaling.y = ly;
mesh.scaling.z = lz;
mesh.body = world.createBody();
mesh.body.setPosition((Math.random()*2-1)*5,20,(Math.random()*2-1)*5);
mesh.body.getQuaternion().fromAxisAndAngle(Math.random()*2.0-1.0,Math.random()*2.0-1.0,Math.random()*2.0-1.0,Math.random()*10.0-5.0);
var mass = new ODE.Mass();
mass.setBox(5,lx, ly, lz);
mass.adjust (1);
mesh.body.setMass(mass);
mass.destroy();
mesh.odegeom = space.createBox(lx, ly, lz);
mesh.odegeom.setBody(mesh.body);
RigidBodies.push(mesh);
break;
case ODE.Geom.Types.Capsule :
var radius = 1 + Math.random()*3,l=2 + Math.random()*4;
var mesh = BABYLON.Mesh.CreateSphere('body'+RigidBodies.length,32,2,scene);
mesh.material = new BABYLON.StandardMaterial("Mat"+RigidBodies.length, scene);
mesh.material.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());
mesh.scaling.x = radius;
mesh.scaling.y = radius;
mesh.scaling.z = l;
mesh.body = world.createBody();
mesh.body.setPosition ((Math.random()*2-1)*5,20,(Math.random()*2-1)*5);
mesh.body.getQuaternion().fromAxisAndAngle(Math.random()*2.0-1.0,Math.random()*2.0-1.0,Math.random()*2.0-1.0,Math.random()*10.0-5.0);
var mass = new ODE.Mass();
mass.setCapsule(5,3,radius,l);
mass.adjust (1);
mesh.body.setMass(mass);
mass.destroy();
mesh.odegeom = space.createCapsule(radius,l);
mesh.odegeom.setBody(mesh.body);
RigidBodies.push(mesh);
break;
case ODE.Geom.Types.Cylinder :
var radius = 1 + Math.random()*3,l=2 + Math.random()*4;
var cylinder = BABYLON.Mesh.CreateCylinder('body'+RigidBodies.length,l,2*radius,2*radius,24,2,scene);
cylinder.material = new BABYLON.StandardMaterial("Mat"+RigidBodies.length, scene);
cylinder.material.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());
var mesh = new BABYLON.AbstractMesh('node'+RigidBodies.length, scene);
cylinder.rotation.x = -Math.PI/2;
cylinder.parent = mesh;
mesh.body = world.createBody();
mesh.body.setPosition ((Math.random()*2-1)*5,20,(Math.random()*2-1)*5);
mesh.body.getQuaternion().fromAxisAndAngle(Math.random()*2.0-1.0,Math.random()*2.0-1.0,Math.random()*2.0-1.0,Math.random()*10.0-5.0);
var mass = new ODE.Mass();
mass.setCylinder(5,3,radius,l);
mass.adjust (1);
mesh.body.setMass(mass);
mass.destroy();
mesh.odegeom = space.createCylinder(radius,l);
mesh.odegeom.setBody(mesh.body);
RigidBodies.push(mesh);
break;
case ODE.Geom.Types.Sphere :
var radius = 1 + Math.random()*3;
var mesh = BABYLON.Mesh.CreateSphere('body'+RigidBodies.length,32,2*radius,scene);
mesh.material = new BABYLON.StandardMaterial("Mat"+RigidBodies.length, scene);
mesh.material.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());
mesh.body = world.createBody();
mesh.body.setPosition ((Math.random()*2-1)*5,20,(Math.random()*2-1)*5);
mesh.body.getQuaternion().fromAxisAndAngle(Math.random()*2.0-1.0,Math.random()*2.0-1.0,Math.random()*2.0-1.0,Math.random()*10.0-5.0);
var mass = new ODE.Mass();
mass.setSphere(5,radius);
mass.adjust (1);
mesh.body.setMass(mass);
mass.destroy();
mesh.odegeom = space.createSphere(radius);
mesh.odegeom.setBody(mesh.body);
RigidBodies.push(mesh);
break;
default :
break;
}
}, false);
// the canvas/window resize event handler
window.addEventListener('resize', function(){
engine.resize();
});
});
});
</script>
</body>
</html>