From 8e19719060f986e1d1064ab5dba859c612d69396 Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Mon, 12 Dec 2022 22:52:36 +0530 Subject: [PATCH] make marble shaders better match original, attempt fix internal edge collisions --- src/DifBuilder.hx | 60 +++++++++++++------- src/collision/Collision.hx | 45 ++++++--------- src/collision/CollisionEntity.hx | 4 +- src/collision/CollisionSurface.hx | 2 +- src/dif/Edge.hx | 2 + src/shaders/marble/ClassicGlass.hx | 5 +- src/shaders/marble/ClassicGlassPureSphere.hx | 5 +- src/shaders/marble/ClassicMarb2.hx | 5 +- src/shaders/marble/ClassicMarb3.hx | 5 +- src/shaders/marble/ClassicMetal.hx | 5 +- 10 files changed, 76 insertions(+), 62 deletions(-) diff --git a/src/DifBuilder.hx b/src/DifBuilder.hx index 8f762621..0921e5bb 100644 --- a/src/DifBuilder.hx +++ b/src/DifBuilder.hx @@ -50,10 +50,11 @@ class DifBuilderTriangle { class TriangleEdge { public var index1:Int; public var index2:Int; + public var farPoint:Int; public var surfaceIndex:Int; - public function new(i1:Int, i2:Int, surfaceIndex:Int) { + public function new(i1:Int, i2:Int, farPoint:Int, surfaceIndex:Int) { if (i2 < i1) { index1 = i2; index2 = i1; @@ -61,6 +62,7 @@ class TriangleEdge { index1 = i1; index2 = i2; } + this.farPoint = farPoint; this.surfaceIndex = surfaceIndex; } } @@ -331,7 +333,7 @@ class DifBuilder { colliderSurface.normals = []; colliderSurface.indices = []; colliderSurface.edgeData = []; - colliderSurface.edgeDots = []; + colliderSurface.edgeConcavities = []; colliderSurface.originalIndices = []; colliderSurface.originalSurfaceIndex = surfaceindex; for (k in (surface.windingStart + 2)...(surface.windingStart + surface.windingCount)) { @@ -351,9 +353,9 @@ class DifBuilder { colliderSurface.originalIndices.push(geo.windings[k - 1]); colliderSurface.originalIndices.push(geo.windings[k]); } - var e1 = new TriangleEdge(geo.windings[k], geo.windings[k - 1], surfaceindex); - var e2 = new TriangleEdge(geo.windings[k - 1], geo.windings[k - 2], surfaceindex); - var e3 = new TriangleEdge(geo.windings[k], geo.windings[k - 2], surfaceindex); + var e1 = new TriangleEdge(geo.windings[k], geo.windings[k - 1], geo.windings[k - 2], surfaceindex); + var e2 = new TriangleEdge(geo.windings[k - 1], geo.windings[k - 2], geo.windings[k], surfaceindex); + var e3 = new TriangleEdge(geo.windings[k], geo.windings[k - 2], geo.windings[k - 1], surfaceindex); edges.push(e1); edges.push(e2); edges.push(e3); @@ -457,6 +459,8 @@ class DifBuilder { // trace('Removing internal edge: ${edge.index1} ${edge.index2}'); } else { var difEdge = new Edge(edge.index1, edge.index2, edge.surfaceIndex, edgeMap[edgeHash].surfaceIndex); + difEdge.farPoint0 = edge.farPoint; + difEdge.farPoint1 = edgeMap[edgeHash].farPoint; difEdges.set(edgeHash, difEdge); // Literal edge } } else { @@ -466,7 +470,7 @@ class DifBuilder { function hashEdge(i1:Int, i2:Int) { return i1 >= i2 ? i1 * i1 + i1 + i2 : i1 + i2 * i2; } - function getEdgeDot(edge:Edge) { + function getEdgeConcavity(edge:Edge) { var edgeSurface0 = edge.surfaceIndex0; var surface0 = geo.surfaces[edgeSurface0]; @@ -499,7 +503,19 @@ class DifBuilder { var dot = normal0.dot(normal1); - return dot; + if (Math.abs(dot) < 0.1) + return false; + + var farP0 = geo.points[edge.farPoint0]; + var farP1 = geo.points[edge.farPoint1]; + + var diff = farP1.sub(farP0); + var cdot0 = normal0.dot(diff); + if (cdot0 > -0.1) { + return true; + } + + return false; } function getEdgeNormal(edge:Edge) { var edgeSurface0 = edge.surfaceIndex0; @@ -546,35 +562,35 @@ class DifBuilder { var e1e3 = hashEdge(colliderSurface.originalIndices[i], colliderSurface.originalIndices[i + 2]); var edgeData = 0; if (difEdges.exists(e1e2)) { - if (getEdgeDot(difEdges[e1e2]) < Math.cos(Math.PI / 12)) { - edgeData |= 1; - } - colliderSurface.edgeDots.push(getEdgeDot(difEdges[e1e2])); + // if (getEdgeDot(difEdges[e1e2]) < Math.cos(Math.PI / 12)) { + edgeData |= 1; + // } + colliderSurface.edgeConcavities.push(getEdgeConcavity(difEdges[e1e2])); // colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e1e2])); } else { - colliderSurface.edgeDots.push(0); + colliderSurface.edgeConcavities.push(false); // colliderSurface.edgeNormals.push(new Vector(0, 0, 0)); } if (difEdges.exists(e2e3)) { - if (getEdgeDot(difEdges[e2e3]) < Math.cos(Math.PI / 12)) { - edgeData |= 2; - } - colliderSurface.edgeDots.push(getEdgeDot(difEdges[e2e3])); + // if (getEdgeDot(difEdges[e2e3]) < Math.cos(Math.PI / 12)) { + edgeData |= 2; + // } + colliderSurface.edgeConcavities.push(getEdgeConcavity(difEdges[e2e3])); // colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e2e3])); // colliderSurface.edgeDots.push(dot); } else { - colliderSurface.edgeDots.push(0); + colliderSurface.edgeConcavities.push(false); // colliderSurface.edgeNormals.push(new Vector(0, 0, 0)); } if (difEdges.exists(e1e3)) { - if (getEdgeDot(difEdges[e1e3]) < Math.cos(Math.PI / 12)) { - edgeData |= 4; - } - colliderSurface.edgeDots.push(getEdgeDot(difEdges[e1e3])); + // if (getEdgeDot(difEdges[e1e3]) < Math.cos(Math.PI / 12)) { + edgeData |= 4; + // } + colliderSurface.edgeConcavities.push(getEdgeConcavity(difEdges[e1e3])); // colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e1e3])); // colliderSurface.edgeDots.push(dot); } else { - colliderSurface.edgeDots.push(0); + colliderSurface.edgeConcavities.push(false); // colliderSurface.edgeNormals.push(new Vector(0, 0, 0)); } colliderSurface.edgeData.push(edgeData); diff --git a/src/collision/Collision.hx b/src/collision/Collision.hx index f27b8f58..716837e8 100644 --- a/src/collision/Collision.hx +++ b/src/collision/Collision.hx @@ -61,7 +61,7 @@ class Collision { // 010b: v1v2 is edge // 100b: v0v2 is edge public static function IntersectTriangleSphere(v0:Vector, v1:Vector, v2:Vector, normal:Vector, center:Vector, radius:Float, edgeData:Int, - edgeDots:Array) { + edgeConcavities:Array) { var radiusSq = radius * radius; var res:ITSResult = { @@ -88,7 +88,7 @@ class Collision { if (PointInTriangle(pt, v0, v1, v2)) { res.result = true; res.point = pt; - res.normal = center.sub(pt).normalized(); + res.normal = pnorm; return res; } // return res; @@ -120,30 +120,21 @@ class Collision { if (res.point.distanceSq(center) <= radiusSq) { res.result = true; - if (chosenEdge & edgeData > 0) { - res.normal = center.sub(res.point).normalized(); - } else { // We hit an internal edge - chosenEdge -= 1; - if (chosenEdge > 2) - chosenEdge--; - // if (edgeNormals[chosenEdge].length() < 0.5) { - // res.normal = center.sub(res.point).normalized(); - // } else - var edgeDotAng = Math.acos(edgeDots[chosenEdge]); - if (edgeDotAng < Math.PI / 12) { - // if (edgeDotAng == 0) { - // res.normal = center.sub(res.point).normalized(); - // } else { - // res.normal = normal; // edgeNormals[chosenEdge]; - // } - res.point = null; - res.normal = null; - res.result = false; - } else { - res.result = false; - res.normal = center.sub(res.point).normalized(); + res.normal = center.sub(res.point).normalized(); + + if (res.normal.dot(normal) > 0.8) { + // Internal edge + if (chosenEdge & edgeData > 0) { + chosenEdge -= 1; + if (chosenEdge > 2) + chosenEdge--; + // if (edgeNormals[chosenEdge].length() < 0.5) { + // res.normal = center.sub(res.point).normalized(); + // } else + if (edgeConcavities[chosenEdge]) { // Our edge is concave + res.normal = pnorm; + } } - // trace("Internal Edge Collision"); } return res; @@ -327,7 +318,7 @@ class Collision { } public static function IntersectTriangleCapsule(start:Vector, end:Vector, radius:Float, p1:Vector, p2:Vector, p3:Vector, normal:Vector, edgeData:Int, - edgeDots:Array) { + edgeConcavities:Array) { var dir = end.sub(start); var d = -(p1.dot(normal)); var t = -(start.dot(normal) - d) / dir.dot(normal); @@ -336,7 +327,7 @@ class Collision { if (t < 0) t = 0; var tracePoint = start.add(dir.multiply(t)); - return IntersectTriangleSphere(p1, p2, p3, normal, tracePoint, radius, edgeData, edgeDots); + return IntersectTriangleSphere(p1, p2, p3, normal, tracePoint, radius, edgeData, edgeConcavities); } private static function GetLowestRoot(a:Float, b:Float, c:Float, max:Float):Null { diff --git a/src/collision/CollisionEntity.hx b/src/collision/CollisionEntity.hx index 4b00870d..afb93e58 100644 --- a/src/collision/CollisionEntity.hx +++ b/src/collision/CollisionEntity.hx @@ -195,11 +195,11 @@ class CollisionEntity implements IOctreeObject { var edgeData = surface.edgeData[Math.floor(i / 3)]; - var edgeDots = surface.edgeDots.slice(Math.floor(i / 3), Math.floor(i / 3) + 3); + var edgeConcavities = surface.edgeConcavities.slice(Math.floor(i / 3), Math.floor(i / 3) + 3); var surfacenormal = surface.normals[surface.indices[i]].transformed3x3(transform).normalized(); - var res = Collision.IntersectTriangleSphere(v0, v, v2, surfacenormal, position, radius, edgeData, edgeDots); + var res = Collision.IntersectTriangleSphere(v0, v, v2, surfacenormal, position, radius, edgeData, edgeConcavities); var closest = res.point; // var closest = Collision.ClosestPtPointTriangle(position, radius, v0, v, v2, surfacenormal); if (closest != null) { diff --git a/src/collision/CollisionSurface.hx b/src/collision/CollisionSurface.hx index 7551b942..608beaf1 100644 --- a/src/collision/CollisionSurface.hx +++ b/src/collision/CollisionSurface.hx @@ -21,7 +21,7 @@ class CollisionSurface implements IOctreeObject { public var edgeData:Array; - public var edgeDots:Array; + public var edgeConcavities:Array; public var originalIndices:Array; public var originalSurfaceIndex:Int; diff --git a/src/dif/Edge.hx b/src/dif/Edge.hx index 8918dd6f..8db5d0c9 100644 --- a/src/dif/Edge.hx +++ b/src/dif/Edge.hx @@ -10,6 +10,8 @@ class Edge { public var pointIndex1:Int32; public var surfaceIndex0:Int32; public var surfaceIndex1:Int32; + public var farPoint0:Int32; + public var farPoint1:Int32; public function new(pointIndex0, pointIndex1, surfaceIndex0, surfaceIndex1) { this.pointIndex0 = pointIndex0; diff --git a/src/shaders/marble/ClassicGlass.hx b/src/shaders/marble/ClassicGlass.hx index 8c24ee43..4450e117 100644 --- a/src/shaders/marble/ClassicGlass.hx +++ b/src/shaders/marble/ClassicGlass.hx @@ -59,8 +59,9 @@ class ClassicGlass extends hxsl.Shader { var diffuse = dirLight * (dot(transformedNormal, -dirLightDir) + 1.3) * 0.5; // Specular - var r = reflect(dirLightDir, transformedNormal).normalize(); - var specValue = saturate(r.dot((camera.position - transformedPosition).normalize())) * fragLightW; + var eyeVec = (camera.position - transformedPosition).normalize(); + var halfAng = (eyeVec - dirLightDir).normalize(); + var specValue = saturate(transformedNormal.dot(halfAng)) * fragLightW; var specular = specularColor * pow(specValue, shininess); var viewDir = normalize(camera.position - pixelTransformedPosition); diff --git a/src/shaders/marble/ClassicGlassPureSphere.hx b/src/shaders/marble/ClassicGlassPureSphere.hx index e9a965b8..919d1f55 100644 --- a/src/shaders/marble/ClassicGlassPureSphere.hx +++ b/src/shaders/marble/ClassicGlassPureSphere.hx @@ -47,8 +47,9 @@ class ClassicGlassPureSphere extends hxsl.Shader { var diffuse = dirLight * (dot(transformedNormal, -dirLightDir) + 1.3) * 0.5; // Specular - var r = reflect(dirLightDir, transformedNormal).normalize(); - var specValue = saturate(r.dot((camera.position - transformedPosition).normalize())) * fragLightW; + var eyeVec = (camera.position - transformedPosition).normalize(); + var halfAng = (eyeVec - dirLightDir).normalize(); + var specValue = saturate(transformedNormal.dot(halfAng)) * fragLightW; var specular = specularColor * pow(specValue, shininess); var viewDir = normalize(camera.position - pixelTransformedPosition); diff --git a/src/shaders/marble/ClassicMarb2.hx b/src/shaders/marble/ClassicMarb2.hx index d20f33f7..28b1f56c 100644 --- a/src/shaders/marble/ClassicMarb2.hx +++ b/src/shaders/marble/ClassicMarb2.hx @@ -45,8 +45,9 @@ class ClassicMarb2 extends hxsl.Shader { var diffuse = dirLight * (dot(transformedNormal, -dirLightDir) + 1.3) * 0.5; // Specular - var r = reflect(dirLightDir, transformedNormal).normalize(); - var specValue = saturate(r.dot((camera.position - transformedPosition).normalize())) * fragLightW; + var eyeVec = (camera.position - transformedPosition).normalize(); + var halfAng = (eyeVec - dirLightDir).normalize(); + var specValue = saturate(transformedNormal.dot(halfAng)) * fragLightW; var specular = specularColor * pow(specValue, shininess); var viewDir = normalize(camera.position - pixelTransformedPosition); diff --git a/src/shaders/marble/ClassicMarb3.hx b/src/shaders/marble/ClassicMarb3.hx index fc1dc052..c120e352 100644 --- a/src/shaders/marble/ClassicMarb3.hx +++ b/src/shaders/marble/ClassicMarb3.hx @@ -45,8 +45,9 @@ class ClassicMarb3 extends hxsl.Shader { var diffuse = vec4(dirLight, 1) * (dot(transformedNormal, -dirLightDir) + 1.3) * 0.5; // Specular - var r = reflect(dirLightDir, transformedNormal).normalize(); - var specValue = saturate(r.dot((camera.position - transformedPosition).normalize())) * fragLightW; + var eyeVec = (camera.position - transformedPosition).normalize(); + var halfAng = (eyeVec - dirLightDir).normalize(); + var specValue = saturate(transformedNormal.dot(halfAng)) * fragLightW; var specular = specularColor * pow(specValue, shininess); var viewDir = normalize(camera.position - pixelTransformedPosition); diff --git a/src/shaders/marble/ClassicMetal.hx b/src/shaders/marble/ClassicMetal.hx index b038ff52..1a251e29 100644 --- a/src/shaders/marble/ClassicMetal.hx +++ b/src/shaders/marble/ClassicMetal.hx @@ -59,8 +59,9 @@ class ClassicMetal extends hxsl.Shader { var diffuse = dirLight * (dot(transformedNormal, -dirLightDir) + 1.3) * 0.5; // Specular - var r = reflect(dirLightDir, transformedNormal).normalize(); - var specValue = saturate(r.dot((camera.position - transformedPosition).normalize())) * fragLightW; + var eyeVec = (camera.position - transformedPosition).normalize(); + var halfAng = (eyeVec - dirLightDir).normalize(); + var specValue = saturate(transformedNormal.dot(halfAng)) * fragLightW; var specular = specularColor * pow(specValue, shininess); var viewDir = normalize(camera.position - pixelTransformedPosition);