private static Transform CreateModelFrom( Core_Voxel.Result.VoxelNode vNode, VoxelData.MaterialData[] materials, Transform parent, Vector3 pivot, ref List <Mesh> meshs, ref Dictionary <Texture2D, Material[]> materialsMap, bool isRig, bool withAvatar, Shader[] shaders, string[] shaderKeywords, Vector2[] shaderRemaps, float modelScale ) { Quaternion rot = vNode.Rotation; Vector3 pivotFixOffset = rot * pivot; Vector3 fixedModelSize = rot * vNode.Size.ToVector3(); pivotFixOffset.Scale(fixedModelSize); Vector3 scaleFix = rot * (0.5f * (Vector3.one - vNode.Scale.ToVector3())); Vector3 fixedMvPos = vNode.Position.ToVector3(); for (int i = 0; i < 3; i++) { fixedMvPos[i] += (Mathf.RoundToInt(fixedModelSize[i]) % 2) * 0.5f * (scaleFix[i] > 0.5f ? -1 : 1); } var root = new GameObject().transform; root.SetParent(parent); root.localRotation = vNode.Rotation; root.localScale = vNode.Scale.ToVector3(); root.gameObject.SetActive(vNode.Active); if (vNode.Model != null) { root.name = !string.IsNullOrEmpty(vNode.Name) ? vNode.Name : GetIndexedName("Model", parent.childCount - 1); // BAS: FIX rotated position fixedModelSize = Util.VectorAbs(fixedModelSize); root.localPosition = (fixedMvPos - 0.5f * fixedModelSize + pivotFixOffset) * modelScale; // Empty Check bool isEmpty = true; var uMesh = vNode.Model; if (uMesh.Count > 0) { for (int i = 0; i < uMesh.Count; i++) { if (uMesh[i].vertexCount > 0) { isEmpty = false; break; } } } if (!isEmpty) { // Add Assets Texture2D texture = vNode.Texture; if (!texture) { texture = new Texture2D(4, 4); } Material[] mats; if (!materialsMap.ContainsKey(texture)) { Dictionary <int, Material> matMap = new Dictionary <int, Material>(); for (int i = 0; i < uMesh.Count; i++) { int matIndex = uMesh.GetMaterialIndexAt(i); Material mat; if (matMap.ContainsKey(matIndex)) { mat = matMap[matIndex]; } else { mat = VoxelData.GetMaterialFrom(materials[matIndex], texture, shaders, shaderKeywords, shaderRemaps); matMap.Add(matIndex, mat); } } mats = new Material[matMap.Count]; foreach (var indexMat in matMap) { mats[indexMat.Key] = indexMat.Value; } materialsMap.Add(texture, mats); } else { mats = materialsMap[texture]; } // Add Mesh To if (uMesh.Count == 1) { var mesh = uMesh[0]; int matIndex = uMesh.GetMaterialIndexAt(0); if (!meshs.Contains(mesh)) { meshs.Add(mesh); } AddMeshTo(mesh, root, mats[matIndex], isRig); } else { for (int i = 0; i < uMesh.Count; i++) { var target = new GameObject("m_" + i.ToString()).transform; target.SetParent(root); target.SetAsLastSibling(); target.localPosition = Vector3.zero; target.localRotation = Quaternion.identity; target.localScale = Vector3.one; var mesh = uMesh[i]; if (!meshs.Contains(mesh)) { meshs.Add(mesh); } int matIndex = uMesh.GetMaterialIndexAt(i); AddMeshTo(mesh, target, mats[matIndex], false); } } } } else if (vNode.Children != null && vNode.Children.Length > 0) { // Sub Objects root.name = !string.IsNullOrEmpty(vNode.Name) ? vNode.Name : "Container"; root.localPosition = vNode.Position.ToVector3() * modelScale; for (int i = 0; i < vNode.Children.Length; i++) { CreateModelFrom(vNode.Children[i], materials, root, pivot, ref meshs, ref materialsMap, isRig, withAvatar, shaders, shaderKeywords, shaderRemaps, modelScale); } } return(root); }
private static Transform CreateModelFrom( Core_Voxel.Result.VoxelNode vNode, Transform parent, Vector3 pivot, ref List <Mesh> meshs, ref Dictionary <Texture2D, Material> materialsMap, bool isRig, bool withAvatar ) { Quaternion rot = vNode.Rotation; Vector3 pivotFixOffset = rot * pivot; Vector3 fixedModelSize = rot * vNode.Size.ToVector3(); pivotFixOffset.Scale(fixedModelSize); Vector3 scaleFix = rot * (0.5f * (Vector3.one - vNode.Scale.ToVector3())); scaleFix.Scale(fixedModelSize); pivotFixOffset -= scaleFix; Vector3 fixedMvPos = vNode.Position.ToVector3(); fixedMvPos.x += Mathf.RoundToInt(fixedModelSize.x % 2f) * 0.5f; fixedMvPos.y += Mathf.RoundToInt(fixedModelSize.y % 2f) * 0.5f; fixedMvPos.z += Mathf.RoundToInt(fixedModelSize.z % 2f) * 0.5f; var root = new GameObject().transform; root.SetParent(parent); root.localRotation = vNode.Rotation; root.localScale = vNode.Scale.ToVector3(); root.gameObject.SetActive(vNode.Active); if (vNode.Model != null) { root.name = !string.IsNullOrEmpty(vNode.Name) ? vNode.Name : GetIndexedName("Model", parent.childCount - 1); root.localPosition = (fixedMvPos - 0.5f * fixedModelSize + pivotFixOffset) * ModelScale; // Empty Check bool isEmpty = true; var uMesh = vNode.Model; if (uMesh.Count > 0) { for (int i = 0; i < uMesh.Count; i++) { if (uMesh[i].vertexCount > 0) { isEmpty = false; break; } } } if (!isEmpty) { // Add Assets Texture2D texture = vNode.Texture; if (!texture) { texture = new Texture2D(4, 4); } Material mat = new Material(TheShader) { mainTexture = texture }; materialsMap.Add(texture, mat); // Add Mesh To if (vNode.Model.Count == 1) { var mesh = vNode.Model[0]; if (!meshs.Contains(mesh)) { meshs.Add(mesh); } AddMeshTo(mesh, root, mat, isRig); } else { for (int i = 0; i < vNode.Model.Count; i++) { var target = new GameObject("m_" + i.ToString()).transform; target.SetParent(root); target.SetAsLastSibling(); target.localPosition = Vector3.zero; target.localRotation = Quaternion.identity; target.localScale = Vector3.one; var mesh = vNode.Model[i]; if (!meshs.Contains(mesh)) { meshs.Add(mesh); } AddMeshTo(mesh, target, mat, false); } } } } else if (vNode.Children != null && vNode.Children.Length > 0) { // Sub Objects root.name = !string.IsNullOrEmpty(vNode.Name) ? vNode.Name : "Container"; root.localPosition = vNode.Position.ToVector3() * ModelScale; for (int i = 0; i < vNode.Children.Length; i++) { CreateModelFrom(vNode.Children[i], root, pivot, ref meshs, ref materialsMap, isRig, withAvatar); } } return(root); }