From dfa953d63caa92f47ac6f6bfd52ee4b952ddbb4a Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Fri, 28 Jun 2024 23:10:52 +0530 Subject: [PATCH] optimize materials --- src/DifBuilder.hx | 49 +++--- src/DtsObject.hx | 61 ++++--- src/InstanceManager.hx | 358 +++++++++++++++++++++++------------------ src/mesh/Polygon.hx | 350 +++++++++++++++++++--------------------- 4 files changed, 433 insertions(+), 385 deletions(-) diff --git a/src/DifBuilder.hx b/src/DifBuilder.hx index f5eaa727..a9b33ae2 100644 --- a/src/DifBuilder.hx +++ b/src/DifBuilder.hx @@ -1,5 +1,6 @@ package src; +import h3d.scene.MultiMaterial; import shaders.DefaultCubemapMaterial; import shaders.DefaultNormalMaterial; import shaders.DefaultMaterial; @@ -86,7 +87,7 @@ class TriangleEdge { class DifCache { var dif:Dif; var difTriangles:Map>; - var prims:Map; + var prim:Polygon; public function new() {} } @@ -894,7 +895,7 @@ class DifBuilder { cache = new DifCache(); cache.difTriangles = mats; cache.dif = dif; - cache.prims = []; + cache.prim = null; buildNewCache = true; difCache.set(cachePath, cache); } @@ -949,12 +950,16 @@ class DifBuilder { }); var time = Console.time(); + var prim:Polygon = null; + if (!buildNewCache && cache != null) { + prim = cache.prim; + } else { + prim = new Polygon(); + cache.prim = prim; + } + var materials = []; for (grp => tris in mats) { - var prim:Polygon = null; - - if (!buildNewCache && cache != null) { - prim = cache.prims.get(grp); - } else { + if (buildNewCache || cache == null) { var points = []; var normals = []; var uvs = []; @@ -990,15 +995,13 @@ class DifBuilder { n.push(new Point(-tri.n2.x, tri.n2.y, tri.n2.z)); n.push(new Point(-tri.n1.x, tri.n1.y, tri.n1.z)); } - prim = new Polygon(points); - prim.uvs = uvs; - prim.normals = normals; - prim.tangents = t; - prim.bitangents = b; - prim.texMatNormals = n; - if (buildNewCache) { - cache.prims.set(grp, prim); - } + prim.appendPoints(points); + prim.appendUVs(uvs); + prim.appendNormals(normals); + prim.appendTangents(t); + prim.appendBitangents(b); + prim.appendTexMatNormals(n); + prim.nextMaterial(); } var texture:Texture; @@ -1026,7 +1029,7 @@ class DifBuilder { thisprops.light = false; // We will calculate our own lighting material.props = thisprops; material.shadows = false; - material.receiveShadows = true; + material.receiveShadows = false; material.mainPass.setPassName("interior"); fwd(); }); @@ -1037,20 +1040,26 @@ class DifBuilder { texture.mipMap = Linear; material.texture = texture; material.shadows = false; - material.receiveShadows = true; + material.receiveShadows = false; } } else { Console.warn('Unable to load ${grp} texture for dif ${path}'); material = Material.create(); material.shadows = false; - material.receiveShadows = true; + material.receiveShadows = false; } // material.mainPass.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1)); if (Debug.wireFrame) material.mainPass.wireframe = true; - var mesh = new Mesh(prim, material, itr); + materials.push(material); } + + if (buildNewCache || cache == null) { + prim.endPrimitive(); + } + + var mesh = new MultiMaterial(prim, materials, itr); var interval = Console.time() - time; Console.log('Geometry build time ${interval}'); diff --git a/src/DtsObject.hx b/src/DtsObject.hx index 9fc0efb2..1ab87901 100644 --- a/src/DtsObject.hx +++ b/src/DtsObject.hx @@ -1,5 +1,6 @@ package src; +import h3d.scene.MultiMaterial; import h3d.col.Point; import collision.CollisionWorld; import shaders.EnvMap; @@ -223,33 +224,38 @@ class DtsObject extends GameObject { var vertexNormals = mesh.normals.map(v -> new Vector(-v.x, v.y, v.z)); var geometry = this.generateMaterialGeometry(mesh, vertices, vertexNormals); + var poly = new Polygon(); + var usedMats = []; for (k in 0...geometry.length) { if (geometry[k].vertices.length == 0) continue; - var poly = new Polygon(geometry[k].vertices); - poly.normals = geometry[k].normals; - poly.uvs = geometry[k].uvs; - poly.tangents = geometry[k].tangents; - poly.bitangents = geometry[k].bitangents; - poly.texMatNormals = geometry[k].texNormals; + usedMats.push(materials[k]); - var obj = new Mesh(poly, materials[k], this.graphNodes[i]); - meshToIndex.set(obj, dts.objects.indexOf(object)); + poly.appendPoints(geometry[k].vertices); + poly.appendUVs(geometry[k].uvs); + poly.appendNormals(geometry[k].normals); + poly.appendTangents(geometry[k].tangents); + poly.appendBitangents(geometry[k].bitangents); + poly.appendTexMatNormals(geometry[k].texNormals); + poly.nextMaterial(); } + poly.endPrimitive(); + var obj = new MultiMaterial(poly, usedMats, this.graphNodes[i]); + meshToIndex.set(obj, dts.objects.indexOf(object)); + + poly.endPrimitive(); } else { - var usedMats = []; + // var usedMats = []; - for (prim in mesh.primitives) { - if (!usedMats.contains(prim.matIndex)) { - usedMats.push(prim.matIndex); - } - } + // for (prim in mesh.primitives) { + // if (!usedMats.contains(prim.matIndex)) { + // usedMats.push(prim.matIndex); + // } + // } - for (k in usedMats) { - var obj = new Object(this.graphNodes[i]); - meshToIndex.set(obj, dts.objects.indexOf(object)); - } + var obj = new Object(this.graphNodes[i]); + meshToIndex.set(obj, dts.objects.indexOf(object)); } } @@ -1538,14 +1544,17 @@ class DtsObject extends GameObject { var node = this.meshes[idx]; if (node != null) { for (ch in node.getMeshes()) { - for (pass in ch.material.getPasses()) { - var alphashader = pass.getShader(AlphaMult); - if (alphashader != null) - alphashader.alpha = opacity * this.currentOpacity; - else { - alphashader = new AlphaMult(); - alphashader.alpha = opacity * this.currentOpacity; - pass.addShader(alphashader); + var multimat = cast(ch, MultiMaterial); + for (mat in multimat.materials) { + for (pass in ch.material.getPasses()) { + var alphashader = pass.getShader(AlphaMult); + if (alphashader != null) + alphashader.alpha = opacity * this.currentOpacity; + else { + alphashader = new AlphaMult(); + alphashader.alpha = opacity * this.currentOpacity; + pass.addShader(alphashader); + } } } } diff --git a/src/InstanceManager.hx b/src/InstanceManager.hx index 940d229c..66a92296 100644 --- a/src/InstanceManager.hx +++ b/src/InstanceManager.hx @@ -1,5 +1,7 @@ package src; +import h3d.mat.Material; +import h3d.scene.MultiMaterial; import shaders.EnvMap; import h3d.shader.CubeMap; import shaders.NormalMaterial; @@ -27,8 +29,8 @@ class MeshBatchInfo { var meshbatch:MeshBatch; var transparencymeshbatch:MeshBatch; var mesh:Mesh; - var dtsShader:DtsTexture; - var glowPassDtsShader:DtsTexture; + var dtsShaders:Array; + var glowPassDtsShaders:Array; var baseBounds:h3d.col.Bounds; public function new() {} @@ -156,38 +158,38 @@ class InstanceManager { if (minfo.meshbatch != null) { minfo.meshbatch.begin(opaqueinstances.length); for (instance in opaqueinstances) { // Draw the opaque shit first - var dtsShader = minfo.dtsShader; // minfo.meshbatch.material.mainPass.getShader(DtsTexture); + // minfo.meshbatch.material.mainPass.getShader(DtsTexture); var subOpacity = 1.0; - if (dtsShader != null) { - if (instance.gameObject.animateSubObjectOpacities) { - subOpacity = instance.gameObject.getSubObjectOpacity(instance.emptyObj); - if (subOpacity == 0) - continue; // Do not draw - // minfo.meshbatch.shadersChanged = true; - } + for (dtsShader in minfo.dtsShaders) { + if (dtsShader != null) { + if (instance.gameObject.animateSubObjectOpacities) { + subOpacity = instance.gameObject.getSubObjectOpacity(instance.emptyObj); + if (subOpacity == 0) + continue; // Do not draw + // minfo.meshbatch.shadersChanged = true; + } - dtsShader.currentOpacity = instance.gameObject.currentOpacity * subOpacity; + dtsShader.currentOpacity = instance.gameObject.currentOpacity * subOpacity; + } } var transform = instance.emptyObj.getAbsPos(); - minfo.meshbatch.material.mainPass.depthWrite = minfo.mesh.material.mainPass.depthWrite; - minfo.meshbatch.material.mainPass.depthTest = minfo.mesh.material.mainPass.depthTest; - // minfo.meshbatch.shadersChanged = true; - minfo.meshbatch.material.mainPass.setPassName(minfo.mesh.material.mainPass.name); - minfo.meshbatch.material.mainPass.enableLights = minfo.mesh.material.mainPass.enableLights; + // minfo.meshbatch.material.mainPass.depthWrite = minfo.mesh.material.mainPass.depthWrite; + // minfo.meshbatch.material.mainPass.depthTest = minfo.mesh.material.mainPass.depthTest; + // // minfo.meshbatch.shadersChanged = true; + // minfo.meshbatch.material.mainPass.setPassName(minfo.mesh.material.mainPass.name); + // minfo.meshbatch.material.mainPass.enableLights = minfo.mesh.material.mainPass.enableLights; minfo.meshbatch.worldPosition = transform; - minfo.meshbatch.material.mainPass.culling = minfo.mesh.material.mainPass.culling; + // minfo.meshbatch.material.mainPass.culling = minfo.mesh.material.mainPass.culling; - minfo.meshbatch.material.mainPass.blendSrc = minfo.mesh.material.mainPass.blendSrc; - minfo.meshbatch.material.mainPass.blendDst = minfo.mesh.material.mainPass.blendDst; - minfo.meshbatch.material.mainPass.blendOp = minfo.mesh.material.mainPass.blendOp; - minfo.meshbatch.material.mainPass.blendAlphaSrc = minfo.mesh.material.mainPass.blendAlphaSrc; - minfo.meshbatch.material.mainPass.blendAlphaDst = minfo.mesh.material.mainPass.blendAlphaDst; - minfo.meshbatch.material.mainPass.blendAlphaOp = minfo.mesh.material.mainPass.blendAlphaOp; + // minfo.meshbatch.material.mainPass.blendSrc = minfo.mesh.material.mainPass.blendSrc; + // minfo.meshbatch.material.mainPass.blendDst = minfo.mesh.material.mainPass.blendDst; + // minfo.meshbatch.material.mainPass.blendOp = minfo.mesh.material.mainPass.blendOp; + // minfo.meshbatch.material.mainPass.blendAlphaSrc = minfo.mesh.material.mainPass.blendAlphaSrc; + // minfo.meshbatch.material.mainPass.blendAlphaDst = minfo.mesh.material.mainPass.blendAlphaDst; + // minfo.meshbatch.material.mainPass.blendAlphaOp = minfo.mesh.material.mainPass.blendAlphaOp; // handle the glow pass too - var glowPass = minfo.meshbatch.material.getPass("glow"); - if (glowPass != null) { - dtsShader = minfo.glowPassDtsShader; + for (dtsShader in minfo.glowPassDtsShaders) { if (dtsShader != null) dtsShader.currentOpacity = instance.gameObject.currentOpacity * subOpacity; } @@ -198,15 +200,16 @@ class InstanceManager { if (minfo.transparencymeshbatch != null) { minfo.transparencymeshbatch.begin(transparentinstances.length); for (instance in transparentinstances) { // Non opaque shit - var dtsShader = minfo.dtsShader; - if (dtsShader != null) { - dtsShader.currentOpacity = instance.gameObject.currentOpacity; + for (dtsShader in minfo.dtsShaders) { + if (dtsShader != null) { + dtsShader.currentOpacity = instance.gameObject.currentOpacity; + } } - minfo.transparencymeshbatch.material.blendMode = Alpha; + // minfo.transparencymeshbatch.material.blendMode = Alpha; // minfo.transparencymeshbatch.material.color.a = instance.gameObject.currentOpacity; // minfo.transparencymeshbatch.material.mainPass.setPassName(minfo.mesh.material.mainPass.name); // minfo.transparencymeshbatch.shadersChanged = true; - minfo.transparencymeshbatch.material.mainPass.enableLights = minfo.mesh.material.mainPass.enableLights; + // minfo.transparencymeshbatch.material.mainPass.enableLights = minfo.mesh.material.mainPass.enableLights; // minfo.transparencymeshbatch.material.mainPass.depthWrite = false; // if (dtsShader != null) { // dtsShader.currentOpacity = instance.gameObject.currentOpacity; @@ -243,159 +246,196 @@ class InstanceManager { var objs = getAllChildren(object); var minfos = []; for (obj in objs) { - var isMesh = obj is Mesh; + var isMesh = obj is MultiMaterial; var minfo:MeshBatchInfo = new MeshBatchInfo(); minfo.instances = [new MeshInstance(obj, object)]; - minfo.meshbatch = isMesh ? new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material.clone(), scene) : null; + minfo.meshbatch = isMesh ? new MeshBatch(cast(cast(obj, MultiMaterial).primitive), null, scene) : null; minfo.mesh = isMesh ? cast obj : null; minfo.baseBounds = isMesh ? @:privateAccess cast(minfo.meshbatch.primitive, Instanced).baseBounds : null; + minfo.dtsShaders = []; + minfo.glowPassDtsShaders = []; if (isMesh) { - var mat = cast(obj, Mesh).material; - var minfoshaders = []; - for (shader in minfo.meshbatch.material.mainPass.getShaders()) { - minfoshaders.push(shader); - } - for (shader in minfoshaders) - minfo.meshbatch.material.mainPass.removeShader(shader); - var addshaders = []; - for (shader in mat.mainPass.getShaders()) { - addshaders.push(shader); - } - for (shader in addshaders) - minfo.meshbatch.material.mainPass.addShader(shader); - var glowPass = mat.getPass("glow"); - if (glowPass != null) { - var gpass = glowPass.clone(); - gpass.enableLights = false; - gpass.depthTest = glowPass.depthTest; - gpass.blendSrc = glowPass.blendSrc; - gpass.blendDst = glowPass.blendDst; - gpass.blendOp = glowPass.blendOp; - gpass.blendAlphaSrc = glowPass.blendAlphaSrc; - gpass.blendAlphaDst = glowPass.blendAlphaDst; - gpass.blendAlphaOp = glowPass.blendAlphaOp; - if (glowPass.culling == None) { - gpass.culling = glowPass.culling; - } - - minfoshaders = []; - - for (shader in gpass.getShaders()) { + minfo.transparencymeshbatch = new MeshBatch(cast(cast(obj, MultiMaterial).primitive), null, scene); + minfo.transparencymeshbatch.materials = []; + minfo.meshbatch.materials = []; + for (mat in cast(obj, MultiMaterial).materials) { + var matclone:Material = cast mat.clone(); + var minfoshaders = []; + for (shader in matclone.mainPass.getShaders()) { minfoshaders.push(shader); } for (shader in minfoshaders) - gpass.removeShader(shader); + matclone.mainPass.removeShader(shader); var addshaders = []; - for (shader in glowPass.getShaders()) { + for (shader in mat.mainPass.getShaders()) { addshaders.push(shader); } for (shader in addshaders) - gpass.addShader(shader); + matclone.mainPass.addShader(shader); + var glowPass = mat.getPass("glow"); + if (glowPass != null) { + var gpass = glowPass.clone(); + gpass.enableLights = false; + gpass.depthTest = glowPass.depthTest; + gpass.blendSrc = glowPass.blendSrc; + gpass.blendDst = glowPass.blendDst; + gpass.blendOp = glowPass.blendOp; + gpass.blendAlphaSrc = glowPass.blendAlphaSrc; + gpass.blendAlphaDst = glowPass.blendAlphaDst; + gpass.blendAlphaOp = glowPass.blendAlphaOp; + if (glowPass.culling == None) { + gpass.culling = glowPass.culling; + } - minfo.glowPassDtsShader = gpass.getShader(DtsTexture); + minfoshaders = []; - minfo.meshbatch.material.addPass(gpass); - } - var refractPass = mat.getPass("refract"); - if (refractPass != null) { - var gpass = refractPass.clone(); - gpass.enableLights = false; - gpass.depthTest = refractPass.depthTest; - gpass.blendSrc = refractPass.blendSrc; - gpass.blendDst = refractPass.blendDst; - gpass.blendOp = refractPass.blendOp; - gpass.blendAlphaSrc = refractPass.blendAlphaSrc; - gpass.blendAlphaDst = refractPass.blendAlphaDst; - gpass.blendAlphaOp = refractPass.blendAlphaOp; - if (refractPass.culling == None) { - gpass.culling = refractPass.culling; + for (shader in gpass.getShaders()) { + minfoshaders.push(shader); + } + for (shader in minfoshaders) + gpass.removeShader(shader); + var addshaders = []; + for (shader in glowPass.getShaders()) { + addshaders.push(shader); + } + for (shader in addshaders) + gpass.addShader(shader); + minfo.glowPassDtsShaders.push(gpass.getShader(DtsTexture)); + + matclone.addPass(gpass); + } else { + minfo.glowPassDtsShaders.push(null); + } + var refractPass = mat.getPass("refract"); + if (refractPass != null) { + var gpass = refractPass.clone(); + gpass.enableLights = false; + gpass.depthTest = refractPass.depthTest; + gpass.blendSrc = refractPass.blendSrc; + gpass.blendDst = refractPass.blendDst; + gpass.blendOp = refractPass.blendOp; + gpass.blendAlphaSrc = refractPass.blendAlphaSrc; + gpass.blendAlphaDst = refractPass.blendAlphaDst; + gpass.blendAlphaOp = refractPass.blendAlphaOp; + if (refractPass.culling == None) { + gpass.culling = refractPass.culling; + } + + minfoshaders = []; + + for (shader in gpass.getShaders()) { + minfoshaders.push(shader); + } + for (shader in minfoshaders) + gpass.removeShader(shader); + var addshaders = []; + for (shader in refractPass.getShaders()) { + addshaders.push(shader); + } + for (shader in addshaders) + gpass.addShader(shader); + + matclone.addPass(gpass); + } + var zPass = mat.getPass("zPass"); + if (zPass != null) { + var gpass = zPass.clone(); + gpass.enableLights = false; + gpass.depthTest = zPass.depthTest; + gpass.blendSrc = zPass.blendSrc; + gpass.blendDst = zPass.blendDst; + gpass.blendOp = zPass.blendOp; + gpass.blendAlphaSrc = zPass.blendAlphaSrc; + gpass.blendAlphaDst = zPass.blendAlphaDst; + gpass.blendAlphaOp = zPass.blendAlphaOp; + gpass.colorMask = zPass.colorMask; + minfoshaders = []; + + for (shader in gpass.getShaders()) { + minfoshaders.push(shader); + } + for (shader in minfoshaders) + gpass.removeShader(shader); + var addshaders = []; + for (shader in zPass.getShaders()) { + addshaders.push(shader); + } + for (shader in addshaders) + gpass.addShader(shader); + + matclone.addPass(gpass); } - minfoshaders = []; + matclone.mainPass.depthWrite = mat.mainPass.depthWrite; + matclone.mainPass.depthTest = mat.mainPass.depthTest; + // minfo.meshbatch.shadersChanged = true; + matclone.mainPass.setPassName(mat.mainPass.name); + matclone.mainPass.enableLights = mat.mainPass.enableLights; + matclone.mainPass.culling = mat.mainPass.culling; - for (shader in gpass.getShaders()) { + matclone.mainPass.blendSrc = mat.mainPass.blendSrc; + matclone.mainPass.blendDst = mat.mainPass.blendDst; + matclone.mainPass.blendOp = mat.mainPass.blendOp; + matclone.mainPass.blendAlphaSrc = mat.mainPass.blendAlphaSrc; + matclone.mainPass.blendAlphaDst = mat.mainPass.blendAlphaDst; + matclone.mainPass.blendAlphaOp = mat.mainPass.blendAlphaOp; + + minfo.dtsShaders.push(matclone.mainPass.getShader(DtsTexture)); + + for (p in matclone.getPasses()) + @:privateAccess p.batchMode = true; + minfo.meshbatch.materials.push(matclone); + // var dtsshader = mat.mainPass.getShader(DtsTexture); + // if (dtsshader != null) { + // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); + // minfo.meshbatch.material.mainPass.addShader(dtsshader); + // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; + // minfo.meshbatch.material.mainPass.depthWrite = mat.mainPass.depthWrite; + // } + // var phongshader = mat.mainPass.getShader(PhongMaterial); + // if (phongshader != null) { + // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); + // minfo.meshbatch.material.mainPass.addShader(phongshader); + // // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; + // } + // var noiseshder = mat.mainPass.getShader(NoiseTileMaterial); + // if (noiseshder != null) { + // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); + // minfo.meshbatch.material.mainPass.addShader(noiseshder); + // // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; + // } + // var nmapshdr = mat.mainPass.getShader(NormalMaterial); + // if (nmapshdr != null) { + // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); + // minfo.meshbatch.material.mainPass.addShader(nmapshdr); + // // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; + // } + // var cubemapshdr = mat.mainPass.getShader(EnvMap); + // if (cubemapshdr != null) { + // minfo.meshbatch.material.mainPass.addShader(cubemapshdr); + // } + + var matclonetransp:Material = cast mat.clone(); + + minfoshaders = []; + for (shader in matclonetransp.mainPass.getShaders()) { minfoshaders.push(shader); } for (shader in minfoshaders) - gpass.removeShader(shader); - var addshaders = []; - for (shader in refractPass.getShaders()) { - addshaders.push(shader); + matclonetransp.mainPass.removeShader(shader); + matclonetransp.mainPass.removeShader(matclonetransp.textureShader); + for (shader in mat.mainPass.getShaders()) { + matclonetransp.mainPass.addShader(shader); } - for (shader in addshaders) - gpass.addShader(shader); - minfo.meshbatch.material.addPass(gpass); - } - var zPass = mat.getPass("zPass"); - if (zPass != null) { - var gpass = zPass.clone(); - gpass.enableLights = false; - gpass.depthTest = zPass.depthTest; - gpass.blendSrc = zPass.blendSrc; - gpass.blendDst = zPass.blendDst; - gpass.blendOp = zPass.blendOp; - gpass.blendAlphaSrc = zPass.blendAlphaSrc; - gpass.blendAlphaDst = zPass.blendAlphaDst; - gpass.blendAlphaOp = zPass.blendAlphaOp; - gpass.colorMask = zPass.colorMask; - minfoshaders = []; + for (p in matclonetransp.getPasses()) + @:privateAccess p.batchMode = true; - for (shader in gpass.getShaders()) { - minfoshaders.push(shader); - } - for (shader in minfoshaders) - gpass.removeShader(shader); - var addshaders = []; - for (shader in zPass.getShaders()) { - addshaders.push(shader); - } - for (shader in addshaders) - gpass.addShader(shader); + matclonetransp.blendMode = Alpha; + matclonetransp.mainPass.enableLights = mat.mainPass.enableLights; - minfo.meshbatch.material.addPass(gpass); - } - minfo.dtsShader = minfo.meshbatch.material.mainPass.getShader(DtsTexture); - // var dtsshader = mat.mainPass.getShader(DtsTexture); - // if (dtsshader != null) { - // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); - // minfo.meshbatch.material.mainPass.addShader(dtsshader); - // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; - // minfo.meshbatch.material.mainPass.depthWrite = mat.mainPass.depthWrite; - // } - // var phongshader = mat.mainPass.getShader(PhongMaterial); - // if (phongshader != null) { - // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); - // minfo.meshbatch.material.mainPass.addShader(phongshader); - // // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; - // } - // var noiseshder = mat.mainPass.getShader(NoiseTileMaterial); - // if (noiseshder != null) { - // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); - // minfo.meshbatch.material.mainPass.addShader(noiseshder); - // // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; - // } - // var nmapshdr = mat.mainPass.getShader(NormalMaterial); - // if (nmapshdr != null) { - // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); - // minfo.meshbatch.material.mainPass.addShader(nmapshdr); - // // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; - // } - // var cubemapshdr = mat.mainPass.getShader(EnvMap); - // if (cubemapshdr != null) { - // minfo.meshbatch.material.mainPass.addShader(cubemapshdr); - // } - minfo.transparencymeshbatch = new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material.clone(), scene); - minfoshaders = []; - for (shader in minfo.transparencymeshbatch.material.mainPass.getShaders()) { - minfoshaders.push(shader); - } - for (shader in minfoshaders) - minfo.transparencymeshbatch.material.mainPass.removeShader(shader); - minfo.transparencymeshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); - for (shader in mat.mainPass.getShaders()) { - minfo.transparencymeshbatch.material.mainPass.addShader(shader); + minfo.transparencymeshbatch.materials.push(matclonetransp); } // minfo.transparencymeshbatch.material.mainPass.culling = mat.mainPass.culling; diff --git a/src/mesh/Polygon.hx b/src/mesh/Polygon.hx index c6e3d507..5baebd1c 100644 --- a/src/mesh/Polygon.hx +++ b/src/mesh/Polygon.hx @@ -4,36 +4,103 @@ import h3d.prim.*; import h3d.col.Point; class Polygon extends MeshPrimitive { - public var points:Array; - public var normals:Array; - public var tangents:Array; - public var bitangents:Array; - public var texMatNormals:Array; - public var uvs:Array; - public var idx:hxd.IndexBuffer; + public var points:Array; + public var normals:Array; + public var tangents:Array; + public var bitangents:Array; + public var texMatNormals:Array; + public var uvs:Array; + public var indexStarts:Array; + public var indexCounts:Array; + + var currentMaterial:Int = 0; + var curTris = 0; var bounds:h3d.col.Bounds; - var scaled = 1.; - var translatedX = 0.; - var translatedY = 0.; - var translatedZ = 0.; - - public function new(points, ?idx) { - this.points = points; - this.idx = idx; + public function new() { + this.indexStarts = [0]; + this.indexCounts = []; + this.points = []; + this.uvs = []; + this.normals = []; + this.tangents = []; + this.bitangents = []; + this.texMatNormals = []; } override function getBounds() { if (bounds == null) { var b = new h3d.col.Bounds(); - for (p in points) - b.addPoint(p); + var i = 0; + while (i < points.length) { + b.addPoint(new h3d.col.Point(points[i], points[i + 1], points[i + 2])); + i += 3; + } bounds = b; } return bounds; } + public function appendPoints(pts:Array) { + for (p in pts) { + this.points.push(p.x); + this.points.push(p.y); + this.points.push(p.z); + } + curTris += Math.floor(pts.length / 3); + } + + public function appendNormals(pts:Array) { + for (p in pts) { + this.normals.push(p.x); + this.normals.push(p.y); + this.normals.push(p.z); + } + } + + public function appendTangents(pts:Array) { + for (p in pts) { + this.tangents.push(p.x); + this.tangents.push(p.y); + this.tangents.push(p.z); + } + } + + public function appendBitangents(pts:Array) { + for (p in pts) { + this.bitangents.push(p.x); + this.bitangents.push(p.y); + this.bitangents.push(p.z); + } + } + + public function appendTexMatNormals(pts:Array) { + for (p in pts) { + this.texMatNormals.push(p.x); + this.texMatNormals.push(p.y); + this.texMatNormals.push(p.z); + } + } + + public function appendUVs(uvs:Array) { + for (uv in uvs) { + this.uvs.push(uv.u); + this.uvs.push(uv.v); + } + } + + public function nextMaterial() { + indexStarts.push(Math.floor(this.points.length / 9)); + indexCounts.push(curTris); + curTris = 0; + } + + public function endPrimitive() { + indexCounts.push(curTris); + curTris = 0; + } + override function alloc(engine:h3d.Engine) { dispose(); @@ -67,140 +134,84 @@ class Polygon extends MeshPrimitive { } var buf = new hxd.FloatBuffer(); - for (k in 0...points.length) { - var p = points[k]; - buf.push(p.x); - buf.push(p.y); - buf.push(p.z); + for (k in 0...Std.int(points.length / 3)) { + buf.push(points[k * 3]); + buf.push(points[k * 3 + 1]); + buf.push(points[k * 3 + 2]); if (normals != null) { - var n = normals[k]; - buf.push(n.x); - buf.push(n.y); - buf.push(n.z); + buf.push(normals[k * 3]); + buf.push(normals[k * 3 + 1]); + buf.push(normals[k * 3 + 2]); } if (tangents != null) { - var t = tangents[k]; - buf.push(t.x); - buf.push(t.y); - buf.push(t.z); + buf.push(tangents[k * 3]); + buf.push(tangents[k * 3 + 1]); + buf.push(tangents[k * 3 + 2]); } if (bitangents != null) { - var t = bitangents[k]; - buf.push(t.x); - buf.push(t.y); - buf.push(t.z); + buf.push(bitangents[k * 3]); + buf.push(bitangents[k * 3 + 1]); + buf.push(bitangents[k * 3 + 2]); } if (texMatNormals != null) { - var t = texMatNormals[k]; - buf.push(t.x); - buf.push(t.y); - buf.push(t.z); + buf.push(texMatNormals[k * 3]); + buf.push(texMatNormals[k * 3 + 1]); + buf.push(texMatNormals[k * 3 + 2]); } if (uvs != null) { var t = uvs[k]; - buf.push(t.u); - buf.push(t.v); + buf.push(uvs[k * 2]); + buf.push(uvs[k * 2 + 1]); } } var flags:Array = []; - if (idx == null) - flags.push(Triangles); + flags.push(Triangles); if (normals == null || tangents != null) flags.push(RawFormat); buffer = h3d.Buffer.ofFloats(buf, size, flags); for (i in 0...names.length) addBuffer(names[i], buffer, positions[i]); - - if (idx != null) - indexes = h3d.Indexes.alloc(idx); - } - - public function unindex() { - if (idx != null && points.length != idx.length) { - var p = []; - var used = []; - for (i in 0...idx.length) - p.push(points[idx[i]].clone()); - if (normals != null) { - var n = []; - for (i in 0...idx.length) - n.push(normals[idx[i]].clone()); - normals = n; - } - if (tangents != null) { - var t = []; - for (i in 0...idx.length) - t.push(tangents[idx[i]].clone()); - tangents = t; - } - if (uvs != null) { - var t = []; - for (i in 0...idx.length) - t.push(uvs[idx[i]].clone()); - uvs = t; - } - points = p; - idx = null; - } - } - - public function translate(dx, dy, dz) { - translatedX += dx; - translatedY += dy; - translatedZ += dz; - for (p in points) { - p.x += dx; - p.y += dy; - p.z += dz; - } - } - - public function scale(s:Float) { - scaled *= s; - for (p in points) { - p.x *= s; - p.y *= s; - p.z *= s; - } } public function addNormals() { // make per-point normal normals = new Array(); for (i in 0...points.length) - normals[i] = new Point(); + normals[i] = 0; var pos = 0; for (i in 0...triCount()) { var i0, i1, i2; - if (idx == null) { - i0 = pos++; - i1 = pos++; - i2 = pos++; - } else { - i0 = idx[pos++]; - i1 = idx[pos++]; - i2 = idx[pos++]; - } - var p0 = points[i0]; - var p1 = points[i1]; - var p2 = points[i2]; + i0 = pos++; + i1 = pos++; + i2 = pos++; + var p0 = new h3d.Vector(points[3 * i0], points[3 * i0 + 1], points[3 * i0 + 2]); + var p1 = new h3d.Vector(points[3 * i1], points[3 * i1 + 1], points[3 * i1 + 2]); + var p2 = new h3d.Vector(points[3 * i2], points[3 * i2 + 1], points[3 * i2 + 2]); // this is the per-face normal var n = p1.sub(p0).cross(p2.sub(p0)); // add it to each point - normals[i0].x += n.x; - normals[i0].y += n.y; - normals[i0].z += n.z; - normals[i1].x += n.x; - normals[i1].y += n.y; - normals[i1].z += n.z; - normals[i2].x += n.x; - normals[i2].y += n.y; - normals[i2].z += n.z; + normals[3 * i0] += n.x; + normals[3 * i0 + 1] += n.y; + normals[3 * i0 + 2] += n.z; + + normals[3 * i1] += n.x; + normals[3 * i1 + 1] += n.y; + normals[3 * i1 + 2] += n.z; + + normals[3 * i2] += n.x; + normals[3 * i2 + 1] += n.y; + normals[3 * i2 + 2] += n.z; } // normalize all normals - for (n in normals) + for (k in 0...Std.int(points.length / 3)) { + var n = new h3d.Vector(normals[k * 3], normals[k * 3 + 1], normals[k * 3 + 2]); n.normalize(); + + normals[k * 3] = n.x; + normals[k * 3 + 1] = n.y; + normals[k * 3 + 2] = n.z; + } } public function addTangents() { @@ -210,26 +221,21 @@ class Polygon extends MeshPrimitive { addUVs(); tangents = []; for (i in 0...points.length) - tangents[i] = new Point(); + tangents[i] = 0; var pos = 0; for (i in 0...triCount()) { var i0, i1, i2; - if (idx == null) { - i0 = pos++; - i1 = pos++; - i2 = pos++; - } else { - i0 = idx[pos++]; - i1 = idx[pos++]; - i2 = idx[pos++]; - } - var p0 = points[i0]; - var p1 = points[i1]; - var p2 = points[i2]; - var uv0 = uvs[i0]; - var uv1 = uvs[i1]; - var uv2 = uvs[i2]; - var n = normals[i0]; + i0 = pos++; + i1 = pos++; + i2 = pos++; + + var p0 = new h3d.Vector(points[3 * i0], points[3 * i0 + 1], points[3 * i0 + 2]); + var p1 = new h3d.Vector(points[3 * i1], points[3 * i1 + 1], points[3 * i1 + 2]); + var p2 = new h3d.Vector(points[3 * i2], points[3 * i2 + 1], points[3 * i2 + 2]); + var uv0 = new UV(uvs[2 * i0], uvs[2 * i0 + 1]); + var uv1 = new UV(uvs[2 * i1], uvs[2 * i1 + 1]); + var uv2 = new UV(uvs[2 * i2], uvs[2 * i2 + 1]); + var n = new h3d.Vector(normals[3 * i0], normals[3 * i0 + 1], normals[3 * i0 + 2]); var k0 = p1.sub(p0); var k1 = p2.sub(p0); @@ -242,36 +248,33 @@ class Polygon extends MeshPrimitive { t.normalize(); // add it to each point - tangents[i0].x += t.x; - tangents[i0].y += t.y; - tangents[i0].z += t.z; - tangents[i1].x += t.x; - tangents[i1].y += t.y; - tangents[i1].z += t.z; - tangents[i2].x += t.x; - tangents[i2].y += t.y; - tangents[i2].z += t.z; + tangents[3 * i0] += t.x; + tangents[3 * i0 + 1] += t.y; + tangents[3 * i0 + 2] += t.z; + + tangents[3 * i1] += t.x; + tangents[3 * i1 + 1] += t.y; + tangents[3 * i1 + 2] += t.z; + + tangents[3 * i2] += t.x; + tangents[3 * i2 + 1] += t.y; + tangents[3 * i2 + 2] += t.z; + } + for (k in 0...Std.int(points.length / 3)) { + var n = new h3d.Vector(tangents[k * 3], tangents[k * 3 + 1], tangents[k * 3 + 2]); + n.normalize(); + + tangents[k * 3] = n.x; + tangents[k * 3 + 1] = n.y; + tangents[k * 3 + 2] = n.z; } - for (t in tangents) - t.normalize(); } public function addUVs() { uvs = []; - for (i in 0...points.length) - uvs[i] = new UV(points[i].x, points[i].y); - } - - public function uvScale(su:Float, sv:Float) { - if (uvs == null) - throw "Missing UVs"; - var m = new Map(); - for (t in uvs) { - if (m.exists(t)) - continue; - m.set(t, true); - t.u *= su; - t.v *= sv; + for (k in 0...Std.int(points.length / 3)) { + uvs[k * 2] = points[k * 3]; + uvs[k * 2 + 1] = points[k * 3 + 1]; } } @@ -279,38 +282,25 @@ class Polygon extends MeshPrimitive { var n = super.triCount(); if (n != 0) return n; - return Std.int((idx == null ? points.length : idx.length) / 3); + return Std.int(points.length / 9); } override function vertexCount() { return points.length; } - override function getCollider():h3d.col.Collider { - var vertexes = new haxe.ds.Vector(points.length * 3); - var indexes = new haxe.ds.Vector(idx.length); - var vid = 0; - for (p in points) { - vertexes[vid++] = p.x; - vertexes[vid++] = p.y; - vertexes[vid++] = p.z; - } - for (i in 0...idx.length) - indexes[i] = idx[i]; - var poly = new h3d.col.Polygon(); - poly.addBuffers(vertexes, indexes); - return poly; + override function selectMaterial(material:Int) { + currentMaterial = material; + } + + override function getMaterialIndexes(material:Int):{count:Int, start:Int} { + return {start: indexStarts[material] * 3, count: indexCounts[material] * 3}; } override function render(engine:h3d.Engine) { if (buffer == null || buffer.isDisposed()) alloc(engine); var bufs = getBuffers(engine); - if (indexes != null) - engine.renderMultiBuffers(bufs, indexes); - else if (buffer.flags.has(Quads)) - engine.renderMultiBuffers(bufs, engine.mem.quadIndexes, 0, triCount()); - else - engine.renderMultiBuffers(bufs, engine.mem.triIndexes, 0, triCount()); + engine.renderMultiBuffers(bufs, engine.mem.triIndexes, indexStarts[currentMaterial], indexCounts[currentMaterial]); } }