View
Theme
Font Style
7pt
8pt
9pt
10pt
11pt
Line Style
100%
110%
120%
130%
140%
Bold Keyword
Default
Inspector
Kkaefer
Eclipse
SQ Light
Lesser
Dark
Cobalt
Monokai
Rubyblue
Night
SQ Dark
Ambiance
Blackboard
Line Num.
Wrap Lines
Preview
Redraw
JS Tab
HTML Tab
CSS Tab
Live Tab
Prev. Tab
Next Tab
Browser
History…
Help
Edit
Settings
Auto Complete
Match Brackets
Match Highlight
Strip Whitespace
Auto Close Brackets
Auto Close Quotes
Show Print Margin
Undo
Redo
Delete
Select Line
Select All
Find & Replace
Find
Find in Repo.
Find Next
Find Previous
Replace Single
Replace All
Wrap Search
Revert
As Template
Diff Revision
Format
Compress
Text
Zen Coding
Indent
Tab Width
1
2
3
4
5
6
7
8
Indent Unit
1
2
3
4
5
6
7
8
Smart Indent
Use Tabs
Visible Tabs
Shift Left
Shift Right
Put Indent
Number
Increment by 1
Decrement by 1
Increment by 0.1
Decrement by 0.1
Increment by 10
Decrement by 10
Simple Math
Comment
Line
Move Up
Move Down
Copy Up
Copy Down
Go to Line…
Remove Line
Next Point
Prev. Point
Help
Share
Login
You can jump to the latest bin by adding
/latest
to your URL
×
z
Find
→
←
⟲
Replace
⊗
All
Replace
/* TODO RENDER - Tyre bumpmap - Body lightmap - Change envmap * Brake light WISHLIST - Skidmarks - Camera RCZ * Hand brake */ var camera, scene, renderer, loader, stats, ambientLight, directionalLight; var car, body, lfw, rfw, lrw, rrw, bm; //var reflectionCar, reflectionFrontLeftWheel, reflectionFrontRightWheel, reflectionRearLeftWheel, reflectionRearRightWheel; var dt, ta; var debug; // _______________________________________________________________________________________ FXX var DEG2RAD = Math.PI / 180; var DEG90 = Math.PI / 2; var sa = 0, s1 = 0, fs = false, rs = false; var ur = false, ul = false, uu = false, ud = false; // _______________________________________________________________________________________ Private // Unless otherwise specified all Points are in car reference frame. // SAE convention: x is to the front of the car, y is to the right, z is down. var cvel = new THREE.Vector3(); var vel = new THREE.Vector3(); var a2d = new THREE.Vector3(); // Acceleration in world coords var force = new THREE.Vector3(); var res = new THREE.Vector3(); var acc = new THREE.Vector3(); var ft = new THREE.Vector3(); var flf = new THREE.Vector3(); var flr = new THREE.Vector3(); var av = 0, aa = 0; // Angular velocity, angular acceleration // _______________________________________________________________________________________ Camera var distance = 10; var height = 5; var heightDamping = 2; var rotationDamping = 3; var randomPositionMin = new THREE.Vector3( 3, 0.1, 3 ); var randomPositionMax = new THREE.Vector3( 5, 3, 5 ); var cameraSpeedMin = 0.1; var cameraSpeedMax = 0.1; var cameraShotTime = 5; var target = new THREE.Vector3(); var cameraSpeed = new THREE.Vector3( 4, 2, 4 ); var cameraTime = 0; var userWeight = 1; var angleX, angleY, orbitX, orbitY, orbitDistance; var orbitOrigin = new THREE.Vector3( 4, 2, 4 ); // _______________________________________________________________________________________ SkidMarks var enableSkidMarks = false; var maxMarks = 1024; // Maximum number of marks total handled by one instance of the script. var markWidth = 0.275; // The width of the skidmarks. Should match the width of the wheel that it is used for. In meters. var numMarks = 0; var lastMark = -1; // Variables for each mark created. Needed to generate the correct mesh. var markSection = { pos: new THREE.Vector3(), normal: new THREE.Vector3(), posl: new THREE.Vector3(), posr: new THREE.Vector3(), intensity: 0.0, lastIndex: 0 }; var skidmarks = []; var updated = false; var skm, skg; var v3 = new THREE.Vector3(); // _______________________________________________________________________________________ Setup if( Detector.webgl ) { init(); } else { Detector.addGetWebGLMessage(); document.write( '
' ); } function init() { // 3D var container = document.getElementById( 'container' ); scene = new THREE.Scene(); // Camera camera = new THREE.Camera( 35, window.innerWidth / window.innerHeight, 0.01, 200000 ); camera.position.y = 2; camera.position.z = 8; // Ligths ambientLight = new THREE.AmbientLight( 0x808080 ); scene.addLight( ambientLight ); directionalLight = new THREE.DirectionalLight( 0xFFFFFF, 1.5 ); directionalLight.position.x = 0; directionalLight.position.y = 1; directionalLight.position.z = 0; directionalLight.position.normalize(); scene.addLight( directionalLight ); // Renderer renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); // Loader loader = new THREE.Loader( true ); document.body.appendChild( loader.statusDomElement ); // Car CreateCar(); LoadCar(); if( enableSkidMarks ) SetupSkidMarks(); // Input document.addEventListener( 'keydown', onKeyDown, false ); document.addEventListener( 'keyup', onKeyUp, false ); // Stats stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.top = '0px'; stats.domElement.style.zIndex = 100; container.appendChild( stats.domElement ); ta = new Date().getTime(); animate(); } function CreateCar() { var material = new THREE.MeshBasicMaterial( { color: 0xFFFFFF } ); car = new THREE.Object3D(); scene.addObject( car ); body = new THREE.Object3D(); body.rotation.y = DEG90; car.addChild( body ); lfw = new THREE.Object3D(); lfw.position.x = 1.3928; lfw.position.y = 0.34; lfw.position.z = -0.69; car.addChild( lfw ); rfw = new THREE.Object3D(); rfw.position.x = 1.40; rfw.position.y = 0.34; rfw.position.z = 0.69; car.addChild( rfw ); lrw = new THREE.Object3D(); lrw.position.x = -2; lrw.position.y = 0.34; lrw.position.z = -0.69; car.addChild( lrw ); rrw = new THREE.Object3D(); rrw.position.x = -2; rrw.position.y = 0.34; rrw.position.z = 0.69; car.addChild( rrw ); } function LoadCar() { var r = "/assets/racer/obj/"; var urls = [ r + "envmap_right.jpg", r + "envmap_left.jpg", r + "envmap_top.jpg", r + "envmap_bottom.jpg", r + "envmap_front.jpg", r + "envmap_back.jpg" ]; var envmap = ImageUtils.loadTextureCube( urls ); var bodyPaint = { x: 0, y: 0.5859, z: 0, material: new THREE.MeshLambertMaterial( { color: 0xffffff, map: ImageUtils.loadTexture( '/assets/racer/obj/BodyPaint.jpg' ), envMap: envmap, combine: THREE.MultiplyOperation, reflectivity: 1 } ) }; var suspension = { x: 0, y: 0.4044, z: -0.3071, material: new THREE.MeshPhongMaterial( { color: 0x0A0A0A } ) }; var insideBlack = { x: 0, y: 0.5773, z: 0.7290, material: new THREE.MeshBasicMaterial( { color: 0x000000 } ) }; var glossyBlack = { x: 0, y: 0.4115, z: -0.7112, material: new THREE.MeshPhongMaterial( { color: 0x0A0A0A, specular: 0x606060 } ) }; var chrome = { x: 0, y: 0.5867, z: 0.3202, material: new THREE.MeshPhongMaterial( { color: 0xFFFFFF, envMap: envmap, combine: THREE.MultiplyOperation } ) }; var bolts = { x: 0, y: 0.5694, z: 0.8672, material: new THREE.MeshPhongMaterial( { color: 0x844410, specular: 0x808080, shininess: 0.5, ambient: 0x808080 } ) }; var windshield = { x: 0, y: 0.6777, z: 0.5647, material: new THREE.MeshPhongMaterial( { color: 0xFFFFFF, envMap: envmap, combine: THREE.MixOperation, opacity: 0.5 } ) }; var rearLight = { x: 0, y: 0.4652, z: -2.34, material: new THREE.MeshBasicMaterial( { color: 0x800000, map: ImageUtils.loadTexture( '/assets/racer/obj/RearLights.jpg' ) } ) }; var rearLightGlass = { x: 0, y: 0.4652, z: -2.34, material: new THREE.MeshBasicMaterial( { color: 0xFF0000, envMap: envmap, combine: THREE.MixOperation, opacity: 0.5 } ) }; var steeringWheel = { x: 0, y: 0.5933, z: 0.5054, material: new THREE.MeshPhongMaterial( { color: 0xFFFFFF, map: ImageUtils.loadTexture( '/assets/racer/obj/SteeringWheel.jpg' ) } ) }; var driver = { x: -0.0113, y: 0.4063, z: 0.5277, material: new THREE.MeshPhongMaterial( { color: 0xFFFFFF, map: ImageUtils.loadTexture( '/assets/racer/obj/Driver.jpg' ) } ) }; var helmet = { x: 0.0016, y: 0.7287, z: -0.0175, material: new THREE.MeshBasicMaterial( { color: 0xFFFFFF, map: ImageUtils.loadTexture( '/assets/racer/obj/Helmet.jpg' ), envMap: envmap, combine: THREE.MultiplyOperation } ) }; var visor = { x: 0.0016, y: 0.6993, z: 0.0520, material: new THREE.MeshBasicMaterial( { color: 0xFFFFFF, map: ImageUtils.loadTexture( '/assets/racer/obj/Visor.jpg' ), envMap: envmap, combine: THREE.MultiplyOperation } ) }; var tyre = { x: 0, y: 0, z: 0, material: new THREE.MeshPhongMaterial( { color: 0xFFFFFF, map: ImageUtils.loadTexture( '/assets/racer/obj/Tyre.jpg' ), specular: 0x808080, shininess: 0.5, ambient: 0x808080 } ) }; var rim = { x: 0, y: 0, z: 0, material: new THREE.MeshPhongMaterial( { color: 0xFFFFFF, map: ImageUtils.loadTexture( '/assets/racer/obj/Rim.jpg' ), ambient: 0x404040 } ) }; var wheelBase = { x: 0, y: 0, z: 0, material: new THREE.MeshBasicMaterial( { color: 0x000000 } ) }; helmet.material.map.wrap_s = THREE.RepeatWrapping; bm = rearLight.material; loader.loadBinary( { model: "/assets/racer/obj/BodyPaint.js", callback: function( geometry ) { AddBodyPart( geometry, bodyPaint ); } } ); loader.loadBinary( { model: "/assets/racer/obj/Suspension.js", callback: function( geometry ) { AddBodyPart( geometry, suspension ); } } ); loader.loadBinary( { model: "/assets/racer/obj/InsideBlack.js", callback: function( geometry ) { AddBodyPart( geometry, insideBlack ); } } ); loader.loadBinary( { model: "/assets/racer/obj/GlossyBlack.js", callback: function( geometry ) { AddBodyPart( geometry, glossyBlack ); } } ); loader.loadBinary( { model: "/assets/racer/obj/Chrome.js", callback: function( geometry ) { AddBodyPart( geometry, chrome ); } } ); loader.loadBinary( { model: "/assets/racer/obj/Bolts.js", callback: function( geometry ) { AddBodyPart( geometry, bolts ); } } ); loader.loadBinary( { model: "/assets/racer/obj/Windshield.js", callback: function( geometry ) { AddBodyPart( geometry, windshield ); } } ); loader.loadBinary( { model: "/assets/racer/obj/RearLight.js", callback: function( geometry ) { AddBodyPart( geometry, rearLight ); } } ); loader.loadBinary( { model: "/assets/racer/obj/RearLightGlass.js", callback: function( geometry ) { AddBodyPart( geometry, rearLightGlass ); } } ); loader.loadBinary( { model: "/assets/racer/obj/SteeringWheel.js", callback: function( geometry ) { AddBodyPart( geometry, steeringWheel ); } } ); loader.loadBinary( { model: "/assets/racer/obj/DriverBody.js", callback: function( geometry ) { AddBodyPart( geometry, driver ); } } ); loader.loadBinary( { model: "/assets/racer/obj/Helmet.js", callback: function( geometry ) { AddBodyPart( geometry, helmet ); } } ); loader.loadBinary( { model: "/assets/racer/obj/Visor.js", callback: function( geometry ) { AddBodyPart( geometry, visor ); } } ); loader.loadBinary( { model: "/assets/racer/obj/Tyre.js", callback: function( geometry ) { AddWheelPart( geometry, tyre ); } } ); loader.loadBinary( { model: "/assets/racer/obj/Rim.js", callback: function( geometry ) { AddWheelPart( geometry, rim ); } } ); loader.loadBinary( { model: "/assets/racer/obj/WheelBase.js", callback: function( geometry ) { AddWheelPart( geometry, wheelBase ); } } ); loader.loadBinary( { model: "/assets/racer/obj/HelloEnjoy.js", callback: function( geometry ) { AddHelloEnjoy( geometry ); } } ); var shadowMesh = new THREE.Mesh( new Plane( 7.5, 7.5 ), new THREE.MeshBasicMaterial( { color: 0xFFFFFF, map: ImageUtils.loadTexture( '/assets/racer/obj/Shadow.jpg' ) } ) ); shadowMesh.position.x = -0.4; shadowMesh.position.y = -0.001; shadowMesh.rotation.x = -DEG90; shadowMesh.rotation.z = -DEG90; car.addChild( shadowMesh ); } function AddHelloEnjoy( geometry ) { var mesh = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: 0x000000 } ) ); mesh.position.y = 0.01; mesh.rotation.x = -DEG90; scene.addObject( mesh ); } function AddBodyPart( geometry, data ) { loader.statusDomElement.innerHTML = "Creating model ..."; var mesh = new THREE.Mesh( geometry, data.material ); mesh.position.x = data.x; mesh.position.y = data.y; mesh.position.z = data.z; body.addChild( mesh ); loader.statusDomElement.style.display = "none"; loader.statusDomElement.innerHTML = "Loading model ..."; } function AddWheelPart( geometry, data ) { var mesh = new THREE.Mesh( geometry, data.material ); mesh.position.x = data.x; mesh.position.y = data.y; mesh.position.z = data.z; mesh.rotation.y = -DEG90; lfw.addChild( mesh ); mesh = new THREE.Mesh( geometry, data.material ); mesh.position.x = data.x; mesh.position.y = data.y; mesh.position.z = data.z; mesh.rotation.y = DEG90; rfw.addChild( mesh ); mesh = new THREE.Mesh( geometry, data.material ); mesh.position.x = data.x; mesh.position.y = data.y; mesh.position.z = data.z; mesh.rotation.y = -DEG90; lrw.addChild( mesh ); mesh = new THREE.Mesh( geometry, data.material ); mesh.position.x = data.x; mesh.position.y = data.y; mesh.position.z = data.z; mesh.rotation.y = DEG90; rrw.addChild( mesh ); } function AddTyrePart( geometry, data ) { // geometry.computeVertexNormals(); geometry.computeTangents(); AddWheelPart( geometry, data ); } // _______________________________________________________________________________________ Update function animate() { requestAnimationFrame( animate ); loop(); } function loop() { var time = new Date().getTime(); dt = (time - ta) * 0.001; ta = time; UpdateCar(); SteerWheels(); UpdateCamera(); if( enableSkidMarks ) UpdateSkidMarks(); if( debug ) { console.log( av ); debug = false; } renderer.render( scene, camera ); stats.update(); } // _______________________________________________________________________________________ Update Car function SteerWheels() { var steerValue = 2.5 * dt; var leftCmd = ul? -1 : 0; var rightCmd = ur? 1 : 0; var steerCmd = leftCmd + rightCmd; if( steerCmd == 0 ) steerValue = Math.min( steerValue, Math.abs( s1 ) ); if( steerCmd > s1 ) s1 += steerValue; else if( steerCmd < s1 ) s1 -= steerValue; s1 = Math.min( 1, Math.max( s1, -1 ) ); sa = s1 * 20 * DEG2RAD; } function UpdateCar() { // These constants are arbitrary values, not realistic ones. var carDrag = 5; // Factor for air resistance (drag) var carResistance = 30; // Factor for rolling resistance var carCorneringStiffnessFront = -5; // Cornering stiffness (Front) var carCorneringStiffnessRear = -5.2; // Cornering stiffness (Rear) var carMaxGrip = 2; // Maximum (normalised) friction force, =diameter of friction circle var carCenterMassDistanceFront = 1; // Front distance in m, distance from CG to front axle var carCenterMassDistanceRear = 1; // Rear distance in m, idem to rear axle // Physics var wheelBase = carCenterMassDistanceFront + carCenterMassDistanceRear; // Wheelbase in m, must be b+c var carAngle = car.rotation.y; var sn = Math.sin( carAngle ); var cs = Math.cos( carAngle ); // SAE convention: x is to the front of the car, y is to the right, z is down // bangz: Velocity of Car. Vlat and Vlong // transform velocity in world reference frame to velocity in car reference frame vel.x = cs * cvel.y + sn * cvel.x; vel.y = -sn * cvel.y + cs * cvel.x; // Reverse steering hack var sar = ( vel.x > 0 )? sa : -sa; // Lateral force on wheels // // Resulting velocity of the wheels as result of the yaw rate of the car body // v = yawrate * r where r is distance of wheel to CG (approx. half wheel base) // yawrate (ang.velocity) must be in rad/s // var yawSpeed = wheelBase * 0.5 * av; var rotAngle, sideSlip, slipAngleFront, slipAngleRear, torque; // Singularity if( Math.abs( vel.x ) < 0.2 ) { vel.x = vel.y = rotAngle = sideSlip = slipAngleFront = // av = // yawSpeed = slipAngleRear = 0; } else { // bangz: velocity.x = fVLong_, velocity.y = fVLat_ rotAngle = Math.atan2( yawSpeed, Math.abs( vel.x ) ); // Calculate the side slip angle of the car (a.k.a. beta) sideSlip = Math.atan2( vel.y, Math.abs( vel.x ) ); // Calculate slip angles for front and rear wheels (a.k.a. alpha) slipAngleFront = sideSlip + rotAngle - sar; slipAngleRear = sideSlip - rotAngle; } // weight per axle = half car mass times 1G (=9.8m/s^2) var carMass = 1500; // Mass in kg var weight = carMass * 9.8 * 0.5; // lateral force on front wheels = (Ca * slip angle) capped to friction circle * load flf.x = 0; flf.y = carCorneringStiffnessFront * slipAngleFront; flf.y = Math.min( carMaxGrip, flf.y ); flf.y = Math.max( -carMaxGrip, flf.y ); flf.y *= weight; if( fs ) flf.y *= 0.5; // lateral force on rear wheels flr.x = 0; flr.y = carCorneringStiffnessRear * slipAngleRear; flr.y = Math.min( carMaxGrip, flr.y ); flr.y = Math.max( -carMaxGrip, flr.y ); flr.y *= weight; if( rs ) flr.y *= 0.7; // longtitudinal force on rear wheels - very simple traction model // Accelerate / Reverse var driverThrottle = uu? 100 : 0; var driverBrake = ud? -100 : 0; ft.x = 100 * (driverThrottle + driverBrake); ft.y = 0; // Brake light bm.color.setHex( (driverBrake < 0)? 0xFF0000 : 0x800000 ); if( rs ) ft.x *= 0.5; // FORCES AND TORQUE ON BODY // drag and rolling resistance res.x = -( carResistance * vel.x + carDrag * vel.x * Math.abs(vel.x) ); res.y = -( carResistance * vel.y + carDrag * vel.y * Math.abs(vel.y) ); // sum forces force.x = ft.x + Math.sin( sar ) * flf.x + flr.x + res.x; force.y = ft.y + Math.cos( sar ) * flf.y + flr.y + res.y; // Singularity if( force.x == 0 && vel.x == 0 ) { flf.y = flr.y = force.y = torque = acc.x = acc.y = aa = a2d.x = a2d.y = cvel.x = cvel.y = av = 0; } else { // torque on body from lateral forces torque = carCenterMassDistanceFront * flf.y - carCenterMassDistanceRear * flr.y; // ACCELERATION // Newton F = m.a, therefore a = F/m acc.x = force.x / carMass; acc.y = force.y / carMass; var carInertia = 1500; // Inertia in kg.m aa = torque / carInertia; // VELOCITY AND POSITION // transform acceleration from car reference frame to world reference frame a2d.x = cs * acc.y + sn * acc.x; a2d.y = -sn * acc.y + cs * acc.x; // velocity is integrated acceleration cvel.x += dt * a2d.x; cvel.y += dt * a2d.y; // ANGULAR VELOCITY // integrate angular acceleration to get angular velocity av += dt * aa; } // position is integrated velocity car.position.z -= dt * cvel.x; car.position.x += dt * cvel.y; if( enableSkidMarks && Math.abs( slipAngleRear ) > 0.5 ) { lastMark = AddSkidMark( car.position, new THREE.Vector3(0,1,0), 1, lastMark ); // console.log( slipAngleRear ); // console.log( car.position.x + " " + car.position.y + " " + car.position.z ); } // HEADING // integrate angular velocity to get angular orientation carAngle += dt * av; car.rotation.y = carAngle; // In deg lfw.rotation.y = sa; rfw.rotation.y = sa; var carWheelRadius = 0.334; // Radius in m // var rot = (dt * Math.abs( cvel.y )) / carWheelRadius; var rot = 0.012 * vel.x / carWheelRadius; lfw.rotation.z -= rot; rfw.rotation.z -= rot; lrw.rotation.z -= rot; rrw.rotation.z -= rot; } // _______________________________________________________________________________________ Update Camera function UpdateCamera() { // userWeight = Mathf.Lerp( userWeight, 1, 0.05f ); /* if( Input.GetButtonDown( "Fire1" ) ) { angleX = angleY = orbitX = orbitY = 0; orbitOrigin = transform.position - target.position; orbitDistance = orbitOrigin.magnitude; orbitOrigin.Normalize(); cameraTime = CameraTime; } if( Input.GetButton( "Fire1" ) ) { float orbitMultX = -1; float orbitMultY = 1; angleX += Input.GetAxis("Mouse X"); angleY += Input.GetAxis("Mouse Y"); orbitX = Mathf.Lerp( orbitX, angleX, 0.02f ); orbitY = Mathf.Lerp( orbitY, angleY, 0.02f ); //DC.Log( angleX + " " + angleY ); //DC.Log( "___" + orbitX + " " + orbitY ); orbitDistance = Mathf.Lerp( orbitDistance, 4, 0.02f ); Quaternion orbitRotation = Quaternion.Euler( orbitY * orbitMultY, orbitX * orbitMultX, 0 ); Vector3 orbitPosition = orbitRotation * orbitOrigin * orbitDistance + target.position; orbitPosition.y = Mathf.Max( orbitPosition.y, 0.1f ); transform.position = orbitPosition; } else */ if( true ) { var cameraDistance = camera.position.distanceTo( camera.target.position ); /* if( cameraDistance > 40 || cameraDistance < 2 ) cameraTime = 0; */ cameraTime -= dt; if( cameraTime < 0 ) { cameraTime = cameraShotTime; // Position if( car.position.length() > 50 ) //car.position = new THREE.Vector3(); var prevPos = camera.position.clone(); var targetPos = car.position.clone(); if( targetPos.length > 100 ) { //prevPos -= targetPos; //targetPos = new THREE.Vector3(); } var newPos = prevPos.clone(); var tries = 200; /* while( --tries > 0 && prevPos.distanceTo( newPos ) < 3 ) { var angle = Math.random() * 2 * Math.PI; newPos.x = targetPos.x + randomPositionMin.x + Math.random() * (randomPositionMax.x-randomPositionMin.x) * Math.cos( angle ); newPos.y = targetPos.y + randomPositionMin.y + Math.random() * (randomPositionMax.y-randomPositionMin.y); newPos.z = targetPos.z + randomPositionMin.z + Math.random() * (randomPositionMax.z-randomPositionMin.z) * Math.sin( angle ); } */ camera.position = newPos; // Speed camera.position.x += prevPos.x * dt; camera.position.y += prevPos.y * dt; camera.position.z += prevPos.z * dt; /* var dir = Math.random(); if( dir < 0.4 ) // X cameraSpeed.x = cameraSpeedMin + Math.random() * (cameraSpeedMax - cameraSpeedMin); else if( dir < 0.8 ) // Z cameraSpeed.x = cameraSpeedMin + Math.random() * (cameraSpeedMax - cameraSpeedMin); else // Y cameraSpeed.x = cameraSpeedMin + Math.random() * (cameraSpeedMax - cameraSpeedMin); cameraSpeed.x *= (Math.random() > 0.5)? 1 : -1; cameraSpeed.z *= (Math.random() > 0.5)? 1 : -1; */ } /* camera.position.x += cameraSpeed.x * dt; camera.position.y += cameraSpeed.y * dt; camera.position.z += cameraSpeed.z * dt; */ camera.target.position.x -= (camera.target.position.x - car.position.x) * 0.05; camera.target.position.y -= (camera.target.position.y - car.position.y) * 0.05; camera.target.position.z -= (camera.target.position.z - car.position.z) * 0.05; } } // _______________________________________________________________________________________ Keyboard function onKeyDown( e ) { // console.log( e.keyCode ); var key = e.keyCode; if( key == 38 || key == 87 ) uu = true; else if( key == 40 || key == 83 ) ud = true; else if( key == 37 || key == 65 ) ur = true; else if ( key == 39 || key == 68 ) ul = true; else if ( key == 32 ) rs = true; else if ( e.keyCode == 13 ) cameraTime = 0; // else if ( e.keyCode == 13 ) debug = true; } function onKeyUp( e ) { var key = e.keyCode; if( key == 38 || key == 87 ) uu = false; else if( key == 40 || key == 83 ) ud = false; else if( key == 37 || key == 65 ) ur = false; else if ( key == 39 || key == 68 ) ul = false; else if ( key == 32 ) rs = false; } function log( text ) { var e = document.getElementById("log"); e.innerHTML = text + "
" + e.innerHTML; } // _______________________________________________________________________________________ Skidmarks // Initiallizes the array holding the skidmark sections. function SetupSkidMarks() { for( var i = 0; i < maxMarks; i++ ) { skidmarks[ i ] = { pos: new THREE.Vector3(), normal: new THREE.Vector3(), posl: new THREE.Vector3(), posr: new THREE.Vector3(), intensity: 0.0, lastIndex: 0 }; } skg = new THREE.Geometry(); skm = new THREE.Mesh( skg, new THREE.MeshBasicMaterial( { color: 0x00FF00 } ) ); skm.position.y = 0.1; //skm.boundRadius = 999; /* var size = 2; var vs = 500; for( var i = 0; i < vs; i++ ) { skg.vertices.push( new THREE.Vertex( new THREE.Vector3( Math.random() * size,Math.random() * size,Math.random() * size) ) ); } for( var i = 0; i < 500; i++ ) { skg.faces.push( new THREE.Face3( Math.floor( Math.random() * vs), Math.floor( Math.random() * vs), Math.floor( Math.random() * vs) ) ); } */ scene.addObject( skm ); } // Function called by the wheels that is skidding. Gathers all the information needed to // create the mesh later. Sets the intensity of the skidmark section b setting the alpha // of the vertex color. function AddSkidMark( pos, normal, intensity, lastIndex ) { if( intensity > 1 ) intensity = 1; if( intensity < 0 ) return -1; curr = skidmarks[ numMarks % maxMarks ]; curr.pos.copy( pos ); // curr.pos.add( pos + normal * 0.02; // The distance the skidmarks is places above the surface it is placed upon. In meters. curr.normal.copy( normal ); curr.intensity = intensity; curr.lastIndex = lastIndex; if( lastIndex != -1 ) { width2 = markWidth * 0.5; last = skidmarks[ lastIndex % maxMarks ]; dir = new THREE.Vector3(); dir = dir.sub( curr.pos, last.pos ); xDir = new THREE.Vector3(); xDir.cross( dir, normal ); xDir.normalize(); var xDir2 = new THREE.Vector3(); xDir2.copy( xDir ); xDir2.multiplyScalar( width2 ); curr.posl.add( curr.pos, xDir2 ); curr.posr.sub( curr.pos, xDir2 ); // curr.tangent = new Vector4( xDir.x, xDir.y, xDir.z, 1 ); if( last.lastIndex == -1 ) { // last.tangent = curr.tangent; last.posl.add( curr.pos, xDir2 ); last.posr.sub( curr.pos, xDir2 ); } } numMarks++; updated = true; return numMarks -1; } function ClearSkidMarks() { numMarks = 0; updated = true; } // If the mesh needs to be updated, i.e. a new section has been added, // the current mesh is removed, and a new mesh for the skidmarks is generated. function UpdateSkidMarks() { if( ! updated ) return; updated = false; var segmentCount = 0; /* for( var j = 0; j < numMarks && j < maxMarks; j++ ) if( skidmarks[ j ].lastIndex != -1 && skidmarks[ j ].lastIndex > numMarks - maxMarks ) segmentCount++; Vector3[] vertices = new Vector3[ segmentCount * 4 ]; Vector3[] normals = new Vector3[ segmentCount * 4 ]; Vector4[] tangents = new Vector4[ segmentCount * 4 ]; Color[] colors = new Color[ segmentCount * 4 ]; Vector2[] uvs = new Vector2[ segmentCount * 4 ]; int[] triangles = new int[ segmentCount * 6 ]; */ // segmentCount = 0; var vertices = skg.vertices; for( var i = 0; i < numMarks && i < maxMarks; i++ ) { if( skidmarks[i].lastIndex != -1 && skidmarks[i].lastIndex > numMarks - maxMarks ) { var curr = skidmarks[i]; var last = skidmarks[curr.lastIndex % maxMarks]; vertices[segmentCount * 4 + 1] = new THREE.Vertex( new THREE.Vector3( last.posl.x, last.posl.y, last.posl.z )); vertices[segmentCount * 4 + 0] = new THREE.Vertex( new THREE.Vector3( last.posr.x, last.posr.y, last.posr.z )); vertices[segmentCount * 4 + 2] = new THREE.Vertex( new THREE.Vector3( curr.posl.x, curr.posl.y, curr.posl.z )); vertices[segmentCount * 4 + 3] = new THREE.Vertex( new THREE.Vector3( curr.posr.x, curr.posr.y, curr.posr.z )); /* var normals = skg.normals; normals[segmentCount * 4 + 0] = last.normal; normals[segmentCount * 4 + 1] = last.normal; normals[segmentCount * 4 + 2] = curr.normal; normals[segmentCount * 4 + 3] = curr.normal; tangents[segmentCount * 4 + 0] = last.tangent; tangents[segmentCount * 4 + 1] = last.tangent; tangents[segmentCount * 4 + 2] = curr.tangent; tangents[segmentCount * 4 + 3] = curr.tangent; colors[segmentCount * 4 + 0]=new Color(0, 0, 0, last.intensity); colors[segmentCount * 4 + 1]=new Color(0, 0, 0, last.intensity); colors[segmentCount * 4 + 2]=new Color(0, 0, 0, curr.intensity); colors[segmentCount * 4 + 3]=new Color(0, 0, 0, curr.intensity); */ skg.uvs[ segmentCount ] = [ new THREE.UV(0, 0), new THREE.UV(1, 0), new THREE.UV(0, 1), new THREE.UV(1, 1) ]; /* uvs[segmentCount * 4 + 0] = new THREE.UV(0, 0); uvs[segmentCount * 4 + 1] = new THREE.UV(1, 0); uvs[segmentCount * 4 + 2] = new THREE.UV(0, 1); uvs[segmentCount * 4 + 3] = new THREE.UV(1, 1); */ var face = new THREE.Face4( segmentCount * 4 + 0, segmentCount * 4 + 1, segmentCount * 4 + 2, segmentCount * 4 + 3 ); face.normal = new THREE.Vector3( 0, 1, 0 ); skg.faces[ segmentCount ] = face; segmentCount++; } skg.computeCentroids(); skg.computeFaceNormals(); skg.computeBoundingBox(); skg.computeBoundingSphere(); } //console.log( skg.vertices ); //console.log( skg.uvs ); //console.log( skg.faces.length ); /* mesh.vertices=vertices; mesh.normals=normals; mesh.tangents=tangents; mesh.triangles=triangles; mesh.colors=colors; mesh.uv=uvs; */ }
HelloRacer™ WebGL
HelloRacer™ WebGL
— Created by
HelloEnjoy™
— Powered by
three.js
Use WASD or cursor keys to drive, space for hand brake and enter to change camera.
body { background-color: #fff; margin: 0px; overflow: hidden; } #info { position: absolute; top: 0px; width: 100%; color: #808080; padding: 5px; font-family: “helvetica neue”, helvetica, arial, sans-serif; font-size: 13px; text-align: center; } #info2 { position: absolute; bottom: 0px; width: 100%; color: #808080; padding: 5px; font-family: “helvetica neue”, helvetica, arial, sans-serif; font-size: 13px; text-align: center; } a { color: #000; text-decoration: none; } a:hover { color: #ff1561; }
Pop out
Help
About
×
×