Add material groups to lines.

This commit is contained in:
kovacsv 2023-10-23 09:36:58 +02:00
parent 97e7be4732
commit 0f3e42be4b

View File

@ -97,6 +97,12 @@ export class ThreeNodeTree
} }
} }
export const MaterialGeometryType =
{
Line : 1,
Face : 2
};
export class ThreeMaterialHandler export class ThreeMaterialHandler
{ {
constructor (model, stateHandler, conversionParams, conversionOutput) constructor (model, stateHandler, conversionParams, conversionOutput)
@ -107,19 +113,30 @@ export class ThreeMaterialHandler
this.conversionOutput = conversionOutput; this.conversionOutput = conversionOutput;
this.shadingType = GetShadingType (model); this.shadingType = GetShadingType (model);
this.modelToThreeLineMaterial = new Map ();
this.modelToThreeMaterial = new Map (); this.modelToThreeMaterial = new Map ();
} }
GetThreeMaterial (modelMaterialIndex) GetThreeMaterial (modelMaterialIndex, geometryType)
{ {
if (!this.modelToThreeMaterial.has (modelMaterialIndex)) { if (geometryType === MaterialGeometryType.Face) {
let threeMaterial = this.CreateThreeMaterial (modelMaterialIndex); if (!this.modelToThreeMaterial.has (modelMaterialIndex)) {
this.modelToThreeMaterial.set (modelMaterialIndex, threeMaterial); let threeMaterial = this.CreateThreeFaceMaterial (modelMaterialIndex);
this.modelToThreeMaterial.set (modelMaterialIndex, threeMaterial);
}
return this.modelToThreeMaterial.get (modelMaterialIndex);
} else if (geometryType === MaterialGeometryType.Line) {
if (!this.modelToThreeLineMaterial.has (modelMaterialIndex)) {
let threeMaterial = this.CreateThreeLineMaterial (modelMaterialIndex);
this.modelToThreeLineMaterial.set (modelMaterialIndex, threeMaterial);
}
return this.modelToThreeLineMaterial.get (modelMaterialIndex);
} else {
return null;
} }
return this.modelToThreeMaterial.get (modelMaterialIndex);
} }
CreateThreeMaterial (materialIndex) CreateThreeFaceMaterial (materialIndex)
{ {
let material = this.model.GetMaterial (materialIndex); let material = this.model.GetMaterial (materialIndex);
let baseColor = ConvertColorToThreeColor (material.color); let baseColor = ConvertColorToThreeColor (material.color);
@ -150,7 +167,7 @@ export class ThreeMaterialHandler
} }
threeMaterial.specular = specularColor; threeMaterial.specular = specularColor;
threeMaterial.shininess = material.shininess * 100.0; threeMaterial.shininess = material.shininess * 100.0;
this.LoadTexture (threeMaterial, material.specularMap, (threeTexture) => { this.LoadFaceTexture (threeMaterial, material.specularMap, (threeTexture) => {
threeMaterial.specularMap = threeTexture; threeMaterial.specularMap = threeTexture;
}); });
} }
@ -159,7 +176,7 @@ export class ThreeMaterialHandler
if (material.type === MaterialType.Physical) { if (material.type === MaterialType.Physical) {
threeMaterial.metalness = material.metalness; threeMaterial.metalness = material.metalness;
threeMaterial.roughness = material.roughness; threeMaterial.roughness = material.roughness;
this.LoadTexture (threeMaterial, material.metalnessMap, (threeTexture) => { this.LoadFaceTexture (threeMaterial, material.metalnessMap, (threeTexture) => {
threeMaterial.metalness = 1.0; threeMaterial.metalness = 1.0;
threeMaterial.roughness = 1.0; threeMaterial.roughness = 1.0;
threeMaterial.metalnessMap = threeTexture; threeMaterial.metalnessMap = threeTexture;
@ -171,19 +188,19 @@ export class ThreeMaterialHandler
let emissiveColor = ConvertColorToThreeColor (material.emissive); let emissiveColor = ConvertColorToThreeColor (material.emissive);
threeMaterial.emissive = emissiveColor; threeMaterial.emissive = emissiveColor;
this.LoadTexture (threeMaterial, material.diffuseMap, (threeTexture) => { this.LoadFaceTexture (threeMaterial, material.diffuseMap, (threeTexture) => {
if (!material.multiplyDiffuseMap) { if (!material.multiplyDiffuseMap) {
threeMaterial.color.setRGB (1.0, 1.0, 1.0); threeMaterial.color.setRGB (1.0, 1.0, 1.0);
} }
threeMaterial.map = threeTexture; threeMaterial.map = threeTexture;
}); });
this.LoadTexture (threeMaterial, material.bumpMap, (threeTexture) => { this.LoadFaceTexture (threeMaterial, material.bumpMap, (threeTexture) => {
threeMaterial.bumpMap = threeTexture; threeMaterial.bumpMap = threeTexture;
}); });
this.LoadTexture (threeMaterial, material.normalMap, (threeTexture) => { this.LoadFaceTexture (threeMaterial, material.normalMap, (threeTexture) => {
threeMaterial.normalMap = threeTexture; threeMaterial.normalMap = threeTexture;
}); });
this.LoadTexture (threeMaterial, material.emissiveMap, (threeTexture) => { this.LoadFaceTexture (threeMaterial, material.emissiveMap, (threeTexture) => {
threeMaterial.emissiveMap = threeTexture; threeMaterial.emissiveMap = threeTexture;
}); });
@ -194,7 +211,28 @@ export class ThreeMaterialHandler
return threeMaterial; return threeMaterial;
} }
LoadTexture (threeMaterial, texture, onTextureLoaded) CreateThreeLineMaterial (materialIndex)
{
let material = this.model.GetMaterial (materialIndex);
let baseColor = ConvertColorToThreeColor (material.color);
let materialParams = {
color : baseColor,
opacity : material.opacity
};
if (this.conversionParams.forceMediumpForMaterials) {
materialParams.precision = 'mediump';
}
let threeMaterial = new THREE.LineBasicMaterial (materialParams);
if (material.isDefault) {
this.conversionOutput.defaultMaterial = threeMaterial;
}
return threeMaterial;
}
LoadFaceTexture (threeMaterial, texture, onTextureLoaded)
{ {
function SetTextureParameters (texture, threeTexture) function SetTextureParameters (texture, threeTexture)
{ {
@ -236,11 +274,19 @@ export class ThreeMaterialHandler
export class ThreeMeshMaterialHandler export class ThreeMeshMaterialHandler
{ {
constructor (threeGeometry, materialHandler) constructor (threeGeometry, geometryType, materialHandler)
{ {
this.threeGeometry = threeGeometry; this.threeGeometry = threeGeometry;
this.geometryType = geometryType;
this.materialHandler = materialHandler; this.materialHandler = materialHandler;
this.itemVertexCount = null;
if (geometryType === MaterialGeometryType.Face) {
this.itemVertexCount = 3;
} else if (geometryType === MaterialGeometryType.Line) {
this.itemVertexCount = 2;
}
this.meshThreeMaterials = []; this.meshThreeMaterials = [];
this.meshOriginalMaterials = []; this.meshOriginalMaterials = [];
@ -256,7 +302,7 @@ export class ThreeMeshMaterialHandler
} }
this.groupStart = itemIndex; this.groupStart = itemIndex;
let threeMaterial = this.materialHandler.GetThreeMaterial (materialIndex); let threeMaterial = this.materialHandler.GetThreeMaterial (materialIndex, this.geometryType);
this.meshThreeMaterials.push (threeMaterial); this.meshThreeMaterials.push (threeMaterial);
this.meshOriginalMaterials.push (materialIndex); this.meshOriginalMaterials.push (materialIndex);
@ -264,15 +310,15 @@ export class ThreeMeshMaterialHandler
} }
} }
Finalize (triangleCount) Finalize (itemCount)
{ {
this.AddGroup (this.groupStart, triangleCount - 1); this.AddGroup (this.groupStart, itemCount - 1);
} }
AddGroup (start, end) AddGroup (start, end)
{ {
let materialIndex = this.meshThreeMaterials.length - 1; let materialIndex = this.meshThreeMaterials.length - 1;
this.threeGeometry.addGroup (start * 3, (end - start + 1) * 3, materialIndex); this.threeGeometry.addGroup (start * this.itemVertexCount, (end - start + 1) * this.itemVertexCount, materialIndex);
} }
} }
@ -297,7 +343,7 @@ export function ConvertModelToThreeObject (model, conversionParams, conversionOu
}); });
let threeGeometry = new THREE.BufferGeometry (); let threeGeometry = new THREE.BufferGeometry ();
let meshMaterialHandler = new ThreeMeshMaterialHandler (threeGeometry, materialHandler); let meshMaterialHandler = new ThreeMeshMaterialHandler (threeGeometry, MaterialGeometryType.Face, materialHandler);
let vertices = []; let vertices = [];
let vertexColors = []; let vertexColors = [];
@ -306,8 +352,8 @@ export function ConvertModelToThreeObject (model, conversionParams, conversionOu
let meshHasVertexColors = (mesh.VertexColorCount () > 0); let meshHasVertexColors = (mesh.VertexColorCount () > 0);
let meshHasUVs = (mesh.TextureUVCount () > 0); let meshHasUVs = (mesh.TextureUVCount () > 0);
for (let i = 0; i < triangleIndices.length; i++) { let processedTriangleCount = 0;
let triangleIndex = triangleIndices[i]; for (let triangleIndex of triangleIndices) {
let triangle = mesh.GetTriangle (triangleIndex); let triangle = mesh.GetTriangle (triangleIndex);
let v0 = mesh.GetVertex (triangle.v0); let v0 = mesh.GetVertex (triangle.v0);
@ -346,9 +392,10 @@ export function ConvertModelToThreeObject (model, conversionParams, conversionOu
uvs.push (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); uvs.push (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
} }
meshMaterialHandler.ProcessItem (i, triangle.mat); meshMaterialHandler.ProcessItem (processedTriangleCount, triangle.mat);
processedTriangleCount += 1;
} }
meshMaterialHandler.Finalize (triangleCount); meshMaterialHandler.Finalize (processedTriangleCount);
threeGeometry.setAttribute ('position', new THREE.Float32BufferAttribute (vertices, 3)); threeGeometry.setAttribute ('position', new THREE.Float32BufferAttribute (vertices, 3));
if (vertexColors.length !== 0) { if (vertexColors.length !== 0) {
@ -388,28 +435,29 @@ export function ConvertModelToThreeObject (model, conversionParams, conversionOu
return aLine.mat - bLine.mat; return aLine.mat - bLine.mat;
}); });
let threeGeometry = new THREE.BufferGeometry ();
let meshMaterialHandler = new ThreeMeshMaterialHandler (threeGeometry, MaterialGeometryType.Line, materialHandler);
let vertices = []; let vertices = [];
for (let lineIndex of lineIndices) { let segmentCount = 0;
let line = mesh.GetLine (lineIndex); for (let i = 0; i < lineIndices.length; i++) {
for (let vertexIndex of line.GetVertices ()) { let line = mesh.GetLine (lineIndices[i]);
let lineVertices = line.GetVertices ();
for (let vertexIndex of lineVertices) {
let vertex = mesh.GetVertex (vertexIndex); let vertex = mesh.GetVertex (vertexIndex);
vertices.push (vertex.x, vertex.y, vertex.z); vertices.push (vertex.x, vertex.y, vertex.z);
} }
meshMaterialHandler.ProcessItem (segmentCount, line.mat);
segmentCount += lineVertices.length / 2;
} }
meshMaterialHandler.Finalize (segmentCount);
let threeGeometry = new THREE.BufferGeometry ();
threeGeometry.setAttribute ('position', new THREE.Float32BufferAttribute (vertices, 3)); threeGeometry.setAttribute ('position', new THREE.Float32BufferAttribute (vertices, 3));
const material = new THREE.LineBasicMaterial ({ let threeLine = new THREE.LineSegments (threeGeometry, meshMaterialHandler.meshThreeMaterials);
color: 0x0000ff
});
let lineOriginalMaterials = [material];
let threeLine = new THREE.LineSegments (threeGeometry, material);
threeLine.userData = { threeLine.userData = {
originalMeshInstance : meshInstance, originalMeshInstance : meshInstance,
originalMaterials : lineOriginalMaterials, originalMaterials : meshMaterialHandler.meshOriginalMaterials,
threeMaterials : null threeMaterials : null
}; };
return threeLine; return threeLine;