public int GetFillTriangleCount(RageVertex[] fillVerts, bool AAfill) { switch (GetFill()) { case Fill.None: return 0; case Fill.Solid: case Fill.Gradient: if (AAfill) { return (fillVerts.Length / 2) - 2 + fillVerts.Length; } else { return fillVerts.Length - 2; } case Fill.Landscape: if (AAfill) { return ((fillVerts.Length / 3) - 1) * 4; } else { return ((fillVerts.Length / 2) - 1) * 2; } } return 0; }
public void GenerateTriangles(Mesh mesh, RageVertex[] fillVerts, RageVertex[] embossVerts, RageVertex[] outlineVerts, bool AAfill, bool AAemboss, bool AAoutline, bool multipleMaterials) { int[] tris = null; Vector2[] verts = new Vector2[0]; if (GetFill() != Fill.Landscape) { if (AAfill) { verts = new Vector2[fillVerts.Length / 2]; } else { verts = new Vector2[fillVerts.Length]; } for (int i = 0; i < verts.Length; i++) { verts[i] = new Vector2(fillVerts[i].position.x, fillVerts[i].position.y); } } tris = new int[GetOutlineTriangleCount(outlineVerts, AAoutline) * 3 + GetFillTriangleCount(fillVerts, AAfill) * 3 + GetEmbossTriangleCount(embossVerts, AAemboss) * 3]; int tIndex = 0; int vertsPerBand = 0; int bandCount = 0; switch (GetFill()) { case Fill.None: break; case Fill.Solid: case Fill.Gradient: Triangulator triangulator = new Triangulator(verts); int[] fillTris = triangulator.Triangulate(); for (int i = 0; i < fillTris.Length; i++) { tris[tIndex++] = fillTris[i]; } break; case Fill.Landscape: if (AAfill) { bandCount = 2; vertsPerBand = fillVerts.Length / 3; } else { bandCount = 1; vertsPerBand = fillVerts.Length / 2; } for (int v = 0; v < vertsPerBand-1; v++) { for (int b = 0; b < bandCount; b++) { tris[tIndex++] = v + b * vertsPerBand; tris[tIndex++] = v + (b + 1) * vertsPerBand; tris[tIndex++] = v + (b + 1) * vertsPerBand + 1; tris[tIndex++] = v + b * vertsPerBand; tris[tIndex++] = v + (b + 1) * vertsPerBand + 1; tris[tIndex++] = v + b * vertsPerBand + 1; } } break; } vertsPerBand = 0; bandCount = 0; // fill antialiasing triangles if (AAfill) { vertsPerBand = verts.Length-1; for (int v = 0; v <= vertsPerBand; v++) { for (int b = 0; b < 1; b++) { tris[tIndex++] = v + b * vertsPerBand; tris[tIndex++] = v + (b + 1) * vertsPerBand; tris[tIndex++] = v + (b + 1) * vertsPerBand + 1; tris[tIndex++] = v + b * vertsPerBand; tris[tIndex++] = v + (b + 1) * vertsPerBand + 1; tris[tIndex++] = v + b * vertsPerBand + 1; } } } if (AAemboss) { vertsPerBand = embossVerts.Length / 4; bandCount = 3; } else { vertsPerBand = embossVerts.Length / 2; bandCount = 1; } for (int v = 0; v < vertsPerBand-1; v++) { for (int b = 0; b < bandCount; b++) { if (v < vertsPerBand - 1) { tris[tIndex++] = v + b * vertsPerBand + fillVerts.Length; tris[tIndex++] = v + (b + 1) * vertsPerBand + 1 + fillVerts.Length; tris[tIndex++] = v + (b + 1) * vertsPerBand + fillVerts.Length; tris[tIndex++] = v + b * vertsPerBand + fillVerts.Length; tris[tIndex++] = v + b * vertsPerBand + 1 + fillVerts.Length; tris[tIndex++] = v + (b + 1) * vertsPerBand + 1 + fillVerts.Length; } } } if (AAoutline) { vertsPerBand = outlineVerts.Length / 4; bandCount = 3; } else { vertsPerBand = outlineVerts.Length / 2; bandCount = 1; } for (int v = 0; v < vertsPerBand-1; v++) { for (int b = 0; b < bandCount; b++) { tris[tIndex++] = v + b * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[tIndex++] = v + (b + 1) * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = v + (b + 1) * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[tIndex++] = v + b * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[tIndex++] = v + b * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = v + (b + 1) * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; } } // Free outline AA caps if (GetOutline() == Outline.Free && AAoutline) { int vertsInBand = outlineVerts.Length / 4; tris[tIndex++] = 0 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = vertsInBand * 2 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = vertsInBand + embossVerts.Length + fillVerts.Length; tris[tIndex++] = 0 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = vertsInBand * 3 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = vertsInBand * 2 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = vertsInBand * 1 - 1 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = vertsInBand * 3 - 1 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = vertsInBand * 2 - 1 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = vertsInBand * 1 - 1 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = vertsInBand * 4 - 1 + embossVerts.Length + fillVerts.Length; tris[tIndex++] = vertsInBand * 3 - 1 + embossVerts.Length + fillVerts.Length; } if (multipleMaterials) { int ii = 0; int[] outlineTriangles = new int[GetOutlineTriangleCount(outlineVerts, AAoutline) * 3]; int[] restOfTriangles = new int[tris.Length - GetOutlineTriangleCount(outlineVerts, AAoutline) * 3]; mesh.subMeshCount = 2; for (; ii < restOfTriangles.Length; ii++) { restOfTriangles[ii] = tris[ii]; } if (GetTexturing1() == UVMapping.Fill) { mesh.SetTriangles(restOfTriangles, 0); } if (GetTexturing2() == UVMapping.Fill) { mesh.SetTriangles(restOfTriangles, 1); } for (; ii < tris.Length; ii++) { outlineTriangles[ii - restOfTriangles.Length] = tris[ii]; } if (GetTexturing1() == UVMapping.Outline) { mesh.SetTriangles(outlineTriangles, 0); } if (GetTexturing2() == UVMapping.Outline) { mesh.SetTriangles(outlineTriangles, 1); } } else { if (inverseTriangleDrawOrder) { int len = tris.Length; int[] triangles2 = new int[tris.Length]; for (int i = 0; i < len; i+=3) { triangles2[len - i - 3] = tris[i]; triangles2[len - i - 3 + 1] = tris[i + 1]; triangles2[len - i - 3 + 2] = tris[i + 2]; } tris = triangles2; } mesh.triangles = tris; } }
public int GetEmbossTriangleCount(RageVertex[] embossVerts, bool AAemboss) { if (GetEmboss() != Emboss.None) { if (AAemboss) { return ((embossVerts.Length / 4) - 1) * 6; } else { return embossVerts.Length - 2; } } else { return 0; } }
private RageVertex[] GenerateEmbossVerts() { RageVertex[] splits = GetSplits(embossVertexCount, 0f, 1f); RageVertex[] embossVerts = new RageVertex[0]; if (emboss != Emboss.None && embossVertexCount > 2) { int vertsInBand = splits.Length; embossVerts = new RageVertex[splits.Length * 4]; Vector3 sunVector = RotatePoint2D_CCW(new Vector3(0f, -1f, 0f), embossAngle / (180f / Mathf.PI)); Vector3[] embossVectors = new Vector3[splits.Length]; Vector3[] normals = new Vector3[splits.Length]; float[] dots = new float[splits.Length]; float[] mags = new float[splits.Length]; for (int v = 0; v < splits.Length; v++) { float p = (float)v / (float)splits.Length; normals[v] = spline.GetAvgNormal(p, new Vector3(0f, 0f, 1f), 0.05f, 3)*-1f; dots[v] = Vector3.Dot(sunVector, normals[v]); mags[v] = Mathf.Clamp01(Mathf.Abs(dots[v]) - embossOffset); if (dots[v] > 0f) { embossVectors[v] = (sunVector+normals[v] * 2f).normalized * embossSize * mags[v]; } else { embossVectors[v] = (sunVector-normals[v]*2f).normalized * embossSize * mags[v] * -1f; } } for (int v = 0; v < splits.Length; v++) { Vector3 embossVector = new Vector3(); for (int i = -Mathf.FloorToInt(embossCurveSmoothness); i <= Mathf.FloorToInt(embossCurveSmoothness)+1; i++) { if (i != 0) { embossVector += embossVectors[mod(v - i, splits.Length)] * (1f - (float)Mathf.Abs(i) / (embossCurveSmoothness+1)); } else { embossVector += embossVectors[mod(v - i, splits.Length)]; } } embossVector *= 1f / (Mathf.FloorToInt(embossCurveSmoothness)*2+1); embossVerts[v + 0 * vertsInBand].position = splits[v].position - normals[v] * AntiAliasingWidth; embossVerts[v + 1 * vertsInBand].position = splits[v].position; embossVerts[v + 2 * vertsInBand].position = splits[v].position + embossVector; embossVerts[v + 3 * vertsInBand].position = splits[v].position + embossVector + normals[v] * AntiAliasingWidth; if (embossVector.sqrMagnitude > 0.01f) { if (dots[v] < 0f) { if (emboss == Emboss.Sharp) { embossVerts[v + 0 * vertsInBand].color = embossColor2 * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = embossColor2 * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v]*4f)); embossVerts[v + 2 * vertsInBand].color = embossColor2 * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 3 * vertsInBand].color = embossColor2 * new Color(1f, 1f, 1f, 0f); } else { embossVerts[v + 0 * vertsInBand].color = embossColor2 * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = embossColor2 * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 2 * vertsInBand].color = embossColor2 * new Color(1f, 1f, 1f, 0f); embossVerts[v + 3 * vertsInBand].color = embossColor2 * new Color(1f, 1f, 1f, 0f); } } else { if (emboss == Emboss.Sharp) { embossVerts[v + 0 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 2 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 3 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, 0f); } else { embossVerts[v + 0 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 2 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, 0f); embossVerts[v + 3 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, 0f); } } } else { embossVerts[v + 0 * vertsInBand].position = splits[v].position - normals[v] * AntiAliasingWidth; embossVerts[v + 1 * vertsInBand].position = splits[v].position; embossVerts[v + 2 * vertsInBand].position = splits[v].position; embossVerts[v + 3 * vertsInBand].position = splits[v].position; embossVerts[v + 0 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, 0f); embossVerts[v + 2 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, 0f); embossVerts[v + 3 * vertsInBand].color = embossColor1 * new Color(1f, 1f, 1f, 0f); } embossVerts[v + 0 * vertsInBand].uv = new Vector2(1f, 1f); embossVerts[v + 1 * vertsInBand].uv = new Vector2(1f, 1f); embossVerts[v + 2 * vertsInBand].uv = new Vector2(1f, 1f); embossVerts[v + 3 * vertsInBand].uv = new Vector2(1f, 1f); } } else { embossVerts = new RageVertex[0]; } return embossVerts; }
public RageVertex[] GenerateOutlineVerts(bool antialiasing, bool multipleMaterials) { RageVertex[] outlineVerts = new RageVertex[0]; if (GetOutline() != Outline.None) { RageVertex[] splits=null; if (GetOutline() == Outline.Free && GetFill() != Fill.None && GetFill() != Fill.Landscape) { splits = GetSplits(GetVertexCount() - (Mathf.FloorToInt((float)GetVertexCount() * 1f / GetPointCount())), 0f, 1f - 1f / GetPointCount()); } else { splits = GetSplits(GetVertexCount(), 0f, 1f); } int vertsInBand = splits.Length; float uvPos = 0f; if (antialiasing) { outlineVerts = new RageVertex[splits.Length * 4]; } else { outlineVerts = new RageVertex[splits.Length * 2]; } for (int v = 0; v < splits.Length; v++) { Vector3 normal = new Vector3(); float edgeWidth = GetOutlineWidth(splits[v].splinePosition * GetLastSplinePosition()); float AAWidth = GetAntialiasingWidth(splits[v].splinePosition * GetLastSplinePosition()); if (corners != Corner.Beak) { if (GetFill() != Fill.Landscape) { normal = GetNormal(splits[v].splinePosition); } else { normal = new Vector3(0f, 1f, 0f) * GetLandscapeOutlineAlign() + GetNormal(splits[v].splinePosition) * (1f - GetLandscapeOutlineAlign()); normal.Normalize(); } } else { if ((outline != Outline.Free) || (v < splits.Length - 1 && v > 0)) { normal = FindNormal(splits[GetIndex(v - 1, splits.Length)].position, splits[v].position, splits[GetIndex(v + 1, splits.Length)].position, edgeWidth); normal *= -1; edgeWidth = 1f; } else { if ((v < splits.Length - 1 && v > 0)) { normal = GetNormal(splits[v].splinePosition * GetLastSplinePosition()); } else { if (v == 0) { normal = FindNormal(splits[0].position + (splits[0].position - splits[1].position), splits[0].position, splits[1].position, edgeWidth); normal *= -1; edgeWidth = 1f; } else { normal = FindNormal(splits[splits.Length - 1].position + (splits[splits.Length - 1].position - splits[splits.Length - 2].position), splits[splits.Length - 1].position, splits[splits.Length - 2].position, edgeWidth); edgeWidth = 1f; } } } if (normal.magnitude > this.maxBeakLength * this.OutlineWidth) { normal = normal.normalized * this.maxBeakLength * this.OutlineWidth; } } if (v > 0) { uvPos += (splits[v].position - splits[v - 1].position).magnitude; } Vector3 scaledNormal = ScaleToLocal(normal.normalized); Vector3 normalizedNormal = normal.normalized; if (antialiasing) { Vector3 freeLineCapTangent = new Vector3(0f, 0f, 0f); if (v == 0 && GetOutline() == Outline.Free) { freeLineCapTangent = Vector3.Cross(normal, new Vector3(0f, 0f, -1f)) * AAWidth; } else if (v == splits.Length - 1 && GetOutline() == Outline.Free) { freeLineCapTangent = Vector3.Cross(normal, new Vector3(0f, 0f, -1f)) * -AAWidth; } outlineVerts[v + 0 * vertsInBand].position = splits[v].position + scaledNormal * AAWidth + normal * edgeWidth * 0.5f + normalizedNormal * GetOutlineNormalOffset() + freeLineCapTangent; outlineVerts[v + 1 * vertsInBand].position = splits[v].position + normal * edgeWidth * 0.5f + normalizedNormal * GetOutlineNormalOffset(); outlineVerts[v + 2 * vertsInBand].position = splits[v].position - normal * edgeWidth * 0.5f + normalizedNormal * GetOutlineNormalOffset(); outlineVerts[v + 3 * vertsInBand].position = splits[v].position - normal * edgeWidth * 0.5f - scaledNormal * AAWidth + normalizedNormal * GetOutlineNormalOffset() + freeLineCapTangent; } else { outlineVerts[v + 0 * vertsInBand].position = splits[v].position + normal * edgeWidth * 0.5f + normal * GetOutlineNormalOffset(); outlineVerts[v + 1 * vertsInBand].position = splits[v].position - normal * edgeWidth * 0.5f + normal * GetOutlineNormalOffset(); } Color outlineCol1 = Color.black; Color outlineCol2 = Color.black; switch (GetOutlineGradient()) { case OutlineGradient.None: outlineCol1 = GetOutlineColor1(); outlineCol2 = GetOutlineColor1(); break; case OutlineGradient.Default: outlineCol1 = GetOutlineColor1(); outlineCol2 = GetOutlineColor2(); break; case OutlineGradient.Inverse: outlineCol1 = GetOutlineColor2(); outlineCol2 = GetOutlineColor1(); break; } if (antialiasing) { outlineVerts[v + 0 * vertsInBand].color = outlineCol2 * new Color(1f, 1f, 1f, 0f); outlineVerts[v + 1 * vertsInBand].color = outlineCol2 * new Color(1f, 1f, 1f, 1f); outlineVerts[v + 2 * vertsInBand].color = outlineCol1 * new Color(1f, 1f, 1f, 1f); outlineVerts[v + 3 * vertsInBand].color = outlineCol1 * new Color(1f, 1f, 1f, 0f); } else { outlineVerts[v + 0 * vertsInBand].color = outlineCol2 * new Color(1f, 1f, 1f, 1f); outlineVerts[v + 1 * vertsInBand].color = outlineCol1 * new Color(1f, 1f, 1f, 1f); } float AAWidthRelatedToEdgeWidth = 0f; if (AAWidth > 0f && edgeWidth > 0f && antialiasing) { AAWidthRelatedToEdgeWidth = AAWidth / edgeWidth; } if (!multipleMaterials) { switch (GetTexturing1()) { case UVMapping.None: case UVMapping.Fill: outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2(0f, 0f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2(0f, 0f); if (antialiasing) { outlineVerts[v + 2 * vertsInBand].uv1 = new Vector2(0f, 0f); outlineVerts[v + 3 * vertsInBand].uv1 = new Vector2(0f, 0f); } break; case UVMapping.Outline: if (antialiasing) { outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 1f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 1f - AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 2 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 3 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 0f); } else { outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 1f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 0f); } break; } switch (GetTexturing2()) { case UVMapping.None: case UVMapping.Fill: if (antialiasing) { outlineVerts[v + 0 * vertsInBand].uv2 = new Vector2(0f, 0f); outlineVerts[v + 1 * vertsInBand].uv2 = new Vector2(0f, 0f); outlineVerts[v + 2 * vertsInBand].uv2 = new Vector2(0f, 0f); outlineVerts[v + 3 * vertsInBand].uv2 = new Vector2(0f, 0f); } else { outlineVerts[v + 0 * vertsInBand].uv2 = new Vector2(0f, 0f); outlineVerts[v + 1 * vertsInBand].uv2 = new Vector2(0f, 0f); } break; case UVMapping.Outline: if (antialiasing) { outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 1f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 1f - AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 2 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 3 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 0f); } else { outlineVerts[v + 0 * vertsInBand].uv2 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 0.99f); outlineVerts[v + 1 * vertsInBand].uv2 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 0.01f); } break; } } else { if (antialiasing) { outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 1f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 1f - AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 2 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 3 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 0f); } else { outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 0.99f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2(uvPos / GetOutlineTexturingScaleInv(), 0.01f); } } } } else { outlineVerts = new RageVertex[0]; } /* for (int index = 0; index < outlineVerts.Length; index++) { outlineVerts[index].position -= transform.forward * 0.2f; } */ return outlineVerts; }
public void RefreshPhysics() { //Debug.Log("RefreshPhysics"); if (boxColliders == null && GetPhysics() == Physics.Boxed) { boxColliders = new BoxCollider[1]; } if (!Application.isPlaying && !GetCreatePhysicsInEditor()) { DestroyPhysicsChildren(); } if (Application.isPlaying || GetCreatePhysicsInEditor()) { switch (GetPhysics()) { case Physics.None: DestroyPhysicsChildren(); break; case Physics.Boxed: DestroyMeshCollider(); if (lastPhysicsVertsCount != GetSplits(physicsColliderCount, 0f, 1f).Length || boxColliders[0] == null) { if (!Application.isPlaying) { DestroyPhysicsChildren(); } lastPhysicsVertsCount = GetSplits(physicsColliderCount, 0f, 1f).Length; RageVertex[] splits = new RageVertex[0]; splits = GetSplits(physicsColliderCount, 0f, 1f); boxColliders = new BoxCollider[splits.Length - 1]; int t = 0; t = splits.Length - 1; for (int i = 0; i < t; i++) { GameObject newObj = new GameObject(); newObj.name = "ZZZ_" + gameObject.name + "_BoxCollider"; newObj.transform.parent = transform; BoxCollider box = newObj.AddComponent(typeof(BoxCollider)) as BoxCollider; box.material = GetPhysicsMaterial(); int i2 = i + 1; Vector3 pos; Vector3 pos2; Vector3 norm = GetNormal(splits[i].splinePosition); Vector3 norm2 = GetNormal(splits[i2].splinePosition); pos = splits[i].position - norm * (GetBoxColliderDepth() * 0.5f - GetPhysicsNormalOffset()); pos2 = splits[i2].position - norm2 * (GetBoxColliderDepth() * 0.5f - GetPhysicsNormalOffset()); newObj.layer = transform.gameObject.layer; newObj.tag = transform.gameObject.tag; newObj.gameObject.transform.localPosition = (pos + pos2) * 0.5f; newObj.gameObject.transform.LookAt(transform.TransformPoint(newObj.gameObject.transform.localPosition + Vector3.Cross((pos - pos2).normalized, new Vector3(0f, 0f, -1f))), new Vector3(1f, 0f, 0f)); newObj.gameObject.transform.localScale = new Vector3(GetPhysicsZDepth(), ((pos + norm * GetBoxColliderDepth() * 0.5f) - (pos2 + norm2 * GetBoxColliderDepth() * 0.5f)).magnitude, 1f * GetBoxColliderDepth()); boxColliders[i] = box; } } else { int i = 0; RageVertex[] splits = new RageVertex[0]; splits = GetSplits(GetPhysicsColliderCount(), 0f, 1f); foreach (BoxCollider obj in boxColliders) { obj.material = GetPhysicsMaterial(); int i2 = i + 1; Vector3 norm = GetNormal(splits[i].splinePosition); Vector3 norm2 = GetNormal(splits[i2].splinePosition); Vector3 pos; Vector3 pos2; pos = splits[i].position - norm * (GetBoxColliderDepth() * 0.5f - GetPhysicsNormalOffset()); pos2 = splits[i2].position - norm2 * (GetBoxColliderDepth() * 0.5f - GetPhysicsNormalOffset()); obj.gameObject.transform.localPosition = (pos + pos2) * 0.5f; obj.gameObject.transform.LookAt(transform.TransformPoint(obj.gameObject.transform.localPosition + Vector3.Cross((pos - pos2).normalized, new Vector3(0f, 0f, -1f))), new Vector3(1f, 0f, 0f)); obj.gameObject.transform.localScale = new Vector3(GetPhysicsZDepth(), ((pos + norm * GetBoxColliderDepth() * 0.5f) - (pos2 + norm2 * GetBoxColliderDepth() * 0.5f)).magnitude, 1f * GetBoxColliderDepth()); i++; } lastPhysicsVertsCount = physicsColliderCount; } break; case Physics.MeshCollider: DestroyBoxColliders(); if (GetPhysicsColliderCount() > 2 && (GetCreatePhysicsInEditor() || Application.isPlaying)) { Vector3[] verts = null; RageVertex[] splits2 = null; int[] tris = null; int tt = 0; if (GetFill() != Fill.Landscape) { splits2 = GetSplits(GetPhysicsColliderCount(), 0f, 1f); verts = new Vector3[splits2.Length * 2]; //verts = new Vector3[GetPhysicsColliderCount() * 2]; tris = new int[verts.Length * 3 + (verts.Length - 2) * 6]; //splits2 = GetSplits(GetPhysicsColliderCount(), 0f, 1f); for (int v = 0; v < verts.Length; v += 2) { verts[v] = splits2[v / 2].position + new Vector3(0f, 0f, GetPhysicsZDepth() * 0.5f) + GetNormal(splits2[v / 2].splinePosition) * GetPhysicsNormalOffset(); verts[v + 1] = splits2[v / 2].position + new Vector3(0f, 0f, GetPhysicsZDepth() * -0.5f) + GetNormal(splits2[v / 2].splinePosition) * GetPhysicsNormalOffset(); if (v < verts.Length - 2) { tris[tt + 0] = v + 0; tris[tt + 1] = v + 2; tris[tt + 2] = v + 1; tris[tt + 3] = v + 1; tris[tt + 4] = v + 2; tris[tt + 5] = v + 3; } else { tris[tt + 0] = v + 0; tris[tt + 1] = 0; tris[tt + 2] = v + 1; tris[tt + 3] = v + 1; tris[tt + 4] = 0; tris[tt + 5] = 1; } tt += 6; } } else { splits2 = GetSplits(GetPhysicsColliderCount(), 0f, 1f); verts = new Vector3[splits2.Length * 2 + 4]; tris = new int[verts.Length * 3 + (verts.Length - 2) * 6]; //verts = new Vector3[GetPhysicsColliderCount() * 2 + 4]; //tris = new int[verts.Length * 3 + (verts.Length - 2) * 6]; //splits2 = GetSplits(GetPhysicsColliderCount() - 1, 0f, 1f); float bottomY = GetBounds().yMin - Mathf.Clamp(GetLandscapeBottomDepth(), 1f, 100000000f); verts[0] = new Vector3(splits2[0].position.x, bottomY, GetPhysicsZDepth() * 0.5f); verts[1] = new Vector3(splits2[0].position.x, bottomY, GetPhysicsZDepth() * -0.5f); for (int v = 2; v < verts.Length - 2; v += 2) { verts[v] = splits2[(v - 2) / 2].position + new Vector3(0f, 0f, GetPhysicsZDepth() * 0.5f) + GetNormal(splits2[(v - 2) / 2].splinePosition) * GetPhysicsNormalOffset(); verts[v + 1] = splits2[(v - 2) / 2].position + new Vector3(0f, 0f, GetPhysicsZDepth() * -0.5f) + GetNormal(splits2[(v - 2) / 2].splinePosition) * GetPhysicsNormalOffset(); } for (int v = 0; v < verts.Length; v += 2) { if (v < verts.Length - 2) { tris[tt + 0] = v + 0; tris[tt + 1] = v + 2; tris[tt + 2] = v + 1; tris[tt + 3] = v + 1; tris[tt + 4] = v + 2; tris[tt + 5] = v + 3; } else { tris[tt + 0] = v + 0; tris[tt + 1] = 0; tris[tt + 2] = v + 1; tris[tt + 3] = v + 1; tris[tt + 4] = 0; tris[tt + 5] = 1; } tt += 6; } verts[verts.Length - 2] = new Vector3(splits2[splits2.Length - 1].position.x, bottomY, GetPhysicsZDepth() * 0.5f); verts[verts.Length - 1] = new Vector3(splits2[splits2.Length - 1].position.x, bottomY, GetPhysicsZDepth() * -0.5f); } Vector2[] pverts = new Vector2[verts.Length / 2]; for (int i = 0; i < pverts.Length; i++) { pverts[i] = new Vector2(verts[i * 2].x, verts[i * 2].y); } Vector2[] pverts2 = new Vector2[verts.Length / 2]; for (int i = 0; i < pverts2.Length; i++) { pverts2[i] = new Vector2(verts[i * 2 + 1].x, verts[i * 2 + 1].y); } Triangulator triangulator = new Triangulator(pverts); int[] fillTris = triangulator.Triangulate(); //for (int i = fillTris.Length - 1; i >= 0; i--) for (int i = 0; i < fillTris.Length; i++) { tris[tt++] = fillTris[i] * 2; } Triangulator triangulator2 = new Triangulator(pverts2); int[] fillTris2 = triangulator2.Triangulate(); //for (int i = 0; i < fillTris2.Length; i++) for (int i = fillTris2.Length-1; i >= 0; i--) { tris[tt++] = fillTris2[i] * 2 + 1; } MeshCollider meshCollider = gameObject.GetComponent(typeof(MeshCollider)) as MeshCollider; bool wasNull = false; if (meshCollider == null) { wasNull = true; } Mesh colMesh = null; if (wasNull) { colMesh = new Mesh(); } else { if (meshCollider.sharedMesh != null) { colMesh = meshCollider.sharedMesh; } else { colMesh = new Mesh(); } } colMesh.Clear(); colMesh.vertices = verts; colMesh.triangles = tris; colMesh.RecalculateBounds(); colMesh.RecalculateNormals(); colMesh.Optimize(); if (wasNull) { //MeshFilter filter = gameObject.GetComponent(typeof(MeshFilter)) as MeshFilter; meshCollider = gameObject.AddComponent(typeof(MeshCollider)) as MeshCollider; } meshCollider.sharedMesh = null; meshCollider.sharedMesh = colMesh; meshCollider.sharedMaterial = physicsMaterial; meshCollider.convex = GetCreateConvexMeshCollider(); } break; case Physics.OutlineMeshCollider: DestroyBoxColliders(); if (GetPhysicsColliderCount() > 2 && (GetCreatePhysicsInEditor() || Application.isPlaying)) { int splitCount = GetPhysicsColliderCount(); Vector3[] verts = new Vector3[(splitCount + 1) * 4]; int[] tris = new int[splitCount * 24]; int v = 0; for (int i = 0; i <= splitCount; i++) { float splinePos = (float)i / (float)splitCount; Vector3 normal = GetNormal(splinePos); verts[v++] = GetPosition(splinePos) + normal * GetOutlineWidth() * 0.5f + normal * GetOutlineNormalOffset() + new Vector3(0f, 0f, GetPhysicsZDepth() * 0.5f); verts[v++] = GetPosition(splinePos) + normal * GetOutlineWidth() * -0.5f + normal * GetOutlineNormalOffset() + new Vector3(0f, 0f, GetPhysicsZDepth() * 0.5f); verts[v++] = GetPosition(splinePos) + normal * GetOutlineWidth() * -0.5f + normal * GetOutlineNormalOffset() - new Vector3(0f, 0f, GetPhysicsZDepth() * 0.5f); verts[v++] = GetPosition(splinePos) + normal * GetOutlineWidth() * 0.5f + normal * GetOutlineNormalOffset() - new Vector3(0f, 0f, GetPhysicsZDepth() * 0.5f); } int t = 0; for (int i = 0; i < splitCount; i++) { tris[t++] = i * 4 + 0; tris[t++] = i * 4 + 0 + 4 + 1; tris[t++] = i * 4 + 0 + 4; tris[t++] = i * 4 + 0; tris[t++] = i * 4 + 0 + 1; tris[t++] = i * 4 + 0 + 4 + 1; tris[t++] = i * 4 + 1; tris[t++] = i * 4 + 1 + 4 + 1; tris[t++] = i * 4 + 1 + 4; tris[t++] = i * 4 + 1; tris[t++] = i * 4 + 1 + 1; tris[t++] = i * 4 + 1 + 4 + 1; tris[t++] = i * 4 + 2; tris[t++] = i * 4 + 2 + 4 + 1; tris[t++] = i * 4 + 2 + 4; tris[t++] = i * 4 + 2; tris[t++] = i * 4 + 2 + 1; tris[t++] = i * 4 + 2 + 4 + 1; tris[t++] = i * 4 + 3; tris[t++] = i * 4 + 3 + 1; tris[t++] = i * 4 + 3 + 4; tris[t++] = i * 4 + 3; tris[t++] = i * 4; tris[t++] = i * 4 + 3 + 1; /* tris[t++] = i * 4 + 0; tris[t++] = i * 4 + 0 + 4; tris[t++] = i * 4 + 0 + 4 + 1; tris[t++] = i * 4 + 0; tris[t++] = i * 4 + 0 + 4 + 1; tris[t++] = i * 4 + 0 + 1; tris[t++] = i * 4 + 1; tris[t++] = i * 4 + 1 + 4; tris[t++] = i * 4 + 1 + 4 + 1; tris[t++] = i * 4 + 1; tris[t++] = i * 4 + 1 + 4 + 1; tris[t++] = i * 4 + 1 + 1; tris[t++] = i * 4 + 2; tris[t++] = i * 4 + 2 + 4; tris[t++] = i * 4 + 2 + 4 + 1; tris[t++] = i * 4 + 2; tris[t++] = i * 4 + 2 + 4 + 1; tris[t++] = i * 4 + 2 + 1; tris[t++] = i * 4 + 3; tris[t++] = i * 4 + 3 + 4; tris[t++] = i * 4 + 3 + 1; tris[t++] = i * 4 + 3; tris[t++] = i * 4 + 3 + 1; tris[t++] = i * 4; */ } MeshCollider meshCollider = gameObject.GetComponent(typeof(MeshCollider)) as MeshCollider; bool wasNull = false; if (meshCollider == null) { wasNull = true; } Mesh colMesh = null; if (wasNull) { colMesh = new Mesh(); } else { if (meshCollider.sharedMesh != null) { colMesh = meshCollider.sharedMesh; } else { colMesh = new Mesh(); } } colMesh.Clear(); colMesh.vertices = verts; colMesh.triangles = tris; colMesh.RecalculateBounds(); colMesh.RecalculateNormals(); colMesh.Optimize(); if (wasNull) { //MeshFilter filter = gameObject.GetComponent(typeof(MeshFilter)) as MeshFilter; meshCollider = gameObject.AddComponent(typeof(MeshCollider)) as MeshCollider; } meshCollider.sharedMesh = null; meshCollider.sharedMesh = colMesh; meshCollider.sharedMaterial = physicsMaterial; meshCollider.convex = GetCreateConvexMeshCollider(); } break; } } }
public RageVertex[] GenerateEmbossVerts(bool antialiasing) { RageVertex[] splits = GetSplits(GetVertexCount(), 0f, 1f); RageVertex[] embossVerts = new RageVertex[0]; if (GetEmboss() != Emboss.None) { int vertsInBand = splits.Length; if (antialiasing) { embossVerts = new RageVertex[splits.Length * 4]; } else { embossVerts = new RageVertex[splits.Length * 2]; } Vector3 sunVector = RotatePoint2D_CCW(new Vector3(0f, -1f, 0f), GetEmbossAngleDeg() / (180f / Mathf.PI)); Vector3[] embossVectors = new Vector3[splits.Length]; Vector3[] normals = new Vector3[splits.Length]; float[] dots = new float[splits.Length]; float[] mags = new float[splits.Length]; for (int v = 0; v < splits.Length; v++) { float p = (float)v / (float)splits.Length; normals[v] = spline.GetAvgNormal(p * GetLastSplinePosition(), 0.05f, 3); if (v == splits.Length - 1) { normals[v] = normals[0]; } dots[v] = Vector3.Dot(sunVector, normals[v]); mags[v] = Mathf.Clamp01(Mathf.Abs(dots[v]) - GetEmbossOffset()); if (dots[v] > 0f) { embossVectors[v] = (sunVector - normals[v] * 2f).normalized * GetEmbossSize() * mags[v]; } else { embossVectors[v] = (sunVector + normals[v] * 2f).normalized * GetEmbossSize() * mags[v] * -1f; } } for (int v = 0; v < splits.Length; v++) { Vector3 embossVector = new Vector3(); int v2 = v; if (v == splits.Length - 1) { v2 = 0; } for (int i = -Mathf.FloorToInt(GetEmbossSmoothness()); i <= Mathf.FloorToInt(GetEmbossSmoothness()) + 1; i++) { if (i != 0) { embossVector += embossVectors[mod(v2 - i, splits.Length)] * (1f - (float)Mathf.Abs(i) / (GetEmbossSmoothness() + 1)); } else { embossVector += embossVectors[mod(v2 - i, splits.Length)]; } } embossVector *= 1f / (Mathf.FloorToInt(GetEmbossSmoothness()) * 2 + 1); if (antialiasing) { embossVerts[v + 0 * vertsInBand].position = splits[v].position - embossVector.normalized * GetAntialiasingWidth() * 1f; embossVerts[v + 1 * vertsInBand].position = splits[v].position; embossVerts[v + 2 * vertsInBand].position = splits[v].position + embossVector; embossVerts[v + 3 * vertsInBand].position = splits[v].position + embossVector + embossVector.normalized * GetAntialiasingWidth(); } else { embossVerts[v + 0 * vertsInBand].position = splits[v].position; embossVerts[v + 1 * vertsInBand].position = splits[v].position + embossVector; } if (embossVector.sqrMagnitude > 0.0001f) { if (dots[v] < 0f) { if (GetEmboss() == Emboss.Sharp) { if (antialiasing) { embossVerts[v + 0 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 2 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 3 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); } else { embossVerts[v + 0 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 1 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); } } else { if (antialiasing) { embossVerts[v + 0 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 2 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); embossVerts[v + 3 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); } else { embossVerts[v + 0 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 1 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); } } } else { if (GetEmboss() == Emboss.Sharp) { if (antialiasing) { embossVerts[v + 0 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 2 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 3 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, 0f); } else { embossVerts[v + 0 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 1 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); } } else { if (antialiasing) { embossVerts[v + 0 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 2 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, 0f); embossVerts[v + 3 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, 0f); } else { embossVerts[v + 0 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, Mathf.Clamp01(mags[v] * 4f)); embossVerts[v + 1 * vertsInBand].color = GetEmbossColor2() * new Color(1f, 1f, 1f, 0f); } } } } else { if (antialiasing) { embossVerts[v + 0 * vertsInBand].position = splits[v].position - embossVector.normalized * GetAntialiasingWidth(); embossVerts[v + 1 * vertsInBand].position = splits[v].position; embossVerts[v + 2 * vertsInBand].position = splits[v].position; embossVerts[v + 3 * vertsInBand].position = splits[v].position; } else { embossVerts[v + 0 * vertsInBand].position = splits[v].position; embossVerts[v + 1 * vertsInBand].position = splits[v].position; } if (antialiasing) { embossVerts[v + 0 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); embossVerts[v + 2 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); embossVerts[v + 3 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); } else { embossVerts[v + 0 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); embossVerts[v + 1 * vertsInBand].color = GetEmbossColor1() * new Color(1f, 1f, 1f, 0f); } } if (antialiasing) { embossVerts[v + 0 * vertsInBand].uv1 = new Vector2(0f, 0f); embossVerts[v + 1 * vertsInBand].uv1 = new Vector2(0f, 0f); embossVerts[v + 2 * vertsInBand].uv1 = new Vector2(0f, 0f); embossVerts[v + 3 * vertsInBand].uv1 = new Vector2(0f, 0f); } else { embossVerts[v + 0 * vertsInBand].uv1 = new Vector2(0f, 0f); embossVerts[v + 1 * vertsInBand].uv1 = new Vector2(0f, 0f); } } } else { embossVerts = new RageVertex[0]; } /* for (int index = 0; index < embossVerts.Length; index++) { embossVerts[index].position -= transform.forward * 0.1f; }*/ return embossVerts; }
public void GenerateTriangles(Mesh mesh, RageVertex[] fillVerts, RageVertex[] embossVerts, RageVertex[] outlineVerts, bool AAfill, bool AAemboss, bool AAoutline, bool multipleMaterials) { int[] trisIdxs = null; Vector2[] verts = new Vector2[0]; if (GetFill() != Fill.Landscape) { if (AAfill) verts = new Vector2[fillVerts.Length / 2]; else verts = new Vector2[fillVerts.Length]; for (int i = 0; i < verts.Length; i++) verts[i] = new Vector2(fillVerts[i].position.x, fillVerts[i].position.y); } trisIdxs = new int[GetOutlineTriangleCount(outlineVerts, AAoutline) * 3 + GetFillTriangleCount(fillVerts, AAfill) * 3 + GetEmbossTriangleCount(embossVerts, AAemboss) * 3]; int currentIdx = 0; int vertsPerBand = 0; int bandCount = 0; switch (GetFill()) { case Fill.None: break; case Fill.Solid: case Fill.Gradient: int[] fillTris = Triangulator.Triangulate(verts); for (int i = 0; i < fillTris.Length; i++) trisIdxs[currentIdx++] = fillTris[i]; break; case Fill.Landscape: if (AAfill) { bandCount = 2; vertsPerBand = fillVerts.Length / 3; } else { bandCount = 1; vertsPerBand = fillVerts.Length / 2; } for (int v = 0; v < vertsPerBand-1; v++) for (int b = 0; b < bandCount; b++) { trisIdxs[currentIdx++] = v + b * vertsPerBand; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand + 1; trisIdxs[currentIdx++] = v + b * vertsPerBand; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand + 1; trisIdxs[currentIdx++] = v + b * vertsPerBand + 1; } break; } int numTrisAA = 0; if (AAfill) numTrisAA += (verts.Length)*6; if (AAoutline && outlineVerts.Length != 0) numTrisAA += 2 * (outlineVerts.Length / 4 - 1) * 6; if (GetOutline() == Outline.Free && AAoutline) numTrisAA += 12; //Debug.Log("Tris aa: " + numTrisAA + " " + AAoutline + ", numVerts " + verts.Length + " outlineVertLength: " + outlineVerts.Length); int[] trisAaIdxs = new int[0]; int idxTriAA = 0; if (numTrisAA > 0) trisAaIdxs = new int[numTrisAA]; else trisAaIdxs = new int[0]; // fill antialiasing triangles if (AAfill) { vertsPerBand = verts.Length-1; //Debug.Log("AA Fill Verts Per Band: " + vertsPerBand); if (_perspectiveMode) for (int v = 0; v <= vertsPerBand; v++) { for (int b = 0; b < 1; b++) { trisAaIdxs[idxTriAA++] = v + b * vertsPerBand; trisAaIdxs[idxTriAA++] = v + (b + 1) * vertsPerBand; trisAaIdxs[idxTriAA++] = v + (b + 1) * vertsPerBand + 1; trisAaIdxs[idxTriAA++] = v + b * vertsPerBand; trisAaIdxs[idxTriAA++] = v + (b + 1) * vertsPerBand + 1; trisAaIdxs[idxTriAA++] = v + b * vertsPerBand + 1; } } else for (int v = 0; v <= vertsPerBand; v++) { for (int b = 0; b < 1; b++) { trisIdxs[currentIdx++] = v + b * vertsPerBand; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand + 1; trisIdxs[currentIdx++] = v + b * vertsPerBand; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand + 1; trisIdxs[currentIdx++] = v + b * vertsPerBand + 1; } } } if (AAemboss) { vertsPerBand = embossVerts.Length / 4; bandCount = 3; } else { vertsPerBand = embossVerts.Length / 2; bandCount = 1; } for (int v = 0; v < vertsPerBand-1; v++) for (int b = 0; b < bandCount; b++) if (v < vertsPerBand - 1) { trisIdxs[currentIdx++] = v + b * vertsPerBand + fillVerts.Length; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand + 1 + fillVerts.Length; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand + fillVerts.Length; trisIdxs[currentIdx++] = v + b * vertsPerBand + fillVerts.Length; trisIdxs[currentIdx++] = v + b * vertsPerBand + 1 + fillVerts.Length; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand + 1 + fillVerts.Length; } if (AAoutline) { vertsPerBand = outlineVerts.Length / 4; bandCount = 3; } else { vertsPerBand = outlineVerts.Length / 2; bandCount = 1; } for (int v = 0; v < vertsPerBand-1; v++) { for (int b = 0; b < bandCount; b++) { if (b == 1 || !PerspectiveMode || !AAoutline) { trisIdxs[currentIdx++] = v + b * vertsPerBand + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = v + b * vertsPerBand + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = v + b * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = v + (b + 1) * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; continue; } if (trisAaIdxs.Length != 0) { trisIdxs[currentIdx++] = 0; trisIdxs[currentIdx++] = 0; trisIdxs[currentIdx++] = 0; trisIdxs[currentIdx++] = 0; trisIdxs[currentIdx++] = 0; trisIdxs[currentIdx++] = 0; } //Debug.Log("vertsPerBand: "+vertsPerBand+" trisAALen:"+trisAA.Length); if (vertsPerBand <= 0 || trisAaIdxs.Length == 0) continue; //Debug.Log("idxTriAA: " + idxTriAA + " :: trisAA count: " + trisAA.Length + " :: vertsPerBand: " + vertsPerBand); trisAaIdxs[idxTriAA++] = v + b * vertsPerBand + embossVerts.Length + fillVerts.Length; trisAaIdxs[idxTriAA++] = v + (b + 1) * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; trisAaIdxs[idxTriAA++] = v + (b + 1) * vertsPerBand + embossVerts.Length + fillVerts.Length; trisAaIdxs[idxTriAA++] = v + b * vertsPerBand + embossVerts.Length + fillVerts.Length; trisAaIdxs[idxTriAA++] = v + b * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; trisAaIdxs[idxTriAA++] = v + (b + 1) * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; } } // Free outline AA caps if (GetOutline() == Outline.Free && AAoutline) { int vertsInBand = outlineVerts.Length / 4; trisIdxs[currentIdx++] = 0 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = vertsInBand * 2 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = vertsInBand + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = 0 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = vertsInBand * 3 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = vertsInBand * 2 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = vertsInBand * 1 - 1 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = vertsInBand * 3 - 1 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = vertsInBand * 2 - 1 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = vertsInBand * 1 - 1 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = vertsInBand * 4 - 1 + embossVerts.Length + fillVerts.Length; trisIdxs[currentIdx++] = vertsInBand * 3 - 1 + embossVerts.Length + fillVerts.Length; } if (!_perspectiveMode && multipleMaterials) { int ii = 0; int[] outlineTriangles = new int[GetOutlineTriangleCount(outlineVerts, AAoutline) * 3]; int[] restOfTriangles = new int[trisIdxs.Length - GetOutlineTriangleCount(outlineVerts, AAoutline) * 3]; mesh.subMeshCount = 2; for (; ii < restOfTriangles.Length; ii++) restOfTriangles[ii] = trisIdxs[ii]; if (GetTexturing1() == UVMapping.Fill) mesh.SetTriangles(restOfTriangles, 0); if (GetTexturing2() == UVMapping.Fill) mesh.SetTriangles(restOfTriangles, 1); for (; ii < trisIdxs.Length; ii++) outlineTriangles[ii - restOfTriangles.Length] = trisIdxs[ii]; if (GetTexturing1() == UVMapping.Outline) mesh.SetTriangles(outlineTriangles, 0); if (GetTexturing2() == UVMapping.Outline) mesh.SetTriangles(outlineTriangles, 1); } else { if (inverseTriangleDrawOrder) { int len = trisIdxs.Length; int[] triangles2 = new int[trisIdxs.Length]; for (int i = 0; i < len; i+=3) { triangles2[len - i - 3] = trisIdxs[i]; triangles2[len - i - 3 + 1] = trisIdxs[i + 1]; triangles2[len - i - 3 + 2] = trisIdxs[i + 2]; } trisIdxs = triangles2; } mesh.triangles = trisIdxs; mesh.subMeshCount = 2; mesh.SetTriangles(trisIdxs,0); mesh.SetTriangles(trisAaIdxs,1); } }
private RageVertex[] OutlineVerts(bool antialiasing, bool multipleMaterials) { RageVertex[] outlineVerts; RageVertex[] splits; if (GetOutline() == Outline.Free && GetFill() != Fill.None && GetFill() != Fill.Landscape) splits = GetSplits (GetVertexCount() - (Mathf.FloorToInt ((float) GetVertexCount() * 1f / GetPointCount())), 0f, 1f - 1f / GetPointCount()); else splits = GetSplits (GetVertexCount(), 0f, 1f); int vertsInBand = splits.Length; float uvPos = 0f; outlineVerts = antialiasing? new RageVertex[splits.Length * 4] : outlineVerts = new RageVertex[splits.Length * 2]; for (int v = 0; v < splits.Length; v++) { float edgeWidth = GetOutlineWidth (splits[v].splinePosition * GetLastSplinePosition()); float AAWidth = GetAntialiasingWidth (splits[v].splinePosition * GetLastSplinePosition()); Vector3 normal = OutlineVertsCheckCorner(splits, v, ref edgeWidth); if (v > 0) uvPos += (splits[v].position - splits[v - 1].position).magnitude; Vector3 scaledNormal = ScaleToLocal (normal.normalized); Vector3 normalizedNormal = normal.normalized; var normalOffset = GetOutlineNormalOffset(); outlineVerts = OutlineVertsProcessSplit(antialiasing, scaledNormal, vertsInBand, edgeWidth, normalOffset, normalizedNormal, outlineVerts, v, normal, splits, AAWidth); Color outlineCol1 = DefaultSolidColor; Color outlineCol2 = DefaultSolidColor; switch (GetOutlineGradient()) { case OutlineGradient.None: outlineCol1 = GetOutlineColor1(); outlineCol2 = GetOutlineColor1(); break; case OutlineGradient.Default: outlineCol1 = GetOutlineColor1(); outlineCol2 = GetOutlineColor2(); break; case OutlineGradient.Inverse: outlineCol1 = GetOutlineColor2(); outlineCol2 = GetOutlineColor1(); break; } if (antialiasing) { outlineVerts[v + 0 * vertsInBand].color = outlineCol2 * DefaultTransparentColor; outlineVerts[v + 1 * vertsInBand].color = outlineCol2 * DefaultSolidColor; outlineVerts[v + 2 * vertsInBand].color = outlineCol1 * DefaultSolidColor; outlineVerts[v + 3 * vertsInBand].color = outlineCol1 * DefaultTransparentColor; } else { outlineVerts[v + 0 * vertsInBand].color = outlineCol2 * DefaultSolidColor; outlineVerts[v + 1 * vertsInBand].color = outlineCol1 * DefaultSolidColor; } float AAWidthRelatedToEdgeWidth = 0f; if (AAWidth > 0f && edgeWidth > 0f && antialiasing) AAWidthRelatedToEdgeWidth = AAWidth / edgeWidth; if (!multipleMaterials) { OutlineVertsSingleMaterial(antialiasing, uvPos, AAWidthRelatedToEdgeWidth, outlineVerts, v, vertsInBand); } else { if (antialiasing) { outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 1f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 1f - AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 2 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 3 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 0f); } else { outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 0.99f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 0.01f); } } } return outlineVerts; }
private RageVertex[] GetSplits(int vertCount, float start, float end) { RageVertex[] splitsFixed = new RageVertex[vertCount]; for (int v=0; v<vertCount; v++) { splitsFixed[v].splinePosition = ((float)v / (float)(vertCount)) * (end-start) + start; if (outline == Outline.Free && v == vertCount-1) { splitsFixed[v].position = spline.GetPoint(splitsFixed[v].splinePosition-0.2f/(float)vertCount); } else { splitsFixed[v].position = spline.GetPoint(splitsFixed[v].splinePosition); } splitsFixed[v].color = new Color(1f, 1f, 1f, 1f); splitsFixed[v].uv = new Vector2(0f, 0f); } return splitsFixed; }
public RageVertex[] GenerateOutlineVerts(bool antialiasing, bool multipleMaterials) { RageVertex[] outlineVerts; if (GetOutline() == Outline.None) outlineVerts = new RageVertex[0]; else outlineVerts = OutlineVerts (antialiasing, multipleMaterials); for (int index = 0; index < outlineVerts.Length; index++) outlineVerts[index].position += outlineOffset; return outlineVerts; }
private int[] GenerateTriangles(RageVertex[] fillVerts, RageVertex[] embossVerts, RageVertex[] outlineVerts) { int[] tris = null; Vector2[] verts = new Vector2[0]; if (outline == Outline.None) { verts = new Vector2[fillVerts.Length/2]; } else { verts = new Vector2[fillVerts.Length]; } for (int i = 0; i < verts.Length; i++) { verts[i] = new Vector2(fillVerts[i].position.x, fillVerts[i].position.y); } Triangulator triangulator = new Triangulator(verts); int t = 0; int[] fillTris = triangulator.Triangulate(); if (outline == Outline.None) { tris = new int[((embossVerts.Length / 4) * 6 + (outlineVerts.Length / 4) * 6 + (fillVerts.Length / 2) * 2) * 3 + fillTris.Length]; } else { if (outline == Outline.Loop) { tris = new int[((outlineVerts.Length / 4) * 6 + (embossVerts.Length / 4) * 6 + (outlineVerts.Length / 4) * 6) * 3 + fillTris.Length]; } else { tris = new int[(((outlineVerts.Length-1) / 4) * 6 + (embossVerts.Length / 4) * 6 + (outlineVerts.Length / 4) * 6) * 3 + fillTris.Length]; } } for (int i = 0; i < fillTris.Length; i++) { tris[t++] = fillTris[i]; } int vertsPerBand = 0; if (outline == Outline.None) { vertsPerBand = verts.Length; for (int v = 0; v < vertsPerBand; v++) { for (int b = 0; b < 1; b++) { if (v < vertsPerBand - 1) { tris[t++] = v + b * vertsPerBand; tris[t++] = v + (b + 1) * vertsPerBand + 1; tris[t++] = v + (b + 1) * vertsPerBand; tris[t++] = v + b * vertsPerBand; tris[t++] = v + b * vertsPerBand + 1; tris[t++] = v + (b + 1) * vertsPerBand + 1; } else { tris[t++] = v + b * vertsPerBand; tris[t++] = (b + 1) * vertsPerBand; tris[t++] = v + (b + 1) * vertsPerBand; tris[t++] = v + b * vertsPerBand; tris[t++] = b * vertsPerBand; tris[t++] = (b + 1) * vertsPerBand; } } } } vertsPerBand = embossVerts.Length / 4; for (int v = 0; v < vertsPerBand; v++) { for (int b = 0; b < 3; b++) { if (v < vertsPerBand - 1) { tris[t++] = v + b * vertsPerBand + fillVerts.Length; tris[t++] = v + (b + 1) * vertsPerBand + 1 + fillVerts.Length; tris[t++] = v + (b + 1) * vertsPerBand + fillVerts.Length; tris[t++] = v + b * vertsPerBand + fillVerts.Length; tris[t++] = v + b * vertsPerBand + 1 + fillVerts.Length; tris[t++] = v + (b + 1) * vertsPerBand + 1 + fillVerts.Length; } else { tris[t++] = v + b * vertsPerBand + fillVerts.Length; tris[t++] = (b + 1) * vertsPerBand + fillVerts.Length; tris[t++] = v + (b + 1) * vertsPerBand + fillVerts.Length; tris[t++] = v + b * vertsPerBand + fillVerts.Length; tris[t++] = b * vertsPerBand + fillVerts.Length; tris[t++] = (b + 1) * vertsPerBand + fillVerts.Length; } } } vertsPerBand = outlineVerts.Length / 4; for (int v = 0; v < vertsPerBand; v++) { for (int b = 0; b < 3; b++) { if (v < vertsPerBand - 1) { tris[t++] = v + b * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[t++] = v + (b + 1) * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; tris[t++] = v + (b + 1) * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[t++] = v + b * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[t++] = v + b * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; tris[t++] = v + (b + 1) * vertsPerBand + 1 + embossVerts.Length + fillVerts.Length; } else { if (outline == Outline.Loop) { tris[t++] = v + b * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[t++] = (b + 1) * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[t++] = v + (b + 1) * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[t++] = v + b * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[t++] = b * vertsPerBand + embossVerts.Length + fillVerts.Length; tris[t++] = (b + 1) * vertsPerBand + embossVerts.Length + fillVerts.Length; } } } } return tris; }
private RageVertex[] GenerateOutlineVerts() { RageVertex[] outlineVerts = new RageVertex[0]; if (outline != Outline.None && outlineVertexCount > 2) { RageVertex[] splits = null; if (outline == Outline.Loop) { splits = GetSplits(outlineVertexCount, 0f, 1f); } else { splits = GetSplits(outlineVertexCount, 0f, (float)(spline.points.Length - 1) / (float)spline.points.Length + 1f / (float)outlineVertexCount); } int vertsInBand = splits.Length; outlineVerts = new RageVertex[splits.Length * 4]; for (int v = 0; v < splits.Length; v++) { Vector3 normal = new Vector3(); if (v == splits.Length - 1 && outline == Outline.Free) { normal = spline.GetNormal(splits[v-1].splinePosition, new Vector3(0f, 0f, -1f), true); } else { normal = spline.GetNormal(splits[v].splinePosition, new Vector3(0f, 0f, -1f), true); } Vector3 scaledNormal = ScaleToLocal(normal); float edgeWidth = spline.GetWidth(splits[v].splinePosition) * OutlineWidth; if (fill == Fill.None) { outlineVerts[v + 0 * vertsInBand].position = splits[v].position + scaledNormal * AntiAliasingWidth + normal * edgeWidth * 0.5f; outlineVerts[v + 1 * vertsInBand].position = splits[v].position + normal * edgeWidth * 0.5f; outlineVerts[v + 2 * vertsInBand].position = splits[v].position - normal * edgeWidth * 0.5f; outlineVerts[v + 3 * vertsInBand].position = splits[v].position - scaledNormal * AntiAliasingWidth - normal * edgeWidth * 0.5f; } else { outlineVerts[v + 0 * vertsInBand].position = splits[v].position + scaledNormal * AntiAliasingWidth + normal * edgeWidth; outlineVerts[v + 1 * vertsInBand].position = splits[v].position + normal * edgeWidth; outlineVerts[v + 2 * vertsInBand].position = splits[v].position; outlineVerts[v + 3 * vertsInBand].position = splits[v].position - scaledNormal * AntiAliasingWidth; } outlineVerts[v + 0 * vertsInBand].color = outlineColor1 * new Color(1f, 1f, 1f, 0f); outlineVerts[v + 1 * vertsInBand].color = outlineColor1 * new Color(1f, 1f, 1f, 1f); outlineVerts[v + 2 * vertsInBand].color = outlineColor1 * new Color(1f, 1f, 1f, 1f); outlineVerts[v + 3 * vertsInBand].color = outlineColor1 * new Color(1f, 1f, 1f, 0f); outlineVerts[v + 0 * vertsInBand].uv = new Vector2(0f, 0f); outlineVerts[v + 1 * vertsInBand].uv = new Vector2(0f, 0f); outlineVerts[v + 2 * vertsInBand].uv = new Vector2(0f, 0f); outlineVerts[v + 3 * vertsInBand].uv = new Vector2(0f, 0f); } } else { outlineVerts = new RageVertex[0]; } return outlineVerts; }
private RageVertex[] GenerateFillVerts() { RageVertex[] fillVerts = new RageVertex[0]; if (fill != Fill.None && fillVertexCount > 2) { RageVertex[] splits = GetSplits(fillVertexCount, 0f, 1f); if (outline == Outline.None) { fillVerts = new RageVertex[splits.Length * 2]; } else { fillVerts = new RageVertex[splits.Length]; } for (int v = 0; v < splits.Length; v++) { Vector3 normal = spline.GetNormal(splits[v].splinePosition, new Vector3(0f, 0f, -1f), true); Vector3 scaledNormal = ScaleToLocal(normal); if (outline == Outline.None) { fillVerts[v].position = splits[v].position; fillVerts[v + splits.Length].position = splits[v].position + scaledNormal * AntiAliasingWidth; fillVerts[v].color = GetFillColor(fillVerts[v].position); fillVerts[v + splits.Length].color = GetFillColor(fillVerts[v + splits.Length].position) * new Color(1f, 1f, 1f, 0f); fillVerts[v].uv = GetFillUV(fillVerts[v].position, normal, splits[v].splinePosition); fillVerts[v + splits.Length].uv = GetFillUV(fillVerts[v + splits.Length].position, normal, splits[v].splinePosition); } else { fillVerts[v].position = splits[v].position + scaledNormal * (spline.GetWidth(splits[v].splinePosition) * OutlineWidth * 0.2f); fillVerts[v].color = GetFillColor(fillVerts[v].position); fillVerts[v].uv = GetFillUV(fillVerts[v].position, normal, splits[v].splinePosition); } } } return fillVerts; }
public int GetOutlineTriangleCount(RageVertex[] outlineVerts, bool AAoutline) { if (GetOutline() != Outline.None) { if (AAoutline) { if (GetOutline() == Outline.Free) { return ((outlineVerts.Length / 4) - 1) * 6 + 4; } else { return ((outlineVerts.Length / 4) - 1) * 6; } } else { return outlineVerts.Length - 2; } } else { return 0; } }
private Vector3 OutlineVertsCheckCorner(RageVertex[] splits, int v, ref float edgeWidth) { Vector3 normal; if (corners != Corner.Beak) { if (GetFill() != Fill.Landscape) normal = GetNormal (splits[v].splinePosition); else { normal = Vector3.up * GetLandscapeOutlineAlign() + GetNormal (splits[v].splinePosition) * (1f - GetLandscapeOutlineAlign()); normal.Normalize(); } } else { if ((outline != Outline.Free) || (v < splits.Length - 1 && v > 0)) { normal = FindNormal (splits[GetIndex (v - 1, splits.Length)].position, splits[v].position, splits[GetIndex (v + 1, splits.Length)].position, edgeWidth); normal *= -1; edgeWidth = 1f; } else { if ((v < splits.Length - 1 && v > 0)) normal = GetNormal (splits[v].splinePosition * GetLastSplinePosition()); else { if (v == 0) { normal = FindNormal (splits[0].position + (splits[0].position - splits[1].position), splits[0].position, splits[1].position, edgeWidth); normal *= -1; edgeWidth = 1f; } else { normal = FindNormal (splits[splits.Length - 1].position + (splits[splits.Length - 1].position - splits[splits.Length - 2].position), splits[splits.Length - 1].position, splits[splits.Length - 2].position, edgeWidth); edgeWidth = 1f; } } } if (normal.magnitude > this.maxBeakLength * this.OutlineWidth) normal = normal.normalized * this.maxBeakLength * this.OutlineWidth; } return normal; }
public RageVertex[] GetSplits(int vertCount, float start, float end) { RageVertex[] splits = new RageVertex[vertCount+1]; for (int v = 0; v < splits.Length; v++) { splits[v].splinePosition = Mathf.Clamp01(((float)v / (float)(vertCount)) * (end-start) + start); if (Mathf.Approximately(splits[v].splinePosition, 1f) && !SplineIsOpenEnded()) { splits[v].splinePosition = 0f; } splits[v].splineSegmentPosition = spline.GetSegmentPosition(splits[v].splinePosition); splits[v].position = GetPosition(splits[v].splinePosition); splits[v].curveStart = spline.points[spline.GetFloorIndex(splits[v].splinePosition)]; splits[v].curveEnd = spline.points[spline.GetCeilIndex(splits[v].splinePosition)]; splits[v].color = new Color(1f, 1f, 1f, 1f); } if (GetOptimize()) { splits = Optimize(splits); } if (splits.Length != vertCount) { //Debug.Log("splits.length:" + splits.Length + ", vertCount:" + vertCount); } return splits; }
private RageVertex[] OutlineVertsProcessSplit(bool antialiasing, Vector3 scaledNormal, int vertsInBand, float edgeWidth, float outlineNormalOffset, Vector3 normalizedNormal, RageVertex[] outlineVerts, int v, Vector3 normal, RageVertex[] splits, float AAWidth) { Vector3 normalizedEdgeWidth = Mathfx.Mult(normal, edgeWidth, 0.5f); if (antialiasing) { Vector3 freeLineCapTangent; if (v == 0 && GetOutline() == Outline.Free) freeLineCapTangent = Vector3.Cross(normal, Mathfx.Mult(Vector3.back, AAWidth)); else if (v == splits.Length - 1 && GetOutline() == Outline.Free) freeLineCapTangent = Vector3.Cross(normal, Mathfx.Mult(Vector3.back, -AAWidth)); else freeLineCapTangent = Vector3.zero; Vector3 normalizedOutlineNormal = Mathfx.Mult(normalizedNormal, outlineNormalOffset); Vector3 normalizedAaWidth = Mathfx.Mult(scaledNormal, AAWidth); outlineVerts[v + 0 * vertsInBand].position = Mathfx.Add(splits[v].position, normalizedAaWidth, normalizedEdgeWidth, normalizedOutlineNormal, freeLineCapTangent) + outlineAaOffset; outlineVerts[v + 1 * vertsInBand].position = Mathfx.Add(splits[v].position, normalizedEdgeWidth, normalizedOutlineNormal); outlineVerts[v + 2 * vertsInBand].position = splits[v].position - normalizedEdgeWidth + normalizedOutlineNormal; outlineVerts[v + 3 * vertsInBand].position = splits[v].position - normalizedAaWidth - normalizedEdgeWidth + Mathfx.Add(normalizedOutlineNormal, freeLineCapTangent) + outlineAaOffset; } else { Vector3 outlineOffset = Mathfx.Mult(normal, outlineNormalOffset); outlineVerts[v + 0 * vertsInBand].position = Mathfx.Add(splits[v].position, normalizedEdgeWidth, outlineOffset); outlineVerts[v + 1 * vertsInBand].position = splits[v].position - normalizedEdgeWidth + outlineOffset; } return outlineVerts; }
private RageVertex[] Optimize(RageVertex[] array) { BitArray toRemove = new BitArray(array.Length, false); int removeCount = 0; // check i-th vertex if we can remove it // if we can - remove it, and check next int prev = 0; for (int i = 1; i < array.Length - 1; i++) { Vector3 a = array[prev].position; Vector3 v = array[i].position; Vector3 b = array[i + 1].position; Vector3 v1 = a - v; Vector3 v2 = b - v; float acos = Vector3.Dot(v1, v2) / (v1.magnitude * v2.magnitude); float dif = 180.0f - Mathf.Rad2Deg * Mathf.Acos(acos); //Debug.Log(dif); if (dif < GetOptimizeAngle()) { toRemove[i] = true; removeCount++; } else { prev = i; } } if (removeCount == 0) { return array; } RageVertex[] result = new RageVertex[array.Length - removeCount]; // copy int index = 0; for (int i = 0; i < result.Length; i++) { while(toRemove[index]) { index++; } result[i] = array[index]; index++; } //Debug.Log(array.Length + " / " + result.Length); return result; }
private void OutlineVertsSingleMaterial(bool antialiasing, float uvPos, float AAWidthRelatedToEdgeWidth, RageVertex[] outlineVerts, int v, int vertsInBand) { switch (GetTexturing1()) { case UVMapping.None: case UVMapping.Fill: outlineVerts[v + 0 * vertsInBand].uv1 = Vector2.zero; outlineVerts[v + 1 * vertsInBand].uv1 = Vector2.zero; if (antialiasing) { outlineVerts[v + 2 * vertsInBand].uv1 = Vector2.zero; outlineVerts[v + 3 * vertsInBand].uv1 = Vector2.zero; } break; case UVMapping.Outline: if (antialiasing) { outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 1f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 1f - AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 2 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 3 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 0f); } else { outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 1f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 0f); } break; } switch (GetTexturing2()) { case UVMapping.None: case UVMapping.Fill: if (antialiasing) { outlineVerts[v + 0 * vertsInBand].uv2 = Vector2.zero; outlineVerts[v + 1 * vertsInBand].uv2 = Vector2.zero; outlineVerts[v + 2 * vertsInBand].uv2 = Vector2.zero; outlineVerts[v + 3 * vertsInBand].uv2 = Vector2.zero; } else { outlineVerts[v + 0 * vertsInBand].uv2 = Vector2.zero; outlineVerts[v + 1 * vertsInBand].uv2 = Vector2.zero; } break; case UVMapping.Outline: if (antialiasing) { outlineVerts[v + 0 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 1f); outlineVerts[v + 1 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 1f - AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 2 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), AAWidthRelatedToEdgeWidth * 0.5f); outlineVerts[v + 3 * vertsInBand].uv1 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 0f); } else { outlineVerts[v + 0 * vertsInBand].uv2 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 0.99f); outlineVerts[v + 1 * vertsInBand].uv2 = new Vector2 (uvPos / GetOutlineTexturingScaleInv(), 0.01f); } break; } }
public RageVertex[] GenerateFillVerts(bool antialiasing, bool multipleMaterials) { RageVertex[] fillVerts = new RageVertex[0]; switch(GetFill()) { case Fill.None: break; case Fill.Solid: case Fill.Gradient: RageVertex[] splits = GetSplits(GetVertexCount()-1, 0f, 1f - 1f/GetVertexCount()); if (antialiasing) { fillVerts = new RageVertex[splits.Length * 2]; } else { fillVerts = new RageVertex[splits.Length]; } for (int v = 0; v < splits.Length; v++) { Vector3 normal = GetNormal(splits[v].splinePosition); Vector3 scaledNormal = ScaleToLocal(normal); if (antialiasing) { fillVerts[v].position = splits[v].position; fillVerts[v + splits.Length].position = splits[v].position + scaledNormal * GetAntialiasingWidth(); fillVerts[v].color = GetFillColor(fillVerts[v].position); fillVerts[v + splits.Length].color = GetFillColor(fillVerts[v + splits.Length].position) * new Color(1f, 1f, 1f, 0f); } else { fillVerts[v].position = splits[v].position; fillVerts[v].color = GetFillColor(fillVerts[v].position); } if (!multipleMaterials) { switch (GetTexturing1()) { case UVMapping.None: case UVMapping.Outline: fillVerts[v].uv1 = new Vector2(0f, 0f); break; case UVMapping.Fill: fillVerts[v].uv1 = GetFillUV(fillVerts[v].position); if (antialiasing) { fillVerts[v + splits.Length].uv1 = GetFillUV(fillVerts[v + splits.Length].position); } break; } switch (GetTexturing2()) { case UVMapping.None: case UVMapping.Outline: fillVerts[v].uv2 = new Vector2(0f, 0f); break; case UVMapping.Fill: fillVerts[v].uv2 = GetFillUV2(fillVerts[v].position); if (antialiasing) { fillVerts[v + splits.Length].uv2 = GetFillUV2(fillVerts[v + splits.Length].position); } break; } } else { fillVerts[v].uv1 = GetFillUV(fillVerts[v].position); if (antialiasing) { fillVerts[v + splits.Length].uv1 = GetFillUV(fillVerts[v + splits.Length].position); } } } break; case Fill.Landscape: RageVertex[] splits2 = GetSplits(GetVertexCount(), 0f, 1f); float bottomY = GetBounds().yMin - Mathf.Clamp(GetLandscapeBottomDepth(), 1f, 100000000f);; if (antialiasing) { fillVerts = new RageVertex[splits2.Length * 3]; } else { fillVerts = new RageVertex[splits2.Length * 2]; } for (int v = 0; v < splits2.Length; v++) { Vector3 normal = GetNormal(splits2[v].splinePosition); Vector3 scaledNormal = ScaleToLocal(normal); if (antialiasing) { fillVerts[v].position = new Vector3(splits2[v].position.x, bottomY); fillVerts[v + splits2.Length].position = splits2[v].position; fillVerts[v + splits2.Length * 2].position = splits2[v].position + scaledNormal * GetAntialiasingWidth(); fillVerts[v].color = GetFillColor2(); fillVerts[v + splits2.Length].color = GetFillColor1(); fillVerts[v + splits2.Length * 2].color = GetFillColor1()*new Color(1f, 1f, 1f, 0f); } else { fillVerts[v].position = new Vector3(splits2[v].position.x, bottomY); fillVerts[v + splits2.Length].position = splits2[v].position; fillVerts[v].color = GetFillColor2(); fillVerts[v + splits2.Length].color = GetFillColor1(); } if (!multipleMaterials) { switch (GetTexturing1()) { case UVMapping.None: case UVMapping.Outline: fillVerts[v].uv1 = new Vector2(0f, 0f); fillVerts[v + splits2.Length].uv1 = new Vector2(0f, 0f); if (antialiasing) { fillVerts[v + splits2.Length * 2].uv1 = new Vector2(0f, 0f); } break; case UVMapping.Fill: fillVerts[v].uv1 = GetFillUV(fillVerts[v].position); fillVerts[v + splits2.Length].uv1 = GetFillUV(fillVerts[v + splits2.Length].position); if (antialiasing) { fillVerts[v + splits2.Length * 2].uv1 = GetFillUV(fillVerts[v + splits2.Length * 2].position); } break; } switch (GetTexturing2()) { case UVMapping.None: case UVMapping.Outline: fillVerts[v].uv2 = new Vector2(0f, 0f); fillVerts[v + splits2.Length].uv2 = new Vector2(0f, 0f); if (antialiasing) { fillVerts[v + splits2.Length * 2].uv2 = new Vector2(0f, 0f); } break; case UVMapping.Fill: fillVerts[v].uv2 = GetFillUV(fillVerts[v].position); fillVerts[v + splits2.Length].uv2 = GetFillUV(fillVerts[v + splits2.Length].position); if (antialiasing) { fillVerts[v + splits2.Length * 2].uv2 = GetFillUV(fillVerts[v + splits2.Length * 2].position); } break; } } else { fillVerts[v].uv1 = GetFillUV(fillVerts[v].position); fillVerts[v + splits2.Length].uv1 = GetFillUV(fillVerts[v + splits2.Length].position); if (antialiasing) { fillVerts[v + splits2.Length * 2].uv1 = GetFillUV(fillVerts[v + splits2.Length * 2].position); } } } break; } return fillVerts; }
public void RefreshPhysics(bool forcePhysics) { if (createPhysicsInEditor || Application.isPlaying) { if (boxColliders == null) { boxColliders = new BoxCollider[1]; } if (physics != Physics.None && physicsColliderCount > 2) { if (lastPhysicsVertsCount != physicsColliderCount || boxColliders[0] == null || forcePhysics) { DestroyPhysicsChildren(); RageVertex[] splits = new RageVertex[0]; if (outline == Outline.Free && fill == Fill.None) { splits = GetSplits(physicsColliderCount + 1, 0f, (float)(spline.points.Length - 1) / (float)spline.points.Length); } else { splits = GetSplits(physicsColliderCount, 0f, 1f); } boxColliders = new BoxCollider[splits.Length]; int t = 0; if (outline == Outline.Free && fill == Fill.None) { t = splits.Length - 1; } else { t = splits.Length; } float outlineW = 0f; if (outline != Outline.None) { if (fill != Fill.None) { outlineW = OutlineWidth; } else { outlineW = OutlineWidth*0.5f; } } for (int i = 0; i < t; i++) { GameObject newObj = new GameObject(); newObj.name = "ZZZ_" + gameObject.name + "_BoxCollider"; newObj.transform.parent = transform; BoxCollider box = newObj.AddComponent(typeof(BoxCollider)) as BoxCollider; box.material = physicsMaterial; int i2 = mod(i + 1, splits.Length); Vector3 norm = spline.GetNormal(splits[i].splinePosition, new Vector3(0f, 0f, -1f), true); Vector3 norm2 = spline.GetNormal(splits[i2].splinePosition, new Vector3(0f, 0f, -1f), true); Vector3 pos = splits[i].position + norm * (outlineW * spline.GetWidth(splits[i].splinePosition) + 0.5f + AntiAliasingWidth * 0.5f); Vector3 pos2 = splits[i2].position + norm2 * (outlineW * spline.GetWidth(splits[i2].splinePosition) + 0.5f + AntiAliasingWidth * 0.5f); newObj.transform.localPosition = (pos + pos2) * 0.5f - 0.5f * norm; newObj.transform.LookAt(transform.TransformPoint(newObj.transform.localPosition + Vector3.Cross((pos2 - pos).normalized, new Vector3(0f, 0f, -1f))), new Vector3(1f, 0f, 0f)); newObj.transform.localScale = new Vector3(100f, (pos2 - pos).magnitude, 1f); boxColliders[i] = box; } } else { float outlineW = 0f; if (outline != Outline.None) { outlineW = OutlineWidth; } int i = 0; RageVertex[] splits = new RageVertex[0]; if (outline == Outline.Free && fill == Fill.None) { splits = GetSplits(physicsColliderCount, 0f, (float)(spline.points.Length - 1) / (float)spline.points.Length + 1f / (float)physicsColliderCount); } else { splits = GetSplits(physicsColliderCount, 0f, 1f); } foreach (BoxCollider obj in boxColliders) { //obj.material = physicsMaterial; obj.material = physicsMaterial; int i2 = mod(i + 1, physicsColliderCount); Vector3 norm = spline.GetNormal(splits[i].splinePosition, new Vector3(0f, 0f, -1f), true); Vector3 norm2 = spline.GetNormal(splits[i2].splinePosition, new Vector3(0f, 0f, -1f), true); Vector3 pos = splits[i].position + norm * (outlineW * spline.GetWidth(splits[i].splinePosition) + 0.5f + AntiAliasingWidth * 0.5f); Vector3 pos2 = splits[i2].position + norm2 * (outlineW * spline.GetWidth(splits[i2].splinePosition) + 0.5f + AntiAliasingWidth * 0.5f); obj.gameObject.transform.localPosition = (pos + pos2) * 0.5f - 0.5f * norm; obj.gameObject.transform.LookAt(transform.TransformPoint(obj.gameObject.transform.localPosition + Vector3.Cross((pos2 - pos).normalized, new Vector3(0f, 0f, -1f))), new Vector3(1f, 0f, 0f)); obj.gameObject.transform.localScale = new Vector3(100f, (pos2 - pos).magnitude, 1f); i++; } lastPhysicsVertsCount = physicsColliderCount; } } else { DestroyPhysicsChildren(); } } else { DestroyPhysicsChildren(); } }