2016-10-28 11:50:55 +02:00
|
|
|
if (typeof GameLib == 'undefined') {
|
|
|
|
function GameLib() {}
|
2016-09-30 14:21:53 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof GameLib.D3 == 'undefined') {
|
|
|
|
GameLib.D3 = function(){};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof Q == 'undefined') {
|
|
|
|
if (typeof require == 'undefined') {
|
|
|
|
console.warn('You need the Q promise library for the GameLib.D3');
|
|
|
|
throw new Error('You need the Q promise library for the GameLib.D3');
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var Q = require('q');
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* BoneWeight object - associates a vertex to a bone with some weight
|
|
|
|
* @param boneIndex int
|
|
|
|
* @param weight float
|
2016-09-30 13:55:21 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.BoneWeight = function(
|
|
|
|
boneIndex,
|
|
|
|
weight
|
|
|
|
) {
|
|
|
|
this.boneIndex = boneIndex;
|
|
|
|
this.weight = weight;
|
2016-09-30 13:55:21 +02:00
|
|
|
};
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Bone Superset
|
2016-09-30 13:55:21 +02:00
|
|
|
* @param id
|
2016-10-28 11:50:55 +02:00
|
|
|
* @param name string
|
|
|
|
* @param boneId
|
|
|
|
* @param childBoneIds
|
|
|
|
* @param parentBoneId
|
|
|
|
* @param quaternion
|
|
|
|
* @param position
|
|
|
|
* @param rotation
|
|
|
|
* @param scale GameLib.D3.Vector3
|
|
|
|
* @param up
|
2016-09-30 13:55:21 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Bone = function(
|
2016-09-30 13:55:21 +02:00
|
|
|
id,
|
2016-10-28 11:50:55 +02:00
|
|
|
boneId,
|
2016-09-30 13:55:21 +02:00
|
|
|
name,
|
2016-10-28 11:50:55 +02:00
|
|
|
childBoneIds,
|
|
|
|
parentBoneId,
|
|
|
|
quaternion,
|
|
|
|
position,
|
|
|
|
rotation,
|
|
|
|
scale,
|
|
|
|
up
|
2016-09-30 13:55:21 +02:00
|
|
|
) {
|
|
|
|
this.id = id;
|
|
|
|
this.name = name;
|
2016-10-28 11:50:55 +02:00
|
|
|
this.boneId = boneId;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof childBoneIds == 'undefined') {
|
|
|
|
childBoneIds = [];
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.childBoneIds = childBoneIds;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof parentBoneId == 'undefined') {
|
|
|
|
parentBoneId = null;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.parentBoneId = parentBoneId;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof quaternion == 'undefined') {
|
|
|
|
quaternion = new GameLib.D3.Vector4();
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.quaternion = quaternion;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof position == 'undefined') {
|
|
|
|
position = new GameLib.D3.Vector3(0,0,0);
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.position = position;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof rotation == 'undefined') {
|
|
|
|
rotation = new GameLib.D3.Vector3(0,0,0);
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.rotation = rotation;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof scale == 'undefined') {
|
|
|
|
scale = new GameLib.D3.Vector3(1,1,1);
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.scale = scale;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof up == 'undefined') {
|
|
|
|
up = new GameLib.D3.Vector3(0,1,0);
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.up = up;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* Physics Broadphase Superset
|
|
|
|
* @param id
|
|
|
|
* @param name String
|
|
|
|
* @param broadphaseType Number
|
|
|
|
* @param engine GameLib.D3.Engine
|
|
|
|
* @param createInstance Boolean
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Broadphase = function(
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
broadphaseType,
|
|
|
|
engine,
|
|
|
|
createInstance
|
|
|
|
) {
|
|
|
|
this.id = id;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof name == 'undefined') {
|
|
|
|
name = 'broadphase-' + broadphaseType;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.name = name;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof broadphaseType == 'undefined') {
|
|
|
|
broadphaseType = GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.broadphaseType = broadphaseType;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof engine == 'undefined') {
|
|
|
|
engine = null;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.engine = engine;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.instance = null;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (createInstance) {
|
|
|
|
this.createInstance();
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Creates a custom Broadphase instance based on the engine type
|
|
|
|
*/
|
|
|
|
GameLib.D3.Broadphase.prototype.createInstance = function() {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (!(this.engine instanceof GameLib.D3.Engine)) {
|
|
|
|
console.warn('No Engine');
|
|
|
|
throw new Error('No Engine');
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.engine.isNotCannonThrow();
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var instance = null;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) {
|
|
|
|
instance = new this.engine.instance.NaiveBroadphase();
|
|
|
|
} else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID) {
|
|
|
|
instance = new this.engine.instance.GridBroadphase();
|
|
|
|
} else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP) {
|
|
|
|
instance = new this.engine.instance.SAPBroardphase();
|
|
|
|
} else {
|
|
|
|
console.warn('Unsupported broadphase type: ' + this.broadphaseType);
|
|
|
|
throw new Error('Unsupported broadphase type: ' + this.broadphaseType);
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
|
|
|
|
this.instance = instance;
|
|
|
|
|
|
|
|
return instance;
|
2016-09-30 13:55:21 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Broadphase Types
|
2016-09-30 13:55:21 +02:00
|
|
|
* @type {number}
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE = 0x1;
|
|
|
|
GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID = 0x2;
|
|
|
|
GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP = 0x3;
|
|
|
|
/**
|
|
|
|
* Color Superset
|
|
|
|
* @param r
|
|
|
|
* @param g
|
|
|
|
* @param b
|
|
|
|
* @param a
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Color = function(r, g, b, a) {
|
|
|
|
this.r = r;
|
|
|
|
this.g = g;
|
|
|
|
this.b = b;
|
|
|
|
this.a = a;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* Engine Superset
|
|
|
|
* @param engineType
|
|
|
|
* @param instance {CANNON | Ammo | Goblin}
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Engine = function(
|
|
|
|
engineType,
|
|
|
|
instance
|
|
|
|
) {
|
|
|
|
this.engineType = engineType;
|
|
|
|
this.instance = instance;
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* True if CANNON physics
|
|
|
|
* @returns {boolean}
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Engine.prototype.isCannon = function() {
|
|
|
|
return (this.engineType == GameLib.D3.Engine.ENGINE_TYPE_CANNON)
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Logs a warning and throws an error if not cannon
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Engine.prototype.isNotCannonThrow = function() {
|
|
|
|
if (this.engineType != GameLib.D3.Engine.ENGINE_TYPE_CANNON) {
|
|
|
|
console.warn('Only CANNON supported for this function');
|
|
|
|
throw new Error('Only CANNON supported for this function');
|
|
|
|
}
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* True if Ammo physics
|
|
|
|
* @returns {boolean}
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Engine.prototype.isAmmo = function() {
|
|
|
|
return (this.engineType == GameLib.D3.Engine.ENGINE_TYPE_AMMO)
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* True if Goblin physics
|
|
|
|
* @returns {boolean}
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Engine.prototype.isGoblin = function() {
|
|
|
|
return (this.engineType == GameLib.D3.Engine.ENGINE_TYPE_GOBLIN)
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Physics GameLib.D3.Engine Types
|
2016-09-30 13:55:21 +02:00
|
|
|
* @type {number}
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Engine.ENGINE_TYPE_CANNON = 0x1;
|
|
|
|
GameLib.D3.Engine.ENGINE_TYPE_AMMO = 0x2;
|
|
|
|
GameLib.D3.Engine.ENGINE_TYPE_GOBLIN = 0x3;
|
2016-09-30 13:55:21 +02:00
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Fly Controls
|
|
|
|
* @param camera
|
|
|
|
* @param THREE
|
|
|
|
* @param canvas
|
2016-09-30 13:55:21 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.FlyControls = function(
|
|
|
|
camera,
|
|
|
|
THREE,
|
|
|
|
canvas
|
2016-09-30 13:55:21 +02:00
|
|
|
) {
|
2016-10-28 11:50:55 +02:00
|
|
|
this.flySpeed = 100;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.canvas = canvas;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.THREE = THREE;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.yaw = 0;
|
|
|
|
this.pitch = 0;
|
|
|
|
this.canRotate = false;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.moveForward = false;
|
|
|
|
this.moveBackward = false;
|
|
|
|
this.moveLeft = false;
|
|
|
|
this.moveRight = false;
|
|
|
|
this.moveUp = false;
|
|
|
|
this.moveDown = false;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.mouseUpCallback = this.onMouseUp.bind(this);
|
|
|
|
this.mouseDownCallback = this.onMouseDown.bind(this);
|
|
|
|
this.mouseMoveCallback = this.onMouseMove.bind(this);
|
|
|
|
this.mouseWheelCallback = this.onMouseWheel.bind(this);
|
|
|
|
this.keyDownCallback = this.onKeyDown.bind(this);
|
|
|
|
this.keyUpCallback = this.onKeyUp.bind(this);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.camera = camera;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.canvas.addEventListener('keydown', this.keyDownCallback, false);
|
|
|
|
this.canvas.addEventListener('keyup', this.keyUpCallback, false);
|
|
|
|
this.canvas.addEventListener('mousedown', this.mouseDownCallback, false);
|
|
|
|
this.canvas.addEventListener('mouseup', this.mouseUpCallback, false);
|
|
|
|
this.canvas.addEventListener('mousewheel', this.mouseWheelCallback, false);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;
|
|
|
|
this.element = document.body;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (this.havePointerLock) {
|
|
|
|
this.element.requestPointerLock = this.element.requestPointerLock || this.element.mozRequestPointerLock || this.element.webkitRequestPointerLock;
|
|
|
|
document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Go forward / backward on mouse wheel
|
|
|
|
* @param event
|
|
|
|
*/
|
|
|
|
GameLib.D3.FlyControls.prototype.onMouseWheel = function(event) {
|
|
|
|
this.moveForward = true;
|
|
|
|
this.applyTranslation(event.wheelDelta * 0.001);
|
|
|
|
event.preventDefault();
|
|
|
|
this.moveForward = false;
|
2016-09-30 13:55:21 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Start rotating the camera on mouse middle button down
|
|
|
|
* @param event
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.FlyControls.prototype.onMouseDown = function(event) {
|
|
|
|
if (event.button == 1) {
|
|
|
|
this.canRotate = true;
|
|
|
|
this.canvas.addEventListener('mousemove', this.mouseMoveCallback, false);
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Stop rotating on middle mouse button down
|
|
|
|
* @param event
|
|
|
|
*/
|
|
|
|
GameLib.D3.FlyControls.prototype.onMouseUp = function(event) {
|
|
|
|
if (event.button == 1) {
|
|
|
|
this.canRotate = false;
|
|
|
|
this.canvas.removeEventListener('mousemove', this.mouseMoveCallback);
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Apply current yaw and pitch to camera
|
|
|
|
*/
|
|
|
|
GameLib.D3.FlyControls.prototype.applyRotation = function() {
|
|
|
|
this.camera.rotation.set(this.pitch, this.yaw, 0, "YXZ");
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Apply current position to camera
|
|
|
|
* @param deltaTime
|
|
|
|
*/
|
|
|
|
GameLib.D3.FlyControls.prototype.applyTranslation = function(deltaTime) {
|
|
|
|
var direction = new this.THREE.Vector3(0, 0, -1);
|
|
|
|
var rotation = new this.THREE.Euler(0, 0, 0, "YXZ");
|
|
|
|
rotation.set(this.pitch, this.yaw, 0, "YXZ");
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
direction = direction.applyEuler(rotation);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var forward = direction.normalize();
|
|
|
|
var right = forward.cross(new this.THREE.Vector3(0, 1, 0));
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if(this.moveForward) {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.camera.position.x += forward.x * (deltaTime * this.flySpeed);
|
|
|
|
this.camera.position.y += forward.y * (deltaTime * this.flySpeed);
|
|
|
|
this.camera.position.z += forward.z * (deltaTime * this.flySpeed);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
} else if(this.moveBackward) {
|
|
|
|
|
|
|
|
this.camera.position.x -= forward.x * (deltaTime * this.flySpeed);
|
|
|
|
this.camera.position.y -= forward.y * (deltaTime * this.flySpeed);
|
|
|
|
this.camera.position.z -= forward.z * (deltaTime * this.flySpeed);
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if(this.moveLeft) {
|
|
|
|
|
|
|
|
this.camera.position.x -= right.x * (deltaTime * this.flySpeed);
|
|
|
|
this.camera.position.y -= right.y * (deltaTime * this.flySpeed);
|
|
|
|
this.camera.position.z -= right.z * (deltaTime * this.flySpeed);
|
|
|
|
|
|
|
|
} else if(this.moveRight) {
|
|
|
|
|
|
|
|
this.camera.position.x += right.x * (deltaTime * this.flySpeed);
|
|
|
|
this.camera.position.y += right.y * (deltaTime * this.flySpeed);
|
|
|
|
this.camera.position.z += right.z * (deltaTime * this.flySpeed);
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if(this.moveUp) {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.camera.position.y += (deltaTime * this.flySpeed);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
} else if(this.moveDown) {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.camera.position.y -= (deltaTime * this.flySpeed);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* This update function should be called from the animation function in order to apply the 'frame rate independent'
|
|
|
|
* movement to the camera
|
|
|
|
* @param deltaTime
|
|
|
|
*/
|
|
|
|
GameLib.D3.FlyControls.prototype.update = function(deltaTime) {
|
|
|
|
this.applyRotation();
|
|
|
|
this.applyTranslation(deltaTime);
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Rotate on mouse move
|
|
|
|
* @param event
|
|
|
|
*/
|
|
|
|
GameLib.D3.FlyControls.prototype.onMouseMove = function ( event ) {
|
|
|
|
if (this.canRotate) {
|
|
|
|
var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
|
|
|
|
var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.yaw -= movementX * 0.002;
|
|
|
|
this.pitch -= movementY * 0.002;
|
2016-09-30 12:56:58 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Keyboard controls
|
|
|
|
* @param event
|
|
|
|
*/
|
|
|
|
GameLib.D3.FlyControls.prototype.onKeyDown = function ( event ) {
|
|
|
|
switch ( event.keyCode ) {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 87: // w
|
|
|
|
this.moveForward = true;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 65: // a
|
|
|
|
this.moveLeft = true;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 83: // s
|
|
|
|
this.moveBackward = true;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 68: // d
|
|
|
|
this.moveRight = true;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 104: // keypad up arrow
|
|
|
|
this.moveUp = true;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 98: // keypad down arrow
|
|
|
|
this.moveDown = true;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Keyboard controls
|
|
|
|
* @param event
|
|
|
|
*/
|
|
|
|
GameLib.D3.FlyControls.prototype.onKeyUp = function ( event ) {
|
|
|
|
switch ( event.keyCode ) {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 38: // up
|
|
|
|
case 87: // w
|
|
|
|
this.moveForward = false;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 37: // left
|
|
|
|
case 65: // a
|
|
|
|
this.moveLeft = false;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 40: // down
|
|
|
|
case 83: // s
|
|
|
|
this.moveBackward = false;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 39: // right
|
|
|
|
case 68: // d
|
|
|
|
this.moveRight = false;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 104: // keypad up arrow
|
|
|
|
this.moveUp = false;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
case 98: // keypad down arrow
|
|
|
|
this.moveDown = false;
|
|
|
|
break;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
|
|
|
GameLib.D3.Game = function (
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
) {
|
|
|
|
this.scenes = {};
|
|
|
|
this.physicsWorlds = [];
|
|
|
|
this.sceneToPhysicsWorldsMap = {};
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Game.prototype.AddScene = function(
|
|
|
|
scene
|
|
|
|
) {
|
|
|
|
this.scenes[scene.name] = scene;
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Game.prototype.AddPhysicsWorld = function(
|
|
|
|
physicsWorld
|
|
|
|
) {
|
|
|
|
this.physicsWorlds.push(physicsWorld);
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Game.prototype.LinkPhysicsWorldToScene = function(
|
|
|
|
physicsWorld,
|
|
|
|
scene
|
|
|
|
) {
|
|
|
|
this.sceneToPhysicsWorldsMap[scene.name] = this.sceneToPhysicsWorldsMap[scene.name] || [];
|
|
|
|
this.sceneToPhysicsWorldsMap[scene.name].push(physicsWorld);
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Game.prototype.GetPhysicsWorldsForScene = function (
|
|
|
|
scene
|
|
|
|
) {
|
|
|
|
return this.sceneToPhysicsWorldsMap[scene.name];
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Game.prototype.ProcessPhysics = function (
|
|
|
|
timestep
|
|
|
|
) {
|
|
|
|
for(var s in this.sceneToPhysicsWorldsMap) {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var physicsWorldArray = this.sceneToPhysicsWorldsMap[s];
|
|
|
|
var scene = this.scenes[s];
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if(scene && physicsWorldArray) {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for(var i = 0, l = physicsWorldArray.length; i < l; i++) {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var physicsWorld = physicsWorldArray[i];
|
|
|
|
physicsWorld.Step(timestep);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for(var p in physicsWorld.linkedPairs) {
|
|
|
|
var pair = physicsWorld.linkedPairs[p];
|
|
|
|
var mesh = pair.threeMesh;
|
|
|
|
var body = pair.physicsBody;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if(mesh) {
|
|
|
|
if(physicsWorld.engineType === GameLib.D3.Physics.TYPE_CANNON) {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var quaternion = new THREE.Quaternion();
|
|
|
|
quaternion.copy(body.rigidBodyInstance.quaternion);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var quaternionCopy = quaternion.clone();
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var position = new THREE.Vector3();
|
|
|
|
position.copy(body.rigidBodyInstance.position);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if(mesh.permutate) {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if(mesh.permutate.offset) {
|
|
|
|
if(mesh.permutate.offset.quaternion) {
|
|
|
|
var offsetQuaternion = new THREE.Quaternion();
|
|
|
|
offsetQuaternion.copy(mesh.permutate.offset.quaternion);
|
|
|
|
quaternion = quaternion.multiply(offsetQuaternion).normalize();
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if(mesh.permutate.offset.position) {
|
|
|
|
var offsetPosition = new THREE.Vector3();
|
|
|
|
offsetPosition.copy(mesh.permutate.offset.position);
|
|
|
|
//position = position.add(offsetPosition);
|
|
|
|
position = position.add(offsetPosition.applyQuaternion(quaternionCopy));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
mesh.position.copy(position);
|
|
|
|
mesh.quaternion.copy(quaternion);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Game.prototype.LinkPair = function (
|
|
|
|
threeMesh,
|
|
|
|
physicsBody,
|
|
|
|
physicsWorld
|
|
|
|
) {
|
|
|
|
physicsWorld.linkedPairs = physicsWorld.linkedPairs || [];
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
physicsWorld.linkedPairs.push({
|
|
|
|
threeMesh : threeMesh,
|
|
|
|
physicsBody : physicsBody
|
|
|
|
});
|
2016-09-30 13:55:21 +02:00
|
|
|
};
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Graphics Superset
|
|
|
|
* @param graphicsType
|
|
|
|
* @param instance {THREE}
|
|
|
|
* @constructor
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Graphics = function(
|
|
|
|
graphicsType,
|
|
|
|
instance
|
|
|
|
) {
|
|
|
|
this.graphicsType = graphicsType;
|
|
|
|
this.instance = instance;
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* True if THREE physics
|
|
|
|
* @returns {boolean}
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Graphics.prototype.isThree = function() {
|
|
|
|
return (this.graphicsType == GameLib.D3.Graphics.GRAPHICS_TYPE_THREE)
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Logs a warning and throws an error if not cannon
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Graphics.prototype.isNotThreeThrow = function() {
|
|
|
|
if (this.graphicsType != GameLib.D3.Graphics.GRAPHICS_TYPE_THREE) {
|
|
|
|
console.warn('Only THREE supported for this function');
|
|
|
|
throw new Error('Only THREE supported for this function');
|
|
|
|
}
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Physics GameLib.D3.Graphics Types
|
2016-09-30 13:55:21 +02:00
|
|
|
* @type {number}
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Graphics.GRAPHICS_TYPE_THREE = 0x1;
|
2016-09-30 13:55:21 +02:00
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* @param sizeX Number
|
|
|
|
* @param sizeY Number
|
|
|
|
* @param matrix matrix 2D Array with height data (Column Major)
|
|
|
|
* @param elementSize Number
|
|
|
|
* @param heightScale Number
|
|
|
|
* @constructor
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Heightmap = function(
|
|
|
|
sizeX,
|
|
|
|
sizeY,
|
|
|
|
matrix,
|
|
|
|
elementSize,
|
|
|
|
heightScale
|
|
|
|
) {
|
|
|
|
if (typeof sizeX == 'undefined') {
|
|
|
|
sizeX = 0;
|
|
|
|
}
|
|
|
|
this.sizeX = sizeX;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof sizeY == 'undefined') {
|
|
|
|
sizeY = 0;
|
|
|
|
}
|
|
|
|
this.sizeY = sizeY;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof matrix == 'undefined') {
|
|
|
|
matrix = [];
|
|
|
|
}
|
|
|
|
this.matrix = matrix;
|
|
|
|
|
|
|
|
if (typeof elementSize == 'undefined') {
|
|
|
|
elementSize = 10;
|
|
|
|
}
|
|
|
|
this.elementSize = elementSize;
|
|
|
|
|
|
|
|
if (typeof heightScale == 'undefined') {
|
|
|
|
heightScale = 15;
|
|
|
|
}
|
|
|
|
this.elementSize = heightScale;
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Creates a graphics instance mesh from the graphics, physics and physics shape
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param shape GameLib.D3.Shape
|
|
|
|
* @param engine GameLib.D3.Engine
|
|
|
|
* @returns {THREE.Mesh|this.meshes}
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Heightmap.GenerateInstanceMesh = function(
|
|
|
|
graphics,
|
|
|
|
shape,
|
|
|
|
engine
|
|
|
|
) {
|
|
|
|
graphics.isNotThreeThrow();
|
|
|
|
engine.isNotCannonThrow();
|
|
|
|
|
|
|
|
var geometry = new graphics.instance.Geometry();
|
|
|
|
|
|
|
|
var v0 = new engine.instance.Vec3();
|
|
|
|
var v1 = new engine.instance.Vec3();
|
|
|
|
var v2 = new engine.instance.Vec3();
|
|
|
|
|
|
|
|
for (var xi = 0; xi < shape.instance.data.length - 1; xi++) {
|
|
|
|
for (var yi = 0; yi < shape.instance.data[xi].length - 1; yi++) {
|
|
|
|
for (var k = 0; k < 2; k++) {
|
|
|
|
shape.instance.getConvexTrianglePillar(xi, yi, k===0);
|
|
|
|
v0.copy(shape.instance.pillarConvex.vertices[0]);
|
|
|
|
v1.copy(shape.instance.pillarConvex.vertices[1]);
|
|
|
|
v2.copy(shape.instance.pillarConvex.vertices[2]);
|
|
|
|
v0.vadd(shape.instance.pillarOffset, v0);
|
|
|
|
v1.vadd(shape.instance.pillarOffset, v1);
|
|
|
|
v2.vadd(shape.instance.pillarOffset, v2);
|
|
|
|
geometry.vertices.push(
|
|
|
|
new graphics.instance.Vector3(v0.x, v0.y, v0.z),
|
|
|
|
new graphics.instance.Vector3(v1.x, v1.y, v1.z),
|
|
|
|
new graphics.instance.Vector3(v2.x, v2.y, v2.z)
|
|
|
|
);
|
|
|
|
var i = geometry.vertices.length - 3;
|
|
|
|
geometry.faces.push(new graphics.instance.Face3(i, i+1, i+2));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
geometry.computeBoundingSphere();
|
|
|
|
geometry.computeFaceNormals();
|
|
|
|
|
|
|
|
return new graphics.instance.Mesh(
|
|
|
|
geometry,
|
|
|
|
new graphics.instance.MeshNormalMaterial(
|
|
|
|
{
|
|
|
|
wireframe: false,
|
|
|
|
shading : graphics.instance.SmoothShading
|
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Needs an RGBA
|
|
|
|
* @param imagePath string
|
|
|
|
* @param heightScale
|
|
|
|
* @param callback
|
|
|
|
* @constructor
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Heightmap.GenerateHeightmapDataFromImage = function (
|
|
|
|
imagePath,
|
|
|
|
heightScale,
|
|
|
|
callback
|
|
|
|
) {
|
|
|
|
var img = new Image();
|
|
|
|
|
|
|
|
img.onload = function () {
|
|
|
|
|
|
|
|
var canvas = document.createElement('canvas');
|
|
|
|
canvas.width = img.width;
|
|
|
|
canvas.height = img.height;
|
|
|
|
|
|
|
|
var context = canvas.getContext('2d');
|
|
|
|
context.drawImage(img, 0, 0);
|
|
|
|
|
|
|
|
var imgd = context.getImageData(0, 0, img.width, img.height);
|
|
|
|
var pixels = imgd.data;
|
|
|
|
|
|
|
|
var heightList = [];
|
|
|
|
for (var i = 0, n = pixels.length; i < n; i += (4)) {
|
|
|
|
heightList.push(pixels[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
var matrix = [];
|
|
|
|
var sizeX = img.width,
|
|
|
|
sizeY = img.height;
|
|
|
|
|
|
|
|
for (var x = 0; x < sizeX; x++) {
|
|
|
|
matrix.push([]);
|
|
|
|
for (var j = 0; j < sizeY; j++) {
|
|
|
|
var height = (heightList[(sizeX - x) + j * sizeY] / 255) * heightScale;
|
|
|
|
matrix[x].push(height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo: delete canvas here
|
|
|
|
|
|
|
|
callback(
|
|
|
|
new GameLib.D3.Heightmap(
|
|
|
|
sizeX,
|
|
|
|
sizeY,
|
|
|
|
matrix,
|
|
|
|
10,
|
|
|
|
heightScale
|
|
|
|
)
|
|
|
|
);
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
img.src = imagePath;
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Image
|
2016-09-30 13:55:21 +02:00
|
|
|
* @param id
|
2016-10-28 11:50:55 +02:00
|
|
|
* @param textureLink
|
|
|
|
* @param filename
|
|
|
|
* @param size
|
|
|
|
* @param contentType
|
2016-09-30 13:55:21 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Image = function(
|
2016-09-30 13:55:21 +02:00
|
|
|
id,
|
2016-10-28 11:50:55 +02:00
|
|
|
textureLink,
|
|
|
|
filename,
|
|
|
|
size,
|
|
|
|
contentType
|
2016-09-30 13:55:21 +02:00
|
|
|
) {
|
|
|
|
this.id = id;
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.filename = filename;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.textureLink = textureLink;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof size == 'undefined') {
|
|
|
|
size = 0;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.size = size;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof contentType == 'undefined') {
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
contentType = 'application/octet-stream';
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (this.filename.match(/(png)$/i)) {
|
|
|
|
contentType = 'image/png';
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (this.filename.match(/(jpg|jpeg)$/i)) {
|
|
|
|
contentType = 'image/jpeg';
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (this.filename.match(/(gif)$/i)) {
|
|
|
|
contentType = 'image/gif';
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.contentType = contentType;
|
2016-09-30 13:55:21 +02:00
|
|
|
};
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Light Superset
|
2016-09-30 13:55:21 +02:00
|
|
|
* @param id
|
2016-10-28 11:50:55 +02:00
|
|
|
* @param lightType
|
2016-09-30 13:55:21 +02:00
|
|
|
* @param name
|
2016-10-28 11:50:55 +02:00
|
|
|
* @param color
|
|
|
|
* @param intensity
|
2016-09-30 13:55:21 +02:00
|
|
|
* @param position
|
2016-10-28 11:50:55 +02:00
|
|
|
* @param targetPosition
|
2016-09-30 13:55:21 +02:00
|
|
|
* @param quaternion
|
|
|
|
* @param rotation
|
|
|
|
* @param scale
|
2016-10-28 11:50:55 +02:00
|
|
|
* @param distance
|
|
|
|
* @param decay
|
|
|
|
* @param power
|
|
|
|
* @param angle
|
|
|
|
* @param penumbra
|
2016-09-30 13:55:21 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Light = function(
|
2016-09-30 13:55:21 +02:00
|
|
|
id,
|
2016-10-28 11:50:55 +02:00
|
|
|
lightType,
|
2016-09-30 13:55:21 +02:00
|
|
|
name,
|
2016-10-28 11:50:55 +02:00
|
|
|
color,
|
|
|
|
intensity,
|
2016-09-30 13:55:21 +02:00
|
|
|
position,
|
2016-10-28 11:50:55 +02:00
|
|
|
targetPosition,
|
2016-09-30 13:55:21 +02:00
|
|
|
quaternion,
|
|
|
|
rotation,
|
|
|
|
scale,
|
2016-10-28 11:50:55 +02:00
|
|
|
distance,
|
|
|
|
decay,
|
|
|
|
power,
|
|
|
|
angle,
|
|
|
|
penumbra
|
2016-09-30 13:55:21 +02:00
|
|
|
) {
|
|
|
|
this.id = id;
|
2016-10-28 11:50:55 +02:00
|
|
|
this.lightType = lightType;
|
2016-09-30 13:55:21 +02:00
|
|
|
this.name = name;
|
2016-10-28 11:50:55 +02:00
|
|
|
this.color = color;
|
|
|
|
this.intensity = intensity;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
if (typeof position == 'undefined') {
|
|
|
|
position = new GameLib.D3.Vector3(0,0,0);
|
|
|
|
}
|
|
|
|
this.position = position;
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof targetPosition == 'undefined') {
|
|
|
|
targetPosition = new GameLib.D3.Vector3(0,0,0);
|
|
|
|
}
|
|
|
|
this.targetPosition = targetPosition;
|
|
|
|
|
|
|
|
if (typeof quaternion == 'undefined'){
|
|
|
|
quaternion = new GameLib.D3.Vector4();
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
|
|
|
this.quaternion = quaternion;
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof rotation == 'undefined'){
|
2016-09-30 13:55:21 +02:00
|
|
|
rotation = new GameLib.D3.Vector3(0,0,0);
|
|
|
|
}
|
|
|
|
this.rotation = rotation;
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof scale == 'undefined'){
|
2016-09-30 13:55:21 +02:00
|
|
|
scale = new GameLib.D3.Vector3(1,1,1);
|
|
|
|
}
|
|
|
|
this.scale = scale;
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof distance == 'undefined'){
|
|
|
|
distance = 0;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.distance = distance;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof decay == 'undefined'){
|
|
|
|
decay = 1;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.decay = decay;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof power == 'undefined'){
|
|
|
|
power = 4 * Math.PI;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.power = power;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof angle == 'undefined'){
|
|
|
|
angle = Math.PI / 3;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.angle = angle;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof penumbra == 'undefined'){
|
|
|
|
penumbra = 0;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.penumbra = penumbra;
|
2016-09-30 13:55:21 +02:00
|
|
|
};
|
2016-09-30 14:12:27 +02:00
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Material Superset
|
2016-09-30 14:12:27 +02:00
|
|
|
* @param id
|
|
|
|
* @param name
|
2016-10-28 11:50:55 +02:00
|
|
|
* @param materialType
|
|
|
|
* @param opacity
|
|
|
|
* @param side
|
|
|
|
* @param transparent
|
|
|
|
* @param maps
|
|
|
|
* @param specular
|
|
|
|
* @param lightMapIntensity
|
|
|
|
* @param aoMapIntensity
|
|
|
|
* @param color
|
|
|
|
* @param emissive
|
|
|
|
* @param emissiveIntensity
|
|
|
|
* @param combine
|
|
|
|
* @param shininess
|
|
|
|
* @param reflectivity
|
|
|
|
* @param refractionRatio
|
|
|
|
* @param fog
|
|
|
|
* @param wireframe
|
|
|
|
* @param wireframeLineWidth
|
|
|
|
* @param wireframeLineCap
|
|
|
|
* @param wireframeLineJoin
|
|
|
|
* @param vertexColors
|
|
|
|
* @param skinning
|
|
|
|
* @param morphTargets
|
|
|
|
* @param morphNormals
|
|
|
|
* @param lineWidth
|
|
|
|
* @param lineCap
|
|
|
|
* @param lineJoin
|
|
|
|
* @param dashSize
|
|
|
|
* @param gapWidth
|
|
|
|
* @param blending
|
|
|
|
* @param blendSrc
|
|
|
|
* @param blendDst
|
|
|
|
* @param blendEquation
|
|
|
|
* @param depthTest
|
|
|
|
* @param depthFunc
|
|
|
|
* @param depthWrite
|
|
|
|
* @param polygonOffset
|
|
|
|
* @param polygonOffsetFactor
|
|
|
|
* @param polygonOffsetUnits
|
|
|
|
* @param alphaTest
|
|
|
|
* @param clippingPlanes
|
|
|
|
* @param clipShadows
|
|
|
|
* @param visible
|
|
|
|
* @param overdraw
|
|
|
|
* @param shading
|
|
|
|
* @param bumpScale
|
|
|
|
* @param normalScale
|
|
|
|
* @param displacementScale
|
|
|
|
* @param displacementBias
|
|
|
|
* @param roughness
|
|
|
|
* @param metalness
|
|
|
|
* @param pointSize
|
|
|
|
* @param pointSizeAttenuation
|
|
|
|
* @param spriteRotation
|
|
|
|
* @param envMapIntensity
|
2016-09-30 14:12:27 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Material = function(
|
2016-09-30 14:12:27 +02:00
|
|
|
id,
|
|
|
|
name,
|
2016-10-28 11:50:55 +02:00
|
|
|
materialType,
|
|
|
|
opacity,
|
|
|
|
side,
|
|
|
|
transparent,
|
|
|
|
maps,
|
|
|
|
specular,
|
|
|
|
lightMapIntensity,
|
|
|
|
aoMapIntensity,
|
|
|
|
color,
|
|
|
|
emissive,
|
|
|
|
emissiveIntensity,
|
|
|
|
combine,
|
|
|
|
shininess,
|
|
|
|
reflectivity,
|
|
|
|
refractionRatio,
|
|
|
|
fog,
|
|
|
|
wireframe,
|
|
|
|
wireframeLineWidth,
|
|
|
|
wireframeLineCap,
|
|
|
|
wireframeLineJoin,
|
|
|
|
vertexColors,
|
|
|
|
skinning,
|
|
|
|
morphTargets,
|
|
|
|
morphNormals,
|
|
|
|
lineWidth,
|
|
|
|
lineCap,
|
|
|
|
lineJoin,
|
|
|
|
dashSize,
|
|
|
|
gapWidth,
|
|
|
|
blending,
|
|
|
|
blendSrc,
|
|
|
|
blendDst,
|
|
|
|
blendEquation,
|
|
|
|
depthTest,
|
|
|
|
depthFunc,
|
|
|
|
depthWrite,
|
|
|
|
polygonOffset,
|
|
|
|
polygonOffsetFactor,
|
|
|
|
polygonOffsetUnits,
|
|
|
|
alphaTest,
|
|
|
|
clippingPlanes,
|
|
|
|
clipShadows,
|
|
|
|
visible,
|
|
|
|
overdraw,
|
|
|
|
shading,
|
|
|
|
bumpScale,
|
|
|
|
normalScale,
|
|
|
|
displacementScale,
|
|
|
|
displacementBias,
|
|
|
|
roughness,
|
|
|
|
metalness,
|
|
|
|
pointSize,
|
|
|
|
pointSizeAttenuation,
|
|
|
|
spriteRotation,
|
|
|
|
envMapIntensity
|
2016-09-30 14:12:27 +02:00
|
|
|
) {
|
|
|
|
this.id = id;
|
|
|
|
this.name = name;
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof materialType == 'undefined') {
|
|
|
|
materialType = GameLib.D3.Material.TYPE_MESH_STANDARD;
|
|
|
|
}
|
|
|
|
this.materialType = materialType;
|
2016-09-30 14:12:27 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof opacity == 'undefined') {
|
|
|
|
opacity = 1.0;
|
|
|
|
}
|
|
|
|
this.opacity = opacity;
|
2016-09-30 14:12:27 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof side == 'undefined') {
|
|
|
|
side = GameLib.D3.Material.TYPE_FRONT_SIDE;
|
2016-09-30 14:12:27 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.side = side;
|
2016-09-30 14:12:27 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof transparent == 'undefined') {
|
|
|
|
transparent = false;
|
|
|
|
}
|
|
|
|
this.transparent = transparent;
|
2016-10-04 10:05:18 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof maps == 'undefined') {
|
|
|
|
maps = {
|
|
|
|
alpha: null,
|
|
|
|
ao: null,
|
|
|
|
bump: null,
|
|
|
|
diffuse: null,
|
|
|
|
displacement: null,
|
|
|
|
emissive: null,
|
|
|
|
environment: null,
|
|
|
|
light: null,
|
|
|
|
metalness: null,
|
|
|
|
normal: null,
|
|
|
|
roughness: null,
|
|
|
|
specular: null
|
|
|
|
};
|
2016-09-30 14:12:27 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.maps = maps;
|
2016-09-30 14:12:27 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof specular == 'undefined') {
|
|
|
|
specular = new GameLib.D3.Color(0.06, 0.06, 0.06, 0.06);
|
|
|
|
}
|
|
|
|
this.specular = specular;
|
2016-09-30 14:12:27 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof lightMapIntensity == 'undefined') {
|
|
|
|
lightMapIntensity = 1;
|
|
|
|
}
|
|
|
|
this.lightMapIntensity = lightMapIntensity;
|
2016-10-13 11:24:05 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof aoMapIntensity == 'undefined') {
|
|
|
|
aoMapIntensity = 1;
|
|
|
|
}
|
|
|
|
this.aoMapIntensity = aoMapIntensity;
|
2016-09-30 14:12:27 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof color == 'undefined') {
|
|
|
|
color = new GameLib.D3.Color(1, 1, 1, 1)
|
|
|
|
}
|
|
|
|
this.color = color;
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof emissive == 'undefined') {
|
|
|
|
emissive = new GameLib.D3.Color(0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
this.emissive = emissive;
|
2016-09-30 14:12:27 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof emissiveIntensity == 'undefined') {
|
|
|
|
emissiveIntensity = 1;
|
|
|
|
}
|
|
|
|
this.emissiveIntensity = emissiveIntensity;
|
2016-09-30 14:12:27 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof combine == 'undefined') {
|
|
|
|
combine = GameLib.D3.Material.TYPE_MULTIPLY_OPERATION;
|
|
|
|
}
|
|
|
|
this.combine = combine;
|
2016-09-30 14:12:27 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof shininess == 'undefined') {
|
|
|
|
shininess = 30;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.shininess = shininess;
|
|
|
|
|
|
|
|
if (typeof reflectivity == 'undefined') {
|
|
|
|
reflectivity = 1;
|
|
|
|
}
|
|
|
|
this.reflectivity = reflectivity;
|
|
|
|
|
|
|
|
if (typeof refractionRatio == 'undefined') {
|
|
|
|
refractionRatio = 0.98;
|
|
|
|
}
|
|
|
|
this.refractionRatio = refractionRatio;
|
|
|
|
|
|
|
|
if (typeof fog == 'undefined') {
|
|
|
|
fog = true;
|
|
|
|
}
|
|
|
|
this.fog = fog;
|
|
|
|
|
|
|
|
if (typeof wireframe == 'undefined') {
|
|
|
|
wireframe = false;
|
|
|
|
}
|
|
|
|
this.wireframe = wireframe;
|
|
|
|
|
|
|
|
if (typeof wireframeLineWidth == 'undefined') {
|
|
|
|
wireframeLineWidth = 1;
|
|
|
|
}
|
|
|
|
this.wireframeLineWidth = wireframeLineWidth;
|
|
|
|
|
|
|
|
if (typeof wireframeLineCap == 'undefined') {
|
|
|
|
wireframeLineCap = 'round';
|
|
|
|
}
|
|
|
|
this.wireframeLineCap = wireframeLineCap;
|
|
|
|
|
|
|
|
if (typeof wireframeLineJoin == 'undefined') {
|
|
|
|
wireframeLineJoin = 'round';
|
|
|
|
}
|
|
|
|
this.wireframeLineJoin = wireframeLineJoin;
|
|
|
|
|
|
|
|
if (typeof vertexColors == 'undefined') {
|
|
|
|
vertexColors = GameLib.D3.Material.TYPE_NO_COLORS;
|
|
|
|
}
|
|
|
|
this.vertexColors = vertexColors;
|
|
|
|
|
|
|
|
if (typeof skinning == 'undefined') {
|
|
|
|
skinning = false;
|
|
|
|
}
|
|
|
|
this.skinning = skinning;
|
|
|
|
|
|
|
|
if (typeof morphTargets == 'undefined') {
|
|
|
|
morphTargets = false;
|
|
|
|
}
|
|
|
|
this.morphTargets = morphTargets;
|
|
|
|
|
|
|
|
if (typeof morphNormals == 'undefined') {
|
|
|
|
morphNormals = false;
|
|
|
|
}
|
|
|
|
this.morphNormals = morphNormals;
|
|
|
|
|
|
|
|
if (typeof overdraw == 'undefined') {
|
|
|
|
overdraw = 0;
|
|
|
|
}
|
|
|
|
this.overdraw = overdraw;
|
|
|
|
|
|
|
|
if (typeof lineWidth == 'undefined') {
|
|
|
|
lineWidth = 1;
|
|
|
|
}
|
|
|
|
this.lineWidth = lineWidth;
|
|
|
|
|
|
|
|
if (typeof lineCap == 'undefined') {
|
|
|
|
lineCap = 'round';
|
|
|
|
}
|
|
|
|
this.lineCap = lineCap;
|
|
|
|
|
|
|
|
if (typeof lineJoin == 'undefined') {
|
|
|
|
lineJoin = 'round';
|
|
|
|
}
|
|
|
|
this.lineJoin = lineJoin;
|
|
|
|
|
|
|
|
if (typeof dashSize == 'undefined') {
|
|
|
|
dashSize = 3;
|
|
|
|
}
|
|
|
|
this.dashSize = dashSize;
|
|
|
|
|
|
|
|
if (typeof gapWidth == 'undefined') {
|
|
|
|
gapWidth = 1;
|
|
|
|
}
|
|
|
|
this.gapWidth = gapWidth;
|
|
|
|
|
|
|
|
if (typeof blending == 'undefined') {
|
|
|
|
blending = GameLib.D3.Material.TYPE_NORMAL_BLENDING;
|
|
|
|
}
|
|
|
|
this.blending = blending;
|
|
|
|
|
|
|
|
if (typeof blendSrc == 'undefined') {
|
|
|
|
blendSrc = GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR;
|
|
|
|
}
|
|
|
|
this.blendSrc = blendSrc;
|
|
|
|
|
|
|
|
if (typeof blendDst == 'undefined') {
|
|
|
|
blendDst = GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR;
|
|
|
|
}
|
|
|
|
this.blendDst = blendDst;
|
|
|
|
|
|
|
|
if (typeof blendEquation == 'undefined') {
|
|
|
|
blendEquation = GameLib.D3.Material.TYPE_ADD_EQUATION;
|
|
|
|
}
|
|
|
|
this.blendEquation = blendEquation;
|
|
|
|
|
|
|
|
if (typeof depthTest == 'undefined') {
|
|
|
|
depthTest = true;
|
|
|
|
}
|
|
|
|
this.depthTest = depthTest;
|
|
|
|
|
|
|
|
if (typeof depthFunc == 'undefined') {
|
|
|
|
depthFunc = GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH;
|
|
|
|
}
|
|
|
|
this.depthFunc = depthFunc;
|
|
|
|
|
|
|
|
if (typeof depthWrite == 'undefined') {
|
|
|
|
depthWrite = true;
|
|
|
|
}
|
|
|
|
this.depthWrite = depthWrite;
|
|
|
|
|
|
|
|
if (typeof polygonOffset == 'undefined') {
|
|
|
|
polygonOffset = false;
|
|
|
|
}
|
|
|
|
this.polygonOffset = polygonOffset;
|
|
|
|
|
|
|
|
if (typeof polygonOffsetFactor == 'undefined') {
|
|
|
|
polygonOffsetFactor = 1;
|
|
|
|
}
|
|
|
|
this.polygonOffsetFactor = polygonOffsetFactor;
|
|
|
|
|
|
|
|
if (typeof polygonOffsetUnits == 'undefined') {
|
|
|
|
polygonOffsetUnits = 1;
|
|
|
|
}
|
|
|
|
this.polygonOffsetUnits = polygonOffsetUnits;
|
|
|
|
|
|
|
|
if (typeof alphaTest == 'undefined') {
|
|
|
|
alphaTest = 0;
|
|
|
|
}
|
|
|
|
this.alphaTest = alphaTest;
|
|
|
|
|
|
|
|
if (typeof clippingPlanes == 'undefined') {
|
|
|
|
clippingPlanes = [];
|
|
|
|
}
|
|
|
|
this.clippingPlanes = clippingPlanes;
|
|
|
|
|
|
|
|
if (typeof clipShadows == 'undefined') {
|
|
|
|
clipShadows = false;
|
|
|
|
}
|
|
|
|
this.clipShadows = clipShadows;
|
|
|
|
|
|
|
|
if (typeof visible == 'undefined') {
|
|
|
|
visible = true;
|
|
|
|
}
|
|
|
|
this.visible = visible;
|
|
|
|
|
|
|
|
if (typeof shading == 'undefined') {
|
|
|
|
shading = GameLib.D3.Material.TYPE_FLAT_SHADING;
|
|
|
|
}
|
|
|
|
this.shading = shading;
|
|
|
|
|
|
|
|
if (typeof bumpScale == 'undefined') {
|
|
|
|
bumpScale = 1;
|
|
|
|
}
|
|
|
|
this.bumpScale = bumpScale;
|
|
|
|
|
|
|
|
if (typeof normalScale == 'undefined') {
|
|
|
|
normalScale = 1;
|
|
|
|
}
|
|
|
|
this.normalScale = normalScale;
|
|
|
|
|
|
|
|
if (typeof displacementScale == 'undefined') {
|
|
|
|
displacementScale = 1;
|
|
|
|
}
|
|
|
|
this.displacementScale = displacementScale;
|
|
|
|
|
|
|
|
if (typeof displacementBias == 'undefined') {
|
|
|
|
displacementBias = 0;
|
|
|
|
}
|
|
|
|
this.displacementBias = displacementBias;
|
|
|
|
|
|
|
|
if (typeof roughness == 'undefined') {
|
|
|
|
roughness = 0.5;
|
|
|
|
}
|
|
|
|
this.roughness = roughness;
|
|
|
|
|
|
|
|
if (typeof metalness == 'undefined') {
|
|
|
|
metalness = 0.5;
|
|
|
|
}
|
|
|
|
this.metalness = metalness;
|
|
|
|
|
|
|
|
if (typeof pointSize == 'undefined') {
|
|
|
|
pointSize = 1;
|
|
|
|
}
|
|
|
|
this.pointSize = pointSize;
|
|
|
|
|
|
|
|
if (typeof pointSizeAttenuation == 'undefined') {
|
|
|
|
pointSizeAttenuation = true;
|
|
|
|
}
|
|
|
|
this.pointSizeAttenuation = pointSizeAttenuation;
|
|
|
|
|
|
|
|
if (typeof spriteRotation == 'undefined') {
|
|
|
|
spriteRotation = 0;
|
|
|
|
}
|
|
|
|
this.spriteRotation = spriteRotation;
|
|
|
|
|
|
|
|
if (typeof envMapIntensity == 'undefined') {
|
|
|
|
envMapIntensity = 1.0;
|
|
|
|
}
|
|
|
|
this.envMapIntensity = envMapIntensity;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Combine Method
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Material.TYPE_MULTIPLY_OPERATION = 0;
|
|
|
|
GameLib.D3.Material.TYPE_MIX_OPERATION = 1;
|
|
|
|
GameLib.D3.Material.TYPE_ADD_OPERATION = 2;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Vertex Color Mode
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Material.TYPE_NO_COLORS = 0;
|
|
|
|
GameLib.D3.Material.TYPE_FACE_COLORS = 1;
|
|
|
|
GameLib.D3.Material.TYPE_VERTEX_COLORS = 2;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Blending Mode
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Material.TYPE_NORMAL_BLENDING = 1;
|
|
|
|
GameLib.D3.Material.TYPE_ADDITIVE_BLENDING = 2;
|
|
|
|
GameLib.D3.Material.TYPE_SUBTRACTIVE_BLENDING = 3;
|
|
|
|
GameLib.D3.Material.TYPE_MULTIPLY_BLENDING = 4;
|
|
|
|
GameLib.D3.Material.TYPE_CUSTOM_BLENDING = 5;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Blend Source and Destination
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Material.TYPE_ZERO_FACTOR = 200;
|
|
|
|
GameLib.D3.Material.TYPE_ONE_FACTOR = 201;
|
|
|
|
GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR = 202;
|
|
|
|
GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR = 203;
|
|
|
|
GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR = 204;
|
|
|
|
GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR = 205;
|
|
|
|
GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR = 206;
|
|
|
|
GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR = 207;
|
|
|
|
GameLib.D3.Material.TYPE_DST_COLOR_FACTOR = 208;
|
|
|
|
GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR = 209;
|
|
|
|
GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR = 210;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Blend Operation
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Material.TYPE_ADD_EQUATION = 100;
|
|
|
|
GameLib.D3.Material.TYPE_SUBTRACT_EQUATION = 101;
|
|
|
|
GameLib.D3.Material.TYPE_REVERSE_SUBTRACT_EQUATION = 102;
|
|
|
|
GameLib.D3.Material.TYPE_MIN_EQUATION = 103;
|
|
|
|
GameLib.D3.Material.TYPE_MAX_EQUATION = 104;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Depth Function
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Material.TYPE_NEVER_DEPTH = 0;
|
|
|
|
GameLib.D3.Material.TYPE_ALWAYS_DEPTH = 1;
|
|
|
|
GameLib.D3.Material.TYPE_LESS_DEPTH = 2;
|
|
|
|
GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH = 3;
|
|
|
|
GameLib.D3.Material.TYPE_EQUAL_DEPTH = 4;
|
|
|
|
GameLib.D3.Material.TYPE_GREATER_EQUAL_DEPTH = 5;
|
|
|
|
GameLib.D3.Material.TYPE_GREATER_DEPTH = 6;
|
|
|
|
GameLib.D3.Material.TYPE_NOT_EQUAL_DEPTH = 7;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Culling Mode
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Material.TYPE_FRONT_SIDE = 0;
|
|
|
|
GameLib.D3.Material.TYPE_BACK_SIDE = 1;
|
|
|
|
GameLib.D3.Material.TYPE_DOUBLE_SIDE = 2;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shading Type
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Material.TYPE_FLAT_SHADING = 1;
|
|
|
|
GameLib.D3.Material.TYPE_SMOOTH_SHADING = 2;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Material Type
|
|
|
|
* @type {string}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Material.TYPE_LINE_BASIC = "LineBasicMaterial";
|
|
|
|
GameLib.D3.Material.TYPE_LINE_DASHED = "LineDashedMaterial";
|
|
|
|
GameLib.D3.Material.TYPE_MESH_BASIC = "MeshBasicMaterial";
|
|
|
|
GameLib.D3.Material.TYPE_MESH_DEPTH = "MeshDepthMaterial";
|
|
|
|
GameLib.D3.Material.TYPE_MESH_LAMBERT = "MeshLambertMaterial";
|
|
|
|
GameLib.D3.Material.TYPE_MESH_NORMAL = "MeshNormalMaterial";
|
|
|
|
GameLib.D3.Material.TYPE_MESH_PHONG = "MeshPhongMaterial";
|
|
|
|
GameLib.D3.Material.TYPE_MESH_STANDARD = "MeshStandardMaterial";
|
|
|
|
GameLib.D3.Material.TYPE_POINTS = "PointsMaterial";
|
|
|
|
GameLib.D3.Material.TYPE_SPRITE = "SpriteMaterial";
|
|
|
|
GameLib.D3.Material.TYPE_MULTI_MATERIAL= "MultiMaterial";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an instance Material from a GameLib.D3.Material
|
|
|
|
* @param gameLibMaterial GameLib.D3.Material
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param uploadUrl String
|
|
|
|
* @param progressCallback
|
|
|
|
*/
|
|
|
|
GameLib.D3.Material.createInstanceMaterial = function(
|
|
|
|
gameLibMaterial,
|
|
|
|
graphics,
|
|
|
|
uploadUrl,
|
|
|
|
progressCallback
|
|
|
|
) {
|
|
|
|
|
|
|
|
var defer = Q.defer();
|
|
|
|
|
|
|
|
var instanceMaterial = null;
|
|
|
|
|
|
|
|
var blenderMaps = [];
|
|
|
|
|
|
|
|
if (gameLibMaterial.materialType == GameLib.D3.Material.TYPE_MESH_STANDARD) {
|
|
|
|
|
|
|
|
instanceMaterial = new graphics.instance.MeshStandardMaterial({
|
|
|
|
name: gameLibMaterial.name,
|
|
|
|
opacity: gameLibMaterial.opacity,
|
|
|
|
transparent: gameLibMaterial.transparent,
|
|
|
|
blending: gameLibMaterial.blending,
|
|
|
|
blendSrc: gameLibMaterial.blendSrc,
|
|
|
|
blendDst: gameLibMaterial.blendDst,
|
|
|
|
blendEquation: gameLibMaterial.blendEquation,
|
|
|
|
depthTest: gameLibMaterial.depthTest,
|
|
|
|
depthFunc: gameLibMaterial.depthFunc,
|
|
|
|
depthWrite: gameLibMaterial.depthWrite,
|
|
|
|
polygonOffset: gameLibMaterial.polygonOffset,
|
|
|
|
polygonOffsetFactor: gameLibMaterial.polygonOffsetFactor,
|
|
|
|
polygonOffsetUnits: gameLibMaterial.polygonOffsetUnits,
|
|
|
|
alphaTest: gameLibMaterial.alphaTest,
|
|
|
|
clippingPlanes: gameLibMaterial.clippingPlanes,
|
|
|
|
clipShadows: gameLibMaterial.clipShadows,
|
|
|
|
overdraw: gameLibMaterial.overdraw,
|
|
|
|
visible: gameLibMaterial.visible,
|
|
|
|
side: gameLibMaterial.side,
|
|
|
|
color: new graphics.instance.Color(
|
|
|
|
gameLibMaterial.color.r,
|
|
|
|
gameLibMaterial.color.g,
|
|
|
|
gameLibMaterial.color.b
|
|
|
|
),
|
|
|
|
roughness: gameLibMaterial.roughness,
|
|
|
|
metalness: gameLibMaterial.metalness,
|
|
|
|
lightMapIntensity: gameLibMaterial.lightMapIntensity,
|
|
|
|
aoMapIntensity: gameLibMaterial.aoMapIntensity,
|
|
|
|
emissive: new graphics.instance.Color(
|
|
|
|
gameLibMaterial.emissive.r,
|
|
|
|
gameLibMaterial.emissive.g,
|
|
|
|
gameLibMaterial.emissive.b
|
|
|
|
),
|
|
|
|
emissiveIntensity: gameLibMaterial.emissiveIntensity,
|
|
|
|
bumpScale: gameLibMaterial.bumpScale,
|
|
|
|
normalScale: gameLibMaterial.normalScale,
|
|
|
|
displacementScale: gameLibMaterial.displacementScale,
|
|
|
|
refractionRatio: gameLibMaterial.refractionRatio,
|
|
|
|
fog: gameLibMaterial.fog,
|
|
|
|
shading: gameLibMaterial.shading,
|
|
|
|
wireframe: gameLibMaterial.wireframe,
|
|
|
|
wireframeLinewidth: gameLibMaterial.wireframeLineWidth,
|
|
|
|
wireframeLinecap: gameLibMaterial.wireframeLineCap,
|
|
|
|
wireframeLinejoin: gameLibMaterial.wireframeLineJoin,
|
|
|
|
vertexColors: gameLibMaterial.vertexColors,
|
|
|
|
skinning: gameLibMaterial.skinning,
|
|
|
|
morphTargets: gameLibMaterial.morphTargets,
|
|
|
|
morphNormals: gameLibMaterial.morphNormals
|
|
|
|
});
|
|
|
|
|
|
|
|
blenderMaps.push(
|
|
|
|
'diffuse',
|
|
|
|
'light',
|
|
|
|
'ao',
|
|
|
|
'emissive',
|
|
|
|
'bump',
|
|
|
|
'normal',
|
|
|
|
'displacement',
|
|
|
|
'roughness',
|
|
|
|
'metalness',
|
|
|
|
'alpha',
|
|
|
|
'environment'
|
|
|
|
);
|
|
|
|
} else if (gameLibMaterial.materialType == GameLib.D3.Material.TYPE_MESH_PHONG) {
|
|
|
|
|
|
|
|
instanceMaterial = new graphics.instance.MeshPhongMaterial({
|
|
|
|
name: gameLibMaterial.name,
|
|
|
|
opacity: gameLibMaterial.opacity,
|
|
|
|
transparent: gameLibMaterial.transparent,
|
|
|
|
blending: gameLibMaterial.blending,
|
|
|
|
blendSrc: gameLibMaterial.blendSrc,
|
|
|
|
blendDst: gameLibMaterial.blendDst,
|
|
|
|
blendEquation: gameLibMaterial.blendEquation,
|
|
|
|
depthTest: gameLibMaterial.depthTest,
|
|
|
|
depthFunc: gameLibMaterial.depthFunc,
|
|
|
|
depthWrite: gameLibMaterial.depthWrite,
|
|
|
|
polygonOffset: gameLibMaterial.polygonOffset,
|
|
|
|
polygonOffsetFactor: gameLibMaterial.polygonOffsetFactor,
|
|
|
|
polygonOffsetUnits: gameLibMaterial.polygonOffsetUnits,
|
|
|
|
alphaTest: gameLibMaterial.alphaTest,
|
|
|
|
clippingPlanes: gameLibMaterial.clippingPlanes,
|
|
|
|
clipShadows: gameLibMaterial.clipShadows,
|
|
|
|
overdraw: gameLibMaterial.overdraw,
|
|
|
|
visible: gameLibMaterial.visible,
|
|
|
|
side: gameLibMaterial.side,
|
|
|
|
color: new graphics.instance.Color(
|
|
|
|
gameLibMaterial.color.r,
|
|
|
|
gameLibMaterial.color.g,
|
|
|
|
gameLibMaterial.color.b
|
|
|
|
),
|
|
|
|
specular: new graphics.instance.Color(
|
|
|
|
gameLibMaterial.specular.r,
|
|
|
|
gameLibMaterial.specular.g,
|
|
|
|
gameLibMaterial.specular.b
|
|
|
|
),
|
|
|
|
shininess: gameLibMaterial.shininess,
|
|
|
|
lightMapIntensity: gameLibMaterial.lightMapIntensity,
|
|
|
|
aoMapIntensity: gameLibMaterial.aoMapIntensity,
|
|
|
|
emissive: new graphics.instance.Color(
|
|
|
|
gameLibMaterial.emissive.r,
|
|
|
|
gameLibMaterial.emissive.g,
|
|
|
|
gameLibMaterial.emissive.b
|
|
|
|
),
|
|
|
|
emissiveIntensity: gameLibMaterial.emissiveIntensity,
|
|
|
|
bumpScale: gameLibMaterial.bumpScale,
|
|
|
|
normalScale: gameLibMaterial.normalScale,
|
|
|
|
displacementScale: gameLibMaterial.displacementScale,
|
|
|
|
combine: gameLibMaterial.combine,
|
|
|
|
refractionRatio: gameLibMaterial.refractionRatio,
|
|
|
|
fog: gameLibMaterial.fog,
|
|
|
|
shading: gameLibMaterial.shading,
|
|
|
|
wireframe: gameLibMaterial.wireframe,
|
|
|
|
wireframeLinewidth: gameLibMaterial.wireframeLineWidth,
|
|
|
|
wireframeLinecap: gameLibMaterial.wireframeLineCap,
|
|
|
|
wireframeLinejoin: gameLibMaterial.wireframeLineJoin,
|
|
|
|
vertexColors: gameLibMaterial.vertexColors,
|
|
|
|
skinning: gameLibMaterial.skinning,
|
|
|
|
morphTargets: gameLibMaterial.morphTargets,
|
|
|
|
morphNormals: gameLibMaterial.morphNormals
|
|
|
|
});
|
|
|
|
|
|
|
|
blenderMaps.push(
|
|
|
|
'diffuse',
|
|
|
|
'light',
|
|
|
|
'ao',
|
|
|
|
'emissive',
|
|
|
|
'bump',
|
|
|
|
'normal',
|
|
|
|
'displacement',
|
|
|
|
'specular',
|
|
|
|
'alpha',
|
|
|
|
'environment'
|
|
|
|
);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
console.log("material type is not implemented yet: " + gameLibMaterial.materialType + " - material indexes could be screwed up");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (blenderMaps.length > 0) {
|
|
|
|
var textureMaps = GameLib.D3.Texture.loadMaps(
|
|
|
|
gameLibMaterial,
|
|
|
|
blenderMaps,
|
|
|
|
instanceMaterial,
|
|
|
|
graphics,
|
|
|
|
uploadUrl,
|
|
|
|
progressCallback
|
|
|
|
);
|
|
|
|
Q.all(textureMaps).then(
|
|
|
|
function(){
|
|
|
|
defer.resolve(instanceMaterial);
|
|
|
|
}
|
|
|
|
).catch(
|
|
|
|
function(error){
|
|
|
|
console.log(error);
|
|
|
|
defer.reject(error);
|
|
|
|
}
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
defer.resolve(instanceMaterial);
|
|
|
|
}
|
|
|
|
|
|
|
|
return defer.promise;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* Matrix 3 Maths
|
|
|
|
* @param row0 GameLib.D3.Vector3
|
|
|
|
* @param row1 GameLib.D3.Vector3
|
|
|
|
* @param row2 GameLib.D3.Vector3
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Matrix3 = function(
|
|
|
|
row0,
|
|
|
|
row1,
|
|
|
|
row2
|
|
|
|
) {
|
|
|
|
this.identity();
|
|
|
|
|
|
|
|
if (row0) {
|
|
|
|
this.rows[0] = row0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (row1) {
|
|
|
|
this.rows[1] = row1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (row2) {
|
|
|
|
this.rows[2] = row2;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set matrix to identity
|
|
|
|
*/
|
|
|
|
GameLib.D3.Matrix3.prototype.identity = function () {
|
|
|
|
this.rows = [
|
|
|
|
new GameLib.D3.Vector4(1, 0, 0),
|
|
|
|
new GameLib.D3.Vector4(0, 1, 0),
|
|
|
|
new GameLib.D3.Vector4(0, 0, 1)
|
|
|
|
];
|
|
|
|
};
|
|
|
|
GameLib.D3.Matrix4 = function(
|
|
|
|
row0,
|
|
|
|
row1,
|
|
|
|
row2,
|
|
|
|
row3
|
|
|
|
) {
|
|
|
|
|
|
|
|
this.identity();
|
|
|
|
|
|
|
|
if (row0) {
|
|
|
|
this.rows[0] = row0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (row1) {
|
|
|
|
this.rows[1] = row1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (row2) {
|
|
|
|
this.rows[2] = row2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (row3) {
|
|
|
|
this.rows[3] = row3;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Matrix4.prototype.rotationMatrixX = function (radians) {
|
|
|
|
this.identity();
|
|
|
|
this.rows[1] = new GameLib.D3.Vector4(0, Math.cos(radians), -1 * Math.sin(radians), 0);
|
|
|
|
this.rows[2] = new GameLib.D3.Vector4(0, Math.sin(radians), Math.cos(radians), 0);
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Matrix4.prototype.rotationMatrixY = function (radians) {
|
|
|
|
this.identity();
|
|
|
|
this.rows[0] = new GameLib.D3.Vector4(
|
|
|
|
Math.cos(radians),
|
|
|
|
0,
|
|
|
|
Math.sin(radians),
|
|
|
|
0
|
|
|
|
);
|
|
|
|
this.rows[2] = new GameLib.D3.Vector4(
|
|
|
|
-1 * Math.sin(radians),
|
|
|
|
0,
|
|
|
|
Math.cos(radians),
|
|
|
|
0
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Matrix4.prototype.rotationMatrixZ = function (radians) {
|
|
|
|
this.identity();
|
|
|
|
this.rows[0] = new GameLib.D3.Vector4(Math.cos(radians), -1 * Math.sin(radians), 0, 0);
|
|
|
|
this.rows[1] = new GameLib.D3.Vector4(Math.sin(radians), Math.cos(radians), 0, 0);
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Matrix4.prototype.rotateX = function (radians, point) {
|
|
|
|
this.identity();
|
|
|
|
this.rotationMatrixX(radians);
|
|
|
|
return this.multiply(point);
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Matrix4.prototype.rotateY = function (radians, point) {
|
|
|
|
this.identity();
|
|
|
|
this.rotationMatrixY(radians);
|
|
|
|
return this.multiply(point);
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Matrix4.prototype.rotateZ = function (radians, point) {
|
|
|
|
this.identity();
|
|
|
|
this.rotationMatrixZ(radians);
|
|
|
|
return this.multiply(point);
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Matrix4.prototype.multiply = function (mvp) {
|
|
|
|
if (mvp instanceof GameLib.D3.Vector4) {
|
|
|
|
return new GameLib.D3.Vector4(
|
|
|
|
this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z + this.rows[0].w * mvp.w,
|
|
|
|
this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z + this.rows[1].w * mvp.w,
|
|
|
|
this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + this.rows[2].w * mvp.w,
|
|
|
|
this.rows[3].x * mvp.x + this.rows[3].y * mvp.y + this.rows[3].z * mvp.z + this.rows[3].w * mvp.w
|
|
|
|
);
|
|
|
|
} else if (mvp instanceof GameLib.D3.Vector3) {
|
|
|
|
return new GameLib.D3.Vector3(
|
|
|
|
this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z,
|
|
|
|
this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z,
|
|
|
|
this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Matrix4.prototype.identity = function () {
|
|
|
|
this.rows = [
|
|
|
|
new GameLib.D3.Vector4(1, 0, 0, 0),
|
|
|
|
new GameLib.D3.Vector4(0, 1, 0, 0),
|
|
|
|
new GameLib.D3.Vector4(0, 0, 1, 0),
|
|
|
|
new GameLib.D3.Vector4(0, 0, 0, 1)
|
|
|
|
];
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Matrix4.prototype.lookAt = function (position, target, up) {
|
|
|
|
|
|
|
|
var pv = new GameLib.D3.Vector3(position.x, position.y, position.z);
|
|
|
|
|
|
|
|
var z = pv.subtract(target).normalize();
|
|
|
|
|
|
|
|
if (z.squared() === 0) {
|
|
|
|
z.z = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
var x = up.cross(z).normalize();
|
|
|
|
|
|
|
|
if (x.squared() === 0) {
|
|
|
|
z.x += 0.0001;
|
|
|
|
x = up.cross(z).normalize();
|
|
|
|
}
|
|
|
|
|
|
|
|
var y = z.cross(x);
|
|
|
|
|
|
|
|
this.rows[0].x = x.x;
|
|
|
|
this.rows[0].y = x.y;
|
|
|
|
this.rows[0].z = x.z;
|
|
|
|
|
|
|
|
this.rows[1].x = y.x;
|
|
|
|
this.rows[1].y = y.y;
|
|
|
|
this.rows[1].z = y.z;
|
|
|
|
|
|
|
|
this.rows[2].x = z.x;
|
|
|
|
this.rows[2].y = z.y;
|
|
|
|
this.rows[2].z = z.z;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
|
|
|
|
// te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;
|
|
|
|
// te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;
|
|
|
|
// te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;
|
|
|
|
|
|
|
|
|
|
|
|
// var matrix4 = new Matrix4();
|
|
|
|
//
|
|
|
|
// matrix4.rows[0] = side.negative();
|
|
|
|
// matrix4.rows[1] = _up;
|
|
|
|
// matrix4.rows[2] = forward;
|
|
|
|
|
|
|
|
//
|
|
|
|
// matrix4.setColumn(0, side.negative());
|
|
|
|
// matrix4.setColumn(1, _up);
|
|
|
|
// matrix4.setColumn(2, forward);
|
|
|
|
|
|
|
|
//return matrix4;
|
|
|
|
|
|
|
|
// return new Matrix4(
|
|
|
|
// new Vector4(
|
|
|
|
// side.x,
|
|
|
|
// side.y,
|
|
|
|
// side.z,
|
|
|
|
// side.negative().dot(position)
|
|
|
|
// ),
|
|
|
|
// new Vector4(
|
|
|
|
// _up.x,
|
|
|
|
// _up.y,
|
|
|
|
// _up.z,
|
|
|
|
// _up.negative().dot(position)
|
|
|
|
// ),
|
|
|
|
// new Vector4(
|
|
|
|
// forward.negative().x,
|
|
|
|
// forward.negative().y,
|
|
|
|
// forward.negative().z,
|
|
|
|
// forward.dot(position)
|
|
|
|
// )
|
|
|
|
// )
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mesh Superset
|
|
|
|
* @param id
|
|
|
|
* @param path
|
|
|
|
* @param name
|
|
|
|
* @param meshType
|
|
|
|
* @param vertices
|
|
|
|
* @param faces
|
|
|
|
* @param skeleton
|
|
|
|
* @param faceVertexUvs
|
|
|
|
* @param skinIndices
|
|
|
|
* @param skinWeights
|
|
|
|
* @param materials
|
|
|
|
* @param position
|
|
|
|
* @param quaternion
|
|
|
|
* @param rotation
|
|
|
|
* @param scale
|
|
|
|
* @param up
|
|
|
|
* @param physics
|
|
|
|
* @param parentMeshId
|
|
|
|
* @param parentSceneId
|
|
|
|
* @param rawData
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Mesh = function(
|
|
|
|
id,
|
|
|
|
path,
|
|
|
|
name,
|
|
|
|
meshType,
|
|
|
|
vertices,
|
|
|
|
faces,
|
|
|
|
skeleton,
|
|
|
|
faceVertexUvs,
|
|
|
|
skinIndices,
|
|
|
|
skinWeights,
|
|
|
|
materials,
|
|
|
|
position,
|
|
|
|
quaternion,
|
|
|
|
rotation,
|
|
|
|
scale,
|
|
|
|
up,
|
|
|
|
physics,
|
|
|
|
parentMeshId,
|
|
|
|
parentSceneId,
|
|
|
|
rawData
|
|
|
|
) {
|
|
|
|
this.id = id;
|
|
|
|
this.path = path;
|
|
|
|
this.name = name;
|
|
|
|
this.meshType = meshType;
|
|
|
|
this.vertices = vertices;
|
|
|
|
this.faces = faces;
|
|
|
|
|
|
|
|
if (typeof skeleton == 'undefined') {
|
|
|
|
skeleton = null;
|
|
|
|
}
|
|
|
|
this.skeleton = skeleton;
|
|
|
|
|
|
|
|
if (typeof faceVertexUvs == 'undefined') {
|
|
|
|
faceVertexUvs = [];
|
|
|
|
}
|
|
|
|
this.faceVertexUvs = faceVertexUvs;
|
|
|
|
|
|
|
|
if (typeof skinIndices == 'undefined') {
|
|
|
|
skinIndices = [];
|
|
|
|
}
|
|
|
|
this.skinIndices = skinIndices;
|
|
|
|
|
|
|
|
if (typeof skinWeights == 'undefined') {
|
|
|
|
skinWeights = [];
|
|
|
|
}
|
|
|
|
this.skinWeights = skinWeights;
|
|
|
|
|
|
|
|
if (typeof materials == 'undefined') {
|
|
|
|
materials = [];
|
|
|
|
}
|
|
|
|
this.materials = materials;
|
|
|
|
|
|
|
|
if (typeof position == 'undefined') {
|
|
|
|
position = new GameLib.D3.Vector3(0,0,0);
|
|
|
|
}
|
|
|
|
this.position = position;
|
|
|
|
|
|
|
|
if (typeof quaternion == 'undefined') {
|
|
|
|
new GameLib.D3.Vector4();
|
|
|
|
}
|
|
|
|
this.quaternion = quaternion;
|
|
|
|
|
|
|
|
if (typeof rotation == 'undefined') {
|
|
|
|
rotation = new GameLib.D3.Vector3(0,0,0);
|
|
|
|
}
|
|
|
|
this.rotation = rotation;
|
|
|
|
|
|
|
|
if (typeof scale == 'undefined') {
|
|
|
|
scale = new GameLib.D3.Vector3(1,1,1);
|
|
|
|
}
|
|
|
|
this.scale = scale;
|
|
|
|
|
|
|
|
if (typeof up == 'undefined') {
|
|
|
|
up = new GameLib.D3.Vector3(0,1,0);
|
|
|
|
}
|
|
|
|
this.up = up;
|
|
|
|
|
|
|
|
this.physics = physics;
|
|
|
|
|
|
|
|
this.parentMeshId = parentMeshId;
|
|
|
|
|
|
|
|
this.parentSceneId = parentSceneId;
|
|
|
|
|
|
|
|
this.rawData = null;// rawData;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mesh Type
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Mesh.TYPE_NORMAL = 0;
|
|
|
|
GameLib.D3.Mesh.TYPE_SKINNED = 1;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a THREE Mesh from GameLib.D3.Mesh
|
|
|
|
* @param gameLibMesh GameLib.D3.Mesh
|
|
|
|
* @param instanceGeometry
|
|
|
|
* @param instanceMaterial
|
|
|
|
* @param graphics
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Mesh.createInstanceMesh = function(gameLibMesh, instanceGeometry, instanceMaterial, graphics) {
|
|
|
|
|
|
|
|
var threeMesh = null;
|
|
|
|
|
|
|
|
if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_NORMAL) {
|
|
|
|
threeMesh = new graphics.instance.Mesh(instanceGeometry, instanceMaterial);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_SKINNED) {
|
|
|
|
|
|
|
|
var bones = gameLibMesh.skeleton.bones;
|
|
|
|
|
|
|
|
var skinIndices = gameLibMesh.skinIndices;
|
|
|
|
|
|
|
|
var skinWeights = gameLibMesh.skinWeights;
|
|
|
|
|
|
|
|
var threeBones = [];
|
|
|
|
|
|
|
|
for (var bi = 0; bi < bones.length; bi++) {
|
|
|
|
|
|
|
|
var bone = new graphics.instance.Bone();
|
|
|
|
|
|
|
|
bone.name = bones[bi].name;
|
|
|
|
|
|
|
|
bone.position.x = bones[bi].position.x;
|
|
|
|
bone.position.y = bones[bi].position.y;
|
|
|
|
bone.position.z = bones[bi].position.z;
|
|
|
|
|
|
|
|
bone.rotation.x = bones[bi].rotation.x;
|
|
|
|
bone.rotation.y = bones[bi].rotation.y;
|
|
|
|
bone.rotation.z = bones[bi].rotation.z;
|
|
|
|
|
|
|
|
bone.quaternion.x = bones[bi].quaternion.x;
|
|
|
|
bone.quaternion.y = bones[bi].quaternion.y;
|
|
|
|
bone.quaternion.z = bones[bi].quaternion.z;
|
|
|
|
bone.quaternion.w = bones[bi].quaternion.w;
|
|
|
|
|
|
|
|
bone.scale.x = bones[bi].scale.x;
|
|
|
|
bone.scale.y = bones[bi].scale.y;
|
|
|
|
bone.scale.z = bones[bi].scale.z;
|
|
|
|
|
|
|
|
bone.up.x = bones[bi].up.x;
|
|
|
|
bone.up.y = bones[bi].up.y;
|
|
|
|
bone.up.z = bones[bi].up.z;
|
|
|
|
|
|
|
|
threeBones.push(bone);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup the bone relationships
|
|
|
|
*/
|
|
|
|
for (var br = 0; br < bones.length; br++) {
|
|
|
|
for (var cbi = 0; cbi < bones[br].childBoneIds.length; cbi++) {
|
|
|
|
threeBones[br].add(threeBones[bones[br].childBoneIds[cbi]]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup bones (indexes)
|
|
|
|
*/
|
|
|
|
for (var si = 0; si < skinIndices.length; si++) {
|
|
|
|
instanceGeometry.skinIndices.push(
|
|
|
|
new graphics.instance.Vector4(
|
|
|
|
skinIndices[si].x,
|
|
|
|
skinIndices[si].y,
|
|
|
|
skinIndices[si].z,
|
|
|
|
skinIndices[si].w
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup bones (weights)
|
|
|
|
*/
|
|
|
|
for (var sw = 0; sw < skinWeights.length; sw++) {
|
|
|
|
instanceGeometry.skinWeights.push(
|
|
|
|
new graphics.instance.Vector4(
|
|
|
|
skinWeights[sw].x,
|
|
|
|
skinWeights[sw].y,
|
|
|
|
skinWeights[sw].z,
|
|
|
|
skinWeights[sw].w
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
threeMesh = new graphics.instance.SkinnedMesh(instanceGeometry, instanceMaterial);
|
|
|
|
|
|
|
|
var skeleton = new graphics.instance.Skeleton(threeBones);
|
|
|
|
|
|
|
|
skeleton.useVertexTexture = gameLibMesh.skeleton.useVertexTexture;
|
|
|
|
|
|
|
|
for (var i = 0; i < bones.length; i++) {
|
|
|
|
if (bones[i].parentBoneId === null) {
|
|
|
|
threeMesh.add(threeBones[i]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
threeMesh.bind(skeleton);
|
|
|
|
|
|
|
|
threeMesh.pose();
|
|
|
|
|
|
|
|
threeMesh.skeleton.skeletonHelper = new graphics.instance.SkeletonHelper(threeMesh);
|
|
|
|
threeMesh.skeleton.skeletonHelper.material.linewidth = 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (threeMesh == null) {
|
|
|
|
console.log('cannot handle meshes of type ' + gameLibMesh.meshType + ' yet.');
|
|
|
|
}
|
|
|
|
|
|
|
|
gameLibMesh.threeMeshId = threeMesh.id;
|
|
|
|
|
|
|
|
return threeMesh;
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.prototype.invertWindingOrder = function(triangles) {
|
|
|
|
|
|
|
|
for (var i = 0; i < triangles.length; i++) {
|
|
|
|
var v1 = triangles[i].v1;
|
|
|
|
triangles[i].v1 = triangles[i].v2;
|
|
|
|
triangles[i].v2 = v1;
|
|
|
|
|
|
|
|
var backupUV = triangles[i].triangle.v1uv;
|
|
|
|
triangles[i].triangle.v1uv = triangles[i].triangle.v2uv;
|
|
|
|
triangles[i].triangle.v2uv = backupUV;
|
|
|
|
}
|
|
|
|
|
|
|
|
return triangles;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This function resets a the winding order of a mesh from a reference point V (the average center of the mesh)
|
|
|
|
*/
|
|
|
|
GameLib.D3.prototype.resetWindingOrder = function(faces, vertices) {
|
|
|
|
|
|
|
|
var vertexList = new GameLib.D3.Vector3.Points();
|
|
|
|
|
|
|
|
for (var v = 0; v < vertices.length; v++) {
|
|
|
|
vertexList.add(new GameLib.D3.Vector3(
|
|
|
|
vertices[v].position.x,
|
|
|
|
vertices[v].position.y,
|
|
|
|
vertices[v].position.z
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
var V = vertexList.average();
|
|
|
|
|
|
|
|
var triangles = [];
|
|
|
|
|
|
|
|
for (var s = 0; s < faces.length; s += 3) {
|
|
|
|
|
|
|
|
var v0 = faces[s];
|
|
|
|
var v1 = faces[s+1];
|
|
|
|
var v2 = faces[s+2];
|
|
|
|
|
|
|
|
triangles.push(
|
|
|
|
{
|
|
|
|
v0 : v0,
|
|
|
|
v1 : v1,
|
|
|
|
v2 : v2,
|
|
|
|
edges : [
|
|
|
|
{v0: v0, v1: v1},
|
|
|
|
{v0: v1, v1: v2},
|
|
|
|
{v0: v2, v1: v0}
|
|
|
|
],
|
|
|
|
winding : 0,
|
|
|
|
edgeIndex : -1,
|
|
|
|
processed : false
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < triangles.length; i++) {
|
|
|
|
if (
|
|
|
|
GameLib.D3.Vector3.clockwise(
|
|
|
|
vertices[triangles[i].v0].position,
|
|
|
|
vertices[triangles[i].v1].position,
|
|
|
|
vertices[triangles[i].v2].position,
|
|
|
|
V
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
console.log('clockwise');
|
|
|
|
var bv1 = triangles[i].v1;
|
|
|
|
triangles[i].v1 = triangles[i].v2;
|
|
|
|
triangles[i].v2 = bv1;
|
|
|
|
} else {
|
|
|
|
console.log('not clockwise');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return triangles;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This function resets the winding order for triangles in faces, given an initial triangle and orientation edge
|
|
|
|
* used pseudocode from
|
|
|
|
* http://stackoverflow.com/questions/17036970/how-to-correct-winding-of-triangles-to-counter-clockwise-direction-of-a-3d-mesh
|
|
|
|
* We need to use a graph traversal algorithm,
|
|
|
|
* lets assume we have method that returns neighbor of triangle on given edge
|
|
|
|
*
|
|
|
|
* neighbor_on_egde( next_tria, edge )
|
|
|
|
*
|
|
|
|
* to_process = set of pairs triangle and orientation edge, initial state is one good oriented triangle with any edge on it
|
|
|
|
* processed = set of processed triangles; initial empty
|
|
|
|
*
|
|
|
|
* while to_process is not empty:
|
|
|
|
* next_tria, orientation_edge = to_process.pop()
|
|
|
|
* add next_tria in processed
|
|
|
|
* if next_tria is not opposite oriented than orientation_edge:
|
|
|
|
* change next_tria (ABC) orientation (B<->C)
|
|
|
|
* for each edge (AB) in next_tria:
|
|
|
|
* neighbor_tria = neighbor_on_egde( next_tria, edge )
|
|
|
|
* if neighbor_tria exists and neighbor_tria not in processed:
|
|
|
|
* to_process add (neighbor_tria, edge opposite oriented (BA))
|
|
|
|
* @param faces GameLib.D3.TriangleFace[]
|
|
|
|
* @param orientationEdge GameLib.D3.Vector2
|
|
|
|
* @returns {Array}
|
|
|
|
*/
|
|
|
|
GameLib.D3.fixWindingOrder = function(faces, orientationEdge) {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if a TriangleFace belonging to a TriangleEdge has already been processed
|
|
|
|
* @param processed TriangleEdge[]
|
|
|
|
* @param triangle TriangleFace
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
function inProcessed(processed, triangle) {
|
|
|
|
|
|
|
|
for (var i = 0; i < processed.length; i++) {
|
|
|
|
if (processed[i].triangle.equals(triangle)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a neighbouring triangle on a specific edge - preserving the edge orientation
|
|
|
|
* @param edge GameLib.D3.Vector2
|
|
|
|
* @param faces GameLib.D3.TriangleFace[]
|
|
|
|
* @param currentTriangle
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
|
|
|
function neighbourOnEdge(edge, faces, currentTriangle) {
|
|
|
|
|
|
|
|
for (var i = 0; i < faces.length; i++) {
|
|
|
|
if (
|
|
|
|
(faces[i].v0 == edge.x && faces[i].v1 == edge.y) ||
|
|
|
|
(faces[i].v1 == edge.x && faces[i].v2 == edge.y) ||
|
|
|
|
(faces[i].v2 == edge.x && faces[i].v0 == edge.y) ||
|
|
|
|
(faces[i].v0 == edge.y && faces[i].v1 == edge.x) ||
|
|
|
|
(faces[i].v1 == edge.y && faces[i].v2 == edge.x) ||
|
|
|
|
(faces[i].v2 == edge.y && faces[i].v0 == edge.x)
|
|
|
|
) {
|
|
|
|
|
|
|
|
var triangle = new GameLib.D3.TriangleFace(
|
|
|
|
faces[i].v0,
|
|
|
|
faces[i].v1,
|
|
|
|
faces[i].v2,
|
|
|
|
faces[i].materialIndex,
|
|
|
|
faces[i].v0uv,
|
|
|
|
faces[i].v1uv,
|
|
|
|
faces[i].v2uv
|
|
|
|
);
|
|
|
|
|
|
|
|
if (triangle.equals(currentTriangle)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new GameLib.D3.TriangleEdge(
|
|
|
|
triangle,
|
|
|
|
edge
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
var toProcess = [
|
|
|
|
new GameLib.D3.TriangleEdge(
|
|
|
|
new GameLib.D3.TriangleFace(
|
|
|
|
faces[0].v0,
|
|
|
|
faces[0].v1,
|
|
|
|
faces[0].v2,
|
|
|
|
faces[0].materialIndex,
|
|
|
|
faces[0].v0uv,
|
|
|
|
faces[0].v1uv,
|
|
|
|
faces[0].v2uv
|
|
|
|
),
|
|
|
|
orientationEdge
|
|
|
|
)
|
|
|
|
];
|
|
|
|
|
|
|
|
var processed = [];
|
|
|
|
|
|
|
|
while (toProcess.length > 0) {
|
|
|
|
|
|
|
|
var triangleEdge = toProcess.pop();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If edge is the same orientation (i.e. the edge order is the same as the given triangle edge) it needs to be reversed
|
|
|
|
* to have the same winding order)
|
|
|
|
*/
|
|
|
|
if (
|
|
|
|
(triangleEdge.triangle.v0 == triangleEdge.edge.x &&
|
|
|
|
triangleEdge.triangle.v1 == triangleEdge.edge.y) ||
|
|
|
|
(triangleEdge.triangle.v1 == triangleEdge.edge.x &&
|
|
|
|
triangleEdge.triangle.v2 == triangleEdge.edge.y) ||
|
|
|
|
(triangleEdge.triangle.v2 == triangleEdge.edge.x &&
|
|
|
|
triangleEdge.triangle.v0 == triangleEdge.edge.y)
|
|
|
|
) {
|
|
|
|
var backupV = triangleEdge.triangle.v1;
|
|
|
|
triangleEdge.triangle.v1 = triangleEdge.triangle.v2;
|
|
|
|
triangleEdge.triangle.v2 = backupV;
|
|
|
|
|
|
|
|
var backupUV = triangleEdge.triangle.v1uv;
|
|
|
|
triangleEdge.triangle.v1uv = triangleEdge.triangle.v2uv;
|
|
|
|
triangleEdge.triangle.v2uv = backupUV;
|
|
|
|
}
|
|
|
|
|
|
|
|
processed.push(triangleEdge);
|
|
|
|
|
|
|
|
var edges = [
|
|
|
|
new GameLib.D3.Vector2(
|
|
|
|
triangleEdge.triangle.v0,
|
|
|
|
triangleEdge.triangle.v1
|
|
|
|
),
|
|
|
|
new GameLib.D3.Vector2(
|
|
|
|
triangleEdge.triangle.v1,
|
|
|
|
triangleEdge.triangle.v2
|
|
|
|
),
|
|
|
|
new GameLib.D3.Vector2(
|
|
|
|
triangleEdge.triangle.v2,
|
|
|
|
triangleEdge.triangle.v0
|
|
|
|
)
|
|
|
|
];
|
|
|
|
|
|
|
|
for (var j = 0; j < edges.length; j++) {
|
|
|
|
var neighbour = neighbourOnEdge(edges[j], faces, triangleEdge.triangle);
|
|
|
|
if (neighbour && !inProcessed(processed, neighbour.triangle)) {
|
|
|
|
toProcess.push(neighbour);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* In processed - we will have some duplicates - only add the unique ones
|
|
|
|
* @type {Array}
|
|
|
|
*/
|
|
|
|
var triangles = [];
|
|
|
|
for (var i = 0; i < processed.length; i++) {
|
|
|
|
var found = false;
|
|
|
|
for (var k = 0; k < triangles.length; k++) {
|
|
|
|
if (triangles[k].equals(processed[i].triangle)){
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
triangles.push(processed[i].triangle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return triangles;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is a work-around function to fix polys which don't triangulate because
|
|
|
|
* they could lie on Z-plane (XZ or YZ)) - we translate the poly to the origin, systematically rotate the poly around
|
|
|
|
* Z then Y axis
|
|
|
|
* @param verticesFlat []
|
|
|
|
* @param grain is the amount to systematically rotate the poly by - a finer grain means a more accurate maximum XY
|
|
|
|
* @return []
|
|
|
|
*/
|
|
|
|
GameLib.D3.fixPolyZPlane = function(verticesFlat, grain) {
|
|
|
|
|
|
|
|
if ((verticesFlat.length % 3) != 0 && !(verticesFlat.length > 9)) {
|
|
|
|
console.log("The vertices are not in the right length : " + verticesFlat.length);
|
|
|
|
}
|
|
|
|
|
|
|
|
var vertices = [];
|
|
|
|
|
|
|
|
var points = new GameLib.D3.Vector4.Points();
|
|
|
|
|
|
|
|
for (var i = 0; i < verticesFlat.length; i += 3) {
|
|
|
|
points.add(new GameLib.D3.Vector3(
|
|
|
|
verticesFlat[i],
|
|
|
|
verticesFlat[i + 1],
|
|
|
|
verticesFlat[i + 2]
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
points.toOrigin();
|
|
|
|
|
|
|
|
points.maximizeXDistance(grain);
|
|
|
|
|
|
|
|
points.maximizeYDistance(grain);
|
|
|
|
|
|
|
|
for (i = 0; i < points.vectors.length; i++) {
|
|
|
|
vertices.push(
|
|
|
|
[
|
|
|
|
points.vectors[i].x,
|
|
|
|
points.vectors[i].y
|
|
|
|
]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return vertices;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* Physics SuperSet Namespace Object
|
|
|
|
* @param id
|
|
|
|
* @param name
|
|
|
|
* @param engine GameLib.D3.Engine
|
|
|
|
* @param worlds
|
|
|
|
* @returns {{World: World}}
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Physics = function(
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
engine,
|
|
|
|
worlds
|
|
|
|
) {
|
|
|
|
this.id = id;
|
|
|
|
this.name = name;
|
|
|
|
this.engine = engine;
|
|
|
|
|
|
|
|
if (typeof worlds == 'undefined') {
|
|
|
|
worlds = [];
|
|
|
|
}
|
|
|
|
this.worlds = worlds;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Solver Types
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Physics.SPLIT_SOLVER = 0x1;
|
|
|
|
GameLib.D3.Physics.GS_SOLVER = 0x2;
|
|
|
|
/**
|
|
|
|
* Contains a Poly vertex data structure
|
|
|
|
* @param localIndex
|
|
|
|
* @param mvertIndex
|
|
|
|
* @param uv GameLib.D3.Vector2
|
|
|
|
* @param materialIndex
|
|
|
|
* @param edgeIndex
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.PolyVertex = function(
|
|
|
|
localIndex,
|
|
|
|
mvertIndex,
|
|
|
|
uv,
|
|
|
|
materialIndex,
|
|
|
|
edgeIndex
|
|
|
|
) {
|
|
|
|
this.localIndex = localIndex;
|
|
|
|
this.mvertIndex = mvertIndex;
|
|
|
|
this.uv = uv;
|
|
|
|
this.materialIndex = materialIndex;
|
|
|
|
this.edgeIndex = edgeIndex;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clone a PolyVertex
|
|
|
|
* @returns {GameLib.D3.PolyVertex}
|
|
|
|
*/
|
|
|
|
GameLib.D3.PolyVertex.prototype.clone = function() {
|
|
|
|
return new GameLib.D3.PolyVertex(
|
|
|
|
this.localIndex,
|
|
|
|
this.mvertIndex,
|
|
|
|
this.uv.copy(),
|
|
|
|
this.materialIndex,
|
|
|
|
this.edgeIndex
|
|
|
|
)
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param engine GamLib.D3.Engine
|
|
|
|
* @param chassisBody GamLib.D3.RigidBody
|
2016-10-28 12:53:08 +02:00
|
|
|
* @param wheels GameLib.D3.RaycastWheel[]
|
2016-10-28 11:50:55 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.RaycastVehicle = function(
|
|
|
|
engine,
|
2016-10-28 12:53:08 +02:00
|
|
|
chassisBody,
|
|
|
|
wheels
|
2016-10-28 11:50:55 +02:00
|
|
|
) {
|
|
|
|
this.engine = engine;
|
|
|
|
this.engine.isNotCannonThrow();
|
|
|
|
|
|
|
|
this.chassisBody = chassisBody;
|
|
|
|
|
2016-10-28 12:53:08 +02:00
|
|
|
if (typeof wheels == 'undefined') {
|
|
|
|
wheels = [];
|
|
|
|
}
|
|
|
|
this.wheels = wheels;
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.instance = this.createInstance();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* private
|
|
|
|
* @returns {GameLib.D3.RaycastVehicle|GameLib.D3.Physics.RaycastVehicle|*}
|
|
|
|
*/
|
|
|
|
GameLib.D3.RaycastVehicle.prototype.createInstance = function() {
|
2016-10-28 13:11:53 +02:00
|
|
|
return new this.engine.instance.RaycastVehicle({
|
2016-10-28 11:50:55 +02:00
|
|
|
chassisBody: this.chassisBody.instance
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds a raycast wheel to this vehicle
|
|
|
|
* @param wheel GameLib.D3.RaycastWheel
|
|
|
|
*/
|
|
|
|
GameLib.D3.RaycastVehicle.prototype.addWheel = function (
|
|
|
|
wheel
|
|
|
|
) {
|
2016-10-28 12:53:08 +02:00
|
|
|
this.wheels.push(wheel);
|
|
|
|
this.instance.addWheel(wheel.instance);
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
|
|
|
GameLib.D3.RaycastWheel = function(
|
|
|
|
engine,
|
|
|
|
chassisConnectionPointLocal,
|
|
|
|
chassisConnectionPointWorld,
|
|
|
|
directionLocal,
|
|
|
|
directionWorld,
|
|
|
|
axleLocal,
|
|
|
|
axleWorld,
|
|
|
|
suspensionRestLength,
|
|
|
|
suspensionMaxLength,
|
|
|
|
radius,
|
|
|
|
suspensionStiffness,
|
|
|
|
dampingCompression,
|
|
|
|
dampingRelaxation,
|
|
|
|
frictionSlip,
|
|
|
|
steering,
|
|
|
|
rotation,
|
|
|
|
deltaRotation,
|
|
|
|
rollInfluence,
|
|
|
|
maxSuspensionForce,
|
|
|
|
isFrontWheel,
|
|
|
|
clippedInvContactDotSuspension,
|
|
|
|
suspensionRelativeVelocity,
|
|
|
|
suspensionForce,
|
|
|
|
skidInfo,
|
|
|
|
suspensionLength,
|
|
|
|
maxSuspensionTravel,
|
|
|
|
useCustomSlidingRotationalSpeed,
|
|
|
|
customSlidingRotationalSpeed
|
|
|
|
) {
|
|
|
|
this.engine = engine;
|
|
|
|
this.engine.isNotCannonThrow();
|
|
|
|
|
|
|
|
if(typeof chassisConnectionPointLocal == 'undefined') {
|
|
|
|
chassisConnectionPointLocal = new this.engine.instance.Vec3();
|
|
|
|
}
|
|
|
|
this.chassisConnectionPointLocal = chassisConnectionPointLocal;
|
|
|
|
|
|
|
|
if(typeof chassisConnectionPointWorld == 'undefined') {
|
|
|
|
chassisConnectionPointWorld = new this.engine.instance.Vec3();
|
|
|
|
}
|
|
|
|
this.chassisConnectionPointWorld = chassisConnectionPointWorld;
|
|
|
|
|
|
|
|
if(typeof directionLocal == 'undefined') {
|
|
|
|
directionLocal = new this.engine.instance.Vec3();
|
|
|
|
}
|
|
|
|
this.directionLocal = directionLocal;
|
|
|
|
|
|
|
|
if(typeof directionWorld == 'undefined') {
|
|
|
|
directionWorld = new this.engine.instance.Vec3();
|
|
|
|
}
|
|
|
|
this.directionWorld = directionWorld;
|
|
|
|
|
|
|
|
if(typeof axleLocal == 'undefined') {
|
|
|
|
axleLocal = new this.engine.instance.Vec3();
|
|
|
|
}
|
|
|
|
this.axleLocal = axleLocal;
|
|
|
|
|
|
|
|
if(typeof axleWorld == 'undefined') {
|
|
|
|
axleWorld = new this.engine.instance.Vec3();
|
|
|
|
}
|
|
|
|
this.axleWorld = axleWorld;
|
|
|
|
|
|
|
|
if(typeof suspensionRestLength == 'undefined') {
|
|
|
|
suspensionRestLength = 1;
|
|
|
|
}
|
|
|
|
this.suspensionRestLength = suspensionRestLength;
|
|
|
|
|
|
|
|
if(typeof suspensionMaxLength == 'undefined') {
|
|
|
|
suspensionMaxLength = 2;
|
|
|
|
}
|
|
|
|
this.suspensionMaxLength = suspensionMaxLength;
|
|
|
|
|
|
|
|
if(typeof radius == 'undefined') {
|
|
|
|
radius = 1;
|
|
|
|
}
|
|
|
|
this.radius = radius;
|
|
|
|
|
|
|
|
if(typeof suspensionStiffness == 'undefined') {
|
|
|
|
suspensionStiffness = 100;
|
|
|
|
}
|
|
|
|
this.suspensionStiffness = suspensionStiffness;
|
|
|
|
|
|
|
|
if(typeof dampingCompression == 'undefined') {
|
|
|
|
dampingCompression = 10;
|
|
|
|
}
|
|
|
|
this.dampingCompression = dampingCompression;
|
|
|
|
|
|
|
|
if(typeof dampingRelaxation == 'undefined') {
|
|
|
|
dampingRelaxation = 10;
|
|
|
|
}
|
|
|
|
this.dampingRelaxation = dampingRelaxation;
|
|
|
|
|
|
|
|
if(typeof frictionSlip == 'undefined') {
|
|
|
|
frictionSlip = 10000;
|
|
|
|
}
|
|
|
|
this.frictionSlip = frictionSlip;
|
|
|
|
|
|
|
|
if(typeof steering == 'undefined') {
|
|
|
|
steering = 0;
|
|
|
|
}
|
|
|
|
this.steering = steering;
|
|
|
|
|
|
|
|
if(typeof rotation == 'undefined') {
|
|
|
|
rotation = 0;
|
|
|
|
}
|
|
|
|
this.rotation = rotation;
|
|
|
|
|
|
|
|
if(typeof deltaRotation == 'undefined') {
|
|
|
|
deltaRotation = 0;
|
|
|
|
}
|
|
|
|
this.deltaRotation = deltaRotation;
|
|
|
|
|
|
|
|
if(typeof rollInfluence == 'undefined') {
|
|
|
|
rollInfluence = 0.01;
|
|
|
|
}
|
|
|
|
this.rollInfluence = rollInfluence;
|
|
|
|
|
|
|
|
if(typeof maxSuspensionForce == 'undefined') {
|
|
|
|
maxSuspensionForce = Number.MAX_VALUE;
|
|
|
|
}
|
|
|
|
this.maxSuspensionForce = maxSuspensionForce;
|
|
|
|
|
|
|
|
if(typeof isFrontWheel == 'undefined') {
|
|
|
|
isFrontWheel = true;
|
|
|
|
}
|
|
|
|
this.isFrontWheel = isFrontWheel;
|
|
|
|
|
|
|
|
if(typeof clippedInvContactDotSuspension == 'undefined') {
|
|
|
|
clippedInvContactDotSuspension = 1;
|
|
|
|
}
|
|
|
|
this.clippedInvContactDotSuspension = clippedInvContactDotSuspension;
|
|
|
|
|
|
|
|
if(typeof suspensionRelativeVelocity == 'undefined') {
|
|
|
|
suspensionRelativeVelocity = 0;
|
|
|
|
}
|
|
|
|
this.suspensionRelativeVelocity = suspensionRelativeVelocity;
|
|
|
|
|
|
|
|
if(typeof suspensionForce == 'undefined') {
|
|
|
|
suspensionForce = 0;
|
|
|
|
}
|
|
|
|
this.suspensionForce = suspensionForce;
|
|
|
|
|
|
|
|
if(typeof skidInfo == 'undefined') {
|
|
|
|
skidInfo = 0;
|
|
|
|
}
|
|
|
|
this.skidInfo = skidInfo;
|
|
|
|
|
|
|
|
if(typeof suspensionLength == 'undefined') {
|
|
|
|
suspensionLength = 0;
|
|
|
|
}
|
|
|
|
this.suspensionLength = suspensionLength;
|
|
|
|
|
|
|
|
if(typeof maxSuspensionTravel == 'undefined') {
|
|
|
|
maxSuspensionTravel = 1;
|
|
|
|
}
|
|
|
|
this.maxSuspensionTravel = maxSuspensionTravel;
|
|
|
|
|
|
|
|
if(typeof useCustomSlidingRotationalSpeed == 'undefined') {
|
|
|
|
useCustomSlidingRotationalSpeed = false;
|
|
|
|
}
|
|
|
|
this.useCustomSlidingRotationalSpeed = useCustomSlidingRotationalSpeed;
|
|
|
|
|
|
|
|
if(typeof customSlidingRotationalSpeed == 'undefined') {
|
|
|
|
customSlidingRotationalSpeed = -0.1;
|
|
|
|
}
|
|
|
|
this.customSlidingRotationalSpeed = customSlidingRotationalSpeed;
|
2016-10-28 12:53:08 +02:00
|
|
|
|
|
|
|
this.instance = this.createInstance();
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.RaycastWheel.prototype.createInstance = function() {
|
|
|
|
|
|
|
|
return new this.engine.instance.WheelInfo({
|
|
|
|
chassisConnectionPointLocal : this.chassisConnectionPointLocal,
|
|
|
|
chassisConnectionPointWorld : this.chassisConnectionPointWorld,
|
|
|
|
directionLocal : this.directionLocal,
|
|
|
|
directionWorld : this.directionWorld,
|
|
|
|
axleLocal : this.axleLocal,
|
|
|
|
axleWorld : this.axleWorld,
|
|
|
|
suspensionRestLength : this.suspensionRestLength,
|
|
|
|
suspensionMaxLength : this.suspensionMaxLength,
|
|
|
|
radius : this.radius,
|
|
|
|
suspensionStiffness : this.suspensionStiffness,
|
|
|
|
dampingCompression : this.dampingCompression,
|
|
|
|
dampingRelaxation : this.dampingRelaxation,
|
|
|
|
frictionSlip : this.frictionSlip,
|
|
|
|
steering : this.steering,
|
|
|
|
rotation : this.rotation,
|
|
|
|
deltaRotation : this.deltaRotation,
|
|
|
|
rollInfluence : this.rollInfluence,
|
|
|
|
maxSuspensionForce : this.maxSuspensionForce,
|
|
|
|
isFrontWheel : this.isFrontWheel,
|
|
|
|
clippedInvContactDotSuspension : this.clippedInvContactDotSuspension,
|
|
|
|
suspensionRelativeVelocity : this.suspensionRelativeVelocity,
|
|
|
|
suspensionForce : this.suspensionForce,
|
|
|
|
skidInfo : this.skidInfo,
|
|
|
|
suspensionLength : this.suspensionLength,
|
|
|
|
maxSuspensionTravel : this.maxSuspensionTravel,
|
|
|
|
useCustomSlidingRotationalSpeed : this.useCustomSlidingRotationalSpeed,
|
|
|
|
customSlidingRotationalSpeed : this.customSlidingRotationalSpeed
|
|
|
|
});
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Physics Rigid Body Vehicle Superset
|
2016-10-28 13:11:53 +02:00
|
|
|
* @param engine
|
|
|
|
* @param chassisBody
|
|
|
|
* @param wheels
|
2016-10-28 11:50:55 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.RigidBodyVehicle = function(
|
2016-10-28 13:11:53 +02:00
|
|
|
engine,
|
|
|
|
chassisBody,
|
|
|
|
wheels
|
2016-10-28 11:50:55 +02:00
|
|
|
) {
|
|
|
|
this.engine = engine;
|
|
|
|
this.engine.isNotCannonThrow();
|
|
|
|
|
2016-10-28 13:11:53 +02:00
|
|
|
this.chassisBody = chassisBody;
|
2016-10-28 11:50:55 +02:00
|
|
|
|
2016-10-28 13:11:53 +02:00
|
|
|
if (typeof wheels == 'undefined') {
|
|
|
|
wheels = [];
|
|
|
|
}
|
|
|
|
this.wheels = wheels;
|
|
|
|
|
|
|
|
this.instance = this.createInstance();
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2016-10-28 13:11:53 +02:00
|
|
|
* @returns {GameLib.D3.RigidVehicle}
|
2016-10-28 11:50:55 +02:00
|
|
|
*/
|
2016-10-28 13:11:53 +02:00
|
|
|
GameLib.D3.RigidBodyVehicle.prototype.createInstance = function() {
|
|
|
|
return new this.engine.instance.RigidVehicle({
|
|
|
|
chassisBody: this.chassisBody.instance
|
2016-10-28 11:50:55 +02:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds a wheel to this rigid body vehicle
|
2016-10-28 13:11:53 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 13:11:53 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param wheel
|
|
|
|
*/
|
|
|
|
GameLib.D3.RigidBodyVehicle.prototype.addWheel = function(wheel) {
|
|
|
|
this.wheels.push(wheel);
|
|
|
|
this.instance.addWheel(wheel.instance);
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* RigidBody Superset
|
|
|
|
* @param engine GameLib.D3.Engine
|
|
|
|
* @param mass
|
|
|
|
* @param friction
|
|
|
|
* @param position
|
|
|
|
* @param quaternion
|
|
|
|
* @param velocity
|
|
|
|
* @param angularVelocity
|
|
|
|
* @param linearDamping
|
|
|
|
* @param angularDamping
|
|
|
|
* @param allowSleep
|
|
|
|
* @param sleepSpeedLimit
|
|
|
|
* @param sleepTimeLimit
|
|
|
|
* @param collisionFilterGroup
|
|
|
|
* @param collisionFilterMask
|
|
|
|
* @param fixedRotation
|
|
|
|
* @param shape GameLib.D3.Shape
|
|
|
|
* @returns {GameLib.D3.Physics.RigidBody}
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.RigidBody = function(
|
|
|
|
engine,
|
|
|
|
mass,
|
|
|
|
friction,
|
|
|
|
position,
|
|
|
|
quaternion,
|
|
|
|
velocity,
|
|
|
|
angularVelocity,
|
|
|
|
linearDamping,
|
|
|
|
angularDamping,
|
|
|
|
allowSleep,
|
|
|
|
sleepSpeedLimit,
|
|
|
|
sleepTimeLimit,
|
|
|
|
collisionFilterGroup,
|
|
|
|
collisionFilterMask,
|
|
|
|
fixedRotation,
|
|
|
|
shape
|
|
|
|
) {
|
|
|
|
|
|
|
|
this.position = position || new GameLib.D3.Vector3();
|
|
|
|
this.velocity = velocity || new GameLib.D3.Vector3();
|
|
|
|
this.angularVelocity = angularVelocity || new GameLib.D3.Vector3();
|
|
|
|
this.quaternion = quaternion || new GameLib.D3.Vector4(0, 0, 0, 1);
|
|
|
|
this.mass = typeof mass == "undefined" ? 0 : mass;
|
|
|
|
this.friction = typeof friction == "undefined" ? 5 : friction;
|
|
|
|
this.linearDamping = typeof linearDamping == "undefined" ? 0.01 : linearDamping;
|
|
|
|
this.angularDamping = typeof angularDamping == "undefined" ? 0.01 : angularDamping;
|
|
|
|
this.allowSleep = typeof allowSleep == "undefined" ? true : allowSleep;
|
|
|
|
this.sleepSpeedLimit = typeof sleepSpeedLimit == "undefined" ? 0.1 : sleepSpeedLimit;
|
|
|
|
this.sleepTimeLimit = typeof sleepTimeLimit == "undefined" ? 1.0 : sleepTimeLimit;
|
|
|
|
this.collisionFilterGroup = typeof collisionFilterGroup == "undefined" ? 1 : collisionFilterGroup;
|
|
|
|
this.collisionFilterMask = typeof collisionFilterMask == "undefined" ? 1 : collisionFilterMask;
|
|
|
|
this.fixedRotation = typeof fixedRotation == "undefined" ? false : fixedRotation;
|
|
|
|
this.shape = typeof shape == "undefined" ? null : shape;
|
|
|
|
|
|
|
|
this.engine = engine;
|
|
|
|
|
|
|
|
this.engine.isNotCannonThrow();
|
|
|
|
|
|
|
|
this.instance = this.createInstance();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* private function
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
|
|
|
GameLib.D3.RigidBody.prototype.createInstance = function() {
|
|
|
|
|
|
|
|
var instance = new this.engine.instance.Body({
|
|
|
|
mass: mass,
|
|
|
|
friction: this.friction,
|
|
|
|
position: new this.engine.instance.Vec3(
|
|
|
|
this.position.x,
|
|
|
|
this.position.y,
|
|
|
|
this.position.z
|
|
|
|
),
|
|
|
|
velocity: new this.engine.instance.Vec3(
|
|
|
|
this.velocity.x,
|
|
|
|
this.velocity.y,
|
|
|
|
this.velocity.z
|
|
|
|
),
|
|
|
|
quaternion: new this.engine.instance.Quaternion(
|
|
|
|
this.quaternion.x,
|
|
|
|
this.quaternion.y,
|
|
|
|
this.quaternion.z,
|
|
|
|
this.quaternion.w
|
|
|
|
),
|
|
|
|
angularVelocity: new this.engine.instance.Vec3(
|
|
|
|
this.angularVelocity.x,
|
|
|
|
this.angularVelocity.y,
|
|
|
|
this.angularVelocity.z
|
|
|
|
),
|
|
|
|
linearDamping: this.linearDamping,
|
|
|
|
angularDamping: this.angularDamping,
|
|
|
|
allowSleep: this.allowSleep,
|
|
|
|
sleepSpeedLimit: this.sleepSpeedLimit,
|
|
|
|
sleepTimeLimit: this.sleepTimeLimit,
|
|
|
|
collisionFilterGroup: this.collisionFilterGroup,
|
|
|
|
collisionFilterMask: this.collisionFilterMask,
|
|
|
|
fixedRotation: this.fixedRotation,
|
|
|
|
shape: this.shape.instance
|
|
|
|
});
|
|
|
|
|
|
|
|
this.instance = instance;
|
|
|
|
|
|
|
|
return instance;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds a shape to this rigid body
|
|
|
|
* @param shape GameLib.D3.Shape
|
|
|
|
* @param offset GameLib.D3.Vector3
|
|
|
|
* @param orientation GameLib.D3.Vector4
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.RigidBody.prototype.addShape = function(
|
|
|
|
shape,
|
|
|
|
offset,
|
|
|
|
orientation
|
|
|
|
) {
|
|
|
|
if (!offset) {
|
|
|
|
offset = new GameLib.D3.Vector3(0,0,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!orientation) {
|
|
|
|
orientation = new GameLib.D3.Vector4(0,0,0,1);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.instance.addShape(
|
|
|
|
shape.instance,
|
|
|
|
new this.engine.instance.Vec3(
|
|
|
|
offset.x,
|
|
|
|
offset.y,
|
|
|
|
offset.z
|
|
|
|
),
|
|
|
|
new this.engine.instance.Quaternion(
|
|
|
|
orientation.x,
|
|
|
|
orientation.y,
|
|
|
|
orientation.z,
|
|
|
|
orientation.w
|
|
|
|
)
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-10-28 13:11:53 +02:00
|
|
|
/**
|
|
|
|
* Created by tj on 28.10.16.
|
|
|
|
*/
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Scenes are objects putting meshes into 'world space'
|
|
|
|
* @param id
|
|
|
|
* @param path String
|
|
|
|
* @param name String
|
|
|
|
* @param meshes GameLib.D3.Mesh[]
|
|
|
|
* @param quaternion
|
|
|
|
* @param position
|
|
|
|
* @param rotation
|
|
|
|
* @param scale
|
|
|
|
* @param parentSceneId
|
|
|
|
* @param lights
|
|
|
|
* @param physics GameLib.D3.Physics
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Scene = function(
|
|
|
|
id,
|
|
|
|
path,
|
|
|
|
name,
|
|
|
|
meshes,
|
|
|
|
quaternion,
|
|
|
|
position,
|
|
|
|
rotation,
|
|
|
|
scale,
|
|
|
|
parentSceneId,
|
|
|
|
lights,
|
|
|
|
physics
|
|
|
|
) {
|
|
|
|
this.id = id;
|
|
|
|
this.path = path;
|
|
|
|
this.name = name;
|
|
|
|
if (this.name.trim() == "") {
|
|
|
|
this.name = 'unnamed';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof meshes == 'undefined') {
|
|
|
|
meshes = [];
|
|
|
|
}
|
|
|
|
this.meshes = meshes;
|
|
|
|
|
|
|
|
if (typeof quaternion == 'undefined') {
|
|
|
|
quaternion = new GameLib.D3.Vector4();
|
|
|
|
}
|
|
|
|
this.quaternion = quaternion;
|
|
|
|
|
|
|
|
if (typeof position == 'undefined') {
|
|
|
|
position = new GameLib.D3.Vector3(0,0,0);
|
|
|
|
}
|
|
|
|
this.position = position;
|
|
|
|
|
|
|
|
if (typeof rotation == 'undefined') {
|
|
|
|
rotation = new GameLib.D3.Vector3(0,0,0);
|
|
|
|
}
|
|
|
|
this.rotation = rotation;
|
|
|
|
|
|
|
|
if (typeof scale == 'undefined') {
|
|
|
|
scale = new GameLib.D3.Vector3(1,1,1);
|
|
|
|
}
|
|
|
|
this.scale = scale;
|
|
|
|
|
|
|
|
if (typeof parentSceneId == 'undefined') {
|
|
|
|
parentSceneId = null;
|
|
|
|
}
|
|
|
|
this.parentSceneId = parentSceneId;
|
|
|
|
|
|
|
|
if (typeof lights == 'undefined') {
|
|
|
|
lights = [];
|
|
|
|
}
|
|
|
|
this.lights = lights;
|
|
|
|
|
|
|
|
if (typeof physics == 'undefined') {
|
|
|
|
physics = [];
|
|
|
|
}
|
|
|
|
this.physics = physics;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Loads a scene directly from the API
|
|
|
|
* @param gameLibScene GameLib.D3.Scene
|
|
|
|
* @param onLoaded callback
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param uploadUrl String
|
|
|
|
* @param progressCallback callback
|
|
|
|
* @param apiUrl
|
|
|
|
*/
|
|
|
|
GameLib.D3.Scene.loadSceneFromApi = function(
|
|
|
|
gameLibScene,
|
|
|
|
onLoaded,
|
|
|
|
graphics,
|
|
|
|
uploadUrl,
|
|
|
|
progressCallback,
|
|
|
|
apiUrl
|
|
|
|
) {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* First check if this is a client or server side request
|
|
|
|
*/
|
|
|
|
if (typeof XMLHttpRequest == 'undefined') {
|
|
|
|
console.warn('implement server side loading from API here');
|
|
|
|
return onLoaded(null, new Error('not implemented'));
|
|
|
|
}
|
|
|
|
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
|
|
xhr.open(
|
|
|
|
'GET',
|
|
|
|
apiUrl + '/scene/load' + gameLibScene.path + '/' + gameLibScene.name
|
|
|
|
);
|
|
|
|
|
|
|
|
xhr.onreadystatechange = function(xhr) {
|
|
|
|
return function() {
|
|
|
|
if (xhr.readyState == 4) {
|
|
|
|
|
|
|
|
var response = JSON.parse(xhr.responseText);
|
|
|
|
|
|
|
|
if (!response.scene || response.scene.length == 0) {
|
|
|
|
return onLoaded(null, null, new Error('Could not load scene'));
|
|
|
|
}
|
|
|
|
|
|
|
|
var scene = response.scene[0];
|
|
|
|
|
|
|
|
var physics3ds = [];
|
|
|
|
|
|
|
|
if (scene.physics && scene.physics.length > 0) {
|
|
|
|
|
|
|
|
for (var p = 0; p < scene.physics.length; p++) {
|
|
|
|
|
|
|
|
var physics = scene.physics[p];
|
|
|
|
|
|
|
|
var engine = null;
|
|
|
|
|
|
|
|
if (physics.engine.engineType == GameLib.D3.Engine.ENGINE_TYPE_CANNON) {
|
|
|
|
engine = new GameLib.D3.Engine(
|
|
|
|
GameLib.D3.Engine.ENGINE_TYPE_CANNON,
|
|
|
|
CANNON
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
var physics3d = new GameLib.D3.Physics(
|
|
|
|
physics.id,
|
|
|
|
physics.name,
|
|
|
|
engine,
|
|
|
|
null
|
|
|
|
);
|
|
|
|
|
|
|
|
var worlds3d = [];
|
|
|
|
|
|
|
|
for (var w = 0; w < physics.worlds.length; w++) {
|
|
|
|
|
|
|
|
var world = physics.worlds[w];
|
|
|
|
|
|
|
|
var broadphase = world.broadphase;
|
|
|
|
|
|
|
|
var broadphase3d = new GameLib.D3.Physics.Broadphase(
|
|
|
|
broadphase.id,
|
|
|
|
broadphase.name,
|
|
|
|
broadphase.broadphaseType
|
|
|
|
);
|
|
|
|
|
|
|
|
var solver = world.solver;
|
|
|
|
|
|
|
|
var solver3d = new GameLib.D3.Physics.Solver(
|
|
|
|
solver.id,
|
|
|
|
solver.name,
|
|
|
|
solver.solverType,
|
|
|
|
solver.iterations,
|
|
|
|
solver.tolerance
|
|
|
|
);
|
|
|
|
|
|
|
|
var bodies = world.rigidBodies;
|
|
|
|
|
|
|
|
var bodies3d = [];
|
|
|
|
|
|
|
|
for (var b = 0; b < bodies.length; b++) {
|
|
|
|
|
|
|
|
var body = bodies[b];
|
|
|
|
|
|
|
|
//TODO: add all body properties here
|
|
|
|
var body3d = new GameLib.D3.Physics.RigidBody(
|
|
|
|
body.id,
|
|
|
|
body.name
|
|
|
|
);
|
|
|
|
|
|
|
|
bodies3d.push(body3d);
|
|
|
|
}
|
|
|
|
|
|
|
|
var world3d = new GameLib.D3.Physics.World(
|
|
|
|
null,
|
|
|
|
world.name,
|
|
|
|
physics3d,
|
|
|
|
new GameLib.D3.Vector3(
|
|
|
|
world.gravity.x,
|
|
|
|
world.gravity.y,
|
|
|
|
world.gravity.z
|
|
|
|
),
|
|
|
|
broadphase3d,
|
|
|
|
solver3d,
|
|
|
|
bodies3d
|
|
|
|
);
|
|
|
|
|
|
|
|
worlds3d.push(world3d);
|
|
|
|
}
|
|
|
|
|
|
|
|
physics3ds.push(physics3d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var lights3d = [];
|
|
|
|
|
|
|
|
for (var l = 0; l < scene.lights.length; l++) {
|
|
|
|
|
|
|
|
var light = scene.lights[l];
|
|
|
|
|
|
|
|
var light3d = new GameLib.D3.Light(
|
|
|
|
light.id,
|
|
|
|
light.lightType,
|
|
|
|
light.name,
|
|
|
|
new GameLib.D3.Color(
|
|
|
|
light.color.r,
|
|
|
|
light.color.g,
|
|
|
|
light.color.b,
|
|
|
|
light.color.a
|
|
|
|
),
|
|
|
|
light.intensity,
|
|
|
|
new GameLib.D3.Vector3(
|
|
|
|
light.position.x,
|
|
|
|
light.position.y,
|
|
|
|
light.position.z
|
|
|
|
),
|
|
|
|
new GameLib.D3.Vector3(
|
|
|
|
light.targetPosition.x,
|
|
|
|
light.targetPosition.y,
|
|
|
|
light.targetPosition.z
|
|
|
|
),
|
|
|
|
new GameLib.D3.Vector4(
|
|
|
|
light.quaternion.x,
|
|
|
|
light.quaternion.y,
|
|
|
|
light.quaternion.z,
|
|
|
|
light.quaternion.w
|
|
|
|
),
|
|
|
|
new GameLib.D3.Vector3(
|
|
|
|
light.rotation.x,
|
|
|
|
light.rotation.y,
|
|
|
|
light.rotation.z
|
|
|
|
),
|
|
|
|
new GameLib.D3.Vector3(
|
|
|
|
light.scale.x,
|
|
|
|
light.scale.y,
|
|
|
|
light.scale.z
|
|
|
|
),
|
|
|
|
light.distance,
|
|
|
|
light.decay,
|
|
|
|
light.power,
|
|
|
|
light.angle,
|
|
|
|
light.penumbra
|
|
|
|
);
|
|
|
|
|
|
|
|
lights3d.push(light3d);
|
|
|
|
}
|
|
|
|
|
|
|
|
var scene3d = new GameLib.D3.Scene(
|
|
|
|
scene._id || scene.id,
|
|
|
|
scene.path,
|
|
|
|
scene.name,
|
|
|
|
scene.meshes,
|
|
|
|
new GameLib.D3.Vector4(
|
|
|
|
scene.quaternion.x,
|
|
|
|
scene.quaternion.y,
|
|
|
|
scene.quaternion.z,
|
|
|
|
scene.quaternion.w
|
|
|
|
),
|
|
|
|
new GameLib.D3.Vector3(
|
|
|
|
scene.position.x,
|
|
|
|
scene.position.y,
|
|
|
|
scene.position.z
|
|
|
|
),
|
|
|
|
new GameLib.D3.Vector3(
|
|
|
|
scene.rotation.x,
|
|
|
|
scene.rotation.y,
|
|
|
|
scene.rotation.z
|
|
|
|
),
|
|
|
|
new GameLib.D3.Vector3(
|
|
|
|
scene.scale.x,
|
|
|
|
scene.scale.y,
|
|
|
|
scene.scale.z
|
|
|
|
),
|
|
|
|
scene.parentSceneId,
|
|
|
|
lights3d,
|
|
|
|
physics3ds
|
|
|
|
);
|
|
|
|
|
|
|
|
GameLib.D3.Scene.loadScene(
|
|
|
|
scene3d,
|
|
|
|
onLoaded,
|
|
|
|
false,
|
|
|
|
graphics,
|
|
|
|
uploadUrl,
|
|
|
|
progressCallback
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}(xhr);
|
|
|
|
|
|
|
|
xhr.send();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Loads a GameLib.D3.Scene object into a Graphics Instance Scene object
|
|
|
|
* @param gameLibScene GameLib.D3.Scene
|
|
|
|
* @param onLoaded callback when all meshes have loaded
|
|
|
|
* @param computeNormals set to true to compute new face and vertex normals during load
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param uploadUrl
|
|
|
|
* @param progressCallback
|
|
|
|
*/
|
|
|
|
GameLib.D3.Scene.loadScene = function(
|
|
|
|
gameLibScene,
|
|
|
|
onLoaded,
|
|
|
|
computeNormals,
|
|
|
|
graphics,
|
|
|
|
uploadUrl,
|
|
|
|
progressCallback
|
|
|
|
) {
|
|
|
|
|
|
|
|
console.log("loading scene " + gameLibScene.name);
|
|
|
|
|
|
|
|
graphics.isNotThreeThrow();
|
|
|
|
|
|
|
|
var meshQ = [];
|
|
|
|
|
|
|
|
for (var m = 0; m < gameLibScene.meshes.length; m++) {
|
|
|
|
|
|
|
|
var mesh = gameLibScene.meshes[m];
|
|
|
|
|
|
|
|
console.log("loading mesh " + mesh.name);
|
|
|
|
|
|
|
|
var geometry = new graphics.instance.Geometry();
|
|
|
|
|
|
|
|
var vertices = mesh.vertices;
|
|
|
|
|
|
|
|
var faces = mesh.faces;
|
|
|
|
|
|
|
|
var faceVertexUvs = mesh.faceVertexUvs;
|
|
|
|
|
|
|
|
var materials = mesh.materials;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup vertices
|
|
|
|
*/
|
|
|
|
for (var v = 0; v < vertices.length; v++) {
|
|
|
|
geometry.vertices.push(
|
|
|
|
new graphics.instance.Vector3(
|
|
|
|
vertices[v].position.x,
|
|
|
|
vertices[v].position.y,
|
|
|
|
vertices[v].position.z
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup faces
|
|
|
|
*/
|
|
|
|
for (var f = 0; f < faces.length; f++) {
|
|
|
|
|
|
|
|
var face = new graphics.instance.Face3(
|
|
|
|
faces[f].v0,
|
|
|
|
faces[f].v1,
|
|
|
|
faces[f].v2,
|
|
|
|
new graphics.instance.Vector3(
|
|
|
|
faces[f].normal.x,
|
|
|
|
faces[f].normal.y,
|
|
|
|
faces[f].normal.z
|
|
|
|
),
|
|
|
|
new graphics.instance.Color(
|
|
|
|
faces[f].color.r,
|
|
|
|
faces[f].color.g,
|
|
|
|
faces[f].color.b
|
|
|
|
),
|
|
|
|
faces[f].materialIndex
|
|
|
|
);
|
|
|
|
|
|
|
|
face.vertexColors = [
|
|
|
|
new graphics.instance.Color(
|
|
|
|
faces[f].vertexColors[0].r,
|
|
|
|
faces[f].vertexColors[0].g,
|
|
|
|
faces[f].vertexColors[0].b
|
|
|
|
),
|
|
|
|
new graphics.instance.Color(
|
|
|
|
faces[f].vertexColors[1].r,
|
|
|
|
faces[f].vertexColors[1].g,
|
|
|
|
faces[f].vertexColors[1].b
|
|
|
|
),
|
|
|
|
new graphics.instance.Color(
|
|
|
|
faces[f].vertexColors[2].r,
|
|
|
|
faces[f].vertexColors[2].g,
|
|
|
|
faces[f].vertexColors[2].b
|
|
|
|
)
|
|
|
|
];
|
|
|
|
|
|
|
|
face.normal = new graphics.instance.Vector3(
|
|
|
|
faces[f].normal.x,
|
|
|
|
faces[f].normal.y,
|
|
|
|
faces[f].normal.z
|
|
|
|
);
|
|
|
|
|
|
|
|
face.vertexNormals = [
|
|
|
|
new graphics.instance.Vector3(
|
|
|
|
faces[f].vertexNormals[0].x,
|
|
|
|
faces[f].vertexNormals[0].y,
|
|
|
|
faces[f].vertexNormals[0].z
|
|
|
|
),
|
|
|
|
new graphics.instance.Vector3(
|
|
|
|
faces[f].vertexNormals[1].x,
|
|
|
|
faces[f].vertexNormals[1].y,
|
|
|
|
faces[f].vertexNormals[1].z
|
|
|
|
),
|
|
|
|
new graphics.instance.Vector3(
|
|
|
|
faces[f].vertexNormals[2].x,
|
|
|
|
faces[f].vertexNormals[2].y,
|
|
|
|
faces[f].vertexNormals[2].z
|
|
|
|
)
|
|
|
|
];
|
|
|
|
|
|
|
|
geometry.faces.push(face);
|
|
|
|
}
|
|
|
|
|
|
|
|
geometry.faceVertexUvs = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup face UVs
|
|
|
|
*/
|
|
|
|
for (var fm = 0; fm < faceVertexUvs.length; fm++) {
|
|
|
|
|
|
|
|
var faceMaterialVertexUvs = faceVertexUvs[fm];
|
|
|
|
|
|
|
|
geometry.faceVertexUvs[fm] = [];
|
|
|
|
|
|
|
|
for (var fuv = 0; fuv < faceMaterialVertexUvs.length; fuv++) {
|
|
|
|
geometry.faceVertexUvs[fm][fuv] = [];
|
|
|
|
geometry.faceVertexUvs[fm][fuv].push(
|
|
|
|
new graphics.instance.Vector2(
|
|
|
|
faceMaterialVertexUvs[fuv][0].x,
|
|
|
|
faceMaterialVertexUvs[fuv][0].y
|
|
|
|
),
|
|
|
|
new graphics.instance.Vector2(
|
|
|
|
faceMaterialVertexUvs[fuv][1].x,
|
|
|
|
faceMaterialVertexUvs[fuv][1].y
|
|
|
|
),
|
|
|
|
new graphics.instance.Vector2(
|
|
|
|
faceMaterialVertexUvs[fuv][2].x,
|
|
|
|
faceMaterialVertexUvs[fuv][2].y
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Re-calculate normals (if we have to)
|
|
|
|
* @type {Array}
|
|
|
|
*/
|
|
|
|
if (computeNormals) {
|
|
|
|
geometry.computeFaceNormals();
|
|
|
|
geometry.computeVertexNormals();
|
|
|
|
}
|
|
|
|
|
|
|
|
var instanceMaterialLoaders = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup materials
|
|
|
|
*/
|
|
|
|
for (var mi = 0; mi < materials.length; mi++) {
|
|
|
|
instanceMaterialLoaders.push(
|
|
|
|
GameLib.D3.Material.createInstanceMaterial(
|
|
|
|
materials[mi],
|
|
|
|
graphics,
|
|
|
|
uploadUrl,
|
|
|
|
progressCallback
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
var result = Q.all(instanceMaterialLoaders).then(
|
|
|
|
function(mesh, geometry) {
|
|
|
|
return function(materials) {
|
|
|
|
|
|
|
|
console.log("loaded material : " + materials[0].name);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* We don't support MultiMaterial atm - it doesn't work with raycasting
|
|
|
|
*/
|
|
|
|
var material = materials[0];
|
|
|
|
|
|
|
|
var threeMesh = GameLib.D3.Mesh.createInstanceMesh(
|
|
|
|
mesh,
|
|
|
|
geometry,
|
|
|
|
material,
|
|
|
|
graphics
|
|
|
|
);
|
|
|
|
threeMesh.name = mesh.name;
|
|
|
|
|
|
|
|
threeMesh.position.x = mesh.position.x;
|
|
|
|
threeMesh.position.y = mesh.position.y;
|
|
|
|
threeMesh.position.z = mesh.position.z;
|
|
|
|
|
|
|
|
threeMesh.rotation.x = mesh.rotation.x;
|
|
|
|
threeMesh.rotation.y = mesh.rotation.y;
|
|
|
|
threeMesh.rotation.z = mesh.rotation.z;
|
|
|
|
|
|
|
|
threeMesh.scale.x = mesh.scale.x;
|
|
|
|
threeMesh.scale.y = mesh.scale.y;
|
|
|
|
threeMesh.scale.z = mesh.scale.z;
|
|
|
|
|
|
|
|
threeMesh.quaternion.x = mesh.quaternion.x;
|
|
|
|
threeMesh.quaternion.y = mesh.quaternion.y;
|
|
|
|
threeMesh.quaternion.z = mesh.quaternion.z;
|
|
|
|
threeMesh.quaternion.w = mesh.quaternion.w;
|
|
|
|
|
|
|
|
return threeMesh;
|
|
|
|
};
|
|
|
|
}(mesh, geometry)
|
|
|
|
).catch(function(error){
|
|
|
|
console.log(error);
|
|
|
|
});
|
|
|
|
|
|
|
|
meshQ.push(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
Q.all(meshQ).then(
|
|
|
|
function(instanceMeshes){
|
|
|
|
console.log("all meshes have loaded");
|
|
|
|
if (typeof onLoaded != 'undefined') {
|
|
|
|
|
|
|
|
var instanceLights = [];
|
|
|
|
|
|
|
|
for (var sli = 0; sli < gameLibScene.lights.length; sli++) {
|
|
|
|
|
|
|
|
var gameLibLight = gameLibScene.lights[sli];
|
|
|
|
|
|
|
|
var light = null;
|
|
|
|
|
|
|
|
if (gameLibLight.lightType == 'AmbientLight') {
|
|
|
|
light = new graphics.instance.AmbientLight(gameLibLight.color, gameLibLight.intensity);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gameLibLight.lightType == 'DirectionalLight') {
|
|
|
|
light = new graphics.instance.DirectionalLight(gameLibLight.color, gameLibLight.intensity);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gameLibLight.lightType == 'PointLight') {
|
|
|
|
light = new graphics.instance.PointLight(gameLibLight.color, gameLibLight.intensity);
|
|
|
|
light.distance = gameLibLight.distance;
|
|
|
|
light.decay = gameLibLight.decay;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gameLibLight.lightType == 'SpotLight') {
|
|
|
|
light = new graphics.instance.SpotLight(gameLibLight.color, gameLibLight.intensity);
|
|
|
|
light.distance = gameLibLight.distance;
|
|
|
|
light.angle = gameLibLight.angle;
|
|
|
|
light.penumbra = gameLibLight.penumbra;
|
|
|
|
light.decay = gameLibLight.decay;
|
|
|
|
}
|
|
|
|
|
|
|
|
light.position.x = gameLibLight.position.x;
|
|
|
|
light.position.y = gameLibLight.position.y;
|
|
|
|
light.position.z = gameLibLight.position.z;
|
|
|
|
|
|
|
|
light.rotation.x = gameLibLight.rotation.x;
|
|
|
|
light.rotation.y = gameLibLight.rotation.y;
|
|
|
|
light.rotation.z = gameLibLight.rotation.z;
|
|
|
|
|
|
|
|
if (light == null) {
|
|
|
|
console.warn('Does not support lights of type :' + gameLibLight.lightType + ', not imported');
|
|
|
|
} else {
|
|
|
|
light.name = gameLibLight.name;
|
|
|
|
instanceLights.push(light);
|
|
|
|
}
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var instanceScene = new graphics.instance.Scene();
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
instanceScene.name = gameLibScene.name;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
instanceScene.position.x = gameLibScene.position.x;
|
|
|
|
instanceScene.position.y = gameLibScene.position.y;
|
|
|
|
instanceScene.position.z = gameLibScene.position.z;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
instanceScene.rotation.x = gameLibScene.rotation.x;
|
|
|
|
instanceScene.rotation.y = gameLibScene.rotation.y;
|
|
|
|
instanceScene.rotation.z = gameLibScene.rotation.z;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
instanceScene.scale.x = gameLibScene.scale.x;
|
|
|
|
instanceScene.scale.y = gameLibScene.scale.y;
|
|
|
|
instanceScene.scale.z = gameLibScene.scale.z;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
instanceScene.quaternion.x = gameLibScene.quaternion.x;
|
|
|
|
instanceScene.quaternion.y = gameLibScene.quaternion.y;
|
|
|
|
instanceScene.quaternion.z = gameLibScene.quaternion.z;
|
|
|
|
instanceScene.quaternion.w = gameLibScene.quaternion.w;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var m = 0; m < instanceMeshes.length; m++) {
|
|
|
|
instanceScene.add(instanceMeshes[m]);
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var l = 0; l < instanceLights.length; l++) {
|
|
|
|
instanceScene.add(instanceLights[l]);
|
|
|
|
}
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
onLoaded(
|
|
|
|
gameLibScene,
|
|
|
|
{
|
|
|
|
scene: instanceScene,
|
|
|
|
lights: instanceLights,
|
|
|
|
meshes: instanceMeshes
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}).catch(
|
|
|
|
function(error){
|
|
|
|
console.log(error);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Physics Shape Superset
|
|
|
|
* @param engine GameLib.D3.Engine
|
|
|
|
* @param shapeType
|
|
|
|
* @param scale GameLib.D3.Vector3
|
|
|
|
* @param vertices Number[]
|
|
|
|
* @param indices Number[]
|
|
|
|
* @param radius Number
|
|
|
|
* @param halfExtensions GameLib.D3.Vector3
|
|
|
|
* @param radiusTop Number
|
|
|
|
* @param radiusBottom Number
|
|
|
|
* @param height Number
|
|
|
|
* @param numSegments Number
|
|
|
|
* @param heightmap GameLib.D3.Heightmap
|
|
|
|
* @param elementSize
|
2016-09-30 13:55:21 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Shape = function(
|
|
|
|
engine,
|
|
|
|
shapeType,
|
|
|
|
scale,
|
|
|
|
vertices,
|
|
|
|
indices,
|
|
|
|
radius,
|
|
|
|
halfExtensions,
|
|
|
|
radiusTop,
|
|
|
|
radiusBottom,
|
|
|
|
height,
|
|
|
|
numSegments,
|
|
|
|
heightmap
|
2016-09-30 13:55:21 +02:00
|
|
|
) {
|
2016-10-28 11:50:55 +02:00
|
|
|
this.engine = engine;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.engine.isNotCannonThrow();
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.shapeType = shapeType;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.instance = this.createInstance();
|
|
|
|
|
|
|
|
if (typeof scale == 'undefined') {
|
|
|
|
scale = new GameLib.D3.Vector3(1, 1, 1)
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.scale = scale;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof vertices == 'undefined') {
|
|
|
|
vertices = [];
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.vertices = vertices;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof indices == 'undefined') {
|
|
|
|
indices = [];
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.indices = indices;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof radius == 'undefined') {
|
|
|
|
radius = 1;
|
|
|
|
}
|
|
|
|
this.radius = radius;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof halfExtensions == 'undefined') {
|
|
|
|
halfExtensions = new GameLib.D3.Vector3(1,1,1);
|
|
|
|
}
|
|
|
|
this.halfExtensions = halfExtensions;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof radiusTop == 'undefined') {
|
|
|
|
radiusTop = 1;
|
|
|
|
}
|
|
|
|
this.radiusTop = radiusTop;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof radiusBottom == 'undefined') {
|
|
|
|
radiusBottom = 1;
|
|
|
|
}
|
|
|
|
this.radiusBottom = radiusBottom;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof height == 'undefined') {
|
|
|
|
height = 1;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.height = height;
|
|
|
|
|
|
|
|
if (typeof numSegments == 'undefined') {
|
|
|
|
numSegments = 1;
|
|
|
|
}
|
|
|
|
this.numSegments = numSegments;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof heightmap == 'undefined') {
|
|
|
|
heightmap = new GameLib.D3.Heightmap();
|
|
|
|
}
|
|
|
|
this.heightmap = heightmap;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Shape constants
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Shape.SHAPE_TYPE_SPHERE = 1;
|
|
|
|
GameLib.D3.Shape.SHAPE_TYPE_BOX = 2;
|
|
|
|
GameLib.D3.Shape.SHAPE_TYPE_TRIMESH = 3;
|
|
|
|
GameLib.D3.Shape.SHAPE_TYPE_CYLINDER = 4;
|
|
|
|
GameLib.D3.Shape.SHAPE_TYPE_HEIGHT_MAP = 5;
|
|
|
|
GameLib.D3.Shape.SHAPE_TYPE_CONVEX_HULL = 6;
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
GameLib.D3.Shape.prototype.createInstance = function() {
|
|
|
|
|
|
|
|
var instance = null;
|
|
|
|
|
|
|
|
if (this.shapeType == GameLib.D3.Shape.SHAPE_TYPE_TRIMESH) {
|
|
|
|
instance = new this.engine.instance.Trimesh(
|
|
|
|
this.vertices,
|
|
|
|
this.indices
|
|
|
|
);
|
|
|
|
} else if (this.shapeType == GameLib.D3.Shape.SHAPE_TYPE_SPHERE) {
|
|
|
|
instance = new this.engine.instance.Sphere(
|
|
|
|
this.radius
|
|
|
|
);
|
|
|
|
} else if (this.shapeType == GameLib.D3.Shape.SHAPE_TYPE_BOX) {
|
|
|
|
instance = new this.engine.instance.Box(
|
|
|
|
new this.engine.instance.Vec3(
|
|
|
|
this.halfExtensions.x,
|
|
|
|
this.halfExtensions.y,
|
|
|
|
this.halfExtensions.z
|
|
|
|
)
|
|
|
|
);
|
|
|
|
} else if (this.shapeType == GameLib.D3.Shape.SHAPE_TYPE_CYLINDER) {
|
|
|
|
instance = new this.engine.instance.Cylinder(
|
|
|
|
this.radiusTop,
|
|
|
|
this.radiusBottom,
|
|
|
|
this.height,
|
|
|
|
this.numSegments
|
|
|
|
);
|
|
|
|
} else if (this.shapeType == GameLib.D3.Shape.SHAPE_TYPE_HEIGHT_MAP) {
|
|
|
|
instance = new this.engine.instance.Heightfield(
|
|
|
|
this.heightmap.matrix,
|
|
|
|
{
|
|
|
|
elementSize: this.heightmap.elementSize
|
|
|
|
}
|
|
|
|
);
|
|
|
|
} else if (this.shapeType == GameLib.D3.Shape.SHAPE_TYPE_CONVEX_HULL) {
|
|
|
|
console.warn('Shape type not implemented: ' + this.shapeType);
|
|
|
|
throw new Error('Shape type not implemented: ' + this.shapeType);
|
|
|
|
} else {
|
|
|
|
console.warn('Shape type not implemented: ' + this.shapeType);
|
|
|
|
throw new Error('Shape type not implemented: ' + this.shapeType);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.instance = instance;
|
|
|
|
|
|
|
|
return instance;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* update
|
|
|
|
*/
|
|
|
|
GameLib.D3.Shape.prototype.update = function(
|
|
|
|
engine
|
|
|
|
) {
|
|
|
|
engine.isNotCannonThrow();
|
|
|
|
|
|
|
|
if(this.shapeType === GameLib.D3.Shape.SHAPE_TYPE_TRIMESH) {
|
|
|
|
this.instance.setScale(
|
|
|
|
new engine.instance.Vec3(
|
|
|
|
this.scale.x,
|
|
|
|
this.scale.y,
|
|
|
|
this.scale.z
|
|
|
|
)
|
|
|
|
);
|
|
|
|
this.instance.updateAABB();
|
|
|
|
this.instance.updateNormals();
|
|
|
|
this.instance.updateEdges();
|
|
|
|
this.instance.updateBoundingSphereRadius();
|
|
|
|
this.instance.updateTree();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Skeleton Superset
|
2016-09-30 13:55:21 +02:00
|
|
|
* @param id
|
2016-10-28 11:50:55 +02:00
|
|
|
* @param bones GameLib.D3.Bone
|
|
|
|
* @param boneInverses
|
|
|
|
* @param useVertexTexture
|
|
|
|
* @param boneTextureWidth
|
|
|
|
* @param boneTextureHeight
|
|
|
|
* @param boneMatrices
|
|
|
|
* @param boneTexture
|
2016-09-30 13:55:21 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Skeleton = function(
|
2016-09-30 13:55:21 +02:00
|
|
|
id,
|
2016-10-28 11:50:55 +02:00
|
|
|
bones,
|
|
|
|
boneInverses,
|
|
|
|
useVertexTexture,
|
|
|
|
boneTextureWidth,
|
|
|
|
boneTextureHeight,
|
|
|
|
boneMatrices,
|
|
|
|
boneTexture
|
2016-09-30 13:55:21 +02:00
|
|
|
) {
|
|
|
|
this.id = id;
|
2016-10-28 11:50:55 +02:00
|
|
|
|
|
|
|
this.bones = bones;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* An array of Matrix4s that represent the inverse of the matrixWorld of the individual bones.
|
|
|
|
* @type GameLib.D3.Matrix4[]
|
|
|
|
*/
|
|
|
|
if (typeof boneInverses == 'undefined') {
|
|
|
|
boneInverses = [];
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.boneInverses = boneInverses;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Use a vertex texture in the shader - allows for more than 4 bones per vertex, not supported by all devices
|
|
|
|
* @type {boolean}
|
|
|
|
*/
|
|
|
|
if (typeof useVertexTexture == 'undefined') {
|
|
|
|
useVertexTexture = false;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.useVertexTexture = useVertexTexture;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (this.useVertexTexture == true) {
|
|
|
|
console.warn('support for vertex texture bones is not supported yet - something could break somewhere');
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof boneTextureWidth == 'undefined') {
|
|
|
|
boneTextureWidth = 0;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.boneTextureWidth = boneTextureWidth;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof boneTextureHeight == 'undefined') {
|
|
|
|
boneTextureHeight = 0;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.boneTextureHeight = boneTextureHeight;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof boneMatrices == 'undefined') {
|
|
|
|
boneMatrices = [];
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.boneMatrices = boneMatrices;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof boneTexture == 'undefined') {
|
|
|
|
boneTexture = [];
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.boneTexture = boneTexture;
|
2016-09-30 13:55:21 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.SkyBox = function (
|
|
|
|
graphics
|
|
|
|
) {
|
|
|
|
this.id = null;
|
|
|
|
|
|
|
|
this.graphics = graphics;
|
|
|
|
this.graphics.isNotThreeThrow();
|
|
|
|
|
|
|
|
this.texturesFolder = null;
|
2016-09-30 13:55:21 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.SkyBox.prototype.load = function (
|
|
|
|
texturesFolder
|
|
|
|
) {
|
|
|
|
this.texturesFolder = texturesFolder;
|
|
|
|
this.textures = [];
|
|
|
|
this.materials = [];
|
|
|
|
this.mesh = {};
|
|
|
|
this.scene = new this.graphics.instance.Scene();
|
|
|
|
this.textureCube = null;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var textureLoader = new this.graphics.instance.TextureLoader();
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// this textures are used to display the skybox
|
|
|
|
this.textures.push(textureLoader.load(this.texturesFolder + "px.png"));
|
|
|
|
this.textures.push(textureLoader.load(this.texturesFolder + "nx.png"));
|
|
|
|
this.textures.push(textureLoader.load(this.texturesFolder + "py.png"));
|
|
|
|
this.textures.push(textureLoader.load(this.texturesFolder + "ny.png"));
|
|
|
|
this.textures.push(textureLoader.load(this.texturesFolder + "pz.png"));
|
|
|
|
this.textures.push(textureLoader.load(this.texturesFolder + "nz.png"));
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// assign textures to each cube face
|
|
|
|
for (var i = 0; i < 6; i ++) {
|
|
|
|
this.materials.push(new this.graphics.instance.MeshBasicMaterial({ map: this.textures[i] }));
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// create cube geometry
|
|
|
|
this.mesh = new this.graphics.instance.Mesh(new this.graphics.instance.CubeGeometry(1, 1, 1), new this.graphics.instance.MeshFaceMaterial(this.materials));
|
|
|
|
this.mesh.applyMatrix(new this.graphics.instance.Matrix4().makeScale(1, 1, -1));
|
|
|
|
this.scene.add(this.mesh);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// Load env textureCube
|
|
|
|
// this is used for reflections on meshes
|
|
|
|
// mesh.material.envMap = this.textureCube;
|
|
|
|
this.textureCube = new this.graphics.instance.CubeTextureLoader().load([
|
|
|
|
this.texturesFolder + "px.png", this.texturesFolder + "nx.png",
|
|
|
|
this.texturesFolder + "py.png", this.texturesFolder + "ny.png",
|
|
|
|
this.texturesFolder + "pz.png", this.texturesFolder + "nz.png"
|
|
|
|
]);
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.SkyBox.prototype.render = function (
|
|
|
|
threeRenderer,
|
|
|
|
threeCamera
|
|
|
|
) {
|
|
|
|
var cameraPosition = new this.graphics.instance.Vector3(threeCamera.position.x, threeCamera.position.y, threeCamera.position.z);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
threeCamera.position.set(0, 0, 0);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var gl = threeRenderer.context;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
gl.disable(gl.DEPTH_TEST);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
threeRenderer.render(this.scene, threeCamera);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
gl.enable(gl.DEPTH_TEST);
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
threeCamera.position.copy(cameraPosition);
|
2016-09-30 13:55:21 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Physics Solver Superset
|
|
|
|
* @param id
|
|
|
|
* @param name
|
|
|
|
* @param solverType
|
|
|
|
* @param iterations
|
|
|
|
* @param tolerance
|
|
|
|
* @constructor
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Physics.Solver = function(
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
solverType,
|
|
|
|
iterations,
|
|
|
|
tolerance
|
|
|
|
) {
|
|
|
|
this.id = id;
|
|
|
|
if (typeof name == 'undefined') {
|
|
|
|
if (solverType == GameLib.D3.Physics.SPLIT_SOLVER) {
|
|
|
|
name = 'split solver';
|
|
|
|
} else if (solverType == GameLib.D3.Physics.GS_SOLVER) {
|
|
|
|
name = 'gs solver';
|
|
|
|
} else {
|
|
|
|
name = 'unknown solver';
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.name = name;
|
|
|
|
this.solverType = solverType;
|
|
|
|
this.iterations = iterations;
|
|
|
|
this.tolerance = tolerance;
|
|
|
|
};
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Solver Types
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Physics.SPLIT_SOLVER = 0x1;
|
|
|
|
GameLib.D3.Physics.GS_SOLVER = 0x2;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Texture Superset
|
|
|
|
* @param id
|
|
|
|
* @param name
|
|
|
|
* @param image
|
|
|
|
* @param wrapS
|
|
|
|
* @param wrapT
|
|
|
|
* @param repeat
|
|
|
|
* @param data
|
|
|
|
* @param format
|
|
|
|
* @param mapping
|
|
|
|
* @param magFilter
|
|
|
|
* @param minFilter
|
|
|
|
* @param textureType
|
|
|
|
* @param anisotropy
|
|
|
|
* @param offset
|
|
|
|
* @param generateMipmaps
|
|
|
|
* @param flipY
|
|
|
|
* @param mipmaps
|
|
|
|
* @param unpackAlignment
|
|
|
|
* @param premultiplyAlpha
|
|
|
|
* @param encoding
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Texture = function(
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
image,
|
|
|
|
wrapS,
|
|
|
|
wrapT,
|
|
|
|
repeat,
|
|
|
|
data,
|
|
|
|
format,
|
|
|
|
mapping,
|
|
|
|
magFilter,
|
|
|
|
minFilter,
|
|
|
|
textureType,
|
|
|
|
anisotropy,
|
|
|
|
offset,
|
|
|
|
generateMipmaps,
|
|
|
|
flipY,
|
|
|
|
mipmaps,
|
|
|
|
unpackAlignment,
|
|
|
|
premultiplyAlpha,
|
|
|
|
encoding
|
|
|
|
) {
|
|
|
|
this.id = id;
|
|
|
|
this.name = name;
|
|
|
|
this.image = image;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof wrapS == 'undefined') {
|
|
|
|
wrapS = GameLib.D3.Texture.TYPE_REPEAT_WRAPPING;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.wrapS = wrapS;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof wrapT == 'undefined') {
|
|
|
|
wrapT = GameLib.D3.Texture.TYPE_REPEAT_WRAPPING;
|
|
|
|
}
|
|
|
|
this.wrapT = wrapT;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof repeat == 'undefined') {
|
|
|
|
repeat = new GameLib.D3.Vector2(1, 1);
|
|
|
|
}
|
|
|
|
this.repeat = repeat;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof data == 'undefined') {
|
|
|
|
data = null;
|
|
|
|
}
|
|
|
|
this.data = data;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof format == 'undefined') {
|
|
|
|
format = GameLib.D3.Texture.TYPE_RGBA_FORMAT;
|
|
|
|
}
|
|
|
|
this.format = format;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof mapping == 'undefined') {
|
|
|
|
mapping = GameLib.D3.Texture.TYPE_UV_MAPPING;
|
|
|
|
}
|
|
|
|
this.mapping = mapping;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof magFilter == 'undefined') {
|
|
|
|
magFilter = GameLib.D3.Texture.TYPE_LINEAR_FILTER;
|
|
|
|
}
|
|
|
|
this.magFilter = magFilter;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof minFilter == 'undefined') {
|
|
|
|
minFilter = GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER;
|
|
|
|
}
|
|
|
|
this.minFilter = minFilter;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof textureType == 'undefined') {
|
|
|
|
textureType = GameLib.D3.Texture.TYPE_UNSIGNED_BYTE;
|
|
|
|
}
|
|
|
|
this.textureType = textureType;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof anisotropy == 'undefined') {
|
|
|
|
anisotropy = 1;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.anisotropy = anisotropy;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof offset == 'undefined') {
|
|
|
|
offset = new GameLib.D3.Vector2(0, 0);
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.offset = offset;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof generateMipmaps == 'undefined') {
|
|
|
|
generateMipmaps = true;
|
|
|
|
}
|
|
|
|
this.generateMipmaps = generateMipmaps;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof flipY == 'undefined') {
|
|
|
|
flipY = true;
|
|
|
|
}
|
|
|
|
this.flipY = flipY;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof mipmaps == 'undefined') {
|
|
|
|
mipmaps = [];
|
|
|
|
}
|
|
|
|
this.mipmaps = mipmaps;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof unpackAlignment == 'undefined') {
|
|
|
|
unpackAlignment = 4;
|
|
|
|
}
|
|
|
|
this.unpackAlignment = unpackAlignment;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof premultiplyAlpha == 'undefined') {
|
|
|
|
premultiplyAlpha = false;
|
2016-09-30 13:55:21 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.premultiplyAlpha = premultiplyAlpha;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof encoding == 'undefined') {
|
|
|
|
encoding = GameLib.D3.Texture.TYPE_LINEAR_ENCODING;
|
|
|
|
}
|
|
|
|
this.encoding = encoding;
|
2016-09-30 13:55:21 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2016-10-28 11:50:55 +02:00
|
|
|
* Texture Formats
|
|
|
|
* @type {number}
|
2016-09-30 13:55:21 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Texture.TYPE_ALPHA_FORMAT = 1019;
|
|
|
|
GameLib.D3.Texture.TYPE_RGB_FORMAT = 1020;
|
|
|
|
GameLib.D3.Texture.TYPE_RGBA_FORMAT = 1021;
|
|
|
|
GameLib.D3.Texture.TYPE_LUMINANCE_FORMAT = 1022;
|
|
|
|
GameLib.D3.Texture.TYPE_LUMINANCE_ALPHA_FORMAT = 1023;
|
|
|
|
GameLib.D3.Texture.TYPE_DEPTH_FORMAT = 1026;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Mapping modes
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Texture.TYPE_UV_MAPPING = 300;
|
|
|
|
GameLib.D3.Texture.TYPE_CUBE_REFLECTION_MAPPING = 301;
|
|
|
|
GameLib.D3.Texture.TYPE_CUBE_REFRACTION_MAPPING = 302;
|
|
|
|
GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING = 303;
|
|
|
|
GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING = 304;
|
|
|
|
GameLib.D3.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING = 305;
|
|
|
|
GameLib.D3.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING = 306;
|
|
|
|
GameLib.D3.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING = 307;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Wrapping Modes
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Texture.TYPE_REPEAT_WRAPPING = 1000;
|
|
|
|
GameLib.D3.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING = 1001;
|
|
|
|
GameLib.D3.Texture.TYPE_MIRRORED_REPEAT_WRAPPING = 1002;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Mipmap Filters
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Texture.TYPE_NEAREST_FILTER = 1003;
|
|
|
|
GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER = 1004;
|
|
|
|
GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER = 1005;
|
|
|
|
GameLib.D3.Texture.TYPE_LINEAR_FILTER = 1006;
|
|
|
|
GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER = 1007;
|
|
|
|
GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER = 1008;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Texture Data Types
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Texture.TYPE_UNSIGNED_BYTE = 1009;
|
|
|
|
GameLib.D3.Texture.TYPE_BYTE = 1010;
|
|
|
|
GameLib.D3.Texture.TYPE_SHORT = 1011;
|
|
|
|
GameLib.D3.Texture.TYPE_UNSIGNED_SHORT = 1012;
|
|
|
|
GameLib.D3.Texture.TYPE_INT = 1013;
|
|
|
|
GameLib.D3.Texture.TYPE_UNSIGNED_INT = 1014;
|
|
|
|
GameLib.D3.Texture.TYPE_FLOAT = 1015;
|
|
|
|
GameLib.D3.Texture.TYPE_HALF_FLOAT = 1025;
|
2016-09-30 13:55:21 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* Encoding Modes
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Texture.TYPE_LINEAR_ENCODING = 3000; // NO ENCODING AT ALL.
|
|
|
|
GameLib.D3.Texture.TYPE_SRGB_ENCODING = 3001;
|
|
|
|
GameLib.D3.Texture.TYPE_GAMMA_ENCODING = 3007; // USES GAMMA_FACTOR, FOR BACKWARDS COMPATIBILITY WITH WEBGLRENDERER.GAMMAINPUT/GAMMAOUTPUT
|
|
|
|
GameLib.D3.Texture.TYPE_RGBE_ENCODING = 3002; // AKA RADIANCE.
|
|
|
|
GameLib.D3.Texture.TYPE_LOG_LUV_ENCODING = 3003;
|
|
|
|
GameLib.D3.Texture.TYPE_RGBM7_ENCODING = 3004;
|
|
|
|
GameLib.D3.Texture.TYPE_RGBM16_ENCODING = 3005;
|
|
|
|
GameLib.D3.Texture.TYPE_RGBD_ENCODING = 3006; // MAXRANGE IS 256.
|
2016-09-30 13:55:21 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Defers loading of an image and resolves once image is loaded
|
2016-10-28 11:50:55 +02:00
|
|
|
* @param gameLibTexture GameLib.D3.Texture
|
|
|
|
* @param instanceMaterial
|
|
|
|
* @param instanceMaterialMapType
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param uploadUrl String
|
|
|
|
* @param progressCallback
|
2016-09-30 13:55:21 +02:00
|
|
|
* @returns {Promise}
|
2016-09-30 12:56:58 +02:00
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Texture.loadMap = function(
|
|
|
|
gameLibTexture,
|
|
|
|
instanceMaterial,
|
|
|
|
instanceMaterialMapType,
|
|
|
|
graphics,
|
|
|
|
uploadUrl,
|
|
|
|
progressCallback
|
|
|
|
) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var defer = Q.defer();
|
2016-09-30 12:56:58 +02:00
|
|
|
|
|
|
|
var imagePath = null;
|
2016-10-28 11:50:55 +02:00
|
|
|
|
|
|
|
var textureLoader = new graphics.instance.TextureLoader();
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.filename) {
|
2016-09-30 12:56:58 +02:00
|
|
|
/**
|
|
|
|
* Else, load from upload source
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
imagePath = uploadUrl + '/' + gameLibTexture.image.filename;
|
2016-09-30 12:56:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (imagePath) {
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
textureLoader.crossOrigin = '';
|
|
|
|
|
|
|
|
textureLoader.load(
|
2016-09-30 12:56:58 +02:00
|
|
|
imagePath,
|
|
|
|
function(texture) {
|
|
|
|
/**
|
|
|
|
* onLoad
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
instanceMaterial[instanceMaterialMapType] = texture;
|
|
|
|
instanceMaterial[instanceMaterialMapType].name = gameLibTexture.name;
|
|
|
|
instanceMaterial[instanceMaterialMapType].anisotropy = gameLibTexture.anisotropy;
|
|
|
|
instanceMaterial[instanceMaterialMapType].encoding = gameLibTexture.encoding;
|
|
|
|
instanceMaterial[instanceMaterialMapType].flipY = gameLibTexture.flipY;
|
2016-09-30 13:55:21 +02:00
|
|
|
/**
|
|
|
|
* We don't restore the format since this changing from OS to OS and breaks the implementation sometimes
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
instanceMaterial[instanceMaterialMapType].generateMipmaps = gameLibTexture.generateMipmaps;
|
|
|
|
instanceMaterial[instanceMaterialMapType].magFilter = gameLibTexture.magFilter;
|
|
|
|
instanceMaterial[instanceMaterialMapType].minFilter = gameLibTexture.minFilter;
|
|
|
|
instanceMaterial[instanceMaterialMapType].mapping = gameLibTexture.mapping;
|
|
|
|
instanceMaterial[instanceMaterialMapType].mipmaps = gameLibTexture.mipmaps;
|
|
|
|
instanceMaterial[instanceMaterialMapType].offset = new graphics.instance.Vector2(
|
2016-09-30 13:55:21 +02:00
|
|
|
gameLibTexture.offset.x,
|
|
|
|
gameLibTexture.offset.y
|
2016-09-30 12:56:58 +02:00
|
|
|
);
|
2016-10-28 11:50:55 +02:00
|
|
|
instanceMaterial[instanceMaterialMapType].premultiplyAlpha = gameLibTexture.premultiplyAlpha;
|
|
|
|
instanceMaterial[instanceMaterialMapType].textureType = gameLibTexture.textureType;
|
|
|
|
instanceMaterial[instanceMaterialMapType].wrapS = gameLibTexture.wrapS;
|
|
|
|
instanceMaterial[instanceMaterialMapType].wrapT = gameLibTexture.wrapT;
|
|
|
|
instanceMaterial[instanceMaterialMapType].unpackAlignment = gameLibTexture.unpackAlignment;
|
|
|
|
instanceMaterial.needsUpdate = true;
|
|
|
|
defer.resolve(true);
|
2016-09-30 12:56:58 +02:00
|
|
|
},
|
|
|
|
function(xhr) {
|
|
|
|
/**
|
|
|
|
* onProgress
|
|
|
|
*/
|
2016-10-28 11:50:55 +02:00
|
|
|
if (progressCallback) {
|
|
|
|
progressCallback(Math.round(xhr.loaded / xhr.total * 100));
|
2016-09-30 12:56:58 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
function(error) {
|
|
|
|
/**
|
|
|
|
* onError
|
|
|
|
*/
|
|
|
|
console.log("an error occurred while trying to load the image : " + imagePath);
|
2016-10-28 11:50:55 +02:00
|
|
|
defer.resolve(null);
|
2016-09-30 12:56:58 +02:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
} else {
|
|
|
|
defer.resolve(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
return defer.promise;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an array of image loading Promises
|
|
|
|
* @param gameLibMaterial
|
|
|
|
* @param blenderMaps
|
|
|
|
* @param instanceMaterial
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param uploadUrl String
|
|
|
|
* @param progressCallback
|
|
|
|
* @returns Q[]
|
|
|
|
*/
|
|
|
|
GameLib.D3.Texture.loadMaps = function(
|
|
|
|
gameLibMaterial,
|
|
|
|
blenderMaps,
|
|
|
|
instanceMaterial,
|
|
|
|
graphics,
|
|
|
|
uploadUrl,
|
|
|
|
progressCallback
|
|
|
|
) {
|
|
|
|
|
|
|
|
var textureMaps = [];
|
|
|
|
|
|
|
|
for (var ti = 0; ti < blenderMaps.length; ti++) {
|
|
|
|
|
|
|
|
var map = blenderMaps[ti];
|
|
|
|
|
|
|
|
if (gameLibMaterial.maps.hasOwnProperty(map)) {
|
|
|
|
|
|
|
|
var blenderTexture = gameLibMaterial.maps[map];
|
|
|
|
|
|
|
|
if (
|
|
|
|
blenderTexture &&
|
|
|
|
blenderTexture.image &&
|
|
|
|
blenderTexture.image.filename
|
|
|
|
) {
|
|
|
|
|
|
|
|
var instanceMap = null;
|
|
|
|
|
|
|
|
if (map == 'alpha') {
|
|
|
|
instanceMap = 'alhpaMap';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map == 'ao') {
|
|
|
|
instanceMap = 'aoMap';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map == 'bump') {
|
|
|
|
instanceMap = 'bumpMap';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map == 'displacement') {
|
|
|
|
instanceMap = 'displacementMap';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map == 'emissive') {
|
|
|
|
instanceMap = 'emissiveMap';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map == 'environment') {
|
|
|
|
instanceMap = 'envMap';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map == 'light') {
|
|
|
|
instanceMap = 'lightMap';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map == 'specular') {
|
|
|
|
instanceMap = 'specularMap';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map == 'diffuse') {
|
|
|
|
instanceMap = 'map';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map == 'roughness') {
|
|
|
|
instanceMap = 'roughnessMap';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map == 'metalness') {
|
|
|
|
instanceMap = 'metalnessMap';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (instanceMap == null) {
|
|
|
|
console.warn("unsupported map type : " + map);
|
|
|
|
}
|
|
|
|
|
|
|
|
textureMaps.push(
|
|
|
|
GameLib.D3.Texture.loadMap(
|
|
|
|
gameLibMaterial.maps[map],
|
|
|
|
instanceMaterial,
|
|
|
|
instanceMap,
|
|
|
|
graphics,
|
|
|
|
uploadUrl,
|
|
|
|
progressCallback
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return textureMaps;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* TriangleEdge
|
|
|
|
* @param triangle
|
|
|
|
* @param edge
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.TriangleEdge = function(
|
|
|
|
triangle,
|
|
|
|
edge
|
|
|
|
) {
|
|
|
|
this.triangle = triangle;
|
|
|
|
this.edge = edge;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* TriangleFace
|
|
|
|
* @param v0
|
|
|
|
* @param v1
|
|
|
|
* @param v2
|
|
|
|
* @param materialIndex
|
|
|
|
* @param v0uv
|
|
|
|
* @param v1uv
|
|
|
|
* @param v2uv
|
|
|
|
* @param color
|
|
|
|
* @param vertexColors
|
|
|
|
* @param vertexNormals
|
|
|
|
* @param normal
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.TriangleFace = function(
|
|
|
|
v0,
|
|
|
|
v1,
|
|
|
|
v2,
|
|
|
|
materialIndex,
|
|
|
|
v0uv,
|
|
|
|
v1uv,
|
|
|
|
v2uv,
|
|
|
|
color,
|
|
|
|
vertexColors,
|
|
|
|
vertexNormals,
|
|
|
|
normal
|
|
|
|
) {
|
|
|
|
this.v0 = v0;
|
|
|
|
this.v1 = v1;
|
|
|
|
this.v2 = v2;
|
|
|
|
this.materialIndex = materialIndex;
|
|
|
|
this.v0uv = v0uv;
|
|
|
|
this.v1uv = v1uv;
|
|
|
|
this.v2uv = v2uv;
|
|
|
|
if (!color) {
|
|
|
|
color = new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff);
|
|
|
|
}
|
|
|
|
this.color = color;
|
|
|
|
|
|
|
|
if (!vertexColors) {
|
|
|
|
vertexColors = [
|
|
|
|
new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff),
|
|
|
|
new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff),
|
|
|
|
new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff)
|
|
|
|
];
|
|
|
|
}
|
|
|
|
this.vertexColors = vertexColors;
|
|
|
|
|
|
|
|
if (!vertexNormals) {
|
|
|
|
vertexNormals = [
|
|
|
|
new GameLib.D3.Vector3(),
|
|
|
|
new GameLib.D3.Vector3(),
|
|
|
|
new GameLib.D3.Vector3()
|
|
|
|
]
|
|
|
|
}
|
|
|
|
this.vertexNormals = vertexNormals;
|
|
|
|
|
|
|
|
if (!normal) {
|
|
|
|
normal = new GameLib.D3.Vector3(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.normal = normal;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clone a TriangleFace
|
|
|
|
* @returns {GameLib.D3.TriangleFace}
|
|
|
|
*/
|
|
|
|
GameLib.D3.TriangleFace.prototype.clone = function(){
|
|
|
|
return new GameLib.D3.TriangleFace(
|
|
|
|
this.v0,
|
|
|
|
this.v1,
|
|
|
|
this.v2,
|
|
|
|
this.materialIndex,
|
|
|
|
this.v0uv.copy(),
|
|
|
|
this.v1uv.copy(),
|
|
|
|
this.v2uv.copy()
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if two triangles are equal (their vertex indices match in some order)
|
|
|
|
* @param triangle
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
GameLib.D3.TriangleFace.prototype.equals = function(triangle) {
|
|
|
|
return !!(
|
|
|
|
(
|
|
|
|
(this.v0 == triangle.v0) &&
|
|
|
|
(this.v1 == triangle.v1) &&
|
|
|
|
(this.v2 == triangle.v2)
|
|
|
|
)
|
|
|
|
||
|
|
|
|
(
|
|
|
|
(this.v0 == triangle.v0) &&
|
|
|
|
(this.v1 == triangle.v2) &&
|
|
|
|
(this.v2 == triangle.v1)
|
|
|
|
)
|
|
|
|
||
|
|
|
|
(
|
|
|
|
(this.v0 == triangle.v1) &&
|
|
|
|
(this.v1 == triangle.v0) &&
|
|
|
|
(this.v2 == triangle.v2)
|
|
|
|
)
|
|
|
|
||
|
|
|
|
(
|
|
|
|
(this.v0 == triangle.v1) &&
|
|
|
|
(this.v1 == triangle.v2) &&
|
|
|
|
(this.v2 == triangle.v0)
|
|
|
|
)
|
|
|
|
||
|
|
|
|
(
|
|
|
|
(this.v0 == triangle.v2) &&
|
|
|
|
(this.v1 == triangle.v0) &&
|
|
|
|
(this.v2 == triangle.v1)
|
|
|
|
)
|
|
|
|
||
|
|
|
|
(
|
|
|
|
(this.v0 == triangle.v2) &&
|
|
|
|
(this.v1 == triangle.v1) &&
|
|
|
|
(this.v2 == triangle.v0)
|
|
|
|
));
|
|
|
|
};
|
|
|
|
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector2 = function(x, y) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.x = 0;
|
|
|
|
this.y = 0;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (x) {
|
|
|
|
this.x = x;
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (y) {
|
|
|
|
this.y = y;
|
2016-09-30 12:56:58 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector2.prototype.copy = function() {
|
|
|
|
return new GameLib.D3.Vector2(
|
|
|
|
this.x,
|
|
|
|
this.y
|
|
|
|
);
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector2.prototype.equals = function(v) {
|
|
|
|
return !!(((this.x == v.x) &&
|
|
|
|
(this.y == v.y)) ||
|
|
|
|
((this.y == v.x) &&
|
|
|
|
(this.x == v.y)));
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3 = function(x, y, z) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.x = 0;
|
|
|
|
this.y = 0;
|
|
|
|
this.z = 0;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (x) {
|
|
|
|
this.x = x;
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (y) {
|
|
|
|
this.y = y;
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (z) {
|
|
|
|
this.z = z;
|
|
|
|
}
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.prototype.subtract = function (v) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (v instanceof GameLib.D3.Vector3) {
|
|
|
|
this.x -= v.x;
|
|
|
|
this.y -= v.y;
|
|
|
|
this.z -= v.z;
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (v instanceof GameLib.D3.Vector4) {
|
|
|
|
console.warn("trying to subtract vector of bigger length (4 vs 3))");
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
return this;
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.prototype.cross = function (v) {
|
|
|
|
return new GameLib.D3.Vector3(
|
|
|
|
this.y * v.z - this.z * v.y,
|
|
|
|
this.z * v.x - this.x * v.z,
|
|
|
|
this.x * v.y - this.y * v.x
|
|
|
|
);
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.prototype.negative = function () {
|
|
|
|
this.x *= -1;
|
|
|
|
this.y *= -1;
|
|
|
|
this.z *= -1;
|
|
|
|
return this;
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.clockwise = function (u, v, w, viewPoint) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var normal = GameLib.D3.Vector3.normal(u, v, w);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var uv = u.copy();
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var winding = normal.dot(uv.subtract(viewPoint));
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
return (winding > 0);
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.normal = function (u, v, w) {
|
|
|
|
var vv = v.copy();
|
|
|
|
var wv = w.copy();
|
|
|
|
return vv.subtract(u).cross(wv.subtract(u));
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.prototype.lookAt = function (at, up) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var lookAtMatrix = GameLib.D3.Matrix4.lookAt(this, at, up);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.multiply(lookAtMatrix);
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.prototype.translate = function (v) {
|
|
|
|
this.x += v.x;
|
|
|
|
this.y += v.y;
|
|
|
|
this.z += v.z;
|
|
|
|
return this;
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.prototype.squared = function () {
|
|
|
|
return this.x * this.x + this.y * this.y + this.z * this.z;
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.prototype.copy = function () {
|
|
|
|
return new GameLib.D3.Vector3(
|
|
|
|
this.x,
|
|
|
|
this.y,
|
|
|
|
this.z
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Vector3.prototype.multiply = function (s) {
|
|
|
|
if (s instanceof GameLib.D3.Vector3) {
|
|
|
|
this.x *= s.x;
|
|
|
|
this.y *= s.y;
|
|
|
|
this.z *= s.z;
|
|
|
|
} else if (s instanceof GameLib.D3.Matrix4) {
|
|
|
|
var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z;
|
|
|
|
var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z;
|
|
|
|
var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z;
|
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
|
|
|
this.z = z;
|
|
|
|
} else {
|
|
|
|
console.log("functionality not implemented - please do this");
|
|
|
|
throw new Error("not implemented");
|
2016-09-30 12:56:58 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
return this;
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.prototype.dot = function (v) {
|
|
|
|
return (this.x * v.x) + (this.y * v.y) + (this.z * v.z);
|
2016-09-30 12:56:58 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector3.prototype.normalize = function () {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var EPSILON = 0.000001;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var v2 = this.squared();
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (v2 < EPSILON) {
|
|
|
|
return this; //do nothing for zero vector
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var invLength = 1 / Math.sqrt(v2);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.x *= invLength;
|
|
|
|
this.y *= invLength;
|
|
|
|
this.z *= invLength;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
return this;
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4 = function(x, y, z, w) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.x = 0;
|
|
|
|
this.y = 0;
|
|
|
|
this.z = 0;
|
|
|
|
this.w = 0;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (x) {
|
|
|
|
this.x = x;
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (y) {
|
|
|
|
this.y = y;
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (z) {
|
|
|
|
this.z = z;
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (w) {
|
|
|
|
this.w = w;
|
|
|
|
}
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.prototype.translate = function (v) {
|
|
|
|
this.x += v.x;
|
|
|
|
this.y += v.y;
|
|
|
|
this.z += v.z;
|
|
|
|
return this;
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.prototype.copy = function () {
|
|
|
|
return new GameLib.D3.Vector4(
|
|
|
|
this.x,
|
|
|
|
this.y,
|
|
|
|
this.z,
|
|
|
|
this.w
|
|
|
|
);
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.prototype.multiply = function (s) {
|
|
|
|
if (s instanceof GameLib.D3.Vector3) {
|
|
|
|
this.x *= s.x;
|
|
|
|
this.y *= s.y;
|
|
|
|
this.z *= s.z;
|
|
|
|
} else if (s instanceof GameLib.D3.Matrix4) {
|
|
|
|
var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z + s.rows[0].w * this.w;
|
|
|
|
var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z + s.rows[1].w * this.w;
|
|
|
|
var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z + s.rows[2].w * this.w;
|
|
|
|
var w = s.rows[3].x * this.x + s.rows[3].y * this.y + s.rows[3].z * this.z + s.rows[3].w * this.w;
|
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
|
|
|
this.z = z;
|
|
|
|
this.w = w;
|
|
|
|
} else {
|
|
|
|
console.log("functionality not implemented - please do this");
|
|
|
|
throw new Error("not implemented");
|
|
|
|
}
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.prototype.normalize = function () {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// note - leave w untouched
|
|
|
|
var EPSILON = 0.000001;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var v2 = this.x * this.x + this.y * this.y + this.z * this.z;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (v2 < EPSILON) {
|
|
|
|
return this; //do nothing for zero vector
|
2016-09-30 12:56:58 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var invLength = 1 / Math.sqrt(v2);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.x *= invLength;
|
|
|
|
this.y *= invLength;
|
|
|
|
this.z *= invLength;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
return this;
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.prototype.subtract = function (v) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (v instanceof GameLib.D3.Vector3) {
|
|
|
|
this.x -= v.x;
|
|
|
|
this.y -= v.y;
|
|
|
|
this.z -= v.z;
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (v instanceof GameLib.D3.Vector4) {
|
|
|
|
this.x -= v.x;
|
|
|
|
this.y -= v.y;
|
|
|
|
this.z -= v.z;
|
|
|
|
this.w -= v.w;
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
return this;
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.Points = function () {
|
|
|
|
this.vectors = [];
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.Points.prototype.add = function (vector) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (vector instanceof GameLib.D3.Vector3) {
|
|
|
|
vector = new GameLib.D3.Vector4(
|
|
|
|
vector.x,
|
|
|
|
vector.y,
|
|
|
|
vector.z,
|
|
|
|
1
|
2016-09-30 12:56:58 +02:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (!vector instanceof GameLib.D3.Vector4) {
|
|
|
|
console.warn("Vector needs to be of type Vector4");
|
|
|
|
throw new Error("Vector needs to be of type Vector4");
|
2016-09-30 16:05:33 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.vectors.push(vector);
|
2016-09-30 16:05:33 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
return this;
|
2016-09-30 16:05:33 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.Points.prototype.copy = function () {
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var vectors = [];
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
|
|
vectors.push(this.vectors[i].copy());
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
return vectors;
|
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.Points.prototype.maximizeXDistance = function (grain) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2));
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var multiplier = 0;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var rotationMatrixY = new GameLib.D3.Matrix4().rotationMatrixY(grain);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var totalRadians = 0;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var backupVectors = this.copy();
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var maxXDistance = 0;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var i = 0; i < Math.PI * 2; i += grain) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
multiplier++;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var j = 0; j < this.vectors.length; j++) {
|
|
|
|
this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]);
|
2016-09-30 12:56:58 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var distances = this.distances();
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (distances.x > maxXDistance) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
maxXDistance = distances.x;
|
|
|
|
totalRadians = multiplier * grain;
|
|
|
|
}
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.vectors = backupVectors;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// console.log("distance: " + maxXDistance + " radians : " + totalRadians);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixY(totalRadians);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var k = 0; k < this.vectors.length; k++) {
|
|
|
|
this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]);
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2));
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.Points.prototype.maximizeYDistance = function (grain) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2));
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var multiplier = 0;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var rotationMatrixX = new GameLib.D3.Matrix4().rotationMatrixX(grain);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var totalRadians = 0;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var backupVectors = this.copy();
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var maxYDistance = 0;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var i = 0; i < Math.PI * 2; i += grain) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
multiplier++;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var j = 0; j < this.vectors.length; j++) {
|
|
|
|
this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]);
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var distances = this.distances();
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (distances.y > maxYDistance) {
|
|
|
|
maxYDistance = distances.y;
|
|
|
|
totalRadians = multiplier * grain;
|
|
|
|
}
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.vectors = backupVectors;
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// console.log("distance: " + maxYDistance + " radians : " + totalRadians);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixX(totalRadians);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var k = 0; k < this.vectors.length; k++) {
|
|
|
|
this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]);
|
|
|
|
}
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2));
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
};
|
2016-09-30 12:56:58 +02:00
|
|
|
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.Points.prototype.lookAt = function (at, up) {
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var polyCenter = this.average();
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
console.log("poly center : " + JSON.stringify(polyCenter));
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var lookAtMatrix = new GameLib.D3.Matrix4().lookAt(polyCenter, at, up);
|
2016-09-30 12:56:58 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
lookAtMatrix.rows[0] = new GameLib.D3.Vector4(1, 0, 0, 0);
|
|
|
|
lookAtMatrix.rows[1] = new GameLib.D3.Vector4(0, 0, 1, 0);
|
|
|
|
lookAtMatrix.rows[2] = new GameLib.D3.Vector4(0, 1, 0, 0);
|
2016-09-30 15:57:36 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2));
|
|
|
|
|
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
|
|
console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i]));
|
|
|
|
this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]);
|
|
|
|
console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i]));
|
2016-10-04 15:32:12 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.Points.prototype.distances = function () {
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var minX = this.vectors[0].x;
|
|
|
|
var minY = this.vectors[0].y;
|
|
|
|
var minZ = this.vectors[0].z;
|
2016-10-13 11:24:05 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var maxX = this.vectors[0].x;
|
|
|
|
var maxY = this.vectors[0].y;
|
|
|
|
var maxZ = this.vectors[0].z;
|
2016-10-13 11:24:05 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
|
|
if (this.vectors[i].x < minX) {
|
|
|
|
minX = this.vectors[i].x;
|
2016-10-13 11:24:05 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
if (this.vectors[i].y < minY) {
|
|
|
|
minY = this.vectors[i].y;
|
|
|
|
}
|
|
|
|
if (this.vectors[i].z < minZ) {
|
|
|
|
minZ = this.vectors[i].z;
|
2016-10-13 11:24:05 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (this.vectors[i].x > maxX) {
|
|
|
|
maxX = this.vectors[i].x;
|
|
|
|
}
|
|
|
|
if (this.vectors[i].y > maxY) {
|
|
|
|
maxY = this.vectors[i].y;
|
|
|
|
}
|
|
|
|
if (this.vectors[i].z > maxZ) {
|
|
|
|
maxZ = this.vectors[i].z;
|
|
|
|
}
|
2016-10-04 15:32:12 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
|
|
|
|
return new GameLib.D3.Vector3(
|
|
|
|
Math.abs(maxX - minX),
|
|
|
|
Math.abs(maxY - minY),
|
|
|
|
Math.abs(maxY - minZ)
|
|
|
|
)
|
2016-10-04 15:32:12 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.Points.prototype.average = function () {
|
|
|
|
var averageX = 0;
|
|
|
|
var averageY = 0;
|
|
|
|
var averageZ = 0;
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
|
|
averageX += this.vectors[i].x;
|
|
|
|
averageY += this.vectors[i].y;
|
|
|
|
averageZ += this.vectors[i].z;
|
2016-10-04 15:32:12 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
return new GameLib.D3.Vector3(
|
|
|
|
averageX / this.vectors.length,
|
|
|
|
averageY / this.vectors.length,
|
|
|
|
averageZ / this.vectors.length
|
|
|
|
);
|
2016-10-13 11:24:05 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.Points.prototype.negative = function () {
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
|
|
this.vectors[i].x *= -1;
|
|
|
|
this.vectors[i].y *= -1;
|
|
|
|
this.vectors[i].z *= -1;
|
2016-10-13 11:24:05 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
|
|
|
|
return this;
|
2016-10-13 11:24:05 +02:00
|
|
|
};
|
|
|
|
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.Vector4.Points.prototype.toOrigin = function () {
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var distanceFromOrigin = this.average().negative();
|
2016-10-13 11:24:05 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
|
|
this.vectors[i].translate(distanceFromOrigin);
|
|
|
|
}
|
2016-10-13 11:24:05 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* The normal gets assigned when the face calculates its normal
|
|
|
|
* @param position
|
|
|
|
* @param boneWeights GameLib.D3.BoneWeight[]
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Vertex = function(
|
2016-10-04 15:32:12 +02:00
|
|
|
position,
|
2016-10-28 11:50:55 +02:00
|
|
|
boneWeights
|
|
|
|
) {
|
|
|
|
this.position = position;
|
|
|
|
this.boneWeights = boneWeights;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* World SuperSet - contains the custom world instance
|
|
|
|
* @param id
|
|
|
|
* @param name
|
|
|
|
* @param engine
|
|
|
|
* @param gravity
|
|
|
|
* @param broadphase
|
|
|
|
* @param solver
|
|
|
|
* @param rigidBodies
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.World = function(
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
engine,
|
|
|
|
gravity,
|
|
|
|
broadphase,
|
|
|
|
solver,
|
|
|
|
rigidBodies
|
2016-10-04 15:32:12 +02:00
|
|
|
) {
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.id = id;
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.name = name;
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof gravity == 'undefined') {
|
|
|
|
gravity = new GameLib.D3.Vector3(0, -9.81, 0);
|
2016-10-04 15:32:12 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.gravity = gravity;
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof broadphase == 'undefined') {
|
|
|
|
broadphase = new GameLib.D3.Physics.Broadphase(
|
|
|
|
null,
|
|
|
|
'broadPhaseNaive',
|
|
|
|
GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE
|
|
|
|
);
|
2016-10-04 15:32:12 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.broadphase = broadphase;
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof solver == 'undefined') {
|
|
|
|
solver = new GameLib.D3.Physics.Solver(
|
|
|
|
null,
|
|
|
|
'GSSolver',
|
|
|
|
GameLib.D3.Physics.GS_SOLVER
|
|
|
|
);
|
2016-10-04 15:32:12 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.solver = solver;
|
2016-10-04 15:32:12 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof rigidBodies == 'undefined') {
|
|
|
|
rigidBodies = [];
|
2016-10-13 11:24:05 +02:00
|
|
|
}
|
2016-10-28 11:50:55 +02:00
|
|
|
this.rigidBodies = rigidBodies;
|
|
|
|
|
|
|
|
this.engine = engine;
|
|
|
|
|
|
|
|
this.engine.isNotCannonThrow();
|
|
|
|
|
|
|
|
this.instance = this.createInstance();
|
2016-10-13 11:24:05 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
* private
|
|
|
|
* @returns {GameLib.D3.World|GameLib.D3.Physics.World|*}
|
|
|
|
*/
|
|
|
|
GameLib.D3.World.prototype.createInstance = function() {
|
|
|
|
|
|
|
|
var instance = new this.engine.instance.World();
|
|
|
|
|
|
|
|
instance.broadphase = this.broadphase.instance;
|
|
|
|
|
|
|
|
instance.solver = this.solver.instance;
|
|
|
|
|
|
|
|
instance.gravity.x = this.gravity.x;
|
|
|
|
instance.gravity.y = this.gravity.y;
|
|
|
|
instance.gravity.z = this.gravity.z;
|
|
|
|
|
|
|
|
instance.name = this.name;
|
|
|
|
|
|
|
|
return instance;
|
2016-10-13 15:16:28 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param rigidBody GameLib.D3.RigidBody
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.World.prototype.addRigidBody = function(
|
|
|
|
rigidBody
|
2016-10-04 15:32:12 +02:00
|
|
|
) {
|
2016-10-28 11:50:55 +02:00
|
|
|
this.instance.addBody(rigidBody.instance);
|
2016-10-04 10:05:18 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param vehicle (GameLib.D3.RigidBodyVehicle | GameLib.D3.RaycastVehicle)
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.World.prototype.addVehicle = function(
|
2016-10-13 11:24:05 +02:00
|
|
|
vehicle // note: physics.vehicle
|
2016-10-04 10:05:18 +02:00
|
|
|
) {
|
2016-10-28 11:50:55 +02:00
|
|
|
vehicle.instance.addToWorld(this.world.instance);
|
2016-10-04 10:05:18 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.World.prototype.step = function(
|
2016-10-04 10:05:18 +02:00
|
|
|
timeStep
|
|
|
|
) {
|
2016-10-28 11:50:55 +02:00
|
|
|
// todo: figure out, why this call to internal step is more stable for trimesh collisions.....
|
|
|
|
//this.worldObject.internalStep(timeStep);
|
|
|
|
//return;
|
|
|
|
|
|
|
|
var now = performance.now() / 1000;
|
|
|
|
if(!this.lastCallTime){
|
|
|
|
// last call time not saved, cant guess elapsed time. Take a simple step.
|
|
|
|
this.instance.step(timeStep);
|
|
|
|
this.lastCallTime = now;
|
|
|
|
return;
|
|
|
|
}
|
2016-10-07 10:21:50 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
var timeSinceLastCall = now - this.lastCallTime;
|
2016-10-07 10:21:50 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.instance.step(timeStep, timeSinceLastCall);
|
2016-10-07 10:21:50 +02:00
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
this.lastCallTime = now;
|
2016-10-04 10:05:18 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
GameLib.D3.World.prototype.GetIndexedVertices = function(
|
2016-10-04 15:32:12 +02:00
|
|
|
triangleMeshShape
|
2016-09-30 15:57:36 +02:00
|
|
|
) {
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) {
|
2016-09-30 15:57:36 +02:00
|
|
|
|
|
|
|
return {
|
|
|
|
vertices : triangleMeshShape.vertices,
|
|
|
|
indices : triangleMeshShape.indices
|
|
|
|
};
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// todo: implement this for other physics engines.
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
2016-10-28 13:06:56 +02:00
|
|
|
* @param triangleMeshShape GameLib.D3.Shape
|
|
|
|
* @param normalLength Number
|
|
|
|
* @param scale GameLib.D3.Vector3
|
|
|
|
* @param opacity Number
|
|
|
|
* @param wireframeColor HexCode
|
|
|
|
* @param graphics THREE
|
2016-10-28 11:50:55 +02:00
|
|
|
* @returns {THREE.Mesh|this.meshes}
|
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 13:06:56 +02:00
|
|
|
GameLib.D3.World.prototype.generateWireframeViewTriangleMesh = function(
|
|
|
|
graphics,
|
2016-09-30 15:57:36 +02:00
|
|
|
triangleMeshShape,
|
|
|
|
normalLength,
|
|
|
|
scale,
|
|
|
|
opacity,
|
|
|
|
wireframeColor
|
|
|
|
) {
|
2016-10-28 13:06:56 +02:00
|
|
|
graphics.isNotThreeThrow();
|
|
|
|
this.engine.isNotCannonThrow();
|
|
|
|
|
|
|
|
if(typeof normalLength == 'undefined') {
|
|
|
|
normalLength = 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(typeof scale == 'undefined') {
|
|
|
|
scale = new graphics.instance.Vector3(1, 1, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(typeof opacity == 'undefined') {
|
|
|
|
opacity = 0.5;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(typeof wireframeColor == 'undefined') {
|
|
|
|
wireframeColor = 0xfefefe;
|
|
|
|
}
|
|
|
|
|
|
|
|
var graphicsGeometry = new graphics.instance.Geometry();
|
|
|
|
|
|
|
|
var wireframeMesh = new graphics.instance.Mesh(
|
|
|
|
graphicsGeometry,
|
|
|
|
new graphics.instance.MeshBasicMaterial({
|
|
|
|
color: wireframeColor,
|
2016-09-30 15:57:36 +02:00
|
|
|
wireframe: true,
|
2016-10-28 13:06:56 +02:00
|
|
|
opacity: opacity
|
2016-09-30 15:57:36 +02:00
|
|
|
})
|
|
|
|
);
|
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
for(var i = 0, l = triangleMeshShape.instance.vertices.length / 3; i < l; ++i) {
|
|
|
|
graphicsGeometry.vertices.push(
|
|
|
|
new graphics.instance.Vector3(
|
|
|
|
triangleMeshShape.instance.vertices[i * 3],
|
|
|
|
triangleMeshShape.instance.vertices[i * 3 + 1],
|
|
|
|
triangleMeshShape.instance.vertices[i * 3 + 2]
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(var i = 0, l = triangleMeshShape.instance.indices.length / 3; i < l; ++i) {
|
|
|
|
var i0 = triangleMeshShape.instance.indices[i * 3];
|
|
|
|
var i1 = triangleMeshShape.instance.indices[i * 3 + 1];
|
|
|
|
var i2 = triangleMeshShape.instance.indices[i * 3 + 2];
|
|
|
|
|
|
|
|
graphicsGeometry.faces.push(
|
|
|
|
new graphics.instance.Face3(
|
|
|
|
i0,
|
|
|
|
i1,
|
|
|
|
i2
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
// Center point on the current triangle
|
|
|
|
|
|
|
|
var centroid = new graphics.instance.Vector3()
|
|
|
|
.add(graphicsGeometry.vertices[i0])
|
|
|
|
.add(graphicsGeometry.vertices[i1])
|
|
|
|
.add(graphicsGeometry.vertices[i2])
|
|
|
|
.divideScalar(3);
|
|
|
|
|
|
|
|
// Get the normal from the mesh shape itself
|
|
|
|
var normal = new this.engine.instance.Vec3();
|
|
|
|
triangleMeshShape.instance.getNormal(i , normal);
|
|
|
|
|
|
|
|
var arrow = new graphics.instance.ArrowHelper(
|
|
|
|
new graphics.instance.Vector3(
|
|
|
|
normal.x,
|
|
|
|
normal.y,
|
|
|
|
normal.z
|
|
|
|
),
|
|
|
|
centroid,
|
|
|
|
normalLength,
|
|
|
|
new graphics.instance.Color(
|
|
|
|
normal.x,
|
|
|
|
normal.y,
|
|
|
|
normal.z
|
|
|
|
)
|
|
|
|
);
|
|
|
|
wireframeMesh.add( arrow );
|
|
|
|
}
|
|
|
|
|
|
|
|
wireframeMesh.scale.x = scale.x;
|
|
|
|
wireframeMesh.scale.y = scale.y;
|
|
|
|
wireframeMesh.scale.z = scale.z;
|
|
|
|
|
|
|
|
return wireframeMesh;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param convexPolyMeshShape GameLib.D3.Shape
|
|
|
|
* @param normalLength Number
|
|
|
|
* @param scale GameLib.D3.Vector3
|
|
|
|
* @param opacity Number
|
|
|
|
* @param wireframeColor HexCode
|
|
|
|
* @param graphics THREE
|
|
|
|
* @returns {THREE.Mesh|this.meshes}
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.World.prototype.generateWireframeViewConvexPolyMesh = function(
|
|
|
|
graphics,
|
|
|
|
convexPolyMeshShape,
|
|
|
|
normalLength,
|
|
|
|
scale,
|
|
|
|
opacity,
|
|
|
|
wireframeColor
|
|
|
|
) {
|
|
|
|
graphics.isNotThreeThrow();
|
|
|
|
this.engine.isNotCannonThrow();
|
|
|
|
|
|
|
|
if(typeof normalLength == 'undefined') {
|
|
|
|
normalLength = 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(typeof scale == 'undefined') {
|
|
|
|
scale = new graphics.instance.Vector3(1, 1, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(typeof opacity == 'undefined') {
|
|
|
|
opacity = 0.5;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(typeof wireframeColor == 'undefined') {
|
|
|
|
wireframeColor = 0xfefefe;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var graphicsGeometry = new graphics.instance.Geometry();
|
|
|
|
var wireframeMesh = new graphics.instance.Mesh(
|
|
|
|
graphicsGeometry,
|
|
|
|
new graphics.instance.MeshBasicMaterial({
|
|
|
|
color: wireframeColor,
|
|
|
|
wireframe: true,
|
|
|
|
opacity: opacity
|
|
|
|
})
|
|
|
|
);
|
2016-09-30 15:57:36 +02:00
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
for(var i = 0, l = convexPolyMeshShape.instance.vertices.length; i < l; i++) {
|
|
|
|
var vertex = convexPolyMeshShape.instance.vertices[i];
|
|
|
|
graphicsGeometry.vertices.push(new graphics.instance.Vector3(vertex.x, vertex.y, vertex.z));
|
2016-09-30 15:57:36 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
for(var i = 0, l = convexPolyMeshShape.instance.faces.length; i < l; i++) {
|
|
|
|
var face = convexPolyMeshShape.instance.faces[i];
|
2016-09-30 15:57:36 +02:00
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
var i0 = face[0];
|
|
|
|
var i1 = face[1];
|
|
|
|
var i2 = face[2];
|
2016-09-30 15:57:36 +02:00
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
graphicsGeometry.faces.push(new graphics.instance.Face3(i0, i1, i2));
|
2016-09-30 15:57:36 +02:00
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
// Center point on the current triangle
|
|
|
|
var centroid = new graphics.instance.Vector3()
|
|
|
|
.add(graphicsGeometry.vertices[i0])
|
|
|
|
.add(graphicsGeometry.vertices[i1])
|
|
|
|
.add(graphicsGeometry.vertices[i2])
|
2016-09-30 15:57:36 +02:00
|
|
|
.divideScalar(3);
|
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
var normalVec3 = convexPolyMeshShape.instance.faceNormals[i];
|
|
|
|
var normal = new graphics.instance.Vector3(
|
|
|
|
normalVec3.x,
|
|
|
|
normalVec3.y,
|
|
|
|
normalVec3.z
|
|
|
|
);
|
2016-09-30 15:57:36 +02:00
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
var arrow = new graphics.instance.ArrowHelper(
|
|
|
|
normal,
|
|
|
|
centroid,
|
|
|
|
normalLength,
|
|
|
|
new graphics.instance.Color(
|
|
|
|
normal.x,
|
|
|
|
normal.y,
|
|
|
|
normal.z
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
wireframeMesh.add( arrow );
|
2016-09-30 15:57:36 +02:00
|
|
|
}
|
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
wireframeMesh.scale.x = scale.x;
|
|
|
|
wireframeMesh.scale.y = scale.y;
|
|
|
|
wireframeMesh.scale.z = scale.z;
|
2016-09-30 15:57:36 +02:00
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
return wireframeMesh;
|
2016-09-30 15:57:36 +02:00
|
|
|
};
|
|
|
|
|
2016-10-28 11:50:55 +02:00
|
|
|
/**
|
2016-10-28 13:06:56 +02:00
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param graphicsMesh THREE.Mesh
|
|
|
|
* @param mass Number
|
|
|
|
* @param friction Number
|
|
|
|
* @param createCollisionSubMeshes Boolean
|
|
|
|
* @param facesPerSubsection Number
|
|
|
|
* @param subsectionsToMerge Number
|
|
|
|
* @returns {Object}
|
2016-10-28 11:50:55 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
2016-10-28 13:06:56 +02:00
|
|
|
GameLib.D3.World.prototype.generateTriangleMeshShapeDivided = function(
|
|
|
|
graphics,
|
|
|
|
graphicsMesh,
|
|
|
|
mass,
|
|
|
|
friction,
|
|
|
|
createCollisionSubMeshes,
|
|
|
|
facesPerSubsection,
|
|
|
|
subsectionsToMerge
|
2016-09-30 15:57:36 +02:00
|
|
|
) {
|
2016-10-28 13:06:56 +02:00
|
|
|
graphics.isNotThreeThrow();
|
|
|
|
this.engine.isNotCannonThrow();
|
|
|
|
|
|
|
|
if(mass == null || typeof mass == 'undefined') {
|
|
|
|
mass = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(friction == null || typeof friction == 'undefined') {
|
|
|
|
friction = 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(createCollisionSubMeshes == null || typeof createCollisionSubMeshes == 'undefined') {
|
|
|
|
createCollisionSubMeshes = false;
|
|
|
|
}
|
|
|
|
|
2016-09-30 15:57:36 +02:00
|
|
|
var processedFaces = 0;
|
|
|
|
var facesPerSubSection = facesPerSubsection || 0;
|
|
|
|
var subMeshesToMerge = subsectionsToMerge || 0;
|
2016-10-28 13:06:56 +02:00
|
|
|
var totalAmtFaces = graphicsMesh.geometry.faces.length;
|
2016-09-30 15:57:36 +02:00
|
|
|
var facesToProcess = createCollisionSubMeshes ? (subMeshesToMerge * facesPerSubSection) : totalAmtFaces;
|
|
|
|
|
|
|
|
var pairs = []; // output
|
|
|
|
|
|
|
|
var vertices = [];
|
|
|
|
var indicies = [];
|
|
|
|
|
|
|
|
for(var i = 0; i <= totalAmtFaces; i++) {
|
|
|
|
if(processedFaces == facesToProcess || i == totalAmtFaces) {
|
|
|
|
|
|
|
|
var body = null;
|
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
var meshShape = new this.engine.instance.Trimesh(vertices, indicies);
|
2016-09-30 15:57:36 +02:00
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
meshShape.setScale(new this.engine.instance.Vec3(
|
|
|
|
graphicsMesh.scale.x,
|
|
|
|
graphicsMesh.scale.y,
|
|
|
|
graphicsMesh.scale.z
|
|
|
|
));
|
2016-09-30 15:57:36 +02:00
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
meshShape.updateAABB();
|
|
|
|
meshShape.updateNormals();
|
|
|
|
meshShape.updateEdges();
|
|
|
|
meshShape.updateBoundingSphereRadius();
|
|
|
|
meshShape.updateTree();
|
2016-09-30 15:57:36 +02:00
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
body = new this.engine.instance.Body({
|
|
|
|
mass: mass,
|
|
|
|
friction: friction
|
|
|
|
});
|
|
|
|
body.addShape(meshShape);
|
2016-09-30 15:57:36 +02:00
|
|
|
|
|
|
|
pairs.push({
|
2016-10-28 13:06:56 +02:00
|
|
|
threeObject : createCollisionSubMeshes ? null : graphicsMesh,
|
2016-09-30 15:57:36 +02:00
|
|
|
physicsObject : body
|
|
|
|
});
|
|
|
|
|
|
|
|
vertices = [];
|
|
|
|
indicies = [];
|
|
|
|
processedFaces = 0;
|
|
|
|
|
|
|
|
if(i == totalAmtFaces) {
|
|
|
|
return pairs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
var face = graphicsMesh.geometry.faces[i];
|
2016-09-30 15:57:36 +02:00
|
|
|
indicies.push(indicies.length);
|
|
|
|
indicies.push(indicies.length);
|
|
|
|
indicies.push(indicies.length);
|
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
var v0 = graphicsMesh.geometry.vertices[face.a];
|
|
|
|
var v1 = graphicsMesh.geometry.vertices[face.b];
|
|
|
|
var v2 = graphicsMesh.geometry.vertices[face.c];
|
2016-09-30 15:57:36 +02:00
|
|
|
|
|
|
|
vertices.push(v0.x, v0.y, v0.z);
|
|
|
|
vertices.push(v1.x, v1.y, v1.z);
|
|
|
|
vertices.push(v2.x, v2.y, v2.z);
|
|
|
|
|
|
|
|
processedFaces++;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-10-28 13:06:56 +02:00
|
|
|
/**
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param graphicsMesh THREE.Mesh
|
|
|
|
* @returns {GameLib.D3.RigidBody}
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.World.prototype.generateTriangleMeshShape = function(
|
|
|
|
graphics,
|
|
|
|
graphicsMesh
|
|
|
|
) {
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
// Note: I did not test this yet with the API data.
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
|
|
|
var scaledVertices = [];
|
|
|
|
for(var i = 0, l = graphicsMesh.geometry.vertices.length; i < l; i++) {
|
|
|
|
|
|
|
|
var vertex = graphicsMesh.geometry.vertices[i];
|
|
|
|
|
|
|
|
scaledVertices.push(new this.engine.instance.Vec3(
|
|
|
|
vertex.x * graphicsMesh.scale.x,
|
|
|
|
vertex.y * graphicsMesh.scale.y,
|
|
|
|
vertex.z * graphicsMesh.scale.z
|
|
|
|
));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var triangleFaces = [];
|
|
|
|
for(var f = 0, fl = graphicsMesh.geometry.faces.length; f < fl; f++) {
|
|
|
|
var i0 = graphicsMesh.geometry.faces[f].a;
|
|
|
|
var i1 = graphicsMesh.geometry.faces[f].b;
|
|
|
|
var i2 = graphicsMesh.geometry.faces[f].c;
|
|
|
|
|
|
|
|
triangleFaces.push([
|
|
|
|
i0,
|
|
|
|
i1,
|
|
|
|
i2
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - -
|
|
|
|
// Create collision mesh
|
|
|
|
// - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
|
|
|
var reindexedFaces = {};
|
|
|
|
var vertices = [];
|
|
|
|
var faces = [];
|
|
|
|
|
|
|
|
var processedFaces = 0;
|
|
|
|
var totalFacesToProcess = triangleFaces.length;
|
|
|
|
var flLastIndex = 0;
|
|
|
|
|
|
|
|
for(var f = 0; f < totalFacesToProcess; f++) {
|
|
|
|
|
|
|
|
var i0 = triangleFaces[f][0];
|
|
|
|
var i1 = triangleFaces[f][1];
|
|
|
|
var i2 = triangleFaces[f][2];
|
|
|
|
|
|
|
|
if(typeof reindexedFaces[i0] === 'undefined') {
|
|
|
|
vertices.push(scaledVertices[i0].x, scaledVertices[i0].y, scaledVertices[i0].z);
|
|
|
|
reindexedFaces[i0] = flLastIndex;
|
|
|
|
flLastIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(typeof reindexedFaces[i1] === 'undefined') {
|
|
|
|
vertices.push(scaledVertices[i1].x, scaledVertices[i1].y, scaledVertices[i1].z);
|
|
|
|
reindexedFaces[i1] = flLastIndex;
|
|
|
|
flLastIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(typeof reindexedFaces[i2] === 'undefined') {
|
|
|
|
vertices.push(scaledVertices[i2].x, scaledVertices[i2].y, scaledVertices[i2].z);
|
|
|
|
reindexedFaces[i2] = flLastIndex;
|
|
|
|
flLastIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
faces.push(reindexedFaces[i0], reindexedFaces[i1], reindexedFaces[i2]);
|
|
|
|
|
|
|
|
processedFaces++;
|
|
|
|
}
|
|
|
|
|
|
|
|
var shape = GameLib.D3.Shape(this.engine, GameLib.D3.Shape.SHAPE_TYPE_TRIMESH, graphicsMesh.scale, vertices, faces);
|
|
|
|
var body = GameLib.D3.RigidBody(this.engine, 0, 12);
|
|
|
|
|
|
|
|
body.addShape(shape);
|
|
|
|
this.addRigidBody(body);
|
|
|
|
|
|
|
|
// process the mesh children recursively
|
|
|
|
for(var c in graphicsMesh.children) {
|
|
|
|
this.generateTriangleMeshShape(graphics, graphicsMesh.children[c]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return body;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param triangleMeshBody GameLib.D3.RigidBody
|
|
|
|
* @param rayscale Number
|
|
|
|
* @param maxTriangleDistance Number
|
|
|
|
* @param createCompoundShape Boolean
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param triangleMeshShapes GameLib.D3.Shape[]
|
|
|
|
* @param createDebugView Boolean
|
|
|
|
* @returns {GameLib.D3.RigidBody}
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.World.prototype.fixupTriangleMeshShape = function(
|
|
|
|
triangleMeshBody,
|
|
|
|
triangleMeshShapes,
|
|
|
|
rayscale,
|
|
|
|
maxTriangleDistance,
|
|
|
|
createCompoundShape,
|
|
|
|
graphics,
|
|
|
|
createDebugView
|
|
|
|
) {
|
|
|
|
this.engine.isNotCannonThrow();
|
|
|
|
|
|
|
|
graphics.isNotThreeThrow();
|
|
|
|
|
|
|
|
if(rayscale == null || typeof rayscale == 'undefined' || rayscale == 0) {
|
|
|
|
rayscale = 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(maxTriangleDistance == null || typeof maxTriangleDistance == 'undefined') {
|
|
|
|
maxTriangleDistance = 13;
|
|
|
|
}
|
|
|
|
|
|
|
|
var world = this.instance;
|
|
|
|
|
|
|
|
var raycastResult = new this.engine.instance.RaycastResult();
|
|
|
|
|
|
|
|
var brokenFaceIndicators = [];
|
|
|
|
var wireframeMeshes = [];
|
|
|
|
|
|
|
|
var totalFaces = 0;
|
|
|
|
var totalBrokenFaces = 0;
|
|
|
|
var totalFixedFaces = 0;
|
|
|
|
var fixedTriangleMeshObjects = [];
|
|
|
|
|
|
|
|
for(var i in triangleMeshShapes) {
|
|
|
|
var trimesh = triangleMeshShapes[i];
|
|
|
|
|
|
|
|
var brokenFaces = [];
|
|
|
|
totalFaces += (trimesh.indices.length / 3);
|
|
|
|
|
|
|
|
for(var face = 0; face < trimesh.indices.length / 3; face++) {
|
|
|
|
|
|
|
|
var i0 = trimesh.indices[face * 3];
|
|
|
|
var i1 = trimesh.indices[face * 3 + 1];
|
|
|
|
var i2 = trimesh.indices[face * 3 + 2];
|
|
|
|
|
|
|
|
var triangleCenterPoint = new graphics.instance.Vector3()
|
|
|
|
.add(new graphics.instance.Vector3(
|
|
|
|
trimesh.vertices[i0 * 3],
|
|
|
|
trimesh.vertices[i0 * 3 + 1],
|
|
|
|
trimesh.vertices[i0 * 3 + 2])
|
|
|
|
)
|
|
|
|
.add(new graphics.instance.Vector3(
|
|
|
|
trimesh.vertices[i1 * 3],
|
|
|
|
trimesh.vertices[i1 * 3 + 1],
|
|
|
|
trimesh.vertices[i1 * 3 + 2])
|
|
|
|
)
|
|
|
|
.add(new graphics.instance.Vector3(
|
|
|
|
trimesh.vertices[i2 * 3],
|
|
|
|
trimesh.vertices[i2 * 3 + 1],
|
|
|
|
trimesh.vertices[i2 * 3 + 2])
|
|
|
|
)
|
|
|
|
.divideScalar(3);
|
|
|
|
|
|
|
|
var triangleNormal = new this.engine.instance.Vec3();
|
|
|
|
trimesh.getNormal(face , triangleNormal);
|
|
|
|
|
|
|
|
var from = new this.engine.instance.Vec3(
|
|
|
|
triangleCenterPoint.x + triangleNormal.x,
|
|
|
|
triangleCenterPoint.y + triangleNormal.y,
|
|
|
|
triangleCenterPoint.z + triangleNormal.z
|
|
|
|
);
|
|
|
|
|
|
|
|
var to = new this.engine.instance.Vec3(
|
|
|
|
from.x - triangleNormal.x * rayscale,
|
|
|
|
from.y - triangleNormal.y * rayscale,
|
|
|
|
from.z - triangleNormal.z * rayscale
|
|
|
|
);
|
|
|
|
|
|
|
|
world.raycastClosest(from, to, {}, raycastResult);
|
|
|
|
|
|
|
|
// visualize results
|
|
|
|
if(createDebugView){
|
|
|
|
var graphicsGeometry = new graphics.instance.Geometry();
|
|
|
|
var wireframeMesh = new graphics.instance.Mesh(
|
|
|
|
graphicsGeometry,
|
|
|
|
new graphics.instance.MeshBasicMaterial({
|
|
|
|
color: 0xff0000,
|
|
|
|
wireframe: true,
|
|
|
|
opacity: 1
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
var arrow = new graphics.instance.ArrowHelper(
|
|
|
|
new graphics.instance.Vector3(
|
|
|
|
triangleNormal.x,
|
|
|
|
triangleNormal.y,
|
|
|
|
triangleNormal.z
|
|
|
|
).normalize(),
|
|
|
|
|
|
|
|
new graphics.instance.Vector3(
|
|
|
|
from.x,
|
|
|
|
from.y,
|
|
|
|
from.z
|
|
|
|
),
|
|
|
|
|
|
|
|
rayscale / 2,
|
|
|
|
raycastResult.hasHit ? new graphics.instance.Color(0, 1, 0)
|
|
|
|
: new graphics.instance.Color(1, 0, 0)
|
|
|
|
);
|
|
|
|
|
|
|
|
wireframeMesh.add( arrow );
|
|
|
|
|
|
|
|
wireframeMeshes.add(wireframeMesh);
|
|
|
|
brokenFaceIndicators.push(wireframeMesh);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!raycastResult.hasHit) {
|
|
|
|
brokenFaces.push({
|
|
|
|
faceIndex : face,
|
|
|
|
|
|
|
|
vertices : [
|
|
|
|
new this.engine.instance.Vec3(
|
|
|
|
trimesh.vertices[i0 * 3],
|
|
|
|
trimesh.vertices[i0 * 3 + 1],
|
|
|
|
trimesh.vertices[i0 * 3 + 2]
|
|
|
|
),
|
|
|
|
|
|
|
|
new this.engine.instance.Vec3(
|
|
|
|
trimesh.vertices[i1 * 3],
|
|
|
|
trimesh.vertices[i1 * 3 + 1],
|
|
|
|
trimesh.vertices[i1 * 3 + 2]
|
|
|
|
),
|
|
|
|
|
|
|
|
new this.engine.instance.Vec3(
|
|
|
|
trimesh.vertices[i2 * 3],
|
|
|
|
trimesh.vertices[i2 * 3 + 1],
|
|
|
|
trimesh.vertices[i2 * 3 + 2]
|
|
|
|
)
|
|
|
|
],
|
|
|
|
|
|
|
|
center : triangleCenterPoint,
|
|
|
|
|
|
|
|
parent : trimesh
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// fix up broken faces
|
|
|
|
|
|
|
|
var bFaceIndexed = {};
|
|
|
|
for(var b = 0; b < brokenFaces.length; b++) {
|
|
|
|
var brokenFace = brokenFaces[b];
|
|
|
|
|
|
|
|
if(brokenFace.marked) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
bFaceIndexed[b] = {
|
|
|
|
indices : [],
|
|
|
|
vertices : []
|
|
|
|
};
|
|
|
|
|
|
|
|
var indicesAmount = bFaceIndexed[b].indices.length;
|
|
|
|
|
|
|
|
// add the current broken face itself to the array
|
|
|
|
bFaceIndexed[b].indices.push(
|
|
|
|
indicesAmount,
|
|
|
|
indicesAmount + 1,
|
|
|
|
indicesAmount + 2
|
|
|
|
);
|
|
|
|
|
|
|
|
bFaceIndexed[b].vertices.push(
|
|
|
|
brokenFace.vertices[0].x,
|
|
|
|
brokenFace.vertices[0].y,
|
|
|
|
brokenFace.vertices[0].z
|
|
|
|
);
|
|
|
|
|
|
|
|
bFaceIndexed[b].vertices.push(
|
|
|
|
brokenFace.vertices[1].x,
|
|
|
|
brokenFace.vertices[1].y,
|
|
|
|
brokenFace.vertices[1].z
|
|
|
|
);
|
|
|
|
|
|
|
|
bFaceIndexed[b].vertices.push(
|
|
|
|
brokenFace.vertices[2].x,
|
|
|
|
brokenFace.vertices[2].y,
|
|
|
|
brokenFace.vertices[2].z
|
|
|
|
);
|
|
|
|
|
|
|
|
for(var bb = 0; bb < brokenFaces.length; bb++) {
|
|
|
|
|
|
|
|
if(bb == b) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
var otherBrokenFace = brokenFaces[bb];
|
|
|
|
|
|
|
|
if(otherBrokenFace.marked) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(brokenFace.center.distanceTo(otherBrokenFace.center) <= maxTriangleDistance) {
|
|
|
|
var indicesAmount = bFaceIndexed[b].indices.length;
|
|
|
|
|
|
|
|
bFaceIndexed[b].indices.push(
|
|
|
|
indicesAmount,
|
|
|
|
indicesAmount + 1,
|
|
|
|
indicesAmount + 2
|
|
|
|
);
|
|
|
|
|
|
|
|
bFaceIndexed[b].vertices.push(
|
|
|
|
otherBrokenFace.vertices[0].x,
|
|
|
|
otherBrokenFace.vertices[0].y,
|
|
|
|
otherBrokenFace.vertices[0].z
|
|
|
|
);
|
|
|
|
|
|
|
|
bFaceIndexed[b].vertices.push(
|
|
|
|
otherBrokenFace.vertices[1].x,
|
|
|
|
otherBrokenFace.vertices[1].y,
|
|
|
|
otherBrokenFace.vertices[1].z
|
|
|
|
);
|
|
|
|
|
|
|
|
bFaceIndexed[b].vertices.push(
|
|
|
|
otherBrokenFace.vertices[2].x,
|
|
|
|
otherBrokenFace.vertices[2].y,
|
|
|
|
otherBrokenFace.vertices[2].z
|
|
|
|
);
|
|
|
|
|
|
|
|
otherBrokenFace.marked = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
// Decide if we want to create new rigid bodies, or create a compound mesh
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
|
|
|
for(var e in bFaceIndexed) {
|
|
|
|
var element = bFaceIndexed[e];
|
|
|
|
|
|
|
|
var shape = new GameLib.D3.Shape(this.engine, GameLib.D3.Shape.SHAPE_TYPE_TRIMESH, null, element.vertices, element.indices);
|
|
|
|
|
|
|
|
if(createCompoundShape) {
|
|
|
|
triangleMeshBody.addShape(shape);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
var body = new GameLib.D3.RigidBody(this.engine, 0, 12);
|
|
|
|
body.addShape(shape);
|
|
|
|
this.instance.addRigidBody(body);
|
|
|
|
}
|
|
|
|
|
|
|
|
fixedTriangleMeshObjects.push(shape);
|
|
|
|
totalFixedFaces += element.indices.length / 3;
|
|
|
|
|
|
|
|
console.log("created mesh shape", element.indices.length / 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: remove duplicate indices
|
|
|
|
/*trimesh.updateNormals();
|
|
|
|
trimesh.updateEdges();
|
|
|
|
trimesh.updateTree();
|
|
|
|
trimesh.updateAABB();
|
|
|
|
trimesh.updateBoundingSphereRadius();*/
|
|
|
|
|
|
|
|
// map faceIndex to flat face index (faceIndex * 3) +0, 1, 2 -> triangle indices
|
|
|
|
console.log("i = " + i, brokenFaces);
|
|
|
|
totalBrokenFaces += brokenFaces.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log("total faces", totalFaces);
|
|
|
|
console.log("total broken faces", totalBrokenFaces);
|
|
|
|
console.log("broken faces in percent", (totalBrokenFaces / totalFaces) * 100);
|
|
|
|
console.log("total fixed faces", totalFixedFaces);
|
|
|
|
console.log("fixed triangle mesh shapes", fixedTriangleMeshObjects.length);
|
|
|
|
|
|
|
|
return {
|
|
|
|
brokenFaceIndicators : brokenFaceIndicators,
|
|
|
|
fixedTriangleMeshShapes : fixedTriangleMeshObjects,
|
|
|
|
wireframeMeshes : wireframeMeshes
|
|
|
|
};
|
|
|
|
};
|
2016-10-28 11:50:55 +02:00
|
|
|
if (typeof module !== 'undefined') {
|
|
|
|
module.exports = GameLib;
|
2016-09-30 14:33:37 +02:00
|
|
|
}
|