private static int GetVertexComponentLength(VertexFlags flags) { switch (flags) { case VertexFlags.Position: case VertexFlags.BlendData: return(8); case VertexFlags.Normals: case VertexFlags.flag_0x80: case VertexFlags.TexCoords0: case VertexFlags.TexCoords1: case VertexFlags.TexCoords2: case VertexFlags.TexCoords7: case VertexFlags.flag_0x20000: case VertexFlags.DamageGroup: return(4); case VertexFlags.Tangent: return(0); case VertexFlags.flag_0x40000: return(12); default: return(-1); } }
private void Init(VertexFlags flags, int i) { string text = string.Format("{0} LOD: {1}", Language.GetString("$MODEL_OPTIONS_TEXT"), i.ToString()); ModelOptionsText.Text = text; options = new Dictionary <string, bool>(); options.Add("NORMALS", false); options.Add("TANGENTS", false); options.Add("DIFFUSE", false); options.Add("UV1", false); options.Add("UV2", false); options.Add("AO", false); options.Add("FLIP_UV", false); options.Add("COLOR0", false); options.Add("COLOR1", false); ImportNormalBox.Enabled = flags.HasFlag(VertexFlags.Normals); ImportTangentBox.Enabled = flags.HasFlag(VertexFlags.Tangent); ImportDiffuseBox.Enabled = flags.HasFlag(VertexFlags.TexCoords0); ImportUV1Box.Enabled = flags.HasFlag(VertexFlags.TexCoords1); ImportUV2Box.Enabled = flags.HasFlag(VertexFlags.TexCoords2); ImportAOBox.Enabled = flags.HasFlag(VertexFlags.ShadowTexture); ImportColor0Box.Enabled = flags.HasFlag(VertexFlags.Color); ImportColor1Box.Enabled = flags.HasFlag(VertexFlags.Color1); FlipUVBox.Enabled = false; }
private BlockFacing(string code, byte flag, int index, int oppositeIndex, int horizontalAngleIndex, Vec3i facingVector, Vec3f planeCenter, EnumAxis axis, Cuboidf plane) { this.index = index; this.meshDataIndex = (byte)(index + 1); this.horizontalAngleIndex = horizontalAngleIndex; this.flag = flag; this.code = code; this.oppositeIndex = oppositeIndex; this.normali = facingVector; this.normalf = new Vec3f(facingVector.X, facingVector.Y, facingVector.Z); this.normald = new Vec3d((double)facingVector.X, (double)facingVector.Y, (double)facingVector.Z); this.plane = plane; normalPacked = NormalUtil.PackNormal(normalf.X, normalf.Y, normalf.Z); normalb = (byte)( (axis == EnumAxis.Z ? 1 : 0) << 0 | (facingVector.Z < 0 ? 1 : 0) << 1 | (axis == EnumAxis.Y ? 1 : 0) << 2 | (facingVector.Y < 0 ? 1 : 0) << 3 | (axis == EnumAxis.X ? 1 : 0) << 4 | (facingVector.X < 0 ? 1 : 0) << 5 ); normalPackedFlags = VertexFlags.PackNormal(normalf); this.planeCenter = planeCenter; this.axis = axis; }
private static int GetVertexComponentLength(VertexFlags flags) { switch (flags) { case VertexFlags.Position: case VertexFlags.Skin: return(8); case VertexFlags.Normals: case VertexFlags.Color: case VertexFlags.TexCoords0: case VertexFlags.TexCoords1: case VertexFlags.TexCoords2: case VertexFlags.Unk05: case VertexFlags.ShadowTexture: case VertexFlags.Color1: case VertexFlags.DamageGroup: return(4); case VertexFlags.Tangent: return(0); case VertexFlags.BBCoeffs: return(12); default: return(-1); } }
public FrameResourceModelOptions(VertexFlags flags, int i, bool is32bit) { InitializeComponent(); Label_BufferType.Visible = is32bit; Init(flags, i); Localise(); }
public void DrawVectorImage(MeshGenerationContextUtils.RectangleParams rectParams) { VectorImage vectorImage = rectParams.vectorImage; Debug.Assert(vectorImage != null); VertexFlags vertexFlags = (vectorImage.atlas != null) ? VertexFlags.IsSVGGradients : VertexFlags.IsSolid; int settingIndexOffset = 0; bool flag = vectorImage.atlas != null && this.m_VectorImageManager != null; if (flag) { GradientRemap gradientRemap = this.m_VectorImageManager.AddUser(vectorImage); vertexFlags = (gradientRemap.isAtlassed ? VertexFlags.IsSVGGradients : VertexFlags.IsCustomSVGGradients); settingIndexOffset = gradientRemap.destIndex; } int count = this.m_Entries.Count; MeshGenerationContext.MeshFlags flags = MeshGenerationContext.MeshFlags.None; bool flag2 = vertexFlags == VertexFlags.IsSVGGradients; if (flag2) { flags = MeshGenerationContext.MeshFlags.IsSVGGradients; } else { bool flag3 = vertexFlags == VertexFlags.IsCustomSVGGradients; if (flag3) { flags = MeshGenerationContext.MeshFlags.IsCustomSVGGradients; } } MeshBuilder.AllocMeshData meshAlloc = new MeshBuilder.AllocMeshData { alloc = this.m_AllocThroughDrawMeshDelegate, texture = ((vertexFlags == VertexFlags.IsCustomSVGGradients) ? vectorImage.atlas : null), flags = flags }; int num; int num2; MeshBuilder.MakeVectorGraphics(rectParams, settingIndexOffset, meshAlloc, out num, out num2); Debug.Assert(count <= this.m_Entries.Count + 1); bool flag4 = count != this.m_Entries.Count; if (flag4) { this.m_SVGBackgroundEntryIndex = this.m_Entries.Count - 1; bool flag5 = num != 0 && num2 != 0; if (flag5) { UIRStylePainter.Entry entry = this.m_Entries[this.m_SVGBackgroundEntryIndex]; entry.vertices = entry.vertices.Slice(0, num); entry.indices = entry.indices.Slice(0, num2); this.m_Entries[this.m_SVGBackgroundEntryIndex] = entry; } } }
private void Init(VertexFlags flags) { ImportNormalBox.Enabled = flags.HasFlag(VertexFlags.Normals); ImportUV0Box.Enabled = flags.HasFlag(VertexFlags.TexCoords0); ImportUV1Box.Enabled = flags.HasFlag(VertexFlags.TexCoords1); ImportUV2Box.Enabled = flags.HasFlag(VertexFlags.TexCoords2); ImportUV7Box.Enabled = flags.HasFlag(VertexFlags.ShadowTexture); FlipUVBox.Enabled = false; }
public override void OnJsonTesselation(ref MeshData sourceMesh, ref int[] lightRgbsByCorner, BlockPos pos, Block[] chunkExtBlocks, int extIndex3d) { base.OnJsonTesselation(ref sourceMesh, ref lightRgbsByCorner, pos, chunkExtBlocks, extIndex3d); for (int i = 0; i < sourceMesh.FlagsCount; i++) { sourceMesh.Flags[i] &= VertexFlags.ClearNormalBitMask; sourceMesh.Flags[i] |= VertexFlags.PackNormal(0, 1, 0); } }
//Constructor public BSVertexDesc() { unchecked { vf1 = (byte)0; vf2 = (byte)0; vf3 = (byte)0; vf4 = (byte)0; vf5 = (byte)0; vertexAttributes = (VertexFlags)0; vf8 = (byte)0; } }
private static void TessellateFilledFan(TessellationType tessellationType, Vector2 center, float radius, Color color, float posZ, VertexFlags vertexFlags, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly) { VertexFlags innerVertexFlags, outerVertexFlags; if (tessellationType == TessellationType.EdgeCorner) { innerVertexFlags = VertexFlags.IsEdge; outerVertexFlags = VertexFlags.IsSolid; } else { innerVertexFlags = vertexFlags; outerVertexFlags = vertexFlags; } if (countOnly) { vertexCount += (UInt16)(kSubdivisions + 1); indexCount += (UInt16)((kSubdivisions - 1) * 3); return; } var p = new Vector2(center.x - radius, center.y); var verts = vertices.GetValueOrDefault(); var inds = indices.GetValueOrDefault(); verts[vertexCount++] = new Vertex() { position = new Vector3(center.x, center.y, posZ), uv = p, tint = color, flags = (float)innerVertexFlags }; verts[vertexCount++] = new Vertex() { position = new Vector3(p.x, p.y, posZ), uv = center, tint = color, flags = (float)outerVertexFlags }; for (int k = 1; k < kSubdivisions; ++k) { float angle = (Mathf.PI / 2.0f) * ((float)k) / (kSubdivisions - 1); p = center + new Vector2(-Mathf.Cos(angle), -Mathf.Sin(angle)) * radius; verts[vertexCount++] = new Vertex() { position = new Vector3(p.x, p.y, posZ), uv = center, tint = color, flags = (float)outerVertexFlags }; inds[indexCount++] = (UInt16)(indexOffset + 0); inds[indexCount++] = (UInt16)(indexOffset + k + 1); inds[indexCount++] = (UInt16)(indexOffset + k); } indexOffset += (UInt16)(kSubdivisions + 1); }
void GetVertexFormat(Mesh mesh, int boneCount, out VertexFlags flags, out int stride) { stride = 3; flags = 0; if (mesh.HasNormals) { stride += 3; flags |= VertexFlags.Normal; } if (mesh.HasTextureCoords(0)) { stride += 2; flags |= VertexFlags.TexCoord0; } if (mesh.HasTextureCoords(1)) { stride += 2; flags |= VertexFlags.TexCoord0; } if (mesh.HasTextureCoords(2)) { stride += 2; flags |= VertexFlags.TexCoord0; } if (mesh.HasTextureCoords(3)) { stride += 2; flags |= VertexFlags.TexCoord0; } if (mesh.HasVertexColors(0)) { stride += 4; flags |= VertexFlags.Color0; } if (mesh.HasVertexColors(1)) { stride += 4; flags |= VertexFlags.Color1; } if (mesh.HasVertexColors(2)) { stride += 4; flags |= VertexFlags.Color2; } if (mesh.HasVertexColors(3)) { stride += 4; flags |= VertexFlags.Color3; } stride += boneCount * 2; }
public void ReadPrerequisites(string name) { using (BinaryReader reader = new BinaryReader(File.Open(name, FileMode.Open))) { ushort MeshFlags = reader.ReadUInt16(); VertexDecleration = (VertexFlags)reader.ReadUInt32(); int IndexSize = reader.ReadInt32(); IndexBuffer = reader.ReadBytes(IndexSize); VertexCount = reader.ReadInt32(); int VertexSize = reader.ReadInt32(); VertexBuffer = reader.ReadBytes(VertexSize); } //VertexDecleration = (VertexFlags)134933; //Offset = new Vector3(-233.86592f, -642.7829f, -1.5614158f); //Scale = 0.013024263f; int vertexSize; Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = GetVertexOffsets(out vertexSize); int tempVertexSize = VertexBuffer.Length / VertexCount; Vertex[] Vertices = new Vertex[VertexCount]; for (int x = 0; x != VertexCount; x++) { //declare data required and send to decompresser byte[] data = new byte[tempVertexSize]; Array.Copy(VertexBuffer, (x * tempVertexSize), data, 0, tempVertexSize); Vertex decompressed = VertexTranslator.DecompressVertex(data, VertexDecleration, Vector3.Zero, 1.525879E-05f, vertexOffsets); Vertices[x] = decompressed; } Int3[] Triangles = new Int3[IndexBuffer.Length / 3]; int index = 0; for (int y = 0; y != IndexBuffer.Length; y += 6) { int X = BitConverter.ToUInt16(IndexBuffer, y + 0); int Y = BitConverter.ToUInt16(IndexBuffer, y + 2); int Z = BitConverter.ToUInt16(IndexBuffer, y + 4); Int3 triangle = new Int3(X, Y, Z); Triangles[index] = triangle; index++; } File.WriteAllLines(name + ".obj", BuildMesh(Vertices, Triangles)); }
static VertexFormat GetVertexFormat(VertexFlags flags, int boneSlotCount) { uint elemCount = 0, f = (uint)flags; for (elemCount = 0; f != 0; elemCount++) { f &= f - 1; } var elems = new VertexElement[(int)elemCount + 1 + (boneSlotCount * 2)]; int offset = 3, idx = 1; elems[0] = new VertexElement("Position", 0, 3); if ((flags & VertexFlags.Normal) != 0) { elems[idx++] = new VertexElement("Normal", offset, 3); offset += 3; } for (var i = 0; i < 4; i++) { if (((int)flags & ((int)VertexFlags.TexCoord0 << i)) != 0) { elems[idx++] = new VertexElement("TexCoord" + i, offset, 2); offset += 2; } } for (var i = 0; i < 4; i++) { if (((int)flags & ((int)VertexFlags.Color0 << i)) != 0) { elems[idx++] = new VertexElement("Color" + i, offset, 4); offset += 4; } } for (var i = 0; i < boneSlotCount; i++) { elems[idx++] = new VertexElement("BoneWeight" + i, offset++, 1); } for (var i = 0; i < boneSlotCount; i++) { elems[idx++] = new VertexElement("BoneIndex" + i, offset++, 1); } return(new VertexFormat(offset, elems)); }
public void ReadPrerequisites() { VertexDecleration = (VertexFlags)134933; Offset = new Vector3(-233.86592f, -642.7829f, -1.5614158f); Scale = 0.013024263f; int vertexSize; Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = GetVertexOffsets(out vertexSize); VertexBuffer = File.ReadAllBytes("M3/VertexBuffer.bin"); IndexBuffer = File.ReadAllBytes("M3/IndexBuffer.bin"); int tempVertexSize = VertexBuffer.Length / VertexCount; Vertex[] Vertices = new Vertex[VertexCount]; for (int x = 0; x != VertexCount; x++) { //declare data required and send to decompresser byte[] data = new byte[tempVertexSize]; Array.Copy(VertexBuffer, (x * tempVertexSize), data, 0, tempVertexSize); Vertex decompressed = VertexTranslator.DecompressVertex(data, VertexDecleration, Vector3.Zero, 1.525879E-05f, vertexOffsets); Vertices[x] = decompressed; } Int3[] Triangles = new Int3[IndexBuffer.Length / 3]; int index = 0; for (int y = 0; y != IndexBuffer.Length; y += 6) { Int3 triangle = new Int3(); triangle.X = BitConverter.ToUInt16(IndexBuffer, y + 0); triangle.Y = BitConverter.ToUInt16(IndexBuffer, y + 2); triangle.Z = BitConverter.ToUInt16(IndexBuffer, y + 4); Triangles[index] = triangle; index++; } File.WriteAllLines("Test.obj", BuildMesh(Vertices, Triangles)); }
public static VertexFlags GetFlags(MeshSection meshSec) { VertexFlags flags = new VertexFlags(); flags.TextureCoordinateFormat = (CoordinateFormat)GetBitFieldRange(meshSec.VertexFlags, 0, 2); flags.ColorFormat = (ColorFormat)GetBitFieldRange(meshSec.VertexFlags, 2, 3); flags.NormalFormat = (CoordinateFormat)GetBitFieldRange(meshSec.VertexFlags, 5, 2); flags.PositionFormat = (CoordinateFormat)GetBitFieldRange(meshSec.VertexFlags, 7, 2); flags.WeightFormat = (CoordinateFormat)GetBitFieldRange(meshSec.VertexFlags, 9, 2); flags.IndicesFormat = (byte)GetBitFieldRange(meshSec.VertexFlags, 11, 2); flags.Unused1 = (byte)GetBitFieldRange(meshSec.VertexFlags, 13, 1) == 1; flags.SkinningWeightsCount = (byte)GetBitFieldRange(meshSec.VertexFlags, 14, 3); flags.Unused2 = (byte)GetBitFieldRange(meshSec.VertexFlags, 17, 1) == 1; flags.MorphWeightsCount = (byte)GetBitFieldRange(meshSec.VertexFlags, 18, 3); flags.Unused3 = (byte)GetBitFieldRange(meshSec.VertexFlags, 21, 2); flags.SkipTransformPipeline = (byte)GetBitFieldRange(meshSec.VertexFlags, 23, 1) == 1; flags.UniformDiffuseFlag = (byte)GetBitFieldRange(meshSec.VertexFlags, 24, 1) == 1; flags.Unknown1 = (byte)GetBitFieldRange(meshSec.VertexFlags, 25, 3); flags.Primitive = (PrimitiveType)GetBitFieldRange(meshSec.VertexFlags, 28, 4); return(flags); }
public void ReadFromFile(MemoryStream reader, bool isBigEndian) { distance = reader.ReadSingle(isBigEndian); indexBufferRef = new HashName(reader, isBigEndian); vertexDeclaration = (VertexFlags)reader.ReadUInt32(isBigEndian); vertexBufferRef = new HashName(reader, isBigEndian); numVerts = reader.ReadInt32(isBigEndian); nZero1 = reader.ReadInt32(isBigEndian); nPartition = reader.ReadInt32(isBigEndian); if (nPartition != 0) { partitionInfo.ReadFromFile(reader, isBigEndian); } matSplitType = reader.ReadInt32(isBigEndian); if (matSplitType != 0) { splitInfo.ReadFromFile(reader, isBigEndian, matSplitType); } zeroTail = reader.ReadInt32(isBigEndian); }
public void ReadFromFile(BinaryReader reader) { distance = reader.ReadSingle(); indexBufferRef = new Hash(reader); vertexDeclaration = (VertexFlags)reader.ReadUInt32(); vertexBufferRef = new Hash(reader); numVerts = reader.ReadInt32(); nZero1 = reader.ReadInt32(); nPartition = reader.ReadInt32(); if (nPartition != 0) { partitionInfo.ReadFromFile(reader); } matSplitType = reader.ReadInt32(); if (matSplitType != 0) { splitInfo.ReadFromFile(reader, matSplitType); } zeroTail = reader.ReadInt32(); }
void GetVertexFormat (Mesh mesh, int boneCount, out VertexFlags flags, out int stride) { stride = 3; flags = 0; if (mesh.HasNormals) { stride += 3; flags |= VertexFlags.Normal; } if (mesh.HasTextureCoords(0)) { stride += 2; flags |= VertexFlags.TexCoord0; } if (mesh.HasTextureCoords(1)) { stride += 2; flags |= VertexFlags.TexCoord0; } if (mesh.HasTextureCoords(2)) { stride += 2; flags |= VertexFlags.TexCoord0; } if (mesh.HasTextureCoords(3)) { stride += 2; flags |= VertexFlags.TexCoord0; } if (mesh.HasVertexColors(0)) { stride += 4; flags |= VertexFlags.Color0; } if (mesh.HasVertexColors(1)) { stride += 4; flags |= VertexFlags.Color1; } if (mesh.HasVertexColors(2)) { stride += 4; flags |= VertexFlags.Color2; } if (mesh.HasVertexColors(3)) { stride += 4; flags |= VertexFlags.Color3; } stride += boneCount * 2; }
public static void ReadMeshData(Stream stream, Pmo pmo, int MeshNumber = 0) { // Go to mesh position. if (MeshNumber == 0) { stream.Seek(pmo.PMO_StartPosition + pmo.header.MeshOffset0, SeekOrigin.Begin); } else { stream.Seek(pmo.PMO_StartPosition + pmo.header.MeshOffset1, SeekOrigin.Begin); } UInt16 VertCnt = 0xFFFF; while (VertCnt > 0) { MeshChunks meshChunk = new MeshChunks(); meshChunk.MeshNumber = MeshNumber; meshChunk.SectionInfo = Mapping.ReadObject <MeshSection>(stream); // Exit if Vertex Count is zero. if (meshChunk.SectionInfo.VertexCount <= 0) { break; } meshChunk.TextureID = meshChunk.SectionInfo.TextureID; VertexFlags flags = GetFlags(meshChunk.SectionInfo); bool isColorFlagRisen = flags.UniformDiffuseFlag; if (pmo.header.SkeletonOffset != 0) { meshChunk.SectionInfo_opt1 = Mapping.ReadObject <MeshSectionOptional1>(stream); } if (isColorFlagRisen) { meshChunk.SectionInfo_opt2 = Mapping.ReadObject <MeshSectionOptional2>(stream); } if (meshChunk.SectionInfo.TriangleStripCount > 0) { meshChunk.TriangleStripValues = new UInt16[meshChunk.SectionInfo.TriangleStripCount]; for (int i = 0; i < meshChunk.SectionInfo.TriangleStripCount; i++) { meshChunk.TriangleStripValues[i] = stream.ReadUInt16(); } } // Get Formats. CoordinateFormat TexCoordFormat = flags.TextureCoordinateFormat; CoordinateFormat VertexPositionFormat = flags.PositionFormat; CoordinateFormat WeightFormat = flags.WeightFormat; ColorFormat ColorFormat = flags.ColorFormat; UInt32 SkinningWeightsCount = flags.SkinningWeightsCount; BinaryReader r = new BinaryReader(stream); long positionAfterHeader = stream.Position; if (meshChunk.SectionInfo.TriangleStripCount > 0) { int vertInd = 0; for (int p = 0; p < meshChunk.SectionInfo.TriangleStripCount; p++) { for (int s = 0; s < (meshChunk.TriangleStripValues[p] - 2); s++) { if (s % 2 == 0) { meshChunk.Indices.Add(vertInd + s + 0); meshChunk.Indices.Add(vertInd + s + 1); meshChunk.Indices.Add(vertInd + s + 2); } else { meshChunk.Indices.Add(vertInd + s + 0); meshChunk.Indices.Add(vertInd + s + 2); meshChunk.Indices.Add(vertInd + s + 1); } } vertInd += meshChunk.TriangleStripValues[p]; } } else { if (flags.Primitive == PrimitiveType.PRIMITIVE_TRIANGLE_STRIP) { for (int s = 0; s < (meshChunk.SectionInfo.VertexCount - 2); s++) { if (s % 2 == 0) { meshChunk.Indices.Add(s + 0); meshChunk.Indices.Add(s + 1); meshChunk.Indices.Add(s + 2); } else { meshChunk.Indices.Add(s + 1); meshChunk.Indices.Add(s + 0); meshChunk.Indices.Add(s + 2); } } } } for (int v = 0; v < meshChunk.SectionInfo.VertexCount; v++) { long vertexStartPos = stream.Position; int vertexIncreaseAmount = 0; // Vertex Weights. if (pmo.header.SkeletonOffset != 0 && WeightFormat != CoordinateFormat.NO_VERTEX) { WeightData WeightList = new WeightData(); WeightList.weights = new List <float>(); WeightList.coordFormart = WeightFormat; for (int i = 0; i < (SkinningWeightsCount + 1); i++) { switch (WeightFormat) { case CoordinateFormat.NORMALIZED_8_BITS: WeightList.weights.Add(stream.ReadByte() / 128.0f); break; case CoordinateFormat.NORMALIZED_16_BITS: WeightList.weights.Add(stream.ReadUInt16() / 32768.0f); break; case CoordinateFormat.FLOAT_32_BITS: WeightList.weights.Add(stream.ReadFloat()); break; case CoordinateFormat.NO_VERTEX: break; } } meshChunk.jointWeights.Add(WeightList); } Vector2 currentTexCoord = new Vector2(0, 0); switch (TexCoordFormat) { case CoordinateFormat.NORMALIZED_8_BITS: currentTexCoord.X = stream.ReadByte() / 128.0f; currentTexCoord.Y = stream.ReadByte() / 128.0f; meshChunk.textureCoordinates.Add(currentTexCoord); break; case CoordinateFormat.NORMALIZED_16_BITS: vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1); stream.Seek(vertexIncreaseAmount, SeekOrigin.Current); currentTexCoord.X = stream.ReadUInt16() / 32768.0f; currentTexCoord.Y = stream.ReadUInt16() / 32768.0f; meshChunk.textureCoordinates.Add(currentTexCoord); break; case CoordinateFormat.FLOAT_32_BITS: vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3); stream.Seek(vertexIncreaseAmount, SeekOrigin.Current); currentTexCoord.X = stream.ReadFloat(); currentTexCoord.Y = stream.ReadFloat(); meshChunk.textureCoordinates.Add(currentTexCoord); break; case CoordinateFormat.NO_VERTEX: meshChunk.textureCoordinates.Add(currentTexCoord); break; } Vector4 col; if (isColorFlagRisen) { uint c = meshChunk.SectionInfo_opt2.DiffuseColor; col.X = c % 0x100; col.Y = (c >> 8) % 0x100; col.Z = (c >> 16) % 0x100; col.W = (c >> 24) % 0x100; meshChunk.colors.Add(col); } else { switch (ColorFormat) { case Pmo.ColorFormat.NO_COLOR: meshChunk.colors.Add(new Vector4(0xFF, 0xFF, 0xFF, 0xFF)); break; case Pmo.ColorFormat.BGR_5650_16BITS: stream.ReadUInt16(); break; case Pmo.ColorFormat.ABGR_5551_16BITS: stream.ReadUInt16(); break; case Pmo.ColorFormat.ABGR_4444_16BITS: stream.ReadUInt16(); break; case Pmo.ColorFormat.ABGR_8888_32BITS: vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3); stream.Seek(vertexIncreaseAmount, SeekOrigin.Current); col.X = stream.ReadByte(); col.Y = stream.ReadByte(); col.Z = stream.ReadByte(); col.W = stream.ReadByte(); meshChunk.colors.Add(col); break; } } Vector3 currentVertex; // Handle triangles and triangle strips. switch (VertexPositionFormat) { case CoordinateFormat.NORMALIZED_8_BITS: currentVertex.X = r.ReadSByte() / 128.0f; currentVertex.Y = r.ReadSByte() / 128.0f; currentVertex.Z = r.ReadSByte() / 128.0f; meshChunk.vertices.Add(currentVertex); break; case CoordinateFormat.NORMALIZED_16_BITS: vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1); stream.Seek(vertexIncreaseAmount, SeekOrigin.Current); currentVertex.X = (float)stream.ReadInt16() / 32768.0f; currentVertex.Y = (float)stream.ReadInt16() / 32768.0f; currentVertex.Z = (float)stream.ReadInt16() / 32768.0f; meshChunk.vertices.Add(currentVertex); break; case CoordinateFormat.FLOAT_32_BITS: vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3); stream.Seek(vertexIncreaseAmount, SeekOrigin.Current); currentVertex.X = stream.ReadFloat(); currentVertex.Y = stream.ReadFloat(); currentVertex.Z = stream.ReadFloat(); meshChunk.vertices.Add(currentVertex); break; } stream.Seek(vertexStartPos + meshChunk.SectionInfo.VertexSize, SeekOrigin.Begin); if (flags.Primitive == PrimitiveType.PRIMITIVE_TRIANGLE) { meshChunk.Indices.Add(v); } } VertCnt = meshChunk.SectionInfo.VertexCount; pmo.Meshes.Add(meshChunk); // Find position of next data chunk. stream.Seek(positionAfterHeader + (meshChunk.SectionInfo.VertexCount * meshChunk.SectionInfo.VertexSize), SeekOrigin.Begin); stream.Seek(stream.Position % 4, SeekOrigin.Current); } }
public Lod() { vertexDeclaration = 0; }
private MeshData MakeWireMesh(Vec3f pos1, Vec3f pos2, long netId) { float t = 0.015f;//thickness Vec3f dPos = pos2 - pos1; float dist = pos2.Distance(pos1); int nSec = (int)Math.Floor(dist * 2);//number of section nSec = nSec > 5 ? nSec : 5; MeshData mesh = new MeshData(4, 6); mesh.SetMode(EnumDrawMode.Triangles); MeshData mesh_top = new MeshData(4, 6); mesh_top.SetMode(EnumDrawMode.Triangles); MeshData mesh_bot = new MeshData(4, 6); mesh_bot.SetMode(EnumDrawMode.Triangles); MeshData mesh_side = new MeshData(4, 6); mesh_side.SetMode(EnumDrawMode.Triangles); MeshData mesh_side2 = new MeshData(4, 6); mesh_side2.SetMode(EnumDrawMode.Triangles); //out of plane translation vector: Vec3f b = new Vec3f(-dPos.Z, 0, dPos.X).Normalize(); if (dPos.Z == 0 && dPos.X == 0) { b = new Vec3f(1, 0, 0); } int color = debugColors[netId % debugColors.Length]; Vec3f pos; mesh_top.Flags.Fill(0); mesh_bot.Flags.Fill(0); mesh_side.Flags.Fill(0); mesh_side2.Flags.Fill(0); //Add vertices for (int j = 0; j <= nSec; j++) { float x = dPos.X / nSec * j; float y = dPos.Y / nSec * j; float z = dPos.Z / nSec * j; float l = (float)Math.Sqrt(x * x + y * y + z * z); float dy = Catenary(l / dist, 1, 0.5f); pos = new Vec3f(x, y + dy, z); float du = dist / 2 / t / nSec; mesh_top.AddVertex(pos1.X + pos.X - b.X * t, pos1.Y + pos.Y + t, pos1.Z + pos.Z - b.Z * t, j * du, 0, color); mesh_top.AddVertex(pos1.X + pos.X + b.X * t, pos1.Y + pos.Y + t, pos1.Z + pos.Z + b.Z * t, j * du, 1, color); mesh_bot.AddVertex(pos1.X + pos.X - b.X * t, pos1.Y + pos.Y - t, pos1.Z + pos.Z - b.Z * t, j * du, 0, color); mesh_bot.AddVertex(pos1.X + pos.X + b.X * t, pos1.Y + pos.Y - t, pos1.Z + pos.Z + b.Z * t, j * du, 1, color); mesh_side.AddVertex(pos1.X + pos.X - b.X * t, pos1.Y + pos.Y + t, pos1.Z + pos.Z - b.Z * t, j * du, 1, color); mesh_side.AddVertex(pos1.X + pos.X - b.X * t, pos1.Y + pos.Y - t, pos1.Z + pos.Z - b.Z * t, j * du, 0, color); mesh_side2.AddVertex(pos1.X + pos.X + b.X * t, pos1.Y + pos.Y + t, pos1.Z + pos.Z + b.Z * t, j * du, 1, color); mesh_side2.AddVertex(pos1.X + pos.X + b.X * t, pos1.Y + pos.Y - t, pos1.Z + pos.Z + b.Z * t, j * du, 0, color); mesh_top.Flags[2 * j] = VertexFlags.NormalToPackedInt(new Vec3f(0, 1, 0)) << 15; mesh_top.Flags[2 * j + 1] = VertexFlags.NormalToPackedInt(new Vec3f(0, 1, 0)) << 15; mesh_bot.Flags[2 * j] = VertexFlags.NormalToPackedInt(new Vec3f(0, -1, 0)) << 15; mesh_bot.Flags[2 * j + 1] = VertexFlags.NormalToPackedInt(new Vec3f(0, -1, 0)) << 15; mesh_side.Flags[2 * j] = VertexFlags.NormalToPackedInt(-b.X, -b.Y, -b.Z) << 15; mesh_side.Flags[2 * j + 1] = VertexFlags.NormalToPackedInt(-b.X, -b.Y, -b.Z) << 15; mesh_side2.Flags[2 * j] = VertexFlags.NormalToPackedInt(b) << 15; mesh_side2.Flags[2 * j + 1] = VertexFlags.NormalToPackedInt(b) << 15; int flag = VertexFlags.LeavesWindWaveBitMask; if (j != 0 && j < nSec) { //mesh_top.Flags[2 * j] = flag; //mesh_top.Flags[2 * j+1] = flag; //mesh_bot.Flags[2 * j] = flag; //mesh_bot.Flags[2 * j + 1] = flag; //mesh_side.Flags[2 * j] = flag; //mesh_side.Flags[2 * j + 1] = flag; //mesh_side2.Flags[2 * j] = flag; //mesh_side2.Flags[2 * j + 1] = flag; } } //add indices for (int j = 0; j < nSec; j++) { //upper stripe int offset = 2 * j; mesh_top.AddIndex(offset); mesh_top.AddIndex(offset + 3); mesh_top.AddIndex(offset + 2); mesh_top.AddIndex(offset); mesh_top.AddIndex(offset + 1); mesh_top.AddIndex(offset + 3); //lower stripe mesh_bot.AddIndex(offset); mesh_bot.AddIndex(offset + 3); mesh_bot.AddIndex(offset + 1); mesh_bot.AddIndex(offset); mesh_bot.AddIndex(offset + 2); mesh_bot.AddIndex(offset + 3); //sides mesh_side.AddIndex(offset); mesh_side.AddIndex(offset + 3); mesh_side.AddIndex(offset + 1); mesh_side.AddIndex(offset); mesh_side.AddIndex(offset + 2); mesh_side.AddIndex(offset + 3); mesh_side2.AddIndex(offset); mesh_side2.AddIndex(offset + 3); mesh_side2.AddIndex(offset + 2); mesh_side2.AddIndex(offset); mesh_side2.AddIndex(offset + 1); mesh_side2.AddIndex(offset + 3); } mesh.AddMeshData(mesh_top); mesh.AddMeshData(mesh_bot); mesh.AddMeshData(mesh_side); mesh.AddMeshData(mesh_side2); mesh.Rgba.Fill((byte)255); return(mesh); }
public static void WriteMeshData(Stream stream, Pmo pmo) { bool hasSwappedToSecondModel = false; // Write Mesh Data. for (int j = 0; j < pmo.Meshes.Count; j++) { if (!hasSwappedToSecondModel && pmo.Meshes[j].MeshNumber == 1 && pmo.header.MeshOffset0 != 0) { hasSwappedToSecondModel = true; for (uint b = 0; b < 0xC; b++) { stream.Write((byte)0x00); } for (uint b = 0; stream.Position % 0x10 != 0; b++) { stream.Write((byte)0x00); } } MeshChunks chunk = pmo.Meshes[j]; Mapping.WriteObject <Pmo.MeshSection>(stream, chunk.SectionInfo); if (chunk.SectionInfo_opt1 != null) { Mapping.WriteObject <Pmo.MeshSectionOptional1>(stream, chunk.SectionInfo_opt1); } if (chunk.SectionInfo_opt2 != null) { Mapping.WriteObject <Pmo.MeshSectionOptional2>(stream, chunk.SectionInfo_opt2); } if (chunk.TriangleStripValues.Length > 0) { for (int z = 0; z < chunk.TriangleStripValues.Length; z++) { stream.Write((ushort)chunk.TriangleStripValues[z]); } } for (int k = 0; k < pmo.Meshes[j].SectionInfo.VertexCount; k++) { long vertexStartPos = stream.Position; int vertexIncreaseAmount = 0; VertexFlags flags = Pmo.GetFlags(chunk.SectionInfo); // Write Joints. if (flags.WeightFormat != CoordinateFormat.NO_VERTEX) { for (int w = 0; w < flags.SkinningWeightsCount + 1; w++) { int currentIndex = w + (k * (flags.SkinningWeightsCount + 1)); switch (flags.WeightFormat) { case CoordinateFormat.NORMALIZED_8_BITS: stream.Write((byte)(chunk.jointWeights[k].weights[currentIndex] * 127.0f)); break; case CoordinateFormat.NORMALIZED_16_BITS: stream.Write((byte)(chunk.jointWeights[k].weights[currentIndex] * 32767.0f)); break; case CoordinateFormat.FLOAT_32_BITS: StreamExtensions.Write(stream, chunk.jointWeights[k].weights[currentIndex]); break; } } } // Write Texture Coords. switch (flags.TextureCoordinateFormat) { case CoordinateFormat.NORMALIZED_8_BITS: stream.Write((byte)(chunk.textureCoordinates[k].X * 128.0f)); stream.Write((byte)(chunk.textureCoordinates[k].Y * 128.0f)); break; case CoordinateFormat.NORMALIZED_16_BITS: vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1); for (int a = 0; a < vertexIncreaseAmount; a++) { stream.Write((byte)0xAB); } stream.Write((ushort)(chunk.textureCoordinates[k].X * 32768.0f)); stream.Write((ushort)(chunk.textureCoordinates[k].Y * 32768.0f)); break; case CoordinateFormat.FLOAT_32_BITS: vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3); for (int a = 0; a < vertexIncreaseAmount; a++) { stream.Write((byte)0xAB); } StreamExtensions.Write(stream, chunk.textureCoordinates[k].X); StreamExtensions.Write(stream, chunk.textureCoordinates[k].Y); break; } // Write colors. switch (flags.ColorFormat) { case Pmo.ColorFormat.NO_COLOR: break; case Pmo.ColorFormat.BGR_5650_16BITS: break; case Pmo.ColorFormat.ABGR_5551_16BITS: break; case Pmo.ColorFormat.ABGR_4444_16BITS: break; case Pmo.ColorFormat.ABGR_8888_32BITS: vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3); for (int a = 0; a < vertexIncreaseAmount; a++) { stream.Write((byte)0xAB); } stream.Write((byte)(chunk.colors[k].X)); stream.Write((byte)(chunk.colors[k].Y)); stream.Write((byte)(chunk.colors[k].Z)); stream.Write((byte)(chunk.colors[k].W)); break; } // Write vertices. switch (flags.PositionFormat) { case CoordinateFormat.NORMALIZED_8_BITS: StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].X * 128.0f)); StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].Y * 128.0f)); StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].Z * 128.0f)); break; case CoordinateFormat.NORMALIZED_16_BITS: vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1); for (int a = 0; a < vertexIncreaseAmount; a++) { stream.Write((byte)0xAB); } StreamExtensions.Write(stream, (short)(chunk.vertices[k].X * 32768.0f)); StreamExtensions.Write(stream, (short)(chunk.vertices[k].Y * 32768.0f)); StreamExtensions.Write(stream, (short)(chunk.vertices[k].Z * 32768.0f)); break; case CoordinateFormat.FLOAT_32_BITS: vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3); for (int a = 0; a < vertexIncreaseAmount; a++) { stream.Write((byte)0xAB); } StreamExtensions.Write(stream, chunk.vertices[k].X); StreamExtensions.Write(stream, chunk.vertices[k].Y); StreamExtensions.Write(stream, chunk.vertices[k].Z); break; } int padding = ((int)vertexStartPos + chunk.SectionInfo.VertexSize) - (int)stream.Position; for (int p = 0; p < padding; p++) { stream.Write((byte)0xAB); } } // Remainder. uint remainder = (uint)stream.Position % 4; for (int p = 0; p < remainder; p++) { stream.Write((byte)0x00); } if (j == (pmo.Meshes.Count - 1)) { for (uint b = 0; b < 0xC; b++) { try { stream.Write((byte)0x00); } catch (Exception ex) { ex.ToString(); } } int pd = (int)stream.Position % 0x10; for (int n = 0; pd != 0; n++) { try { stream.Write((byte)0x00); } catch (Exception ex) { ex.ToString(); } pd = (int)stream.Position % 0x10; } } } }
private static void TessellateBorderedRectInternal(Rect rect, Color color, float posZ, VertexFlags vertexFlags, BorderParameters border, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly = false) { if (IsSimpleRectangle(border)) { UInt16 indexOffset = 0; TessellateQuad(rect, TessellationType.Content, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } else { TessellateRoundBorders(rect, color, posZ, vertexFlags, border, vertices, indices, ref vertexCount, ref indexCount, countOnly); } }
private static void TessellateRoundBorders(Rect rect, Color color, float posZ, VertexFlags vertexFlags, BorderParameters border, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly) { // To tessellate the 4 corners, the rect is divided in 4 quadrants and every quadrant is computed as if they were the top-left corner. // The quadrants are then mirrored and the triangles winding flipped as necessary. UInt16 indexOffset = 0; UInt16 startVc = 0, startIc = 0; bool hasBorder = HasBorder(border); var halfSize = new Vector2(rect.width / 2.0f, rect.height / 2.0f); var quarterRect = new Rect(rect.x, rect.y, halfSize.x, halfSize.y); // Top-left TessellateRoundedCorner(quarterRect, color, posZ, vertexFlags, border.topLeftRadius, border.leftWidth, border.topWidth, hasBorder, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); // Top-right startVc = vertexCount; startIc = indexCount; TessellateRoundedCorner(quarterRect, color, posZ, vertexFlags, border.topRightRadius, border.rightWidth, border.topWidth, hasBorder, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); MirrorVertices(quarterRect, vertices, startVc, vertexCount - startVc, true); FlipWinding(indices, startIc, indexCount - startIc); // Bottom-right startVc = vertexCount; startIc = indexCount; TessellateRoundedCorner(quarterRect, color, posZ, vertexFlags, border.bottomRightRadius, border.rightWidth, border.bottomWidth, hasBorder, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); MirrorVertices(quarterRect, vertices, startVc, vertexCount - startVc, true); MirrorVertices(quarterRect, vertices, startVc, vertexCount - startVc, false); // Bottom-left startVc = vertexCount; startIc = indexCount; TessellateRoundedCorner(quarterRect, color, posZ, vertexFlags, border.bottomLeftRadius, border.leftWidth, border.bottomWidth, hasBorder, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); MirrorVertices(quarterRect, vertices, startVc, vertexCount - startVc, false); FlipWinding(indices, startIc, indexCount - startIc); }
private static void TessellateBorderedFan(TessellationType tessellationType, Vector2 center, float radius, float leftWidth, float topWidth, Color color, float posZ, VertexFlags vertexFlags, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly) { VertexFlags innerVertexFlags, outerVertexFlags; if (tessellationType == TessellationType.EdgeCorner) { innerVertexFlags = VertexFlags.IsEdge; outerVertexFlags = VertexFlags.IsSolid; } else { innerVertexFlags = vertexFlags; outerVertexFlags = vertexFlags; } if (countOnly) { vertexCount += (UInt16)(kSubdivisions * 2); indexCount += (UInt16)((kSubdivisions - 1) * 6); return; } var a = radius - leftWidth; var b = radius - topWidth; var p = new Vector2(center.x - radius, center.y); var q = new Vector2(center.x - a, center.y); var verts = vertices.GetValueOrDefault(); var inds = indices.GetValueOrDefault(); verts[vertexCount++] = new Vertex { position = new Vector3(q.x, q.y, posZ), uv = q - p, tint = color, flags = (float)innerVertexFlags }; verts[vertexCount++] = new Vertex { position = new Vector3(p.x, p.y, posZ), uv = p - q, tint = color, flags = (float)outerVertexFlags }; for (int k = 1; k < kSubdivisions; ++k) { float percent = ((float)k) / (kSubdivisions - 1); float angle = (Mathf.PI / 2.0f) * percent; p = center + new Vector2(-Mathf.Cos(angle), -Mathf.Sin(angle)) * radius; q = center + new Vector2(-a * Mathf.Cos(angle), -b * Mathf.Sin(angle)); verts[vertexCount++] = new Vertex { position = new Vector3(q.x, q.y, posZ), uv = q - p, tint = color, flags = (float)innerVertexFlags }; verts[vertexCount++] = new Vertex { position = new Vector3(p.x, p.y, posZ), uv = p - q, tint = color, flags = (float)outerVertexFlags }; int i = k * 2; inds[indexCount++] = (UInt16)(indexOffset + (i - 2)); inds[indexCount++] = (UInt16)(indexOffset + (i)); inds[indexCount++] = (UInt16)(indexOffset + (i - 1)); inds[indexCount++] = (UInt16)(indexOffset + (i - 1)); inds[indexCount++] = (UInt16)(indexOffset + (i)); inds[indexCount++] = (UInt16)(indexOffset + (i + 1)); } indexOffset += (UInt16)(kSubdivisions * 2); }
public FrameResourceModelOptions(VertexFlags flags) { InitializeComponent(); Init(flags); Localise(); }
private static void TessellateQuad(Rect rect, TessellationType tessellationType, Color color, float posZ, VertexFlags vertexFlags, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly) { if (rect.width < kEpsilon || rect.height < kEpsilon) { return; } if (countOnly) { vertexCount += 4; indexCount += 6; return; } float x0 = rect.x; float x3 = rect.xMax; float y0 = rect.y; float y3 = rect.yMax; Vector2 uv0, uv1, uv2, uv3; float flags0, flags1, flags2, flags3; switch (tessellationType) { case TessellationType.EdgeHorizontal: // The uvs contain the displacement from the vertically opposed corner. uv0 = new Vector2(0, y0 - y3); uv1 = new Vector2(0, y0 - y3); uv2 = new Vector2(0, y3 - y0); uv3 = new Vector2(0, y3 - y0); flags0 = flags1 = (float)VertexFlags.IsSolid; flags2 = flags3 = (float)VertexFlags.IsEdge; break; case TessellationType.EdgeVertical: // The uvs contain the displacement from the horizontally opposed corner. uv0 = new Vector2(x0 - x3, 0); uv1 = new Vector2(x3 - x0, 0); uv2 = new Vector2(x0 - x3, 0); uv3 = new Vector2(x3 - x0, 0); flags0 = flags2 = (float)VertexFlags.IsSolid; flags1 = flags3 = (float)VertexFlags.IsEdge; break; case TessellationType.EdgeCorner: uv0 = uv1 = uv2 = uv3 = Vector2.zero; flags0 = flags1 = flags2 = flags3 = (float)VertexFlags.IsSolid; break; case TessellationType.Content: uv0 = uv1 = uv2 = uv3 = Vector2.zero; // UVs are computed later for content flags0 = flags1 = flags2 = flags3 = (float)vertexFlags; break; default: throw new NotImplementedException(); } var verts = vertices.GetValueOrDefault(); verts[vertexCount++] = new Vertex { position = new Vector3(x0, y0, posZ), uv = uv0, tint = color, flags = flags0 }; verts[vertexCount++] = new Vertex { position = new Vector3(x3, y0, posZ), uv = uv1, tint = color, flags = flags1 }; verts[vertexCount++] = new Vertex { position = new Vector3(x0, y3, posZ), uv = uv2, tint = color, flags = flags2 }; verts[vertexCount++] = new Vertex { position = new Vector3(x3, y3, posZ), uv = uv3, tint = color, flags = flags3 }; var inds = indices.GetValueOrDefault(); inds[indexCount++] = (UInt16)(indexOffset + 0); inds[indexCount++] = (UInt16)(indexOffset + 2); inds[indexCount++] = (UInt16)(indexOffset + 1); inds[indexCount++] = (UInt16)(indexOffset + 3); inds[indexCount++] = (UInt16)(indexOffset + 1); inds[indexCount++] = (UInt16)(indexOffset + 2); indexOffset += 4; }
///<summary> /// Tessellates the border OR the content: /// If any of the left/right/top/bottom border parameters is greater than Epsilon, we tessellate ONLY a border. /// Otherwise we tessellate ONLY the content. /// </summary> /// <param name="vertexFlags">Flags are only used for content, not for a border.</param> public static void TessellateBorderedRect(Rect rect, Rect texCoords, Color color, BorderParameters border, float posZ, VertexFlags vertexFlags, UIRMeshBuilder.AllocMeshData meshAlloc) { if (rect.width < kEpsilon || rect.height < kEpsilon) { return; } Profiler.BeginSample("TessellateBorderedRect"); border = AdjustBorderParameters(rect, border); UInt16 vertexCount = 0, indexCount = 0; CountBorderedRectTriangles(rect, border, ref vertexCount, ref indexCount); var mesh = meshAlloc(vertexCount, indexCount); vertexCount = 0; indexCount = 0; TessellateBorderedRectInternal(rect, color, posZ, vertexFlags, border, mesh.vertices, mesh.indices, ref vertexCount, ref indexCount); if (!HasBorder(border) && ((vertexFlags == VertexFlags.IsTextured) || (vertexFlags == VertexFlags.IsCustom))) { ComputeUVs(rect, texCoords, mesh.vertices); } Profiler.EndSample(); }
public Lod() { vertexDeclaration = 0; numUVChannels = 4; }
private MeshData[] GenContentMeshes(ITesselatorAPI tesselator) { ItemStack content = GetContents(); if (content == null) { return(null); } Dictionary <string, MeshData[]> meshes = ObjectCacheUtil.GetOrCreate(Api, "plantContainerContentMeshes", () => { return(new Dictionary <string, MeshData[]>()); }); MeshData[] meshwithVariants; string containersize = this.ContainerSize; string key = GetContents()?.ToString() + "-" + containersize; if (meshes.TryGetValue(key, out meshwithVariants)) { return(meshwithVariants); } curContProps = PlantContProps; if (curContProps == null) { return(null); } CompositeShape compoShape = curContProps.Shape; if (compoShape == null) { compoShape = content.Class == EnumItemClass.Block ? content.Block.Shape : content.Item.Shape; } ModelTransform transform = curContProps.Transform; if (transform == null) { transform = new ModelTransform().EnsureDefaultValues(); transform.Translation.Y = Block.Attributes["fillHeight"].AsFloat(0.4f); } contentTexSource = content.Class == EnumItemClass.Block ? capi.Tesselator.GetTexSource(content.Block) : capi.Tesselator.GetTextureSource(content.Item); List <IAsset> assets; if (compoShape.Base.Path.EndsWith("*")) { assets = Api.Assets.GetMany(compoShape.Base.WithPathPrefixOnce("shapes/").Path.Substring(0, compoShape.Base.Path.Length - 1), compoShape.Base.Domain); } else { assets = new List <IAsset>(); assets.Add(Api.Assets.TryGet(compoShape.Base.WithPathPrefixOnce("shapes/").WithPathAppendixOnce(".json"))); } if (assets != null && assets.Count > 0) { meshwithVariants = new MeshData[assets.Count]; for (int i = 0; i < assets.Count; i++) { IAsset asset = assets[i]; Shape shape = asset.ToObject <Shape>(); shapeTextures = shape.Textures; MeshData mesh; tesselator.TesselateShape("plant container content shape", shape, out mesh, this); for (int j = 0; j < mesh.RenderPassCount; j++) { mesh.RenderPasses[j] = (int)EnumChunkRenderPass.OpaqueNoCull; } Block block = GetContents()?.Block; VertexFlags flags = block?.VertexFlags; if (flags != null && flags.GrassWindWave) { int grassWave = VertexFlags.FoliageWindWaveBitMask | VertexFlags.WeakWaveBitMask; for (int vertexNum = 0; vertexNum < mesh.GetVerticesCount(); vertexNum++) { float y = mesh.xyz[vertexNum * 3 + 1]; if (y > block.WaveFlagMinY) { mesh.Flags[vertexNum] |= grassWave; } } } mesh.ModelTransform(transform); meshwithVariants[i] = mesh; } } else { Api.World.Logger.Error("Plant container, content asset {0} not found,", compoShape.Base.WithPathPrefixOnce("shapes/").WithPathAppendixOnce(".json")); } return(meshes[key] = meshwithVariants); }
private static void TessellateRoundedCorner(Rect rect, Color color, float posZ, VertexFlags vertexFlags, float radius, float leftWidth, float topWidth, bool hasBorder, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly) { var cornerCenter = rect.position + new Vector2(radius, radius); var subRect = Rect.zero; if (radius < kEpsilon) { if (!hasBorder) { // Without radius and no borders, we use a single quad to fill the section // ------- // | | // | | // ------- TessellateQuad(rect, TessellationType.Content, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } else { // Without radius with borders, we use two quads for the outlines // ------------ // | | B | // | A |------- // | | // | | // ----- if (leftWidth > kEpsilon) { // A subRect = new Rect(rect.x, rect.y, leftWidth, rect.height); TessellateQuad(subRect, TessellationType.EdgeVertical, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } if (topWidth > kEpsilon) { // B subRect = new Rect(rect.x + leftWidth, rect.y, rect.width - leftWidth, topWidth); TessellateQuad(subRect, TessellationType.EdgeHorizontal, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } } return; } if (!hasBorder) { // Without borders, we can just fill the corner with radius, plus up to 2 quads to fill the remainder of the section // _------- // *\ | | // *__\| A | // | | | // | B | | // | | | // ---------- TessellateFilledFan(TessellationType.Content, cornerCenter, radius, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); if (radius < rect.width) { // A subRect = new Rect(rect.x + radius, rect.y, rect.width - radius, rect.height); TessellateQuad(subRect, TessellationType.Content, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } if (radius < rect.height) { // B subRect = new Rect(rect.x, rect.y + radius, radius < rect.width ? radius : rect.width, rect.height - radius); TessellateQuad(subRect, TessellationType.Content, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } } else { // With borders, we have to create a fan-shaped outline, plus up to 2 quads for the straight outlines // If the radius is smaller than the border width, we create a filled fan plus the required quads instead. if (radius < leftWidth || radius < topWidth) { // A TessellateFilledFan(TessellationType.EdgeCorner, cornerCenter, radius, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); if (radius < leftWidth && radius < topWidth) { // _______________ // -* | | | // * A\ | C| | // *____\|__| F | // | B | | // |________|__________| // | | // | E | // | | // |________| // B subRect = new Rect(rect.x, rect.y + radius, leftWidth, topWidth - radius); TessellateQuad(subRect, TessellationType.EdgeCorner, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); // C subRect = new Rect(rect.x + radius, rect.y, leftWidth - radius, radius); TessellateQuad(subRect, TessellationType.EdgeCorner, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } else if (radius < leftWidth) { // ____________ // -* | | F | // * A\ | B|_______| // *____\|__| // | | // | | // | E | // | | // | | // |________| // B subRect = new Rect(rect.x + radius, rect.y, leftWidth - radius, Mathf.Max(radius, topWidth)); TessellateQuad(subRect, TessellationType.EdgeCorner, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } else { // ____________ // -* | | // * A\ | | // *____\| F | // | B | | // |_____|__________| // | | // |E | // | | // |__| // B subRect = new Rect(rect.x, rect.y + radius, Mathf.Max(radius, leftWidth), topWidth - radius); TessellateQuad(subRect, TessellationType.EdgeCorner, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } } else { // _________ // -* | F | // * A\_|_______| // *__/ // | | // | | // |E | // | | // |__| // A TessellateBorderedFan(TessellationType.EdgeCorner, cornerCenter, radius, leftWidth, topWidth, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } // Tessellate the straight outlines // E float cornerSize = Mathf.Max(radius, topWidth); subRect = new Rect(rect.x, rect.y + cornerSize, leftWidth, rect.height - cornerSize); TessellateQuad(subRect, TessellationType.EdgeVertical, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); // F cornerSize = Mathf.Max(radius, leftWidth); subRect = new Rect(rect.x + cornerSize, rect.y, rect.width - cornerSize, topWidth); TessellateQuad(subRect, TessellationType.EdgeHorizontal, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } }
/// <summary> /// Uninitialize OpenGL element array drawing. /// </summary> public static void UninitArrayState(VertexFlags types) { if ((types & VertexFlags.Pos) != 0) Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY); if ((types & VertexFlags.Normal) != 0) Gl.glDisableClientState(Gl.GL_NORMAL_ARRAY); if ((types & VertexFlags.Color) != 0) Gl.glDisableClientState(Gl.GL_COLOR_ARRAY); if ((types & VertexFlags.Texture) != 0) Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY); }
static VertexFormat GetVertexFormat (VertexFlags flags, int boneSlotCount) { uint elemCount = 0, f = (uint)flags; for (elemCount = 0; f != 0; elemCount++) f &= f - 1; var elems = new VertexElement[(int)elemCount + 1 + (boneSlotCount * 2)]; int offset = 3, idx = 1; elems[0] = new VertexElement("Position", 0, 3); if ((flags & VertexFlags.Normal) != 0) { elems[idx++] = new VertexElement("Normal", offset, 3); offset += 3; } for (var i = 0; i < 4; i++) { if (((int)flags & ((int)VertexFlags.TexCoord0 << i)) != 0) { elems[idx++] = new VertexElement("TexCoord" + i, offset, 2); offset += 2; } } for (var i = 0; i < 4; i++) { if (((int)flags & ((int)VertexFlags.Color0 << i)) != 0) { elems[idx++] = new VertexElement("Color" + i, offset, 4); offset += 4; } } for (var i = 0; i < boneSlotCount; i++) elems[idx++] = new VertexElement("BoneWeight" + i, offset++, 1); for (var i = 0; i < boneSlotCount; i++) elems[idx++] = new VertexElement("BoneIndex" + i, offset++, 1); return new VertexFormat(offset, elems); }