/*{{ javascript("jslib/camera.js") }}*/
/*{{ javascript("jslib/floor.js") }}*/
/*{{ javascript("jslib/mouseforces.js") }}*/
/*{{ javascript("jslib/observer.js") }}*/
/*{{ javascript("jslib/utilities.js") }}*/
/*{{ javascript("jslib/requesthandler.js") }}*/
/*{{ javascript("jslib/services/turbulenzservices.js") }}*/
/*{{ javascript("jslib/services/turbulenzbridge.js") }}*/
/*{{ javascript("jslib/services/gamesession.js") }}*/
/*{{ javascript("jslib/services/mappingtable.js") }}*/
/*{{ javascript("scripts/htmlcontrols.js") }}*/
/*global TurbulenzEngine: true */
/*global RequestHandler: false */
/*global window: false */
/*global Camera: false */
/*global CameraController: false */
/*global Floor: false */
/*global RequestHandler: false */
/*global HTMLControls: false */
/*global MouseForces: false */
/*global TurbulenzServices: false */
TurbulenzEngine.onload = function onloadFn() {
var errorCallback = function errorCallback(msg) {
window.alert(msg);
};
var graphicsDeviceParameters = {
};
var graphicsDevice = TurbulenzEngine.createGraphicsDevice(graphicsDeviceParameters);
if(!graphicsDevice.shadingLanguageVersion) {
errorCallback("No shading language support detected.\nPlease check your graphics drivers are up to date.");
graphicsDevice = null;
return;
}
var mathDeviceParameters = {
};
var mathDevice = TurbulenzEngine.createMathDevice(mathDeviceParameters);
var inputDeviceParameters = {
};
var inputDevice = TurbulenzEngine.createInputDevice(inputDeviceParameters);
var assetsToLoad = 3;
// Setup camera & controller
var camera = Camera.create(mathDevice);
var cameraInitialize = function cameraInitializeFn() {
var worldUp = mathDevice.v3BuildYAxis();
camera.lookAt(worldUp, worldUp, mathDevice.v3Build(0.0, 3.0, -15.0));
camera.updateViewMatrix();
};
cameraInitialize();
var cameraController = CameraController.create(graphicsDevice, inputDevice, camera);
var floor = Floor.create(graphicsDevice, mathDevice);
var requestHandlerParameters = {
};
var requestHandler = RequestHandler.create(requestHandlerParameters);
var shader3d = null;
var technique3d = null;
var shader3dLoaded = function shader3dLoadedFn(shaderText) {
if(shaderText) {
var shaderParameters = JSON.parse(shaderText);
shader3d = graphicsDevice.createShader(shaderParameters);
if(shader3d) {
technique3d = shader3d.getTechnique("textured3D");
assetsToLoad -= 1;
}
}
};
var sharedTechniqueParameters = graphicsDevice.createTechniqueParameters({
diffuse: null
});
/*jshint white: false*/
// Vertex buffer parameters for crate
var vertexbufferParameters = {
numVertices: 24,
attributes: [
'FLOAT3',
'SHORT2'
],
dynamic: false,
data: [
-0.5,
-0.5,
0.5,
0,
0,
0.5,
-0.5,
0.5,
1,
0,
0.5,
0.5,
0.5,
1,
1,
-0.5,
0.5,
0.5,
0,
1,
-0.5,
0.5,
0.5,
0,
0,
0.5,
0.5,
0.5,
1,
0,
0.5,
0.5,
-0.5,
1,
1,
-0.5,
0.5,
-0.5,
0,
1,
-0.5,
0.5,
-0.5,
1,
1,
0.5,
0.5,
-0.5,
0,
1,
0.5,
-0.5,
-0.5,
0,
0,
-0.5,
-0.5,
-0.5,
1,
0,
-0.5,
-0.5,
-0.5,
0,
0,
0.5,
-0.5,
-0.5,
1,
0,
0.5,
-0.5,
0.5,
1,
1,
-0.5,
-0.5,
0.5,
0,
1,
0.5,
-0.5,
0.5,
0,
0,
0.5,
-0.5,
-0.5,
1,
0,
0.5,
0.5,
-0.5,
1,
1,
0.5,
0.5,
0.5,
0,
1,
-0.5,
-0.5,
-0.5,
0,
0,
-0.5,
-0.5,
0.5,
1,
0,
-0.5,
0.5,
0.5,
1,
1,
-0.5,
0.5,
-0.5,
0,
1
]
};
/*jshint white: true*/
var vertexbuffer = graphicsDevice.createVertexBuffer(vertexbufferParameters);
var semantics = graphicsDevice.createSemantics([
graphicsDevice.SEMANTIC_POSITION,
graphicsDevice.SEMANTIC_TEXCOORD
]);
/*jshint white: false*/
var indexbufferParameters = {
numIndices: 36,
format: 'USHORT',
dynamic: false,
data: [
2,
0,
1,
3,
0,
2,
6,
4,
5,
7,
4,
6,
10,
8,
9,
11,
8,
10,
14,
12,
13,
15,
12,
14,
18,
16,
17,
19,
16,
18,
22,
20,
21,
23,
20,
22
]
};
/*jshint white: true*/
var indexbuffer = graphicsDevice.createIndexBuffer(indexbufferParameters);
var primitive = graphicsDevice.PRIMITIVE_TRIANGLES;
var numIndices = 36;
// Cache mathDevice functions
var m43MulM44 = mathDevice.m43MulM44;
var isVisibleBoxOrigin = mathDevice.isVisibleBoxOrigin;
var v4Build = mathDevice.v4Build;
var m43BuildTranslation = mathDevice.m43BuildTranslation;
var shader2d = null;
var technique2d = null;
var shader2dLoaded = function shader2dLoadedFn(shaderText) {
if(shaderText) {
var shaderParameters = JSON.parse(shaderText);
shader2d = graphicsDevice.createShader(shaderParameters);
if(shader2d) {
technique2d = shader2d.getTechnique("constantColor2D");
assetsToLoad -= 1;
}
}
};
var techniqueParameters2d = graphicsDevice.createTechniqueParameters({
clipSpace: null,
constantColor: mathDevice.v4Build(0, 0, 0, 1)
});
var linePrim = graphicsDevice.PRIMITIVE_LINES;
var cursorFormat = [
graphicsDevice.VERTEXFORMAT_FLOAT3
];
var cursorSemantic = graphicsDevice.createSemantics([
graphicsDevice.SEMANTIC_POSITION
]);
var clearColor = mathDevice.v4Build(0.95, 0.95, 1.0, 1.0);
//
// Physics
//
var physicsDeviceParameters = {
};
var physicsDevice = TurbulenzEngine.createPhysicsDevice(physicsDeviceParameters);
var dynamicsWorldParameters = {
};
var dynamicsWorld = physicsDevice.createDynamicsWorld(dynamicsWorldParameters);
// Specify the generic settings for the collision objects
var collisionMargin = 0.005;
var mass = 20.0;
var cubeExtents = mathDevice.v3Build(0.5, 0.5, 0.5);
// Floor is represented by a plane
var floorShape = physicsDevice.createPlaneShape({
normal: mathDevice.v3Build(0, 1, 0),
distance: 0,
margin: collisionMargin
});
var floorObject = physicsDevice.createCollisionObject({
shape: floorShape,
transform: mathDevice.m43BuildIdentity(),
friction: 0.5,
restitution: 0.3,
group: physicsDevice.FILTER_STATIC,
mask: physicsDevice.FILTER_ALL
});
// Adds the floor collision object to the physicsDevice
dynamicsWorld.addCollisionObject(floorObject);
var boxShape = physicsDevice.createBoxShape({
halfExtents: cubeExtents,
margin: collisionMargin
});
var inertia = boxShape.inertia;
inertia = mathDevice.v3ScalarMul(inertia, mass);
var boxBody = physicsDevice.createRigidBody({
shape: boxShape,
mass: mass,
inertia: inertia,
transform: mathDevice.m43BuildTranslation(0.0, 1.0, 0.0),
friction: 0.5,
restitution: 0.3,
angularDamping: 0.9,
frozen: false
});
dynamicsWorld.addRigidBody(boxBody);
var doReset = false;
var reset = function resetFn() {
var transform = mathDevice.m43BuildIdentity();
var v3Zero = mathDevice.v3BuildZero();
var body = boxBody;
body.transform = mathDevice.m43BuildTranslation(0.0, 1.0, 0.0, transform);
body.linearVelocity = v3Zero;
body.angularVelocity = v3Zero;
body.active = true;
cameraInitialize();
};
// Controls
var htmlControls = HTMLControls.create();
htmlControls.addButtonControl({
id: "button01",
value: "Reset",
fn: function schedulResetFn() {
doReset = true;
}
});
htmlControls.register();
var keyCodes = inputDevice.keyCodes;
var mouseCodes = inputDevice.mouseCodes;
var onKeyUp = function physicsOnkeyupFn(keynum) {
// If the key R is released we reset the positions
if(keynum === keyCodes.R) {
reset();
}
};
// Mouse forces
var dragMin = mathDevice.v3Build(-1000, 0, -1000);
var dragMax = mathDevice.v3Build(1000, 1000, 1000);
var mouseForces = MouseForces.create(graphicsDevice, inputDevice, mathDevice, physicsDevice, dragMin, dragMax);
var onMouseDown = function (button) {
if(mouseCodes.BUTTON_0 === button || mouseCodes.BUTTON_1 === button) {
mouseForces.onmousedown();
}
};
var onMouseUp = function (button) {
if(mouseCodes.BUTTON_0 === button || mouseCodes.BUTTON_1 === button) {
mouseForces.onmouseup();
}
};
// Add event listeners
inputDevice.addEventListener("keyup", onKeyUp);
inputDevice.addEventListener("mousedown", onMouseDown);
inputDevice.addEventListener("mouseup", onMouseUp);
//
// Update
//
var update = function updateFn() {
inputDevice.update();
if(doReset) {
reset();
doReset = false;
}
if(mouseForces.pickedBody) {
// If we're dragging a body don't apply the movement to the camera
cameraController.pitch = 0;
cameraController.turn = 0;
cameraController.step = 0;
}
cameraController.update();
var aspectRatio = (graphicsDevice.width / graphicsDevice.height);
if(aspectRatio !== camera.aspectRatio) {
camera.aspectRatio = aspectRatio;
camera.updateProjectionMatrix();
}
camera.updateViewProjectionMatrix();
if(0 >= assetsToLoad) {
mouseForces.update(dynamicsWorld, camera, 0.1);
dynamicsWorld.update();
}
var vp = camera.viewProjectionMatrix;
var transform = mathDevice.m43BuildIdentity();
var wvp;
if(graphicsDevice.beginFrame()) {
graphicsDevice.clear(clearColor, 1.0, 0);
floor.render(graphicsDevice, camera);
if(0 >= assetsToLoad) {
graphicsDevice.setStream(vertexbuffer, semantics);
graphicsDevice.setIndexBuffer(indexbuffer);
graphicsDevice.setTechnique(technique3d);
graphicsDevice.setTechniqueParameters(sharedTechniqueParameters);
boxBody.calculateTransform(transform);
wvp = m43MulM44.call(mathDevice, transform, vp, wvp);
if(isVisibleBoxOrigin.call(mathDevice, cubeExtents, wvp)) {
// Use directly the active technique when just a single property changes
technique3d.worldViewProjection = wvp;
graphicsDevice.drawIndexed(primitive, numIndices);
}
if(!mouseForces.pickedBody) {
graphicsDevice.setTechnique(technique2d);
var screenWidth = graphicsDevice.width;
var screenHeight = graphicsDevice.height;
techniqueParameters2d['clipSpace'] = v4Build.call(mathDevice, 2.0 / screenWidth, -2.0 / screenHeight, -1.0, 1.0);
graphicsDevice.setTechniqueParameters(techniqueParameters2d);
var writer = graphicsDevice.beginDraw(linePrim, 4, cursorFormat, cursorSemantic);
if(writer) {
var halfWidth = screenWidth * 0.5;
var halfHeight = screenHeight * 0.5;
writer([
halfWidth - 10,
halfHeight
]);
writer([
halfWidth + 10,
halfHeight
]);
writer([
halfWidth,
halfHeight - 10
]);
writer([
halfWidth,
halfHeight + 10
]);
graphicsDevice.endDraw(writer);
}
}
}
graphicsDevice.endFrame();
}
};
var intervalID = TurbulenzEngine.setInterval(update, 1000 / 60);
var mappingTableReceived = function mappingTableReceivedFn(mappingTable) {
var textureParameters = {
src: mappingTable.getURL("textures/crate.jpg"),
mipmaps: true,
onload: function (texture) {
sharedTechniqueParameters['diffuse'] = texture;
assetsToLoad -= 1;
}
};
graphicsDevice.createTexture(textureParameters);
requestHandler.request({
src: mappingTable.getURL("shaders/generic3D.cgfx"),
onload: shader3dLoaded
});
requestHandler.request({
src: mappingTable.getURL("shaders/generic2D.cgfx"),
onload: shader2dLoaded
});
};
var gameSessionCreated = function gameSessionCreatedFn(gameSession) {
TurbulenzServices.createMappingTable(requestHandler, gameSession, mappingTableReceived);
};
var gameSession = TurbulenzServices.createGameSession(requestHandler, gameSessionCreated);
TurbulenzEngine.onunload = function destroyScene() {
TurbulenzEngine.clearInterval(intervalID);
if(gameSession) {
gameSession.destroy();
gameSession = null;
}
requestHandler = null;
indexbuffer = null;
vertexbuffer = null;
semantics = null;
cursorSemantic = null;
primitive = null;
linePrim = null;
technique3d = null;
shader3d = null;
technique2d = null;
shader2d = null;
techniqueParameters2d = null;
sharedTechniqueParameters = null;
mouseForces = null;
floor = null;
cameraController = null;
camera = null;
boxBodies = null;
inertia = null;
clearColor = null;
m43MulM44 = null;
m43BuildTranslation = null;
isVisibleBoxOrigin = null;
v4Build = null;
dragMax = null;
dragMin = null;
mouseCodes = null;
keyCodes = null;
TurbulenzEngine.flush();
physicsDevice = null;
inputDevice = null;
graphicsDevice = null;
mathDevice = null;
};
};