/// <summary> /// Generates a shadow volume structure out of the given vertex structures. /// </summary> public static VertexStructure GenerateShadowVolume(this IEnumerable <VertexStructure> structures, Vector3 lightDirection, float shadowVolumeLength) { VertexStructure result = new VertexStructure(); //Find all edges from given view direction List <Line> shadowVolumeEdges = GenerateEdgesSeenFromViewpoint(structures, lightDirection); //Build the structure based on the found edges Vector3 lightNormal = Vector3.Normalize(lightDirection); VertexStructureSurface actSurface = result.FirstSurface; foreach (Line actEdge in shadowVolumeEdges) { Line targetEdge = new Line( actEdge.StartPosition + lightNormal * shadowVolumeLength, actEdge.EndPosition + lightNormal * shadowVolumeLength); actSurface.AddTriangle( new Vertex(actEdge.StartPosition, Color4.White), new Vertex(actEdge.EndPosition, Color4.White), new Vertex(targetEdge.EndPosition, Color4.White)); actSurface.AddTriangle( new Vertex(targetEdge.EndPosition, Color4.White), new Vertex(targetEdge.StartPosition, Color4.White), new Vertex(actEdge.StartPosition, Color4.White)); } return(result); }
/// <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> /// Applies the material with the given name for following surfaces. /// </summary> /// <param name="arguments">Passed argumetns.</param> private void HandleKeyword_Obj_UseMtl(string arguments) { string[] names = arguments.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (names.Length != 1) { throw new SeeingSharpGraphicsException($"Invalid count of arguments for keyword 'usemtl', (expected=1, got={names.Length})!"); } m_currentSurface = m_targetVertexStructure.CreateOrGetExistingSurfaceByName((string)names[0]); }
/// <summary> /// Reads the definition of a new material. /// </summary> /// <param name="arguments">Passed argumetns.</param> private void HandleKeyword_Mtl_NewMtl(string arguments) { string[] names = arguments.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (names.Length != 1) { throw new SeeingSharpGraphicsException($"Invalid count of arguments for keyword 'newmtl', (expected=1, got={names.Length})!"); } m_currentMaterialDefinition = m_targetVertexStructure.CreateSurface(name: names[0]); }
/// <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_vertices.Count)) { throw new ArgumentException("startVertex"); } if (vertexCount + startVertex > m_vertices.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)) { Vertex v1 = m_vertices[actSurface.IndicesInternal[triangleStartIndex]]; Vertex v2 = m_vertices[actSurface.IndicesInternal[triangleStartIndex + 1]]; Vertex v3 = m_vertices[actSurface.IndicesInternal[triangleStartIndex + 2]]; finalNormalHelper += Vector3Ex.CalculateTriangleNormal(v1.Geometry.Position, v2.Geometry.Position, v3.Geometry.Position, false); normalCount++; } } } // Calculate final normal if (normalCount > 0) { Vertex actVertex = m_vertices[actVertexIndex]; actVertex.Normal = finalNormalHelper / finalNormalHelper.Length(); m_vertices[actVertexIndex] = actVertex; normalCount = 0; } } }
/// <summary> /// Builds all vertex structures for the given detail level. /// </summary> /// <param name="buildOptions">Some generic options for structure building</param> public override VertexStructure BuildStructure(StructureBuildOptions buildOptions) { VertexStructure structureFromChild = m_objTypeToStack.BuildStructure(buildOptions); structureFromChild.EnsureNotNull(nameof(structureFromChild)); BoundingBox childStructBox = structureFromChild.GenerateBoundingBox(); Vector3 correctionVector = -childStructBox.GetBottomCenter(); // Copy metadata infomration of the VertexStructures VertexStructure result = structureFromChild.Clone( copyGeometryData: false, capacityMultiplier: m_stackSize); // Build geometry for (int loop = 0; loop < m_stackSize; loop++) { float actYCorrection = childStructBox.Height * loop; Vector3 localCorrection = new Vector3(correctionVector.X, correctionVector.Y + actYCorrection, correctionVector.Z); int baseVertex = loop * structureFromChild.CountVertices; foreach (Vertex actVertex in structureFromChild.Vertices) { // Change vertex properties based on stack position Vertex changedVertex = actVertex; changedVertex.Position = changedVertex.Position + localCorrection; if (loop % 2 == 1) { changedVertex.Color = changedVertex.Color.ChangeColorByLight(0.05f); } // Add the vertex result.AddVertex(changedVertex); } // Clone all surfaces foreach (VertexStructureSurface actSurfaceFromChild in structureFromChild.Surfaces) { VertexStructureSurface newSurface = result.CreateSurface(actSurfaceFromChild.CountTriangles); foreach (Triangle actTriangle in actSurfaceFromChild.Triangles) { newSurface.AddTriangle( baseVertex + actTriangle.Index1, baseVertex + actTriangle.Index2, baseVertex + actTriangle.Index3); } } } return(result); }
/// <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> /// IDWriteTextLayout::Draw calls this function to instruct the client to render a run of glyphs. /// </summary> /// <param name="clientDrawingContext">The application-defined drawing context passed to <see cref="M:SharpDX.DirectWrite.TextLayout.Draw_(System.IntPtr,System.IntPtr,System.Single,System.Single)" />.</param> /// <param name="baselineOriginX">The pixel location (X-coordinate) at the baseline origin of the glyph run.</param> /// <param name="baselineOriginY">The pixel location (Y-coordinate) at the baseline origin of the glyph run.</param> /// <param name="measuringMode">The measuring method for glyphs in the run, used with the other properties to determine the rendering mode.</param> /// <param name="glyphRun">Pointer to the glyph run instance to render.</param> /// <param name="glyphRunDescription">A pointer to the optional glyph run description instance which contains properties of the characters associated with this run.</param> /// <param name="clientDrawingEffect">Application-defined drawing effects for the glyphs to render. Usually this argument represents effects such as the foreground brush filling the interior of text.</param> /// <returns> /// If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// </returns> /// <unmanaged>HRESULT DrawGlyphRun([None] void* clientDrawingContext,[None] FLOAT baselineOriginX,[None] FLOAT baselineOriginY,[None] DWRITE_MEASURING_MODE measuringMode,[In] const DWRITE_GLYPH_RUN* glyphRun,[In] const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription,[None] IUnknown* clientDrawingEffect)</unmanaged> /// <remarks> /// The <see cref="M:SharpDX.DirectWrite.TextLayout.Draw_(System.IntPtr,System.IntPtr,System.Single,System.Single)" /> function calls this callback function with all the information about glyphs to render. The application implements this callback by mostly delegating the call to the underlying platform's graphics API such as {{Direct2D}} to draw glyphs on the drawing context. An application that uses GDI can implement this callback in terms of the <see cref="M:SharpDX.DirectWrite.BitmapRenderTarget.DrawGlyphRun(System.Single,System.Single,SharpDX.Direct2D1.MeasuringMode,SharpDX.DirectWrite.GlyphRun,SharpDX.DirectWrite.RenderingParams,SharpDX.Color4)" /> method. /// </remarks> public override SDX.Result DrawGlyphRun( object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, GlyphRun glyphRun, GlyphRunDescription glyphRunDescription, SDX.ComObject clientDrawingEffect) { if ((glyphRun.Indices == null) || (glyphRun.Indices.Length == 0)) { return(SDX.Result.Ok);; } SharpDX.DirectWrite.Factory dWriteFactory = GraphicsCore.Current.FactoryDWrite; SharpDX.Direct2D1.Factory d2DFactory = GraphicsCore.Current.FactoryD2D; // Extrude geometry data out of given glyph run SimplePolygon2DGeometrySink geometryExtruder = new SimplePolygon2DGeometrySink(new Vector2(baselineOriginX, baselineOriginY)); using (PathGeometry pathGeometry = new PathGeometry(d2DFactory)) { // Write all geometry data into a standard PathGeometry object using (GeometrySink geoSink = pathGeometry.Open()) { glyphRun.FontFace.GetGlyphRunOutline( glyphRun.FontSize, glyphRun.Indices, glyphRun.Advances, glyphRun.Offsets, glyphRun.IsSideways, glyphRun.BidiLevel % 2 == 1, geoSink); geoSink.Close(); } // Simplify written geometry and write it into own structure pathGeometry.Simplify(GeometrySimplificationOption.Lines, m_geometryOptions.SimplificationFlatternTolerance, geometryExtruder); } // Structure for caching the result VertexStructure tempStructure = new VertexStructure(); VertexStructureSurface tempSurface = tempStructure.CreateSurface(); // Create the text surface if (m_geometryOptions.MakeSurface) { // Separate polygons by clock direction // Order polygons as needed for further hole finding algorithm IEnumerable <Polygon2D> fillingPolygons = geometryExtruder.GeneratedPolygons .Where(actPolygon => actPolygon.EdgeOrder == EdgeOrder.CounterClockwise) .OrderBy(actPolygon => actPolygon.BoundingBox.Size.X * actPolygon.BoundingBox.Size.Y); List <Polygon2D> holePolygons = geometryExtruder.GeneratedPolygons .Where(actPolygon => actPolygon.EdgeOrder == EdgeOrder.Clockwise) .OrderByDescending(actPolygon => actPolygon.BoundingBox.Size.X * actPolygon.BoundingBox.Size.Y) .ToList(); // Build geometry for all polygons int loopPolygon = 0; foreach (Polygon2D actFillingPolygon in fillingPolygons) { // Find all corresponding holes BoundingBox2D actFillingPolygonBounds = actFillingPolygon.BoundingBox; IEnumerable <Polygon2D> correspondingHoles = holePolygons .Where(actHolePolygon => actHolePolygon.BoundingBox.IsContainedBy(actFillingPolygonBounds)) .ToList(); // Two steps here: // - Merge current filling polygon and all its holes. // - Remove found holes from current hole list Polygon2D polygonForRendering = actFillingPolygon; Polygon2D polygonForTriangulation = actFillingPolygon.Clone(); List <Vector2> cutPoints = new List <Vector2>(); foreach (Polygon2D actHole in correspondingHoles) { holePolygons.Remove(actHole); polygonForRendering = polygonForRendering.MergeWithHole(actHole, Polygon2DMergeOptions.Default, cutPoints); polygonForTriangulation = polygonForTriangulation.MergeWithHole(actHole, new Polygon2DMergeOptions() { MakeMergepointSpaceForTriangulation = true }); } loopPolygon++; int actBaseIndex = (int)tempStructure.CountVertices; EdgeOrder edgeOrder = polygonForRendering.EdgeOrder; float edgeSize = edgeOrder == EdgeOrder.CounterClockwise ? 0.1f : 0.4f; // Append all vertices to temporary VertexStructure for (int loop = 0; loop < polygonForRendering.Vertices.Count; loop++) { // Calculate 3d location and texture coordinate Vector3 actVertexLocation = new Vector3( polygonForRendering.Vertices[loop].X, 0f, polygonForRendering.Vertices[loop].Y); Vector2 actTexCoord = new Vector2( (polygonForRendering.Vertices[loop].X - polygonForRendering.BoundingBox.Location.X) / polygonForRendering.BoundingBox.Size.X, (polygonForRendering.Vertices[loop].Y - polygonForRendering.BoundingBox.Location.Y) / polygonForRendering.BoundingBox.Size.Y); if (float.IsInfinity(actTexCoord.X) || float.IsNaN(actTexCoord.X)) { actTexCoord.X = 0f; } if (float.IsInfinity(actTexCoord.Y) || float.IsNaN(actTexCoord.Y)) { actTexCoord.Y = 0f; } // Append the vertex to the result tempStructure.AddVertex( new Vertex( actVertexLocation, m_geometryOptions.SurfaceVertexColor, actTexCoord, new Vector3(0f, 1f, 0f))); } // Generate cubes on each vertex if requested if (m_geometryOptions.GenerateCubesOnVertices) { for (int loop = 0; loop < polygonForRendering.Vertices.Count; loop++) { Color4 colorToUse = Color4.GreenColor; float pointRenderSize = 0.1f; if (cutPoints.Contains(polygonForRendering.Vertices[loop])) { colorToUse = Color4.RedColor; pointRenderSize = 0.15f; } Vector3 actVertexLocation = new Vector3( polygonForRendering.Vertices[loop].X, 0f, polygonForRendering.Vertices[loop].Y); tempSurface.BuildCube24V(actVertexLocation, pointRenderSize, colorToUse); } } // Triangulate the polygon IEnumerable <int> triangleIndices = polygonForTriangulation.TriangulateUsingCuttingEars(); if (triangleIndices == null) { continue; } if (triangleIndices == null) { throw new SeeingSharpGraphicsException("Unable to triangulate given PathGeometry object!"); } // Append all triangles to the temporary structure using (IEnumerator <int> indexEnumerator = triangleIndices.GetEnumerator()) { while (indexEnumerator.MoveNext()) { int index1 = indexEnumerator.Current; int index2 = 0; int index3 = 0; if (indexEnumerator.MoveNext()) { index2 = indexEnumerator.Current; } else { break; } if (indexEnumerator.MoveNext()) { index3 = indexEnumerator.Current; } else { break; } tempSurface.AddTriangle( (int)(actBaseIndex + index3), (int)(actBaseIndex + index2), (int)(actBaseIndex + index1)); } } } } // Make volumetric outlines int triangleCountWithoutSide = tempSurface.CountTriangles; if (m_geometryOptions.MakeVolumetricText) { float volumetricTextDepth = m_geometryOptions.VolumetricTextDepth; if (m_geometryOptions.VerticesScaleFactor > 0f) { volumetricTextDepth = volumetricTextDepth / m_geometryOptions.VerticesScaleFactor; } // Add all side surfaces foreach (Polygon2D actPolygon in geometryExtruder.GeneratedPolygons) { foreach (Line2D actLine in actPolygon.Lines) { tempSurface.BuildRect4V( new Vector3(actLine.StartPosition.X, -volumetricTextDepth, actLine.StartPosition.Y), new Vector3(actLine.EndPosition.X, -volumetricTextDepth, actLine.EndPosition.Y), new Vector3(actLine.EndPosition.X, 0f, actLine.EndPosition.Y), new Vector3(actLine.StartPosition.X, 0f, actLine.StartPosition.Y), m_geometryOptions.VolumetricSideSurfaceVertexColor); } } } // Do also make back surface? if (m_geometryOptions.MakeBackSurface) { for (int loop = 0; loop < triangleCountWithoutSide; loop++) { Triangle triangle = tempSurface.Triangles[loop]; Vertex vertex0 = tempStructure.Vertices[triangle.Index1]; Vertex vertex1 = tempStructure.Vertices[triangle.Index2]; Vertex vertex2 = tempStructure.Vertices[triangle.Index3]; Vector3 changeVector = new Vector3(0f, -m_geometryOptions.VolumetricTextDepth, 0f); tempSurface.AddTriangle( vertex2.Copy(vertex2.Position - changeVector, Vector3.Negate(vertex2.Normal)), vertex1.Copy(vertex1.Position - changeVector, Vector3.Negate(vertex1.Normal)), vertex0.Copy(vertex0.Position - changeVector, Vector3.Negate(vertex0.Normal))); } } // TODO: Make this configurable tempStructure.ToggleCoordinateSystem(); // Scale the text using given scale factor if (m_geometryOptions.VerticesScaleFactor > 0f) { Matrix4x4 scaleMatrix = Matrix4x4.CreateScale( m_geometryOptions.VerticesScaleFactor, m_geometryOptions.VerticesScaleFactor, m_geometryOptions.VerticesScaleFactor); Matrix4Stack transformMatrix = new Matrix4Stack(scaleMatrix); transformMatrix.TransformLocal(m_geometryOptions.VertexTransform); tempStructure.UpdateVerticesUsingRelocationFunc((actVector) => Vector3.Transform(actVector, transformMatrix.Top)); } // Calculate all normals before adding to target structure if (m_geometryOptions.CalculateNormals) { tempStructure.CalculateNormalsFlat(); } // Merge temporary structure to target structure m_targetSurface.AddStructure(tempStructure); return(SDX.Result.Ok); }
/// <summary> /// Initializes a new instance of the <see cref="VertexStructureTextRenderer" /> class. /// </summary> public VertexStructureTextRenderer(VertexStructureSurface targetSurface, TextGeometryOptions textGeometryOptions) : base() { m_targetSurface = targetSurface; m_geometryOptions = textGeometryOptions; }
/// <summary> /// Reads a triangle from a binary STL file. /// </summary> private void ReadTriangle(BinaryReader reader, VertexStructure vertexStructure, StlImportOptions importOptions) { float ni = ReadFloat(reader); float nj = ReadFloat(reader); float nk = ReadFloat(reader); var normal = new Vector3(ni, nj, nk); float x1 = ReadFloat(reader); float y1 = ReadFloat(reader); float z1 = ReadFloat(reader); var v1 = new Vector3(x1, y1, z1); float x2 = ReadFloat(reader); float y2 = ReadFloat(reader); float z2 = ReadFloat(reader); var v2 = new Vector3(x2, y2, z2); float x3 = ReadFloat(reader); float y3 = ReadFloat(reader); float z3 = ReadFloat(reader); var v3 = new Vector3(x3, y3, z3); // Try to read color information var attrib = Convert.ToString(ReadUInt16(reader), 2).PadLeft(16, '0').ToCharArray(); var hasColor = attrib[0].Equals('1'); Color currentColor = Color.Transparent; if (hasColor) { int blue = attrib[15].Equals('1') ? 1 : 0; blue = attrib[14].Equals('1') ? blue + 2 : blue; blue = attrib[13].Equals('1') ? blue + 4 : blue; blue = attrib[12].Equals('1') ? blue + 8 : blue; blue = attrib[11].Equals('1') ? blue + 16 : blue; int b = blue * 8; int green = attrib[10].Equals('1') ? 1 : 0; green = attrib[9].Equals('1') ? green + 2 : green; green = attrib[8].Equals('1') ? green + 4 : green; green = attrib[7].Equals('1') ? green + 8 : green; green = attrib[6].Equals('1') ? green + 16 : green; int g = green * 8; int red = attrib[5].Equals('1') ? 1 : 0; red = attrib[4].Equals('1') ? red + 2 : red; red = attrib[3].Equals('1') ? red + 4 : red; red = attrib[2].Equals('1') ? red + 8 : red; red = attrib[1].Equals('1') ? red + 16 : red; int r = red * 8; currentColor = new Color(Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b)); } VertexStructureSurface targetSurface = vertexStructure.FirstSurface; if (importOptions.IsChangeTriangleOrderNeeded()) { targetSurface.AddTriangle( new Vertex(v3, currentColor, Vector2.Zero, normal), new Vertex(v2, currentColor, Vector2.Zero, normal), new Vertex(v1, currentColor, Vector2.Zero, normal)); } else { targetSurface.AddTriangle( new Vertex(v1, currentColor, Vector2.Zero, normal), new Vertex(v2, currentColor, Vector2.Zero, normal), new Vertex(v3, currentColor, Vector2.Zero, normal)); } }
/// <summary> /// Builds the structure needed for the pallet /// </summary> /// <param name="buildOptions">Some generic options for structure building</param> public override VertexStructure BuildStructure(StructureBuildOptions buildOptions) { VertexStructure result = new VertexStructure(); VertexStructureSurface surface = result.CreateSurface(); //Build pallet #region ----------------------------------------------------------- if (buildOptions.IsHighDetail) { float middleFront = m_width / 2f; float middleSide = m_depth / 2f; float middleFrontBegin = middleFront - m_bigFooterWidth / 2f; float middleSideBegin = middleSide - m_bigFooterWidth / 2f; float lastBeginSmall = m_width - m_smallFooterWidth; float lastBeginBig = m_depth - m_bigFooterWidth; float footerHeight = m_palletHeight - m_boardHeight * 3f; float quarterFrontBegin = ((m_bigFooterWidth / 2f) + ((middleFront - (m_bigFooterWidth / 2f)) / 2f)) - (m_smallFooterWidth / 2f); // +(middleFront / 2f - m_smallFooterWidth / 2f); float threeQuarterFrontBegin = middleFront + (middleFront - quarterFrontBegin - m_smallFooterWidth); //(middleFront / 2f) * 3f - m_smallFooterWidth / 2f; for (int loop = 0; loop < m_palletCount; loop++) { Color4 actColor = loop % 2 == 0 ? m_palletColor : m_palletCollor2; float actYCoord = m_palletHeight * loop; surface.Material = m_palletMaterial; //Build 3 board on bottom surface.BuildCube24V(new Vector3(0f, actYCoord, 0f), new Vector3(m_smallFooterWidth, m_boardHeight, m_depth), actColor); surface.BuildCube24V(new Vector3(middleFrontBegin, actYCoord, 0f), new Vector3(m_bigFooterWidth, m_boardHeight, m_depth), actColor); surface.BuildCube24V(new Vector3(lastBeginSmall, actYCoord, 0f), new Vector3(m_smallFooterWidth, m_boardHeight, m_depth), actColor); //Build 9 footers surface.BuildCubeSides16V(new Vector3(0f, m_boardHeight + actYCoord, 0f), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), actColor); surface.BuildCubeSides16V(new Vector3(0f, m_boardHeight + actYCoord, middleSideBegin), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), actColor); surface.BuildCubeSides16V(new Vector3(0f, m_boardHeight + actYCoord, lastBeginBig), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), actColor); surface.BuildCubeSides16V(new Vector3(middleFrontBegin, m_boardHeight + actYCoord, 0f), new Vector3(m_bigFooterWidth, footerHeight, m_bigFooterWidth), actColor); surface.BuildCubeSides16V(new Vector3(middleFrontBegin, m_boardHeight + actYCoord, middleSideBegin), new Vector3(m_bigFooterWidth, footerHeight, m_bigFooterWidth), actColor); surface.BuildCubeSides16V(new Vector3(middleFrontBegin, m_boardHeight + actYCoord, lastBeginBig), new Vector3(m_bigFooterWidth, footerHeight, m_bigFooterWidth), actColor); surface.BuildCubeSides16V(new Vector3(lastBeginSmall, m_boardHeight + actYCoord, 0f), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), actColor); surface.BuildCubeSides16V(new Vector3(lastBeginSmall, m_boardHeight + actYCoord, middleSideBegin), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), actColor); surface.BuildCubeSides16V(new Vector3(lastBeginSmall, m_boardHeight + actYCoord, lastBeginBig), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), actColor); //Build boards above footers surface.BuildCube24V(new Vector3(0f, m_boardHeight + footerHeight + actYCoord, 0f), new Vector3(m_width, m_boardHeight, m_bigFooterWidth), actColor); surface.BuildCube24V(new Vector3(0f, m_boardHeight + footerHeight + actYCoord, middleSideBegin), new Vector3(m_width, m_boardHeight, m_bigFooterWidth), actColor); surface.BuildCube24V(new Vector3(0f, m_boardHeight + footerHeight + actYCoord, lastBeginBig), new Vector3(m_width, m_boardHeight, m_bigFooterWidth), actColor); //Build top boards float localYPos = m_palletHeight - m_boardHeight; surface.BuildCube24V(new Vector3(0f, localYPos + actYCoord, 0f), new Vector3(m_bigFooterWidth, m_boardHeight, m_depth), actColor); surface.BuildCube24V(new Vector3(middleFrontBegin, localYPos + actYCoord, 0f), new Vector3(m_bigFooterWidth, m_boardHeight, m_depth), actColor); surface.BuildCube24V(new Vector3(m_width - m_bigFooterWidth, localYPos + actYCoord, 0f), new Vector3(m_bigFooterWidth, m_boardHeight, m_depth), actColor); surface.BuildCube24V(new Vector3(quarterFrontBegin, localYPos + actYCoord, 0f), new Vector3(m_smallFooterWidth, m_boardHeight, m_depth), actColor); surface.BuildCube24V(new Vector3(threeQuarterFrontBegin, localYPos + actYCoord, 0f), new Vector3(m_smallFooterWidth, m_boardHeight, m_depth), actColor); } } else { for (int loop = 0; loop < m_palletCount; loop++) { Color4 actColor = loop % 2 == 0 ? m_palletColor : m_palletCollor2; surface.BuildCube24V( new Vector3(0f, m_palletHeight * loop, 0f), new Vector3(m_width, m_palletHeight, m_depth), actColor); } } #endregion ----------------------------------------------------------- Matrix4x4 rotMatrix = Matrix4x4.CreateRotationY(EngineMath.RAD_90DEG); result.UpdateVerticesUsingRelocationBy(new Vector3(-m_width / 2f, 0f, -m_depth / 2f)); result.CalculateTangentsAndBinormals(); result.TransformVertices(rotMatrix); result.FitToCenteredCube(1f, FitToCuboidMode.Stretch, SpacialOriginLocation.LowerCenter); return(result); }
/// <summary> /// Builds the structure needed for the pallet /// </summary> /// <param name="buildOptions">Some generic options for structure building</param> public override VertexStructure BuildStructure(StructureBuildOptions buildOptions) { bool createContent = m_contentHeight > 0f; // Prepare result array VertexStructure result = new VertexStructure(); VertexStructureSurface surfacePallet = result.CreateSurface(); VertexStructureSurface surfaceContent = null; if (createContent) { surfaceContent = result.CreateSurface(); } // Build pallet #region ----------------------------------------------------------- if (buildOptions.IsHighDetail) { float middleFront = m_width / 2f; float middleSide = m_depth / 2f; float middleFrontBegin = middleFront - m_bigFooterWidth / 2f; float middleSideBegin = middleSide - m_bigFooterWidth / 2f; float lastBeginSmall = m_width - m_smallFooterWidth; float lastBeginBig = m_depth - m_bigFooterWidth; float footerHeight = m_palletHeight - m_boardHeight * 3f; float quarterFrontBegin = ((m_bigFooterWidth / 2f) + ((middleFront - (m_bigFooterWidth / 2f)) / 2f)) - (m_smallFooterWidth / 2f); // +(middleFront / 2f - m_smallFooterWidth / 2f); float threeQuarterFrontBegin = middleFront + (middleFront - quarterFrontBegin - m_smallFooterWidth); //(middleFront / 2f) * 3f - m_smallFooterWidth / 2f; surfacePallet.Material = m_palletMaterial; // Build 3 board on bottom surfacePallet.BuildCube24V(new Vector3(0f, 0f, 0f), new Vector3(m_smallFooterWidth, m_boardHeight, m_depth), m_palletColor); surfacePallet.BuildCube24V(new Vector3(middleFrontBegin, 0f, 0f), new Vector3(m_bigFooterWidth, m_boardHeight, m_depth), m_palletColor); surfacePallet.BuildCube24V(new Vector3(lastBeginSmall, 0f, 0f), new Vector3(m_smallFooterWidth, m_boardHeight, m_depth), m_palletColor); // Build 9 footers surfacePallet.BuildCubeSides16V(new Vector3(0f, m_boardHeight, 0f), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), m_palletColor); surfacePallet.BuildCubeSides16V(new Vector3(0f, m_boardHeight, middleSideBegin), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), m_palletColor); surfacePallet.BuildCubeSides16V(new Vector3(0f, m_boardHeight, lastBeginBig), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), m_palletColor); surfacePallet.BuildCubeSides16V(new Vector3(middleFrontBegin, m_boardHeight, 0f), new Vector3(m_bigFooterWidth, footerHeight, m_bigFooterWidth), m_palletColor); surfacePallet.BuildCubeSides16V(new Vector3(middleFrontBegin, m_boardHeight, middleSideBegin), new Vector3(m_bigFooterWidth, footerHeight, m_bigFooterWidth), m_palletColor); surfacePallet.BuildCubeSides16V(new Vector3(middleFrontBegin, m_boardHeight, lastBeginBig), new Vector3(m_bigFooterWidth, footerHeight, m_bigFooterWidth), m_palletColor); surfacePallet.BuildCubeSides16V(new Vector3(lastBeginSmall, m_boardHeight, 0f), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), m_palletColor); surfacePallet.BuildCubeSides16V(new Vector3(lastBeginSmall, m_boardHeight, middleSideBegin), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), m_palletColor); surfacePallet.BuildCubeSides16V(new Vector3(lastBeginSmall, m_boardHeight, lastBeginBig), new Vector3(m_smallFooterWidth, footerHeight, m_bigFooterWidth), m_palletColor); // Build boards above footers surfacePallet.BuildCube24V(new Vector3(0f, m_boardHeight + footerHeight, 0f), new Vector3(m_width, m_boardHeight, m_bigFooterWidth), m_palletColor); surfacePallet.BuildCube24V(new Vector3(0f, m_boardHeight + footerHeight, middleSideBegin), new Vector3(m_width, m_boardHeight, m_bigFooterWidth), m_palletColor); surfacePallet.BuildCube24V(new Vector3(0f, m_boardHeight + footerHeight, lastBeginBig), new Vector3(m_width, m_boardHeight, m_bigFooterWidth), m_palletColor); // Build top boards float localYPos = m_palletHeight - m_boardHeight; surfacePallet.BuildCube24V(new Vector3(0f, localYPos, 0f), new Vector3(m_bigFooterWidth, m_boardHeight, m_depth), m_palletColor); surfacePallet.BuildCube24V(new Vector3(middleFrontBegin, localYPos, 0f), new Vector3(m_bigFooterWidth, m_boardHeight, m_depth), m_palletColor); surfacePallet.BuildCube24V(new Vector3(m_width - m_bigFooterWidth, localYPos, 0f), new Vector3(m_bigFooterWidth, m_boardHeight, m_depth), m_palletColor); surfacePallet.BuildCube24V(new Vector3(quarterFrontBegin, localYPos, 0f), new Vector3(m_smallFooterWidth, m_boardHeight, m_depth), m_palletColor); surfacePallet.BuildCube24V(new Vector3(threeQuarterFrontBegin, localYPos, 0f), new Vector3(m_smallFooterWidth, m_boardHeight, m_depth), m_palletColor); } else { surfacePallet.BuildCube24V( new Vector3(0f, 0f, 0f), new Vector3(m_width, m_palletHeight, m_depth), m_palletColor); } #endregion ----------------------------------------------------------- // Build content #region ----------------------------------------------------------- if (createContent) { surfaceContent.Material = m_contentMaterial; surfaceContent.BuildCubeSides16V(new Vector3(0f, m_palletHeight, 0f), new Vector3(m_width, m_contentHeight, m_depth), m_contentColor); surfaceContent.BuildCubeTop4V(new Vector3(0f, m_palletHeight, 0f), new Vector3(m_width, m_contentHeight, m_depth), m_contentColor); surfaceContent.BuildCubeBottom4V(new Vector3(0f, m_palletHeight, 0f), new Vector3(m_width, m_contentHeight, m_depth), m_contentColor); } #endregion ----------------------------------------------------------- Matrix4x4 rotMatrix = Matrix4x4.CreateRotationY(EngineMath.RAD_90DEG); result.UpdateVerticesUsingRelocationBy(new Vector3(-m_width / 2f, 0f, -m_depth / 2f)); result.CalculateTangentsAndBinormals(); result.TransformVertices(rotMatrix); return(result); }
public void RemoveSurface(VertexStructureSurface surface) { m_surfaces.Remove(surface); }
/// <summary> /// Fills the given vertex structure using information from the given AC-File-Objects. /// </summary> /// <param name="objInfo">The object information from the AC file.</param> /// <param name="acMaterials">A list containing all materials from the AC file.</param> /// <param name="structure">The VertexStructure to be filled.</param> /// <param name="transformStack">Current matrix stack (for stacked objects).</param> private static void FillVertexStructure(VertexStructure structure, List <ACMaterialInfo> acMaterials, ACObjectInfo objInfo, Matrix4Stack transformStack) { List <Tuple <int, int> > standardShadedVertices = new List <Tuple <int, int> >(); transformStack.Push(); try { // Perform local transformation for the current AC object transformStack.TransformLocal(objInfo.Rotation); transformStack.TranslateLocal(objInfo.Translation); // Build structures material by material for (int actMaterialIndex = 0; actMaterialIndex < acMaterials.Count; actMaterialIndex++) { ACMaterialInfo actMaterial = acMaterials[actMaterialIndex]; VertexStructureSurface actStructSurface = structure.CreateOrGetExistingSurface(actMaterial.CreateMaterialProperties()); bool isNewSurface = actStructSurface.CountTriangles == 0; // Create and configure vertex structure actStructSurface.Material = NamedOrGenericKey.Empty; actStructSurface.TextureKey = !string.IsNullOrEmpty(objInfo.Texture) ? new NamedOrGenericKey(objInfo.Texture) : NamedOrGenericKey.Empty; actStructSurface.MaterialProperties.DiffuseColor = actMaterial.Diffuse; actStructSurface.MaterialProperties.AmbientColor = actMaterial.Ambient; actStructSurface.MaterialProperties.EmissiveColor = actMaterial.Emissive; actStructSurface.MaterialProperties.Shininess = actMaterial.Shininess; actStructSurface.MaterialProperties.SpecularColor = actMaterial.Specular; // Initialize local index table (needed for vertex reuse) int oneSideVertexCount = objInfo.Vertices.Count; int[] localIndices = new int[oneSideVertexCount * 2]; for (int loop = 0; loop < localIndices.Length; loop++) { localIndices[loop] = int.MaxValue; } // Process all surfaces foreach (ACSurface actSurface in objInfo.Surfaces) { // Get the vertex index on which to start int startVertexIndex = structure.CountVertices; int startTriangleIndex = actStructSurface.CountTriangles; // Only handle surfaces of the current material if (actSurface.Material != actMaterialIndex) { continue; } // Sort out unsupported surfaces if (actSurface.VertexReferences.Count < 3) { continue; } if (actSurface.IsLine) { continue; } if (actSurface.IsClosedLine) { continue; } // Preprocess referenced vertices int oneSideSurfaceVertexCount = actSurface.VertexReferences.Count; int countSurfaceSides = actSurface.IsTwoSided ? 2 : 1; int[] onStructureReferencedVertices = new int[oneSideSurfaceVertexCount * countSurfaceSides]; List <int> surfaceVertexReferences = actSurface.VertexReferences; for (int loop = 0; loop < surfaceVertexReferences.Count; loop++) { Vector2 actTexCoord = actSurface.TextureCoordinates[loop]; if (!actSurface.IsFlatShaded) { // Try to reuse vertices on standard shading if (localIndices[surfaceVertexReferences[loop]] == int.MaxValue) { Vector3 position = Vector3.Transform( objInfo.Vertices[surfaceVertexReferences[loop]].Position, transformStack.Top); localIndices[surfaceVertexReferences[loop]] = structure.AddVertex(new Vertex( position, Color4.White, actTexCoord, Vector3.Zero)); if (actSurface.IsTwoSided) { localIndices[surfaceVertexReferences[loop] + oneSideVertexCount] = structure.AddVertex(new Vertex( position, Color4.White, actTexCoord, Vector3.Zero)); } } // Store vertex reference for this surface's index onStructureReferencedVertices[loop] = localIndices[surfaceVertexReferences[loop]]; if (actSurface.IsTwoSided) { onStructureReferencedVertices[loop + oneSideSurfaceVertexCount] = localIndices[surfaceVertexReferences[loop] + oneSideVertexCount]; } } else { // Create one vertex for one reference for flat shading Vector3 position = Vector3.Transform( objInfo.Vertices[surfaceVertexReferences[loop]].Position, transformStack.Top); onStructureReferencedVertices[loop] = structure.AddVertex(new Vertex( position, Color4.White, actTexCoord, Vector3.Zero)); if (actSurface.IsTwoSided) { onStructureReferencedVertices[loop + oneSideSurfaceVertexCount] = structure.AddVertex(new Vertex( position, Color4.White, actTexCoord, Vector3.Zero)); } } } // Build object geometry switch (actSurface.VertexReferences.Count) { case 3: // Front side actStructSurface.AddTriangle( onStructureReferencedVertices[0], onStructureReferencedVertices[1], onStructureReferencedVertices[2]); // Back side if (actSurface.IsTwoSided) { actStructSurface.AddTriangle( onStructureReferencedVertices[5], onStructureReferencedVertices[4], onStructureReferencedVertices[3]); } break; case 4: // Front side actStructSurface.AddTriangle( onStructureReferencedVertices[0], onStructureReferencedVertices[1], onStructureReferencedVertices[2]); actStructSurface.AddTriangle( onStructureReferencedVertices[2], onStructureReferencedVertices[3], onStructureReferencedVertices[0]); // Back side if (actSurface.IsTwoSided) { actStructSurface.AddTriangle( onStructureReferencedVertices[6], onStructureReferencedVertices[5], onStructureReferencedVertices[4]); actStructSurface.AddTriangle( onStructureReferencedVertices[4], onStructureReferencedVertices[7], onStructureReferencedVertices[6]); } break; default: if (!actSurface.IsTwoSided) { // Front side actStructSurface.AddPolygonByCuttingEars(onStructureReferencedVertices); } else { // Front and back side actStructSurface.AddPolygonByCuttingEars(onStructureReferencedVertices.Subset(0, oneSideSurfaceVertexCount)); actStructSurface.AddPolygonByCuttingEars(onStructureReferencedVertices.Subset(oneSideSurfaceVertexCount, oneSideSurfaceVertexCount)); } break; } // Perform shading if (actSurface.IsFlatShaded) { actStructSurface.CalculateNormalsFlat( startTriangleIndex, actStructSurface.CountTriangles - startTriangleIndex); } else { // Nothing to be done for now.. int vertexCount = structure.CountVertices - startVertexIndex; if (vertexCount > 0) { standardShadedVertices.Add( Tuple.Create((int)startVertexIndex, vertexCount)); } } } // Calculate default shading finally (if any) foreach (var actStandardShadedPair in standardShadedVertices) { structure.CalculateNormals( actStandardShadedPair.Item1, actStandardShadedPair.Item2); } standardShadedVertices.Clear(); // Append generated VertexStructure to the output collection if ((actStructSurface.CountTriangles <= 0) && (isNewSurface)) { structure.RemoveSurface(actStructSurface); } } //Fill in all child object data foreach (ACObjectInfo actObjInfo in objInfo.Childs) { FillVertexStructure(structure, acMaterials, actObjInfo, transformStack); } } finally { transformStack.Pop(); } }
/// <summary> /// Builds the structure. /// </summary> public override VertexStructure BuildStructure(StructureBuildOptions buildOptions) { VertexStructure result = new VertexStructure(); // Hold dictionary containg materials and corresponding structures Dictionary <NamedOrGenericKey, VertexStructureSurface> materialRelated = new Dictionary <NamedOrGenericKey, VertexStructureSurface>(); // Build bottom structure VertexStructureSurface bottomSurface = result.CreateSurface(); bottomSurface.Material = m_bottomMaterial; materialRelated[m_bottomMaterial] = bottomSurface; // Calculate half vector of total ground size. Vector2 totalHalfSize = new Vector2(m_totalSizeWithoutBorder.X / 2f, m_totalSizeWithoutBorder.Y / 2f); Vector2 tileHalfSize = new Vector2(m_tileSize.X / 2f, m_tileSize.Y / 2f); // Build all tiles foreach (FloorTile actTile in m_groundTiles) { // Get the material of the tile NamedOrGenericKey actMaterial = actTile.Material; if (actMaterial.IsEmpty) { actMaterial = m_groundMaterial; } // Get surface object VertexStructureSurface actSurface = null; if (materialRelated.ContainsKey(actMaterial)) { actSurface = materialRelated[actMaterial]; } else { actSurface = result.CreateSurface(); actSurface.Material = actMaterial; materialRelated[actMaterial] = actSurface; } // Get position of the tile Vector3 tilePosition = new Vector3( (actTile.XPos * m_tileSize.X) - totalHalfSize.X, 0f, (actTile.YPos * m_tileSize.Y) - totalHalfSize.Y); // Add tile information to current VertexStructures actSurface.BuildCubeTop4V( new Vector3(tilePosition.X, -m_height, tilePosition.Z), new Vector3(m_tileSize.X, m_height, m_tileSize.Y), Color4.White); bottomSurface.BuildCubeBottom4V( new Vector3(tilePosition.X, -m_height, tilePosition.Z), new Vector3(m_tileSize.X, m_height, m_tileSize.Y), Color4.White); } // Build all borders VertexStructureSurface borderSurface = null; if (materialRelated.ContainsKey(m_borderMaterial)) { borderSurface = materialRelated[m_borderMaterial]; } else { borderSurface = result.CreateSurface(); borderSurface.Material = m_borderMaterial; materialRelated[m_borderMaterial] = borderSurface; } foreach (BorderInformation actBorder in m_borders) { if (m_borderSize <= 0f) { Vector3 tilePosition = new Vector3( (actBorder.TileXPos * m_tileSize.X) - totalHalfSize.X, 0f, (actBorder.TileYPos * m_tileSize.Y) - totalHalfSize.Y); //Build simple borders switch (actBorder.Location) { case BorderLocation.Left: borderSurface.BuildRect4V( new Vector3(tilePosition.X, -m_height, tilePosition.Z), new Vector3(tilePosition.X, 0f, tilePosition.Z), new Vector3(tilePosition.X, 0f, tilePosition.Z + m_tileSize.Y), new Vector3(tilePosition.X, -m_height, tilePosition.Z + m_tileSize.Y)); break; case BorderLocation.Top: borderSurface.BuildRect4V( new Vector3(tilePosition.X, -m_height, tilePosition.Z + m_tileSize.Y), new Vector3(tilePosition.X, 0f, tilePosition.Z + m_tileSize.Y), new Vector3(tilePosition.X + m_tileSize.X, 0f, tilePosition.Z + m_tileSize.Y), new Vector3(tilePosition.X + m_tileSize.X, -m_height, tilePosition.Z + m_tileSize.Y)); break; case BorderLocation.Right: borderSurface.BuildRect4V( new Vector3(tilePosition.X + m_tileSize.X, -m_height, tilePosition.Z + m_tileSize.Y), new Vector3(tilePosition.X + m_tileSize.X, 0f, tilePosition.Z + m_tileSize.Y), new Vector3(tilePosition.X + m_tileSize.X, 0f, tilePosition.Z), new Vector3(tilePosition.X + m_tileSize.X, -m_height, tilePosition.Z)); break; case BorderLocation.Bottom: borderSurface.BuildRect4V( new Vector3(tilePosition.X + m_tileSize.X, -m_height, tilePosition.Z), new Vector3(tilePosition.X + m_tileSize.X, 0f, tilePosition.Z), new Vector3(tilePosition.X, 0f, tilePosition.Z), new Vector3(tilePosition.X, -m_height, tilePosition.Z)); break; } } else { //Build complex borders } } //Return all generated VertexStructures return(result); }
/// <summary> /// Builds the structures. /// </summary> public override VertexStructure BuildStructure(StructureBuildOptions buildOptions) { VertexStructure result = new VertexStructure(); // Calculate parameters Vector3 firstCoordinate = new Vector3( -((TilesX * TileWidth) / 2f), 0f, -((TilesZ * TileWidth) / 2f)); float tileWidthX = this.TileWidth; float tileWidthZ = this.TileWidth; float fieldWidth = tileWidthX * TilesX; float fieldDepth = tileWidthZ * TilesZ; float fieldWidthHalf = fieldWidth / 2f; float fieldDepthHalf = fieldDepth / 2f; int tileMiddleX = (TilesX % 2 == 0) && (this.HighlightXZLines) ? this.TilesX / 2 : 1; int tileMiddleZ = (TilesZ % 2 == 0) && (this.HighlightXZLines) ? this.TilesZ / 2 : 1; // Define lower ground structure if (this.GenerateGround) { VertexStructureSurface lowerGround = result.CreateSurface(); lowerGround.EnableTextureTileMode(new Vector2(TileWidth, TileWidth)); lowerGround.BuildRect4V( new Vector3(-fieldWidthHalf, -0.01f, -fieldDepthHalf), new Vector3(fieldWidthHalf, -0.01f, -fieldDepthHalf), new Vector3(fieldWidthHalf, -0.01f, fieldDepthHalf), new Vector3(-fieldWidthHalf, -0.01f, fieldDepthHalf), new Vector3(0f, 1f, 0f), this.GroundColor); lowerGround.Material = this.GroundMaterial; } // Define line structures VertexStructureSurface genStructureDefaultLine = result.CreateSurface(); VertexStructureSurface genStructureGroupLine = result.CreateSurface(); for (int actTileX = 0; actTileX < TilesX + 1; actTileX++) { Vector3 localStart = firstCoordinate + new Vector3(actTileX * tileWidthX, 0f, 0f); Vector3 localEnd = localStart + new Vector3(0f, 0f, tileWidthZ * TilesZ); Color4 actLineColor = this.LineColor; float devider = actTileX % this.GroupTileCount == 0 ? this.LineSmallDevider : this.LineBigDevider; if (this.HighlightXZLines && (actTileX == tileMiddleX)) { actLineColor = this.ZLineHighlightColor; devider = this.LineSmallDevider; } VertexStructureSurface targetStruture = actTileX % this.GroupTileCount == 0 ? genStructureGroupLine : genStructureDefaultLine; targetStruture.BuildRect4V( localStart - new Vector3(tileWidthX / devider, 0f, 0f), localStart + new Vector3(tileWidthX / devider, 0f, 0f), localEnd + new Vector3(tileWidthX / devider, 0f, 0f), localEnd - new Vector3(tileWidthX / devider, 0f, 0f), actLineColor); if (this.BuildBackFaces) { targetStruture.BuildRect4V( localEnd - new Vector3(tileWidthX / devider, 0f, 0f), localEnd + new Vector3(tileWidthX / devider, 0f, 0f), localStart + new Vector3(tileWidthX / devider, 0f, 0f), localStart - new Vector3(tileWidthX / devider, 0f, 0f), actLineColor); } } for (int actTileZ = 0; actTileZ < TilesZ + 1; actTileZ++) { Vector3 localStart = firstCoordinate + new Vector3(0f, 0f, actTileZ * tileWidthZ); Vector3 localEnd = localStart + new Vector3(tileWidthX * TilesX, 0f, 0f); Color4 actLineColor = this.LineColor; float devider = actTileZ % this.GroupTileCount == 0 ? this.LineSmallDevider : this.LineBigDevider; if (this.HighlightXZLines && (actTileZ == tileMiddleZ)) { actLineColor = this.XLineHighlightColor; devider = this.LineSmallDevider; } VertexStructureSurface targetStruture = actTileZ % this.GroupTileCount == 0 ? genStructureGroupLine : genStructureDefaultLine; targetStruture.BuildRect4V( localStart + new Vector3(0f, 0f, tileWidthZ / devider), localStart - new Vector3(0f, 0f, tileWidthZ / devider), localEnd - new Vector3(0f, 0f, tileWidthZ / devider), localEnd + new Vector3(0f, 0f, tileWidthZ / devider), actLineColor); if (this.BuildBackFaces) { targetStruture.BuildRect4V( localEnd + new Vector3(0f, 0f, tileWidthZ / devider), localEnd - new Vector3(0f, 0f, tileWidthZ / devider), localStart - new Vector3(0f, 0f, tileWidthZ / devider), localStart + new Vector3(0f, 0f, tileWidthZ / devider), actLineColor); } } genStructureDefaultLine.Material = this.LineMaterial; genStructureGroupLine.Material = this.LineMaterial; if (genStructureDefaultLine.CountTriangles == 0) { result.RemoveSurface(genStructureDefaultLine); } if (genStructureGroupLine.CountTriangles == 0) { result.RemoveSurface(genStructureGroupLine); } // Return all generated structures return(result); }
/// <summary> /// Reads a facet. /// </summary> private void ReadFacet(StreamReader reader, string normalString, VertexStructure newStructure, StlImportOptions importOptions) { m_cachedPoints.Clear(); // Read all geometry Vector3 normal = ParseNormal(normalString); ReadLine(reader, "outer"); while (true) { string line = reader.ReadLine(); Vector3 point; if (TryParseVertex(line, out point)) { m_cachedPoints.Add(point); continue; } string id, values; ParseLine(line, out id, out values); if (id == "endloop") { break; } } // Read end ReadLine(reader, "endfacet"); // Overtake geometry data VertexStructureSurface targetSurfae = newStructure.FirstSurface; int pointCount = m_cachedPoints.Count; switch (m_cachedPoints.Count) { case 0: case 1: case 2: break; case 3: if (importOptions.IsChangeTriangleOrderNeeded()) { targetSurfae.AddTriangle( new Vertex(m_cachedPoints[2], Color4.Transparent, Vector2.Zero, normal), new Vertex(m_cachedPoints[1], Color4.Transparent, Vector2.Zero, normal), new Vertex(m_cachedPoints[0], Color4.Transparent, Vector2.Zero, normal)); } else { targetSurfae.AddTriangle( new Vertex(m_cachedPoints[0], Color4.Transparent, Vector2.Zero, normal), new Vertex(m_cachedPoints[1], Color4.Transparent, Vector2.Zero, normal), new Vertex(m_cachedPoints[2], Color4.Transparent, Vector2.Zero, normal)); } break; default: int[] indices = new int[pointCount]; if (importOptions.IsChangeTriangleOrderNeeded()) { for (int loop = pointCount - 1; loop > -1; loop--) { indices[loop] = newStructure.AddVertex( new Vertex(m_cachedPoints[loop], Color4.Transparent, Vector2.Zero, normal)); } } else { for (int loop = 0; loop < pointCount; loop++) { indices[loop] = newStructure.AddVertex( new Vertex(m_cachedPoints[loop], Color4.Transparent, Vector2.Zero, normal)); } } targetSurfae.AddPolygonByCuttingEars(indices); break; } }