public MeshVertices GetMesh_Vertices_Shape(Transform transform) { if (mesh_shape_vertices == null) { Mesh mesh = GetMesh_Shape(); mesh_shape_vertices = new MeshVertices(); if (mesh != null) { MeshVertice vertice; int triangleCount = mesh.triangles.GetLength(0); for (int i = 0; i < triangleCount; i = i + 3) { vertice = new MeshVertice(); vertice.a = new Vector2D(transform.TransformPoint(mesh.vertices [mesh.triangles [i]])); vertice.b = new Vector2D(transform.TransformPoint(mesh.vertices [mesh.triangles [i + 1]])); vertice.c = new Vector2D(transform.TransformPoint(mesh.vertices [mesh.triangles [i + 2]])); mesh_shape_vertices.list.Add(vertice); } } } return(mesh_shape_vertices); }
/// <summary> /// Apply all the mest details to the object /// </summary> /// <param name="baseobject">The object to add the mesh too</param> public void ApplyMeshDetails(GameObject baseobject) { #if DEBUG CenterMesh(baseobject); Mesh mesh = new Mesh(); mesh.name = baseobject.name + "Mesh"; baseobject.GetComponent <MeshFilter>().mesh = mesh; mesh.vertices = MeshVertices.ToArray(); mesh.uv = MeshUVs.ToArray(); // Create the material and assign triangles Renderer r = baseobject.GetComponent <Renderer>(); List <Material> materials = new List <Material>(); int count = 0; mesh.subMeshCount = _meshMaterialsTriangles.Count; foreach (MaterialFrequency mf in RoadConstructorHelper.MaterialFrequencySet.GetDetails) { int[] tris = GetTriangles(mf.Material.name).ToArray(); if (tris.Length == 0) { continue; } materials.Add(mf.Material); mesh.SetTriangles(tris, count++); } mesh.subMeshCount = count; // just in case we didn't add all of them r.materials = materials.ToArray(); mesh.RecalculateNormals(); mesh.RecalculateTangents(); mesh.RecalculateBounds(); if (RoadConstructorHelper.Lighting.BakedLighting) { if (count != 0) { UnwrapParam up = new UnwrapParam(); up.hardAngle = RoadConstructorHelper.Lighting.HardAngle; up.packMargin = RoadConstructorHelper.Lighting.PackMargin; up.angleError = RoadConstructorHelper.Lighting.AngleError; up.areaError = RoadConstructorHelper.Lighting.AngleError; Unwrapping.GenerateSecondaryUVSet(mesh, up); } } #if UNITY_5_5_OR_NEWER #if UNITY_EDITOR UnityEditor.MeshUtility.Optimize(mesh); #endif #else mesh.Optimize(); #endif #endif }
public void Cleanup() { MeshVertices.Clear(); IndexBuffer.Clear(); ClusterDatas.Clear(); ResourceState.ResourceSize = 0; }
public Character(TMP_CharacterInfo characterInfo, TMP_MeshInfo meshInfo) { vertexIndex = characterInfo.vertexIndex; baseVertices = new MeshVertices( topLeft: meshInfo.vertices[vertexIndex + 1], topRight: meshInfo.vertices[vertexIndex + 2], bottomLeft: meshInfo.vertices[vertexIndex + 0], bottomRight: meshInfo.vertices[vertexIndex + 3] ); }
/// <summary> /// Loads a COLLADA section /// </summary> /// <param name="reader">XML reader</param> public override object LoadSection( XmlReader reader ) { Hashtable sources = new Hashtable( ); MeshVertices vertices = null; MeshPolygons polygons = null; while ( reader.Read( ) && reader.NodeType != XmlNodeType.EndElement ) { if ( reader.NodeType != XmlNodeType.Element ) { continue; } switch ( reader.Name ) { case "source": { sources[ reader.GetAttribute( "id" ) ] = new MeshSource( reader ); break; } case "vertices": { vertices = new MeshVertices( reader, sources ); break; } case "polygons": { polygons = new MeshPolygons( reader, false, false ); break; } case "triangles": { polygons = new MeshPolygons( reader, true, false ); break; } default: { ReadPastElement( reader ); break; } } } return BuildMesh( vertices, polygons ); }
public void ResetWorld() { // Only If Shape Changed polygons_collider_world_pair = null; polygons_collider_world = null; mesh_collider_vertices = null; ///////////////////////////////////////////// polygons_shape_world_pair = null; polygons_shape_world = null; mesh_shape_vertices = null; }
internal PartFactory(CraftFactory craft, NodeCollection shipPart) { Craft = craft; ShipPart = shipPart; hardpointFactory = new HardpointFactory(craft); // Fetch ship part top level data descriptor = ShipPart.Children.OfType <PartDescriptor <Vector3> >().First(); rotationInfo = ShipPart.Children.OfType <RotationInfo <Vector3> >().First(); verts = ShipPart.OfType <MeshVertices <Vector3> >().First(); vertUV = ShipPart.OfType <VertexUV <Vector2> >().First(); vertNormals = ShipPart.OfType <VertexNormals <Vector3> >().First(); // All meshes are contained inside of a MeshLod // There is only one MeshLod per part. // Each LOD is BranchNode containing a collection of meshes and textures it uses. var lodNode = ShipPart.OfType <LodCollection>().First(); _lods = new List <LodFactory>(); int newLodIndex = 0; for (int i = 0; i < lodNode.MaxRenderDistance.Count; i++) { float distance = lodNode.MaxRenderDistance[i]; // Out of order LODs are probably broken. See TIE98 CAL.OPT. // If this distance is greater than the previous distance (smaller number means greater render distance), // then this LOD is occluded by the previous LOD. if (distance > 0 && i > 0 && distance > lodNode.MaxRenderDistance[i - 1]) { continue; } if (lodNode.Children[i] is NodeCollection branch) { _lods.Add(new LodFactory(this, branch, newLodIndex, distance)); newLodIndex++; } else { Debug.LogError("Skipping LOD" + newLodIndex + " as it is not a NodeCollection"); } } }
private void CreateVerticesAroundPoints() { double oneSegmentSpacing = (2 * Math.PI) / MeshCircleCount; for (int i = 0; i < Vertices.Count; i++) { List <Vector3> cV = new List <Vector3>(); double currVal = 0; for (int j = 0; j < MeshCircleCount; j++) { cV.Add(GetRotatedVectorThatRepresentsPartOfCircle( Vertices[(i == 0) ? Vertices.Count - 1 : i - 1], Vertices[i], Vertices[(i == Vertices.Count - 1) ? 0 : i + 1], currVal)); currVal += oneSegmentSpacing; } MeshVertices.Add(cV); } }
/// <summary> /// Calculate the flat surface normal for a given quad. /// </summary> /// <param name="coordinateReferenceTuple"></param> /// <param name="verts"></param> /// <returns></returns> private static Vector3 GetFaceNormal(CoordinateReferenceTuple coordinateReferenceTuple, MeshVertices <Vector3> verts) { // I'm not aware of any models that have non-planar quads, so just steal unity example code :) Vector3 a = verts.Vertices[coordinateReferenceTuple[1]]; Vector3 b = verts.Vertices[coordinateReferenceTuple[0]]; Vector3 c = verts.Vertices[coordinateReferenceTuple[2]]; var side1 = b - a; var side2 = c - a; return(Vector3.Cross(side1, side2).normalized); }
public static MeshX Subdivide(MeshX mesh) { if (!mesh.helpersInited) { mesh.InitHelpers(); } MeshX newMesh = new MeshX { name = mesh.name + "/s", content = mesh.content, }; newMesh.StartBuilding(); MeshVertices newVertices = new MeshVertices { mesh = newMesh }; Dictionary <System.UInt32, Vertex> edgeMidPositions = new Dictionary <System.UInt32, Vertex>(); for (int pi = 0; pi < mesh.positions.Count; ++pi) { newMesh.AddPosition(default(Vertex)); } for (int vi = 0; vi < mesh.vertexCount; ++vi) { Vertex v = mesh.GetVertex(vi); newMesh.AddVertex(v); } //face points foreach (Face f in mesh.IterAllFaces()) { Vertex[] vs = mesh.GetVertices(mesh.GetFaceVertexIndices(f)); Vertex v = mesh.Average(vs); System.UInt32 keyF = GetFacePointKey(f); newVertices.AddVertices(v, Pair(v, keyF)); } //edge points foreach (Edge e in mesh.IterAllEdges()) { Edge n = mesh.GetNeighbor(e); Vertex midE = mesh.Average( mesh.GetVertices(mesh.GetEdgeVertexIndices(e)) ); System.UInt32 keyE = GetEdgePointKey(e); edgeMidPositions[keyE] = midE; Vertex v = mesh.Average( new[] { midE, newVertices.GetVertex(GetFacePointKey(e.face)), newVertices.GetVertex(GetFacePointKey(n.face)), }, weights: new[] { 2f, 1f, 1f } ); newVertices.AddVertices(v, Pair(v, keyE)); } // move control-points for (int pi = 0; pi < mesh.positions.Count; ++pi) { var edges = new List <Edge>(); var front = new List <Edge>(); foreach (int vi in mesh.positionVertices[pi]) { foreach (Edge e in mesh.vertexEdges[vi]) { edges.Add(e); foreach (Edge edge in new[] { e, mesh.GetNextInFace(e, -1) }) { EdgeType type = mesh.GetEdgeType(edge); if (type != EdgeType.back) { front.Add(edge); } } } } Vertex controlPoint; Vertex[] ms = new Vertex[front.Count]; for (int e = 0; e < front.Count; ++e) { ms[e] = edgeMidPositions[GetEdgePointKey(front[e])]; } Vertex edgeMidAverage = mesh.Average(ms, maskPosition); Vertex[] fs = new Vertex[edges.Count]; for (int e = 0; e < edges.Count; ++e) { fs[e] = newVertices.GetVertex(GetFacePointKey(edges[e].face), maskPosition); } Vertex faceAverage = mesh.Average(fs, maskPosition); controlPoint = mesh.Average( new[] { faceAverage, edgeMidAverage, mesh.GetPosition(pi) }, maskPosition, new[] { 1f, 2f, edges.Count - 3f } ); newMesh.SetPosition(pi, controlPoint); } //face creation newMesh.submeshes = new Submesh[mesh.submeshes.Length]; for (int si = 0; si < mesh.submeshes.Length; ++si) { int[][] faces = mesh.submeshes[si].faces; int faceCount = 0; foreach (int[] face in faces) { faceCount += face.Length; } newMesh.submeshes[si].faces = new int[faceCount][]; int faceIndex = 0; for (int fi = 0; fi < faces.Length; ++fi) { int[] fis = faces[fi]; int edgeCount = fis.Length; Face f = new Face { submesh = si, index = fi }; int ci = newVertices.vertexIndices[GetFacePointKey(f)]; int[] eis = new int[edgeCount]; for (int i = 0; i < edgeCount; ++i) { Edge e = new Edge { face = f, index = i }; eis[i] = newVertices.vertexIndices[GetEdgePointKey(e)]; } for (int i = 0; i < edgeCount; ++i) { int[] q = new int[4]; int s = edgeCount == 4 ? i : 0; q[(0 + s) % 4] = fis[i]; q[(1 + s) % 4] = eis[i]; q[(2 + s) % 4] = ci; q[(3 + s) % 4] = eis[(i - 1 + edgeCount) % edgeCount]; newMesh.submeshes[si].faces[faceIndex++] = q; } } } return(newMesh); }
public static MeshX Subdivide(MeshX mesh, Options options) { if (!mesh.helpersInited) { mesh.InitHelpers(); } if (!mesh.normalPerPosition) { mesh.MakeNormalPerPosition(); } MeshX newMesh = new MeshX { name = mesh.name + "/s", content = mesh.content, normalPerPosition = true, }; newMesh.StartBuilding(); CheckForVertexKeys(mesh); var newVertices = new MeshVertices { mesh = newMesh }; var edgeMidPositions = new Dictionary <VertexKey, Vertex>(); // position & normal // reserve indices for new control-points: they keep indices and we need no special keys for them. // later for control-points we set position & normal only: tangent & uv stay the same. for (int pi = 0; pi < mesh.positions.Count; ++pi) { newMesh.AddPosition(default(Vertex)); } for (int vi = 0; vi < mesh.vertexCount; ++vi) { Vertex v = mesh.GetVertex(vi, maskVertex); newMesh.AddVertex(v, addPosition: false); } // add face-points // "for each face, a face point is created which is the average of all the points of the face." foreach (Face f in mesh.IterAllFaces()) { Vertex[] vs = mesh.GetVertices(mesh.GetFaceVertexIndices(f)); Vertex v = mesh.Average(vs); VertexKey keyF = GetFacePointKey(f); newVertices.AddVertices(v, Pair(v, keyF)); } // add edge-points foreach (Edge e in mesh.IterAllEdges()) { EdgeType type = mesh.GetEdgeType(e); if (type == EdgeType.back) { continue; } if (type == EdgeType.boundary) { // "for the edges that are on the border of a hole, the edge point is just the middle of the edge." Vertex midE = mesh.Average( mesh.GetVertices(mesh.GetEdgeVertexIndices(e)) ); VertexKey keyE = GetEdgePointKey(e); edgeMidPositions[keyE] = midE; newVertices.AddVertices(midE, Pair(midE, keyE)); } else if (type == EdgeType.solid) { // "for each edge, an edge point is created which is the average between the center of the edge // and the center of the segment made with the face points of the two adjacent faces." Edge n = mesh.GetNeighbor(e); Vertex midE = mesh.Average( mesh.GetVertices(mesh.GetEdgeVertexIndices(e)) ); VertexKey keyE = GetEdgePointKey(e); edgeMidPositions[keyE] = midE; Vertex v = mesh.Average( new[] { midE, newVertices.GetVertex(GetFacePointKey(e.face)), newVertices.GetVertex(GetFacePointKey(n.face)), }, weights: new[] { 2f, 1f, 1f } ); newVertices.AddVertices(v, Pair(v, keyE)); } else // seam edge { Edge n = mesh.GetNeighbor(e); Vertex midE = mesh.Average( mesh.GetVertices(mesh.GetEdgeVertexIndices(e)) ); Vertex midN = mesh.Average( mesh.GetVertices(mesh.GetEdgeVertexIndices(n)), maskVertex // pos & normal already got in midE ); VertexKey keyE = GetEdgePointKey(e); VertexKey keyN = GetEdgePointKey(n); edgeMidPositions[keyE] = midE; Vertex p = mesh.Average( // pos & normal only new[] { midE, newVertices.GetVertex(GetFacePointKey(e.face), maskPosition), newVertices.GetVertex(GetFacePointKey(n.face), maskPosition), }, maskPosition, new[] { 2f, 1f, 1f } ); newVertices.AddVertices(p, Pair(midE, keyE), Pair(midN, keyN)); } } // move control-points for (int pi = 0; pi < mesh.positions.Count; ++pi) { // count edges var edges = new List <Edge>(); // edges outcoming from the position var boundaries = new List <Edge>(); var front = new List <Edge>(); foreach (int vi in mesh.positionVertices[pi]) { foreach (Edge e in mesh.vertexEdges[vi]) { edges.Add(e); foreach (Edge edge in new[] { e, mesh.GetNextInFace(e, -1) }) { EdgeType type = mesh.GetEdgeType(edge); if (type == EdgeType.boundary) { boundaries.Add(edge); } else if (type != EdgeType.back) { front.Add(edge); } } } } Debug.AssertFormat(boundaries.Count > 0 || (edges.Count == front.Count), "Counting edges error: boundaries: {0}, edges {1}, front: {2}", boundaries.Count, edges.Count, front.Count); Vertex controlPoint; if (boundaries.Count > 0) { bool isCorner = edges.Count == 1; if (options.boundaryInterpolation == Options.BoundaryInterpolation.fixBoundaries || options.boundaryInterpolation == Options.BoundaryInterpolation.fixCorners && isCorner) { controlPoint = mesh.GetPosition(pi); // keep same position } else { // "for the vertex points that are on the border of a hole, the new coordinates are calculated as follows: // 1. in all the edges the point belongs to, only take in account the middles of the edges that are on the border of the hole // 2. calculate the average between these points (on the hole boundary) and the old coordinates (also on the hole boundary)." Vertex[] vs = new Vertex[boundaries.Count + 1]; vs[0] = mesh.GetPosition(pi); for (int e = 0; e < boundaries.Count; ++e) { vs[e + 1] = edgeMidPositions[GetEdgePointKey(boundaries[e])]; } controlPoint = mesh.Average(vs, maskPosition); } } else { // "for each vertex point, its coordinates are updated from (new_coords): // the old coordinates (P), // the average of the face points of the faces the point belongs to (F), // the average of the centers of edges the point belongs to (R), // how many faces a point belongs to (n), then use this formula: // (F + 2R + (n-3)P) / n" // edge-midpoints Vertex[] ms = new Vertex[front.Count]; for (int e = 0; e < front.Count; ++e) { ms[e] = edgeMidPositions[GetEdgePointKey(front[e])]; } Vertex edgeMidAverage = mesh.Average(ms, maskPosition); // face-points Vertex[] fs = new Vertex[edges.Count]; for (int e = 0; e < edges.Count; ++e) { fs[e] = newVertices.GetVertex(GetFacePointKey(edges[e].face), maskPosition); } Vertex faceAverage = mesh.Average(fs, maskPosition); // new control-point controlPoint = mesh.Average( new[] { faceAverage, edgeMidAverage, mesh.GetPosition(pi) }, maskPosition, new[] { 1f, 2f, edges.Count - 3f } ); } // set moved control-point position to reserved index newMesh.SetPosition(pi, controlPoint); } // add 4 new quads per face // eis[i] // fis[i].----.----.fis[i+1] // | | // eis[i-1]. ci. . // | | // .____.____. newMesh.submeshes = new Submesh[mesh.submeshes.Length]; for (int si = 0; si < mesh.submeshes.Length; ++si) { int[][] faces = mesh.submeshes[si].faces; // get new face count int faceCount = 0; foreach (int[] face in faces) { faceCount += face.Length; } newMesh.submeshes[si].faces = new int[faceCount][]; // fill faces int faceIndex = 0; for (int fi = 0; fi < faces.Length; ++fi) { int[] fis = faces[fi]; int edgeCount = fis.Length; // 3 or 4 // Face f = new Face { submesh = si, index = fi }; int ci = newVertices.vertexIndices[GetFacePointKey(f)]; // face-point index // int[] eis = new int[edgeCount]; // edge-point indices for (int i = 0; i < edgeCount; ++i) { Edge e = new Edge { face = f, index = i }; // get neighbor for solid back edges if (mesh.GetEdgeType(e) == EdgeType.back) //!!! here should be some EdgeType.backOfSeam or EdgeType.backOfSolid { Edge n = mesh.GetNeighbor(e); if (mesh.GetEdgeType(n) == EdgeType.solid) { e = n; } } eis[i] = newVertices.vertexIndices[GetEdgePointKey(e)]; } // for (int i = 0; i < edgeCount; ++i) { int[] q = new int[4]; // new faces are always quads int s = edgeCount == 4 ? i : 0; // shift indices (+ i) to keep quad orientation q[(0 + s) % 4] = fis[i]; q[(1 + s) % 4] = eis[i]; q[(2 + s) % 4] = ci; q[(3 + s) % 4] = eis[(i - 1 + edgeCount) % edgeCount]; newMesh.submeshes[si].faces[faceIndex++] = q; } } } newMesh.FinishBuilding(); return(newMesh); }
/// <summary> /// Builds an OpenGL mesh /// </summary> private object BuildMesh( MeshVertices vertices, MeshPolygons polygons ) { OpenGlMesh mesh = new OpenGlMesh( ); // Set up the index buffer in the mesh if ( polygons.StoredAsTriangles ) { int[] indexBuffer = new int[ polygons.Polygons.Count * 3 ]; int curIndex = 0; foreach ( MeshPolygon curPoly in polygons.Polygons ) { indexBuffer[ curIndex++ ] = curPoly.Indices[ 0 ]; indexBuffer[ curIndex++ ] = curPoly.Indices[ 1 ]; indexBuffer[ curIndex++ ] = curPoly.Indices[ 2 ]; } mesh.CreateGroups( 1 ); mesh.SetGroup( 0, new OpenGlIndexedGroup( Gl.GL_TRIANGLES, indexBuffer ) ); } else { throw new ApplicationException( "sorry, non-triange index buffers not implemented yet" ); } mesh.CreateVertexBuffers( vertices.Sources.Count ); int vboIndex = 0; foreach ( MeshTaggedSource curSource in vertices.Sources ) { // Convert the source semantic to an opengl client state // Swap y and z elements // TODO: Should be a resource flag, at the very least bool swapYz = false; int clientState = 0; switch ( curSource.Semantic ) { case "POSITION": clientState = Gl.GL_VERTEX_ARRAY; swapYz = true; break; case "NORMAL": clientState = Gl.GL_NORMAL_ARRAY; swapYz = true; break; case "COLOR": clientState = Gl.GL_COLOR_ARRAY; break; default: throw new ApplicationException( string.Format( "Unknown mesh semantic \"{0}\"", curSource.Semantic ) ); } // Store the stride (note, for GL this has a slightly different meaning, I think. TODO: Check COLLADA spec. to make sure) int numObjects = curSource.Source.Data.Count / curSource.Source.Stride; short stride = 0; short numElements = ( short )curSource.Source.Stride; Type dataType = curSource.Source.DataType; switch ( Type.GetTypeCode( dataType ) ) { case TypeCode.Single: { // HACK: Swap y and z coordinates - in blender (the 3d editor I'm currently using), z is up, in the engine, y is up. float[] bufferData = ( float[] )curSource.Source.Data.ToArray( dataType ); if ( swapYz ) { for ( int index = 0; index < bufferData.Length; index += 3 ) { float tmp = bufferData[ index + 1 ]; bufferData[ index + 1 ] = bufferData[ index + 2 ]; bufferData[ index + 2 ] = tmp; } } mesh.SetVertexBuffer( vboIndex, new OpenGlVertexBuffer( numObjects, 0, clientState, stride, numElements, Gl.GL_STATIC_DRAW_ARB, bufferData ) ); break; } case TypeCode.Int32: { int[] bufferData = ( int[] )curSource.Source.Data.ToArray( dataType ); mesh.SetVertexBuffer( vboIndex, new OpenGlVertexBuffer( numObjects, 0, clientState, stride, numElements, Gl.GL_STATIC_DRAW_ARB, bufferData ) ); break; } case TypeCode.Byte: { byte[] bufferData = ( byte[] )curSource.Source.Data.ToArray( dataType ); mesh.SetVertexBuffer( vboIndex, new OpenGlVertexBuffer( numObjects, 0, clientState, stride, numElements, Gl.GL_STATIC_DRAW_ARB, bufferData ) ); break; } default: { throw new ApplicationException( string.Format( "Unhandled vertex source type \"{0}\"", curSource.Source.DataType.Name ) ); } } ++vboIndex; } return mesh; }
/// <summary> /// Apply the mesh details to the object /// </summary> /// <param name="baseobject">The object to add the mesh too</param> public void ApplyMeshDetails(GameObject baseobject) { #if DEBUG Mesh mesh = new Mesh(); mesh.name = "RoadMesh"; baseobject.GetComponent <MeshFilter>().mesh = mesh; ApplyObjectOffSet(baseobject.transform.position); mesh.vertices = MeshVertices.ToArray(); mesh.uv = MeshUVs.ToArray(); // Create the material and assign triangles Renderer r = baseobject.GetComponent <Renderer>(); List <Material> materials = new List <Material>(); int count = 0; mesh.subMeshCount = _meshMaterialsTriangles.Count; List <Material> AllMaterials = FindAllMaterials(baseobject); foreach (KeyValuePair <string, List <int> > meshTris in _meshMaterialsTriangles) { if (meshTris.Value.Count == 0) { continue; } Material mat = AllMaterials.Find((m) => m.name == meshTris.Key); materials.Add(mat); mesh.SetTriangles(meshTris.Value.ToArray(), count++); } mesh.subMeshCount = count; // just in case we didn't add all of them r.materials = materials.ToArray(); mesh.RecalculateNormals(); mesh.RecalculateTangents(); mesh.RecalculateBounds(); if (RoadConstructorHelper.Lighting.BakedLighting) { Debug.Log("Appling unwrapping for Baked Lighting"); UnwrapParam up = new UnwrapParam(); up.hardAngle = RoadConstructorHelper.Lighting.HardAngle; up.packMargin = RoadConstructorHelper.Lighting.PackMargin; up.angleError = RoadConstructorHelper.Lighting.AngleError; up.areaError = RoadConstructorHelper.Lighting.AngleError; Unwrapping.GenerateSecondaryUVSet(mesh, up); } #if UNITY_5_5_OR_NEWER #if UNITY_EDITOR // TODO: Added option UnityEditor.MeshUtility.SetMeshCompression(mesh, UnityEditor.ModelImporterMeshCompression.); UnityEditor.MeshUtility.Optimize(mesh); #endif #else mesh.Optimize(); #endif #endif }
public unsafe bool BuildClusterFromMeshSource(CRenderContext rc, RName meshSourceName) { Graphics.Mesh.CGfxMeshDataProvider meshSource = new Graphics.Mesh.CGfxMeshDataProvider(); var meshPrimitive = CEngine.Instance.MeshPrimitivesManager.GetMeshPrimitives(rc, meshSourceName, true); meshSource.InitFromMesh(rc, meshPrimitive); uint a, b, c; a = 0; b = 0; c = 0; List <Cluster> clusterArray = new List <Cluster>(); int vertNum = meshSource.VertexNumber; Vector3 *pPos = (Vector3 *)meshSource.GetVertexPtr(EVertexSteamType.VST_Position, 0).ToPointer(); Vector3 *pNor = (Vector3 *)meshSource.GetVertexPtr(EVertexSteamType.VST_Normal, 0).ToPointer(); Vector4 *pTan = (Vector4 *)meshSource.GetVertexPtr(EVertexSteamType.VST_Tangent, 0).ToPointer(); Vector2 *pDiffUV = (Vector2 *)meshSource.GetVertexPtr(EVertexSteamType.VST_UV, 0).ToPointer(); GpuSceneVertex vert = new GpuSceneVertex(); for (int i = 0; i < vertNum; i++) { vert.Reset(); if (pPos != null) { vert.Position = pPos[i]; } if (pNor != null) { vert.Normal = pNor[i]; } if (pTan != null) { vert.Tangent = pTan[i]; } if (pDiffUV != null) { vert.DiffuseU = pDiffUV[i].X; vert.DiffuseV = pDiffUV[i].Y; } MeshVertices.Add(vert); } for (int i = 0; i < meshSource.TriangleNumber; i++) { meshSource.GetTriangle(i, ref a, ref b, ref c); IndexBuffer.Add(a); IndexBuffer.Add(b); IndexBuffer.Add(c); } Cluster curCluster = null; Vector3 *pPosPtr = (Vector3 *)meshSource.GetVertexPtr(EVertexSteamType.VST_Position, 0).ToPointer(); for (uint i = 0; i < meshSource.AtomNumber; i++) { CDrawPrimitiveDesc desc = meshSource[i, 0]; if (desc.PrimitiveType != EPrimitiveType.EPT_TriangleList) { return(false); } uint startFace = desc.StartIndex / 3; for (uint j = 0; j < desc.NumPrimitives; j++) { if (curCluster == null || curCluster.Data.FaceCount >= 64) { curCluster = new Cluster(); curCluster.Data.InstanceId = i; curCluster.Data.StartFaceIndex = startFace; curCluster.Data.FaceCount = 0; clusterArray.Add(curCluster); } startFace++; curCluster.Data.FaceCount++; } } ClusterDatas.Clear(); for (int i = 0; i < clusterArray.Count; i++) { clusterArray[i].Proccess(pPosPtr, IndexBuffer); ClusterDatas.Add(clusterArray[i].Data); } return(true); }
public bool LoadClusteredMesh(RName name) { Name = name; Cleanup(); var xnd = IO.XndHolder.SyncLoadXND(name.Address); IO.XndNode node = xnd.Node; var attr = node.FindAttrib("Vertices"); if (attr == null) { return(false); } attr.BeginRead(); int count = 0; attr.Read(out count); for (int i = 0; i < count; i++) { GpuSceneVertex vert; attr.Read(out vert); MeshVertices.Add(vert); } attr.EndRead(); attr = node.FindAttrib("ClusterDatas"); if (attr == null) { return(false); } attr.BeginRead(); attr.Read(out count); for (int i = 0; i < count; i++) { GpuCluster cluster; attr.Read(out cluster); ClusterDatas.Add(cluster); } attr.EndRead(); attr = node.FindAttrib("IndexBuffer"); attr.BeginRead(); attr.Read(out count); for (int i = 0; i < count; i++) { uint index; attr.Read(out index); IndexBuffer.Add(index); } attr.EndRead(); unsafe { ResourceState.ResourceSize = (uint)(MeshVertices.Count * sizeof(GpuSceneVertex) + ClusterDatas.Count * sizeof(GpuCluster) + IndexBuffer.Count * sizeof(uint)); } return(true); }
public static void Mask(LightingBuffer2D buffer, LightingCollider2D id, LayerSetting layerSetting, Vector2D offset, float z) { if (false == (id.shape.maskType == LightingCollider2D.MaskType.Collider || id.shape.maskType == LightingCollider2D.MaskType.SpriteCustomPhysicsShape || id.shape.maskType == LightingCollider2D.MaskType.Mesh)) { return; } if (id.isVisibleForLight(buffer) == false) { return; } Mesh mesh = null; MeshVertices vertices = null; if (id.shape.maskType == LightingCollider2D.MaskType.Mesh) { if (id.meshFilter == null) { return; } mesh = id.meshFilter.sharedMesh; } else { mesh = id.shape.GetMesh_MaskType(id.transform); vertices = id.shape.GetMesh_Vertices_MaskType(id.transform); } if (mesh == null) { return; } bool maskEffect = (layerSetting.effect == LightingLayerEffect.InvisibleBellow); LightingMaskMode maskMode = id.maskMode; MeshVertice vertice; if (maskMode == LightingMaskMode.Invisible) { GL.Color(Color.black); } else if (layerSetting.effect == LightingLayerEffect.InvisibleBellow) { float c = (float)offset.y / layerSetting.maskEffectDistance + layerSetting.maskEffectDistance * 2; if (c < 0) { c = 0; } color.r = c; color.g = c; color.b = c; color.a = 1; GL.Color(color); } else { GL.Color(Color.white); } for (int i = 0; i < vertices.list.Count; i++) { vertice = vertices.list[i]; Max2DMatrix.DrawTriangle(vertice.a, vertice.b, vertice.c, offset, z); } LightingDebug.maskGenerations++; }