r3-legacy/src/game-lib-d3-mesh-0.js

570 lines
16 KiB
JavaScript
Raw Normal View History

2016-10-14 12:32:53 +02:00
/**
2016-11-17 18:31:41 +01:00
* Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created
* @param graphics GameLib.D3.Graphics
2016-11-29 12:54:25 +01:00
* @param apiMesh GameLib.D3.API.Mesh
2016-11-17 18:31:41 +01:00
* @constructor
*/
2017-01-05 19:34:28 +01:00
GameLib.D3.Mesh = function (
2016-11-17 18:31:41 +01:00
graphics,
2017-06-08 18:17:03 +02:00
apiMesh
2016-11-17 18:31:41 +01:00
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
if (GameLib.Utils.UndefinedOrNull(apiMesh)) {
apiMesh = {};
}
if (apiMesh instanceof GameLib.D3.Mesh) {
return apiMesh;
}
2016-12-13 15:41:02 +01:00
GameLib.D3.API.Mesh.call(
this,
apiMesh.id,
apiMesh.meshType,
apiMesh.name,
apiMesh.vertices,
apiMesh.faces,
apiMesh.faceVertexUvs,
apiMesh.materials,
apiMesh.parentMesh,
apiMesh.parentScene,
2016-12-13 15:41:02 +01:00
apiMesh.skeleton,
apiMesh.skinIndices,
apiMesh.skinWeights,
apiMesh.position,
apiMesh.quaternion,
apiMesh.scale,
2016-12-15 14:53:39 +01:00
apiMesh.localPosition,
apiMesh.localRotation,
apiMesh.localScale,
2017-01-02 17:05:40 +01:00
apiMesh.up,
apiMesh.modelMatrix,
2017-01-04 16:12:30 +01:00
apiMesh.parentEntity,
apiMesh.renderOrder
2016-12-13 15:41:02 +01:00
);
2017-06-09 16:03:05 +02:00
this.materials = this.materials.map(
function(material) {
if (material instanceof GameLib.D3.API.Material) {
return new GameLib.D3.Material(
this.graphics,
2017-06-09 16:03:05 +02:00
material
)
} else {
return material;
}
2017-06-09 16:03:05 +02:00
}.bind(this)
);
2017-01-05 19:34:28 +01:00
2017-01-06 16:53:53 +01:00
if (this.skeleton) {
this.skeleton = new GameLib.D3.Skeleton(
this.graphics,
this.skeleton
);
}
2017-01-05 19:34:28 +01:00
this.vertices = this.vertices.map(
function (apiVertex) {
return new GameLib.D3.Vertex(
this.graphics,
apiVertex
);
}.bind(this)
);
2016-12-15 14:53:39 +01:00
this.position = new GameLib.Vector3(
2017-01-05 19:34:28 +01:00
this.graphics,
this.position,
this
2016-12-02 16:03:03 +01:00
);
2016-12-15 14:53:39 +01:00
this.scale = new GameLib.Vector3(
2017-01-05 19:34:28 +01:00
this.graphics,
this.scale,
this
2016-12-02 16:03:03 +01:00
);
2016-12-15 14:53:39 +01:00
this.up = new GameLib.Vector3(
2017-01-05 19:34:28 +01:00
this.graphics,
this.up,
this
2016-12-02 16:03:03 +01:00
);
2016-12-15 14:53:39 +01:00
this.quaternion = new GameLib.Quaternion(
2017-01-05 19:34:28 +01:00
this.graphics,
this.quaternion,
this
2016-12-02 16:03:03 +01:00
);
2016-12-15 14:53:39 +01:00
this.localPosition = new GameLib.Vector3(
2017-01-05 19:34:28 +01:00
this.graphics,
this.localPosition,
this
2016-12-13 15:41:02 +01:00
);
2016-12-15 14:53:39 +01:00
this.localRotation = new GameLib.Vector3(
2017-01-05 19:34:28 +01:00
this.graphics,
this.localRotation,
this
2016-12-13 15:41:02 +01:00
);
2016-12-15 14:53:39 +01:00
this.localScale = new GameLib.Vector3(
2017-01-05 19:34:28 +01:00
this.graphics,
this.localScale,
this
2016-12-13 15:41:02 +01:00
);
2016-12-22 17:22:19 +01:00
this.modelMatrix = new GameLib.Matrix4(
2017-01-05 19:34:28 +01:00
this.graphics,
this.modelMatrix,
this
2016-12-22 17:22:19 +01:00
);
2017-01-19 17:50:11 +01:00
this.buildIdToObject();
2016-12-22 17:22:19 +01:00
2017-06-09 16:03:05 +02:00
this.instance = this.createInstance();
2017-01-03 18:15:03 +01:00
this.instance.geometry.computeBoundingBox();
this.width = this.instance.geometry.boundingBox.max.x - this.instance.geometry.boundingBox.min.x;
this.height = this.instance.geometry.boundingBox.max.y - this.instance.geometry.boundingBox.min.y;
this.depth = this.instance.geometry.boundingBox.max.z - this.instance.geometry.boundingBox.min.z;
2016-11-17 18:31:41 +01:00
};
2016-12-13 15:41:02 +01:00
GameLib.D3.Mesh.prototype = Object.create(GameLib.D3.API.Mesh.prototype);
GameLib.D3.Mesh.prototype.constructor = GameLib.D3.Mesh;
2016-10-14 12:32:53 +02:00
/**
* Mesh Type
* @type {number}
*/
2017-06-02 13:52:29 +02:00
GameLib.D3.Mesh.TYPE_NORMAL = 0x0;
GameLib.D3.Mesh.TYPE_SKINNED = 0x1;
GameLib.D3.Mesh.TYPE_CURVE = 0x2;
2016-10-14 12:32:53 +02:00
/**
2017-06-02 13:52:29 +02:00
* Mesh Shape (predefined or custom)
* @type {number}
2016-10-14 12:32:53 +02:00
*/
2017-06-02 13:52:29 +02:00
GameLib.D3.Mesh.SHAPE_CUSTOM = 0x1;
GameLib.D3.Mesh.SHAPE_SPHERE = 0x2;
2016-11-17 18:31:41 +01:00
2017-06-02 13:52:29 +02:00
/**
* Creates custom geometry
* @returns {THREE.Geometry}
*/
GameLib.D3.Mesh.prototype.customGeometry = function(){
var geometry = new THREE.Geometry();
/**
* Setup vertices
*/
for (var v = 0; v < this.vertices.length; v++) {
geometry.vertices.push(
new this.graphics.instance.Vector3(
this.vertices[v].position.x,
this.vertices[v].position.y,
this.vertices[v].position.z
)
)
2016-11-17 18:31:41 +01:00
}
2016-10-14 12:32:53 +02:00
2017-06-02 13:52:29 +02:00
/**
* Setup faces
*/
for (var f = 0; f < this.faces.length; f++) {
2016-11-17 18:31:41 +01:00
2017-06-02 13:52:29 +02:00
var face = new this.graphics.instance.Face3(
this.faces[f].v0,
this.faces[f].v1,
this.faces[f].v2,
new this.graphics.instance.Vector3(
this.faces[f].normal.x,
this.faces[f].normal.y,
this.faces[f].normal.z
),
new this.graphics.instance.Color(
this.faces[f].color.r,
this.faces[f].color.g,
this.faces[f].color.b
),
this.faces[f].materialIndex
);
face.vertexColors = [
new this.graphics.instance.Color(
this.faces[f].vertexColors[0].r,
this.faces[f].vertexColors[0].g,
this.faces[f].vertexColors[0].b
),
new this.graphics.instance.Color(
this.faces[f].vertexColors[1].r,
this.faces[f].vertexColors[1].g,
this.faces[f].vertexColors[1].b
),
new this.graphics.instance.Color(
this.faces[f].vertexColors[2].r,
this.faces[f].vertexColors[2].g,
this.faces[f].vertexColors[2].b
2016-11-17 18:31:41 +01:00
)
2017-06-02 13:52:29 +02:00
];
2016-11-17 18:31:41 +01:00
2017-06-02 13:52:29 +02:00
face.normal = new this.graphics.instance.Vector3(
this.faces[f].normal.x,
this.faces[f].normal.y,
this.faces[f].normal.z
);
2016-11-17 18:31:41 +01:00
2017-06-02 13:52:29 +02:00
face.vertexNormals = [
new this.graphics.instance.Vector3(
this.faces[f].vertexNormals[0].x,
this.faces[f].vertexNormals[0].y,
this.faces[f].vertexNormals[0].z
),
new this.graphics.instance.Vector3(
this.faces[f].vertexNormals[1].x,
this.faces[f].vertexNormals[1].y,
this.faces[f].vertexNormals[1].z
),
new this.graphics.instance.Vector3(
this.faces[f].vertexNormals[2].x,
this.faces[f].vertexNormals[2].y,
this.faces[f].vertexNormals[2].z
)
];
2016-11-17 18:31:41 +01:00
2017-06-02 13:52:29 +02:00
geometry.faces.push(face);
}
geometry.faceVertexUvs = [];
2016-11-17 18:31:41 +01:00
2017-06-02 13:52:29 +02:00
/**
* Setup face UVs
*/
for (var fm = 0; fm < this.faceVertexUvs.length; fm++) {
var faceMaterialVertexUvs = this.faceVertexUvs[fm];
geometry.faceVertexUvs[fm] = [];
for (var fuv = 0; fuv < faceMaterialVertexUvs.length; fuv++) {
geometry.faceVertexUvs[fm][fuv] = [];
geometry.faceVertexUvs[fm][fuv].push(
new this.graphics.instance.Vector2(
faceMaterialVertexUvs[fuv][0].x,
faceMaterialVertexUvs[fuv][0].y
2016-11-17 18:31:41 +01:00
),
2017-06-02 13:52:29 +02:00
new this.graphics.instance.Vector2(
faceMaterialVertexUvs[fuv][1].x,
faceMaterialVertexUvs[fuv][1].y
2016-11-17 18:31:41 +01:00
),
2017-06-02 13:52:29 +02:00
new this.graphics.instance.Vector2(
faceMaterialVertexUvs[fuv][2].x,
faceMaterialVertexUvs[fuv][2].y
2016-11-17 18:31:41 +01:00
)
2017-06-02 13:52:29 +02:00
);
2016-11-17 18:31:41 +01:00
}
2017-06-02 13:52:29 +02:00
}
2016-10-14 12:32:53 +02:00
2017-06-02 13:52:29 +02:00
return geometry;
2016-10-14 12:32:53 +02:00
2017-06-02 13:52:29 +02:00
};
/**
* Creates a mesh instance or updates it
*/
GameLib.D3.Mesh.prototype.createInstance = function(update) {
if (update) {
2017-06-09 16:03:05 +02:00
if (this.parentMesh && this.parentMesh.loaded) {
this.instance.parent = this.parentMesh.instance;
this.instance.position.x = this.localPosition.x;
this.instance.position.y = this.localPosition.y;
this.instance.position.z = this.localPosition.z;
this.instance.rotation.x = this.localRotation.x;
this.instance.rotation.y = this.localRotation.y;
this.instance.rotation.z = this.localRotation.z;
this.instance.scale.x = this.localScale.x;
this.instance.scale.y = this.localScale.y;
this.instance.scale.z = this.localScale.z;
} else {
this.instance.quaternion.x = this.quaternion.x;
this.instance.quaternion.y = this.quaternion.y;
this.instance.quaternion.z = this.quaternion.z;
this.instance.quaternion.w = this.quaternion.w;
this.instance.position.x = this.position.x + this.localPosition.x;
this.instance.position.y = this.position.y + this.localPosition.y;
this.instance.position.z = this.position.z + this.localPosition.z;
this.instance.scale.x = this.scale.x * this.localScale.x;
this.instance.scale.y = this.scale.y * this.localScale.y;
this.instance.scale.z = this.scale.z * this.localScale.z;
this.instance.up.x = this.up.x;
this.instance.up.y = this.up.y;
this.instance.up.z = this.up.z;
this.instance.rotateX(this.localRotation.x);
this.instance.rotateY(this.localRotation.y);
this.instance.rotateZ(this.localRotation.z);
}
this.instance.name = this.name;
2017-06-02 13:52:29 +02:00
2017-06-09 16:03:05 +02:00
if (this.materials.length === 1 && this.materials[0].instance) {
this.instance.material = this.materials[0].instance;
}
this.instance.renderOrder = this.renderOrder;
} else {
var instance = null;
2017-06-02 13:52:29 +02:00
var geometry = null;
if (this instanceof GameLib.D3.Mesh.Sphere) {
geometry = this.sphereGeometry();
} else {
geometry = this.customGeometry();
2016-11-18 16:00:13 +01:00
}
2016-10-14 12:32:53 +02:00
2017-06-08 18:17:03 +02:00
geometry.computeFaceNormals();
geometry.computeVertexNormals();
2016-10-14 12:32:53 +02:00
2017-06-02 13:52:29 +02:00
if (this.meshType === GameLib.D3.Mesh.TYPE_NORMAL) {
instance = new THREE.Mesh(geometry);
2017-06-09 16:03:05 +02:00
} else if (this.meshType === GameLib.D3.Mesh.TYPE_CURVE) {
2017-06-02 13:52:29 +02:00
instance = new THREE.Points(geometry);
2017-06-09 16:03:05 +02:00
} else if (this.meshType === GameLib.D3.Mesh.TYPE_SKINNED) {
2016-10-14 12:32:53 +02:00
2016-11-18 16:00:13 +01:00
/**
* Setup bones (indexes)
*/
for (var si = 0; si < this.skinIndices.length; si++) {
2017-06-02 13:52:29 +02:00
geometry.skinIndices.push(
2016-12-23 16:07:10 +01:00
new THREE.Vector4(
2016-11-18 16:00:13 +01:00
this.skinIndices[si].x,
this.skinIndices[si].y,
this.skinIndices[si].z,
this.skinIndices[si].w
)
);
}
2016-10-14 12:32:53 +02:00
2016-11-18 16:00:13 +01:00
/**
* Setup bones (weights)
*/
for (var sw = 0; sw < this.skinWeights.length; sw++) {
2017-06-02 13:52:29 +02:00
geometry.skinWeights.push(
2016-12-23 16:07:10 +01:00
new THREE.Vector4(
2016-11-18 16:00:13 +01:00
this.skinWeights[sw].x,
this.skinWeights[sw].y,
this.skinWeights[sw].z,
this.skinWeights[sw].w
)
);
}
2016-10-14 12:32:53 +02:00
2017-06-02 13:52:29 +02:00
instance = new THREE.SkinnedMesh(geometry);
2016-10-14 12:32:53 +02:00
2016-12-23 16:07:10 +01:00
instance.add(this.skeleton.rootBoneInstance);
2016-10-14 12:32:53 +02:00
2016-12-23 16:07:10 +01:00
instance.bind(this.skeleton.instance);
2017-06-09 16:03:05 +02:00
} else {
2016-11-18 16:00:13 +01:00
console.log('cannot handle meshes of type ' + this.meshType + ' yet.');
}
2016-10-14 12:32:53 +02:00
2017-06-09 16:03:05 +02:00
instance.name = this.name;
2016-11-17 18:31:41 +01:00
2017-06-09 16:03:05 +02:00
if (this.parentMesh && this.parentMesh.loaded) {
2016-11-17 18:31:41 +01:00
2017-06-09 16:03:05 +02:00
instance.parent = this.parentMesh.instance;
2016-12-22 17:22:19 +01:00
2017-06-09 16:03:05 +02:00
instance.position.x = this.localPosition.x;
instance.position.y = this.localPosition.y;
instance.position.z = this.localPosition.z;
2016-12-22 17:22:19 +01:00
2017-06-09 16:03:05 +02:00
instance.rotation.x = this.localRotation.x;
instance.rotation.y = this.localRotation.y;
instance.rotation.z = this.localRotation.z;
2016-12-22 17:22:19 +01:00
2017-06-09 16:03:05 +02:00
instance.scale.x = this.localScale.x;
instance.scale.y = this.localScale.y;
instance.scale.z = this.localScale.z;
2016-12-22 17:22:19 +01:00
2017-06-09 16:03:05 +02:00
} else {
instance.quaternion.x = this.quaternion.x;
instance.quaternion.y = this.quaternion.y;
instance.quaternion.z = this.quaternion.z;
instance.quaternion.w = this.quaternion.w;
instance.position.x = this.position.x + this.localPosition.x;
instance.position.y = this.position.y + this.localPosition.y;
instance.position.z = this.position.z + this.localPosition.z;
instance.scale.x = this.scale.x * this.localScale.x;
instance.scale.y = this.scale.y * this.localScale.y;
instance.scale.z = this.scale.z * this.localScale.z;
instance.up.x = this.up.x;
instance.up.y = this.up.y;
instance.up.z = this.up.z;
instance.rotateX(this.localRotation.x);
instance.rotateY(this.localRotation.y);
instance.rotateZ(this.localRotation.z);
}
2016-12-22 17:22:19 +01:00
2017-06-09 16:03:05 +02:00
if (this.materials.length === 1 && this.materials[0].instance) {
instance.material = this.materials[0].instance;
}
2017-06-09 16:03:05 +02:00
instance.renderOrder = this.renderOrder;
2017-06-09 16:03:05 +02:00
this.subscribe(
GameLib.Event.MATERIAL_LOADED,
function(data) {
2016-12-13 15:41:02 +01:00
2017-06-09 16:03:05 +02:00
if (this.instance.material === data.material.instance) {
return;
}
2017-02-01 16:09:34 +01:00
2017-06-09 16:03:05 +02:00
if (this.materials[0] === data.material) {
this.instance.material = data.material.instance;
this.instance.geometry.uvsNeedUpdate = true;
}
}
);
2017-01-04 16:12:30 +01:00
2017-06-13 10:45:24 +02:00
this.subscribe(
GameLib.Event.MATERIAL_TYPE_CHANGED,
function(data) {
if (this.materials[0].id === data.material.id) {
this.instance.material = data.material.instance;
this.instance.geometry.uvsNeedUpdate = true;
}
}
);
2017-06-09 16:03:05 +02:00
return instance;
}
2016-10-14 12:32:53 +02:00
};
2016-12-09 20:32:09 +01:00
/**
* Updates the mesh instance
*/
2016-11-21 16:08:39 +01:00
GameLib.D3.Mesh.prototype.updateInstance = function() {
2017-06-09 16:03:05 +02:00
this.createInstance(true);
2016-11-18 16:00:13 +01:00
};
2016-12-09 20:32:09 +01:00
/**
* Converts a GameLib.D3.Mesh to a GameLib.D3.API.Mesh
* @returns {GameLib.D3.API.Mesh}
*/
2017-06-13 14:09:18 +02:00
GameLib.D3.Mesh.prototype.toApiObject = function(save) {
2016-12-09 20:32:09 +01:00
2016-12-23 16:07:10 +01:00
var apiSkeleton = null;
if (this.skeleton) {
2017-06-13 14:09:18 +02:00
if (save) {
this.skeleton.save();
}
apiSkeleton = this.skeleton.id;
}
var apiMaterials = null;
if (this.materials) {
apiMaterials = this.materials.map(
function(material) {
if (save) {
material.save();
}
return material.id;
}
)
2016-12-23 16:07:10 +01:00
}
2016-12-09 20:32:09 +01:00
return new GameLib.D3.API.Mesh(
this.id,
this.meshType,
this.name,
2016-12-22 17:22:19 +01:00
this.vertices.map(
function (vertex) {
2017-05-16 14:51:57 +02:00
return vertex.toApiObject();
2016-12-22 17:22:19 +01:00
}
),
2016-12-09 20:32:09 +01:00
this.faces,
this.faceVertexUvs,
2017-06-13 14:09:18 +02:00
apiMaterials,
GameLib.Utils.IdOrNull(this.parentMesh),
GameLib.Utils.IdOrNull(this.parentScene),
2016-12-23 16:07:10 +01:00
apiSkeleton,
2016-12-09 20:32:09 +01:00
this.skinIndices,
this.skinWeights,
2017-05-16 14:51:57 +02:00
this.position.toApiObject(),
this.quaternion.toApiObject(),
this.scale.toApiObject(),
this.localPosition.toApiObject(),
this.localRotation.toApiObject(),
this.localScale.toApiObject(),
this.up.toApiObject(),
this.modelMatrix.toApiObject(),
2017-01-04 16:12:30 +01:00
GameLib.Utils.IdOrNull(this.parentEntity),
this.renderOrder
2016-12-09 20:32:09 +01:00
);
};
/**
* Converts a standard object mesh to a GameLib.D3.Mesh
* @param graphics GameLib.D3.Graphics
* @param objectMesh {Object}
* @constructor
*/
2017-06-08 18:17:03 +02:00
GameLib.D3.Mesh.FromObjectMesh = function(graphics, objectMesh) {
2016-12-09 20:32:09 +01:00
2017-01-05 19:34:28 +01:00
var apiMesh = GameLib.D3.API.Mesh.FromObjectMesh(objectMesh);
2016-12-09 20:32:09 +01:00
return new GameLib.D3.Mesh(
graphics,
2017-06-08 18:17:03 +02:00
apiMesh
2016-12-09 20:32:09 +01:00
);
};
/**
* Centers the mesh around origin
*/
GameLib.D3.Mesh.prototype.centerAroundOrigin = function() {
var localPosition = this.instance.geometry.center();
this.instance.position.set(0,0,0);
this.instance.updateMatrix();
this.position.x = this.instance.position.x;
this.position.y = this.instance.position.y;
this.position.z = this.instance.position.z;
for (var v = 0; v < this.instance.geometry.vertices.length; v++) {
this.vertices[v].position.x = this.instance.geometry.vertices[v].x;
this.vertices[v].position.y = this.instance.geometry.vertices[v].y;
this.vertices[v].position.z = this.instance.geometry.vertices[v].z;
}
this.localPosition.x = -localPosition.x;
this.localPosition.y = -localPosition.y;
this.localPosition.z = -localPosition.z;
this.updateInstance();
};