void Start() { //GetComponent<MeshFilter>().sharedMesh.MarkDynamic(); if (Mathf.Abs(cubeWidth) < 0.0001f) { cubeWidth = 0.0001f; } if (Mathf.Abs(cubeHeight) < 0.0001f) { cubeHeight = 0.0001f; } if (Mathf.Abs(cubeDepth) < 0.0001f) { cubeDepth = 0.0001f; } if (inputMesh != null) { shape = Shape.CreateShapeFromMesh(inputMesh); } else { shape = CubeShape.CreateCubeShape(1, false, new Vector3(cubeWidth, cubeHeight, cubeDepth)); } output = new DestructionVertexData(); output.prepareVertexData(numVertices); iterativeStack = new DestructionEffectIterative.AppendConsumeStack(); iterativeStack.prepareStack(numVertices / 6); }
public static void generateTrianglesFromShape(DestructionVertexData output, AppendConsumeStack stack, Shape shape, DestructionShapeParams shapeParams, DestructionSensor[] sensors) { //rhi::debugDraw::addSphere( toVector3( sensor.posLSWithScale ), sensor.radius, 0xFF0000FF, true ); tmpUV[0] = Vector3.zero; tmpUV[1] = Vector3.zero; tmpUV[2] = Vector3.zero; for (int itri = 0; itri < shape.numIndices_; itri += 3) { int itri0 = shape.indices_[itri]; int itri1 = shape.indices_[itri + 1]; int itri2 = shape.indices_[itri + 2]; tmpP[0] = shape.GetPosition(itri0); tmpP[1] = shape.GetPosition(itri1); tmpP[2] = shape.GetPosition(itri2); tmpN[0] = shape.GetNormal(itri0); tmpN[1] = shape.GetNormal(itri1); tmpN[2] = shape.GetNormal(itri2); //Vector3 t[3] = //{ // Vector3( picoPolyShape::getTangent( shape, itri0 ) ), // Vector3( picoPolyShape::getTangent( shape, itri1 ) ), // Vector3( picoPolyShape::getTangent( shape, itri2 ) ), //}; if( shape.uvs_ != null && shape.uvs_.Length > 0 ) { tmpUV[0] = shape.GetTexcoord(itri0); tmpUV[1] = shape.GetTexcoord(itri1); tmpUV[2] = shape.GetTexcoord(itri2); } stack.appendTriangle(tmpP, tmpN, tmpUV); if( stack.full() ) { _processIterative(output, stack, sensors, shapeParams); } } //process remaining triangles from stack _processIterative(output, stack, sensors, shapeParams); }
static void _processIterative(DestructionVertexData output, AppendConsumeStack stack, DestructionSensor[] sensors, DestructionShapeParams shapeParams) { int numSensors = sensors.Length; while (!stack.empty()) { bool collisions = false; //consume one triangle from a stack stack.consumeTriangle(tmpP, tmpN, tmpUV); Profiler.BeginSample("_testCollision"); for (uint i = 0; i < numSensors && !collisions; ++i) { collisions = _testCollision(tmpP, sensors[i].posLS, sensors[i].radius, shapeParams.scale); } Profiler.EndSample(); if (!collisions) { _processNoCollision(output, tmpP, tmpN, tmpUV, shapeParams.extrude, shapeParams.scaleInv); continue; } //const float VARIATION_THRESHOLD = 0.2f; Vector3 ea = tmpP[1] - tmpP[0]; Vector3 eb = tmpP[2] - tmpP[1]; Vector3 ec = tmpP[0] - tmpP[2]; scaledLen[0] = Vector3.Scale(ea, shapeParams.scale).sqrMagnitude; // length squared scaledLen[1] = Vector3.Scale(eb, shapeParams.scale).sqrMagnitude; // length squared scaledLen[2] = Vector3.Scale(ec, shapeParams.scale).sqrMagnitude; // length squared float x = shapeParams.voxelRadius * 2.0f; float xsqr = x * x; Profiler.BeginSample("_partitioning"); uint maxi = getMaxIndex(scaledLen); int partition = 0; if (scaledLen[maxi] > xsqr) { partition |= 1 << (int)maxi; float maxiLen = scaledLen[maxi]; const float THRESHOLD = 2.5f; if (maxi == 0) { partition |= ((maxiLen / scaledLen[1]) < THRESHOLD) ? 1 << 1 : 0; partition |= ((maxiLen / scaledLen[2]) < THRESHOLD) ? 1 << 2 : 0; } else if (maxi == 1) { partition |= ((maxiLen / scaledLen[0]) < THRESHOLD) ? 1 << 0 : 0; partition |= ((maxiLen / scaledLen[2]) < THRESHOLD) ? 1 << 2 : 0; } else { partition |= ((maxiLen / scaledLen[0]) < THRESHOLD) ? 1 << 0 : 0; partition |= ((maxiLen / scaledLen[1]) < THRESHOLD) ? 1 << 1 : 0; } } Profiler.EndSample(); //"_partitioning" if (partition != 0) { int numChildVertices = bitcount(partition); if (numChildVertices == 1 || numChildVertices == 2) // two new triangles { Profiler.BeginSample("_twoNewTriangles"); // select longest edge uint maxindex = (scaledLen[0] > scaledLen[1]) ? (uint)0 : 1; maxindex = (scaledLen[maxindex] > scaledLen[2]) ? maxindex : 2; if (maxindex == 0) { /* 2 * * * * * * * * * * * * * * 0-------------3---------------1 */ Vector3 tmpP3 = tmpP[0] + ea * 0.5f; Vector2 tmpUV3 = Vector3.Lerp(tmpUV[0], tmpUV[1], 0.5f); Vector3 tmpN3 = Vector3.Normalize(tmpN[0] + tmpN[1]); stack.appendTriangle(tmpP[0], tmpP3, tmpP[2], tmpN[0], tmpN3, tmpN[2], tmpUV[0], tmpUV3, tmpUV[2]); stack.appendTriangle(tmpP3, tmpP[1], tmpP[2], tmpN3, tmpN[1], tmpN[2], tmpUV3, tmpUV[1], tmpUV[2]); } else if (maxindex == 1) { /* 2 * * * * * * * 3 * * * * * * 0----------------------------1 */ Vector3 tmpP3 = tmpP[1] + eb * 0.5f; Vector2 tmpUV3 = Vector3.Lerp(tmpUV[1], tmpUV[2], 0.5f); Vector3 tmpN3 = Vector3.Normalize(tmpN[1] + tmpN[2]); stack.appendTriangle(tmpP[0], tmpP[1], tmpP3, tmpN[0], tmpN[1], tmpN3, tmpUV[0], tmpUV[1], tmpUV3); stack.appendTriangle(tmpP[0], tmpP3, tmpP[2], tmpN[0], tmpN3, tmpN[2], tmpUV[0], tmpUV3, tmpUV[2]); } else { /* 2 * * * * * * 3 * * * * * * * 0----------------------------1 */ Vector3 tmpP3 = tmpP[2] + ec * 0.5f; Vector2 tmpUV3 = Vector3.Lerp(tmpUV[2], tmpUV[0], 0.5f); Vector3 tmpN3 = Vector3.Normalize(tmpN[2] + tmpN[0]); stack.appendTriangle(tmpP[0], tmpP[1], tmpP3, tmpN[0], tmpN[1], tmpN3, tmpUV[0], tmpUV[1], tmpUV3); stack.appendTriangle(tmpP[1], tmpP[2], tmpP3, tmpN[1], tmpN[2], tmpN3, tmpUV[1], tmpUV[2], tmpUV3); } Profiler.EndSample();// "_twoNewTriangles" } else //three new triangles { Profiler.BeginSample("_threeNewTriangles"); /* 2 *| * * | * * | * * | * * 3 * * * * * * * * * 0---------------------------1 */ const float ONE_OVER_THREE = 1.0f / 3.0f; //Vector3 newPosition = Vector3 tmpP3 = (tmpP[0] + tmpP[1] + tmpP[2]) * ONE_OVER_THREE; Vector2 tmpUV3 = (tmpUV[0] + tmpUV[1] + tmpUV[2]) * ONE_OVER_THREE; Vector3 tmpN3 = (tmpN[0] + tmpN[1] + tmpN[2]) * ONE_OVER_THREE; //static ushort[] triIndices = //[3 * 3] = //{ // 0,1,3, // 1,2,3, // 2,0,3, //}; stack.appendTriangle(tmpP[0], tmpP[1], tmpP3, tmpN[0], tmpN[1], tmpN3, tmpUV[0], tmpUV[1], tmpUV3); stack.appendTriangle(tmpP[1], tmpP[2], tmpP3, tmpN[1], tmpN[2], tmpN3, tmpUV[1], tmpUV[2], tmpUV3); stack.appendTriangle(tmpP[2], tmpP[0], tmpP3, tmpN[2], tmpN[0], tmpN3, tmpUV[2], tmpUV[0], tmpUV3); Profiler.EndSample();// "_threeNewTriangles" } } else { _processWithCollision(output, tmpP, tmpN, tmpUV, sensors, shapeParams); } } }