public GrannySkeletonInfo readSkeletonInfo() { GrannySkeletonInfo skeletonInfo = new GrannySkeletonInfo(); List <GrannyBoneInfo> boneInfos = new List <GrannyBoneInfo>(); for (int bi = 0; bi < wrappedSkeleton.Bones.Count; bi++) { IGrannyBone bone = wrappedSkeleton.Bones[bi]; GrannyBoneInfo boneInfo = new GrannyBoneInfo(); boneInfo.name = bone.Name; boneInfo.parentIndex = bone.ParentIndex; GrannyTransformInfo boneTransformInfo = new GrannyTransformInfo(); IGrannyTransform boneTransform = bone.LocalTransform; boneTransformInfo.flags = GrannyTransformInfo.getFlagsInt(boneTransform.Flags); GrannyBoneWrapper boneWrapper = new GrannyBoneWrapper(bone); boneTransformInfo.orientation = boneWrapper.getOrientation(); boneTransformInfo.position = boneWrapper.getPosition(); boneTransformInfo.scaleShear = boneWrapper.getScaleShear(); boneInfo.localTransform = boneTransformInfo; boneInfo.inverseWorldTransform = bone.InverseWorldTransform; boneInfo.LODError = bone.LODError; boneInfos.Add(boneInfo); } skeletonInfo.bones = boneInfos; return(skeletonInfo); }
public void writeSkeletonInfo(GrannySkeletonInfo skeletonInfo) { int bonesCount = skeletonInfo.bones.Count; setNumBones(bonesCount); int oldBonesPtr = *(int *)getBonesPtr(); *(int *)(getBonesPtr()) = (int)Marshal.AllocHGlobal(bonesCount * boneSize); int newBonesPtr = *(int *)getBonesPtr(); List <GrannyBoneInfo> boneInfos = skeletonInfo.bones; for (int i = 0; i < bonesCount; i++) { MemoryUtil.MemCpy((void *)(newBonesPtr + i * boneSize), (void *)oldBonesPtr, (uint)boneSize); GrannyBoneInfo currentBone = boneInfos[i]; *(int *)(newBonesPtr + (i * boneSize) + 0) = (int)MemoryUtil.getStringIntPtr(currentBone.name); *(int *)(newBonesPtr + (i * boneSize) + 4) = currentBone.parentIndex; int flags = currentBone.localTransform.flags; *(int *)(newBonesPtr + (i * boneSize) + 8) = flags; *(float *)(newBonesPtr + (i * boneSize) + 12) = currentBone.localTransform.position[0]; *(float *)(newBonesPtr + (i * boneSize) + 16) = currentBone.localTransform.position[1]; *(float *)(newBonesPtr + (i * boneSize) + 20) = currentBone.localTransform.position[2]; *(float *)(newBonesPtr + (i * boneSize) + 24) = currentBone.localTransform.orientation[0]; *(float *)(newBonesPtr + (i * boneSize) + 28) = currentBone.localTransform.orientation[1]; *(float *)(newBonesPtr + (i * boneSize) + 32) = currentBone.localTransform.orientation[2]; *(float *)(newBonesPtr + (i * boneSize) + 36) = currentBone.localTransform.orientation[3]; for (int j = 0; j < 9; j++) { *(float *)(newBonesPtr + (i * boneSize) + 40 + (j * 4)) = currentBone.localTransform.scaleShear[j]; } for (int j = 0; j < 16; j++) { *(float *)(newBonesPtr + (i * boneSize) + 76 + (j * 4)) = currentBone.inverseWorldTransform[j]; } *(float *)(newBonesPtr + (i * boneSize) + 140) = 1.0f; // +140 LOD Error // +144 Num Extended Datas // +148 Extended Datas Pointer } }
private static GrannyModelInfo loadModelInfo(string filename) { string currentLine = ""; string numberRegex = "([-+]?[0-9]+\\.?[0-9]*) "; StreamReader streamReader = new StreamReader(filename); while (!currentLine.StartsWith("skeleton")) { currentLine = streamReader.ReadLine(); } GrannyModelInfo modelInfo = new GrannyModelInfo(); GrannySkeletonInfo skeletonInfo = new GrannySkeletonInfo(); List <GrannyBoneInfo> skeletonBones = new List <GrannyBoneInfo>(); while (!currentLine.StartsWith("meshes")) { currentLine = streamReader.ReadLine(); if (!currentLine.StartsWith("meshes")) { string regexString = "([0-9]+) \"(.+)\" "; for (int i = 0; i < 24; i++) { regexString = regexString + numberRegex; } Regex regex = new Regex(regexString.Trim()); MatchCollection mc = regex.Matches(currentLine); foreach (Match m in mc) { GrannyBoneInfo boneInfo = new GrannyBoneInfo(); GrannyTransformInfo transformInfo = new GrannyTransformInfo(); //int boneindex = NumberUtils.parseInt(m.Groups[1].Value.Trim()); string boneName = m.Groups[2].Value; int parentIndex = NumberUtils.parseInt(m.Groups[3].Value.Trim()); float[] position = new float[3]; position[0] = NumberUtils.parseFloat(m.Groups[4].Value.Trim()); position[1] = NumberUtils.parseFloat(m.Groups[5].Value.Trim()); position[2] = NumberUtils.parseFloat(m.Groups[6].Value.Trim()); float[] orientation = new float[4]; orientation[0] = NumberUtils.parseFloat(m.Groups[7].Value.Trim()); orientation[1] = NumberUtils.parseFloat(m.Groups[8].Value.Trim()); orientation[2] = NumberUtils.parseFloat(m.Groups[9].Value.Trim()); orientation[3] = NumberUtils.parseFloat(m.Groups[10].Value.Trim()); float[] scaleShear = new float[9]; scaleShear[0] = 1.0f; scaleShear[1] = 0.0f; scaleShear[2] = 0.0f; scaleShear[3] = 0.0f; scaleShear[4] = 1.0f; scaleShear[5] = 0.0f; scaleShear[6] = 0.0f; scaleShear[7] = 0.0f; scaleShear[8] = 1.0f; float[] invWorld = new float[16]; for (int j = 0; j < 16; j++) { invWorld[j] = NumberUtils.parseFloat(m.Groups[j + 11].Value.Trim()); } bool hasPosition = true; bool hasOrientation = true; int flags = 0; if (NumberUtils.almostEquals(position[0], 0.0f, 4) && NumberUtils.almostEquals(position[1], 0.0f, 4) && NumberUtils.almostEquals(position[2], 0.0f, 4)) { hasPosition = false; } if (NumberUtils.almostEquals(orientation[0], 0.0f, 5) && NumberUtils.almostEquals(orientation[1], 0.0f, 5) && NumberUtils.almostEquals(orientation[2], 0.0f, 5) && NumberUtils.almostEquals(orientation[3], 1.0f, 5)) { hasOrientation = false; } if (hasPosition) { flags = flags + 1; } if (hasOrientation) { flags = flags + 2; } transformInfo.flags = flags; transformInfo.position = position; transformInfo.orientation = orientation; transformInfo.scaleShear = scaleShear; boneInfo.name = boneName; boneInfo.parentIndex = parentIndex; boneInfo.localTransform = transformInfo; boneInfo.inverseWorldTransform = invWorld; boneInfo.LODError = 0; skeletonBones.Add(boneInfo); } } } skeletonInfo.bones = skeletonBones; // Read Meshes int numMeshes = NumberUtils.parseInt(currentLine.Replace("meshes:", "")); List <GrannyMeshInfo> meshInfos = new List <GrannyMeshInfo>(); for (int meshId = 0; meshId < numMeshes; meshId++) { string meshName = ""; while (!currentLine.StartsWith("mesh:")) { currentLine = streamReader.ReadLine(); } string regexString = "\"(.+)\""; Regex regex = new Regex(regexString); MatchCollection mc = regex.Matches(currentLine); foreach (Match m in mc) { meshName = m.Groups[1].Value; } // Read Vertices List <GrannyVertexInfo> vertexInfos = new List <GrannyVertexInfo>(); while (!currentLine.StartsWith("triangles")) { currentLine = streamReader.ReadLine(); if (!currentLine.StartsWith("vertices") && !currentLine.StartsWith("triangles")) { int spacesCount = 0; foreach (char c in currentLine) { if (c == ' ') { spacesCount++; } } bool hasBinormalsAndTangents = spacesCount > 15; regexString = ""; for (int i = 0; i < 16; i++) { regexString = regexString + numberRegex; } if (hasBinormalsAndTangents) { for (int i = 0; i < 6; i++) { regexString = regexString + numberRegex; } } regex = new Regex(regexString.Trim()); mc = regex.Matches(currentLine); foreach (Match m in mc) { GrannyVertexInfo vertexInfo = new GrannyVertexInfo(); float[] position = new float[3]; position[0] = NumberUtils.parseFloat(m.Groups[1].Value.Trim()); position[1] = NumberUtils.parseFloat(m.Groups[2].Value.Trim()); position[2] = NumberUtils.parseFloat(m.Groups[3].Value.Trim()); float[] normal = new float[3]; normal[0] = NumberUtils.parseFloat(m.Groups[4].Value.Trim()); normal[1] = NumberUtils.parseFloat(m.Groups[5].Value.Trim()); normal[2] = NumberUtils.parseFloat(m.Groups[6].Value.Trim()); float[] uv = new float[2]; uv[0] = NumberUtils.parseFloat(m.Groups[7].Value.Trim()); uv[1] = NumberUtils.parseFloat(m.Groups[8].Value.Trim()); int[] boneIndices = new int[4]; boneIndices[0] = NumberUtils.parseInt(m.Groups[9].Value.Trim()); boneIndices[1] = NumberUtils.parseInt(m.Groups[10].Value.Trim()); boneIndices[2] = NumberUtils.parseInt(m.Groups[11].Value.Trim()); boneIndices[3] = NumberUtils.parseInt(m.Groups[12].Value.Trim()); int[] boneWeights = new int[4]; boneWeights[0] = NumberUtils.parseInt(m.Groups[13].Value.Trim()); boneWeights[1] = NumberUtils.parseInt(m.Groups[14].Value.Trim()); boneWeights[2] = NumberUtils.parseInt(m.Groups[15].Value.Trim()); boneWeights[3] = NumberUtils.parseInt(m.Groups[16].Value.Trim()); if (hasBinormalsAndTangents) { float[] tangent = new float[3]; tangent[0] = NumberUtils.parseFloat(m.Groups[17].Value.Trim()); tangent[1] = NumberUtils.parseFloat(m.Groups[18].Value.Trim()); tangent[2] = NumberUtils.parseFloat(m.Groups[19].Value.Trim()); float[] binormal = new float[3]; binormal[0] = NumberUtils.parseFloat(m.Groups[20].Value.Trim()); binormal[1] = NumberUtils.parseFloat(m.Groups[21].Value.Trim()); binormal[2] = NumberUtils.parseFloat(m.Groups[22].Value.Trim()); vertexInfo.binormal = binormal; vertexInfo.tangent = tangent; } vertexInfo.position = position; vertexInfo.normal = normal; vertexInfo.boneIndices = boneIndices; vertexInfo.boneWeights = boneWeights; vertexInfo.uv = uv; vertexInfos.Add(vertexInfo); } } } // Read Triangles List <int[]> triangles = new List <int[]>(); while (!currentLine.StartsWith("mesh") && !currentLine.StartsWith("end")) { currentLine = streamReader.ReadLine(); if (!currentLine.StartsWith("mesh") && !currentLine.StartsWith("end")) { regexString = ""; for (int i = 0; i < 3; i++) { regexString = regexString + "([-+]?[0-9]+\\.?[0-9]*) "; } regex = new Regex(regexString.Trim()); mc = regex.Matches(currentLine); foreach (Match m in mc) { int[] triangle = new int[3]; triangle[0] = NumberUtils.parseInt(m.Groups[1].Value.Trim()); triangle[1] = NumberUtils.parseInt(m.Groups[2].Value.Trim()); triangle[2] = NumberUtils.parseInt(m.Groups[3].Value.Trim()); triangles.Add(triangle); } } } List <PrimaryTopologyGroupInfo> groupInfos = new List <PrimaryTopologyGroupInfo>(); groupInfos.Add(new PrimaryTopologyGroupInfo(0, 0, triangles.Count)); GrannyMeshInfo meshInfo = new GrannyMeshInfo(); meshInfo.name = meshName; meshInfo.vertices = vertexInfos; meshInfo.triangles = triangles; meshInfo.primaryTopologyGroupInfos = groupInfos; meshInfo.materialBindingNames = new List <string> { "DefaultMaterialBinding" }; meshInfos.Add(meshInfo); } modelInfo.skeleton = skeletonInfo; modelInfo.meshBindings = meshInfos; streamReader.Close(); return(modelInfo); }
private static List <GrannyModelInfo> loadModelInfos(string filename, int vertexFormat) { string currentLine = ""; string numberRegex = "([-+]?[0-9]+\\.?[0-9]*) "; StreamReader streamReader = new StreamReader(filename); bool endOfFile = false; List <GrannyModelInfo> modelInfos = new List <GrannyModelInfo>(); while (!endOfFile) { while (!currentLine.StartsWith("skeleton")) { if (currentLine.Equals("end")) { endOfFile = true; break; } currentLine = streamReader.ReadLine(); } if (endOfFile) { break; } GrannyModelInfo modelInfo = new GrannyModelInfo(); GrannySkeletonInfo skeletonInfo = new GrannySkeletonInfo(); List <GrannyBoneInfo> skeletonBones = new List <GrannyBoneInfo>(); while (!currentLine.StartsWith("meshes")) { currentLine = streamReader.ReadLine(); if (!currentLine.StartsWith("meshes")) { string regexString = "([0-9]+) \"(.+)\" "; for (int i = 0; i < 24; i++) { regexString = regexString + numberRegex; } Regex regex = new Regex(regexString.Trim()); MatchCollection mc = regex.Matches(currentLine); foreach (Match m in mc) { GrannyBoneInfo boneInfo = new GrannyBoneInfo(); GrannyTransformInfo transformInfo = new GrannyTransformInfo(); //int boneindex = NumberUtils.parseInt(m.Groups[1].Value.Trim()); string boneName = m.Groups[2].Value; int parentIndex = NumberUtils.parseInt(m.Groups[3].Value.Trim()); float[] position = new float[3]; position[0] = NumberUtils.parseFloat(m.Groups[4].Value.Trim()); position[1] = NumberUtils.parseFloat(m.Groups[5].Value.Trim()); position[2] = NumberUtils.parseFloat(m.Groups[6].Value.Trim()); float[] orientation = new float[4]; orientation[0] = NumberUtils.parseFloat(m.Groups[7].Value.Trim()); orientation[1] = NumberUtils.parseFloat(m.Groups[8].Value.Trim()); orientation[2] = NumberUtils.parseFloat(m.Groups[9].Value.Trim()); orientation[3] = NumberUtils.parseFloat(m.Groups[10].Value.Trim()); float[] scaleShear = new float[9]; scaleShear[0] = 1.0f; scaleShear[1] = 0.0f; scaleShear[2] = 0.0f; scaleShear[3] = 0.0f; scaleShear[4] = 1.0f; scaleShear[5] = 0.0f; scaleShear[6] = 0.0f; scaleShear[7] = 0.0f; scaleShear[8] = 1.0f; float[] invWorld = new float[16]; for (int j = 0; j < 16; j++) { invWorld[j] = NumberUtils.parseFloat(m.Groups[j + 11].Value.Trim()); } bool hasPosition = true; bool hasOrientation = true; int flags = 0; if (NumberUtils.almostEquals(position[0], 0.0f, 4) && NumberUtils.almostEquals(position[1], 0.0f, 4) && NumberUtils.almostEquals(position[2], 0.0f, 4)) { hasPosition = false; } if (NumberUtils.almostEquals(orientation[0], 0.0f, 5) && NumberUtils.almostEquals(orientation[1], 0.0f, 5) && NumberUtils.almostEquals(orientation[2], 0.0f, 5) && NumberUtils.almostEquals(orientation[3], 1.0f, 5)) { hasOrientation = false; } if (hasPosition) { flags = flags + 1; } if (hasOrientation) { flags = flags + 2; } transformInfo.flags = flags; transformInfo.position = position; transformInfo.orientation = orientation; transformInfo.scaleShear = scaleShear; boneInfo.name = boneName; boneInfo.parentIndex = parentIndex; boneInfo.localTransform = transformInfo; boneInfo.inverseWorldTransform = invWorld; boneInfo.LODError = 0; skeletonBones.Add(boneInfo); } } } skeletonInfo.bones = skeletonBones; // Read Meshes int numMeshes = NumberUtils.parseInt(currentLine.Replace("meshes:", "")); List <GrannyMeshInfo> meshInfos = new List <GrannyMeshInfo>(); for (int meshId = 0; meshId < numMeshes; meshId++) { string meshName = ""; while (!currentLine.StartsWith("mesh:")) { currentLine = streamReader.ReadLine(); } string regexString = "\"(.+)\""; Regex regex = new Regex(regexString); MatchCollection mc = regex.Matches(currentLine); foreach (Match m in mc) { meshName = m.Groups[1].Value.Replace("#M", ""); } // Read Materials List <string> materialNames = new List <string>(); while (!currentLine.StartsWith("vertices")) { currentLine = streamReader.ReadLine(); if (!currentLine.StartsWith("materials") && !currentLine.StartsWith("vertices")) { mc = regex.Matches(currentLine); foreach (Match m in mc) { string materialName = m.Groups[1].Value; materialNames.Add(materialName); } } } // Read Vertices int unweightedVertexCount = 0; List <GrannyVertexInfo> vertexInfos = new List <GrannyVertexInfo>(); while (!currentLine.StartsWith("triangles")) { currentLine = streamReader.ReadLine(); if (!currentLine.StartsWith("vertices") && !currentLine.StartsWith("triangles")) { regexString = ""; for (int i = 0; i < 34; i++) { regexString = regexString + numberRegex; } regex = new Regex(regexString.Trim()); mc = regex.Matches(currentLine); foreach (Match m in mc) { GrannyVertexInfo vertexInfo = new GrannyVertexInfo(); float[] position = new float[3]; position[0] = NumberUtils.parseFloat(m.Groups[1].Value.Trim()); position[1] = NumberUtils.parseFloat(m.Groups[2].Value.Trim()); position[2] = NumberUtils.parseFloat(m.Groups[3].Value.Trim()); float[] normal = new float[3]; normal[0] = NumberUtils.parseFloat(m.Groups[4].Value.Trim()); normal[1] = NumberUtils.parseFloat(m.Groups[5].Value.Trim()); normal[2] = NumberUtils.parseFloat(m.Groups[6].Value.Trim()); float[] tangent = new float[3]; tangent[0] = NumberUtils.parseFloat(m.Groups[7].Value.Trim()); tangent[1] = NumberUtils.parseFloat(m.Groups[8].Value.Trim()); tangent[2] = NumberUtils.parseFloat(m.Groups[9].Value.Trim()); float[] binormal = new float[3]; binormal[0] = NumberUtils.parseFloat(m.Groups[10].Value.Trim()); binormal[1] = NumberUtils.parseFloat(m.Groups[11].Value.Trim()); binormal[2] = NumberUtils.parseFloat(m.Groups[12].Value.Trim()); float[] uv = new float[2]; uv[0] = NumberUtils.parseFloat(m.Groups[13].Value.Trim()); uv[1] = NumberUtils.parseFloat(m.Groups[14].Value.Trim()); float[] uv2 = new float[2]; uv2[0] = NumberUtils.parseFloat(m.Groups[15].Value.Trim()); uv2[1] = NumberUtils.parseFloat(m.Groups[16].Value.Trim()); float[] uv3 = new float[2]; uv3[0] = NumberUtils.parseFloat(m.Groups[17].Value.Trim()); uv3[1] = NumberUtils.parseFloat(m.Groups[18].Value.Trim()); int[] boneIndices = new int[8]; for (int j = 0; j < 8; j++) { boneIndices[j] = NumberUtils.parseInt(m.Groups[j + 19].Value.Trim()); } int[] boneWeights = new int[8]; for (int j = 0; j < 8; j++) { boneWeights[j] = NumberUtils.parseInt(m.Groups[j + 27].Value.Trim()); } // Assign unweighted vertices to root bone and record count if (boneWeights[0] == -1) { for (int j = 0; j < 8; j++) { boneIndices[j] = 0; } boneWeights[0] = 255; for (int j = 1; j < 8; j++) { boneWeights[j] = 0; } unweightedVertexCount++; } vertexInfo.position = position; vertexInfo.normal = normal; vertexInfo.tangent = tangent; vertexInfo.binormal = binormal; vertexInfo.uv = uv; vertexInfo.uv2 = uv2; vertexInfo.uv3 = uv3; vertexInfo.boneIndices = boneIndices; vertexInfo.boneWeights = boneWeights; vertexInfos.Add(vertexInfo); } } } if (unweightedVertexCount > 0 && vertexFormat == 0) { MessageBox.Show(unweightedVertexCount + " unweighted vertices have been assigned to root bone.", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Hand); } // Read Triangles List <int[]> triangles = new List <int[]>(); while (!currentLine.StartsWith("mesh") && !currentLine.StartsWith("end") && !currentLine.StartsWith("skeleton")) { currentLine = streamReader.ReadLine(); if (!currentLine.StartsWith("mesh") && !currentLine.StartsWith("end")) { regexString = ""; for (int i = 0; i < 4; i++) { regexString = regexString + "([-+]?[0-9]+\\.?[0-9]*) "; } regex = new Regex(regexString.Trim()); mc = regex.Matches(currentLine); foreach (Match m in mc) { int[] triangle = new int[4]; triangle[0] = NumberUtils.parseInt(m.Groups[1].Value.Trim()); triangle[1] = NumberUtils.parseInt(m.Groups[2].Value.Trim()); triangle[2] = NumberUtils.parseInt(m.Groups[3].Value.Trim()); triangle[3] = NumberUtils.parseInt(m.Groups[4].Value.Trim()); triangles.Add(triangle); } } } List <PrimaryTopologyGroupInfo> groupInfos = new List <PrimaryTopologyGroupInfo>(); int maxMaterialIndex = 0; int groupIndexStart = 0; int triIndex; for (triIndex = 0; triIndex < triangles.Count; triIndex++) { int[] triangle = triangles[triIndex]; int triMaterialIndex = triangle[3]; if (triMaterialIndex > maxMaterialIndex) { groupInfos.Add(new PrimaryTopologyGroupInfo(maxMaterialIndex, groupIndexStart, triIndex - groupIndexStart)); maxMaterialIndex = triMaterialIndex; groupIndexStart = triIndex; } } groupInfos.Add(new PrimaryTopologyGroupInfo(maxMaterialIndex, groupIndexStart, triIndex - groupIndexStart)); GrannyMeshInfo meshInfo = new GrannyMeshInfo(); meshInfo.name = meshName; meshInfo.vertices = vertexInfos; meshInfo.triangles = triangles; meshInfo.primaryTopologyGroupInfos = groupInfos; meshInfo.materialBindingNames = materialNames; meshInfos.Add(meshInfo); } modelInfo.skeleton = skeletonInfo; modelInfo.meshBindings = meshInfos; modelInfos.Add(modelInfo); } streamReader.Close(); return(modelInfos); }