//---------------------------- //---------------------------- // Common.js //---------------------------- //---------------------------- console.println( "* The Javascript 'Common.js' is now being read..." ); var ONE_HALF = 0.5; var PI = 3.14159; var verbose = false; var theBackground = null; var backgroundRed = 0.7; var backgroundGreen = 0.7; var backgroundBlue = 0.7; //--------------------------------------------------------------------- function printNamesOfAllTheMeshes() { var numberOfMeshes = scene.meshes.count; console.println( "Printing names of all the meshes in the scene..." ); console.println( "(there are " + numberOfMeshes + " meshes in this Scene)" ); for (m=0; m 1.0 ) { f = 1.0; } rotationAxis.scaleInPlace( 1.0 - f ); var rotationRate = rotationAxis.length * MOUSE_ROTATION_FORCE * event.deltaTime; if ( rotationRate > 0.000001 ) { rotation.rotateAboutVectorInPlace( rotationRate, rotationAxis ); } rotatedRight = rotation.transformDirection( right ); rotatedUp = rotation.transformDirection( up ); rotatedFront = rotation.transformDirection( front ); //---------------------------------------------------------- // Here is where the resource models are updated.... //---------------------------------------------------------- if ( stickResourceAdded ) { updateSticks( testClock ); } if ( ballResourceAdded ) { updateBalls( event.deltaTime ); } if ( squareResourceAdded ) { updateSquares( event.deltaTime ); } //------------------------------------------------------- // rotating //------------------------------------------------------- if ( action == ROTATING_CUBE_ACTION ) { var mousePointingVector = new Vector3(); var mousePreviousPointingVector = new Vector3(); mousePointingVector.set ( camera.getDirectionFromScreen( mouse_X, mouse_Y, canvasPixelWidth, canvasPixelHeight ) ); mousePreviousPointingVector.set( camera.getDirectionFromScreen( mouse_XPrevious, mouse_YPrevious, canvasPixelWidth, canvasPixelHeight ) ); mouse_XPrevious = mouse_X; mouse_YPrevious = mouse_Y; mouseMotionVector.set( mousePointingVector ); mouseMotionVector.subtractInPlace( mousePreviousPointingVector ); var cameraVector = new Vector3(); cameraVector.set( camera.position ); cameraVector.subtractInPlace( camera.targetPosition ); cameraVector.scaleInPlace( 1.0 / cameraVector.length ); var newAxis = new Vector3( cameraVector.cross( mouseMotionVector ) ); rotationAxis.addScaledInPlace( newAxis, 3.0 ); } else ( action == DRAGGING_BALL_ACTION ) { if ( grabbedBall != -1 ) { var previousPosition = new Vector3( ballPosition[ grabbedBall ] ); var v = new Vector3( camera.getDirectionFromScreen( mouse_X, mouse_Y, canvasPixelWidth, canvasPixelHeight ) ); ballPosition[ grabbedBall ].set( camera.position ); ballPosition[ grabbedBall ].addScaledInPlace( v, grabDistance ); ballVelocity[ grabbedBall ].set( ballPosition[ grabbedBall ] ); ballVelocity[ grabbedBall ].subtractInPlace( previousPosition ); } } } runtime.addEventHandler( timeEventHandler ); //------------------------------------------------------ // General Mouse Event Handler for whole 3D Annotation //------------------------------------------------------ generalMouseEventHandler.onMouseDown = true; generalMouseEventHandler.onMouseMove = true; generalMouseEventHandler.onMouseUp = true; generalMouseEventHandler.onEvent = function( event ) { //----------------------------------------------- // mouse is moving //----------------------------------------------- if ( event.isMouseMove ) { mouse_X = event.mouseX; mouse_Y = event.mouseY; canvasPixelWidth = event.canvasPixelWidth; canvasPixelHeight = event.canvasPixelHeight; } //----------------------------------------------- // mouse just down //----------------------------------------------- if ( event.isMouseDown ) { rotating = false; mouse_X = event.mouseX; mouse_Y = event.mouseY; mouse_XPrevious = mouse_X; mouse_YPrevious = mouse_Y; canvasPixelWidth = event.canvasPixelWidth; canvasPixelHeight = event.canvasPixelHeight; grabbedBall = detectMouseOverBall(); if ( grabbedBall != -1 ) { action = DRAGGING_BALL_ACTION; } else { action = ROTATING_CUBE_ACTION; } } //----------------------------------------------- // mouse just up //----------------------------------------------- if ( event.isMouseUp ) { rotating = false; mouse_X = event.mouseX; mouse_Y = event.mouseY; mouse_XPrevious = mouse_X; mouse_YPrevious = mouse_Y; canvasPixelWidth = event.canvasPixelWidth; canvasPixelHeight = event.canvasPixelHeight; releaseGrabbedBall(); action = NULL_ACTION; } } // generalMouseEventHandler.onEvent method runtime.addEventHandler( generalMouseEventHandler ); //------------------------------------------------------ function detectMouseOverBall() { var ball = -1; var cursorDirection = new Vector3( camera.getDirectionFromScreen( mouse_X, mouse_Y, canvasPixelWidth, canvasPixelHeight ) ); for (var i=0; i -SPAN ) && ( upExtent < SPAN ) && ( upExtent > -SPAN ) && ( frontExtent < SPAN ) && ( frontExtent > -SPAN )) { ballInside[ grabbedBall ] = true; } else { ballInside[ grabbedBall ] = false; } //-------------------------------- // keep this at the end //-------------------------------- grabbedBall = -1; } }//--------------------------------------------------------------- //------------------------------------------------------ function updateSquares( deltaTime ) { if ( squareResourceAdded ) { squareResourceModel[0].transform.setIdentity(); var shift = new Vector3( 0.0, 0.0, -130.0 ); squareResourceModel[0].transform.translateInPlace( shift ); squareResourceModel[0].transform.scaleInPlace( 4.0, 4.0, 4.0 ); squareResourceModel[0].transform.rotateAboutXInPlace( Math.PI * ONE_HALF ); } }//--------------------------------------------------------------- //------------------------------------------------------ function updateSticks( clock ) { for (var v=0; v 1.0 ) { f = 1.0; } ballVelocity[i].scaleInPlace( 1.0 - f ); //----------------------------------------------------------------------- // update position by velocity //----------------------------------------------------------------------- ballPosition[i].addInPlace( ballVelocity[i] ); //----------------------------------------------------------------------- // cube collisions //----------------------------------------------------------------------- updateCubeCollisions( i ); //----------------------------------------------------------------------- // other-ball collisions //----------------------------------------------------------------------- updateBallCollisions( i ); }//------------------------------------------------------ //------------------------------------------------------ function updateCubeCollisions( i ) { var centerToBall = new Vector3( ballPosition[i] ); centerToBall.subtractInPlace( cubePosition ); var rightExtent = centerToBall.dot( rotatedRight ); var upExtent = centerToBall.dot( rotatedUp ); var frontExtent = centerToBall.dot( rotatedFront ); if ( ballInside[i] ) { var minCollisionLimit = -SPAN + BALL_RADIUS; var maxCollisionLimit = SPAN - BALL_RADIUS; if ( rightExtent < minCollisionLimit ) { bounceOffFace( i, rightExtent, rotatedRight, minCollisionLimit ); } else if ( rightExtent > maxCollisionLimit ) { bounceOffFace( i, rightExtent, rotatedRight, maxCollisionLimit ); } if ( upExtent < minCollisionLimit ) { bounceOffFace( i, upExtent, rotatedUp, minCollisionLimit ); } else if ( upExtent > maxCollisionLimit ) { bounceOffFace( i, upExtent, rotatedUp, maxCollisionLimit ); } if ( frontExtent < minCollisionLimit ) { bounceOffFace( i, frontExtent, rotatedFront, minCollisionLimit ); } else if ( frontExtent > maxCollisionLimit ) { bounceOffFace( i, frontExtent, rotatedFront, maxCollisionLimit ); } } else //----------------------------------------------------------------------- // ball is outside! //----------------------------------------------------------------------- { var minCollisionLimit = -SPAN - BALL_RADIUS; var maxCollisionLimit = SPAN + BALL_RADIUS; //--------------------------------------------- // top //--------------------------------------------- if (( upExtent < SPAN + BALL_RADIUS ) && ( upExtent > SPAN )) { if (( rightExtent < SPAN ) && ( rightExtent > -SPAN ) && ( frontExtent < SPAN ) && ( frontExtent > -SPAN )) { bounceOffFace( i, upExtent, rotatedUp, maxCollisionLimit ); } } //--------------------------------------------- // bottom //--------------------------------------------- else if (( upExtent > -SPAN - BALL_RADIUS ) && ( upExtent < -SPAN )) { if (( rightExtent < SPAN ) && ( rightExtent > -SPAN ) && ( frontExtent < SPAN ) && ( frontExtent > -SPAN )) { bounceOffFace( i, upExtent, rotatedUp, minCollisionLimit ); } } //--------------------------------------------- // right //--------------------------------------------- if (( rightExtent < SPAN + BALL_RADIUS ) && ( rightExtent > SPAN )) { if (( upExtent < SPAN ) && ( upExtent > -SPAN ) && ( frontExtent < SPAN ) && ( frontExtent > -SPAN )) { bounceOffFace( i, rightExtent, rotatedRight, maxCollisionLimit ); } } //--------------------------------------------- // left //--------------------------------------------- else if (( rightExtent > -SPAN - BALL_RADIUS ) && ( rightExtent < -SPAN )) { if (( upExtent < SPAN ) && ( upExtent > -SPAN ) && ( frontExtent < SPAN ) && ( frontExtent > -SPAN )) { bounceOffFace( i, rightExtent, rotatedRight, minCollisionLimit ); } } //--------------------------------------------- // front //--------------------------------------------- if (( frontExtent < SPAN + BALL_RADIUS ) && ( frontExtent > SPAN )) { if (( upExtent < SPAN ) && ( upExtent > -SPAN ) && ( rightExtent < SPAN ) && ( rightExtent > -SPAN )) { bounceOffFace( i, frontExtent, rotatedFront, maxCollisionLimit ); } } //--------------------------------------------- // back //--------------------------------------------- else if (( frontExtent > -SPAN - BALL_RADIUS ) && ( frontExtent < -SPAN )) { if (( upExtent < SPAN ) && ( upExtent > -SPAN ) && ( rightExtent < SPAN ) && ( rightExtent > -SPAN )) { bounceOffFace( i, frontExtent, rotatedFront, minCollisionLimit ); } } } }//------------------------------------------------------ //----------------------------------------------------------------- function bounceOffFace( i, extent, directionVector, limit ) { var componentOfVelocity = ballVelocity[i].dot( directionVector ); var bounceForce = new Vector3( directionVector ); bounceForce.scaleInPlace( -( componentOfVelocity + componentOfVelocity * BOUNCE ) ); ballVelocity[i].addInPlace( bounceForce ); ballPosition[i].addScaledInPlace( directionVector, ( limit - extent ) ); }//------------------------------------------------------ //------------------------------------------------------ function updateBallCollisions( i ) { for (var o=i+1; o 0.00001 ) { var f = new Vector3(); f.set( v ); f.scaleInPlace( 1 / distance ); f.scaleInPlace( BALL_TO_BALL_COLLISION_FORCE ); ballVelocity[o].scaleInPlace( 1.0 - BALL_TO_BALL_COLLISION_FRICTION ); ballVelocity[i].scaleInPlace( 1.0 - BALL_TO_BALL_COLLISION_FRICTION ); ballVelocity[o].addInPlace ( f ); ballVelocity[i].subtractInPlace( f ); } } } }//------------------------------------------------------ //------------------------------------------------------ function showBall( index, position, radius ) { if (( ballResourceAdded ) && ( index < numBallResourceModels )) { //------------------------------------------------------------ // set to identity //------------------------------------------------------------ ballResourceModel[ index ].transform.setIdentity(); //------------------------------------------------------------ // scale //------------------------------------------------------------ var scaleMatrix = new Matrix4x4(); scaleMatrix.setIdentity(); scaleMatrix.scaleInPlace( radius / 10.0, radius / 10.0, radius / 10.0); ballResourceModel[ index ].transform.multiplyInPlace( scaleMatrix ); //------------------------------------------------------------ // translate //------------------------------------------------------------ var translationMatrix = new Matrix4x4(); translationMatrix.setIdentity(); translationMatrix.translateInPlace( position ); ballResourceModel[ index ].transform.multiplyInPlace( translationMatrix ); } //if ( ballResourceAdded ) }//------------------------------------------------------ //------------------------------------------------------------------------- function addStickResource( resourceName, modelFileName, imageFileName, howMany ) { var kindOfResource = "stick"; success = addResource( resourceName, modelFileName, imageFileName, howMany, kindOfResource ); if ( success ) { stickResourceAdded = true; } }//--------------------------------------------------------------------- //------------------------------------------------------------------------- function addSquareResource( resourceName, modelFileName, imageFileName, howMany ) { var kindOfResource = "square"; success = addResource( resourceName, modelFileName, imageFileName, howMany, kindOfResource ); if ( success ) { squareResourceAdded = true; } }//--------------------------------------------------------------------- //------------------------------------------------------------------------- function addBallResource( resourceName, modelFileName, imageFileName, howMany ) { var kindOfResource = "ball"; success = addResource( resourceName, modelFileName, imageFileName, howMany, kindOfResource ); if ( success ) { ballResourceAdded = true; } arrangeBallsOrderlyInCube( howMany ); }//--------------------------------------------------------------------- //------------------------------------------------------------------------- function dynamicallyAddBall() { success = addResource( "balls", "hi_res_sphere.u3d", "blue_gray.jpg", 1, "ball"); arrangeBallsRandomlyInCube(numBallResourceModels-1, 1); }//--------------------------------------------------------------------- //------------------------------------------------------------------------- function arrangeBallsRandomlyInCube( startIndex, howMany ) { for ( var i=startIndex; i<(howMany + startIndex); i++) { var x = -SPAN + BALL_RADIUS + Math.random() * ( SPAN * 2.0 - BALL_RADIUS ); var y = -SPAN + BALL_RADIUS + Math.random() * ( SPAN * 2.0 - BALL_RADIUS ); var z = -SPAN + BALL_RADIUS + Math.random() * ( SPAN * 2.0 - BALL_RADIUS ); ballPosition[i].set3( x, y, z ); ballInside [i] = true; ballVelocity[i].set3( 0.0, 0.0, 0.0 ); } }//--------------------------------------------------------------------- //------------------------------------------------------------------------- function arrangeBallsOrderlyInCube( howMany ) { for ( var i=0; i MAX_RESOURCE_MODELS ) { console.println( " "); console.print ( "Oops - I cannot create more than " + MAX_RESOURCE_MODELS + " resource models. "); console.println( "You asked me to create " + howMany + ". I will only generate " + MAX_RESOURCE_MODELS + " of them." ); numResourceModels = MAX_RESOURCE_MODELS - numBallResourceModels; } var extendedModelFileName = "pdf://" + modelFileName; var extendedImageFileName = "pdf://" + imageFileName; var modelResource = new Resource( extendedModelFileName ); if ( modelResource.valid ) { var position = new Vector3(); //---------------------------------------------------------------------------------------- if ( verbose ) console.println( " " ); if ( verbose ) console.print( "* adding " + numResourceModels + " models..." ); for (var i=0; i