make marble shaders better match original, attempt fix internal edge collisions

This commit is contained in:
RandomityGuy 2022-12-12 22:52:36 +05:30
parent 461b81d529
commit 61b37c04e9
5 changed files with 61 additions and 56 deletions

View file

@ -45,10 +45,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;
@ -56,6 +57,7 @@ class TriangleEdge {
index1 = i1;
index2 = i2;
}
this.farPoint = farPoint;
this.surfaceIndex = surfaceIndex;
}
}
@ -165,7 +167,7 @@ class DifBuilder {
colliderSurface.normals = [];
colliderSurface.indices = [];
colliderSurface.edgeData = [];
colliderSurface.edgeDots = [];
colliderSurface.edgeConcavities = [];
colliderSurface.originalIndices = [];
colliderSurface.originalSurfaceIndex = surfaceindex;
@ -186,11 +188,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);
@ -305,6 +305,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 {
@ -315,8 +317,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];
@ -349,9 +350,20 @@ 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;
var surface0 = geo.surfaces[edgeSurface0];
@ -399,35 +411,35 @@ class DifBuilder {
var edgeData = 0;
if (difEdges.exists(e1e2)) {
if (getEdgeDot(difEdges[e1e2]) < Math.cos(Math.PI / 12)) {
// if (getEdgeDot(difEdges[e1e2]) < Math.cos(Math.PI / 12)) {
edgeData |= 1;
}
colliderSurface.edgeDots.push(getEdgeDot(difEdges[e1e2]));
// }
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)) {
// if (getEdgeDot(difEdges[e2e3]) < Math.cos(Math.PI / 12)) {
edgeData |= 2;
}
colliderSurface.edgeDots.push(getEdgeDot(difEdges[e2e3]));
// }
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)) {
// if (getEdgeDot(difEdges[e1e3]) < Math.cos(Math.PI / 12)) {
edgeData |= 4;
}
colliderSurface.edgeDots.push(getEdgeDot(difEdges[e1e3]));
// }
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));
}

View file

@ -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<Float>) {
edgeConcavities:Array<Bool>) {
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
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
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();
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<Float>) {
edgeConcavities:Array<Bool>) {
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<Float> {

View file

@ -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) {

View file

@ -21,7 +21,7 @@ class CollisionSurface implements IOctreeObject {
public var edgeData:Array<Int>;
public var edgeDots:Array<Float>;
public var edgeConcavities:Array<Bool>;
public var originalIndices:Array<Int>;
public var originalSurfaceIndex:Int;

View file

@ -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;