/// <summary> /// Clones this object. /// </summary> public VertexStructureSurface Clone( VertexStructure newOwner, bool copyGeometryData = true, int capacityMultiplier = 1, int baseIndex = 0) { newOwner.EnsureNotNull(nameof(newOwner)); // Create new VertexStructure object int indexCount = m_indices.Count; VertexStructureSurface result = new VertexStructureSurface(newOwner, (indexCount / 3) * capacityMultiplier); // Copy geometry if (copyGeometryData) { for (int loop = 0; loop < indexCount; loop++) { result.m_indices.Add(m_indices[loop] + baseIndex); } } // Copy metadata result.m_materialProperties = m_materialProperties.Clone(); return(result); }
/// <summary> /// Creates the surface on this VertexStructure. /// </summary> /// <param name="triangleCapacity">The triangle capacity.</param> /// <param name="name">The internal name of the material.</param> public VertexStructureSurface CreateSurface(int triangleCapacity = 512, string name = "") { VertexStructureSurface newSurface = new VertexStructureSurface(this, triangleCapacity); newSurface.MaterialProperties.Name = name; m_surfaces.Add(newSurface); return(newSurface); }
/// <summary> /// Calculates normals for all triangles specifyed by the given parameters. /// </summary> /// <param name="startVertex">The vertex index on which to start.</param> /// <param name="vertexCount">Total count of vertices to be updated.</param> public void CalculateNormals(int startVertex, int vertexCount) { if ((startVertex < 0) || (startVertex >= m_rawGeometry.Count)) { throw new ArgumentException("startVertex"); } if (vertexCount + startVertex > m_rawGeometry.Count) { throw new ArgumentException("vertexCount"); } for (int actVertexIndex = startVertex; actVertexIndex < startVertex + vertexCount; actVertexIndex++) { // Find all triangles connected to this vertex and get normals from them Vector3 finalNormalHelper = Vector3.Zero; Vector3 finalNormalHelper2 = Vector3.Zero; int normalCount = 0; int surfaceCount = m_surfaces.Count; for (int actSurfaceIndex = 0; actSurfaceIndex < surfaceCount; actSurfaceIndex++) { VertexStructureSurface actSurface = m_surfaces[actSurfaceIndex]; int triangleCount = actSurface.CountTriangles; for (int loopTriangle = 0; loopTriangle < triangleCount; loopTriangle++) { int triangleStartIndex = loopTriangle * 3; if ((actSurface.IndicesInternal[triangleStartIndex] == actVertexIndex) || (actSurface.IndicesInternal[triangleStartIndex + 1] == actVertexIndex) || (actSurface.IndicesInternal[triangleStartIndex + 2] == actVertexIndex)) { GeometryData geo1 = m_rawGeometry[actSurface.IndicesInternal[triangleStartIndex]]; GeometryData geo2 = m_rawGeometry[actSurface.IndicesInternal[triangleStartIndex + 1]]; GeometryData geo3 = m_rawGeometry[actSurface.IndicesInternal[triangleStartIndex + 2]]; finalNormalHelper += Vector3Ex.CalculateTriangleNormal(geo1.Position, geo2.Position, geo3.Position, false); normalCount++; } } } // Calculate final normal if (normalCount > 0) { GeometryData actGeometry = m_rawGeometry[actVertexIndex]; actGeometry.Normal = finalNormalHelper / finalNormalHelper.Length(); m_rawGeometry[actVertexIndex] = actGeometry; normalCount = 0; } } }
/// <summary> /// Tries to get an existing surface using given MaterialProperties. /// If none exists, then a new surface is created. /// </summary> /// <param name="name">The internal name of the material.</param> /// <param name="triangleCapacity">The triangle capacity.</param> public VertexStructureSurface CreateOrGetExistingSurface(string name, int triangleCapacity = 512) { foreach (VertexStructureSurface actSurface in m_surfaces) { if (actSurface.MaterialProperties.Name == name) { return(actSurface); } } VertexStructureSurface result = CreateSurface(triangleCapacity); result.MaterialProperties.Name = name; return(result); }
/// <summary> /// Tries to get an existing surface using given MaterialProperties. /// If none exists, then a new surface is created. /// </summary> /// <param name="matProperties">The material properties.</param> /// <param name="triangleCapacity">The triangle capacity.</param> public VertexStructureSurface CreateOrGetExistingSurface(MaterialProperties matProperties, int triangleCapacity = 512) { foreach (VertexStructureSurface actSurface in m_surfaces) { if (actSurface.MaterialProperties == matProperties) { return(actSurface); } } VertexStructureSurface result = CreateSurface(triangleCapacity); result.MaterialProperties = matProperties; return(result); }
///// <summary> ///// Fits to centered cube. ///// </summary> //public void FitToCenteredCube() //{ // FitToCenteredCuboid(1f, 1f, 1f, FitToCuboidMode.MaintainAspectRatio, SpacialOriginLocation.Center); //} ///// <summary> ///// Fits to centered cube. ///// </summary> //public void FitToCenteredCube(float cubeSideLength) //{ // FitToCenteredCuboid(cubeSideLength, cubeSideLength, cubeSideLength, FitToCuboidMode.MaintainAspectRatio, SpacialOriginLocation.Center); //} ///// <summary> ///// Fits to centered cube. ///// </summary> //public void FitToCenteredCube(float cubeSideLength, FitToCuboidMode mode) //{ // FitToCenteredCuboid(cubeSideLength, cubeSideLength, cubeSideLength, mode, SpacialOriginLocation.Center); //} ///// <summary> ///// Fits to centered cube. ///// </summary> //public void FitToCenteredCube(float cubeSideLength, FitToCuboidMode mode, SpacialOriginLocation fitOrigin) //{ // FitToCenteredCuboid(cubeSideLength, cubeSideLength, cubeSideLength, mode, fitOrigin); //} ///// <summary> ///// Fits to centered cube. ///// </summary> //public void FitToCenteredCuboid(float cubeSideLengthX, float cubeSideLengthY, float cubeSideLengthZ, FitToCuboidMode fitMode, SpacialOriginLocation fitOrigin) //{ // //Get whole bounding box // BoundingBox boundingBox = this.GenerateBoundingBox(); // Vector3 boundingBoxSize = boundingBox.GetSize(); // if (boundingBox.IsEmpty()) { return; } // if (boundingBoxSize.X <= 0f) { return; } // if (boundingBoxSize.Y <= 0f) { return; } // if (boundingBoxSize.Z <= 0f) { return; } // Vector3 targetCornerALocation = new Vector3( // -boundingBoxSize.X / 2f, // -boundingBoxSize.Y / 2f, // -boundingBoxSize.Z / 2f); // // Calculate resize factors // float resizeFactorX = cubeSideLengthX / boundingBoxSize.X; // float resizeFactorY = cubeSideLengthY / boundingBoxSize.Y; // float resizeFactorZ = cubeSideLengthZ / boundingBoxSize.Z; // if (fitMode == FitToCuboidMode.MaintainAspectRatio) // { // resizeFactorX = Math.Min(resizeFactorX, Math.Min(resizeFactorY, resizeFactorZ)); // resizeFactorY = resizeFactorX; // resizeFactorZ = resizeFactorX; // } // targetCornerALocation.X = targetCornerALocation.X * resizeFactorX; // targetCornerALocation.Y = targetCornerALocation.Y * resizeFactorY; // targetCornerALocation.Z = targetCornerALocation.Z * resizeFactorZ; // switch (fitOrigin) // { // case SpacialOriginLocation.LowerCenter: // targetCornerALocation.Y = 0f; // break; // } // //Bring the structure to origin based location and then scale it // this.UpdateVerticesUsingRelocationBy(Vector3.Negate(boundingBox.CornerA)); // this.UpdateVerticesUsingRelocationFunc((actPosition) => new Vector3( // actPosition.X * resizeFactorX, // actPosition.Y * resizeFactorY, // actPosition.Z * resizeFactorZ)); // this.UpdateVerticesUsingRelocationBy(targetCornerALocation); //} public void RemoveSurface(VertexStructureSurface surface) { m_surfaces.Remove(surface); }