start converting between buffer objects and api objects

beta.r3js.org
-=yb4f310 2017-08-27 12:56:14 +02:00
parent bb6db7338a
commit 6f4b491cf0
9 changed files with 786 additions and 525 deletions

View File

@ -61,6 +61,7 @@ GameLib.Event.RENDER = 0x2b;
GameLib.Event.EVENT_LIST = 0x2c;
GameLib.Event.COMPILE_SUCCESS = 0x2d;
GameLib.Event.COMPILE_FAILED = 0x2e;
GameLib.Event.IMAGE_CHANGED = 0x2f;
/**
* Returns string name of event ID
@ -117,6 +118,7 @@ GameLib.Event.GetEventName = function(number) {
case 0x2c : return 'event_list';
case 0x2d : return 'compile_success';
case 0x2e : return 'compile_failed';
case 0x2f : return 'image_changed';
break;
}

View File

@ -660,15 +660,26 @@ GameLib.Utils.isNumber = function(member) {
};
GameLib.Utils.isVector2 = function(member) {
return (member instanceof GameLib.Vector2);
return (
member instanceof GameLib.API.Vector2 ||
member instanceof GameLib.Vector2
);
};
GameLib.Utils.isVector3 = function(member) {
return (member instanceof GameLib.Vector3);
return (
member instanceof GameLib.API.Vector3 ||
member instanceof GameLib.Vector3
);
};
GameLib.Utils.isVector4 = function(member) {
return (member instanceof GameLib.Vector4);
return (
member instanceof GameLib.API.Vector4 ||
member instanceof GameLib.Vector4 ||
member instanceof GameLib.API.Quaternion ||
member instanceof GameLib.Quaternion
);
};
/**

View File

@ -490,6 +490,7 @@ GameLib.D3.Material.prototype.createMeshBasicMaterialInstance = function() {
* updates textures
*/
GameLib.D3.Material.prototype.updateTextures = function() {
if (this.alphaMap && this.alphaMap.instance) {
this.instance.alphaMap = this.alphaMap.instance;
} else {
@ -972,6 +973,61 @@ GameLib.D3.Material.prototype.toApiObject = function(save) {
return apiMaterial;
};
GameLib.D3.Material.prototype.getTextures = function() {
var textures = [];
if (this.alphaMap) {
textures.push(this.alphaMap);
}
if (this.aoMap) {
textures.push(this.aoMap);
}
if (this.bumpMap) {
textures.push(this.bumpMap);
}
if (this.diffuseMap) {
textures.push(this.diffuseMap);
}
if (this.displacementMap) {
textures.push(this.displacementMap);
}
if (this.emissiveMap) {
textures.push(this.emissiveMap);
}
if (this.environmentMap) {
textures.push(this.environmentMap);
}
if (this.lightMap) {
textures.push(this.lightMap);
}
if (this.metalnessMap) {
textures.push(this.metalnessMap);
}
if (this.normalMap) {
textures.push(this.normalMap);
}
if (this.roughnessMap) {
textures.push(this.roughnessMap);
}
if (this.specularMap) {
textures.push(this.specularMap);
}
return textures;
};
/**
* Creates a GameLib.D3.Material from a material Object
* @param graphics GameLib.D3.Graphics

View File

@ -163,9 +163,258 @@ GameLib.D3.Mesh.MESH_TYPE_CURVE = 0x2;
GameLib.D3.Mesh.MESH_TYPE_SPHERE = 0x3;
GameLib.D3.Mesh.MESH_TYPE_PLANE = 0x4;
GameLib.D3.Mesh.prototype.createInstanceGeometry = function() {
/**
* Setup face indexes - first we sort according to the material index, because later we will create
* groups for each vertice group
*/
this.faces.sort(function(a, b){
if (a.materialIndex < b.materialIndex) {
return -1;
}
if (a.materialIndex > b.materialIndex) {
return 1;
}
return 0;
});
/**
* Setup mesh vertices positions
* @type {Float32Array}
*/
var vertices = new Float32Array(
this.faces.reduce(
function(result, face){
result.push(this.vertices[face.v0].position.x);
result.push(this.vertices[face.v0].position.y);
result.push(this.vertices[face.v0].position.z);
result.push(this.vertices[face.v1].position.x);
result.push(this.vertices[face.v1].position.y);
result.push(this.vertices[face.v1].position.z);
result.push(this.vertices[face.v2].position.x);
result.push(this.vertices[face.v2].position.y);
result.push(this.vertices[face.v2].position.z);
return result;
}.bind(this),
[]
)
);
var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
/**
* Setyp mesh vertices colors
*/
var colors = Float32Array.from(
this.faces.reduce(
function(result, face){
result.push(1,1,1,1,1,1,1,1,1);
// result.push(face.color.r);
// result.push(face.color.g);
// result.push(face.color.b);
// result.push(face.color.r);
// result.push(face.color.g);
// result.push(face.color.b);
// result.push(face.color.r);
// result.push(face.color.g);
// result.push(face.color.b);
return result;
}.bind(this),
[]
)
);
geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3, true));
/**
* Setup face UVs
*/
var uvs = Float32Array.from(
this.faceVertexUvs[0].reduce(
function(result, uv) {
result.push(uv[0].x);
result.push(uv[0].y);
result.push(uv[1].x);
result.push(uv[1].y);
result.push(uv[2].x);
result.push(uv[2].y);
return result;
},
[]
)
);
geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));
/**
* Setup material groups - this means creating a new group for each material index change
* We know faces are sorted according to material index
*/
var groupIndexCounts = this.faces.reduce(
function(result, face) {
var currentGroup = result.pop();
if (currentGroup.index !== face.materialIndex) {
/**
* We have a new group
*/
result.push(currentGroup);
result.push({
index: face.materialIndex,
count: 3
})
} else {
currentGroup.count += 3;
result.push(currentGroup);
}
return result;
},
[
{
index : 0,
count : 0
}
]
);
groupIndexCounts.reduce(
function(start, group) {
geometry.addGroup(start, group.count, group.index);
return start + group.count;
},
0
);
/**
* Apply skin indices
*/
// this.applyBones(geometry);
/**
* Re-compute normals
*/
geometry.computeFaceNormals();
geometry.computeVertexNormals();
return geometry;
};
/**
* Apply geometry data to our game-lib object from the geometry instance (revere of applyVertexData)
* Creates a mesh instance or updates it
*/
GameLib.D3.Mesh.prototype.createInstance = function() {
console.log('mesh create instance');
var geometry = this.createInstanceGeometry();
var instance = null;
var instanceMaterials = function(result, material){
result.push(material.instance);
return result;
};
if (this.skeleton) {
instance = new THREE.SkinnedMesh(
geometry,
this.materials.reduce(
instanceMaterials,
[]
)
);
instance.add(this.skeleton.rootBoneInstance);
instance.bind(this.skeleton.instance);
} else {
instance = new THREE.Mesh(
geometry,
this.materials.reduce(
instanceMaterials,
[]
)
);
}
this.createInstanceDefaults(instance);
return instance;
};
/**
* Updates the mesh instance
*/
GameLib.D3.Mesh.prototype.updateInstance = function() {
console.log('mesh update instance');
if (this.parentMesh && this.parentMesh.loaded) {
if (this.instance.parent !== this.parentMesh.instance) {
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;
if (this.materials.length === 1 && this.materials[0].instance) {
this.instance.material = this.materials[0].instance;
}
this.instance.renderOrder = this.renderOrder;
if (this.helper) {
this.helper.updateInstance();
}
};
/**
* Apply geometry data to our game-lib object from the geometry instance (reverse of applyVertexData)
* @param geometryInstance
*/
GameLib.D3.Mesh.prototype.updateVerticesFromGeometryInstance = function(geometryInstance) {
@ -175,23 +424,151 @@ GameLib.D3.Mesh.prototype.updateVerticesFromGeometryInstance = function(geometry
this.vertices = [];
geometryInstance.vertices.map(function(vertex){
this.vertices.push(
new GameLib.D3.Vertex(
this.graphics,
new GameLib.D3.API.Vertex(
new GameLib.Vector3(
this.graphics,
new GameLib.API.Vector3(
vertex.x,
vertex.y,
vertex.z
)
)
)
)
)
}.bind(this));
this.faces = [];
this.faceVertexUvs = [[]];
if (geometryInstance instanceof THREE.BufferGeometry) {
var vertices = this.instance.geometry.getAttribute('position').array;
var uvs = this.instance.geometry.getAttribute('uv').array;
this.instance.geometry.groups.map(function(group){
var materialIndex = group.materialIndex;
var start = group.start;
var count = group.count;
var faceIndexes = [];
var indexedUvs = [];
for (var i = start; i < count; i ++) {
var vertex = new GameLib.D3.Vertex(
this.graphics,
new GameLib.D3.API.Vertex(
new GameLib.Vector3(
this.graphics,
new GameLib.API.Vector3(
vertices[i*3],
vertices[i*3 + 1],
vertices[i*3 + 2]
)
)
)
);
var uv = new GameLib.Vector2(
this.graphics,
new GameLib.API.Vector2(
uvs[i*2],
uvs[i*2 + 1]
)
);
indexedUvs.push(uv);
var vertexIndex = this.vertices.reduce(
function(result, indexedVertex, currentIndex){
if (indexedVertex.position.equals(vertex.position)) {
result = currentIndex;
}
return result;
},
-1
);
var faceIndex = vertexIndex;
if (vertexIndex === -1) {
this.vertices.push(vertex);
faceIndex = this.vertices.length - 1;
}
faceIndexes.push(faceIndex);
if (faceIndexes.length === 3) {
this.faces.push(new GameLib.D3.TriangleFace(
faceIndexes[0],
faceIndexes[1],
faceIndexes[2],
materialIndex
));
this.faceVertexUvs[0].push([indexedUvs[0], indexedUvs[1], indexedUvs[2]]);
indexedUvs = [];
faceIndexes = [];
}
}
}.bind(this));
console.log('todo : update vertices from buffer geometry');
} else {
geometryInstance.faces.map(function(face){
this.faces.push(
new GameLib.D3.TriangleFace(
face.a,
face.b,
face.c,
face.materialIndex
)
)
}.bind(this));
geometryInstance.vertices.map(function(vertex){
this.vertices.push(
new GameLib.D3.Vertex(
this.graphics,
new GameLib.D3.API.Vertex(
new GameLib.Vector3(
this.graphics,
new GameLib.API.Vector3(
vertex.x,
vertex.y,
vertex.z
)
)
)
)
)
}.bind(this));
geometryInstance.faceVertexUvs[0].map(function(uvs){
this.faceVertexUvs[0].push([
new GameLib.Vector2(
this.graphics,
new GameLib.API.Vector2(
uvs[0].x,
uvs[0].y
)
),
new GameLib.Vector2(
this.graphics,
new GameLib.API.Vector2(
uvs[1].x,
uvs[1].y
)
),
new GameLib.Vector2(
this.graphics,
new GameLib.API.Vector2(
uvs[2].x,
uvs[2].y
)
)
])
}.bind(this))
}
};
@ -290,353 +667,9 @@ GameLib.D3.Mesh.prototype.createInstanceDefaults = function(instance) {
instance.rotateZ(this.localRotation.z);
}
instance.renderOrder = this.renderOrder;
this.subscribe(
GameLib.Event.MATERIAL_TYPE_CHANGED,
function (data) {
/**
* Check if this material is in use by the mesh
*/
var inUse = this.materials.reduce(
function(result, material) {
if (material === data.material) {
result = true;
}
return result;
},
false
);
/**
* If the material is in use, assign all the new material instances to the mesh instance, and update
* geometry uvs
*/
if (inUse) {
this.instance.material = this.materials.map(
function(material){
return material.instance;
}
);
this.instance.geometry.uvsNeedUpdate = true;
}
// if (this.materials[0] === data.material) {
// this.instance.material = data.material.instance;
// this.instance.geometry.uvsNeedUpdate = true;
// }
}
);
};
/**
* Creates a mesh instance or updates it
*/
GameLib.D3.Mesh.prototype.createInstance = function() {
console.log('mesh create instance');
function disposeArray() {
// this.array = null;
}
var geometry = new THREE.BufferGeometry();
/**
* Setup face indexes - first we sort according to the material index, because later we will create
* groups for each vertice group
*/
this.faces.sort(function(a, b){
if (a.materialIndex < b.materialIndex) {
return -1;
}
if (a.materialIndex > b.materialIndex) {
return 1;
}
return 0;
});
/**
* Setup mesh vertices positions
* @type {Float32Array}
*/
var vertices = new Float32Array(
this.faces.reduce(
function(result, face){
result.push(this.vertices[face.v0].position.x);
result.push(this.vertices[face.v0].position.y);
result.push(this.vertices[face.v0].position.z);
result.push(this.vertices[face.v1].position.x);
result.push(this.vertices[face.v1].position.y);
result.push(this.vertices[face.v1].position.z);
result.push(this.vertices[face.v2].position.x);
result.push(this.vertices[face.v2].position.y);
result.push(this.vertices[face.v2].position.z);
return result;
}.bind(this),
[]
)
// this.vertices.reduce(
// function(result, vertex) {
// result.push(vertex.position.x);
// result.push(vertex.position.y);
// result.push(vertex.position.z);
// return result;
// },
// []
// )
);
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3).onUpload( disposeArray ));
/**
* Setyp mesh vertices colors
*/
var colors = Float32Array.from(
this.faces.reduce(
function(result, face){
result.push(1,1,1,1,1,1,1,1,1);
// result.push(face.color.r);
// result.push(face.color.g);
// result.push(face.color.b);
// result.push(face.color.r);
// result.push(face.color.g);
// result.push(face.color.b);
// result.push(face.color.r);
// result.push(face.color.g);
// result.push(face.color.b);
return result;
}.bind(this),
[]
)
);
geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3, true).onUpload( disposeArray ));
/**
* Setup face UVs
*/
var uvs = Float32Array.from(
this.faceVertexUvs[0].reduce(
function(result, uv) {
result.push(uv[0].x);
result.push(uv[0].y);
result.push(uv[1].x);
result.push(uv[1].y);
result.push(uv[2].x);
result.push(uv[2].y);
return result;
},
[]
)
);
geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2).onUpload( disposeArray ));
// geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ).onUpload( disposeArray ) );
// geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ).onUpload( disposeArray ) );
// geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ).onUpload( disposeArray ) );
/**
* Now we create the face indices
*/
// var faceIndices = Uint32Array.from(
// this.faces.reduce(
// function(result, face) {
// result.push(face.v0);
// result.push(face.v1);
// result.push(face.v2);
// return result;
// },
// []
// )
// );
// geometry.setIndex(new THREE.BufferAttribute(faceIndices, 1));
/**
* Setup material groups - this means creating a new group for each material index change
* We know faces are sorted according to material index
*/
var groupIndexCounts = this.faces.reduce(
function(result, face) {
var currentGroup = result.pop();
if (currentGroup.index !== face.materialIndex) {
/**
* We have a new group
*/
result.push(currentGroup);
result.push({
index: face.materialIndex,
count: 3
})
} else {
currentGroup.count += 3;
result.push(currentGroup);
}
return result;
},
[
{
index : 0,
count : 0
}
]
);
groupIndexCounts.reduce(
function(start, group) {
geometry.addGroup(start, group.count, group.index);
return start + group.count;
},
0
);
//geometry.addGroup(0, vertices.length, this.materials.length - 1);
//
// 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
// ),
// new this.graphics.instance.Vector2(
// faceMaterialVertexUvs[fuv][1].x,
// faceMaterialVertexUvs[fuv][1].y
// ),
// new this.graphics.instance.Vector2(
// faceMaterialVertexUvs[fuv][2].x,
// faceMaterialVertexUvs[fuv][2].y
// )
// );
// }
// }
/**
* Apply skin indices
*/
// this.applyBones(geometry);
/**
* Re-compute normals
*/
geometry.computeFaceNormals();
geometry.computeVertexNormals();
var instance = null;
var instanceMaterials = function(result, material){
result.push(material.instance);
return result;
};
if (this.skeleton) {
instance = new THREE.SkinnedMesh(
geometry,
this.materials.reduce(
instanceMaterials,
[]
)
);
instance.add(this.skeleton.rootBoneInstance);
instance.bind(this.skeleton.instance);
} else {
instance = new THREE.Mesh(
geometry,
this.materials.reduce(
instanceMaterials,
[]
)
);
}
//this.createInstanceDefaults(instance);
return instance;
};
/**
* Updates the mesh instance
*/
GameLib.D3.Mesh.prototype.updateInstance = function() {
console.log('mesh update instance');
if (this.parentMesh && this.parentMesh.loaded) {
if (this.instance.parent !== this.parentMesh.instance) {
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;
if (this.materials.length === 1 && this.materials[0].instance) {
this.instance.material = this.materials[0].instance;
}
this.instance.renderOrder = this.renderOrder;
if (this.helper) {
this.helper.updateInstance();
}
};
GameLib.D3.Mesh.prototype.getBoundingBox = function() {
@ -775,31 +808,52 @@ GameLib.D3.Mesh.prototype.applyLocalPositionRotationScale = function() {
this.instance.updateMatrix();
this.localPosition.x = this.instance.position.x;
this.localPosition.y = this.instance.position.y;
this.localPosition.z = this.instance.position.z;
this.updateVerticesFromGeometryInstance(this.instance.geometry);
this.localScale.x = this.instance.scale.x;
this.localScale.y = this.instance.scale.y;
this.localScale.z = this.instance.scale.z;
var geometry = this.createInstanceGeometry();
this.localRotation.x = this.instance.rotation.x;
this.localRotation.y = this.instance.rotation.y;
this.localRotation.z = this.instance.rotation.z;
this.instance.geometry = geometry;
console.log('TODO: update vertices from vertex array - we store them indexed but they live non-indexed');
// var vertices = this.instance.geometry.getAttribute('position').array;
//
// for (var v = 0; v < vertices.length; v+=3) {
//
// this.vertices[v/3].position.x = vertices[v+0];
// this.vertices[v/3].position.y = vertices[v+1];
// this.vertices[v/3].position.z = vertices[v+2];
// }
this.localPosition.x = 0;
this.localPosition.y = 0;
this.localPosition.z = 0;
this.localRotation.x = 0;
this.localRotation.y = 0;
this.localRotation.z = 0;
this.localScale.x = 1;
this.localScale.y = 1;
this.localScale.z = 1;
this.updateInstance();
//
// this.localPosition.x = this.instance.position.x;
// this.localPosition.y = this.instance.position.y;
// this.localPosition.z = this.instance.position.z;
//
// this.localScale.x = this.instance.scale.x;
// this.localScale.y = this.instance.scale.y;
// this.localScale.z = this.instance.scale.z;
//
// this.rotation.x = this.instance.rotation.x;
// this.rotation.y = this.instance.rotation.y;
// this.rotation.z = this.instance.rotation.z;
//
// console.log('TODO: update vertices from vertex array - we store them indexed but they live non-indexed');
// // ;
// //
// // for (var v = 0; v < vertices.length; v+=3) {
// //
// // this.vertices[v/3].position.x = vertices[v+0];
// // this.vertices[v/3].position.y = vertices[v+1];
// // this.vertices[v/3].position.z = vertices[v+2];
// // }
//
// this.updateInstance();
};
/**
* Gets all children components of this Mesh
* @returns {Array}

View File

@ -52,20 +52,27 @@ GameLib.D3.Mesh.Plane.prototype.constructor = GameLib.D3.Mesh.Plane;
GameLib.D3.Mesh.Plane.prototype.createInstance = function() {
var geometry = new THREE.PlaneGeometry(
this.width,
this.height,
this.widthSegments,
this.heightSegments
);
var geometry = null;
/**
* If this geometry is coming from the database, apply the vertex data
*/
if (this.vertices.length > 0) {
this.applyVertexDataToInstance(geometry);
geometry = this.createInstanceGeometry();
} else {
geometry = new THREE.PlaneGeometry(
this.width,
this.height,
this.widthSegments,
this.heightSegments
);
this.updateVerticesFromGeometryInstance(geometry);
geometry = this.createInstanceGeometry();
}
var materialInstances = this.materials.reduce(
@ -96,17 +103,22 @@ GameLib.D3.Mesh.Plane.prototype.updateInstance = function() {
this.instance.userData.widthSegments !== this.widthSegments ||
this.instance.userData.heightSegments !== this.heightSegments
) {
var geometry = new THREE.PlaneGeometry(
this.instance.userData.width = this.width;
this.instance.userData.height = this.height;
this.instance.userData.widthSegments = this.widthSegments;
this.instance.userData.heightSegments = this.heightSegments;
var geometry = new THREE.PlaneGeometry(
this.width,
this.height,
this.widthSegments,
this.heightSegments
);
this.instance.geometry = geometry;
this.updateVerticesFromGeometryInstance(geometry);
this.instance.geometry = this.createInstanceGeometry();
if (this.helper) {
this.removeHelper();
this.createHelper();
@ -196,15 +208,29 @@ GameLib.D3.Mesh.Plane.prototype.getHeightData = function(img,scale) {
* @returns {THREE.PlaneGeometry}
*/
GameLib.D3.Mesh.Plane.prototype.generateHeightMapFromBumpMap = function() {
var data = this.getHeightData();
for ( var i = 0; i < this.instance.geometry.vertices.length; i++ ) {
this.instance.geometry.vertices[i].z = data[i];
}
this.vertices.map(
function(vertex, index) {
vertex.position.z = data[index];
}
);
this.instance.geometry.verticesNeedUpdate = true;
var geometry = this.createInstanceGeometry();
this.updateVerticesFromGeometryInstance(this.instance.geometry);
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();
};

View File

@ -161,7 +161,7 @@ GameLib.D3.Texture.prototype.createInstance = function() {
if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_CUBE) {
if (this.image.instance) {
if (this.image && this.image.instance) {
instance = new THREE.CubeTexture(
[
@ -186,7 +186,7 @@ GameLib.D3.Texture.prototype.createInstance = function() {
} else {
if (this.image.instance) {
if (this.image && this.image.instance) {
instance = new THREE.Texture(
this.image.instance
);
@ -200,17 +200,17 @@ GameLib.D3.Texture.prototype.createInstance = function() {
}
}
//
// instance.name = this.name;
// instance.flipY = this.flipY;
instance.name = this.name;
instance.flipY = this.flipY;
// instance.encoding = this.encoding;
// instance.offset.x = this.offset.x;
// instance.offset.y = this.offset.y;
// instance.repeat.x = this.repeat.x;
// instance.repeat.y = this.repeat.y;
// instance.mapping = this.mapping;
instance.offset.x = this.offset.x;
instance.offset.y = this.offset.y;
instance.repeat.x = this.repeat.x;
instance.repeat.y = this.repeat.y;
//instance.mapping = this.mapping;
// instance.format = this.format;
// instance.wrapS = this.wrapS;
// instance.wrapT = this.wrapT;
instance.wrapS = this.wrapS;
instance.wrapT = this.wrapT;
return instance;
};
@ -222,51 +222,64 @@ GameLib.D3.Texture.prototype.updateInstance = function() {
console.log('texture update instance');
var imageChanged = false;
if (!this.instance) {
console.error('no texture instance');
return;
}
if (!this.image.instance) {
console.error('no image instance');
return;
}
if (this.image && this.image.instance) {
if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_NORMAL) {
if (this.instance.image !== this.image.instance) {
this.instance = new THREE.Texture(
this.image.instance
);
this.mapping = this.instance.mapping;
}
} else if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_CUBE) {
if (this.instance.image[0] !== this.image.instance) {
this.instance = new THREE.CubeTexture(
[
this.image.instance,
this.image.instance,
this.image.instance,
this.image.instance,
this.image.instance,
this.image.instance
]
);
this.mapping = this.instance.mapping;
}
}
if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_NORMAL) {
if (this.instance.image !== this.image.instance) {
this.instance = new THREE.Texture(
this.image.instance
);
this.mapping = this.instance.mapping;
// this.instance.name = this.name;
// this.instance.flipY = this.flipY;
imageChanged = true;
}
} else if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_CUBE) {
if (this.instance.image[0] !== this.image.instance) {
this.instance = new THREE.CubeTexture(
[
this.image.instance,
this.image.instance,
this.image.instance,
this.image.instance,
this.image.instance,
this.image.instance
]
);
this.mapping = this.instance.mapping;
imageChanged = true;
}
}
}
this.instance.name = this.name;
this.instance.flipY = this.flipY;
// this.instance.encoding = this.encoding;
// this.instance.offset.x = this.offset.x;
// this.instance.offset.y = this.offset.y;
// this.instance.repeat.x = this.repeat.x;
// this.instance.repeat.y = this.repeat.y;
// this.instance.mapping = this.mapping;
// this.instance.format = this.format;
// this.instance.wrapS = this.wrapS;
// this.instance.wrapT = this.wrapT;
this.instance.offset.x = this.offset.x;
this.instance.offset.y = this.offset.y;
this.instance.repeat.x = this.repeat.x;
this.instance.repeat.y = this.repeat.y;
this.instance.mapping = this.mapping;
//this.instance.format = this.format;
this.instance.wrapS = this.wrapS;
this.instance.wrapT = this.wrapT;
this.instance.needsUpdate = true;
if (imageChanged) {
this.publish(
GameLib.Event.IMAGE_CHANGED,
{
texture : this
}
)
}
};
/**

View File

@ -113,7 +113,77 @@ GameLib.System.GUI.prototype.start = function() {
)
};
GameLib.System.GUI.prototype.buildVectorControl = function(folder, componentTemplate, property, dimension) {
GameLib.System.GUI.prototype.onChange = function(property, subProperty, affected) {
return function(value) {
affected.map(function(component){
component[property][subProperty] = value;
component.updateInstance();
});
}
};
GameLib.System.GUI.prototype.controller = function(folder, object, property, subProperty, step, listen, affected) {
var min = -100;
var max = 100;
if (property === 'localRotation') {
min = -Math.PI;
max = Math.PI;
}
var handle = folder.add(
object[property],
subProperty,
min,
max,
step
).name(property + '.' + subProperty);
handle.onChange(this.onChange(property, subProperty, affected));
if (listen) {
handle.listen();
}
return handle;
};
GameLib.System.GUI.prototype.buildQuaternionControl = function(folder, componentTemplate, property) {
var step = 0.1;
var object = componentTemplate.template;
var listen = false;
if (componentTemplate.affected.length === 1) {
/**
* If the template only affects a single object - put the handle on this so we can listen for changes
*/
object = componentTemplate.affected[0];
listen = true;
}
var affected = componentTemplate.affected;
this.controller(folder, object, property, 'x', step, listen, affected);
this.controller(folder, object, property, 'y', step, listen, affected);
this.controller(folder, object, property, 'z', step, listen, affected);
this.controller(folder, object, property, 'w', step, listen, affected);
this.controller(folder, object, property, 'angle', step, listen, affected);
object = object[property];
property = 'axis';
this.controller(folder, object, property, 'x', step, listen, affected);
this.controller(folder, object, property, 'y', step, listen, affected);
this.controller(folder, object, property, 'z', step, listen, affected);
};
GameLib.System.GUI.prototype.buildVectorControl = function(folder, componentTemplate, property) {
var step = 0.1;
@ -141,75 +211,21 @@ GameLib.System.GUI.prototype.buildVectorControl = function(folder, componentTemp
step = 0.001;
}
controllers.push();
if (dimension === 4) {
folder.add(
object[property],
'w',
-100,
100,
step
).name(property + '.w').listen().onChange(
function(value) {
affected.map(function(component){
component[property].w = value;
component.updateInstance();
}.bind(this));
}
);
if (GameLib.Utils.isVector4(object[property])) {
controllers.push(this.controller(folder, object, property, 'w', step, listen, affected));
}
folder.add(
object[property],
'x',
-100,
100,
step
).listen().name(property + '.x').onChange(
function(value) {
affected.map(function(component){
component[property].x = value;
component.updateInstance();
}.bind(this));
}
);
folder.add(
object[property],
'y',
-100,
100,
step
).name(property + '.y').listen().onChange(
function(value) {
affected.map(function(component){
component[property].y = value;
component.updateInstance();
}.bind(this));
}
);
controllers.push(this.controller(folder, object, property, 'x', step, listen, affected));
controllers.push(this.controller(folder, object, property, 'y', step, listen, affected));
if (
dimension === 3 ||
dimension === 4
GameLib.Utils.isVector3(object[property]) ||
GameLib.Utils.isVector4(object[property])
) {
folder.add(
object[property],
'z',
-100,
100,
step
).name(property + '.z').listen().onChange(
function(value) {
affected.map(function(component){
component[property].z = value;
component.updateInstance();
}.bind(this));
}
);
controllers.push(this.controller(folder, object, property, 'z', step, listen, affected));
}
};
/**
@ -378,7 +394,15 @@ GameLib.System.GUI.prototype.buildSelectControl = function(folder, componentTemp
/**
* We need to discover the constructor for this component
*/
var constructor = componentTemplate.template[property].constructor;
var constructor = null;
if (componentTemplate.template[property]) {
constructor = componentTemplate.template[property].constructor;
} else {
if (componentTemplate.template.linkedObjects[property]) {
constructor = componentTemplate.template.linkedObjects[property];
}
}
var object = componentTemplate.template;
@ -1256,19 +1280,20 @@ GameLib.System.GUI.prototype.buildGUI = function(data) {
continue;
}
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector2) {
this.buildVectorControl(folder, componentTemplate, templateProperty, 2);
/**
* We only want to affect runtime vectors because their onchange will execute updateInstance()
*/
if (
componentTemplate.template[templateProperty] instanceof GameLib.Vector2 ||
componentTemplate.template[templateProperty] instanceof GameLib.Vector3 ||
componentTemplate.template[templateProperty] instanceof GameLib.Vector4
) {
this.buildVectorControl(folder, componentTemplate, templateProperty);
continue;
}
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector3) {
this.buildVectorControl(folder, componentTemplate, templateProperty, 3);
continue;
}
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector4) {
this.buildVectorControl(folder, componentTemplate, templateProperty, 4);
continue;
if (componentTemplate.template[templateProperty] instanceof GameLib.Quaternion) {
this.buildQuaternionControl(folder, componentTemplate, templateProperty);
}
if (templateProperty === 'parentEntity') {
@ -1277,6 +1302,14 @@ GameLib.System.GUI.prototype.buildGUI = function(data) {
}
if (componentTemplate.template[templateProperty] instanceof Array) {
if (
templateProperty === 'vertices' ||
templateProperty === 'faces'
) {
continue;
}
this.buildArrayManagerControl(folder, componentTemplate, templateProperty);
continue;
}
@ -1288,7 +1321,13 @@ GameLib.System.GUI.prototype.buildGUI = function(data) {
if (typeof componentTemplate.template[templateProperty] === 'object') {
if (componentTemplate.template[templateProperty] instanceof GameLib.Component) {
if (
componentTemplate.template[templateProperty] instanceof GameLib.Component ||
(
componentTemplate.template.linkedObjects &&
componentTemplate.template.linkedObjects[templateProperty]
)
) {
this.buildSelectControl(folder, componentTemplate, templateProperty)
} else {
//TODO: maybe start including some other types of objects

View File

@ -35,6 +35,8 @@ GameLib.System.Linking = function(
this.textureInstanceCreatedSubscription = null;
this.materialInstanceCreatedSubscription = null;
this.meshDeletedSubscription = null;
this.imageChangedSubscription = null;
this.materialTypeChangedSubscription = null;
};
GameLib.System.Linking.prototype = Object.create(GameLib.System.prototype);
@ -96,6 +98,16 @@ GameLib.System.Linking.prototype.start = function() {
GameLib.Event.MESH_DELETED,
this.meshDeleted
);
this.imageChangedSubscription = this.subscribe(
GameLib.Event.IMAGE_CHANGED,
this.imageChanged
);
this.materialTypeChangedSubscription = this.subscribe(
GameLib.Event.MATERIAL_TYPE_CHANGED,
this.materialTypeChanged
)
};
GameLib.System.Linking.prototype.link = function(component, data) {
@ -381,6 +393,22 @@ GameLib.System.Linking.prototype.imageNotFound = function(data) {
};
GameLib.System.Linking.prototype.imageChanged = function(data) {
var materials = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Material);
materials.map(function(material){
var textures = material.getTextures();
if (textures.indexOf(data.texture) !== -1) {
material.updateInstance();
}
});
};
GameLib.System.Linking.prototype.meshInstanceCreated = function(data) {
this.resolveDependencies(data.mesh);
@ -498,6 +526,37 @@ GameLib.System.Linking.prototype.materialInstanceCreated = function(data) {
this.resolveDependencies(data.material);
};
GameLib.System.Linking.prototype.materialTypeChanged = function(data) {
var meshes = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Mesh);
meshes.map(
function(mesh){
var inUse = mesh.materials.reduce(
function(result, material) {
if (material === data.material) {
result = true;
}
return result;
},
false
);
if (inUse) {
mesh.instance.material = mesh.materials.map(function(material){
return material.instance;
});
mesh.instance.geometry.uvsNeedUpdate = true;
}
}
);
};
/**
* Defines what should happen when a parent scene changes
* @param data
@ -640,5 +699,7 @@ GameLib.System.Linking.prototype.stop = function() {
this.textureInstanceCreatedSubscription.remove();
this.materialInstanceCreatedSubscription.remove();
this.meshDeletedSubscription.remove();
this.imageChangedSubscription.remove();
this.materialTypeChangedSubscription.remove();
};

View File

@ -536,13 +536,12 @@ GameLib.System.Storage.prototype.imageUploadComplete = function(data) {
image = GameLib.D3.Image.FromObject(this.graphics, imageData);
}
/**
* Finally, load the image
*/
GameLib.Event.Emit(
GameLib.Event.LOAD_IMAGE,
{
image : image
image : image,
createTexture : true
}
);
@ -719,7 +718,7 @@ GameLib.System.Storage.prototype.loadImage = function(data) {
);
if (onLoaded) {
onLoaded(image);
onLoaded(image, data.createTexture);
}
};