2017-06-23 14:31:41 +02:00
|
|
|
/**
|
|
|
|
* Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param apiMesh GameLib.D3.API.Mesh
|
|
|
|
* @param width
|
|
|
|
* @param height
|
|
|
|
* @param widthSegments
|
|
|
|
* @param heightSegments
|
2017-09-05 05:22:52 +02:00
|
|
|
* @param heightMapScale
|
|
|
|
* @param isHeightMap
|
2017-09-20 15:24:15 +02:00
|
|
|
* @param isClippingPlane
|
|
|
|
* @param distanceFromOrigin
|
2017-06-23 14:31:41 +02:00
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Mesh.Plane = function (
|
|
|
|
graphics,
|
|
|
|
apiMesh,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
widthSegments,
|
2017-08-29 21:58:11 +02:00
|
|
|
heightSegments,
|
|
|
|
heightMapScale,
|
2017-09-20 15:24:15 +02:00
|
|
|
isHeightMap,
|
|
|
|
isClippingPlane,
|
|
|
|
distanceFromOrigin
|
2017-06-23 14:31:41 +02:00
|
|
|
) {
|
|
|
|
this.graphics = graphics;
|
|
|
|
this.graphics.isNotThreeThrow();
|
|
|
|
|
2017-10-29 20:54:34 +01:00
|
|
|
if (GameLib.Utils.UndefinedOrNull(apiMesh)) {
|
|
|
|
apiMesh = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (apiMesh instanceof GameLib.D3.Mesh.Box) {
|
|
|
|
return apiMesh;
|
|
|
|
}
|
|
|
|
|
|
|
|
apiMesh.meshType = GameLib.D3.Mesh.MESH_TYPE_PLANE;
|
|
|
|
|
2017-06-23 14:31:41 +02:00
|
|
|
if (GameLib.Utils.UndefinedOrNull(width)) {
|
|
|
|
width = 1;
|
|
|
|
}
|
|
|
|
this.width = width;
|
|
|
|
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(height)) {
|
|
|
|
height = 1;
|
|
|
|
}
|
|
|
|
this.height = height;
|
|
|
|
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(widthSegments)) {
|
|
|
|
widthSegments = 1;
|
|
|
|
}
|
|
|
|
this.widthSegments = widthSegments;
|
|
|
|
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(heightSegments)) {
|
|
|
|
heightSegments = 1
|
|
|
|
}
|
|
|
|
this.heightSegments = heightSegments;
|
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
if (GameLib.Utils.UndefinedOrNull(heightMapScale)) {
|
|
|
|
heightMapScale = 1;
|
|
|
|
}
|
|
|
|
this.heightMapScale = heightMapScale;
|
|
|
|
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(isHeightMap)) {
|
|
|
|
isHeightMap = false;
|
|
|
|
}
|
|
|
|
this.isHeightMap = isHeightMap;
|
|
|
|
|
2017-09-20 15:24:15 +02:00
|
|
|
if (GameLib.Utils.UndefinedOrNull(isClippingPlane)) {
|
|
|
|
isClippingPlane = false;
|
|
|
|
}
|
|
|
|
this.isClippingPlane = isClippingPlane;
|
|
|
|
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(distanceFromOrigin)) {
|
|
|
|
distanceFromOrigin = 0;
|
|
|
|
}
|
|
|
|
this.distanceFromOrigin = distanceFromOrigin;
|
|
|
|
|
|
|
|
GameLib.D3.Mesh.call(
|
2017-06-23 14:31:41 +02:00
|
|
|
this,
|
|
|
|
this.graphics,
|
|
|
|
apiMesh
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Mesh.Plane.prototype = Object.create(GameLib.D3.Mesh.prototype);
|
|
|
|
GameLib.D3.Mesh.Plane.prototype.constructor = GameLib.D3.Mesh.Plane;
|
|
|
|
|
|
|
|
|
2017-06-28 17:09:06 +02:00
|
|
|
GameLib.D3.Mesh.Plane.prototype.createInstance = function() {
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-08-27 12:56:14 +02:00
|
|
|
var geometry = null;
|
2017-06-23 14:31:41 +02:00
|
|
|
|
|
|
|
/**
|
2017-08-29 21:58:11 +02:00
|
|
|
* If this geometry is not coming from the database, apply the vertex data from the instance to our runtime object
|
2017-06-23 14:31:41 +02:00
|
|
|
*/
|
2017-08-29 21:58:11 +02:00
|
|
|
if (this.vertices.length === 0) {
|
2017-08-27 12:56:14 +02:00
|
|
|
|
|
|
|
geometry = new THREE.PlaneGeometry(
|
|
|
|
this.width,
|
|
|
|
this.height,
|
|
|
|
this.widthSegments,
|
|
|
|
this.heightSegments
|
|
|
|
);
|
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
this.updateVerticesFromGeometryInstance(geometry);
|
|
|
|
|
2017-09-05 13:18:10 +02:00
|
|
|
/**
|
2017-09-05 05:22:52 +02:00
|
|
|
* If this is a heightmap - first generate the z-coordinates
|
|
|
|
*/
|
|
|
|
if (this.isHeightMap) {
|
|
|
|
this.generateHeightMapFromBumpMap();
|
|
|
|
}
|
|
|
|
}
|
2017-08-29 21:58:11 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Now construct the mesh instance
|
|
|
|
*/
|
2017-10-23 14:52:35 +02:00
|
|
|
GameLib.D3.Mesh.prototype.createInstance.call(this);
|
2017-08-29 21:58:11 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Apply some plane specific data to the instance
|
|
|
|
*/
|
2017-10-23 14:52:35 +02:00
|
|
|
this.instance.userData.width = this.width;
|
|
|
|
this.instance.userData.height = this.height;
|
|
|
|
this.instance.userData.widthSegments = this.widthSegments;
|
|
|
|
this.instance.userData.heightSegments = this.heightSegments;
|
|
|
|
this.instance.userData.heightMapScale = this.heightMapScale;
|
|
|
|
this.instance.userData.isHeightMap = this.isHeightMap;
|
|
|
|
this.instance.userData.isClippingPlane = this.isClippingPlane;
|
|
|
|
this.instance.userData.distanceFromOrigin = this.distanceFromOrigin;
|
2017-09-20 15:24:15 +02:00
|
|
|
|
|
|
|
if (this.isClippingPlane) {
|
2017-10-23 14:52:35 +02:00
|
|
|
this.instance.clipping = new THREE.Plane(
|
2017-09-20 15:24:15 +02:00
|
|
|
geometry.faces[0].normal,
|
|
|
|
this.distanceFromOrigin
|
|
|
|
);
|
|
|
|
}
|
2017-06-23 14:31:41 +02:00
|
|
|
};
|
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2017-06-23 14:31:41 +02:00
|
|
|
GameLib.D3.Mesh.Plane.prototype.updateInstance = function() {
|
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
var geometry = null;
|
|
|
|
|
2017-06-23 14:31:41 +02:00
|
|
|
if (
|
|
|
|
this.instance.userData.width !== this.width ||
|
|
|
|
this.instance.userData.height !== this.height ||
|
|
|
|
this.instance.userData.widthSegments !== this.widthSegments ||
|
2017-08-29 21:58:11 +02:00
|
|
|
this.instance.userData.heightSegments !== this.heightSegments ||
|
|
|
|
this.instance.userData.isHeightMap !== this.isHeightMap ||
|
2017-09-20 15:24:15 +02:00
|
|
|
this.instance.userData.heightMapScale !== this.heightMapScale ||
|
|
|
|
this.instance.userData.isClippingPlane !== this.isClippingPlane ||
|
|
|
|
this.instance.userData.distanceFromOrigin !== this.distanceFromOrigin
|
2017-06-23 14:31:41 +02:00
|
|
|
) {
|
2017-08-27 12:56:14 +02:00
|
|
|
this.instance.userData.width = this.width;
|
|
|
|
this.instance.userData.height = this.height;
|
|
|
|
this.instance.userData.widthSegments = this.widthSegments;
|
|
|
|
this.instance.userData.heightSegments = this.heightSegments;
|
2017-08-29 21:58:11 +02:00
|
|
|
this.instance.userData.isHeightMap = this.isHeightMap;
|
|
|
|
this.instance.userData.heightMapScale = this.heightMapScale;
|
2017-09-20 15:24:15 +02:00
|
|
|
this.instance.userData.isClippingPlane = this.isClippingPlane;
|
|
|
|
this.instance.userData.distanceFromOrigin = this.distanceFromOrigin;
|
2017-08-27 12:56:14 +02:00
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
geometry = new THREE.PlaneGeometry(
|
2017-06-23 14:31:41 +02:00
|
|
|
this.width,
|
|
|
|
this.height,
|
|
|
|
this.widthSegments,
|
|
|
|
this.heightSegments
|
|
|
|
);
|
|
|
|
|
|
|
|
this.updateVerticesFromGeometryInstance(geometry);
|
2017-08-24 22:20:40 +02:00
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
if (this.isHeightMap) {
|
|
|
|
this.generateHeightMapFromBumpMap();
|
2017-08-24 22:20:40 +02:00
|
|
|
}
|
2017-08-29 21:58:11 +02:00
|
|
|
|
|
|
|
geometry = this.createInstanceGeometry();
|
|
|
|
|
|
|
|
this.instance.geometry = geometry;
|
2017-09-20 15:24:15 +02:00
|
|
|
|
|
|
|
if (this.isClippingPlane) {
|
|
|
|
this.instance.clipping = new THREE.Plane(
|
|
|
|
geometry.faces[0].normal,
|
|
|
|
this.distanceFromOrigin
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2017-06-23 14:31:41 +02:00
|
|
|
|
|
|
|
GameLib.D3.Mesh.prototype.updateInstance.call(this);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts a GameLib.D3.Mesh to a GameLib.D3.API.Mesh
|
|
|
|
* @returns {GameLib.D3.API.Mesh}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Mesh.Plane.prototype.toApiObject = function() {
|
|
|
|
|
|
|
|
var apiMesh = GameLib.D3.Mesh.prototype.toApiObject.call(this);
|
|
|
|
|
|
|
|
apiMesh.width = this.width;
|
|
|
|
apiMesh.height = this.height;
|
|
|
|
apiMesh.widthSegments = this.widthSegments;
|
|
|
|
apiMesh.heightSegments = this.heightSegments;
|
2017-08-29 21:58:11 +02:00
|
|
|
apiMesh.heightMapScale = this.heightMapScale;
|
|
|
|
apiMesh.isHeightMap = this.isHeightMap;
|
2017-09-20 15:24:15 +02:00
|
|
|
apiMesh.isClippingPlane = this.isClippingPlane;
|
|
|
|
apiMesh.distanceFromOrigin = this.distanceFromOrigin;
|
2017-06-23 14:31:41 +02:00
|
|
|
|
|
|
|
return apiMesh;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* TODO fix all this weird loading shit
|
|
|
|
* Converts a standard object mesh to a GameLib.D3.Mesh
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param objectMesh {Object}
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Mesh.Plane.FromObject = function(graphics, objectMesh) {
|
|
|
|
|
|
|
|
var apiMesh = GameLib.D3.API.Mesh.FromObject(objectMesh);
|
|
|
|
|
|
|
|
return new GameLib.D3.Mesh.Plane(
|
|
|
|
graphics,
|
|
|
|
apiMesh,
|
|
|
|
objectMesh.width,
|
|
|
|
objectMesh.height,
|
|
|
|
objectMesh.widthSegments,
|
2017-08-29 21:58:11 +02:00
|
|
|
objectMesh.heightSegments,
|
|
|
|
objectMesh.heightMapScale,
|
2017-09-20 15:24:15 +02:00
|
|
|
objectMesh.isHeightMap,
|
|
|
|
objectMesh.isClippingPlane,
|
|
|
|
objectMesh.distanceFromOrigin
|
2017-06-23 14:31:41 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
GameLib.D3.Mesh.Plane.prototype.getHeightData = function() {
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
var i;
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
var img = this.materials.reduce(
|
|
|
|
function(result, material) {
|
|
|
|
if (
|
|
|
|
material.bumpMap &&
|
|
|
|
material.bumpMap.image &&
|
|
|
|
material.bumpMap.image.instance
|
|
|
|
) {
|
|
|
|
result = material.bumpMap.image.instance;
|
|
|
|
}
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
return result;
|
|
|
|
},
|
|
|
|
null
|
|
|
|
);
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
if (!img) {
|
|
|
|
throw new Error('bumpmap image not found');
|
|
|
|
}
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
var canvas = document.createElement( 'canvas' );
|
2017-09-01 17:05:29 +02:00
|
|
|
canvas.width = this.widthSegments + 1;//img.width;
|
|
|
|
canvas.height = this.heightSegments + 1;//img.height;
|
2017-08-29 21:58:11 +02:00
|
|
|
var context = canvas.getContext( '2d' );
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-09-01 17:05:29 +02:00
|
|
|
var size = (this.widthSegments + 1) * (this.heightSegments + 1);
|
2017-08-29 21:58:11 +02:00
|
|
|
var data = new Float32Array( size );
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-09-01 17:05:29 +02:00
|
|
|
context.drawImage(img,0,0, canvas.width, canvas.height);
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
for (i = 0; i < size; i ++ ) {
|
|
|
|
data[i] = 0
|
|
|
|
}
|
|
|
|
|
2017-09-01 17:05:29 +02:00
|
|
|
var imgd = context.getImageData(0, 0, (this.widthSegments + 1), (this.heightSegments + 1));
|
2017-08-29 21:58:11 +02:00
|
|
|
var pix = imgd.data;
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
var j=0;
|
|
|
|
for (i = 0; i<pix.length; i +=4) {
|
|
|
|
var all = pix[i]+pix[i+1]+pix[i+2];
|
|
|
|
data[j++] = all/(12*this.heightMapScale);
|
|
|
|
}
|
|
|
|
|
2017-09-01 17:05:29 +02:00
|
|
|
// data = GameLib.Utils.InterpolateArray(data, (this.widthSegments + 1) * (this.heightSegments + 1));
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-09-01 17:05:29 +02:00
|
|
|
return data;
|
2017-06-23 14:31:41 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @returns {THREE.PlaneGeometry}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Mesh.Plane.prototype.generateHeightMapFromBumpMap = function() {
|
2017-08-27 12:56:14 +02:00
|
|
|
|
2017-06-23 14:31:41 +02:00
|
|
|
var data = this.getHeightData();
|
|
|
|
|
2017-08-27 12:56:14 +02:00
|
|
|
this.vertices.map(
|
|
|
|
function(vertex, index) {
|
|
|
|
vertex.position.z = data[index];
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2017-08-29 21:58:11 +02:00
|
|
|
// var geometry = this.createInstanceGeometry();
|
|
|
|
//
|
|
|
|
// this.instance.geometry = geometry;
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-08-27 12:56:14 +02:00
|
|
|
//
|
|
|
|
// var vertices = this.instance.geometry.attributes.position.array;
|
|
|
|
//
|
|
|
|
// for ( var i = 0; i < vertices.length; i += 3 ) {
|
|
|
|
// vertices[i+2] = data[i];
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// this.instance.geometry.attributes.position.needsUpdate = true;
|
2017-06-23 14:31:41 +02:00
|
|
|
|
2017-08-27 12:56:14 +02:00
|
|
|
//this.updateVerticesFromGeometryInstance(this.instance.geometry);
|
2017-06-23 14:31:41 +02:00
|
|
|
|
|
|
|
// this.updateInstance();
|
|
|
|
};
|
2017-09-11 17:47:32 +02:00
|
|
|
|
|
|
|
GameLib.D3.Mesh.Plane.prototype.createPhysicsObjects = function() {
|
|
|
|
|
|
|
|
GameLib.Event.Emit(
|
2017-10-27 15:31:51 +02:00
|
|
|
GameLib.Event.GET_PHYSICS_IMPLEMENTATION,
|
2017-09-11 17:47:32 +02:00
|
|
|
null,
|
2017-10-27 15:31:51 +02:00
|
|
|
function(physics){
|
2017-09-12 21:09:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create the plane shape
|
|
|
|
* @type {GameLib.D3.API.Shape}
|
|
|
|
*/
|
|
|
|
var apiShapePlane = new GameLib.D3.API.Shape(
|
2017-09-11 17:47:32 +02:00
|
|
|
null,
|
|
|
|
'Shape Plane (' + this.name + ')'
|
|
|
|
);
|
|
|
|
|
2017-09-12 21:09:15 +02:00
|
|
|
apiShapePlane.parentMesh = this;
|
2017-09-11 17:47:32 +02:00
|
|
|
|
2017-09-12 21:09:15 +02:00
|
|
|
var shapePlane = new GameLib.D3.Shape.Plane(
|
2017-10-27 15:31:51 +02:00
|
|
|
physics,
|
2017-09-12 21:09:15 +02:00
|
|
|
apiShapePlane
|
2017-09-11 17:47:32 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
var apiRigidBody = new GameLib.D3.API.RigidBody(
|
|
|
|
null,
|
2017-09-12 21:09:15 +02:00
|
|
|
'Rigid Body (' + this.name + ')',
|
|
|
|
0,
|
|
|
|
null,
|
|
|
|
new GameLib.API.Vector3(
|
|
|
|
this.position.x,
|
|
|
|
this.position.y,
|
|
|
|
this.position.z
|
|
|
|
),
|
|
|
|
new GameLib.API.Quaternion(
|
|
|
|
this.quaternion.x,
|
|
|
|
this.quaternion.y,
|
|
|
|
this.quaternion.z,
|
|
|
|
this.quaternion.w,
|
|
|
|
new GameLib.API.Vector3(
|
|
|
|
this.quaternion.axis.x,
|
|
|
|
this.quaternion.axis.y,
|
|
|
|
this.quaternion.axis.z
|
|
|
|
),
|
|
|
|
this.quaternion.angle
|
|
|
|
)
|
2017-09-11 17:47:32 +02:00
|
|
|
);
|
|
|
|
|
2017-09-12 21:09:15 +02:00
|
|
|
apiRigidBody.shapes.push(shapePlane);
|
|
|
|
|
|
|
|
apiRigidBody.parentMesh = this;
|
2017-09-11 17:47:32 +02:00
|
|
|
|
2017-09-12 21:09:15 +02:00
|
|
|
/**
|
|
|
|
* Construct the rigid body
|
|
|
|
* @type {GameLib.D3.RigidBody}
|
|
|
|
*/
|
2017-09-11 17:47:32 +02:00
|
|
|
var rigidBody = new GameLib.D3.RigidBody(
|
2017-10-27 15:31:51 +02:00
|
|
|
physics,
|
2017-09-11 17:47:32 +02:00
|
|
|
apiRigidBody
|
|
|
|
);
|
|
|
|
|
2017-09-12 21:09:15 +02:00
|
|
|
if (this.parentEntity instanceof GameLib.Entity) {
|
|
|
|
this.parentEntity.addComponent(shapePlane);
|
|
|
|
this.parentEntity.addComponent(rigidBody);
|
|
|
|
}
|
2017-09-11 17:47:32 +02:00
|
|
|
|
|
|
|
}.bind(this),
|
|
|
|
function(error){
|
|
|
|
console.log(error.message);
|
|
|
|
throw new Error(error.message);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|