private void Update() { Indices.Clear(); LoadedInstanceIds.Clear(); LoadedGroupIds.Clear(); LoadedFileTypeIds.Clear(); foreach (DatabasePackedFile packed in PackageFiles) { Indices.AddRange(packed.Indices); } foreach (DatabaseIndex index in Indices) { if (!LoadedInstanceIds.Contains(index.InstanceId)) { LoadedInstanceIds.Add(index.InstanceId); } if (!LoadedGroupIds.Contains(index.GroupId)) { LoadedGroupIds.Add(index.GroupId); } if (!LoadedFileTypeIds.Contains(index.TypeId)) { LoadedFileTypeIds.Add(index.TypeId); } } Indices.Changed(); PackageFiles.Changed(); }
} = 3; // по Z /// <summary> /// Добавляет коробку с заданными гранями, выровненными по заданным осям. /// </summary> /// <param name="c">Точка центра куба.</param> /// <param name="Length">Длина коробки вдоль оси X.</param> /// <param name="Width">Длина коробки вдоль оси Y.</param> /// <param name="Height">Длина коробки вдоль оси Z.</param> public override void Update() { //Очистка Positions.Clear(); Indices.Clear(); Normals.Clear(); var c = new Vector3(Length, Width, Height) / 2; AddCubeFace(c, Vector3.UnitX, Vector3.UnitZ, Length, Width, Height); AddCubeFace(c, -Vector3.UnitX, Vector3.UnitZ, Length, Width, Height); AddCubeFace(c, -Vector3.UnitY, Vector3.UnitZ, Width, Length, Height); AddCubeFace(c, Vector3.UnitY, Vector3.UnitZ, Width, Length, Height); AddCubeFace(c, Vector3.UnitZ, Vector3.UnitY, Height, Length, Width); AddCubeFace(c, -Vector3.UnitZ, Vector3.UnitY, Height, Length, Width); // добавление ребер AddEdge(0, 1); AddEdge(1, 2); AddEdge(2, 3); AddEdge(3, 0); AddEdge(4, 5); AddEdge(5, 6); AddEdge(6, 7); AddEdge(7, 4); AddEdge(0, 5); AddEdge(1, 4); AddEdge(2, 7); AddEdge(3, 6); }
/// <summary> /// Clears all vertices, indices, bone tables, materials and strips. /// </summary> public void Clear() { BoneTable.Clear(); Vertices.Clear(); Indices.Clear(); Materials.Clear(); Strips.Clear(); }
public void Clear() { Vertices.Clear(); UVs.Clear(); Indices.Clear(); Normals.Clear(); Colours.Clear(); }
public T Build(GraphicsDevice graphicsDevice, Texture2D texture) { var model = CreateModel(graphicsDevice, texture); Vertices.Clear(); Indices.Clear(); ClearBuffers(); return(model); }
/// <summary> /// Clears all geometry data. /// </summary> public void ClearAllGeometryData() { Positions?.Clear(); Positions?.TrimExcess(); Indices?.Clear(); Indices?.TrimExcess(); Colors?.Clear(); Colors?.TrimExcess(); OnClearAllGeometryData(); }
/// <summary> /// Creates the indices for a scatter plot. /// </summary> /// <returns>The indices for a scatter plot.</returns> /// <param name="numberOfPoints">Number of points.</param> private void createIndicesScatterPlot(int numberOfPoints) { Indices.Clear(); Indices.Capacity = numberOfPoints; for (int i = 0; i < numberOfPoints; i++) { Indices.Add(i); } }
public void Reset() { Textures.Clear(); Indices.Clear(); Vertices.Clear(); RenderBatches.Clear(); OptimizedDraws.Clear(); UnknownShorts1.Clear(); UnknownVectors1.Clear(); TileOccluderInfos.Clear(); }
private void GenerateIndices() { List <VertexFormat> tempVertices = new List <VertexFormat>(); List <int> tempIndices = new List <int>(); foreach (VertexFormat v in Vertices) { //Search for existing vertex int i = 0; bool found = false; foreach (VertexFormat v2 in tempVertices) { if (VertexFormat.Compare(v, v2)) { //found found = true; break; } i++; } //In found join the normals if (found) { tempIndices.Add(i); VertexFormat v2 = tempVertices[i]; } else { i = tempVertices.Count; tempVertices.Add(v); tempIndices.Add(i); } //normal VertexFormat vTemp = tempVertices[i]; vTemp.Normal += v.Normal; tempVertices[i] = vTemp; } //Normalize all Vertices Vertices.Clear(); foreach (VertexFormat v in tempVertices) { v.Normal.Normalize(); Vertices.Add(v); } Vertices.AddRange(tempVertices); Indices.Clear(); Indices.AddRange(tempIndices); }
public void CalculateIndexes() { Indices.Clear(); tree.ProcessCell(Indices); IndexCount = Indices.Count; if (Indices.Count == 0) { return; } IndexBuffer.SetData <int>(Indices.ToArray()); }
public override void Update() { //Clear Positions.Clear(); Indices.Clear(); Normals.Clear(); if (points.Count % 2 != 0) { throw new InvalidOperationException("The number of points should be even."); } var p10 = p1 - p0; var axisY = Vector3.Cross(axisX, p10); axisY.Normalize(); axisX.Normalize(); int index0 = Positions.Count; for (int i = 0; i < points.Count; i++) { var p = points[i]; var d = (axisX * p.X) + (axisY * p.Y); Positions.Add(p0 + d); Positions.Add(p1 + d); if (Normals != null) { d.Normalize(); Normals.Add(d); Normals.Add(d); } } int n = points.Count - 1; for (int i = 0; i < n; i++) { int i0 = index0 + (i * 2); int i1 = i0 + 1; int i2 = i0 + 3; int i3 = i0 + 2; Indices.Add(i0); Indices.Add(i1); Indices.Add(i2); Indices.Add(i2); Indices.Add(i3); Indices.Add(i0); } }
protected override void Dispose(bool disposing) { if (IsDisposed) { return; } if (disposing) { var meshGeometry = ModelMesh; Utilities.Dispose(ref meshGeometry); Indices.Clear(); Vertices.Clear(); Indices = null; Vertices = null; } }
public void Dispose(AssetManager assetManager) { Indices.Clear(); Vertices.Clear(); RenderBatches.Clear(); OptimizedDraws.Clear(); UnknownShorts1.Clear(); UnknownVectors1.Clear(); TileOccluderInfos.Clear(); foreach (Texture texture in Textures) { assetManager.Dispose(texture.ColorNXMap); assetManager.Dispose(texture.SpecNyMap); } }
private void GenerateIndices() { Indices.Clear(); for (int i = 0; i < (Width - 1); i++) { for (int j = 0; j < (Height - 1); j++) { Indices.Add(i * Width + j); Indices.Add(i * Width + j + 1); Indices.Add((i + 1) * Width + j); Indices.Add((i + 1) * Width + j + 1); Indices.Add((i + 1) * Width + j); Indices.Add(i * Width + j + 1); } } }
public Vector3 FindAnyPerpendicular(Vector3 n) { //Clear Positions.Clear(); Indices.Clear(); Normals.Clear(); n.Normalize(); Vector3 u = Vector3.Cross(new Vector3(0, 1, 0), n); if (u.LengthSquared() < 1e-3) { u = Vector3.Cross(new Vector3(1, 0, 0), n); } return(u); }
public void Destroy() { if (m_objTransform != null) { MeshFilter meshFilter = m_objTransform.GetComponent <MeshFilter>(); meshFilter.mesh.Clear(); UnityEngine.Object.Destroy(meshFilter.mesh); meshFilter.mesh = null; UnityEngine.Object.Destroy(meshFilter); UnityEngine.Object.Destroy(m_objTransform); m_objTransform = null; Vertices.Clear(); Uvs.Clear(); Colors.Clear(); Indices.Clear(); } }
public void Unload() { // Don't empty if loading if (Loading || !Expired) { return; } Encoding.Clear(); Root.Clear(); Indices.Clear(); Expired = false; Loading = false; GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect(2, GCCollectionMode.Forced); Scanner.WriteLine($"[{VersionName}] Unloaded."); }
public override void Tessellate() { // Create vertices. Vector3D normal = new Vector3D(0, 1, 0); for (int z = 0; z < _length; ++z) { for (int x = 0; x < _width; ++x) { AddVertex(new Point3D(x, 0, (_length - 1) - z), normal); // Invert z so that winding order is correct. } } // Create indices. for (int z = 0; z < _length - 1; ++z) { for (int x = 0; x < _width; ++x) { // Create vertex for degenerate triangle. if (x == 0 && z > 0) { AddIndex(((z + 0) * _width) + x); } AddIndex(((z + 0) * _width) + x); AddIndex(((z + 1) * _width) + x); // Create vertex for degenerate triangle. if (x == _width - 1 && z < _length - 2) { AddIndex(((z + 1) * _width) + x); } } } // It's easiest to define the plane in terms of a triangle strip, // and then convert it. Int32Collection newIndices = MeshUtility.ConvertTriangleStripToTriangleList(Indices); Indices.Clear(); Indices.AddRange(newIndices); }
/// <summary> /// Optimized the vertex index size by removing duplicate vertices /// </summary> public void Optimize() { Indices.Clear(); List <IOVertex> NewVertices = new List <IOVertex>(); Dictionary <IOVertex, uint> vertexToIndex = new Dictionary <IOVertex, uint>(); foreach (var vertex in Vertices) { if (!vertexToIndex.ContainsKey(vertex)) { vertexToIndex.Add(vertex, (uint)NewVertices.Count); NewVertices.Add(vertex); } Indices.Add(vertexToIndex[vertex]); } SBConsole.WriteLine($"Optimized {Name} {Vertices.Count} -> {NewVertices.Count}"); Vertices.Clear(); Vertices.AddRange(NewVertices); }
/// <summary> /// Добавление сферы. /// </summary> /// <param name="с"> /// Центр сферы. /// </param> /// <param name="Radius"> /// Радиус сферы. /// </param> /// <param name="thetaDiv"> /// The number of divisions around the ellipsoid. /// </param> /// <param name="phiDiv"> /// The number of divisions from top to bottom of the ellipsoid. /// </param> public override void Update() { //Очитска Positions.Clear(); Indices.Clear(); Normals.Clear(); var c = new Vector3(1, 1, 1); int thetaDiv = 32; int phiDiv = 32; int index0 = this.Positions.Count; var dt = 2 * Math.PI / thetaDiv; var dp = Math.PI / phiDiv; for (int pi = 0; pi <= phiDiv; pi++) { var phi = pi * dp; for (int ti = 0; ti <= thetaDiv; ti++) { var theta = ti * dt; var x = Math.Cos(theta) * Math.Sin(phi); var y = Math.Sin(theta) * Math.Sin(phi); var z = Math.Cos(phi); var p = new Vector3((float)(c.X + (Radius * x)), (float)(c.Y + (Radius * y)), (float)(c.Z + (Radius * z))); Positions.Add(new Vector3(p.X, p.Y, p.Z)); if (Normals != null) { var n = new Vector3((float)x, (float)y, (float)z); Normals.Add(n); } } } this.AddIndices(index0, phiDiv + 1, thetaDiv + 1, true); }
protected bool CreateCap(Volume volume, bool partialBuild) { if ((TypeMask & VolumeFaceMask.Hollow) == 0 && (TypeMask & VolumeFaceMask.Open) == 0 && ((volume.Parameters.PathParameters.Begin == 0.0f) && (volume.Parameters.PathParameters.End == 1.0f)) && (volume.Parameters.ProfileParameters.ProfileType == ProfileType.Square && volume.Parameters.PathParameters.PathType == PathType.Line) ) { return(CreateUnCutCubeCap(volume, partialBuild)); } int numVertices = 0, numIndices = 0; List <Vector3> mesh = volume.Points; List <Vector3> profile = volume.Profile.Points; // All types of caps have the same number of vertices and indices numVertices = profile.Count; numIndices = (profile.Count - 2) * 3; //if ((TypeMask & VolumeFaceMask.Hollow) == 0 && (TypeMask & VolumeFaceMask.Open) == 0) //{ // resizeVertices(num_vertices + 1); // //if (!partial_build) // { // resizeIndices(num_indices + 3); // } //} //else //{ // resizeVertices(num_vertices); // //if (!partial_build) // { // resizeIndices(num_indices); // } //} Positions.Clear(); Normals.Clear(); Tangents.Clear(); TexCoords.Clear(); Indices.Clear(); Edge.Clear(); int maxS = volume.Profile.PointCount; int maxT = volume.Path.PointCount; Centre = Vector3.zero; int offset = ((TypeMask & VolumeFaceMask.Top) != 0) ? (maxT - 1) * maxS : BeginS; // Figure out the normal, assume all caps are flat faces. // Cross product to get normals. Vector2 cuv; Vector2 min_uv, max_uv; // VFExtents change Vector3 min = ExtentsMin; Vector3 max = ExtentsMax; // Copy the vertices into the array int srcIndex = offset; // Index in mesh int endIndex = srcIndex + numVertices; // Index in mesh min = mesh[srcIndex]; max = min; int pIndex = 0; // Index in profile if ((TypeMask & VolumeFaceMask.Top) != 0) { min_uv.x = profile[pIndex].x + 0.5f; min_uv.y = profile[pIndex].y + 0.5f; max_uv = min_uv; while (srcIndex < endIndex) { Vector2 tc = new Vector2(profile[pIndex].x + 0.5f, profile[pIndex].y + 0.5f); UpdateMinMax(ref min_uv, ref max_uv, tc); TexCoords.Add(tc); UpdateMinMax(ref min, ref max, mesh[srcIndex]); Positions.Add(mesh[srcIndex]); ++pIndex; ++srcIndex; } } else { min_uv.x = profile[pIndex].x + 0.5f; min_uv.y = 0.5f - profile[pIndex].y; max_uv = min_uv; while (srcIndex < endIndex) { // Mirror for underside. Vector2 tc = new Vector2(profile[pIndex].x + 0.5f, 0.5f - profile[pIndex].y); UpdateMinMax(ref min_uv, ref max_uv, tc); TexCoords.Add(tc); UpdateMinMax(ref min, ref max, mesh[srcIndex]); Positions.Add(mesh[srcIndex]); ++pIndex; ++srcIndex; } } Centre = (min + max) * 0.5f; cuv = (min_uv + max_uv) * 0.5f; VertexData vd = new VertexData { Position = Centre, TexCoord = cuv }; if ((TypeMask & VolumeFaceMask.Hollow) == 0 && (TypeMask & VolumeFaceMask.Open) == 0) { Positions.Add(Centre); TexCoords.Add(cuv); numVertices++; } //if (partial_build) //{ // return TRUE; //} if ((TypeMask & VolumeFaceMask.Hollow) != 0) { CreateHollowCap(numVertices, profile, (TypeMask & VolumeFaceMask.Top) == 0); } else { // Not hollow, generate the triangle fan. CreateSolidCap(numVertices); } Vector3 d0 = Positions[Indices[1]] - Positions[Indices[0]]; Vector3 d1 = Positions[Indices[2]] - Positions[Indices[0]]; Vector3 normal = Vector3.Cross(d0, d1); if (Vector3.Dot(normal, normal) > 0.00001f) { normal.Normalize(); } else { //degenerate, make up a value normal = normal.z >= 0 ? new Vector3(0f, 0f, 1f) : new Vector3(0f, 0f, -1f); } //llassert(llfinite(normal.getF32ptr()[0])); //llassert(llfinite(normal.getF32ptr()[1])); //llassert(llfinite(normal.getF32ptr()[2])); //llassert(!llisnan(normal.getF32ptr()[0])); //llassert(!llisnan(normal.getF32ptr()[1])); //llassert(!llisnan(normal.getF32ptr()[2])); for (int i = 0; i < numVertices; i++) { Normals.Add(normal); } return(true); }
internal void Clear() { Indices.Clear(); Vertices.Clear(); }
public void CalculateIndexes(float threshold) { if (!FlatShading) { Indices.Clear(); } else { Indices = new List <int>(); } List <int> tri_count = new List <int>(); tree.ProcessCell(Indices, tri_count, threshold); if (!FlatShading) { IndexCount = Indices.Count; if (Indices.Count == 0) { return; } } if (!FlatShading) { IndexBuffer.SetData <int>(Indices.ToArray()); } else { List <VertexPositionColorNormal> new_vertices = new List <VertexPositionColorNormal>(); int t_index = 0; for (int i = 0; i < Indices.Count; i += 3) { int count = tri_count[t_index++]; Vector3 n = Vector3.Zero; if (count == 1) { n = GetNormalQ(Vertices, Indices[i + 2], Indices[i + 0], Indices[i + 1]); } else { n = GetNormalQ(Vertices, Indices[i + 2], Indices[i + 0], Indices[i + 1], Indices[i + 5], Indices[i + 3], Indices[i + 4]); } Vector3 nc = n * 0.5f + Vector3.One * 0.5f; nc.Normalize(); Color c = new Color(nc); VertexPositionColorNormal v0 = new VertexPositionColorNormal(Vertices[Indices[i + 0]].Position, c, n); VertexPositionColorNormal v1 = new VertexPositionColorNormal(Vertices[Indices[i + 1]].Position, c, n); VertexPositionColorNormal v2 = new VertexPositionColorNormal(Vertices[Indices[i + 2]].Position, c, n); new_vertices.Add(v0); new_vertices.Add(v1); new_vertices.Add(v2); if (count > 1) { VertexPositionColorNormal v3 = new VertexPositionColorNormal(Vertices[Indices[i + 3]].Position, c, n); VertexPositionColorNormal v4 = new VertexPositionColorNormal(Vertices[Indices[i + 4]].Position, c, n); VertexPositionColorNormal v5 = new VertexPositionColorNormal(Vertices[Indices[i + 5]].Position, c, n); new_vertices.Add(v3); new_vertices.Add(v4); new_vertices.Add(v5); i += 3; } } if (new_vertices.Count > 0) { VertexBuffer.SetData <VertexPositionColorNormal>(new_vertices.ToArray()); } VertexCount = new_vertices.Count; } }
public override void Update() { //Clear Positions.Clear(); Indices.Clear(); Normals.Clear(); Vector3 point1 = new Vector3(0, 0, 0); //origin Vector3 point2 = new Vector3(0, 2, 0); Vector3 n = point2 - point1; //direction var l = Math.Sqrt(n.X * n.X + n.Y * n.Y + n.Z * n.Z); n.Normalize(); int thetaDiv = 32; // var pc = new List <Vector2>(); //points pc.Add(new Vector2(0, 0)); pc.Add(new Vector2(0, Radius)); pc.Add(new Vector2((float)l, Radius)); pc.Add(new Vector2((float)l, 0)); n.Normalize(); Vector3 u = Vector3.Cross(new Vector3(0, 1, 0), n); if (u.LengthSquared() < 1e-3) { u = Vector3.Cross(new Vector3(1, 0, 0), n); } var v = Vector3.Cross(n, u); u.Normalize(); v.Normalize(); var circle = AddCircle(thetaDiv); int index0 = Positions.Count; int counter = pc.Count; int totalNodes = (pc.Count - 1) * 2 * thetaDiv; int rowNodes = (pc.Count - 1) * 2; for (int i = 0; i < thetaDiv; i++) { var w = (v * circle[i].X) + (u * circle[i].Y); for (int j = 0; j + 1 < counter; j++) { var q1 = point1 + (n * pc[j].X) + (w * pc[j].Y); var q2 = point1 + (n * pc[j + 1].X) + (w * pc[j + 1].Y); Positions.Add(new Vector3((float)q1.X, (float)q1.Y, (float)q1.Z)); Positions.Add(new Vector3((float)q2.X, (float)q2.Y, (float)q2.Z)); if (Normals != null) { var tx = pc[j + 1].X - pc[j].X; var ty = pc[j + 1].Y - pc[j].Y; var normal = (-n * ty) + (w * tx); normal.Normalize(); Normals.Add(normal); Normals.Add(normal); } int i0 = index0 + (i * rowNodes) + (j * 2); int i1 = i0 + 1; int i2 = index0 + ((((i + 1) * rowNodes) + (j * 2)) % totalNodes); int i3 = i2 + 1; Indices.Add(i1); Indices.Add(i0); Indices.Add(i2); Indices.Add(i1); Indices.Add(i2); Indices.Add(i3); } } }
protected bool CreateSide(Volume volume, bool partialBuild) { bool flat = TypeMask.HasFlag(VolumeFaceMask.Flat); SculptType sculptStitching = volume.Parameters.SculptType; SculptFlags sculptFlags = volume.Parameters.SculptFlags; bool sculptInvert = sculptFlags.HasFlag(SculptFlags.Invert); bool sculptMirror = sculptFlags.HasFlag(SculptFlags.Mirror); bool sculptReverseHorizontal = (sculptInvert ? !sculptMirror : sculptMirror); // XOR int numVertices, numIndices; List <Vector3> mesh = volume.Points; List <Vector3> profile = volume.Profile.Points; List <Path.PathPoint> pathData = volume.Path.Points; int maxS = volume.Profile.PointCount; int s, t, i; float ss, tt; numVertices = NumS * NumT; numIndices = (NumS - 1) * (NumT - 1) * 6; // TODO: How does partial builds work? //partial_build = (num_vertices > NumVertices || num_indices > NumIndices) ? false : partial_build; //if (!partial_build) //{ // resizeVertices(num_vertices); // resizeIndices(num_indices); // if (!volume->isMeshAssetLoaded()) // { // mEdge.resize(num_indices); // } //} Positions.Clear(); Normals.Clear(); Indices.Clear(); Edge.Clear(); float beginStex = Mathf.Floor(profile[BeginS][2]); bool test = TypeMask.HasFlag(VolumeFaceMask.Inner | VolumeFaceMask.Flat) && NumS > 2; int numS = test ? NumS / 2 : NumS; int curVertex = 0; int endT = BeginT + NumT; // Copy the vertices into the array for (t = BeginT; t < endT; t++) { tt = pathData[t].ExtrusionT; for (s = 0; s < numS; s++) { if (TypeMask.HasFlag(VolumeFaceMask.End)) { ss = s > 0 ? 1f : 0f; } else { // Get s value for tex-coord. if (!flat) { ss = profile[BeginS + s][2]; } else { ss = profile[BeginS + s][2] - beginStex; } } if (sculptReverseHorizontal) { ss = 1f - ss; } // Check to see if this triangle wraps around the array. if (BeginS + s >= maxS) { // We're wrapping i = BeginS + s + maxS * (t - 1); } else { i = BeginS + s + maxS * t; } Positions.Add(mesh[i]); Normals.Add(Vector3.zero); // This will be calculated later TexCoords.Add(new Vector2(ss, tt)); curVertex++; if (test && s > 0) { Positions.Add(mesh[i]); Normals.Add(Vector3.zero); // This will be calculated later TexCoords.Add(new Vector2(ss, tt)); curVertex++; } } if (test) { s = TypeMask.HasFlag(VolumeFaceMask.Open) ? numS - 1 : 0; i = BeginS + s + maxS * t; ss = profile[BeginS + s][2] - beginStex; Positions.Add(mesh[i]); Normals.Add(Vector3.zero); // This will be calculated later TexCoords.Add(new Vector2(ss, tt)); curVertex++; } } Centre = Vector3.zero; int curPos = 0; int endPos = Positions.Count; //get bounding box for this side Vector3 faceMin; Vector3 faceMax; faceMin = faceMax = Positions[curPos++]; while (curPos < endPos) { UpdateMinMax(ref faceMin, ref faceMax, Positions[curPos++]); } // VFExtents change ExtentsMin = faceMin; ExtentsMax = faceMax; int tcCount = NumVertices; if (tcCount % 2 == 1) { //odd number of texture coordinates, duplicate last entry to padded end of array tcCount++; TexCoords.Add(TexCoords[NumVertices - 1]); } int curTc = 0; int endTc = TexCoords.Count; Vector3 tcMin; Vector3 tcMax; tcMin = tcMax = TexCoords[curTc++]; while (curTc < endTc) { UpdateMinMax(ref tcMin, ref tcMax, TexCoords[curTc++]); } //TODO: TexCoordExtents are weird this assumes Vector4 //TexCoordExtentsMin.x = llmin(minp[0], minp[2]); //TexCoordExtentsMin.y = llmin(minp[1], minp[3]); //TexCoordExtentsMax.x = llmax(maxp[0], maxp[2]); //TexCoordExtentsMax.y = llmax(maxp[1], maxp[3]); Centre = (faceMin + faceMax) * 0.5f; bool flatFace = TypeMask.HasFlag(VolumeFaceMask.Flat); //(TypeMask & VolumeFaceMask.Flat) != 0; if (!partialBuild) { // Now we generate the indices. for (t = 0; t < (NumT - 1); t++) { for (s = 0; s < (NumS - 1); s++) { Indices.Add(s + NumS * t); //bottom left Indices.Add(s + 1 + NumS * (t + 1)); //top right Indices.Add(s + NumS * (t + 1)); //top left Indices.Add(s + NumS * t); //bottom left Indices.Add(s + 1 + NumS * t); //bottom right Indices.Add(s + 1 + NumS * (t + 1)); //top right Edge.Add((NumS - 1) * 2 * t + s * 2 + 1); //bottom left/top right neighbor face if (t < NumT - 2) { //top right/top left neighbor face Edge.Add((NumS - 1) * 2 * (t + 1) + s * 2 + 1); } else if (NumT <= 3 || volume.Path.IsOpen == true) { //no neighbor Edge.Add(-1); } else { //wrap on T Edge.Add(s * 2 + 1); } if (s > 0) { //top left/bottom left neighbor face Edge.Add((NumS - 1) * 2 * t + s * 2 - 1); } else if (flatFace || volume.Profile.IsOpen == true) { //no neighbor Edge.Add(-1); } else { //wrap on S Edge.Add((NumS - 1) * 2 * t + (NumS - 2) * 2 + 1); } if (t > 0) { //bottom left/bottom right neighbor face Edge.Add((NumS - 1) * 2 * (t - 1) + s * 2); } else if (NumT <= 3 || volume.Path.IsOpen == true) { //no neighbor Edge.Add(-1); } else { //wrap on T Edge.Add((NumS - 1) * 2 * (NumT - 2) + s * 2); } if (s < NumS - 2) { //bottom right/top right neighbor face Edge.Add((NumS - 1) * 2 * t + (s + 1) * 2); } else if (flatFace || volume.Profile.IsOpen == true) { //no neighbor Edge.Add(-1); } else { //wrap on S Edge.Add((NumS - 1) * 2 * t); } Edge.Add((NumS - 1) * 2 * t + s * 2); //top right/bottom left neighbor face } } } // //clear normals //int dst = Normals.Count; //int end = dst + NumVertices; //Vector3 zero = Vector3.zero; //while (dst < end) // { // Normals.Add(zero); // dst++; //} //generate normals // Compute triangle normals: int count = Indices.Count / 3; List <Vector3> triangleNormals = new List <Vector3>(); int idx = 0; for (int triangleIndex = 0; triangleIndex < count; triangleIndex++) { Vector3 p0 = Positions[Indices[idx + 0]]; Vector3 p1 = Positions[Indices[idx + 1]]; Vector3 p2 = Positions[Indices[idx + 2]]; //calculate triangle normal Vector3 a = p1 - p0; Vector3 b = p2 - p0; Vector3 normal = Vector3.Cross(a, b); if (Vector3.Dot(normal, normal) > 0.00001f) { normal.Normalize(); } else { //degenerate, make up a value normal = normal.z >= 0 ? new Vector3(0f, 0f, 1f) : new Vector3(0f, 0f, -1f); } // This is probably an optimised way to calculate this: //LLQuad & vector1 = *((LLQuad*)&v1); //LLQuad & vector2 = *((LLQuad*)&v2); //LLQuad & amQ = *((LLQuad*)&a); //LLQuad & bmQ = *((LLQuad*)&b); // Vectors are stored in memory in w, z, y, x order from high to low // Set vector1 = { a[W], a[X], a[Z], a[Y] } //vector1 = _mm_shuffle_ps(amQ, amQ, _MM_SHUFFLE(3, 0, 2, 1)); // Set vector2 = { b[W], b[Y], b[X], b[Z] } //vector2 = _mm_shuffle_ps(bmQ, bmQ, _MM_SHUFFLE(3, 1, 0, 2)); // mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] } //vector2 = _mm_mul_ps(vector1, vector2); // vector3 = { a[W], a[Y], a[X], a[Z] } //amQ = _mm_shuffle_ps(amQ, amQ, _MM_SHUFFLE(3, 1, 0, 2)); // vector4 = { b[W], b[X], b[Z], b[Y] } //bmQ = _mm_shuffle_ps(bmQ, bmQ, _MM_SHUFFLE(3, 0, 2, 1)); // mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] } //vector1 = _mm_sub_ps(vector2, _mm_mul_ps(amQ, bmQ)); //llassert(v1.isFinite3()); triangleNormals.Add(normal); idx += 3; } // Add triangle normal contributions from each triangle to the vertex normals: idx = 0; for (int triangleIndex = 0; triangleIndex < count; triangleIndex++) //for each triangle { Vector3 c = triangleNormals[triangleIndex]; Vector3 n0 = Normals[Indices[idx + 0]]; Vector3 n1 = Normals[Indices[idx + 1]]; Vector3 n2 = Normals[Indices[idx + 2]]; n0 += c; n1 += c; n2 += c; //llassert(c.isFinite3()); //even out quad contributions switch (triangleIndex % 2 + 1) { case 0: n0 += c; break; case 1: n1 += c; break; case 2: n2 += c; break; } ; Normals[Indices[idx + 0]] = n0; Normals[Indices[idx + 1]] = n1; Normals[Indices[idx + 2]] = n2; idx += 3; } // adjust normals based on wrapping and stitching Vector3 top = (Positions[0] - Positions[NumS * (NumT - 2)]); bool s_bottom_converges = Vector3.Dot(top, top) < 0.000001f; top = Positions[NumS - 1] - Positions[NumS * (NumT - 2) + NumS - 1]; bool s_top_converges = Vector3.Dot(top, top) < 0.000001f; if (sculptStitching == SculptType.None) // logic for non-sculpt volumes { if (volume.Path.IsOpen == false) { //wrap normals on T for (int j = 0; j < NumS; j++) { Vector3 n = Normals[j] + Normals[NumS * (NumT - 1) + j]; Normals[j] = n; Normals[NumS * (NumT - 1) + j] = n; } } if ((volume.Profile.IsOpen == false) && !(s_bottom_converges)) { //wrap normals on S for (int j = 0; j < NumT; j++) { Vector3 n = Normals[NumS * j] + Normals[NumS * j + NumS - 1]; Normals[NumS * j] = n; Normals[NumS * j + NumS - 1] = n; } } if (volume.Parameters.PathParameters.PathType == PathType.Circle && volume.Parameters.ProfileParameters.ProfileType == ProfileType.CircleHalf) { if (s_bottom_converges) { //all lower S have same normal for (int j = 0; j < NumT; j++) { Normals[NumS * j] = new Vector3(1f, 0f, 0f); } } if (s_top_converges) { //all upper S have same normal for (int j = 0; j < NumT; j++) { Normals[NumS * j + NumS - 1] = new Vector3(-1f, 0f, 0f); } } } } //else // logic for sculpt volumes //{ //BOOL average_poles = FALSE; //BOOL wrap_s = FALSE; //BOOL wrap_t = FALSE; //if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) // average_poles = TRUE; //if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || // (sculpt_stitching == LL_SCULPT_TYPE_TORUS) || // (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) // wrap_s = TRUE; //if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) // wrap_t = TRUE; //if (average_poles) //{ // // average normals for north pole // LLVector4a average; // average.clear(); // for (S32 i = 0; i < mNumS; i++) // { // average.add(norm[i]); // } // // set average // for (S32 i = 0; i < mNumS; i++) // { // norm[i] = average; // } // // average normals for south pole // average.clear(); // for (S32 i = 0; i < mNumS; i++) // { // average.add(norm[i + mNumS * (mNumT - 1)]); // } // // set average // for (S32 i = 0; i < mNumS; i++) // { // norm[i + mNumS * (mNumT - 1)] = average; // } // } //if (wrap_s) //{ // for (S32 i = 0; i < mNumT; i++) // { // LLVector4a n; // n.setAdd(norm[mNumS * i], norm[mNumS * i + mNumS - 1]); // norm[mNumS * i] = n; // norm[mNumS * i + mNumS - 1] = n; // } //} //if (wrap_t) //{ // for (S32 i = 0; i < mNumS; i++) // { // LLVector4a n; // n.setAdd(norm[i], norm[mNumS * (mNumT - 1) + i]); // norm[i] = n; // norm[mNumS * (mNumT - 1) + i] = n; // } //} //} // Normalise normals: for (int normalIndex = 0; normalIndex < Normals.Count; normalIndex++) { Normals[normalIndex] = Normals[normalIndex].normalized; } return(true); }
public void CalculateIndexes(float threshold) { if (!FlatShading) { Indices.Clear(); } else { Indices = new List <int>(); } List <int> tri_count = new List <int>(); tree.ProcessCell(Indices, tri_count, threshold); if (!FlatShading) { IndexCount = Indices.Count; if (Indices.Count == 0) { return; } for (int i = 0; i < Indices.Count; i++) { Indices[i] = Indices[i] & 0xFFFFFFF; } IndexBuffer.SetData <int>(Indices.ToArray()); } else { List <VertexPositionColorNormalNormal> new_vertices = new List <VertexPositionColorNormalNormal>(); List <VertexPositionColor> wire_verts = new List <VertexPositionColor>(); List <int> wire_indexes = new List <int>(); int t_index = 0; for (int i = 0; i < Indices.Count; i += 3) { int count = tri_count[t_index++]; Vector3 n = Vector3.Zero; if (count == 1) { n = GetNormalQ(VerticesDN, Indices[i + 2] & 0xFFFFFFF, Indices[i + 0] & 0xFFFFFFF, Indices[i + 1] & 0xFFFFFFF); } else { n = GetNormalQ(VerticesDN, Indices[i + 2] & 0xFFFFFFF, Indices[i + 0] & 0xFFFFFFF, Indices[i + 1] & 0xFFFFFFF, Indices[i + 5] & 0xFFFFFFF, Indices[i + 3] & 0xFFFFFFF, Indices[i + 4] & 0xFFFFFFF); } Vector3 nc = n * 0.5f + Vector3.One * 0.5f; nc.Normalize(); Color c = new Color(nc); VertexPositionColorNormalNormal v0 = new VertexPositionColorNormalNormal(VerticesDN[Indices[i + 0] & 0xFFFFFFF].Position, c, n, VerticesDN[Indices[i + 0] & 0xFFFFFFF].Normal); VertexPositionColorNormalNormal v1 = new VertexPositionColorNormalNormal(VerticesDN[Indices[i + 1] & 0xFFFFFFF].Position, c, n, VerticesDN[Indices[i + 1] & 0xFFFFFFF].Normal); VertexPositionColorNormalNormal v2 = new VertexPositionColorNormalNormal(VerticesDN[Indices[i + 2] & 0xFFFFFFF].Position, c, n, VerticesDN[Indices[i + 2] & 0xFFFFFFF].Normal); new_vertices.Add(v0); new_vertices.Add(v1); new_vertices.Add(v2); int start = wire_verts.Count; if (count > 1) { VertexPositionColorNormalNormal v3 = new VertexPositionColorNormalNormal(VerticesDN[Indices[i + 3] & 0xFFFFFFF].Position, c, n, VerticesDN[Indices[i + 3] & 0xFFFFFFF].Normal); VertexPositionColorNormalNormal v4 = new VertexPositionColorNormalNormal(VerticesDN[Indices[i + 4] & 0xFFFFFFF].Position, c, n, VerticesDN[Indices[i + 4] & 0xFFFFFFF].Normal); VertexPositionColorNormalNormal v5 = new VertexPositionColorNormalNormal(VerticesDN[Indices[i + 5] & 0xFFFFFFF].Position, c, n, VerticesDN[Indices[i + 5] & 0xFFFFFFF].Normal); new_vertices.Add(v3); new_vertices.Add(v4); new_vertices.Add(v5); if (Indices[i] >= 0x10000000) { //0-2, 2-1, 1-4, 4-0 wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 0] & 0xFFFFFFF].Position, c)); wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 1] & 0xFFFFFFF].Position, c)); wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 2] & 0xFFFFFFF].Position, c)); wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 4] & 0xFFFFFFF].Position, c)); wire_indexes.Add(start + 0); wire_indexes.Add(start + 2); wire_indexes.Add(start + 2); wire_indexes.Add(start + 1); wire_indexes.Add(start + 1); wire_indexes.Add(start + 3); wire_indexes.Add(start + 3); wire_indexes.Add(start + 0); } else { //0-1, 1-2, 2-5, 5-0 wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 0] & 0xFFFFFFF].Position, c)); wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 1] & 0xFFFFFFF].Position, c)); wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 2] & 0xFFFFFFF].Position, c)); wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 5] & 0xFFFFFFF].Position, c)); wire_indexes.Add(start + 0); wire_indexes.Add(start + 1); wire_indexes.Add(start + 1); wire_indexes.Add(start + 2); wire_indexes.Add(start + 2); wire_indexes.Add(start + 3); wire_indexes.Add(start + 3); wire_indexes.Add(start + 0); } i += 3; } else { wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 0] & 0xFFFFFFF].Position, c)); wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 1] & 0xFFFFFFF].Position, c)); wire_verts.Add(new VertexPositionColor(VerticesDN[Indices[i + 2] & 0xFFFFFFF].Position, c)); wire_indexes.Add(start + 0); wire_indexes.Add(start + 1); wire_indexes.Add(start + 1); wire_indexes.Add(start + 2); wire_indexes.Add(start + 2); wire_indexes.Add(start + 0); } } if (new_vertices.Count > 0) { VertexBuffer.SetData <VertexPositionColorNormalNormal>(new_vertices.ToArray()); } if (wire_verts.Count > 0) { WireframeBuffer.SetData <VertexPositionColor>(wire_verts.ToArray()); WireframeIndexBuffer.SetData <int>(wire_indexes.ToArray()); } VertexCount = new_vertices.Count; WireframeCount = wire_indexes.Count; WireframeVertexCount = wire_verts.Count; } }
protected override void ClearItems() { base.ClearItems(); Indices.Clear(); }
/// <summary> /// 頂点およびインデックスを初期化します。 /// </summary> public void Clear() { Vertices.Clear(); Indices.Clear(); }
protected bool CreateUnCutCubeCap(Volume volume, bool partialBuild) { List <Vector3> mesh = volume.Points; List <Vector3> profile = volume.Profile.Points; int maxS = volume.Profile.PointCount; int maxT = volume.Path.PointCount; int gridSize = (profile.Count - 1) / 4; // VFExtents change Vector3 min = ExtentsMin; Vector3 max = ExtentsMax; int offset = ((TypeMask & VolumeFaceMask.Top) != 0) ? (maxT - 1) * maxS : BeginS; { VertexData[] corners = new VertexData[4]; VertexData baseVert = new VertexData(); for (int t = 0; t < 4; t++) { corners[t] = new VertexData { Position = mesh[offset + (gridSize * t)], TexCoord = new Vector2(profile[gridSize * t].x + 0.5f, 0.5f - profile[gridSize * t].y) }; } { Vector3 lhs = corners[1].Position - corners[0].Position; Vector3 rhs = corners[2].Position - corners[1].Position; baseVert.Normal = Vector3.Cross(lhs, rhs); baseVert.Normal.Normalize(); } if ((TypeMask & VolumeFaceMask.Top) == 0) { baseVert.Normal *= -1.0f; } else { //Swap the UVs on the U(X) axis for top face Vector2 swap; swap = corners[0].TexCoord; corners[0].TexCoord = corners[3].TexCoord; corners[3].TexCoord = swap; swap = corners[1].TexCoord; corners[1].TexCoord = corners[2].TexCoord; corners[2].TexCoord = swap; } int size = (gridSize + 1) * (gridSize + 1); //resizeVertices(size); Positions.Clear(); Normals.Clear(); Tangents.Clear(); TexCoords.Clear(); Indices.Clear(); Edge.Clear(); for (int gx = 0; gx < gridSize + 1; gx++) { for (int gy = 0; gy < gridSize + 1; gy++) { VertexData newVert = LerpPlanarVertex(corners[0], corners[1], corners[3], (float)gx / (float)gridSize, (float)gy / (float)gridSize); Positions.Add(newVert.Position); Normals.Add(baseVert.Normal); TexCoords.Add(newVert.TexCoord); if (gx == 0 && gy == 0) { min = newVert.Position; max = min; } else { UpdateMinMax(ref min, ref max, newVert.Position); } } } Centre = (min + max) * 0.5f; ExtentsMin = min; ExtentsMax = max; } if (!partialBuild) { int[] idxs = { 0, 1, (gridSize + 1) + 1, (gridSize + 1) + 1, (gridSize + 1), 0 }; for (int gx = 0; gx < gridSize; gx++) { for (int gy = 0; gy < gridSize; gy++) { if ((TypeMask & VolumeFaceMask.Top) != 0) { for (int i = 5; i >= 0; i--) { Indices.Add((gy * (gridSize + 1)) + gx + idxs[i]); } int edgeValue = gridSize * 2 * gy + gx * 2; if (gx > 0) { Edge.Add(edgeValue); } else { Edge.Add(-1); // Mark face to higlight it } if (gy < gridSize - 1) { Edge.Add(edgeValue); } else { Edge.Add(-1); } Edge.Add(edgeValue); if (gx < gridSize - 1) { Edge.Add(edgeValue); } else { Edge.Add(-1); } if (gy > 0) { Edge.Add(edgeValue); } else { Edge.Add(-1); } Edge.Add(edgeValue); } else { for (int i = 0; i < 6; i++) { Indices.Add((gy * (gridSize + 1)) + gx + idxs[i]); } int edgeValue = gridSize * 2 * gy + gx * 2; if (gy > 0) { Edge.Add(edgeValue); } else { Edge.Add(-1); } if (gx < gridSize - 1) { Edge.Add(edgeValue); } else { Edge.Add(-1); } Edge.Add(edgeValue); if (gy < gridSize - 1) { Edge.Add(edgeValue); } else { Edge.Add(-1); } if (gx > 0) { Edge.Add(edgeValue); } else { Edge.Add(-1); } Edge.Add(edgeValue); } } } } return(true); }