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

399 lines
10 KiB
JavaScript

/**
* Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created
* @param graphics GameLib.GraphicsRuntime
* @param apiMesh GameLib.D3.API.Mesh
* @param width
* @param height
* @param widthSegments
* @param heightSegments
* @param heightMapScale
* @param isHeightMap
* @param isClippingPlane
* @param distanceFromOrigin
* @constructor
*/
GameLib.D3.Mesh.Plane = function (
graphics,
apiMesh,
width,
height,
widthSegments,
heightSegments,
heightMapScale,
isHeightMap,
isClippingPlane,
distanceFromOrigin
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
if (GameLib.Utils.UndefinedOrNull(apiMesh)) {
apiMesh = {};
}
if (apiMesh instanceof GameLib.D3.Mesh.Box) {
return apiMesh;
}
apiMesh.meshType = GameLib.D3.Mesh.MESH_TYPE_PLANE;
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;
if (GameLib.Utils.UndefinedOrNull(heightMapScale)) {
heightMapScale = 1;
}
this.heightMapScale = heightMapScale;
if (GameLib.Utils.UndefinedOrNull(isHeightMap)) {
isHeightMap = false;
}
this.isHeightMap = isHeightMap;
if (GameLib.Utils.UndefinedOrNull(isClippingPlane)) {
isClippingPlane = false;
}
this.isClippingPlane = isClippingPlane;
if (GameLib.Utils.UndefinedOrNull(distanceFromOrigin)) {
distanceFromOrigin = 0;
}
this.distanceFromOrigin = distanceFromOrigin;
GameLib.D3.Mesh.call(
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;
GameLib.D3.Mesh.Plane.prototype.createInstance = function() {
var geometry = null;
/**
* If this geometry is not coming from the database, apply the vertex data from the instance to our runtime object
*/
if (this.vertices.length === 0) {
geometry = new THREE.PlaneGeometry(
this.width,
this.height,
this.widthSegments,
this.heightSegments
);
this.updateVerticesFromGeometryInstance(geometry);
/**
* If this is a heightmap - first generate the z-coordinates
*/
if (this.isHeightMap) {
this.generateHeightMapFromBumpMap();
}
}
/**
* Now construct the mesh instance
*/
GameLib.D3.Mesh.prototype.createInstance.call(this);
/**
* Apply some plane specific data to the instance
*/
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;
if (this.isClippingPlane) {
this.instance.clipping = new THREE.Plane(
geometry.faces[0].normal,
this.distanceFromOrigin
);
}
};
/**
*
*/
GameLib.D3.Mesh.Plane.prototype.updateInstance = function(property) {
var geometry = null;
if (
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.isHeightMap !== this.isHeightMap ||
this.instance.userData.heightMapScale !== this.heightMapScale ||
this.instance.userData.isClippingPlane !== this.isClippingPlane ||
this.instance.userData.distanceFromOrigin !== this.distanceFromOrigin
) {
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.isHeightMap = this.isHeightMap;
this.instance.userData.heightMapScale = this.heightMapScale;
this.instance.userData.isClippingPlane = this.isClippingPlane;
this.instance.userData.distanceFromOrigin = this.distanceFromOrigin;
geometry = new THREE.PlaneGeometry(
this.width,
this.height,
this.widthSegments,
this.heightSegments
);
this.updateVerticesFromGeometryInstance(geometry);
if (this.isHeightMap) {
this.generateHeightMapFromBumpMap();
}
geometry = this.createInstanceGeometry();
this.instance.geometry = geometry;
if (this.isClippingPlane) {
this.instance.clipping = new THREE.Plane(
geometry.faces[0].normal,
this.distanceFromOrigin
)
}
}
GameLib.D3.Mesh.prototype.updateInstance.call(this, property);
};
/**
* 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;
apiMesh.heightMapScale = this.heightMapScale;
apiMesh.isHeightMap = this.isHeightMap;
apiMesh.isClippingPlane = this.isClippingPlane;
apiMesh.distanceFromOrigin = this.distanceFromOrigin;
return apiMesh;
};
/**
* TODO fix all this weird loading shit
* Converts a standard object mesh to a GameLib.D3.Mesh
* @param graphics GameLib.GraphicsRuntime
* @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,
objectMesh.heightSegments,
objectMesh.heightMapScale,
objectMesh.isHeightMap,
objectMesh.isClippingPlane,
objectMesh.distanceFromOrigin
);
};
GameLib.D3.Mesh.Plane.prototype.getHeightData = function() {
var i;
var img = this.materials.reduce(
function(result, material) {
if (
material.bumpMap &&
material.bumpMap.image &&
material.bumpMap.image.instance
) {
result = material.bumpMap.image.instance;
}
return result;
},
null
);
if (!img) {
throw new Error('bumpmap image not found');
}
var canvas = document.createElement( 'canvas' );
canvas.width = this.widthSegments + 1;//img.width;
canvas.height = this.heightSegments + 1;//img.height;
var context = canvas.getContext( '2d' );
var size = (this.widthSegments + 1) * (this.heightSegments + 1);
var data = new Float32Array( size );
context.drawImage(img,0,0, canvas.width, canvas.height);
for (i = 0; i < size; i ++ ) {
data[i] = 0
}
var imgd = context.getImageData(0, 0, (this.widthSegments + 1), (this.heightSegments + 1));
var pix = imgd.data;
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);
}
// data = GameLib.Utils.InterpolateArray(data, (this.widthSegments + 1) * (this.heightSegments + 1));
return data;
};
/**
*
* @returns {THREE.PlaneGeometry}
*/
GameLib.D3.Mesh.Plane.prototype.generateHeightMapFromBumpMap = function() {
var data = this.getHeightData();
this.vertices.map(
function(vertex, index) {
vertex.position.z = data[index];
}
);
// var geometry = this.createInstanceGeometry();
//
// this.instance.geometry = geometry;
//
// 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;
//this.updateVerticesFromGeometryInstance(this.instance.geometry);
// this.updateInstance();
};
GameLib.D3.Mesh.Plane.prototype.createPhysicsObjects = function() {
GameLib.Event.Emit(
GameLib.Event.GET_PHYSICS_RUNTIME,
null,
function(physics){
/**
* Create the plane shape
* @type {GameLib.D3.API.Shape}
*/
var apiShapePlane = new GameLib.D3.API.Shape(
null,
'Shape Plane (' + this.name + ')'
);
apiShapePlane.parentMesh = this;
var shapePlane = new GameLib.D3.Shape.Plane(
physics,
apiShapePlane
);
var apiRigidBody = new GameLib.D3.API.RigidBody(
null,
'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
)
);
apiRigidBody.shapes.push(shapePlane);
apiRigidBody.parentMesh = this;
/**
* Construct the rigid body
* @type {GameLib.D3.RigidBody}
*/
var rigidBody = new GameLib.D3.RigidBody(
physics,
apiRigidBody
);
if (this.parentEntity instanceof GameLib.Entity) {
this.parentEntity.addComponent(shapePlane);
this.parentEntity.addComponent(rigidBody);
}
}.bind(this),
function(error){
console.log(error.message);
throw new Error(error.message);
}
);
};