public static unsafe MeshBGFX CreateStaticMeshFromBlobAsset(RendererBGFXInstance *inst, LitMeshRenderData mesh) { ushort * indices = (ushort *)mesh.Mesh.Value.Indices.GetUnsafePtr(); int nindices = mesh.Mesh.Value.Indices.Length; LitVertex *vertices = (LitVertex *)mesh.Mesh.Value.Vertices.GetUnsafePtr(); int nvertices = mesh.Mesh.Value.Vertices.Length; return(CreateStaticMesh(inst, indices, nindices, vertices, nvertices)); }
public static unsafe void EncodeDebugTangents(RendererBGFXInstance *sys, bgfx.Encoder *encoder, ushort viewId, float2 width, float length, ref LitMeshRenderData mesh, ref float4x4 objTx, ref float4x4 viewTx, ref float4x4 projTx) { int nv = (int)mesh.Mesh.Value.Vertices.Length; LitVertex *vertices = (LitVertex *)mesh.Mesh.Value.Vertices.GetUnsafePtr(); for (int i = 0; i < nv; i++) { EncodeLine(sys, encoder, viewId, vertices[i].Position, vertices[i].Position + vertices[i].Normal * length, new float4(0, 0, 1, 1), width, ref objTx, ref viewTx, ref projTx); EncodeLine(sys, encoder, viewId, vertices[i].Position, vertices[i].Position + vertices[i].Tangent * length, new float4(1, 0, 0, 1), width, ref objTx, ref viewTx, ref projTx); } }
public static void ComputeTangentAndBinormal(NativeArray <LitVertex> vertices, NativeArray <ushort> indices) { unsafe { int nv = vertices.Length; int ni = indices.Length; ushort * inds = (ushort *)indices.GetUnsafePtr(); LitVertex *verts = (LitVertex *)vertices.GetUnsafePtr(); // assumes normal is valid! for (int i = 0; i < ni; i += 3) { int i0 = inds[i + 2]; int i1 = inds[i + 1]; int i2 = inds[i]; Assert.IsTrue(i0 >= 0 && i0 < nv && i1 >= 0 && i1 < nv && i2 >= 0 && i2 < nv); float3 edge1 = verts[i1].Position - verts[i0].Position; Assert.IsTrue(math.lengthsq(edge1) > 0); float3 edge2 = verts[i2].Position - verts[i0].Position; Assert.IsTrue(math.lengthsq(edge2) > 0); float2 uv1 = verts[i1].TexCoord0 - verts[i0].TexCoord0; Assert.IsTrue(math.lengthsq(uv1) > 0); float2 uv2 = verts[i2].TexCoord0 - verts[i0].TexCoord0; Assert.IsTrue(math.lengthsq(uv2) > 0); float r = 1.0f / (uv1.x * uv2.y - uv1.y * uv2.x); float3 n = math.cross(edge2, edge1); float3 tangent = new float3( ((edge1.x * uv2.y) - (edge2.x * uv1.y)) * r, ((edge1.y * uv2.y) - (edge2.y * uv1.y)) * r, ((edge1.z * uv2.y) - (edge2.z * uv1.y)) * r ); float3 bitangent = new float3( ((edge1.x * uv2.x) - (edge2.x * uv1.x)) * r, ((edge1.y * uv2.x) - (edge2.y * uv1.x)) * r, ((edge1.z * uv2.x) - (edge2.z * uv1.x)) * r ); Assert.IsTrue(math.lengthsq(tangent) > 0.0f); Assert.IsTrue(math.lengthsq(bitangent) > 0.0f); float3 n2 = math.cross(tangent, bitangent); if (math.dot(n2, n) > 0.0f) { tangent = -tangent; } verts[i0].Tangent += tangent; verts[i1].Tangent += tangent; verts[i2].Tangent += tangent; } for (int i = 0; i < nv; i++) { Assert.IsTrue(math.lengthsq(verts[i].Tangent) > 0.0f); verts[i].Tangent = math.normalize(verts[i].Tangent); } } }
public static unsafe MeshBGFX CreateStaticSkinnedMeshFromBlobAsset(RendererBGFXInstance *inst, LitMeshRenderData meshData, SkinnedMeshRenderData skinnedData) { ushort * indices = (ushort *)meshData.Mesh.Value.Indices.GetUnsafePtr(); int nindices = meshData.Mesh.Value.Indices.Length; LitVertex * vertices = (LitVertex *)meshData.Mesh.Value.Vertices.GetUnsafePtr(); int nvertices = meshData.Mesh.Value.Vertices.Length; SkinnedMeshVertex *skinningdata = (SkinnedMeshVertex *)skinnedData.SkinnedMeshDataRef.Value.Vertices.GetUnsafePtr(); return(CreateStaticMesh(inst, indices, nindices, vertices, nvertices, skinningdata)); }
public unsafe void CheckVertexLayout() { LitVertex tv; LitVertex *p = &tv; { Debug.Assert((long)&(p->Position) - (long)p == 0); Debug.Assert((long)&(p->TexCoord0) - (long)p == 12); Debug.Assert((long)&(p->Normal) - (long)p == 20); Debug.Assert((long)&(p->Tangent) - (long)p == 32); Debug.Assert((long)&(p->BillboardPos) - (long)p == 44); Debug.Assert((long)&(p->Albedo_Opacity) - (long)p == 56); Debug.Assert((long)&(p->Metal_Smoothness) - (long)p == 72); } }
public static unsafe MeshBGFX CreateStaticMesh(RendererBGFXInstance *inst, ushort *indices, int nindices, LitVertex *vertices, int nvertices, SkinnedMeshVertex *skinningdata = null) { Assert.IsTrue(nindices > 0 && nvertices > 0 && nvertices <= ushort.MaxValue); bool hasSkinningData = skinningdata != null; #if ENABLE_DOTSRUNTIME_PROFILER ProfilerStats.AccumStats.memMeshCount.Accumulate(1); long bytes = nvertices * sizeof(LitVertex) + nindices * sizeof(ushort); if (hasSkinningData) { bytes += nvertices * sizeof(SkinnedMeshVertex); } ProfilerStats.AccumStats.memMesh.Accumulate(bytes); ProfilerStats.AccumStats.memReservedGFX.Accumulate(bytes); ProfilerStats.AccumStats.memUsedGFX.Accumulate(bytes); #endif if (hasSkinningData) { int litVertexSize = sizeof(LitVertex); int skinningVertexSize = sizeof(SkinnedMeshVertex); int totalVertexSize = litVertexSize + skinningVertexSize; byte *tmpBlock = (byte *)UnsafeUtility.Malloc(totalVertexSize * nvertices, 4, Allocator.Temp); UnsafeUtility.MemCpyStride(tmpBlock, totalVertexSize, vertices, litVertexSize, litVertexSize, nvertices); UnsafeUtility.MemCpyStride(tmpBlock + litVertexSize, totalVertexSize, skinningdata, skinningVertexSize, skinningVertexSize, nvertices); bgfx.Memory *bgfxMemory = RendererBGFXStatic.CreateMemoryBlock((byte *)tmpBlock, nvertices * totalVertexSize); UnsafeUtility.Free(tmpBlock, Allocator.Temp); return(new MeshBGFX { indexBufferHandle = bgfx.create_index_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)indices, nindices * 2), (ushort)bgfx.BufferFlags.None).idx, vertexBufferHandle = bgfx.create_vertex_buffer(bgfxMemory, &inst->m_litSkinnedVertexBufferDecl, (ushort)bgfx.BufferFlags.None).idx, indexCount = nindices, vertexCount = nvertices, maxIndexCount = nindices, maxVertexCount = nvertices, vertexLayoutHandle = inst->m_litSkinnedVertexBufferDeclHandle, isDynamic = false, vertexSize = totalVertexSize, }); } else { return(new MeshBGFX { indexCount = nindices, vertexCount = nvertices, maxIndexCount = nindices, maxVertexCount = nvertices, indexBufferHandle = bgfx.create_index_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)indices, nindices * 2), (ushort)bgfx.BufferFlags.None).idx, vertexLayoutHandle = inst->m_litVertexBufferDeclHandle, vertexBufferHandle = bgfx.create_vertex_buffer( RendererBGFXStatic.CreateMemoryBlock((byte *)vertices, nvertices * sizeof(LitVertex)), &inst->m_litVertexBufferDecl, (ushort)bgfx.BufferFlags.None).idx, isDynamic = false, vertexSize = sizeof(LitVertex), }); } }
public static unsafe MeshBGFX CreateStaticMesh(RendererBGFXInstance *inst, ushort *indices, int nindices, LitVertex *vertices, int nvertices) { Assert.IsTrue(nindices > 0 && nvertices > 0 && nvertices <= ushort.MaxValue); #if ENABLE_DOTSRUNTIME_PROFILER ProfilerStats.AccumStats.memMeshCount.Accumulate(1); long bytes = nvertices * sizeof(LitVertex) + nindices * sizeof(ushort); ProfilerStats.AccumStats.memMesh.Accumulate(bytes); ProfilerStats.AccumStats.memReservedGFX.Accumulate(bytes); ProfilerStats.AccumStats.memUsedGFX.Accumulate(bytes); #endif return(new MeshBGFX { indexCount = nindices, vertexCount = nvertices, maxIndexCount = nindices, maxVertexCount = nvertices, indexBufferHandle = bgfx.create_index_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)indices, nindices * 2), (ushort)bgfx.BufferFlags.None).idx, vertexLayoutHandle = inst->m_litVertexBufferDeclHandle, vertexBufferHandle = bgfx.create_vertex_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)vertices, nvertices * sizeof(LitVertex)), &inst->m_litVertexBufferDecl, (ushort)bgfx.BufferFlags.None).idx, isDynamic = false, vertexSize = sizeof(LitVertex), }); }