static void ReadData(StreamReader inputStream, ref Vector3[] vertices, ref Vector3[] normals, ref Color32[] colors32, ref Vector2[] uv, ref int[] triangles, Dictionary <string, int> propertyIndices) { int vertCounter = 0; int faceCounter = 0; while (!inputStream.EndOfStream) { string line = inputStream.ReadLine(); if (line.StartsWith("comment")) //log comments to console. might be useful. or not. { LogComment(line); } else { if (vertCounter < vertices.Length) { VertexData data = ReadVertexDataFromLine(line, propertyIndices); vertices[vertCounter] = new Vector3(data.x, data.y, data.z); normals[vertCounter] = new Vector3(data.nx, data.ny, data.nz); colors32[vertCounter] = new Color32(data.r, data.g, data.b, (byte)255); uv[vertCounter] = new Vector2(data.u, data.v); vertCounter++; } else { string[] split = line.Split(' '); int numberOfVertsPerFace = int.Parse(split[0]); if (numberOfVertsPerFace != 3) { throw new UnityException("The importer isn't built to handle faces with " + numberOfVertsPerFace + " vertices (only triangles are allowed)"); } for (int i = 1; i <= 3; i++) { triangles[(3 * faceCounter) + i - 1] = int.Parse(split[i]); } faceCounter++; } } } }
protected override YAMLMappingNode ExportYAMLRoot() { #warning TODO: provide for null values YAMLMappingNode node = base.ExportYAMLRoot(); node.AddSerializedVersion(SerializedVersion); node.Add("m_SubMeshes", SubMeshes.ExportYAML()); node.Add("m_Shapes", Shapes.ExportYAML()); node.Add("m_BindPose", BindPoses.ExportYAML()); #warning ??? node.Add("m_BoneNames", YAMLSequenceNode.Empty); node.Add("m_BoneNameHashes", BoneNameHashes.ExportYAML(false)); #warning ??? node.Add("m_RootBoneName", YAMLScalarNode.Empty); node.Add("m_RootBoneNameHash", RootBoneNameHash); node.Add("m_MeshCompression", MeshCompression); node.Add("m_IsReadable", IsReadable); node.Add("m_KeepVertices", KeepVertices); node.Add("m_KeepIndices", KeepIndices); node.Add("m_IndexBuffer", IndexBuffer.ExportYAML()); node.Add("m_Skin", Skin.ExportYAML()); node.Add("m_VertexData", VertexData.ExportYAML()); node.Add("m_CompressedMesh", CompressedMesh.ExportYAML()); node.Add("m_LocalAABB", LocalAABB.ExportYAML()); node.Add("m_MeshUsageFlags", MeshUsageFlags); if (IsReadCollision) { node.Add("m_BakedConvexCollisionMesh", CollisionData.BakedConvexCollisionMesh.ExportYAML()); node.Add("m_BakedTriangleCollisionMesh", CollisionData.BakedTriangleCollisionMesh.ExportYAML()); } else { node.Add("m_BakedConvexCollisionMesh", ArrayExtensions.EmptyBytes.ExportYAML()); node.Add("m_BakedTriangleCollisionMesh", ArrayExtensions.EmptyBytes.ExportYAML()); } #warning ??? node.Add("m_MeshOptimized", 0); return(node); }
protected VertexData CreateVertexData() { var data = new VertexData(); var triangleVertices = new[, ] { { 0.5f, 0.5f, 0.0f, /* Vertex Color: */ 1.0f, 0.0f, 0.0f }, { -0.5f, 0.5f, 0.0f, /* Vertex Color: */ 0.0f, 1.0f, 0.0f }, { 0.0f, -0.5f, 0.0f, /* Vertex Color: */ 0.0f, 0.0f, 1.0f }, }; DeviceSize memorySize = (ulong)(sizeof(float) * triangleVertices.Length); data.Buffer = CreateBuffer(memorySize, BufferUsageFlags.VertexBuffer); var memoryRequirements = device.GetBufferMemoryRequirements(data.Buffer); var memoryIndex = FindMemoryIndex(MemoryPropertyFlags.HostVisible); var allocateInfo = new MemoryAllocateInfo(memoryRequirements.Size, memoryIndex); data.DeviceMemory = BindBuffer(data.Buffer, allocateInfo); var mapped = device.MapMemory(data.DeviceMemory, 0, memorySize); VulkanUtils.Copy2DArray(triangleVertices, mapped, memorySize, memorySize); device.UnmapMemory(data.DeviceMemory); data.BindingDescriptions = new[] { new VertexInputBindingDescription(0, (uint)(sizeof(float) * triangleVertices.GetLength(1)), VertexInputRate.Vertex) }; data.AttributeDescriptions = new[] { new VertexInputAttributeDescription(0, 0, Format.R32g32b32Sfloat, 0), new VertexInputAttributeDescription(1, 0, Format.R32g32b32Sfloat, sizeof(float) * 3) }; return(data); }
protected override YAMLMappingNode ExportYAMLRoot(IAssetsExporter exporter) { #warning TODO: values acording to read version (current 2017.3.0f3) YAMLMappingNode node = base.ExportYAMLRoot(exporter); node.AddSerializedVersion(GetSerializedVersion(exporter.Version)); node.Add("m_SubMeshes", SubMeshes.ExportYAML(exporter)); node.Add("m_Shapes", Shapes.ExportYAML(exporter)); node.Add("m_BindPose", BindPoses.ExportYAML(exporter)); #warning ??? node.Add("m_BoneNames", YAMLSequenceNode.Empty); node.Add("m_BoneNameHashes", IsReadBoneNameHashes(exporter.Version) ? BoneNameHashes.ExportYAML(false) : YAMLSequenceNode.Empty); #warning ??? node.Add("m_RootBoneName", YAMLScalarNode.Empty); node.Add("m_RootBoneNameHash", RootBoneNameHash); node.Add("m_MeshCompression", MeshCompression); node.Add("m_IsReadable", IsReadable); node.Add("m_KeepVertices", KeepVertices); node.Add("m_KeepIndices", KeepIndices); node.Add("m_IndexBuffer", IsReadIndexBuffer(exporter.Version) ? IndexBuffer.ExportYAML() : YAMLSequenceNode.Empty); node.Add("m_Skin", Skin.ExportYAML(exporter)); node.Add("m_VertexData", VertexData.ExportYAML(exporter)); node.Add("m_CompressedMesh", CompressedMesh.ExportYAML(exporter)); node.Add("m_LocalAABB", LocalAABB.ExportYAML(exporter)); node.Add("m_MeshUsageFlags", MeshUsageFlags); if (IsReadCollision(exporter.Version)) { node.Add("m_BakedConvexCollisionMesh", CollisionData.BakedConvexCollisionMesh.ExportYAML()); node.Add("m_BakedTriangleCollisionMesh", CollisionData.BakedTriangleCollisionMesh.ExportYAML()); } else { node.Add("m_BakedConvexCollisionMesh", ArrayExtensions.EmptyBytes.ExportYAML()); node.Add("m_BakedTriangleCollisionMesh", ArrayExtensions.EmptyBytes.ExportYAML()); } #warning ??? node.Add("m_MeshOptimized", 0); return(node); }
private IGraph <T> BuildGraph(Vertex <T> vEnd, VertexData[] vTable) { /* * result <-- Instantiate a new graph instance * Add the End Vertex to the result * dataLast <-- vTable[Location of End] * previous <-- Previous of dataLast * * while previous is not null * Add previous to result * Add the edge from last and previous * * dataLast <--vTable[Location of previous] * previous <--previous of dataLast * * return result */ IGraph <T> result = (IGraph <T>)GetType().Assembly.CreateInstance(this.GetType().FullName); result.AddVertex(vEnd.Data); VertexData dataLast = vTable[vEnd.Index]; Vertex <T> prev = dataLast.Previous; while (prev != null) { result.AddVertex(prev.Data); Edge <T> eEdge = GetEdge(prev.Data, dataLast.Vertex.Data); result.AddEdge(eEdge.From.Data, eEdge.To.Data, eEdge.Weight); dataLast = vTable[prev.Index]; prev = dataLast.Previous; } return(result); }
private static List <List <IntPoint> > CreatePolygons(IVertexSource a) { List <List <IntPoint> > allPolys = new List <List <IntPoint> >(); List <IntPoint> currentPoly = null; VertexData last = new VertexData(); VertexData first = new VertexData(); bool addedFirst = false; foreach (VertexData vertexData in a.Vertices()) { if (vertexData.IsLineTo) { if (!addedFirst) { currentPoly.Add(new IntPoint((long)(last.position.x * 1000), (long)(last.position.y * 1000))); addedFirst = true; first = last; } currentPoly.Add(new IntPoint((long)(vertexData.position.x * 1000), (long)(vertexData.position.y * 1000))); last = vertexData; } else { addedFirst = false; currentPoly = new List <IntPoint>(); allPolys.Add(currentPoly); if (vertexData.IsMoveTo) { last = vertexData; } else { last = first; } } } return(allPolys); }
public void Read(AssetStream stream) { Texture.Read(stream); if (IsReadAlphaTexture(stream.Version)) { AlphaTexture.Read(stream); } if (IsReadVertices(stream.Version)) { m_vertices = stream.ReadArray <SpriteVertex>(); m_indices = stream.ReadUInt16Array(); stream.AlignStream(AlignType.Align4); } else { m_subMeshes = stream.ReadArray <SubMesh>(); m_indexBuffer = stream.ReadByteArray(); stream.AlignStream(AlignType.Align4); VertexData.Read(stream); } TextureRect.Read(stream); TextureRectOffset.Read(stream); if (IsReadAtlasRectOffset(stream.Version)) { AtlasRectOffset.Read(stream); } SettingsRaw = stream.ReadUInt32(); if (IsReadUVTransform(stream.Version)) { UVTransform.Read(stream); } if (IsReadDownscaleMultiplier(stream.Version)) { DownscaleMultiplier = stream.ReadSingle(); } }
void RenderTexturedQuad(CommandBuffer cmdBuffer, VertexData vertexData, ImageData imageData, PipelineLayout pipelineLayout, DescriptorSet descriptorSet, RenderPass renderPass, Pipeline pipeline, Framebuffer framebuffer, uint width, uint height) { var viewport = new Viewport(0, 0, width, height, 0, 1); cmdBuffer.SetViewport(0, new[] { viewport }); var renderArea = new Rect2D(new Offset2D(0, 0), new Extent2D(width, height)); var renderPassBegin = new RenderPassBeginInfo(renderPass, framebuffer, renderArea, null); cmdBuffer.BeginRenderPass(renderPassBegin, SubpassContents.Inline); renderPassBegin.Dispose(); cmdBuffer.BindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, new[] { descriptorSet }, null); cmdBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline); cmdBuffer.BindVertexBuffers(0, new[] { vertexData.Buffer }, new DeviceSize[] { 0 }); cmdBuffer.BindIndexBuffer(vertexData.IndexBuffer, 0, IndexType.Uint32); cmdBuffer.DrawIndexed((uint)vertexData.Indicies.Length, 1, 0, 0, 1); cmdBuffer.EndRenderPass(); }
void ShowFlatDependencies(VertexData vertex) { bool first = true; var flatDeps = GetAllDependencies(vertex); Console.WriteLine(); foreach (var d in flatDeps) { var dSize = SpaceAnalyzer == null ? 0 : SpaceAnalyzer.GetSize(d.Item1); if (first) { var sizeStr = dSize > 0 ? $" [size: {dSize}]" : ""; Console.WriteLine($"Distance | {d.Item1.value} [total deps: {flatDeps.Count}]{sizeStr}"); Line(); first = false; continue; } var sizeStr2 = dSize > 0 ? $" [size: {dSize}]" : ""; Console.WriteLine($"{string.Format ("{0,8}", d.Item2)} | {d.Item1.value}{d.Item1.DepsCount}{sizeStr2}"); } }
public static List <List <IntPoint> > CreatePolygons(this IVertexSource sourcePath, double scaling = 1000) { List <List <IntPoint> > allPolys = new List <List <IntPoint> >(); List <IntPoint> currentPoly = null; VertexData last = new VertexData(); VertexData first = new VertexData(); bool addedFirst = false; foreach (VertexData vertexData in sourcePath.Vertices()) { if (vertexData.IsLineTo) { if (!addedFirst) { currentPoly.Add(new IntPoint((long)(last.position.X * scaling), (long)(last.position.Y * scaling))); addedFirst = true; first = last; } currentPoly.Add(new IntPoint((long)(vertexData.position.X * scaling), (long)(vertexData.position.Y * scaling))); last = vertexData; } else { addedFirst = false; currentPoly = new List <IntPoint>(); allPolys.Add(currentPoly); if (vertexData.IsMoveTo) { last = vertexData; } else { last = first; } } } return(allPolys); }
// Check equality on PositionIndex and ChannelData public bool ContentEquals(VertexData other) { if (PositionIndex != other.PositionIndex) { return(false); } if (ChannelData.Length != other.ChannelData.Length) { return(false); } for (var i = 0; i < ChannelData.Length; i++) { if (!Equals(ChannelData[i], other.ChannelData[i])) { return(false); } } return(true); }
public VertexData MakeFakeMesh(ref ElevationData evlData) { // Simple routine to convert or grid of float elevations into a format suitable for a quantized mesh of unsigned short ints VertexData vertices = new VertexData((uint)evlData.GridSize, (uint)evlData.GridSize); try { double ratio = 32767 / (double)(evlData.GridSize - 1); // data flows sw to se and up int m = 0; for (int y = 0; y < evlData.GridSize; y++) { for (int x = 0; x < evlData.GridSize; x++) { try { // todo ratio is wrong vertices.AddVertex(m, (ushort)(x * ratio), (ushort)(y * ratio), QuantizeHeight(evlData.MinimumHeight, evlData.MaximumHeight, evlData.Elev[m])); } catch (Exception ex1) { System.Diagnostics.Debug.WriteLine($"**** MakeFakeMesh Error *********:{ex1}"); } m++; } } } catch (Exception ex) { #if DEBUG System.Diagnostics.Debug.WriteLine($"**** MakeFakeMesh Error *********:{ex}"); #endif } return(vertices); }
void RenderTriangle(CommandBuffer cmdBuffer, VertexData vertexData, RenderPass renderPass, Framebuffer framebuffer, Pipeline pipeline, uint width, uint height) { // Set the viewport var viewport = new Viewport(0, 0, width, height, 0, 0); cmdBuffer.SetViewport(0, new[] { viewport }); var renderArea = new Rect2D(new Offset2D(0, 0), new Extent2D(width, height)); var renderPassBegin = new RenderPassBeginInfo(renderPass, framebuffer, renderArea, null); cmdBuffer.BeginRenderPass(renderPassBegin, SubpassContents.Inline); renderPassBegin.Dispose(); cmdBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline); // Render the triangle cmdBuffer.BindVertexBuffers(0, new[] { vertexData.Buffer }, new DeviceSize[] { 0 }); cmdBuffer.Draw(3, 1, 0, 0); // End the RenderPass cmdBuffer.EndRenderPass(); }
public static void SetBoneInfo(ref VertexData target, int fieldIndex, byte boneIndex, float boneWeight) { Type type = typeof(VertexData); if (indexFieldInfos == null) { indexFieldInfos = new FieldInfo[16]; weightFieldInfos = new FieldInfo[16]; for (int i = 0; i < 16; ++i) { indexFieldInfos[i] = type.GetField(string.Format("boneIndex{0}", i + 1)); weightFieldInfos[i] = type.GetField(string.Format("boneWeight{0}", i + 1)); } } object boxed = (object)target; // hello gc! :) indexFieldInfos[fieldIndex].SetValue(boxed, boneIndex); weightFieldInfos[fieldIndex].SetValue(boxed, boneWeight); target = (VertexData)boxed; }
protected void Initialize() { this.vertexDeclDirty = true; this.buffersNeedRecreating = true; this.boundsDirty = true; this.indexContentDirty = true; this.boundingRadius = 0.0f; vertexData = new VertexData(); indexData = new IndexData(); otherTexCoordRange = new float[2]; otherTexCoordRange[0] = 0.0f; otherTexCoordRange[1] = 1.0f; SetupChainContainers(); vertexData.vertexStart = 0; // index data set up later // set basic white material this.materialName = "BaseWhiteNoLighting"; }
public void Add(VertexData[] intList) { faceMesh.AddItem(intList); for (int i = 0; i < intList.Length; i++) { var line = new VertexData[] { intList[i], intList[(i + 1) % intList.Length] }; lineData.Add(new LineData(line[0], line[1])); if (!lineParentCounts.ContainsKey(line)) { lineParentCounts.Add(line, 0); } lineParentCounts[line]++; lineMesh.AddItem(line); if (!pointParentCounts.ContainsKey(intList[i])) { pointParentCounts.Add(intList[i], 0); } pointParentCounts[intList[i]]++; pointMesh.AddItem(intList[i]); } RecalculateEverything(); }
public void TestAlpha() { VertexData vertexData = new VertexData(); vertexData.NumVertices = 3; IndexData indexData = new IndexData(); indexData.AddTriangle(0, 1, 2); Mesh mesh = new Mesh(vertexData, indexData); mesh.SetVertexAlpha(0, 0.2f); mesh.SetVertexAlpha(1, 0.5f); mesh.SetVertexAlpha(2, 0.8f); float E = 0.02f; AssertAreEqualWithSmallError(mesh.GetVertexAlpha(0), 0.2f, "", E); AssertAreEqualWithSmallError(mesh.GetVertexAlpha(1), 0.5f, "", E); AssertAreEqualWithSmallError(mesh.GetVertexAlpha(2), 0.8f, "", E); }
public void TestGetBounds() { VertexData vertexData = new VertexData(); vertexData.SetPoint(0, 10, 10); vertexData.SetPoint(1, 20, 10); vertexData.SetPoint(2, 10, 20); IndexData indexData = new IndexData(); indexData.AddTriangle(0, 1, 2); Mesh mesh = new Mesh(vertexData, indexData); Rectangle expected = Rectangle.Create(10, 10, 10, 10); CompareRectangles(expected, mesh.Bounds); CompareRectangles(expected, mesh.GetBounds(mesh)); mesh.Rotation = (float)Math.PI / 2.0f; expected.SetTo(-20, 10, 10, 10); CompareRectangles(expected, mesh.Bounds); }
public VTX1(EndianBinaryReader reader, int offset) { Attributes = new VertexData(); reader.BaseStream.Seek(offset, System.IO.SeekOrigin.Begin); reader.SkipInt32(); int vtx1Size = reader.ReadInt32(); int attributeHeaderOffset = reader.ReadInt32(); int[] attribDataOffsets = new int[13]; for (int i = 0; i < 13; i++) { attribDataOffsets[i] = reader.ReadInt32(); } GXVertexAttribute attrib = (GXVertexAttribute)reader.ReadInt32(); while (attrib != GXVertexAttribute.Null) { GXComponentCount componentCount = (GXComponentCount)reader.ReadInt32(); GXDataType componentType = (GXDataType)reader.ReadInt32(); byte fractionalBitCount = reader.ReadByte(); reader.Skip(3); long curPos = reader.BaseStream.Position; int attribDataSize = 0; int attribOffset = GetAttributeDataOffset(attribDataOffsets, vtx1Size, attrib, out attribDataSize); int attribCount = GetAttributeDataCount(attribDataSize, attrib, componentType, componentCount); Attributes.SetAttributeData(attrib, LoadAttributeData(reader, offset + attribOffset, attribCount, fractionalBitCount, attrib, componentType, componentCount)); reader.BaseStream.Seek(curPos, System.IO.SeekOrigin.Begin); attrib = (GXVertexAttribute)reader.ReadInt32(); } reader.BaseStream.Seek(offset + vtx1Size, System.IO.SeekOrigin.Begin); }
public bool WorldDraw(WorldDraw wd) { if (_geometry is Rhino.Geometry.Mesh mesh) { var faces = mesh.Faces.ToHost(); var points = new Point3dCollection(mesh.Vertices.ToHost()); var vertexData = new VertexData(); vertexData.SetNormalVectors(mesh.Normals.ToHost()); bool hasVertColor = mesh.VertexColors.Count != 0; vertexData.SetTrueColors(hasVertColor ? mesh.VertexColors.ToHost() : null); wd.Geometry.Shell(points, faces, null, null, vertexData, false); } else if (_geometry is Rhino.Geometry.Curve curve) { double deviation = System.Math.Max(wd.Deviation(DeviationType.MaxDevForCurve, curve.PointAtStart.ToHost()), 0.01 * curve.GetLength()); var polyline = curve.ToPolyline(10E+4 * Convert.VertexTolerance, Convert.AngleTolerance, deviation, 0.0); if (polyline != null) { var giPoly = new Polyline(); giPoly.Points = new Point3dCollection(polyline.ToPolyline().ToArray().ToHost()); wd.Geometry.Polyline(giPoly); } #if DEBUG else { var tmpFile = new Rhino.FileIO.File3dm(); tmpFile.Objects.AddCurve(curve); tmpFile.Write(System.IO.Path.Combine(System.IO.Path.GetTempPath(), "BricsCAD", "CurveFail.3dm"), new Rhino.FileIO.File3dmWriteOptions()); } #endif } else if (_geometry is Rhino.Geometry.Point) { return(false); } return(true); }
/** Sets up a VertexData instance with the correct positions for 4 vertices so that * the texture can be mapped onto it unscaled. If the texture has a <code>frame</code>, * the vertices will be offset accordingly. * * @param vertexData the VertexData instance to which the positions will be written. * @param vertexID the start position within the VertexData instance. * @param bounds useful only for textures with a frame. This will position the * vertices at the correct position within the given bounds, * distorted appropriately. */ public void SetupVertexPositions(VertexData vertexData, int vertexId = 0, Rectangle bounds = null) { Rectangle frame = Frame; float width = Width; float height = Height; Rectangle sRectangle = Rectangle.Create(); if (frame != null) { sRectangle.SetTo(-frame.X, -frame.Y, width, height); } else { sRectangle.SetTo(0, 0, width, height); } vertexData.SetPoint(vertexId, sRectangle.Left, sRectangle.Top); vertexData.SetPoint(vertexId + 1, sRectangle.Right, sRectangle.Top); vertexData.SetPoint(vertexId + 2, sRectangle.Left, sRectangle.Bottom); vertexData.SetPoint(vertexId + 3, sRectangle.Right, sRectangle.Bottom); if (bounds != null) { float scaleX = bounds.Width / FrameWidth; float scaleY = bounds.Height / FrameHeight; if (scaleX != 1.0 || scaleY != 1.0 || bounds.X != 0 || bounds.Y != 0) { Matrix2D sMatrix = Matrix2D.Create(); sMatrix.Identity(); sMatrix.Scale(scaleX, scaleY); sMatrix.Translate(bounds.X, bounds.Y); vertexData.TransformVertices(sMatrix, vertexId, 4); } } }
// SGD :2013/6/18 15:02:51 // 说明:顶点纹理坐标 private unsafe void ReadTextureCoordData(uint vertexOffset, byte *vertexBuffer_Lock, uint vertexBuffer_VertexSize, VertexData vertexData) { VertexElement texElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_TEXTURE_COORDINATES); float * tReal; if (texElem == null) { for (uint i = 0; i < vertexData.vertexCount; i++) { this._textureCroodnitas[vertexOffset + i] = new Vector2(0f, 0f); } } else { //byte* vextex = vertexBuffer_Lock; //for (uint i = 0; i < vertexData.vertexCount; i++) { // texElem.BaseVertexPointerToElement(vextex, &tReal); // this._textureCroodnitas[vertexOffset + i] = new Vector2(tReal[0], tReal[1]); // vextex += vertexBuffer_VertexSize; //} //读取纹理坐标修正 2013/12/18 VertexData vertex_data = vertexData; HardwareVertexBufferSharedPtr vbufPtr_tex = vertex_data.vertexBufferBinding.GetBuffer(texElem.Source); byte *vertex_tex = (byte *)vbufPtr_tex.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); for (uint i = 0; i < vertex_data.vertexCount; ++i, /*vertex += vbufPtr.VertexSize,*/ vertex_tex += vbufPtr_tex.VertexSize) { //posElem.BaseVertexPointerToElement(vertex, &pReal); texElem.BaseVertexPointerToElement(vertex_tex, &tReal); this._textureCroodnitas[vertexOffset + i] = new Vector2(tReal[0], tReal[1]); vertex_tex += vertexBuffer_VertexSize; //Vector3 pt = new Vector3(pReal[0], pReal[1], pReal[2]); //vertices[current_offset + j] = (orientation * (pt * scale)) + position; //tex_Cors[current_offset + j] = new Vector2(tReal[0], tReal[1]); } vbufPtr_tex.Unlock(); vbufPtr_tex.Dispose(); } }
private VertexData ShowVertexEditSceneUI(VertexData vertexData, int index) { Vector3 pos = handleTransform.TransformPoint(vertexData.GetPosition()); Handles.color = Color.white; float size = HandleUtility.GetHandleSize(pos); Handles.Label(pos + 0.6f * size * Vector3.up, "" + index); if (Handles.Button(pos, handleRotation, 1.2f * size * handleSize, 1.2f * size * pickSize, Handles.DotCap)) { vertexData.isEditMode = true; selectedVertexIndex = index; } if (vertexData.isEditMode) { EditorGUI.BeginChangeCheck(); pos = Handles.DoPositionHandle(pos, handleRotation); pos = handleTransform.InverseTransformPoint(pos); vertexData.positionX = pos.x; vertexData.positionY = pos.y; vertexData.positionZ = pos.z; if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(meshEditor, "Move vertex"); EditorUtility.SetDirty(meshEditor); } } return(vertexData); }
// internal methods internal void SetTarget(Mesh target, VertexData vertexData = null, IndexData targetIndexData = null) { if (_target != target) { if (_target != null) { _target.EnterFrame -= OnEnterFrame; } _target = target; _vertexData = vertexData; _indexData = targetIndexData; if (target != null) { if (EnterFrame != null) { target.EnterFrame += OnEnterFrame; } OnTargetAssigned(target); } } }
/// <summary> /// Initializes a fragment filter with the specified number of passes and resolution. /// </summary> protected FragmentFilter(int numPasses = 1, float resolution = 1.0f) { NumPasses = numPasses; Resolution = resolution; Mode = FragmentFilterMode.Replace; _passTextures = new List <Texture>(numPasses); _projMatrix = Matrix.Create(0, 0, 0, 0, 0, 0); _vertexData = new VertexData(4, true); _vertexData.Vertices[1].TexCoords.X = 1.0f; _vertexData.Vertices[2].TexCoords.Y = 1.0f; _vertexData.Vertices[3].TexCoords.X = 1.0f; _vertexData.Vertices[3].TexCoords.Y = 1.0f; _indexData[0] = 0; _indexData[1] = 1; _indexData[2] = 2; _indexData[3] = 1; _indexData[4] = 3; _indexData[5] = 2; CreatePrograms(); }
protected void InitImage(Texture texture) { if (texture == null) { throw new Exception("texture cannot be null!"); } Rectangle frame = texture.Frame; float width = (frame != null) ? frame.Width : texture.Width; float height = (frame != null) ? frame.Height : texture.Height; bool pma = texture.PremultipliedAlpha; Init(width, height, 0xFFFFFF, pma); _vertexData.Vertices[1].TexCoords.X = 1.0f; _vertexData.Vertices[2].TexCoords.Y = 1.0f; _vertexData.Vertices[3].TexCoords.X = 1.0f; _vertexData.Vertices[3].TexCoords.Y = 1.0f; _texture = texture; _vertexDataCache = new VertexData(4, pma); _vertexDataCacheInvalid = true; }
public Vector2f[][] GenerateOutline(Version version) { if (IsReadVertices(version)) { Vector2f[][] outline = new Vector2f[1][]; outline[0] = new Vector2f[Vertices.Count]; for (int i = 0; i < Vertices.Count; i++) { outline[0][i] = Vertices[i].Position.ToVector2(); } return(outline); } else { List <Vector2f[]> outlines = new List <Vector2f[]>(); foreach (SubMesh submesh in SubMeshes) { Vector3f[] vertices = VertexData.GenerateVertices(version, submesh); VerticesToOutline(outlines, vertices, submesh); } return(outlines.ToArray()); } }
public Vector2f[][] GenerateOutline(Version version) { if (HasVertices(version)) { Vector2f[][] outline = new Vector2f[1][]; outline[0] = new Vector2f[Vertices.Length]; for (int i = 0; i < Vertices.Length; i++) { outline[0][i] = Vertices[i].Position.ToVector2(); } return(outline); } else { List <Vector2f[]> outlines = new List <Vector2f[]>(); for (int i = 0; i < SubMeshes.Length; i++) { Vector3f[] vertices = VertexData.GenerateVertices(version, ref SubMeshes[i]); VerticesToOutline(outlines, vertices, ref SubMeshes[i]); } return(outlines.ToArray()); } }
public void SetData(VertexData v0, VertexData v1, VertexData v2) { Matrix4x4 matrix = new Matrix4x4(); matrix.column_0 = v0.vertex; matrix.column_1 = v1.vertex; matrix.column_2 = v2.vertex; vertices = matrix; matrix.column_0 = (Vector3)v0.uv; matrix.column_1 = (Vector3)v1.uv; matrix.column_2 = (Vector3)v2.uv; uvs = matrix; matrix.column_0 = v0.normal; matrix.column_1 = v1.normal; matrix.column_2 = v2.normal; normals = matrix; rawV0 = v0; rawV1 = v1; rawV2 = v2; }
/// <inheritdoc /> protected override void Initialize() { base.Initialize(); // Matrix i,j -> path _data.Clear(); // Prepare the matrix with initial costs // Walk each edge and add entry in cost dictionary foreach (TEdge edge in VisitedGraph.Edges) { SEquatableEdge <TVertex> ij = edge.ToVertexPair(); double cost = _weights(edge); if (!_data.TryGetValue(ij, out VertexData data)) { _data[ij] = new VertexData(cost, edge); } else if (cost < data.Distance) { _data[ij] = new VertexData(cost, edge); } } }
IEnumerable<VertexData> GetVertexIter() { VertexData vertexData = new VertexData(); vertexData.command = VertexCmd.MoveTo; vertexData.x = originX + radiusX; vertexData.y = originY; yield return vertexData; double anglePerStep = MathHelper.Tau / (double)numSteps; double angle = 0; vertexData.command = VertexCmd.LineTo; if (m_cw) { for (int i = 1; i < numSteps; i++) { angle += anglePerStep; vertexData.x = originX + Math.Cos(MathHelper.Tau - angle) * radiusX; vertexData.y = originY + Math.Sin(MathHelper.Tau - angle) * radiusY; yield return vertexData; } } else { for (int i = 1; i < numSteps; i++) { angle += anglePerStep; vertexData.x = originX + Math.Cos(angle) * radiusX; vertexData.y = originY + Math.Sin(angle) * radiusY; yield return vertexData; } } vertexData.x = (int)EndVertexOrientation.CCW; vertexData.y = 0; vertexData.command = VertexCmd.CloseAndEndFigure; yield return vertexData; vertexData.command = VertexCmd.Stop; yield return vertexData; }
public FVF_PositionNormalColored(VertexData data) { Position = data.Position.ToVector3(); Normal = data.Normal.ToVector3(); Color = (data.Color ?? System.Drawing.Color.White).ToArgb(); }
static List<List<IntPoint>> CreatePolygons(VertexStoreSnap a) { List<List<IntPoint>> allPolys = new List<List<IntPoint>>(); List<IntPoint> currentPoly = null; VertexData last = new VertexData(); VertexData first = new VertexData(); bool addedFirst = false; var snapIter = a.GetVertexSnapIter(); double x, y; VertexCmd cmd = snapIter.GetNextVertex(out x, out y); do { if (cmd == VertexCmd.LineTo) { if (!addedFirst) { currentPoly.Add(new IntPoint((long)(last.x * 1000), (long)(last.y * 1000))); addedFirst = true; first = last; } currentPoly.Add(new IntPoint((long)(x * 1000), (long)(y * 1000))); last = new VertexData(cmd, x, y); } else { addedFirst = false; currentPoly = new List<IntPoint>(); allPolys.Add(currentPoly); if (cmd == VertexCmd.MoveTo) { last = new VertexData(cmd, x, y); } else { last = first; } } cmd = snapIter.GetNextVertex(out x, out y); } while (cmd != VertexCmd.Stop); return allPolys; }
public FVF_PositionNormalTexturedColored(VertexData data) { Position = data.Position.ToVector3(); Normal = data.Normal.ToVector3(); Color = (data.Color ?? System.Drawing.Color.White).ToArgb(); if (data.UV != null) UV = new Vector2(data.UV.U, data.UV.V); else UV = new Vector2(); }
public FVF_PositionNormal(VertexData data) { Position = data.Position.ToVector3(); Normal = data.Normal.ToVector3(); }
void CreateDecal() { Bounds bounds = Bounds.Cleared; foreach( Vertex vertex in vertices ) bounds.Add( vertex.position ); VertexData vertexData = new VertexData(); IndexData indexData = new IndexData(); //init vertexData VertexDeclaration declaration = vertexData.VertexDeclaration; declaration.AddElement( 0, 0, VertexElementType.Float3, VertexElementSemantic.Position ); declaration.AddElement( 0, 12, VertexElementType.Float3, VertexElementSemantic.Normal ); declaration.AddElement( 0, 24, VertexElementType.Float2, VertexElementSemantic.TextureCoordinates, 0 ); declaration.AddElement( 0, 32, VertexElementType.Float3, VertexElementSemantic.Tangent ); VertexBufferBinding bufferBinding = vertexData.VertexBufferBinding; HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( 44, vertices.Length, HardwareBuffer.Usage.StaticWriteOnly ); bufferBinding.SetBinding( 0, vertexBuffer, true ); vertexData.VertexCount = vertices.Length; //init indexData Trace.Assert( vertices.Length < 65536, "Decal: vertices.Length < 65536" ); HardwareIndexBuffer indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( HardwareIndexBuffer.IndexType._16Bit, indices.Length, HardwareBuffer.Usage.StaticWriteOnly ); indexData.SetIndexBuffer( indexBuffer, true ); indexData.IndexCount = indices.Length; //init material Material material = null; shaderBaseMaterial = HighLevelMaterialManager.Instance. GetMaterialByName( sourceMaterialName ) as ShaderBaseMaterial; //only default shader technique for ShaderBase material if( shaderBaseMaterial != null && !shaderBaseMaterial.IsDefaultTechniqueCreated() ) shaderBaseMaterial = null; if( shaderBaseMaterial != null ) { //ShaderBase material material = shaderBaseMaterial.BaseMaterial; } else { //standard material or fallback ShaderBase technique Material sourceMaterial = MaterialManager.Instance.GetByName( sourceMaterialName ); if( sourceMaterial != null ) { //clone standard material clonedStandardMaterial = MaterialManager.Instance.Clone( sourceMaterial, MaterialManager.Instance.GetUniqueName( sourceMaterialName + "_Cloned" ) ); material = clonedStandardMaterial; } } staticMeshObject = SceneManager.Instance.CreateStaticMeshObject( bounds + Position, Position, Quat.Identity, new Vec3( 1, 1, 1 ), material, vertexData, indexData, true ); staticMeshObject.AddToRenderQueue += StaticMeshObject_AddToRenderQueue; UpdateBuffers(); }
public FVF_PositionNormalTextured(VertexData data) { Position = data.Position.ToVector3(); Normal = data.Normal.ToVector3(); if (data.UV != null) UV = new Vector2(data.UV.U, data.UV.V); else UV = new Vector2(); }
private static bool SplitMeshUsingPlane(MeshData meshDataIn, FracturedObject fracturedComponent, SplitOptions splitOptions, Vector3 v3PlaneNormal, Vector3 v3PlaneRight, Vector3 v3PlanePoint, out List<MeshData> listMeshDatasPosOut, out List<MeshData> listMeshDatasNegOut, ProgressDelegate progress = null) { Plane planeSplit = new Plane(v3PlaneNormal, v3PlanePoint); listMeshDatasPosOut = new List<MeshData>(); listMeshDatasNegOut = new List<MeshData>(); // Check if the input object already has been split, to get its split closing submesh bool bNeedsNewSplitSubMesh = meshDataIn.nSplitCloseSubMesh == -1; int nSplitCloseSubMesh = meshDataIn.nSplitCloseSubMesh; // Here we are going to store our output vertex/index data int nCurrentVertexHash = meshDataIn.nCurrentVertexHash; // We will use this to identify vertices with same coordinates but different vertex data. They will share the same vertex hash List<VertexData> listVertexDataPos = new List<VertexData>(); List<VertexData> listVertexDataNeg = new List<VertexData>(); List<int>[] alistIndicesPos = new List<int>[meshDataIn.nSubMeshCount + (meshDataIn.nSplitCloseSubMesh == -1 ? 1 : 0)]; List<int>[] alistIndicesNeg = new List<int>[meshDataIn.nSubMeshCount + (meshDataIn.nSplitCloseSubMesh == -1 ? 1 : 0)]; MeshFaceConnectivity faceConnectivityPos = new MeshFaceConnectivity(); MeshFaceConnectivity faceConnectivityNeg = new MeshFaceConnectivity(); MeshDataConnectivity meshConnectivityPos = new MeshDataConnectivity(); MeshDataConnectivity meshConnectivityNeg = new MeshDataConnectivity(); listVertexDataPos.Capacity = meshDataIn.aVertexData.Length / 2; listVertexDataNeg.Capacity = meshDataIn.aVertexData.Length / 2; if(bNeedsNewSplitSubMesh) { // Make room for the split closing submesh nSplitCloseSubMesh = meshDataIn.nSubMeshCount; alistIndicesPos[nSplitCloseSubMesh] = new List<int>(); alistIndicesNeg[nSplitCloseSubMesh] = new List<int>(); } // Our vertices that form the clipped cap Dictionary<EdgeKeyByHash, int> dicClipVerticesHash = new Dictionary<EdgeKeyByHash, int> (new EdgeKeyByHash.EqualityComparer()); Dictionary<EdgeKeyByHash, CapEdge> dicCapEdges = new Dictionary<EdgeKeyByHash, CapEdge>(new EdgeKeyByHash.EqualityComparer()); // A hash table with our clipped edges, to reuse clipped vertices Dictionary<EdgeKeyByIndex, ClippedEdge> dicClippedEdgesPos = new Dictionary<EdgeKeyByIndex, ClippedEdge>(new EdgeKeyByIndex.EqualityComparer()); Dictionary<EdgeKeyByIndex, ClippedEdge> dicClippedEdgesNeg = new Dictionary<EdgeKeyByIndex, ClippedEdge>(new EdgeKeyByIndex.EqualityComparer()); int nClippedCacheHits = 0; int nClippedCacheMisses = 0; // A hash table with the remapped indices, to reuse non-clipped vertices Dictionary<int, int> dicRemappedIndicesPos = new Dictionary<int, int>(); Dictionary<int, int> dicRemappedIndicesNeg = new Dictionary<int, int>(); for(int nSubMesh = 0; nSubMesh < meshDataIn.nSubMeshCount; nSubMesh++) { // Index list alistIndicesPos[nSubMesh] = new List<int>(); alistIndicesNeg[nSubMesh] = new List<int>(); List<int> listIndicesPos = alistIndicesPos[nSubMesh]; List<int> listIndicesNeg = alistIndicesNeg[nSubMesh]; alistIndicesPos[nSubMesh].Capacity = meshDataIn.aaIndices[nSubMesh].Length / 2; alistIndicesNeg[nSubMesh].Capacity = meshDataIn.aaIndices[nSubMesh].Length / 2; // A reference to the output arrays/lists (it will be switching between positive/negative side along the algorithm) List<VertexData> plistVertexData = listVertexDataPos; List<int> plistObjectIndices = listIndicesPos; MeshFaceConnectivity pFaceConnectivity = faceConnectivityPos; MeshDataConnectivity pMeshConnectivity = meshConnectivityPos; Dictionary<EdgeKeyByIndex, ClippedEdge> pdicClippedEdges = dicClippedEdgesPos; Dictionary<int, int> pdicRemappedIndices = dicRemappedIndicesPos; // Iterate through all submesh faces: for(int i = 0; i < meshDataIn.aaIndices[nSubMesh].Length / 3; i++) { plistVertexData = listVertexDataPos; plistObjectIndices = listIndicesPos; pFaceConnectivity = faceConnectivityPos; pMeshConnectivity = meshConnectivityPos; pdicClippedEdges = dicClippedEdgesPos; pdicRemappedIndices = dicRemappedIndicesPos; int nIndex1 = meshDataIn.aaIndices[nSubMesh][i * 3 + 0]; int nIndex2 = meshDataIn.aaIndices[nSubMesh][i * 3 + 1]; int nIndex3 = meshDataIn.aaIndices[nSubMesh][i * 3 + 2]; int nHashV1 = meshDataIn.aVertexData[nIndex1].nVertexHash; int nHashV2 = meshDataIn.aVertexData[nIndex2].nVertexHash; int nHashV3 = meshDataIn.aVertexData[nIndex3].nVertexHash; Vector3 v1 = meshDataIn.aVertexData[nIndex1].v3Vertex; Vector3 v2 = meshDataIn.aVertexData[nIndex2].v3Vertex; Vector3 v3 = meshDataIn.aVertexData[nIndex3].v3Vertex; // Classify vertices depending on the side of the plane they lay on, then clip if necessary. float fSide1 = v1.x * planeSplit.normal.x + v1.y * planeSplit.normal.y + v1.z * planeSplit.normal.z + planeSplit.distance; float fSide2 = v2.x * planeSplit.normal.x + v2.y * planeSplit.normal.y + v2.z * planeSplit.normal.z + planeSplit.distance; float fSide3 = v3.x * planeSplit.normal.x + v3.y * planeSplit.normal.y + v3.z * planeSplit.normal.z + planeSplit.distance; bool bForceSameSide = false; int nAlmostInPlane = 0; bool bAlmostInPlane1 = false; bool bAlmostInPlane2 = false; bool bAlmostInPlane3 = false; float fFurthest = 0.0f; if(Mathf.Abs(fSide1) < UltimateFracturing.Parameters.EPSILONDISTANCEPLANE) { bAlmostInPlane1 = true; nAlmostInPlane++; } if(Mathf.Abs(fSide2) < UltimateFracturing.Parameters.EPSILONDISTANCEPLANE) { bAlmostInPlane2 = true; nAlmostInPlane++; } if(Mathf.Abs(fSide3) < UltimateFracturing.Parameters.EPSILONDISTANCEPLANE) { bAlmostInPlane3 = true; nAlmostInPlane++; } if(Mathf.Abs(fSide1) > Mathf.Abs(fFurthest)) fFurthest = fSide1; if(Mathf.Abs(fSide2) > Mathf.Abs(fFurthest)) fFurthest = fSide2; if(Mathf.Abs(fSide3) > Mathf.Abs(fFurthest)) fFurthest = fSide3; if(nAlmostInPlane == 1) { // Look if the other two vertices are on the same side. If so, we'll skip the clipping too. if(bAlmostInPlane1 && (fSide2 * fSide3 > 0.0f)) bForceSameSide = true; if(bAlmostInPlane2 && (fSide1 * fSide3 > 0.0f)) bForceSameSide = true; if(bAlmostInPlane3 && (fSide1 * fSide2 > 0.0f)) bForceSameSide = true; } else if(nAlmostInPlane > 1) { bForceSameSide = true; if(nAlmostInPlane == 3) { // Coplanar continue; } } if((fSide1 * fSide2 > 0.0f && fSide2 * fSide3 > 0.0f) || bForceSameSide) { // All on the same side, no clipping needed if(fFurthest < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } int nNewIndex1 = -1; int nNewIndex2 = -1; int nNewIndex3 = -1; // Find vertices in remapped indices list and add vertex data if not present if(pdicRemappedIndices.ContainsKey(nIndex1)) { nNewIndex1 = pdicRemappedIndices[nIndex1]; } if(nNewIndex1 == -1) { nNewIndex1 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex1].Copy()); pdicRemappedIndices[nIndex1] = nNewIndex1; } if(pdicRemappedIndices.ContainsKey(nIndex2)) { nNewIndex2 = pdicRemappedIndices[nIndex2]; } if(nNewIndex2 == -1) { nNewIndex2 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex2].Copy()); pdicRemappedIndices[nIndex2] = nNewIndex2; } if(pdicRemappedIndices.ContainsKey(nIndex3)) { nNewIndex3 = pdicRemappedIndices[nIndex3]; } if(nNewIndex3 == -1) { nNewIndex3 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex3].Copy()); pdicRemappedIndices[nIndex3] = nNewIndex3; } // Add triangle indices if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex1); plistObjectIndices.Add(nNewIndex2); plistObjectIndices.Add(nNewIndex3); if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v1, v2, nHashV1, nHashV2, nNewIndex1, nNewIndex2); pFaceConnectivity.AddEdge(nSubMesh, v2, v3, nHashV2, nHashV3, nNewIndex2, nNewIndex3); pFaceConnectivity.AddEdge(nSubMesh, v3, v1, nHashV3, nHashV1, nNewIndex3, nNewIndex1); } // Add cap edges only if an edge is lying on the plane if(nAlmostInPlane == 2) { if(fFurthest > 0.0f) { if(bAlmostInPlane1 && bAlmostInPlane2 && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV1, nHashV2, v1, v2); if(bAlmostInPlane2 && bAlmostInPlane3 && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV2, nHashV3, v2, v3); if(bAlmostInPlane3 && bAlmostInPlane1 && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV3, nHashV1, v3, v1); } else { if(bAlmostInPlane1 && bAlmostInPlane2 && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV2, nHashV1, v2, v1); if(bAlmostInPlane2 && bAlmostInPlane3 && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV3, nHashV2, v3, v2); if(bAlmostInPlane3 && bAlmostInPlane1 && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV1, nHashV3, v1, v3); } } } else if(nAlmostInPlane == 1) { // Special treatment clipping for one vertex laying on the clipping plane and the other 2 on different sides int nNewIndex1 = -1; int nNewIndex2 = -1; int nNewIndex3 = -1; int nNewIndex4 = -1; int nHashV4 = -1; bool bEdge = false; EdgeKeyByIndex clippedEdgeKey; if(bAlmostInPlane1) { // v1 almost on the clipping plane if(fSide2 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } clippedEdgeKey = new EdgeKeyByIndex(nIndex2, nIndex3); if(pdicClippedEdges.ContainsKey(clippedEdgeKey)) { nClippedCacheHits++; bEdge = true; nNewIndex2 = pdicClippedEdges[clippedEdgeKey].GetFirstIndex(nIndex2); nNewIndex4 = pdicClippedEdges[clippedEdgeKey].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex2)) nNewIndex2 = pdicRemappedIndices[nIndex2]; } // Clip if not present in clipped edge list EdgeKeyByHash clippedEdgeKeyHash = new EdgeKeyByHash(nHashV2, nHashV3); if(dicClipVerticesHash.ContainsKey(clippedEdgeKeyHash)) { nHashV4 = dicClipVerticesHash[clippedEdgeKeyHash]; } else { nHashV4 = nCurrentVertexHash++; dicClipVerticesHash.Add(clippedEdgeKeyHash, nHashV4); } VertexData vd4 = new VertexData(nHashV4); if(bEdge == false) { if(VertexData.ClipAgainstPlane(meshDataIn.aVertexData, nIndex2, nIndex3, v2, v3, planeSplit, ref vd4) == false) { return false; } } // Add geometry of one side // Add vertex data for all data not present in remapped list if(nNewIndex1 == -1) { if(pdicRemappedIndices.ContainsKey(nIndex1)) { nNewIndex1 = pdicRemappedIndices[nIndex1]; } } if(nNewIndex1 == -1) { nNewIndex1 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex1].Copy()); pdicRemappedIndices[nIndex1] = nNewIndex1; } if(nNewIndex2 == -1) { nNewIndex2 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex2].Copy()); pdicRemappedIndices[nIndex2] = nNewIndex2; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex1); plistObjectIndices.Add(nNewIndex2); plistObjectIndices.Add(nNewIndex4); Vector3 v4 = plistVertexData[nNewIndex4].v3Vertex; if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v1, v2, nHashV1, nHashV2, nNewIndex1, nNewIndex2); pFaceConnectivity.AddEdge(nSubMesh, v2, v4, nHashV2, nHashV4, nNewIndex2, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v1, nHashV4, nHashV1, nNewIndex4, nNewIndex1); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV4, nHashV1, plistVertexData[nNewIndex4].v3Vertex, plistVertexData[nNewIndex1].v3Vertex); if(bEdge == false) pdicClippedEdges.Add(clippedEdgeKey, new ClippedEdge(nIndex2, nIndex3, nNewIndex2, nNewIndex3, nNewIndex4)); // Add geometry of other side if(fSide3 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } else { plistVertexData = listVertexDataPos; plistObjectIndices = listIndicesPos; pFaceConnectivity = faceConnectivityPos; pMeshConnectivity = meshConnectivityPos; pdicClippedEdges = dicClippedEdgesPos; pdicRemappedIndices = dicRemappedIndicesPos; } nNewIndex1 = -1; nNewIndex2 = -1; nNewIndex3 = -1; nNewIndex4 = -1; bEdge = false; // Find edges in cache if(pdicClippedEdges.ContainsKey(clippedEdgeKey)) { nClippedCacheHits++; bEdge = true; nNewIndex3 = pdicClippedEdges[clippedEdgeKey].GetSecondIndex(nIndex3); nNewIndex4 = pdicClippedEdges[clippedEdgeKey].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex3)) nNewIndex3 = pdicRemappedIndices[nIndex3]; } // Add vertex data for all data not present in remapped list if(nNewIndex1 == -1) { if(pdicRemappedIndices.ContainsKey(nIndex1)) { nNewIndex1 = pdicRemappedIndices[nIndex1]; } } if(nNewIndex1 == -1) { nNewIndex1 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex1].Copy()); pdicRemappedIndices[nIndex1] = nNewIndex1; } if(nNewIndex3 == -1) { nNewIndex3 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex3].Copy()); pdicRemappedIndices[nIndex3] = nNewIndex3; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex1); plistObjectIndices.Add(nNewIndex4); plistObjectIndices.Add(nNewIndex3); if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v1, v4, nHashV1, nHashV4, nNewIndex1, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v3, nHashV4, nHashV3, nNewIndex4, nNewIndex3); pFaceConnectivity.AddEdge(nSubMesh, v3, v1, nHashV3, nHashV1, nNewIndex3, nNewIndex1); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV1, nHashV4, plistVertexData[nNewIndex1].v3Vertex, plistVertexData[nNewIndex4].v3Vertex); if(bEdge == false) pdicClippedEdges.Add(clippedEdgeKey, new ClippedEdge(nIndex2, nIndex3, nNewIndex2, nNewIndex3, nNewIndex4)); } else if(bAlmostInPlane2) { // v2 almost on the clipping plane if(fSide3 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } clippedEdgeKey = new EdgeKeyByIndex(nIndex3, nIndex1); if(pdicClippedEdges.ContainsKey(clippedEdgeKey)) { nClippedCacheHits++; bEdge = true; nNewIndex3 = pdicClippedEdges[clippedEdgeKey].GetFirstIndex(nIndex3); nNewIndex4 = pdicClippedEdges[clippedEdgeKey].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex3)) nNewIndex3 = pdicRemappedIndices[nIndex3]; } // Clip if not present in clipped edge list EdgeKeyByHash clippedEdgeKeyHash = new EdgeKeyByHash(nHashV3, nHashV1); if(dicClipVerticesHash.ContainsKey(clippedEdgeKeyHash)) { nHashV4 = dicClipVerticesHash[clippedEdgeKeyHash]; } else { nHashV4 = nCurrentVertexHash++; dicClipVerticesHash.Add(clippedEdgeKeyHash, nHashV4); } VertexData vd4 = new VertexData(nHashV4); if(bEdge == false) { if(VertexData.ClipAgainstPlane(meshDataIn.aVertexData, nIndex3, nIndex1, v3, v1, planeSplit, ref vd4) == false) { return false; } } // Add geometry of one side // Add vertex data for all data not present in remapped list if(nNewIndex2 == -1) { if(pdicRemappedIndices.ContainsKey(nIndex2)) { nNewIndex2 = pdicRemappedIndices[nIndex2]; } } if(nNewIndex2 == -1) { nNewIndex2 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex2].Copy()); pdicRemappedIndices[nIndex2] = nNewIndex2; } if(nNewIndex3 == -1) { nNewIndex3 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex3].Copy()); pdicRemappedIndices[nIndex3] = nNewIndex3; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex2); plistObjectIndices.Add(nNewIndex3); plistObjectIndices.Add(nNewIndex4); Vector3 v4 = plistVertexData[nNewIndex4].v3Vertex; if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v2, v3, nHashV2, nHashV3, nNewIndex2, nNewIndex3); pFaceConnectivity.AddEdge(nSubMesh, v3, v4, nHashV3, nHashV4, nNewIndex3, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v2, nHashV4, nHashV2, nNewIndex4, nNewIndex2); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV4, nHashV2, plistVertexData[nNewIndex4].v3Vertex, plistVertexData[nNewIndex2].v3Vertex); if(bEdge == false) pdicClippedEdges.Add(clippedEdgeKey, new ClippedEdge(nIndex3, nIndex1, nNewIndex3, nNewIndex1, nNewIndex4)); // Add geometry of other side if(fSide1 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } else { plistVertexData = listVertexDataPos; plistObjectIndices = listIndicesPos; pFaceConnectivity = faceConnectivityPos; pMeshConnectivity = meshConnectivityPos; pdicClippedEdges = dicClippedEdgesPos; pdicRemappedIndices = dicRemappedIndicesPos; } nNewIndex1 = -1; nNewIndex2 = -1; nNewIndex4 = -1; bEdge = false; // Find edges in cache if(pdicClippedEdges.ContainsKey(clippedEdgeKey)) { nClippedCacheHits++; bEdge = true; nNewIndex1 = pdicClippedEdges[clippedEdgeKey].GetSecondIndex(nIndex1); nNewIndex4 = pdicClippedEdges[clippedEdgeKey].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex1)) nNewIndex1 = pdicRemappedIndices[nIndex1]; } // Add vertex data for all data not present in remapped list if(nNewIndex1 == -1) { nNewIndex1 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex1].Copy()); pdicRemappedIndices[nIndex1] = nNewIndex1; } if(nNewIndex2 == -1) { if(pdicRemappedIndices.ContainsKey(nIndex2)) { nNewIndex2 = pdicRemappedIndices[nIndex2]; } } if(nNewIndex2 == -1) { nNewIndex2 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex2].Copy()); pdicRemappedIndices[nIndex2] = nNewIndex2; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex2); plistObjectIndices.Add(nNewIndex4); plistObjectIndices.Add(nNewIndex1); if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v2, v4, nHashV2, nHashV4, nNewIndex2, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v1, nHashV4, nHashV1, nNewIndex4, nNewIndex1); pFaceConnectivity.AddEdge(nSubMesh, v1, v2, nHashV1, nHashV2, nNewIndex1, nNewIndex2); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV2, nHashV4, plistVertexData[nNewIndex2].v3Vertex, plistVertexData[nNewIndex4].v3Vertex); if(bEdge == false) pdicClippedEdges.Add(clippedEdgeKey, new ClippedEdge(nIndex3, nIndex1, nNewIndex3, nNewIndex1, nNewIndex4)); } else if(bAlmostInPlane3) { // v3 almost on the clipping plane if(fSide1 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } clippedEdgeKey = new EdgeKeyByIndex(nIndex1, nIndex2); if(pdicClippedEdges.ContainsKey(clippedEdgeKey)) { nClippedCacheHits++; bEdge = true; nNewIndex1 = pdicClippedEdges[clippedEdgeKey].GetFirstIndex(nIndex1); nNewIndex4 = pdicClippedEdges[clippedEdgeKey].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex1)) nNewIndex1 = pdicRemappedIndices[nIndex1]; } // Clip if not present in clipped edge list EdgeKeyByHash clippedEdgeKeyHash = new EdgeKeyByHash(nHashV1, nHashV2); if(dicClipVerticesHash.ContainsKey(clippedEdgeKeyHash)) { nHashV4 = dicClipVerticesHash[clippedEdgeKeyHash]; } else { nHashV4 = nCurrentVertexHash++; dicClipVerticesHash.Add(clippedEdgeKeyHash, nHashV4); } VertexData vd4 = new VertexData(nHashV4); if(bEdge == false) { if(VertexData.ClipAgainstPlane(meshDataIn.aVertexData, nIndex1, nIndex2, v1, v2, planeSplit, ref vd4) == false) { return false; } } // Add geometry of one side // Add vertex data for all data not present in remapped list if(nNewIndex1 == -1) { nNewIndex1 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex1].Copy()); pdicRemappedIndices[nIndex1] = nNewIndex1; } if(nNewIndex3 == -1) { if(pdicRemappedIndices.ContainsKey(nIndex3)) { nNewIndex3 = pdicRemappedIndices[nIndex3]; } } if(nNewIndex3 == -1) { nNewIndex3 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex3].Copy()); pdicRemappedIndices[nIndex3] = nNewIndex3; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex1); plistObjectIndices.Add(nNewIndex4); plistObjectIndices.Add(nNewIndex3); Vector3 v4 = plistVertexData[nNewIndex4].v3Vertex; if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v1, v4, nHashV1, nHashV4, nNewIndex1, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v3, nHashV4, nHashV3, nNewIndex4, nNewIndex3); pFaceConnectivity.AddEdge(nSubMesh, v3, v1, nHashV3, nHashV1, nNewIndex3, nNewIndex1); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV4, nHashV3, plistVertexData[nNewIndex4].v3Vertex, plistVertexData[nNewIndex3].v3Vertex); if(bEdge == false) pdicClippedEdges.Add(clippedEdgeKey, new ClippedEdge(nIndex1, nIndex2, nNewIndex1, nNewIndex2, nNewIndex4)); // Add geometry of other side if(fSide2 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } else { plistVertexData = listVertexDataPos; plistObjectIndices = listIndicesPos; pFaceConnectivity = faceConnectivityPos; pMeshConnectivity = meshConnectivityPos; pdicClippedEdges = dicClippedEdgesPos; pdicRemappedIndices = dicRemappedIndicesPos; } nNewIndex2 = -1; nNewIndex3 = -1; nNewIndex4 = -1; bEdge = false; // Find edges in cache if(pdicClippedEdges.ContainsKey(clippedEdgeKey)) { nClippedCacheHits++; bEdge = true; nNewIndex2 = pdicClippedEdges[clippedEdgeKey].GetSecondIndex(nIndex2); nNewIndex4 = pdicClippedEdges[clippedEdgeKey].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex2)) nNewIndex2 = pdicRemappedIndices[nIndex2]; } // Add vertex data for all data not present in remapped list if(nNewIndex2 == -1) { nNewIndex2 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex2].Copy()); pdicRemappedIndices[nIndex2] = nNewIndex2; } if(nNewIndex3 == -1) { if(pdicRemappedIndices.ContainsKey(nIndex3)) { nNewIndex3 = pdicRemappedIndices[nIndex3]; } } if(nNewIndex3 == -1) { nNewIndex3 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex3].Copy()); pdicRemappedIndices[nIndex3] = nNewIndex3; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex2); plistObjectIndices.Add(nNewIndex3); plistObjectIndices.Add(nNewIndex4); if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v2, v3, nHashV2, nHashV3, nNewIndex2, nNewIndex3); pFaceConnectivity.AddEdge(nSubMesh, v3, v4, nHashV3, nHashV4, nNewIndex3, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v2, nHashV4, nHashV2, nNewIndex4, nNewIndex2); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV3, nHashV4, plistVertexData[nNewIndex3].v3Vertex, plistVertexData[nNewIndex4].v3Vertex); if(bEdge == false) pdicClippedEdges.Add(clippedEdgeKey, new ClippedEdge(nIndex1, nIndex2, nNewIndex1, nNewIndex2, nNewIndex4)); } } else { if(fSide1 * fSide2 < 0.0f) { // v1 and v2 on different sides if(fSide2 * fSide3 < 0.0f) { // ... and v3 on same side as v1 if(fSide1 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } int nNewIndex1 = -1; int nNewIndex2 = -1; int nNewIndex3 = -1; int nNewIndex4 = -1; int nNewIndex5 = -1; int nHashV4 = -1; int nHashV5 = -1; bool bEdgeKey1 = false; bool bEdgeKey2 = false; EdgeKeyByIndex edgeKey1 = new EdgeKeyByIndex(nIndex1, nIndex2); EdgeKeyByIndex edgeKey2 = new EdgeKeyByIndex(nIndex2, nIndex3); // Find edges in cache if(pdicClippedEdges.ContainsKey(edgeKey1)) { nClippedCacheHits++; bEdgeKey1 = true; nNewIndex1 = pdicClippedEdges[edgeKey1].GetFirstIndex(nIndex1); nNewIndex4 = pdicClippedEdges[edgeKey1].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex1)) nNewIndex1 = pdicRemappedIndices[nIndex1]; } if(pdicClippedEdges.ContainsKey(edgeKey2)) { nClippedCacheHits++; bEdgeKey2 = true; nNewIndex3 = pdicClippedEdges[edgeKey2].GetSecondIndex(nIndex3); nNewIndex5 = pdicClippedEdges[edgeKey2].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex3)) nNewIndex3 = pdicRemappedIndices[nIndex3]; } // Clip if not present in clipped edge list EdgeKeyByHash clippedEdgeKeyHash = new EdgeKeyByHash(nHashV1, nHashV2); if(dicClipVerticesHash.ContainsKey(clippedEdgeKeyHash)) { nHashV4 = dicClipVerticesHash[clippedEdgeKeyHash]; } else { nHashV4 = nCurrentVertexHash++; dicClipVerticesHash.Add(clippedEdgeKeyHash, nHashV4); } clippedEdgeKeyHash = new EdgeKeyByHash(nHashV2, nHashV3); if(dicClipVerticesHash.ContainsKey(clippedEdgeKeyHash)) { nHashV5 = dicClipVerticesHash[clippedEdgeKeyHash]; } else { nHashV5 = nCurrentVertexHash++; dicClipVerticesHash.Add(clippedEdgeKeyHash, nHashV5); } VertexData vd4 = new VertexData(nHashV4), vd5 = new VertexData(nHashV5); if(bEdgeKey1 == false) { if(VertexData.ClipAgainstPlane(meshDataIn.aVertexData, nIndex1, nIndex2, v1, v2, planeSplit, ref vd4) == false) { return false; } } if(bEdgeKey2 == false) { if(VertexData.ClipAgainstPlane(meshDataIn.aVertexData, nIndex2, nIndex3, v2, v3, planeSplit, ref vd5) == false) { return false; } } // Add geometry of one side // Add vertex data for all data not present in remapped list if(nNewIndex1 == -1) { nNewIndex1 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex1].Copy()); pdicRemappedIndices[nIndex1] = nNewIndex1; } if(nNewIndex3 == -1) { nNewIndex3 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex3].Copy()); pdicRemappedIndices[nIndex3] = nNewIndex3; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(nNewIndex5 == -1) { nNewIndex5 = plistVertexData.Count; plistVertexData.Add(vd5); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex1); plistObjectIndices.Add(nNewIndex4); plistObjectIndices.Add(nNewIndex5); if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex1); plistObjectIndices.Add(nNewIndex5); plistObjectIndices.Add(nNewIndex3); Vector3 v4 = plistVertexData[nNewIndex4].v3Vertex; Vector3 v5 = plistVertexData[nNewIndex5].v3Vertex; if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v1, v4, nHashV1, nHashV4, nNewIndex1, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v5, nHashV4, nHashV5, nNewIndex4, nNewIndex5); pFaceConnectivity.AddEdge(nSubMesh, v5, v1, nHashV5, nHashV1, nNewIndex5, nNewIndex1); pFaceConnectivity.AddEdge(nSubMesh, v1, v5, nHashV1, nHashV5, nNewIndex1, nNewIndex5); pFaceConnectivity.AddEdge(nSubMesh, v5, v3, nHashV5, nHashV3, nNewIndex5, nNewIndex3); pFaceConnectivity.AddEdge(nSubMesh, v3, v1, nHashV3, nHashV1, nNewIndex3, nNewIndex1); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV4, nHashV5, plistVertexData[nNewIndex4].v3Vertex, plistVertexData[nNewIndex5].v3Vertex); if(pdicClippedEdges.ContainsKey(edgeKey1) == false) pdicClippedEdges.Add(edgeKey1, new ClippedEdge(nIndex1, nIndex2, nNewIndex1, nNewIndex2, nNewIndex4)); if(pdicClippedEdges.ContainsKey(edgeKey2) == false) pdicClippedEdges.Add(edgeKey2, new ClippedEdge(nIndex2, nIndex3, nNewIndex2, nNewIndex3, nNewIndex5)); // Add geometry of other side if(fSide2 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } else { plistVertexData = listVertexDataPos; plistObjectIndices = listIndicesPos; pFaceConnectivity = faceConnectivityPos; pMeshConnectivity = meshConnectivityPos; pdicClippedEdges = dicClippedEdgesPos; pdicRemappedIndices = dicRemappedIndicesPos; } nNewIndex1 = -1; nNewIndex2 = -1; nNewIndex3 = -1; nNewIndex4 = -1; nNewIndex5 = -1; bEdgeKey1 = false; bEdgeKey2 = false; // Find edges in cache if(pdicClippedEdges.ContainsKey(edgeKey1)) { nClippedCacheHits++; bEdgeKey1 = true; nNewIndex2 = pdicClippedEdges[edgeKey1].GetSecondIndex(nIndex2); nNewIndex4 = pdicClippedEdges[edgeKey1].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex2)) nNewIndex2 = pdicRemappedIndices[nIndex2]; } if(pdicClippedEdges.ContainsKey(edgeKey2)) { nClippedCacheHits++; bEdgeKey2 = true; nNewIndex2 = pdicClippedEdges[edgeKey2].GetFirstIndex(nIndex2); nNewIndex5 = pdicClippedEdges[edgeKey2].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex2)) nNewIndex2 = pdicRemappedIndices[nIndex2]; } // Add vertex data for all data not present in remapped list if(nNewIndex2 == -1) { nNewIndex2 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex2].Copy()); pdicRemappedIndices[nIndex2] = nNewIndex2; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(nNewIndex5 == -1) { nNewIndex5 = plistVertexData.Count; plistVertexData.Add(vd5); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex4); plistObjectIndices.Add(nNewIndex2); plistObjectIndices.Add(nNewIndex5); if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v4, v2, nHashV4, nHashV2, nNewIndex4, nNewIndex2); pFaceConnectivity.AddEdge(nSubMesh, v2, v5, nHashV2, nHashV5, nNewIndex2, nNewIndex5); pFaceConnectivity.AddEdge(nSubMesh, v5, v4, nHashV5, nHashV4, nNewIndex5, nNewIndex4); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV5, nHashV4, plistVertexData[nNewIndex5].v3Vertex, plistVertexData[nNewIndex4].v3Vertex); if(pdicClippedEdges.ContainsKey(edgeKey1) == false) pdicClippedEdges.Add(edgeKey1, new ClippedEdge(nIndex1, nIndex2, nNewIndex1, nNewIndex2, nNewIndex4)); if(pdicClippedEdges.ContainsKey(edgeKey2) == false) pdicClippedEdges.Add(edgeKey2, new ClippedEdge(nIndex2, nIndex3, nNewIndex2, nNewIndex3, nNewIndex5)); } else { // ... and v3 on same side as v2 if(fSide1 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } int nNewIndex1 = -1; int nNewIndex2 = -1; int nNewIndex3 = -1; int nNewIndex4 = -1; int nNewIndex5 = -1; int nHashV4 = -1; int nHashV5 = -1; bool bEdgeKey1 = false; bool bEdgeKey3 = false; EdgeKeyByIndex edgeKey1 = new EdgeKeyByIndex(nIndex1, nIndex2); EdgeKeyByIndex edgeKey3 = new EdgeKeyByIndex(nIndex1, nIndex3); // Find edges in cache if(pdicClippedEdges.ContainsKey(edgeKey1)) { nClippedCacheHits++; bEdgeKey1 = true; nNewIndex1 = pdicClippedEdges[edgeKey1].GetFirstIndex(nIndex1); nNewIndex4 = pdicClippedEdges[edgeKey1].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex1)) nNewIndex1 = pdicRemappedIndices[nIndex1]; } if(pdicClippedEdges.ContainsKey(edgeKey3)) { nClippedCacheHits++; bEdgeKey3 = true; nNewIndex1 = pdicClippedEdges[edgeKey3].GetFirstIndex(nIndex1); nNewIndex5 = pdicClippedEdges[edgeKey3].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex1)) nNewIndex1 = pdicRemappedIndices[nIndex1]; } // Clip if not present in clipped edge list EdgeKeyByHash clippedEdgeKeyHash = new EdgeKeyByHash(nHashV1, nHashV2); if(dicClipVerticesHash.ContainsKey(clippedEdgeKeyHash)) { nHashV4 = dicClipVerticesHash[clippedEdgeKeyHash]; } else { nHashV4 = nCurrentVertexHash++; dicClipVerticesHash.Add(clippedEdgeKeyHash, nHashV4); } clippedEdgeKeyHash = new EdgeKeyByHash(nHashV1, nHashV3); if(dicClipVerticesHash.ContainsKey(clippedEdgeKeyHash)) { nHashV5 = dicClipVerticesHash[clippedEdgeKeyHash]; } else { nHashV5 = nCurrentVertexHash++; dicClipVerticesHash.Add(clippedEdgeKeyHash, nHashV5); } VertexData vd4 = new VertexData(nHashV4), vd5 = new VertexData(nHashV5); if(bEdgeKey1 == false) { if(VertexData.ClipAgainstPlane(meshDataIn.aVertexData, nIndex1, nIndex2, v1, v2, planeSplit, ref vd4) == false) { return false; } } if(bEdgeKey3 == false) { if(VertexData.ClipAgainstPlane(meshDataIn.aVertexData, nIndex1, nIndex3, v1, v3, planeSplit, ref vd5) == false) { return false; } } // Add geometry of one side // Add vertex data for all data not present in remapped list if(nNewIndex1 == -1) { nNewIndex1 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex1].Copy()); pdicRemappedIndices[nIndex1] = nNewIndex1; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(nNewIndex5 == -1) { nNewIndex5 = plistVertexData.Count; plistVertexData.Add(vd5); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex1); plistObjectIndices.Add(nNewIndex4); plistObjectIndices.Add(nNewIndex5); Vector3 v4 = plistVertexData[nNewIndex4].v3Vertex; Vector3 v5 = plistVertexData[nNewIndex5].v3Vertex; if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v1, v4, nHashV1, nHashV4, nNewIndex1, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v5, nHashV4, nHashV5, nNewIndex4, nNewIndex5); pFaceConnectivity.AddEdge(nSubMesh, v5, v1, nHashV5, nHashV1, nNewIndex5, nNewIndex1); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV4, nHashV5, plistVertexData[nNewIndex4].v3Vertex, plistVertexData[nNewIndex5].v3Vertex); if(pdicClippedEdges.ContainsKey(edgeKey1) == false) pdicClippedEdges.Add(edgeKey1, new ClippedEdge(nIndex1, nIndex2, nNewIndex1, nNewIndex2, nNewIndex4)); if(pdicClippedEdges.ContainsKey(edgeKey3) == false) pdicClippedEdges.Add(edgeKey3, new ClippedEdge(nIndex1, nIndex3, nNewIndex1, nNewIndex3, nNewIndex5)); // Add geometry of other side if(fSide2 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } else { plistVertexData = listVertexDataPos; plistObjectIndices = listIndicesPos; pFaceConnectivity = faceConnectivityPos; pMeshConnectivity = meshConnectivityPos; pdicClippedEdges = dicClippedEdgesPos; pdicRemappedIndices = dicRemappedIndicesPos; } nNewIndex1 = -1; nNewIndex2 = -1; nNewIndex3 = -1; nNewIndex4 = -1; nNewIndex5 = -1; bEdgeKey1 = false; bEdgeKey3 = false; // Find edges in cache if(pdicClippedEdges.ContainsKey(edgeKey1)) { nClippedCacheHits++; bEdgeKey1 = true; nNewIndex2 = pdicClippedEdges[edgeKey1].GetSecondIndex(nIndex2); nNewIndex4 = pdicClippedEdges[edgeKey1].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex2)) nNewIndex2 = pdicRemappedIndices[nIndex2]; } if(pdicClippedEdges.ContainsKey(edgeKey3)) { nClippedCacheHits++; bEdgeKey3 = true; nNewIndex3 = pdicClippedEdges[edgeKey3].GetSecondIndex(nIndex3); nNewIndex5 = pdicClippedEdges[edgeKey3].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex3)) nNewIndex3 = pdicRemappedIndices[nIndex3]; } // Add vertex data for all data not present in remapped list if(nNewIndex2 == -1) { nNewIndex2 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex2].Copy()); pdicRemappedIndices[nIndex2] = nNewIndex2; } if(nNewIndex3 == -1) { nNewIndex3 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex3].Copy()); pdicRemappedIndices[nIndex3] = nNewIndex3; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(nNewIndex5 == -1) { nNewIndex5 = plistVertexData.Count; plistVertexData.Add(vd5); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex4); plistObjectIndices.Add(nNewIndex2); plistObjectIndices.Add(nNewIndex3); if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex4); plistObjectIndices.Add(nNewIndex3); plistObjectIndices.Add(nNewIndex5); if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v4, v2, nHashV4, nHashV2, nNewIndex4, nNewIndex2); pFaceConnectivity.AddEdge(nSubMesh, v2, v3, nHashV2, nHashV3, nNewIndex2, nNewIndex3); pFaceConnectivity.AddEdge(nSubMesh, v3, v4, nHashV3, nHashV4, nNewIndex3, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v3, nHashV4, nHashV3, nNewIndex4, nNewIndex3); pFaceConnectivity.AddEdge(nSubMesh, v3, v5, nHashV3, nHashV5, nNewIndex3, nNewIndex5); pFaceConnectivity.AddEdge(nSubMesh, v5, v4, nHashV5, nHashV4, nNewIndex5, nNewIndex4); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV5, nHashV4, plistVertexData[nNewIndex5].v3Vertex, plistVertexData[nNewIndex4].v3Vertex); if(pdicClippedEdges.ContainsKey(edgeKey1) == false) pdicClippedEdges.Add(edgeKey1, new ClippedEdge(nIndex1, nIndex2, nNewIndex1, nNewIndex2, nNewIndex4)); if(pdicClippedEdges.ContainsKey(edgeKey3) == false) pdicClippedEdges.Add(edgeKey3, new ClippedEdge(nIndex1, nIndex3, nNewIndex1, nNewIndex3, nNewIndex5)); } } else if(fSide2 * fSide3 < 0.0f) { // v1 and v2 on same side, and v3 on different side if(fSide1 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } int nNewIndex1 = -1; int nNewIndex2 = -1; int nNewIndex3 = -1; int nNewIndex4 = -1; int nNewIndex5 = -1; int nHashV4 = -1; int nHashV5 = -1; bool bEdgeKey2 = false; bool bEdgeKey3 = false; EdgeKeyByIndex edgeKey2 = new EdgeKeyByIndex(nIndex2, nIndex3); EdgeKeyByIndex edgeKey3 = new EdgeKeyByIndex(nIndex1, nIndex3); // Find edges in cache if(pdicClippedEdges.ContainsKey(edgeKey2)) { nClippedCacheHits++; bEdgeKey2 = true; nNewIndex2 = pdicClippedEdges[edgeKey2].GetFirstIndex(nIndex2); nNewIndex5 = pdicClippedEdges[edgeKey2].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex2)) nNewIndex2 = pdicRemappedIndices[nIndex2]; } if(pdicClippedEdges.ContainsKey(edgeKey3)) { nClippedCacheHits++; bEdgeKey3 = true; nNewIndex1 = pdicClippedEdges[edgeKey3].GetFirstIndex(nIndex1); nNewIndex4 = pdicClippedEdges[edgeKey3].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex1)) nNewIndex1 = pdicRemappedIndices[nIndex1]; } // Clip if not present in clipped edge list EdgeKeyByHash clippedEdgeKeyHash = new EdgeKeyByHash(nHashV1, nHashV3); if(dicClipVerticesHash.ContainsKey(clippedEdgeKeyHash)) { nHashV4 = dicClipVerticesHash[clippedEdgeKeyHash]; } else { nHashV4 = nCurrentVertexHash++; dicClipVerticesHash.Add(clippedEdgeKeyHash, nHashV4); } clippedEdgeKeyHash = new EdgeKeyByHash(nHashV2, nHashV3); if(dicClipVerticesHash.ContainsKey(clippedEdgeKeyHash)) { nHashV5 = dicClipVerticesHash[clippedEdgeKeyHash]; } else { nHashV5 = nCurrentVertexHash++; dicClipVerticesHash.Add(clippedEdgeKeyHash, nHashV5); } VertexData vd4 = new VertexData(nHashV4), vd5 = new VertexData(nHashV5); if(bEdgeKey2 == false) { if(VertexData.ClipAgainstPlane(meshDataIn.aVertexData, nIndex2, nIndex3, v2, v3, planeSplit, ref vd5) == false) { return false; } } if(bEdgeKey3 == false) { if(VertexData.ClipAgainstPlane(meshDataIn.aVertexData, nIndex1, nIndex3, v1, v3, planeSplit, ref vd4) == false) { return false; } } // Add geometry of one side // Add vertex data for all data not present in remapped list if(nNewIndex1 == -1) { nNewIndex1 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex1].Copy()); pdicRemappedIndices[nIndex1] = nNewIndex1; } if(nNewIndex2 == -1) { nNewIndex2 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex2].Copy()); pdicRemappedIndices[nIndex2] = nNewIndex2; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(nNewIndex5 == -1) { nNewIndex5 = plistVertexData.Count; plistVertexData.Add(vd5); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex2); plistObjectIndices.Add(nNewIndex5); plistObjectIndices.Add(nNewIndex4); if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex2); plistObjectIndices.Add(nNewIndex4); plistObjectIndices.Add(nNewIndex1); Vector3 v4 = plistVertexData[nNewIndex4].v3Vertex; Vector3 v5 = plistVertexData[nNewIndex5].v3Vertex; if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v2, v5, nHashV2, nHashV5, nNewIndex2, nNewIndex5); pFaceConnectivity.AddEdge(nSubMesh, v5, v4, nHashV5, nHashV4, nNewIndex5, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v2, nHashV4, nHashV2, nNewIndex4, nNewIndex2); pFaceConnectivity.AddEdge(nSubMesh, v2, v4, nHashV2, nHashV4, nNewIndex2, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v1, nHashV4, nHashV1, nNewIndex4, nNewIndex1); pFaceConnectivity.AddEdge(nSubMesh, v1, v2, nHashV1, nHashV2, nNewIndex1, nNewIndex2); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV5, nHashV4, plistVertexData[nNewIndex5].v3Vertex, plistVertexData[nNewIndex4].v3Vertex); if(pdicClippedEdges.ContainsKey(edgeKey2) == false) pdicClippedEdges.Add(edgeKey2, new ClippedEdge(nIndex2, nIndex3, nNewIndex2, nNewIndex3, nNewIndex5)); if(pdicClippedEdges.ContainsKey(edgeKey3) == false) pdicClippedEdges.Add(edgeKey3, new ClippedEdge(nIndex1, nIndex3, nNewIndex1, nNewIndex3, nNewIndex4)); // Add geometry of other side if(fSide3 < 0.0f) { plistVertexData = listVertexDataNeg; plistObjectIndices = listIndicesNeg; pFaceConnectivity = faceConnectivityNeg; pMeshConnectivity = meshConnectivityNeg; pdicClippedEdges = dicClippedEdgesNeg; pdicRemappedIndices = dicRemappedIndicesNeg; } else { plistVertexData = listVertexDataPos; plistObjectIndices = listIndicesPos; pFaceConnectivity = faceConnectivityPos; pMeshConnectivity = meshConnectivityPos; pdicClippedEdges = dicClippedEdgesPos; pdicRemappedIndices = dicRemappedIndicesPos; } nNewIndex1 = -1; nNewIndex2 = -1; nNewIndex3 = -1; nNewIndex4 = -1; nNewIndex5 = -1; bEdgeKey2 = false; bEdgeKey3 = false; // Find edges in cache if(pdicClippedEdges.ContainsKey(edgeKey2)) { nClippedCacheHits++; bEdgeKey2 = true; nNewIndex3 = pdicClippedEdges[edgeKey2].GetSecondIndex(nIndex3); nNewIndex5 = pdicClippedEdges[edgeKey2].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex3)) nNewIndex3 = pdicRemappedIndices[nIndex3]; } if(pdicClippedEdges.ContainsKey(edgeKey3)) { nClippedCacheHits++; bEdgeKey3 = true; nNewIndex3 = pdicClippedEdges[edgeKey3].GetSecondIndex(nIndex3); nNewIndex4 = pdicClippedEdges[edgeKey3].nClippedIndex; } else { nClippedCacheMisses++; if(pdicRemappedIndices.ContainsKey(nIndex3)) nNewIndex3 = pdicRemappedIndices[nIndex3]; } // Add vertex data for all data not present in remapped list if(nNewIndex3 == -1) { nNewIndex3 = plistVertexData.Count; plistVertexData.Add(meshDataIn.aVertexData[nIndex3].Copy()); pdicRemappedIndices[nIndex3] = nNewIndex3; } if(nNewIndex4 == -1) { nNewIndex4 = plistVertexData.Count; plistVertexData.Add(vd4); } if(nNewIndex5 == -1) { nNewIndex5 = plistVertexData.Count; plistVertexData.Add(vd5); } if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoChunkConnectionInfo == false) { pMeshConnectivity.NotifyNewClippedFace(meshDataIn, nSubMesh, i, nSubMesh, plistObjectIndices.Count / 3); } plistObjectIndices.Add(nNewIndex5); plistObjectIndices.Add(nNewIndex3); plistObjectIndices.Add(nNewIndex4); if(fracturedComponent.GenerateIslands && splitOptions.bForceNoIslandGeneration == false) { pFaceConnectivity.AddEdge(nSubMesh, v5, v3, nHashV5, nHashV3, nNewIndex5, nNewIndex3); pFaceConnectivity.AddEdge(nSubMesh, v3, v4, nHashV3, nHashV4, nNewIndex3, nNewIndex4); pFaceConnectivity.AddEdge(nSubMesh, v4, v5, nHashV4, nHashV5, nNewIndex4, nNewIndex5); } // Update cap edges and cache if(plistVertexData == listVertexDataPos && splitOptions.bForceNoCap == false) AddCapEdge(dicCapEdges, nHashV4, nHashV5, plistVertexData[nNewIndex4].v3Vertex, plistVertexData[nNewIndex5].v3Vertex); if(pdicClippedEdges.ContainsKey(edgeKey2) == false) pdicClippedEdges.Add(edgeKey2, new ClippedEdge(nIndex2, nIndex3, nNewIndex2, nNewIndex3, nNewIndex5)); if(pdicClippedEdges.ContainsKey(edgeKey3) == false) pdicClippedEdges.Add(edgeKey3, new ClippedEdge(nIndex1, nIndex3, nNewIndex1, nNewIndex3, nNewIndex4)); } } } } // Debug.Log("Clipped cache hits " + nClippedCacheHits + " clipped cache misses " + nClippedCacheMisses); // Compute transforms Vector3 v3CenterPos = Vector3.zero; if(listVertexDataPos.Count > 0) { Vector3 v3Min = Vector3.zero, v3Max = Vector3.zero; MeshData.ComputeMinMax(listVertexDataPos, ref v3Min, ref v3Max); v3CenterPos = (v3Min + v3Max) * 0.5f; } Matrix4x4 mtxToLocalPos = Matrix4x4.TRS(v3CenterPos, meshDataIn.qRotation, meshDataIn.v3Scale).inverse; if(splitOptions.bVerticesAreLocal) { mtxToLocalPos = Matrix4x4.TRS(v3CenterPos, Quaternion.identity, Vector3.one).inverse; } Vector3 v3CenterNeg = Vector3.zero; if(listVertexDataNeg.Count > 0) { Vector3 v3Min = Vector3.zero, v3Max = Vector3.zero; MeshData.ComputeMinMax(listVertexDataNeg, ref v3Min, ref v3Max); v3CenterNeg = (v3Min + v3Max) * 0.5f; } Matrix4x4 mtxToLocalNeg = Matrix4x4.TRS(v3CenterNeg, meshDataIn.qRotation, meshDataIn.v3Scale).inverse; if(splitOptions.bVerticesAreLocal) { mtxToLocalNeg = Matrix4x4.TRS(v3CenterNeg, Quaternion.identity, Vector3.one).inverse; } // Resolve cap outline and add its geometry List<List<Vector3>> listlistResolvedCapVertices = new List<List<Vector3>>(); List<List<int>> listlistResolvedCapHashValues = new List<List<int>>(); bool bNeedsConnectivityPostprocess = false; Matrix4x4 mtxPlane = Matrix4x4.TRS(v3PlanePoint, Quaternion.LookRotation(Vector3.Cross(v3PlaneNormal, v3PlaneRight), v3PlaneNormal), Vector3.one); if(dicCapEdges.Count > 0 && splitOptions.bForceNoCap == false) { if(ResolveCap(dicCapEdges, listlistResolvedCapVertices, listlistResolvedCapHashValues, fracturedComponent)) { if(listlistResolvedCapVertices.Count > 1) { // There's more than one closed cap. We need to postprocess the mesh because there may be more than one object on a side of the plane as a result of the clipping. bNeedsConnectivityPostprocess = (fracturedComponent.GenerateIslands && (splitOptions.bForceNoIslandGeneration == false)) ? true : false; } TriangulateConstrainedDelaunay( listlistResolvedCapVertices, listlistResolvedCapHashValues, splitOptions.bForceCapVertexSoup, fracturedComponent, bNeedsConnectivityPostprocess, faceConnectivityPos, faceConnectivityNeg, meshConnectivityPos, meshConnectivityNeg, splitOptions.nForceMeshConnectivityHash, nSplitCloseSubMesh, mtxPlane, mtxToLocalPos, mtxToLocalNeg, v3CenterPos, v3CenterNeg, alistIndicesPos, listVertexDataPos, alistIndicesNeg, listVertexDataNeg); } else { if(fracturedComponent.Verbose) Debug.LogWarning("Error resolving cap"); } } // Postprocess if necessary if(bNeedsConnectivityPostprocess) { // Search for multiple objects inside each meshes List<MeshData> listIslandsPos = MeshData.PostProcessConnectivity(meshDataIn, faceConnectivityPos, meshConnectivityPos, alistIndicesPos, listVertexDataPos, nSplitCloseSubMesh, nCurrentVertexHash, false); List<MeshData> listIslandsNeg = new List<MeshData>(); if(splitOptions.bIgnoreNegativeSide == false) { listIslandsNeg = MeshData.PostProcessConnectivity(meshDataIn, faceConnectivityNeg, meshConnectivityNeg, alistIndicesNeg, listVertexDataNeg, nSplitCloseSubMesh, nCurrentVertexHash, false); } // Sometimes we are feed a mesh with multiple islands as input. If this is the case, compute connectivity between islands at this point. List<MeshData> listTotalIslands = new List<MeshData>(); listTotalIslands.AddRange(listIslandsPos); listTotalIslands.AddRange(listIslandsNeg); if(fracturedComponent.GenerateChunkConnectionInfo && splitOptions.bForceNoIslandConnectionInfo == false) { for(int i = 0; i < listTotalIslands.Count; i++) { if(progress != null && listTotalIslands.Count > 10 && splitOptions.bForceNoProgressInfo == false) { progress("Fracturing", "Processing island connectivity...", i / (float)listTotalIslands.Count); if(Fracturer.IsFracturingCancelled()) return false; } for(int j = 0; j < listTotalIslands.Count; j++) { if(i != j) { ComputeIslandsMeshDataConnectivity(fracturedComponent, splitOptions.bVerticesAreLocal, listTotalIslands[i], listTotalIslands[j]); } } } } listMeshDatasPosOut.AddRange(listIslandsPos); listMeshDatasNegOut.AddRange(listIslandsNeg); } else { // Create new MeshDatas if(listVertexDataPos.Count > 0 && alistIndicesPos.Length > 0) { MeshData newMeshData = new MeshData(meshDataIn.aMaterials, alistIndicesPos, listVertexDataPos, nSplitCloseSubMesh, v3CenterPos, meshDataIn.qRotation, meshDataIn.v3Scale, mtxToLocalPos, false, false); newMeshData.meshDataConnectivity = meshConnectivityPos; newMeshData.nCurrentVertexHash = nCurrentVertexHash; listMeshDatasPosOut.Add(newMeshData); } if(listVertexDataNeg.Count > 0 && alistIndicesNeg.Length > 0 && splitOptions.bIgnoreNegativeSide == false) { MeshData newMeshData = new MeshData(meshDataIn.aMaterials, alistIndicesNeg, listVertexDataNeg, nSplitCloseSubMesh, v3CenterNeg, meshDataIn.qRotation, meshDataIn.v3Scale, mtxToLocalNeg, false, false); newMeshData.meshDataConnectivity = meshConnectivityNeg; newMeshData.nCurrentVertexHash = nCurrentVertexHash; listMeshDatasNegOut.Add(newMeshData); } } return true; }
//增加读取纹理坐标 private unsafe uint ReadVertexData(uint vertexOffset, VertexData vertexData) { VertexElement posElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); HardwareVertexBufferSharedPtr vertexBuffer = vertexData.vertexBufferBinding.GetBuffer(posElem.Source); byte* vertexMemory = (byte*)vertexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); float* pElem; bool needrecomputeVertex = false; if (this._quaoffset != Quaternion.IDENTITY || this._posoffset != Vector3.ZERO) { needrecomputeVertex = true; } //texture if (_readTextureCoordinate) { ReadTextureCoordData(vertexOffset, vertexMemory, vertexBuffer.VertexSize, vertexData); } if (needrecomputeVertex) { for (uint i = 0; i < vertexData.vertexCount; i++) { posElem.BaseVertexPointerToElement(vertexMemory, &pElem); Vector3 point = new Vector3(pElem[0], pElem[1], pElem[2]); // vertices[current_offset + j] = (orientation * (pt * scale)) + position; _vertices[vertexOffset] = GetVextexTrans(point, this._quaoffset, this._scale, this._posoffset); //point * this.scale; vertexMemory += vertexBuffer.VertexSize; vertexOffset++; } } else { for (uint i = 0; i < vertexData.vertexCount; i++) { posElem.BaseVertexPointerToElement(vertexMemory, &pElem); Vector3 point = new Vector3(pElem[0], pElem[1], pElem[2]); _vertices[vertexOffset] = point * this._scale; vertexMemory += vertexBuffer.VertexSize; vertexOffset++; } } vertexBuffer.Unlock(); // SGD :2013/6/8 13:43:51 // 说明:销毁指针引用 防止.NET回收 vertexBuffer.Dispose(); return vertexOffset; }
public void Add(string name, Texture2D texture, int tiles_x, int tiles_y) { int tile_width = (int)FMath.Round((float)texture.Width / (float)tiles_x); int tile_height = (int)FMath.Round((float)texture.Height / (float)tiles_y); tile_width /= ScaleDivisor; tile_height /= ScaleDivisor; tile_width = System.Math.Max(1, tile_width); tile_height = System.Math.Max(1, tile_height); ColorBuffer color_buffer = new ColorBuffer(tile_width, tile_height, PixelFormat.Rgba); FrameBuffer frame_buffer = new FrameBuffer(); frame_buffer.SetColorTarget(color_buffer); FrameBuffer old_frame_buffer = Director.Instance.GL.Context.GetFrameBuffer(); Director.Instance.GL.Context.SetFrameBuffer(frame_buffer); ShaderProgram.SetAttributeBinding(0, "iPosition"); ShaderProgram.SetAttributeBinding(1, "iUV"); texture.SetWrap(TextureWrapMode.ClampToEdge); texture.SetFilter(TextureFilterMode.Linear); Director.Instance.GL.Context.SetTexture(0, texture); Director.Instance.GL.Context.SetVertexBuffer(0, VertexBuffer); Director.Instance.GL.Context.SetShaderProgram(ShaderProgram); ImageRect old_scissor = Director.Instance.GL.Context.GetScissor(); ImageRect old_viewport = Director.Instance.GL.Context.GetViewport(); Director.Instance.GL.Context.SetScissor(0, 0, tile_width, tile_height); Director.Instance.GL.Context.SetViewport(0, 0, tile_width, tile_height); Entry entry = new Entry(); entry.TilesX = tiles_x; entry.TilesY = tiles_y; entry.TileWidth = tile_width; entry.TileHeight = tile_height; entry.Data = new List<List<byte>>(); for (int i = 0; i < tiles_y * tiles_x; ++i) entry.Data.Add(new List<byte>()); Vector2 uv_step = new Vector2(1.0f, 1.0f) / new Vector2(tiles_x, tiles_y); for (int y = 0; y < tiles_y; y++) { for (int x = 0; x < tiles_x; x++) { float uv_x0 = uv_step.X * (x + 0); float uv_x1 = uv_step.X * (x + 1); float uv_y0 = uv_step.Y * (tiles_y - 1 - y + 0); float uv_y1 = uv_step.Y * (tiles_y - 1 - y + 1); VertexDataArray[0] = new VertexData() { position = new Vector2(-1.0f, -1.0f), uv = new Vector2(uv_x0, uv_y1) }; VertexDataArray[1] = new VertexData() { position = new Vector2(-1.0f, +1.0f), uv = new Vector2(uv_x0, uv_y0) }; VertexDataArray[2] = new VertexData() { position = new Vector2(+1.0f, +1.0f), uv = new Vector2(uv_x1, uv_y0) }; VertexDataArray[3] = new VertexData() { position = new Vector2(+1.0f, -1.0f), uv = new Vector2(uv_x1, uv_y1) }; VertexBuffer.SetIndices(IndexDataArray, 0, 0, 4); VertexBuffer.SetVertices(VertexDataArray, 0, 0, 4); Director.Instance.GL.Context.SetVertexBuffer(0, VertexBuffer); Director.Instance.GL.Context.DrawArrays(DrawMode.TriangleFan, 0, 4); byte[] data = new byte[tile_width * tile_height * 4]; // DEBUG: fill with visible memory pattern //for (int i = 0; i< tile_width * tile_height * 4; ++i) //data[i] = (byte)(i % (tile_width / 4)); Director.Instance.GL.Context.ReadPixels(data, PixelFormat.Rgba, 0, 0, tile_width, tile_height); List<byte> output = entry.Data[tiles_x * y + x]; for (int i = 0; i < tile_width * tile_height * 4; ++i) output.Add(data[i]); } } Director.Instance.GL.Context.SetVertexBuffer(0, null); Director.Instance.GL.Context.SetShaderProgram(null); Director.Instance.GL.Context.SetFrameBuffer(old_frame_buffer); Director.Instance.GL.Context.SetScissor(old_scissor); Director.Instance.GL.Context.SetViewport(old_viewport); TileData[name] = entry; }
// SGD :2013/6/18 15:02:51 // 说明:顶点纹理坐标 private unsafe void ReadTextureCoordData(uint vertexOffset, byte* vertexBuffer_Lock, uint vertexBuffer_VertexSize, VertexData vertexData) { VertexElement texElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_TEXTURE_COORDINATES); float* tReal; if (texElem == null) { for (uint i = 0; i < vertexData.vertexCount; i++) { this._textureCroodnitas[vertexOffset + i] = new Vector2(0f, 0f); } } else { //byte* vextex = vertexBuffer_Lock; //for (uint i = 0; i < vertexData.vertexCount; i++) { // texElem.BaseVertexPointerToElement(vextex, &tReal); // this._textureCroodnitas[vertexOffset + i] = new Vector2(tReal[0], tReal[1]); // vextex += vertexBuffer_VertexSize; //} //读取纹理坐标修正 2013/12/18 VertexData vertex_data=vertexData; HardwareVertexBufferSharedPtr vbufPtr_tex = vertex_data.vertexBufferBinding.GetBuffer(texElem.Source); byte* vertex_tex = (byte*)vbufPtr_tex.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); for (uint i = 0; i < vertex_data.vertexCount; ++i, /*vertex += vbufPtr.VertexSize,*/ vertex_tex += vbufPtr_tex.VertexSize) { //posElem.BaseVertexPointerToElement(vertex, &pReal); texElem.BaseVertexPointerToElement(vertex_tex, &tReal); this._textureCroodnitas[vertexOffset + i] = new Vector2(tReal[0], tReal[1]); vertex_tex += vertexBuffer_VertexSize; //Vector3 pt = new Vector3(pReal[0], pReal[1], pReal[2]); //vertices[current_offset + j] = (orientation * (pt * scale)) + position; //tex_Cors[current_offset + j] = new Vector2(tReal[0], tReal[1]); } vbufPtr_tex.Unlock(); vbufPtr_tex.Dispose(); } }
// Assumes file has everything right, else get bad results and/or an exception is thrown // Assumes read pointer is at the line after "coord Coordinate { point [" /// <summary> /// Reads in all the vertices and indices of the figure being loaded. /// </summary> private void ReadVertsForShapeInVRML() { List<Vector3> verts = new List<Vector3>(); List<Vector3> colors = new List<Vector3>(); List<ushort> vertIndices = new List<ushort>(); List<ushort> colorIndices = new List<ushort>(); ReadVectListFromVMRL(verts); LookForInVMRL("coordIndex ["); ReadIndicesListFromVRML(vertIndices); LookForInVMRL("color Color { color ["); ReadVectListFromVMRL(colors); LookForInVMRL("colorIndex ["); ReadIndicesListFromVRML(colorIndices); for (int i = 0; i < vertIndices.Count; i++) { VertexData v = new VertexData(verts[vertIndices[i]], colors[colorIndices[i]]); vertList.Add(v); } CalculateNormals(); }
private unsafe uint ReadVertexData(uint vertexOffset, VertexData vertexData) { VertexElement posElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); HardwareVertexBufferSharedPtr vertexBuffer = vertexData.vertexBufferBinding.GetBuffer(posElem.Source); byte* vertexMemory = (byte*)vertexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); float* pElem; for (uint i = 0; i < vertexData.vertexCount; i++) { posElem.BaseVertexPointerToElement(vertexMemory, &pElem); Mogre.Vector3 point = new Mogre.Vector3(pElem[0], pElem[1], pElem[2]); vertices[vertexOffset] = point * this.scale; vertexMemory += vertexBuffer.VertexSize; vertexOffset++; } vertexBuffer.Unlock(); return vertexOffset; }
private void CreateBuffers(ushort[] indices, short[] vertices) { var numIndices = (uint)indices.Length; var numVertices = (uint)vertices.Length; _vertexDeclaration = HardwareBufferManager.Singleton.CreateVertexDeclaration(); _vertexDeclaration.AddElement(0, 0, VertexElementType.VET_SHORT2, VertexElementSemantic.VES_POSITION); _ib = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, numIndices, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); _vb = HardwareBufferManager.Singleton.CreateVertexBuffer(_vertexDeclaration.GetVertexSize(0), numVertices, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); unsafe { fixed (ushort* x = indices) _ib.WriteData(0, numIndices * sizeof(ushort), x, true); fixed (short* x = vertices) _vb.WriteData(0, numVertices * sizeof(ushort), x, true); } var binding = new VertexBufferBinding(); binding.SetBinding(0, _vb); VertexData = new VertexData(_vertexDeclaration, binding); VertexData.vertexCount = numVertices; VertexData.vertexStart = 0; IndexData = new IndexData(); IndexData.indexBuffer = _ib; IndexData.indexCount = numIndices; IndexData.indexStart = 0; }
public IEnumerable<VertexData> GetVertexIter() { VertexData vertexData = new VertexData(); vertexData.command = VertexCmd.MoveTo; vertexData.position = m_points[0]; yield return vertexData; vertexData.command = VertexCmd.LineTo; for (int i = 1; i < m_points.Count; i++) { vertexData.position = m_points[i]; yield return vertexData; } vertexData.command = VertexCmd.Stop; vertexData.position = new Vector2(); yield return vertexData; }
/// <summary> /// Calculates the normal vectors based on each set of three vertices. /// Creates a "flat-shaded", or "boxy" style when given to the shader program. /// </summary> private void CalculateNormals() { // This will be completed in a future program // I will explain then why we don't want to use the normals the Wings3d exports. // This assumes that Wings3d exports faces in CC order. // After we cover this, you should be able to write this in a small number of lines using Vector3 operations. // Hint: Loop through, processing 3 verts at a time. // Note that in C#, you can't do: vertList[i + 2].Normal = normal; // You need to do something like: vertList[i + 2] = new VertexData(vertList[i + 2].Position, vertList[i + 2].Color, normal); for (int i = 0; i < vertList.Count; i += 3) { Vector3 normal = Vector3.Cross(vertList[i + 1].Position - vertList[i].Position, vertList[i + 2].Position - vertList[i].Position); normal = Vector3.Normalize(normal); vertList[i] = new VertexData(vertList[i].Position, vertList[i].Color, normal); vertList[i + 1] = new VertexData(vertList[i + 1].Position, vertList[i + 1].Color, normal); vertList[i + 2] = new VertexData(vertList[i + 2].Position, vertList[i + 2].Color, normal); } }
VertexData CreateVertexData( Vec3[] vertices ) { VertexData vertexData = new VertexData(); VertexDeclaration declaration = vertexData.VertexDeclaration; declaration.AddElement( 0, 0, VertexElementType.Float3, VertexElementSemantic.Position ); VertexBufferBinding bufferBinding = vertexData.VertexBufferBinding; HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( 12, vertices.Length, HardwareBuffer.Usage.StaticWriteOnly ); bufferBinding.SetBinding( 0, vertexBuffer, true ); vertexData.VertexCount = vertices.Length; unsafe { Vec3* buffer = (Vec3*)vertexBuffer.Lock( HardwareBuffer.LockOptions.Normal ).ToPointer(); foreach( Vec3 position in vertices ) { *buffer = position; buffer++; } vertexBuffer.Unlock(); } return vertexData; }
public void TestOffscreen(string name, Texture2D texture) { const int Width = 32; const int Height = 32; ImageRect old_scissor = Director.Instance.GL.Context.GetScissor(); ImageRect old_viewport = Director.Instance.GL.Context.GetViewport(); FrameBuffer old_frame_buffer = Director.Instance.GL.Context.GetFrameBuffer(); ColorBuffer color_buffer = new ColorBuffer(Width, Height, PixelFormat.Rgba); FrameBuffer frame_buffer = new FrameBuffer(); frame_buffer.SetColorTarget(color_buffer); System.Console.WriteLine("SetFrameBuffer(): enter"); Director.Instance.GL.Context.SetFrameBuffer(frame_buffer); System.Console.WriteLine("SetFrameBuffer(): exit"); ShaderProgram.SetAttributeBinding(0, "iPosition"); ShaderProgram.SetAttributeBinding(1, "iUV"); texture.SetWrap(TextureWrapMode.ClampToEdge); texture.SetFilter(TextureFilterMode.Linear); Director.Instance.GL.Context.SetTexture(0, texture); Director.Instance.GL.Context.SetVertexBuffer(0, VertexBuffer); Director.Instance.GL.Context.SetShaderProgram(ShaderProgram); Director.Instance.GL.Context.SetScissor(0, 0, Width, Height); Director.Instance.GL.Context.SetViewport(0, 0, Width, Height); float uv_x0 = 0.0f; float uv_x1 = 1.0f; float uv_y0 = 0.0f; float uv_y1 = 1.0f; VertexDataArray[0] = new VertexData() { position = new Vector2(-1.0f, -1.0f), uv = new Vector2(uv_x0, uv_y1) }; VertexDataArray[1] = new VertexData() { position = new Vector2(-1.0f, +1.0f), uv = new Vector2(uv_x0, uv_y0) }; VertexDataArray[2] = new VertexData() { position = new Vector2(+1.0f, +1.0f), uv = new Vector2(uv_x1, uv_y0) }; VertexDataArray[3] = new VertexData() { position = new Vector2(+1.0f, -1.0f), uv = new Vector2(uv_x1, uv_y1) }; VertexBuffer.SetIndices(IndexDataArray, 0, 0, 4); VertexBuffer.SetVertices(VertexDataArray, 0, 0, 4); Director.Instance.GL.Context.SetVertexBuffer(0, VertexBuffer); Director.Instance.GL.Context.DrawArrays(DrawMode.TriangleFan, 0, 4); int count = Width * Height * 4; byte[] data = new byte[count]; System.Console.WriteLine("ReadPixels(): enter"); Director.Instance.GL.Context.ReadPixels(data, PixelFormat.Rgba, 0, 0, Width, Height); System.Console.WriteLine("ReadPixels(): exit"); int nonzero = 0; int nonclear = 0; for (int i = 0; i < count; ++i) { if (data[i] != 0) nonzero++; if (data[i] != 0xfe) nonclear++; System.Console.Write("{0} ", data[i]); if (i % Width == 0) System.Console.WriteLine(""); } System.Console.WriteLine(""); System.Console.WriteLine("nonzero: {0}, nonclear: {1}", nonzero, nonclear); Director.Instance.GL.Context.SetVertexBuffer(0, null); Director.Instance.GL.Context.SetShaderProgram(null); Director.Instance.GL.Context.SetFrameBuffer(old_frame_buffer); Director.Instance.GL.Context.SetScissor(old_scissor); Director.Instance.GL.Context.SetViewport(old_viewport); System.Console.WriteLine("SwapBuffers(): enter"); Director.Instance.GL.Context.SwapBuffers(); System.Console.WriteLine("SwapBuffers(): exit"); Thread.Sleep(250); }
/// <summary> /// Returns ready to display render information for a sidepart of this wall. /// Note: Z component is the height. /// </summary> /// <param name="PartType">Which part (upper, middle, lower)</param> /// <param name="IsLeftSide">Left or Right side</param> /// <param name="TexWidth">Texture width</param> /// <param name="TexHeight">Texture height</param> /// <param name="TexShrink">Texture shrink</param> /// <param name="Scale">Additional scale for vertices</param> /// <returns></returns> public VertexData GetVertexData(WallPartType PartType, bool IsLeftSide, int TexWidth, int TexHeight, int TexShrink, Real Scale = 1.0f) { VertexData RI = new VertexData(); bool drawTopDown = true; RooSideDefFlags flags; int xoffset = 0; int yoffset = 0; // fill vars based on left or right side if (!IsLeftSide) { RI.P0.X = P1.X; RI.P3.X = P2.X; RI.P1.X = P1.X; RI.P2.X = P2.X; RI.P0.Y = P1.Y; RI.P3.Y = P2.Y; RI.P1.Y = P1.Y; RI.P2.Y = P2.Y; flags = RightSide.Flags; xoffset = RightXOffset; yoffset = RightYOffset; switch (PartType) { case WallPartType.Upper: RI.P0.Z = z3; RI.P3.Z = zz3; RI.P1.Z = z2; RI.P2.Z = zz2; drawTopDown = !RightSide.Flags.IsAboveBottomUp; break; case WallPartType.Middle: RI.P0.Z = z2; RI.P3.Z = zz2; RI.P1.Z = z1; RI.P2.Z = zz1; drawTopDown = RightSide.Flags.IsNormalTopDown; break; case WallPartType.Lower: if (BowtieFlags.IsBelowPos || BowtieFlags.IsBelowNeg) { RI.P0.Z = z1Neg; RI.P3.Z = zz1Neg; } else { RI.P0.Z = z1; RI.P3.Z = zz1; } RI.P1.Z = z0; RI.P2.Z = zz0; drawTopDown = RightSide.Flags.IsBelowTopDown; break; } } else { RI.P0.X = P2.X; RI.P3.X = P1.X; RI.P1.X = P2.X; RI.P2.X = P1.X; RI.P0.Y = P2.Y; RI.P3.Y = P1.Y; RI.P1.Y = P2.Y; RI.P2.Y = P1.Y; flags = LeftSide.Flags; xoffset = LeftXOffset; yoffset = LeftYOffset; switch (PartType) { case WallPartType.Upper: RI.P0.Z = zz3; RI.P3.Z = z3; RI.P1.Z = zz2; RI.P2.Z = z2; drawTopDown = !LeftSide.Flags.IsAboveBottomUp; break; case WallPartType.Middle: RI.P0.Z = zz2; RI.P3.Z = z2; RI.P1.Z = zz1; RI.P2.Z = z1; drawTopDown = LeftSide.Flags.IsNormalTopDown; break; case WallPartType.Lower: RI.P0.Z = zz1; RI.P3.Z = z1; RI.P1.Z = zz0; RI.P2.Z = z0; drawTopDown = LeftSide.Flags.IsBelowTopDown; break; } } // scales Real invWidth = 1.0f / (Real)TexWidth; Real invHeight = 1.0f / (Real)TexHeight; Real invWidthFudge = 1.0f / (Real)(TexWidth << 4); Real invHeightFudge = 1.0f / (Real)(TexHeight << 4); // Start with UV calculation, see d3drender.c --- Real u1 = (Real)xoffset * (Real)TexShrink * invHeight; Real u2 = u1 + (ClientLength * (Real)TexShrink * invHeight); // set U RI.UV0.X = u1; RI.UV1.X = u1; RI.UV3.X = u2; RI.UV2.X = u2; // calculate V int bottom, top; if (!drawTopDown) { if (RI.P1.Z == RI.P2.Z) bottom = (int)RI.P1.Z; else { bottom = (int)MathUtil.Min(RI.P1.Z, RI.P2.Z); bottom = bottom & ~(GeometryConstants.FINENESS - 1); } if (RI.P0.Z == RI.P3.Z) top = (int)RI.P0.Z; else { top = (int)MathUtil.Max(RI.P0.Z, RI.P3.Z); top = (top + GeometryConstants.FINENESS - 1) & ~(GeometryConstants.FINENESS - 1); } if (RI.P1.Z == RI.P2.Z) { RI.UV1.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); RI.UV2.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); } else { RI.UV1.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); RI.UV2.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); RI.UV1.Y -= ((Real)RI.P1.Z - bottom) * (Real)TexShrink * invWidthFudge; RI.UV2.Y -= ((Real)RI.P2.Z - bottom) * (Real)TexShrink * invWidthFudge; } RI.UV0.Y = RI.UV1.Y - ((Real)(RI.P0.Z - RI.P1.Z) * (Real)TexShrink * invWidthFudge); RI.UV3.Y = RI.UV2.Y - ((Real)(RI.P3.Z - RI.P2.Z) * (Real)TexShrink * invWidthFudge); } // else, need to place tex origin at top left else { if (RI.P0.Z == RI.P3.Z) top = (int)RI.P0.Z; else { top = (int)MathUtil.Max(RI.P0.Z, RI.P3.Z); top = (top + GeometryConstants.FINENESS - 1) & ~(GeometryConstants.FINENESS - 1); } if (RI.P1.Z == RI.P2.Z) bottom = (int)RI.P1.Z; else { bottom = (int)MathUtil.Min(RI.P1.Z, RI.P2.Z); bottom = bottom & ~(GeometryConstants.FINENESS - 1); } if (RI.P0.Z == RI.P3.Z) { RI.UV0.Y = 0.0f; RI.UV3.Y = 0.0f; } else { RI.UV0.Y = ((Real)top - RI.P0.Z) * (Real)TexShrink * invWidthFudge; RI.UV3.Y = ((Real)top - RI.P3.Z) * (Real)TexShrink * invWidthFudge; } RI.UV0.Y -= ((Real)(yoffset * TexShrink) * invWidth); RI.UV3.Y -= ((Real)(yoffset * TexShrink) * invWidth); RI.UV1.Y = RI.UV0.Y + ((RI.P0.Z - RI.P1.Z) * (Real)TexShrink * invWidthFudge); RI.UV2.Y = RI.UV3.Y + ((RI.P3.Z - RI.P2.Z) * (Real)TexShrink * invWidthFudge); } // backwards if (flags.IsBackwards) { Real temp; temp = RI.UV3.X; RI.UV3.X = RI.UV0.X; RI.UV0.X = temp; temp = RI.UV2.X; RI.UV2.X = RI.UV1.X; RI.UV1.X = temp; } // no vtile // seems to apply only to middle parts, at least for bottom it creates strange holes if (flags.IsNoVTile && PartType == WallPartType.Middle) { if (RI.UV0.Y < 0.0f) { Real tex, wall, ratio, temp; tex = RI.UV1.Y - RI.UV0.Y; if (tex == 0) tex = 1.0f; temp = -RI.UV0.Y; ratio = temp / tex; wall = RI.P0.Z - RI.P1.Z; temp = wall * ratio; RI.P0.Z -= temp; RI.UV0.Y = 0.0f; } if (RI.UV3.Y < 0.0f) { Real tex, wall, ratio, temp; tex = RI.UV2.Y - RI.UV3.Y; if (tex == 0) tex = 1.0f; temp = -RI.UV3.Y; ratio = temp / tex; wall = RI.P3.Z - RI.P2.Z; temp = wall * ratio; RI.P3.Z -= temp; RI.UV3.Y = 0.0f; } RI.P1.Z -= 16.0f; RI.P2.Z -= 16.0f; } RI.UV0.Y += 1.0f / TexWidth; RI.UV3.Y += 1.0f / TexWidth; RI.UV1.Y -= 1.0f / TexWidth; RI.UV2.Y -= 1.0f / TexWidth; // scale by user scale RI.P0 *= Scale; RI.P3 *= Scale; RI.P1 *= Scale; RI.P2 *= Scale; // calculate the normal V3 P0P1 = (RI.P1 - RI.P0); V3 P0P2 = (RI.P2 - RI.P0); RI.Normal = P0P1.CrossProduct(P0P2); RI.Normal.Normalize(); RI.Normal = -RI.Normal; return RI; }
private Mesh GenerateDummyMesh(MeshBinding meshBinding) { var vertexData = new VertexData(); vertexData.VertexComponentNames = meshBinding.Mesh.PrimaryVertexData.VertexComponentNames .Select(name => new GrannyString(name.String)).ToList(); vertexData.Vertices = new List<Vertex>(); var dummyVertex = Helpers.CreateInstance(meshBinding.Mesh.VertexFormat) as Vertex; vertexData.Vertices.Add(dummyVertex); Root.VertexDatas.Add(vertexData); var topology = new TriTopology(); topology.Groups = new List<TriTopologyGroup>(); var group = new TriTopologyGroup(); group.MaterialIndex = 0; group.TriCount = 0; group.TriFirst = 0; topology.Groups.Add(group); topology.Indices = new List<int>(); Root.TriTopologies.Add(topology); var mesh = new Mesh(); mesh.Name = meshBinding.Mesh.Name; mesh.VertexFormat = meshBinding.Mesh.VertexFormat; mesh.PrimaryTopology = topology; mesh.PrimaryVertexData = vertexData; if (meshBinding.Mesh.BoneBindings != null) { mesh.BoneBindings = new List<BoneBinding>(); ConformMeshBoneBindings(mesh, meshBinding.Mesh); } return mesh; }
static void Triangulate( List<Vector3> listVertices, List<int> listIndices, FracturedObject fracturedComponent, List<List<Vector3>> listlistPointsConstrainedDelaunay, List<List<int>> listlistHashValuesConstrainedDelaunay, bool bConnectivityPostprocess, MeshFaceConnectivity faceConnectivityPos, MeshFaceConnectivity faceConnectivityNeg, MeshDataConnectivity meshConnectivityPos, MeshDataConnectivity meshConnectivityNeg, int nForceMeshConnectivityHash, int nSplitCloseSubMesh, Matrix4x4 mtxPlane, Matrix4x4 mtxToLocalPos, Matrix4x4 mtxToLocalNeg, Vector3 v3CenterPos, Vector3 v3CenterNeg, List<int>[] aListIndicesPosInOut, List<VertexData> listVertexDataPosInOut, List<int>[] aListIndicesNegInOut, List<VertexData> listVertexDataNegInOut) { int nPositiveSideIndexStart = listVertexDataPosInOut.Count; int nNegativeSideIndexStart = listVertexDataNegInOut.Count; if(listVertexDataPosInOut.Count < 1 || listVertexDataNegInOut.Count < 1) { return; } // Add vertex data VertexData[] aVtxDataCapPos = new VertexData[listVertices.Count]; VertexData[] aVtxDataCapNeg = new VertexData[listVertices.Count]; Vector3 v3PlaneNormal = mtxPlane.MultiplyVector(Vector3.up); float fReversedCapNormals = fracturedComponent.InvertCapNormals ? -1.0f : 1.0f; Vector3 v3CapNormalLocalPos = mtxToLocalPos.MultiplyVector(-v3PlaneNormal * fReversedCapNormals); Vector3 v3CapNormalLocalNeg = mtxToLocalNeg.MultiplyVector( v3PlaneNormal * fReversedCapNormals); Vector3 v3TangentPos = Vector3.right; v3TangentPos = mtxPlane.MultiplyVector(v3TangentPos); v3TangentPos = mtxToLocalPos.MultiplyVector(v3TangentPos); Vector3 v3TangentNeg = Vector3.right; v3TangentNeg = mtxPlane.MultiplyVector(v3TangentNeg); v3TangentNeg = mtxToLocalNeg.MultiplyVector(v3TangentNeg); Matrix4x4 mtxPlaneInverse = mtxPlane.inverse; Color32 colWhite = new Color32(255, 255, 255, 255); Vector3 v2Mapping = Vector2.zero; for(int i = 0; i < listVertices.Count; i++) { Vector3 v3Local = mtxPlaneInverse.MultiplyPoint3x4(listVertices[i]); v2Mapping.x = v3Local.x * fracturedComponent.SplitMappingTileU; v2Mapping.y = v3Local.z * fracturedComponent.SplitMappingTileV; int nVertexHash = ComputeVertexHash(listVertices[i], listlistPointsConstrainedDelaunay, listlistHashValuesConstrainedDelaunay); aVtxDataCapPos[i] = new VertexData(nVertexHash, listVertices[i], v3CapNormalLocalPos, v3TangentPos, colWhite, v2Mapping, v2Mapping, true, true, listVertexDataPosInOut[0].bHasColor32, listVertexDataPosInOut[0].bHasMapping1, listVertexDataPosInOut[0].bHasMapping2); aVtxDataCapNeg[i] = new VertexData(nVertexHash, listVertices[i], v3CapNormalLocalNeg, v3TangentNeg, colWhite, v2Mapping, v2Mapping, true, true, listVertexDataNegInOut[0].bHasColor32, listVertexDataNegInOut[0].bHasMapping1, listVertexDataNegInOut[0].bHasMapping2); } listVertexDataPosInOut.AddRange(aVtxDataCapPos); listVertexDataNegInOut.AddRange(aVtxDataCapNeg); // Add indices for(int i = 0; i < listIndices.Count / 3; i++) { int nTriangleA = listIndices[i * 3 + 0]; int nTriangleB = listIndices[i * 3 + 1]; int nTriangleC = listIndices[i * 3 + 2]; int nHashPosA = listVertexDataPosInOut[nPositiveSideIndexStart + nTriangleA].nVertexHash; int nHashPosB = listVertexDataPosInOut[nPositiveSideIndexStart + nTriangleB].nVertexHash; int nHashPosC = listVertexDataPosInOut[nPositiveSideIndexStart + nTriangleC].nVertexHash; int nHashNegA = listVertexDataNegInOut[nNegativeSideIndexStart + nTriangleA].nVertexHash; int nHashNegB = listVertexDataNegInOut[nNegativeSideIndexStart + nTriangleB].nVertexHash; int nHashNegC = listVertexDataNegInOut[nNegativeSideIndexStart + nTriangleC].nVertexHash; if(nHashPosA != -1 && nHashPosB != -1 && nHashPosC != -1 && nHashNegA != -1 && nHashNegB != -1 && nHashNegC != -1) { int nMeshConnectivityHash = nForceMeshConnectivityHash == -1 ? MeshDataConnectivity.GetNewHash() : nForceMeshConnectivityHash; // New hash value to identify the 2 shared faces if(fracturedComponent.GenerateChunkConnectionInfo) { meshConnectivityPos.NotifyNewCapFace(nMeshConnectivityHash, nSplitCloseSubMesh, aListIndicesPosInOut[nSplitCloseSubMesh].Count / 3); } aListIndicesPosInOut[nSplitCloseSubMesh].Add(nPositiveSideIndexStart + nTriangleA); aListIndicesPosInOut[nSplitCloseSubMesh].Add(nPositiveSideIndexStart + nTriangleB); aListIndicesPosInOut[nSplitCloseSubMesh].Add(nPositiveSideIndexStart + nTriangleC); if(bConnectivityPostprocess) { faceConnectivityPos.AddEdge(nSplitCloseSubMesh, listVertices[nTriangleA], listVertices[nTriangleB], nHashPosA, nHashPosB, nPositiveSideIndexStart + nTriangleA, nPositiveSideIndexStart + nTriangleB); faceConnectivityPos.AddEdge(nSplitCloseSubMesh, listVertices[nTriangleB], listVertices[nTriangleC], nHashPosB, nHashPosC, nPositiveSideIndexStart + nTriangleB, nPositiveSideIndexStart + nTriangleC); faceConnectivityPos.AddEdge(nSplitCloseSubMesh, listVertices[nTriangleC], listVertices[nTriangleA], nHashPosC, nHashPosA, nPositiveSideIndexStart + nTriangleC, nPositiveSideIndexStart + nTriangleA); } if(fracturedComponent.GenerateChunkConnectionInfo) { meshConnectivityNeg.NotifyNewCapFace(nMeshConnectivityHash, nSplitCloseSubMesh, aListIndicesNegInOut[nSplitCloseSubMesh].Count / 3); } aListIndicesNegInOut[nSplitCloseSubMesh].Add(nNegativeSideIndexStart + nTriangleA); aListIndicesNegInOut[nSplitCloseSubMesh].Add(nNegativeSideIndexStart + nTriangleC); aListIndicesNegInOut[nSplitCloseSubMesh].Add(nNegativeSideIndexStart + nTriangleB); if(bConnectivityPostprocess) { faceConnectivityNeg.AddEdge(nSplitCloseSubMesh, listVertices[nTriangleA], listVertices[nTriangleC], nHashNegA, nHashNegC, nNegativeSideIndexStart + nTriangleA, nNegativeSideIndexStart + nTriangleC); faceConnectivityNeg.AddEdge(nSplitCloseSubMesh, listVertices[nTriangleC], listVertices[nTriangleB], nHashNegC, nHashNegB, nNegativeSideIndexStart + nTriangleC, nNegativeSideIndexStart + nTriangleB); faceConnectivityNeg.AddEdge(nSplitCloseSubMesh, listVertices[nTriangleB], listVertices[nTriangleA], nHashNegB, nHashNegA, nNegativeSideIndexStart + nTriangleB, nNegativeSideIndexStart + nTriangleA); } } } }
public IEnumerable<VertexData> GetVertexIter() { // go to the start if (UseStartEndLimit) { //--------------------------------------------------------- VertexData vertexData = new VertexData(); vertexData.command = VertexCmd.MoveTo; vertexData.x = startX; vertexData.y = startY; yield return vertexData; //--------------------------------------------------------- double angle = startAngle; vertexData.command = VertexCmd.LineTo; //calculate nsteps int n = 0; while (n < calculateNSteps - 1) { angle += flatenDeltaAngle; vertexData.x = originX + Math.Cos(angle) * radiusX; vertexData.y = originY + Math.Sin(angle) * radiusY; yield return vertexData; n++; } //while ((angle < endAngle - flatenDeltaAngle / 4) == (((int)ArcDirection.CounterClockWise) == 1)) //{ // angle += flatenDeltaAngle; // vertexData.x = originX + Math.Cos(angle) * radiusX; // vertexData.y = originY + Math.Sin(angle) * radiusY; // yield return vertexData; //} //--------------------------------------------------------- vertexData.x = endX; vertexData.y = endY; yield return vertexData; vertexData.command = VertexCmd.Stop; yield return vertexData; } else { VertexData vertexData = new VertexData(); vertexData.command = VertexCmd.MoveTo; vertexData.x = originX + Math.Cos(startAngle) * radiusX; vertexData.y = originY + Math.Sin(startAngle) * radiusY; yield return vertexData; //--------------------------------------------------------- double angle = startAngle; vertexData.command = VertexCmd.LineTo; while ((angle < endAngle - flatenDeltaAngle / 4) == (((int)ArcDirection.CounterClockWise) == 1)) { angle += flatenDeltaAngle; vertexData.x = originX + Math.Cos(angle) * radiusX; vertexData.y = originY + Math.Sin(angle) * radiusY; yield return vertexData; } //--------------------------------------------------------- vertexData.x = originX + Math.Cos(endAngle) * radiusX; vertexData.y = originY + Math.Sin(endAngle) * radiusY; yield return vertexData; vertexData.command = VertexCmd.Stop; yield return vertexData; } }