//public int getGroup0TriCount() //{ // return *(int*)(*(int*)(*(int*)(getPrimaryTopologyPtr()) + 4) + 8); //} //public void setGroup0TriCount(int num) //{ // *(int*)(*(int*)(*(int*)(getPrimaryTopologyPtr()) + 4) + 8) = num; //} public unsafe GrannyMeshInfo getMeshInfo() { GrannyMeshInfo meshInfo = new GrannyMeshInfo(); meshInfo.name = Marshal.PtrToStringAnsi((IntPtr)(sbyte *)*(int *)(m_pkMesh)); List <string> boneBindings = new List <string>(); for (int i = 0; i < getNumBoneBindings(); i++) { boneBindings.Add(Marshal.PtrToStringAnsi((IntPtr)(sbyte *)*(int *)(*(int *)(getBoneBindingsPtr()) + i * 44))); } meshInfo.boneBindings = boneBindings; meshInfo.setVertexStructInfos(getVertexStructInfos()); int vertexCount = getNumVertices(); IntPtr vertexPtr = getVerticesPtr(); int vertexSize = meshInfo.bytesPerVertex; List <GrannyVertexInfo> vertexInfos = new List <GrannyVertexInfo>(); for (int i = 0; i < vertexCount; i++) { GrannyVertexInfo currentVertex = new GrannyVertexInfo(); GrannyMeshVertexStructInfo structInfo = meshInfo.getVertexStructInfoByName("Position"); if (structInfo != null) { currentVertex.position = new float[3]; currentVertex.position[0] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)); currentVertex.position[1] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)); currentVertex.position[2] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)); } structInfo = meshInfo.getVertexStructInfoByName("BoneWeights"); if (structInfo != null) { currentVertex.boneWeights = new int[structInfo.count]; for (int j = 0; j < structInfo.count; j++) { currentVertex.boneWeights[j] = (byte)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * j)); } } else { int structInfoCount = 8; currentVertex.boneWeights = new int[structInfoCount]; currentVertex.boneWeights[0] = 255; for (int j = 1; j < structInfoCount; j++) { currentVertex.boneWeights[j] = 0; } } structInfo = meshInfo.getVertexStructInfoByName("BoneIndices"); if (structInfo != null) { currentVertex.boneIndices = new int[structInfo.count]; for (int j = 0; j < structInfo.count; j++) { currentVertex.boneIndices[j] = (byte)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * j)); } } else { int structInfoCount = 8; currentVertex.boneIndices = new int[structInfoCount]; for (int j = 0; j < structInfoCount; j++) { currentVertex.boneIndices[j] = 0; } } structInfo = meshInfo.getVertexStructInfoByName("Normal"); if (structInfo != null) { currentVertex.normal = new float[3]; currentVertex.normal[0] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)); currentVertex.normal[1] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)); currentVertex.normal[2] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)); } structInfo = meshInfo.getVertexStructInfoByName("Binormal"); if (structInfo != null) { currentVertex.binormal = new float[3]; currentVertex.binormal[0] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)); currentVertex.binormal[1] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)); currentVertex.binormal[2] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)); } structInfo = meshInfo.getVertexStructInfoByName("Tangent"); if (structInfo != null) { currentVertex.tangent = new float[3]; currentVertex.tangent[0] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)); currentVertex.tangent[1] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)); currentVertex.tangent[2] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)); } structInfo = meshInfo.getVertexStructInfoByName("TextureCoordinates0"); currentVertex.uv = new float[2]; if (structInfo != null) { currentVertex.uv[0] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)); currentVertex.uv[1] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)); } structInfo = meshInfo.getVertexStructInfoByName("TextureCoordinates1"); currentVertex.uv2 = new float[2]; if (structInfo != null) { currentVertex.uv2[0] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)); currentVertex.uv2[1] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)); } else { currentVertex.uv2[0] = 0f; currentVertex.uv2[1] = 0f; } structInfo = meshInfo.getVertexStructInfoByName("TextureCoordinates2"); currentVertex.uv3 = new float[2]; if (structInfo != null) { currentVertex.uv3[0] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)); currentVertex.uv3[1] = (float)structInfo.convert(*(int *)(vertexPtr) + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)); } else { currentVertex.uv3[0] = 0f; currentVertex.uv3[1] = 0f; } vertexInfos.Add(currentVertex); } meshInfo.vertices = vertexInfos; if (*(int *)(getMaterialBindingsPtr()) != 0) { string materialName = Marshal.PtrToStringAnsi((IntPtr)(sbyte *)*(int *)*(int *)*(int *)(getMaterialBindingsPtr())); meshInfo.materialName = materialName; } int numTriangleGroups = *(int *)*(int *)getPrimaryTopologyPtr(); List <PrimaryTopologyGroupInfo> primaryTopologyGroupInfos = new List <PrimaryTopologyGroupInfo>(); for (int i = 0; i < numTriangleGroups; i++) { PrimaryTopologyGroupInfo primaryTopologyGroupInfo = new PrimaryTopologyGroupInfo(); primaryTopologyGroupInfo.groupMaterialIndex = *(int *)(*(int *)(*(int *)(getPrimaryTopologyPtr()) + 4) + i * 12 + 0); primaryTopologyGroupInfo.groupTriFirst = *(int *)(*(int *)(*(int *)(getPrimaryTopologyPtr()) + 4) + i * 12 + 4); primaryTopologyGroupInfo.groupTriCount = *(int *)(*(int *)(*(int *)(getPrimaryTopologyPtr()) + 4) + i * 12 + 8); primaryTopologyGroupInfos.Add(primaryTopologyGroupInfo); } meshInfo.primaryTopologyGroupInfos = primaryTopologyGroupInfos; int numIndices16 = getNumIndices16(); int numIndices = getNumIndices(); List <int> indices = new List <int>(); if (numIndices16 > 0) { for (int i = 0; i < numIndices16; i++) { indices.Add((int)*(ushort *)(*(int *)(*(int *)(getPrimaryTopologyPtr()) + 28) + i * 2)); } } else if (numIndices > 0) { for (int i = 0; i < numIndices; i++) { indices.Add(*(int *)(*(int *)(*(int *)(getPrimaryTopologyPtr()) + 16) + i * 4)); } } if (indices.Count > 0) { List <int[]> triangles = new List <int[]>(); foreach (PrimaryTopologyGroupInfo info in primaryTopologyGroupInfos) { for (int iTriangle = info.groupTriFirst; iTriangle < info.groupTriFirst + info.groupTriCount; iTriangle++) { int index0 = iTriangle * 3; int index1 = index0 + 1; int index2 = index0 + 2; int[] triangle = new int[4]; triangle[0] = indices[index0]; triangle[1] = indices[index1]; triangle[2] = indices[index2]; triangle[3] = info.groupMaterialIndex; triangles.Add(triangle); } } meshInfo.triangles = triangles; } return(meshInfo); }
unsafe private void writeVertices(GrannyMeshInfo meshInfo) { int vertexCount = meshInfo.vertices.Count; setNumVertices(vertexCount); int vertexSize = meshInfo.bytesPerVertex; int oldVerticesPtr = *(int *)getVerticesPtr(); *(int *)(getVerticesPtr()) = (int)Marshal.AllocHGlobal(vertexCount * vertexSize); int newVerticesPtr = *(int *)getVerticesPtr(); List <GrannyVertexInfo> vertexInfos = meshInfo.vertices; for (int i = 0; i < vertexCount; i++) { MemoryUtil.MemCpy((void *)(newVerticesPtr + i * vertexSize), (void *)oldVerticesPtr, (uint)vertexSize); GrannyVertexInfo currentVertex = vertexInfos[i]; GrannyMeshVertexStructInfo structInfo = meshInfo.getVertexStructInfoByName("Position"); if (structInfo != null) { *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = currentVertex.position[0]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = currentVertex.position[1]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = currentVertex.position[2]; } structInfo = meshInfo.getVertexStructInfoByName("BoneWeights"); if (structInfo != null) { for (int j = 0; j < structInfo.count; j++) { if (j < currentVertex.boneWeights.Length) { *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * j)) = (byte)currentVertex.boneWeights[j]; } else { *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * j)) = (byte)0; } } } structInfo = meshInfo.getVertexStructInfoByName("BoneIndices"); if (structInfo != null) { for (int j = 0; j < structInfo.count; j++) { if (j < currentVertex.boneIndices.Length) { *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * j)) = (byte)currentVertex.boneIndices[j]; } else { *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * j)) = (byte)0; } } } structInfo = meshInfo.getVertexStructInfoByName("Normal"); if (structInfo != null) { // granny_real32 *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = currentVertex.normal[0]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = currentVertex.normal[1]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = currentVertex.normal[2]; } structInfo = meshInfo.getVertexStructInfoByName("Tangent"); if (structInfo != null && currentVertex.tangent != null) { // granny_real32 *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = currentVertex.tangent[0]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = currentVertex.tangent[1]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = currentVertex.tangent[2]; } structInfo = meshInfo.getVertexStructInfoByName("Binormal"); if (structInfo != null && currentVertex.binormal != null) { // granny_real32 *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = currentVertex.binormal[0]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = currentVertex.binormal[1]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = currentVertex.binormal[2]; } structInfo = meshInfo.getVertexStructInfoByName("TextureCoordinates0"); if (structInfo != null) { // granny_real32 *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = currentVertex.uv[0]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = currentVertex.uv[1]; } structInfo = meshInfo.getVertexStructInfoByName("TextureCoordinates1"); if (structInfo != null) { // granny_real32 *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = currentVertex.uv2[0]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = currentVertex.uv2[1]; } structInfo = meshInfo.getVertexStructInfoByName("TextureCoordinates2"); if (structInfo != null) { // granny_real32 *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = currentVertex.uv3[0]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = currentVertex.uv3[1]; } } }
unsafe private void writeVertices(GrannyMeshInfo meshInfo, bool isLeaderFormat, bool isSceneFormat) { int vertexCount = meshInfo.vertices.Count; setNumVertices(vertexCount); int vertexSize = meshInfo.bytesPerVertex; int oldVerticesPtr = *(int *)getVerticesPtr(); *(int *)(getVerticesPtr()) = (int)Marshal.AllocHGlobal(vertexCount * vertexSize); int newVerticesPtr = *(int *)getVerticesPtr(); List <GrannyVertexInfo> vertexInfos = meshInfo.vertices; for (int i = 0; i < vertexCount; i++) { MemoryUtil.MemCpy((void *)(newVerticesPtr + i * vertexSize), (void *)oldVerticesPtr, (uint)vertexSize); GrannyVertexInfo currentVertex = vertexInfos[i]; GrannyMeshVertexStructInfo structInfo = meshInfo.getVertexStructInfoByName("Position"); if (structInfo != null) { *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = currentVertex.position[0]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = currentVertex.position[1]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = currentVertex.position[2]; } if (!isSceneFormat) { structInfo = meshInfo.getVertexStructInfoByName("BoneWeights"); if (structInfo != null) { *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = (byte)currentVertex.boneWeights[0]; *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = (byte)currentVertex.boneWeights[1]; *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = (byte)currentVertex.boneWeights[2]; *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 3)) = (byte)currentVertex.boneWeights[3]; } structInfo = meshInfo.getVertexStructInfoByName("BoneIndices"); if (structInfo != null) { *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = (byte)currentVertex.boneIndices[0]; *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = (byte)currentVertex.boneIndices[1]; *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = (byte)currentVertex.boneIndices[2]; *(byte *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 3)) = (byte)currentVertex.boneIndices[3]; } } if (isLeaderFormat || isSceneFormat) { structInfo = meshInfo.getVertexStructInfoByName("Normal"); if (structInfo != null) { // granny_real16 *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = NumberUtils.floatToHalf(currentVertex.normal[0]); *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = NumberUtils.floatToHalf(currentVertex.normal[1]); *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = NumberUtils.floatToHalf(currentVertex.normal[2]); } structInfo = meshInfo.getVertexStructInfoByName("Binormal"); if (structInfo != null && currentVertex.binormal != null) { // granny_real16 *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = NumberUtils.floatToHalf(currentVertex.binormal[0]); *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = NumberUtils.floatToHalf(currentVertex.binormal[1]); *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = NumberUtils.floatToHalf(currentVertex.binormal[2]); } structInfo = meshInfo.getVertexStructInfoByName("Tangent"); if (structInfo != null && currentVertex.tangent != null) { // granny_real16 *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = NumberUtils.floatToHalf(currentVertex.tangent[0]); *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = NumberUtils.floatToHalf(currentVertex.tangent[1]); *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = NumberUtils.floatToHalf(currentVertex.tangent[2]); } } else { structInfo = meshInfo.getVertexStructInfoByName("Normal"); if (structInfo != null) { // granny_real32 *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = currentVertex.normal[0]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = currentVertex.normal[1]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 2)) = currentVertex.normal[2]; } } if (isLeaderFormat || isSceneFormat) { structInfo = meshInfo.getVertexStructInfoByName("TextureCoordinates0"); if (structInfo != null) { // granny_real16 *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = NumberUtils.floatToHalf(currentVertex.uv[0]); *(ushort *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = NumberUtils.floatToHalf(currentVertex.uv[1]); } } else { structInfo = meshInfo.getVertexStructInfoByName("TextureCoordinates0"); if (structInfo != null) { // granny_real32 *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 0)) = currentVertex.uv[0]; *(float *)(newVerticesPtr + (i * vertexSize) + structInfo.offset + (structInfo.length * 1)) = currentVertex.uv[1]; } } } }