Refactor material conversion.
This commit is contained in:
parent
7420e4dfeb
commit
077d46d112
@ -97,50 +97,31 @@ export class ThreeNodeTree
|
||||
}
|
||||
}
|
||||
|
||||
export function ConvertModelToThreeObject (model, params, output, callbacks)
|
||||
export class ThreeMaterialHandler
|
||||
{
|
||||
function CreateThreeMaterial (stateHandler, model, materialIndex, shadingType, params, output)
|
||||
constructor (model, stateHandler, conversionParams, conversionOutput)
|
||||
{
|
||||
function SetTextureParameters (texture, threeTexture)
|
||||
{
|
||||
threeTexture.wrapS = THREE.RepeatWrapping;
|
||||
threeTexture.wrapT = THREE.RepeatWrapping;
|
||||
threeTexture.rotation = texture.rotation;
|
||||
threeTexture.offset.x = texture.offset.x;
|
||||
threeTexture.offset.y = texture.offset.y;
|
||||
threeTexture.repeat.x = texture.scale.x;
|
||||
threeTexture.repeat.y = texture.scale.y;
|
||||
this.model = model;
|
||||
this.stateHandler = stateHandler;
|
||||
this.conversionParams = conversionParams;
|
||||
this.conversionOutput = conversionOutput;
|
||||
|
||||
this.shadingType = GetShadingType (model);
|
||||
this.modelToThreeMaterial = new Map ();
|
||||
}
|
||||
|
||||
function LoadTexture (stateHandler, threeMaterial, texture, output, onTextureLoaded)
|
||||
GetThreeMaterial (modelMaterialIndex)
|
||||
{
|
||||
if (texture === null || !texture.IsValid ()) {
|
||||
return;
|
||||
if (!this.modelToThreeMaterial.has (modelMaterialIndex)) {
|
||||
let threeMaterial = this.CreateThreeMaterial (modelMaterialIndex);
|
||||
this.modelToThreeMaterial.set (modelMaterialIndex, threeMaterial);
|
||||
}
|
||||
let loader = new THREE.TextureLoader ();
|
||||
stateHandler.OnTextureNeeded ();
|
||||
let textureObjectUrl = null;
|
||||
if (texture.mimeType !== null) {
|
||||
textureObjectUrl = CreateObjectUrlWithMimeType (texture.buffer, texture.mimeType);
|
||||
} else {
|
||||
textureObjectUrl = CreateObjectUrl (texture.buffer);
|
||||
}
|
||||
output.objectUrls.push (textureObjectUrl);
|
||||
loader.load (textureObjectUrl,
|
||||
(threeTexture) => {
|
||||
SetTextureParameters (texture, threeTexture);
|
||||
threeMaterial.needsUpdate = true;
|
||||
onTextureLoaded (threeTexture);
|
||||
stateHandler.OnTextureLoaded ();
|
||||
},
|
||||
null,
|
||||
(err) => {
|
||||
stateHandler.OnTextureLoaded ();
|
||||
}
|
||||
);
|
||||
return this.modelToThreeMaterial.get (modelMaterialIndex);
|
||||
}
|
||||
|
||||
let material = model.GetMaterial (materialIndex);
|
||||
CreateThreeMaterial (materialIndex)
|
||||
{
|
||||
let material = this.model.GetMaterial (materialIndex);
|
||||
let baseColor = ConvertColorToThreeColor (material.color);
|
||||
if (material.vertexColors) {
|
||||
baseColor.setRGB (1.0, 1.0, 1.0);
|
||||
@ -155,12 +136,12 @@ export function ConvertModelToThreeObject (model, params, output, callbacks)
|
||||
side : THREE.DoubleSide
|
||||
};
|
||||
|
||||
if (params.forceMediumpForMaterials) {
|
||||
if (this.conversionParams.forceMediumpForMaterials) {
|
||||
materialParams.precision = 'mediump';
|
||||
}
|
||||
|
||||
let threeMaterial = null;
|
||||
if (shadingType === ShadingType.Phong) {
|
||||
if (this.shadingType === ShadingType.Phong) {
|
||||
threeMaterial = new THREE.MeshPhongMaterial (materialParams);
|
||||
if (material.type === MaterialType.Phong) {
|
||||
let specularColor = ConvertColorToThreeColor (material.specular);
|
||||
@ -169,16 +150,16 @@ export function ConvertModelToThreeObject (model, params, output, callbacks)
|
||||
}
|
||||
threeMaterial.specular = specularColor;
|
||||
threeMaterial.shininess = material.shininess * 100.0;
|
||||
LoadTexture (stateHandler, threeMaterial, material.specularMap, output, (threeTexture) => {
|
||||
this.LoadTexture (threeMaterial, material.specularMap, (threeTexture) => {
|
||||
threeMaterial.specularMap = threeTexture;
|
||||
});
|
||||
}
|
||||
} else if (shadingType === ShadingType.Physical) {
|
||||
} else if (this.shadingType === ShadingType.Physical) {
|
||||
threeMaterial = new THREE.MeshStandardMaterial (materialParams);
|
||||
if (material.type === MaterialType.Physical) {
|
||||
threeMaterial.metalness = material.metalness;
|
||||
threeMaterial.roughness = material.roughness;
|
||||
LoadTexture (stateHandler, threeMaterial, material.metalnessMap, output, (threeTexture) => {
|
||||
this.LoadTexture (threeMaterial, material.metalnessMap, (threeTexture) => {
|
||||
threeMaterial.metalness = 1.0;
|
||||
threeMaterial.roughness = 1.0;
|
||||
threeMaterial.metalnessMap = threeTexture;
|
||||
@ -190,30 +171,72 @@ export function ConvertModelToThreeObject (model, params, output, callbacks)
|
||||
let emissiveColor = ConvertColorToThreeColor (material.emissive);
|
||||
threeMaterial.emissive = emissiveColor;
|
||||
|
||||
LoadTexture (stateHandler, threeMaterial, material.diffuseMap, output, (threeTexture) => {
|
||||
this.LoadTexture (threeMaterial, material.diffuseMap, (threeTexture) => {
|
||||
if (!material.multiplyDiffuseMap) {
|
||||
threeMaterial.color.setRGB (1.0, 1.0, 1.0);
|
||||
}
|
||||
threeMaterial.map = threeTexture;
|
||||
});
|
||||
LoadTexture (stateHandler, threeMaterial, material.bumpMap, output, (threeTexture) => {
|
||||
this.LoadTexture (threeMaterial, material.bumpMap, (threeTexture) => {
|
||||
threeMaterial.bumpMap = threeTexture;
|
||||
});
|
||||
LoadTexture (stateHandler, threeMaterial, material.normalMap, output, (threeTexture) => {
|
||||
this.LoadTexture (threeMaterial, material.normalMap, (threeTexture) => {
|
||||
threeMaterial.normalMap = threeTexture;
|
||||
});
|
||||
LoadTexture (stateHandler, threeMaterial, material.emissiveMap, output, (threeTexture) => {
|
||||
this.LoadTexture (threeMaterial, material.emissiveMap, (threeTexture) => {
|
||||
threeMaterial.emissiveMap = threeTexture;
|
||||
});
|
||||
|
||||
if (material.isDefault) {
|
||||
output.defaultMaterial = threeMaterial;
|
||||
this.conversionOutput.defaultMaterial = threeMaterial;
|
||||
}
|
||||
|
||||
return threeMaterial;
|
||||
}
|
||||
|
||||
function CreateThreeTriangleMesh (meshInstance, modelThreeMaterials)
|
||||
LoadTexture (threeMaterial, texture, onTextureLoaded)
|
||||
{
|
||||
function SetTextureParameters (texture, threeTexture)
|
||||
{
|
||||
threeTexture.wrapS = THREE.RepeatWrapping;
|
||||
threeTexture.wrapT = THREE.RepeatWrapping;
|
||||
threeTexture.rotation = texture.rotation;
|
||||
threeTexture.offset.x = texture.offset.x;
|
||||
threeTexture.offset.y = texture.offset.y;
|
||||
threeTexture.repeat.x = texture.scale.x;
|
||||
threeTexture.repeat.y = texture.scale.y;
|
||||
}
|
||||
|
||||
if (texture === null || !texture.IsValid ()) {
|
||||
return;
|
||||
}
|
||||
let loader = new THREE.TextureLoader ();
|
||||
this.stateHandler.OnTextureNeeded ();
|
||||
let textureObjectUrl = null;
|
||||
if (texture.mimeType !== null) {
|
||||
textureObjectUrl = CreateObjectUrlWithMimeType (texture.buffer, texture.mimeType);
|
||||
} else {
|
||||
textureObjectUrl = CreateObjectUrl (texture.buffer);
|
||||
}
|
||||
this.conversionOutput.objectUrls.push (textureObjectUrl);
|
||||
loader.load (textureObjectUrl,
|
||||
(threeTexture) => {
|
||||
SetTextureParameters (texture, threeTexture);
|
||||
threeMaterial.needsUpdate = true;
|
||||
onTextureLoaded (threeTexture);
|
||||
this.stateHandler.OnTextureLoaded ();
|
||||
},
|
||||
null,
|
||||
(err) => {
|
||||
this.stateHandler.OnTextureLoaded ();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function ConvertModelToThreeObject (model, conversionParams, conversionOutput, callbacks)
|
||||
{
|
||||
function CreateThreeTriangleMesh (meshInstance, materialHandler)
|
||||
{
|
||||
let mesh = meshInstance.mesh;
|
||||
let triangleCount = mesh.TriangleCount ();
|
||||
@ -249,7 +272,8 @@ export function ConvertModelToThreeObject (model, params, output, callbacks)
|
||||
|
||||
let meshHasVertexColors = (mesh.VertexColorCount () > 0);
|
||||
let meshHasUVs = (mesh.TextureUVCount () > 0);
|
||||
for (let triangleIndex of triangleIndices) {
|
||||
for (let i = 0; i < triangleIndices.length; i++) {
|
||||
let triangleIndex = triangleIndices[i];
|
||||
let triangle = mesh.GetTriangle (triangleIndex);
|
||||
|
||||
let v0 = mesh.GetVertex (triangle.v0);
|
||||
@ -290,8 +314,9 @@ export function ConvertModelToThreeObject (model, params, output, callbacks)
|
||||
|
||||
let modelMaterialIndex = triangle.mat;
|
||||
if (!modelToThreeMaterials.has (modelMaterialIndex)) {
|
||||
let threeMaterial = materialHandler.GetThreeMaterial (modelMaterialIndex);
|
||||
modelToThreeMaterials.set (modelMaterialIndex, meshThreeMaterials.length);
|
||||
meshThreeMaterials.push (modelThreeMaterials[modelMaterialIndex]);
|
||||
meshThreeMaterials.push (threeMaterial);
|
||||
meshOriginalMaterials.push (modelMaterialIndex);
|
||||
if (i > 0) {
|
||||
groups[groups.length - 1].end = i - 1;
|
||||
@ -372,113 +397,6 @@ export function ConvertModelToThreeObject (model, params, output, callbacks)
|
||||
threeMaterials : null
|
||||
};
|
||||
return threeLine;
|
||||
// let triangleIndices = [];
|
||||
// for (let i = 0; i < triangleCount; i++) {
|
||||
// triangleIndices.push (i);
|
||||
// }
|
||||
// triangleIndices.sort ((a, b) => {
|
||||
// let aTriangle = mesh.GetTriangle (a);
|
||||
// let bTriangle = mesh.GetTriangle (b);
|
||||
// return aTriangle.mat - bTriangle.mat;
|
||||
// });
|
||||
|
||||
// let threeGeometry = new THREE.BufferGeometry ();
|
||||
// let meshThreeMaterials = [];
|
||||
// let meshOriginalMaterials = [];
|
||||
// let modelToThreeMaterials = new Map ();
|
||||
|
||||
// let vertices = [];
|
||||
// let vertexColors = [];
|
||||
// let normals = [];
|
||||
// let uvs = [];
|
||||
|
||||
// let groups = [];
|
||||
// groups.push ({
|
||||
// start : 0,
|
||||
// end : -1
|
||||
// });
|
||||
|
||||
// let meshHasVertexColors = (mesh.VertexColorCount () > 0);
|
||||
// let meshHasUVs = (mesh.TextureUVCount () > 0);
|
||||
// for (let i = 0; i < triangleIndices.length; i++) {
|
||||
// let triangleIndex = triangleIndices[i];
|
||||
// let triangle = mesh.GetTriangle (triangleIndex);
|
||||
|
||||
// let v0 = mesh.GetVertex (triangle.v0);
|
||||
// let v1 = mesh.GetVertex (triangle.v1);
|
||||
// let v2 = mesh.GetVertex (triangle.v2);
|
||||
// vertices.push (v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, v2.x, v2.y, v2.z);
|
||||
|
||||
// if (triangle.HasVertexColors ()) {
|
||||
// let vc0 = ConvertColorToThreeColor (mesh.GetVertexColor (triangle.c0));
|
||||
// let vc1 = ConvertColorToThreeColor (mesh.GetVertexColor (triangle.c1));
|
||||
// let vc2 = ConvertColorToThreeColor (mesh.GetVertexColor (triangle.c2));
|
||||
// vertexColors.push (
|
||||
// vc0.r, vc0.g, vc0.b,
|
||||
// vc1.r, vc1.g, vc1.b,
|
||||
// vc2.r, vc2.g, vc2.b
|
||||
// );
|
||||
// } else if (meshHasVertexColors) {
|
||||
// vertexColors.push (
|
||||
// 0.0, 0.0, 0.0,
|
||||
// 0.0, 0.0, 0.0,
|
||||
// 0.0, 0.0, 0.0
|
||||
// );
|
||||
// }
|
||||
|
||||
// let n0 = mesh.GetNormal (triangle.n0);
|
||||
// let n1 = mesh.GetNormal (triangle.n1);
|
||||
// let n2 = mesh.GetNormal (triangle.n2);
|
||||
// normals.push (n0.x, n0.y, n0.z, n1.x, n1.y, n1.z, n2.x, n2.y, n2.z);
|
||||
|
||||
// if (triangle.HasTextureUVs ()) {
|
||||
// let u0 = mesh.GetTextureUV (triangle.u0);
|
||||
// let u1 = mesh.GetTextureUV (triangle.u1);
|
||||
// let u2 = mesh.GetTextureUV (triangle.u2);
|
||||
// uvs.push (u0.x, u0.y, u1.x, u1.y, u2.x, u2.y);
|
||||
// } else if (meshHasUVs) {
|
||||
// uvs.push (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
// }
|
||||
|
||||
// let modelMaterialIndex = triangle.mat;
|
||||
// if (!modelToThreeMaterials.has (modelMaterialIndex)) {
|
||||
// modelToThreeMaterials.set (modelMaterialIndex, meshThreeMaterials.length);
|
||||
// meshThreeMaterials.push (modelThreeMaterials[modelMaterialIndex]);
|
||||
// meshOriginalMaterials.push (modelMaterialIndex);
|
||||
// if (i > 0) {
|
||||
// groups[groups.length - 1].end = i - 1;
|
||||
// groups.push ({
|
||||
// start : groups[groups.length - 1].end + 1,
|
||||
// end : -1
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// groups[groups.length - 1].end = triangleCount - 1;
|
||||
|
||||
// threeGeometry.setAttribute ('position', new THREE.Float32BufferAttribute (vertices, 3));
|
||||
// if (vertexColors.length !== 0) {
|
||||
// threeGeometry.setAttribute ('color', new THREE.Float32BufferAttribute (vertexColors, 3));
|
||||
// }
|
||||
// threeGeometry.setAttribute ('normal', new THREE.Float32BufferAttribute (normals, 3));
|
||||
// if (uvs.length !== 0) {
|
||||
// threeGeometry.setAttribute ('uv', new THREE.Float32BufferAttribute (uvs, 2));
|
||||
// }
|
||||
// for (let i = 0; i < groups.length; i++) {
|
||||
// let group = groups[i];
|
||||
// threeGeometry.addGroup (group.start * 3, (group.end - group.start + 1) * 3, i);
|
||||
// }
|
||||
|
||||
// let threeMesh = new THREE.Mesh (threeGeometry, meshThreeMaterials);
|
||||
// threeMesh.name = mesh.GetName ();
|
||||
// threeMesh.userData = {
|
||||
// originalMeshInstance : meshInstance,
|
||||
// originalMaterials : meshOriginalMaterials,
|
||||
// threeMaterials : null
|
||||
// };
|
||||
|
||||
// return threeMesh;
|
||||
}
|
||||
|
||||
function ConvertMesh (threeObject, meshInstance, modelThreeMaterials)
|
||||
@ -498,7 +416,7 @@ export function ConvertModelToThreeObject (model, params, output, callbacks)
|
||||
}
|
||||
}
|
||||
|
||||
function ConvertNodeHierarchy (threeRootNode, model, modelThreeMaterials, stateHandler)
|
||||
function ConvertNodeHierarchy (threeRootNode, model, materialHandler, stateHandler)
|
||||
{
|
||||
let nodeTree = new ThreeNodeTree (model, threeRootNode);
|
||||
let threeNodeItems = nodeTree.GetNodeItems ();
|
||||
@ -507,7 +425,7 @@ export function ConvertModelToThreeObject (model, params, output, callbacks)
|
||||
runTask : (firstMeshInstanceIndex, lastMeshInstanceIndex, onReady) => {
|
||||
for (let meshInstanceIndex = firstMeshInstanceIndex; meshInstanceIndex <= lastMeshInstanceIndex; meshInstanceIndex++) {
|
||||
let nodeItem = threeNodeItems[meshInstanceIndex];
|
||||
ConvertMesh (nodeItem.threeNode, nodeItem.meshInstance, modelThreeMaterials);
|
||||
ConvertMesh (nodeItem.threeNode, nodeItem.meshInstance, materialHandler);
|
||||
}
|
||||
onReady ();
|
||||
},
|
||||
@ -518,14 +436,7 @@ export function ConvertModelToThreeObject (model, params, output, callbacks)
|
||||
}
|
||||
|
||||
let stateHandler = new ThreeConversionStateHandler (callbacks);
|
||||
let shadingType = GetShadingType (model);
|
||||
|
||||
let modelThreeMaterials = [];
|
||||
for (let materialIndex = 0; materialIndex < model.MaterialCount (); materialIndex++) {
|
||||
let threeMaterial = CreateThreeMaterial (stateHandler, model, materialIndex, shadingType, params, output);
|
||||
modelThreeMaterials.push (threeMaterial);
|
||||
}
|
||||
|
||||
let materialHandler = new ThreeMaterialHandler (model, stateHandler, conversionParams, conversionOutput);
|
||||
let threeObject = new THREE.Object3D ();
|
||||
ConvertNodeHierarchy (threeObject, model, modelThreeMaterials, stateHandler);
|
||||
ConvertNodeHierarchy (threeObject, model, materialHandler, stateHandler);
|
||||
}
|
||||
|
||||
@ -877,9 +877,14 @@ export class Website
|
||||
}
|
||||
} else {
|
||||
let userDataArr = GetMeshUserDataArray (viewer, meshInstanceId);
|
||||
let addedMaterialIndices = new Set ();
|
||||
for (let userData of userDataArr) {
|
||||
for (let materialIndex of userData.originalMaterials) {
|
||||
if (addedMaterialIndices.has (materialIndex)) {
|
||||
continue;
|
||||
}
|
||||
usedMaterials.push (GetMaterialReferenceInfo (model, materialIndex));
|
||||
addedMaterialIndices.add (materialIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user