start converting between buffer objects and api objects
parent
bb6db7338a
commit
6f4b491cf0
|
@ -61,6 +61,7 @@ GameLib.Event.RENDER = 0x2b;
|
||||||
GameLib.Event.EVENT_LIST = 0x2c;
|
GameLib.Event.EVENT_LIST = 0x2c;
|
||||||
GameLib.Event.COMPILE_SUCCESS = 0x2d;
|
GameLib.Event.COMPILE_SUCCESS = 0x2d;
|
||||||
GameLib.Event.COMPILE_FAILED = 0x2e;
|
GameLib.Event.COMPILE_FAILED = 0x2e;
|
||||||
|
GameLib.Event.IMAGE_CHANGED = 0x2f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns string name of event ID
|
* Returns string name of event ID
|
||||||
|
@ -117,6 +118,7 @@ GameLib.Event.GetEventName = function(number) {
|
||||||
case 0x2c : return 'event_list';
|
case 0x2c : return 'event_list';
|
||||||
case 0x2d : return 'compile_success';
|
case 0x2d : return 'compile_success';
|
||||||
case 0x2e : return 'compile_failed';
|
case 0x2e : return 'compile_failed';
|
||||||
|
case 0x2f : return 'image_changed';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -660,15 +660,26 @@ GameLib.Utils.isNumber = function(member) {
|
||||||
};
|
};
|
||||||
|
|
||||||
GameLib.Utils.isVector2 = 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) {
|
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) {
|
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
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -490,6 +490,7 @@ GameLib.D3.Material.prototype.createMeshBasicMaterialInstance = function() {
|
||||||
* updates textures
|
* updates textures
|
||||||
*/
|
*/
|
||||||
GameLib.D3.Material.prototype.updateTextures = function() {
|
GameLib.D3.Material.prototype.updateTextures = function() {
|
||||||
|
|
||||||
if (this.alphaMap && this.alphaMap.instance) {
|
if (this.alphaMap && this.alphaMap.instance) {
|
||||||
this.instance.alphaMap = this.alphaMap.instance;
|
this.instance.alphaMap = this.alphaMap.instance;
|
||||||
} else {
|
} else {
|
||||||
|
@ -972,6 +973,61 @@ GameLib.D3.Material.prototype.toApiObject = function(save) {
|
||||||
return apiMaterial;
|
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
|
* Creates a GameLib.D3.Material from a material Object
|
||||||
* @param graphics GameLib.D3.Graphics
|
* @param graphics GameLib.D3.Graphics
|
||||||
|
|
|
@ -163,9 +163,258 @@ GameLib.D3.Mesh.MESH_TYPE_CURVE = 0x2;
|
||||||
GameLib.D3.Mesh.MESH_TYPE_SPHERE = 0x3;
|
GameLib.D3.Mesh.MESH_TYPE_SPHERE = 0x3;
|
||||||
GameLib.D3.Mesh.MESH_TYPE_PLANE = 0x4;
|
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
|
* @param geometryInstance
|
||||||
*/
|
*/
|
||||||
GameLib.D3.Mesh.prototype.updateVerticesFromGeometryInstance = function(geometryInstance) {
|
GameLib.D3.Mesh.prototype.updateVerticesFromGeometryInstance = function(geometryInstance) {
|
||||||
|
@ -175,23 +424,151 @@ GameLib.D3.Mesh.prototype.updateVerticesFromGeometryInstance = function(geometry
|
||||||
|
|
||||||
this.vertices = [];
|
this.vertices = [];
|
||||||
|
|
||||||
geometryInstance.vertices.map(function(vertex){
|
this.faces = [];
|
||||||
this.vertices.push(
|
|
||||||
new GameLib.D3.Vertex(
|
this.faceVertexUvs = [[]];
|
||||||
this.graphics,
|
|
||||||
new GameLib.D3.API.Vertex(
|
if (geometryInstance instanceof THREE.BufferGeometry) {
|
||||||
new GameLib.Vector3(
|
|
||||||
this.graphics,
|
var vertices = this.instance.geometry.getAttribute('position').array;
|
||||||
new GameLib.API.Vector3(
|
|
||||||
vertex.x,
|
var uvs = this.instance.geometry.getAttribute('uv').array;
|
||||||
vertex.y,
|
|
||||||
vertex.z
|
this.instance.geometry.groups.map(function(group){
|
||||||
)
|
|
||||||
)
|
var materialIndex = group.materialIndex;
|
||||||
)
|
|
||||||
)
|
var start = group.start;
|
||||||
)
|
|
||||||
}.bind(this));
|
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.rotateZ(this.localRotation.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
instance.renderOrder = this.renderOrder;
|
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() {
|
GameLib.D3.Mesh.prototype.getBoundingBox = function() {
|
||||||
|
|
||||||
|
@ -775,31 +808,52 @@ GameLib.D3.Mesh.prototype.applyLocalPositionRotationScale = function() {
|
||||||
|
|
||||||
this.instance.updateMatrix();
|
this.instance.updateMatrix();
|
||||||
|
|
||||||
this.localPosition.x = this.instance.position.x;
|
this.updateVerticesFromGeometryInstance(this.instance.geometry);
|
||||||
this.localPosition.y = this.instance.position.y;
|
|
||||||
this.localPosition.z = this.instance.position.z;
|
|
||||||
|
|
||||||
this.localScale.x = this.instance.scale.x;
|
var geometry = this.createInstanceGeometry();
|
||||||
this.localScale.y = this.instance.scale.y;
|
|
||||||
this.localScale.z = this.instance.scale.z;
|
|
||||||
|
|
||||||
this.localRotation.x = this.instance.rotation.x;
|
this.instance.geometry = geometry;
|
||||||
this.localRotation.y = this.instance.rotation.y;
|
|
||||||
this.localRotation.z = this.instance.rotation.z;
|
|
||||||
|
|
||||||
console.log('TODO: update vertices from vertex array - we store them indexed but they live non-indexed');
|
this.localPosition.x = 0;
|
||||||
// var vertices = this.instance.geometry.getAttribute('position').array;
|
this.localPosition.y = 0;
|
||||||
//
|
this.localPosition.z = 0;
|
||||||
// for (var v = 0; v < vertices.length; v+=3) {
|
|
||||||
//
|
this.localRotation.x = 0;
|
||||||
// this.vertices[v/3].position.x = vertices[v+0];
|
this.localRotation.y = 0;
|
||||||
// this.vertices[v/3].position.y = vertices[v+1];
|
this.localRotation.z = 0;
|
||||||
// this.vertices[v/3].position.z = vertices[v+2];
|
|
||||||
// }
|
this.localScale.x = 1;
|
||||||
|
this.localScale.y = 1;
|
||||||
|
this.localScale.z = 1;
|
||||||
|
|
||||||
this.updateInstance();
|
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
|
* Gets all children components of this Mesh
|
||||||
* @returns {Array}
|
* @returns {Array}
|
||||||
|
|
|
@ -52,20 +52,27 @@ GameLib.D3.Mesh.Plane.prototype.constructor = GameLib.D3.Mesh.Plane;
|
||||||
|
|
||||||
GameLib.D3.Mesh.Plane.prototype.createInstance = function() {
|
GameLib.D3.Mesh.Plane.prototype.createInstance = function() {
|
||||||
|
|
||||||
var geometry = new THREE.PlaneGeometry(
|
var geometry = null;
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
this.widthSegments,
|
|
||||||
this.heightSegments
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this geometry is coming from the database, apply the vertex data
|
* If this geometry is coming from the database, apply the vertex data
|
||||||
*/
|
*/
|
||||||
if (this.vertices.length > 0) {
|
if (this.vertices.length > 0) {
|
||||||
this.applyVertexDataToInstance(geometry);
|
|
||||||
|
geometry = this.createInstanceGeometry();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
geometry = new THREE.PlaneGeometry(
|
||||||
|
this.width,
|
||||||
|
this.height,
|
||||||
|
this.widthSegments,
|
||||||
|
this.heightSegments
|
||||||
|
);
|
||||||
|
|
||||||
this.updateVerticesFromGeometryInstance(geometry);
|
this.updateVerticesFromGeometryInstance(geometry);
|
||||||
|
|
||||||
|
geometry = this.createInstanceGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
var materialInstances = this.materials.reduce(
|
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.widthSegments !== this.widthSegments ||
|
||||||
this.instance.userData.heightSegments !== this.heightSegments
|
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.width,
|
||||||
this.height,
|
this.height,
|
||||||
this.widthSegments,
|
this.widthSegments,
|
||||||
this.heightSegments
|
this.heightSegments
|
||||||
);
|
);
|
||||||
|
|
||||||
this.instance.geometry = geometry;
|
|
||||||
|
|
||||||
this.updateVerticesFromGeometryInstance(geometry);
|
this.updateVerticesFromGeometryInstance(geometry);
|
||||||
|
|
||||||
|
this.instance.geometry = this.createInstanceGeometry();
|
||||||
|
|
||||||
if (this.helper) {
|
if (this.helper) {
|
||||||
this.removeHelper();
|
this.removeHelper();
|
||||||
this.createHelper();
|
this.createHelper();
|
||||||
|
@ -196,15 +208,29 @@ GameLib.D3.Mesh.Plane.prototype.getHeightData = function(img,scale) {
|
||||||
* @returns {THREE.PlaneGeometry}
|
* @returns {THREE.PlaneGeometry}
|
||||||
*/
|
*/
|
||||||
GameLib.D3.Mesh.Plane.prototype.generateHeightMapFromBumpMap = function() {
|
GameLib.D3.Mesh.Plane.prototype.generateHeightMapFromBumpMap = function() {
|
||||||
|
|
||||||
var data = this.getHeightData();
|
var data = this.getHeightData();
|
||||||
|
|
||||||
for ( var i = 0; i < this.instance.geometry.vertices.length; i++ ) {
|
this.vertices.map(
|
||||||
this.instance.geometry.vertices[i].z = data[i];
|
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();
|
// this.updateInstance();
|
||||||
};
|
};
|
||||||
|
|
|
@ -161,7 +161,7 @@ GameLib.D3.Texture.prototype.createInstance = function() {
|
||||||
|
|
||||||
if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_CUBE) {
|
if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_CUBE) {
|
||||||
|
|
||||||
if (this.image.instance) {
|
if (this.image && this.image.instance) {
|
||||||
|
|
||||||
instance = new THREE.CubeTexture(
|
instance = new THREE.CubeTexture(
|
||||||
[
|
[
|
||||||
|
@ -186,7 +186,7 @@ GameLib.D3.Texture.prototype.createInstance = function() {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (this.image.instance) {
|
if (this.image && this.image.instance) {
|
||||||
instance = new THREE.Texture(
|
instance = new THREE.Texture(
|
||||||
this.image.instance
|
this.image.instance
|
||||||
);
|
);
|
||||||
|
@ -200,17 +200,17 @@ GameLib.D3.Texture.prototype.createInstance = function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// instance.name = this.name;
|
instance.name = this.name;
|
||||||
// instance.flipY = this.flipY;
|
instance.flipY = this.flipY;
|
||||||
// instance.encoding = this.encoding;
|
// instance.encoding = this.encoding;
|
||||||
// instance.offset.x = this.offset.x;
|
instance.offset.x = this.offset.x;
|
||||||
// instance.offset.y = this.offset.y;
|
instance.offset.y = this.offset.y;
|
||||||
// instance.repeat.x = this.repeat.x;
|
instance.repeat.x = this.repeat.x;
|
||||||
// instance.repeat.y = this.repeat.y;
|
instance.repeat.y = this.repeat.y;
|
||||||
// instance.mapping = this.mapping;
|
//instance.mapping = this.mapping;
|
||||||
// instance.format = this.format;
|
// instance.format = this.format;
|
||||||
// instance.wrapS = this.wrapS;
|
instance.wrapS = this.wrapS;
|
||||||
// instance.wrapT = this.wrapT;
|
instance.wrapT = this.wrapT;
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
};
|
};
|
||||||
|
@ -222,51 +222,64 @@ GameLib.D3.Texture.prototype.updateInstance = function() {
|
||||||
|
|
||||||
console.log('texture update instance');
|
console.log('texture update instance');
|
||||||
|
|
||||||
|
var imageChanged = false;
|
||||||
|
|
||||||
if (!this.instance) {
|
if (!this.instance) {
|
||||||
console.error('no texture instance');
|
console.error('no texture instance');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.image.instance) {
|
if (this.image && this.image.instance) {
|
||||||
console.error('no image instance');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_NORMAL) {
|
if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_NORMAL) {
|
||||||
if (this.instance.image !== this.image.instance) {
|
if (this.instance.image !== this.image.instance) {
|
||||||
this.instance = new THREE.Texture(
|
this.instance = new THREE.Texture(
|
||||||
this.image.instance
|
this.image.instance
|
||||||
);
|
);
|
||||||
this.mapping = this.instance.mapping;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this.instance.name = this.name;
|
imageChanged = true;
|
||||||
// this.instance.flipY = this.flipY;
|
}
|
||||||
|
} 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.encoding = this.encoding;
|
||||||
// this.instance.offset.x = this.offset.x;
|
this.instance.offset.x = this.offset.x;
|
||||||
// this.instance.offset.y = this.offset.y;
|
this.instance.offset.y = this.offset.y;
|
||||||
// this.instance.repeat.x = this.repeat.x;
|
this.instance.repeat.x = this.repeat.x;
|
||||||
// this.instance.repeat.y = this.repeat.y;
|
this.instance.repeat.y = this.repeat.y;
|
||||||
// this.instance.mapping = this.mapping;
|
this.instance.mapping = this.mapping;
|
||||||
// this.instance.format = this.format;
|
//this.instance.format = this.format;
|
||||||
// this.instance.wrapS = this.wrapS;
|
this.instance.wrapS = this.wrapS;
|
||||||
// this.instance.wrapT = this.wrapT;
|
this.instance.wrapT = this.wrapT;
|
||||||
this.instance.needsUpdate = true;
|
this.instance.needsUpdate = true;
|
||||||
|
|
||||||
|
if (imageChanged) {
|
||||||
|
this.publish(
|
||||||
|
GameLib.Event.IMAGE_CHANGED,
|
||||||
|
{
|
||||||
|
texture : this
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
var step = 0.1;
|
||||||
|
|
||||||
|
@ -141,75 +211,21 @@ GameLib.System.GUI.prototype.buildVectorControl = function(folder, componentTemp
|
||||||
step = 0.001;
|
step = 0.001;
|
||||||
}
|
}
|
||||||
|
|
||||||
controllers.push();
|
|
||||||
|
|
||||||
if (dimension === 4) {
|
if (GameLib.Utils.isVector4(object[property])) {
|
||||||
|
controllers.push(this.controller(folder, object, property, 'w', step, listen, affected));
|
||||||
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));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
folder.add(
|
controllers.push(this.controller(folder, object, property, 'x', step, listen, affected));
|
||||||
object[property],
|
controllers.push(this.controller(folder, object, property, 'y', step, listen, affected));
|
||||||
'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));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
dimension === 3 ||
|
GameLib.Utils.isVector3(object[property]) ||
|
||||||
dimension === 4
|
GameLib.Utils.isVector4(object[property])
|
||||||
) {
|
) {
|
||||||
folder.add(
|
controllers.push(this.controller(folder, object, property, 'z', step, listen, affected));
|
||||||
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));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -378,7 +394,15 @@ GameLib.System.GUI.prototype.buildSelectControl = function(folder, componentTemp
|
||||||
/**
|
/**
|
||||||
* We need to discover the constructor for this component
|
* 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;
|
var object = componentTemplate.template;
|
||||||
|
|
||||||
|
@ -1256,19 +1280,20 @@ GameLib.System.GUI.prototype.buildGUI = function(data) {
|
||||||
continue;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector3) {
|
if (componentTemplate.template[templateProperty] instanceof GameLib.Quaternion) {
|
||||||
this.buildVectorControl(folder, componentTemplate, templateProperty, 3);
|
this.buildQuaternionControl(folder, componentTemplate, templateProperty);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector4) {
|
|
||||||
this.buildVectorControl(folder, componentTemplate, templateProperty, 4);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (templateProperty === 'parentEntity') {
|
if (templateProperty === 'parentEntity') {
|
||||||
|
@ -1277,6 +1302,14 @@ GameLib.System.GUI.prototype.buildGUI = function(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (componentTemplate.template[templateProperty] instanceof Array) {
|
if (componentTemplate.template[templateProperty] instanceof Array) {
|
||||||
|
|
||||||
|
if (
|
||||||
|
templateProperty === 'vertices' ||
|
||||||
|
templateProperty === 'faces'
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
this.buildArrayManagerControl(folder, componentTemplate, templateProperty);
|
this.buildArrayManagerControl(folder, componentTemplate, templateProperty);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1288,7 +1321,13 @@ GameLib.System.GUI.prototype.buildGUI = function(data) {
|
||||||
|
|
||||||
if (typeof componentTemplate.template[templateProperty] === 'object') {
|
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)
|
this.buildSelectControl(folder, componentTemplate, templateProperty)
|
||||||
} else {
|
} else {
|
||||||
//TODO: maybe start including some other types of objects
|
//TODO: maybe start including some other types of objects
|
||||||
|
|
|
@ -35,6 +35,8 @@ GameLib.System.Linking = function(
|
||||||
this.textureInstanceCreatedSubscription = null;
|
this.textureInstanceCreatedSubscription = null;
|
||||||
this.materialInstanceCreatedSubscription = null;
|
this.materialInstanceCreatedSubscription = null;
|
||||||
this.meshDeletedSubscription = null;
|
this.meshDeletedSubscription = null;
|
||||||
|
this.imageChangedSubscription = null;
|
||||||
|
this.materialTypeChangedSubscription = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
GameLib.System.Linking.prototype = Object.create(GameLib.System.prototype);
|
GameLib.System.Linking.prototype = Object.create(GameLib.System.prototype);
|
||||||
|
@ -96,6 +98,16 @@ GameLib.System.Linking.prototype.start = function() {
|
||||||
GameLib.Event.MESH_DELETED,
|
GameLib.Event.MESH_DELETED,
|
||||||
this.meshDeleted
|
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) {
|
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) {
|
GameLib.System.Linking.prototype.meshInstanceCreated = function(data) {
|
||||||
|
|
||||||
this.resolveDependencies(data.mesh);
|
this.resolveDependencies(data.mesh);
|
||||||
|
@ -498,6 +526,37 @@ GameLib.System.Linking.prototype.materialInstanceCreated = function(data) {
|
||||||
this.resolveDependencies(data.material);
|
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
|
* Defines what should happen when a parent scene changes
|
||||||
* @param data
|
* @param data
|
||||||
|
@ -640,5 +699,7 @@ GameLib.System.Linking.prototype.stop = function() {
|
||||||
this.textureInstanceCreatedSubscription.remove();
|
this.textureInstanceCreatedSubscription.remove();
|
||||||
this.materialInstanceCreatedSubscription.remove();
|
this.materialInstanceCreatedSubscription.remove();
|
||||||
this.meshDeletedSubscription.remove();
|
this.meshDeletedSubscription.remove();
|
||||||
|
this.imageChangedSubscription.remove();
|
||||||
|
this.materialTypeChangedSubscription.remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -536,13 +536,12 @@ GameLib.System.Storage.prototype.imageUploadComplete = function(data) {
|
||||||
image = GameLib.D3.Image.FromObject(this.graphics, imageData);
|
image = GameLib.D3.Image.FromObject(this.graphics, imageData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Finally, load the image
|
|
||||||
*/
|
|
||||||
GameLib.Event.Emit(
|
GameLib.Event.Emit(
|
||||||
GameLib.Event.LOAD_IMAGE,
|
GameLib.Event.LOAD_IMAGE,
|
||||||
{
|
{
|
||||||
image : image
|
image : image,
|
||||||
|
createTexture : true
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -719,7 +718,7 @@ GameLib.System.Storage.prototype.loadImage = function(data) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (onLoaded) {
|
if (onLoaded) {
|
||||||
onLoaded(image);
|
onLoaded(image, data.createTexture);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue