void AttachMirrorPlane(BabylonTexture babylonTexture, NovaObject novaObject) { // Mirror plane int f1, f2, f3; if (novaObject.Is32bits) { f1 = novaObject.Indices32[2]; f2 = novaObject.Indices32[1]; f3 = novaObject.Indices32[0]; } else { f1 = novaObject.Indices[2]; f2 = novaObject.Indices[1]; f3 = novaObject.Indices[0]; } Vector3 a = novaObject.PositionOnlyVertices[f1]; Vector3 b = novaObject.PositionOnlyVertices[f2]; Vector3 c = novaObject.PositionOnlyVertices[f3]; var mainPlane = new Plane(a, b, c); Matrix matrix = Matrix.Invert(novaObject.WorldMatrix); matrix = Matrix.Transpose(matrix); Plane plane = Plane.Transform(mainPlane, matrix); babylonTexture.mirrorPlane = new[] { plane.Normal.X, plane.Normal.Y, plane.Normal.Z, plane.D }; }
void AttachMirrorPlane(BabylonTexture babylonTexture, NovaObject novaObject) { // Mirror plane int f1, f2, f3; if (novaObject.Is32bits) { f1 = novaObject.Indices32[2]; f2 = novaObject.Indices32[1]; f3 = novaObject.Indices32[0]; } else { f1 = novaObject.Indices[2]; f2 = novaObject.Indices[1]; f3 = novaObject.Indices[0]; } Vector3 a = novaObject.PositionOnlyVertices[f1]; Vector3 b = novaObject.PositionOnlyVertices[f2]; Vector3 c = novaObject.PositionOnlyVertices[f3]; var mainPlane = new Plane(a, b, c); Matrix matrix = Matrix.Invert(novaObject.WorldMatrix); matrix = Matrix.Transpose(matrix); Plane plane = Plane.Transform(mainPlane, matrix); babylonTexture.mirrorPlane = new[] { plane.Normal.X, plane.Normal.Y, plane.Normal.Z, plane.D }; }
private int DumpObjectGeometry(NovaObject novaObject, BabylonMesh babylonMesh, int startIndex, int endIndex) { var verticesIndices = new int[novaObject.VerticesCount]; for (var index = 0; index < verticesIndices.Length; index++) { verticesIndices[index] = -1; } // Vertices var transformMatrix = Matrix.Identity;//.Scaling(novaObject.Scaling) * novaObject.LocalMatrix; var indicesList = new List<int>(); NovaCustomVertexFormat.GlobalVector3[] vertices = novaObject.InternalMesh.LockVertexBuffer<NovaCustomVertexFormat.GlobalVector3>(NovaLock.ReadOnly, novaObject.VerticesCount); // Faces INovaDataStream data = novaObject.InternalMesh.LockIndexBuffer(NovaLock.ReadOnly); int[] indices; if (novaObject.Is32bits) { indices = data.Read<int>(novaObject.FacesCount * 3 * 4); } else { indices = (data.Read<ushort>(novaObject.FacesCount * 3 * 4)).Select(i => (int)i).ToArray(); } var positions = new List<float>(); var normals = new List<float>(); var uvs = new List<float>(); var uvs2 = new List<float>(); var colors = new List<float>(); int exportedVerticesCount = 0; for (var index = 0; index < novaObject.FacesCount; index++) { var v0 = indices[index * 3]; var v1 = indices[index * 3 + 1]; var v2 = indices[index * 3 + 2]; if (v0 < startIndex || v1 < startIndex || v2 < startIndex) { continue; } if (v0 >= startIndex && v0 < endIndex || v1 >= startIndex && v1 < endIndex || v2 >= startIndex && v2 < endIndex) { if (verticesIndices[v0] == -1) { verticesIndices[v0] = exportedVerticesCount++; DumpVertex(vertices[v0], positions, normals, uvs, uvs2, colors, transformMatrix, novaObject); } if (verticesIndices[v1] == -1) { verticesIndices[v1] = exportedVerticesCount++; DumpVertex(vertices[v1], positions, normals, uvs, uvs2, colors, transformMatrix, novaObject); } if (verticesIndices[v2] == -1) { verticesIndices[v2] = exportedVerticesCount++; DumpVertex(vertices[v2], positions, normals, uvs, uvs2, colors, transformMatrix, novaObject); } indicesList.Add(verticesIndices[v0]); indicesList.Add(verticesIndices[v1]); indicesList.Add(verticesIndices[v2]); } } if (positions.Count > 0) { babylonMesh.positions = positions.ToArray(); } if (normals.Count > 0) { babylonMesh.normals = normals.ToArray(); } if (uvs.Count > 0) { babylonMesh.uvs = uvs.ToArray(); } if (uvs2.Count > 0) { babylonMesh.uvs2 = uvs2.ToArray(); } if (colors.Count > 0) { babylonMesh.colors = colors.ToArray(); } babylonMesh.indices = indicesList.ToArray(); // Invert normal order for (var index = 0; index < babylonMesh.indices.Length; index += 3) { var temp = babylonMesh.indices[index]; babylonMesh.indices[index] = babylonMesh.indices[index + 2]; babylonMesh.indices[index + 2] = temp; } novaObject.InternalMesh.UnlockIndexBuffer(); novaObject.InternalMesh.UnlockVertexBuffer(); return exportedVerticesCount; }
private void DumpVertex(NovaCustomVertexFormat.GlobalVector3 vertex, List<float> positions, List<float> normals, List<float> uvs, List<float> uvs2, List<float> colors, Matrix transformMatrix, NovaObject novaObject) { var position = Vector3.TransformCoordinate(vertex.Position, transformMatrix); var normal = Vector3.TransformNormal(vertex.Normal, transformMatrix); positions.Add(position.X); positions.Add(position.Y); positions.Add(position.Z); normals.Add(normal.X); normals.Add(normal.Y); normals.Add(normal.Z); uvs.Add(vertex.Tu); uvs.Add(vertex.Tv); if (novaObject.Use2TextureCoordinatesForMeshCreation) { uvs2.Add(vertex.Tu2); uvs2.Add(vertex.Tv2); } if (novaObject.VertexPaint) { var color = RGBAColor.FromArgb((int)vertex.Color); colors.Add(color.Red); colors.Add(color.Green); colors.Add(color.Blue); } }
void DumpObject(NovaObject novaObject, BabylonScene babylonScene, NovaScene scene, int startIndex, int endIndex, string nameIndex = "") { var babylonMesh = new BabylonMesh(); babylonScene.MeshesList.Add(babylonMesh); babylonMesh.name = novaObject.Name + nameIndex; babylonMesh.id = novaObject.ID.ToString(); babylonMesh.materialId = novaObject.Material == null ? "" : novaObject.Material.ID.ToString(); babylonMesh.parentId = novaObject.ParentEntity == null ? "" : novaObject.ParentEntity.ID.ToString(); babylonMesh.isEnabled = novaObject.Enabled; babylonMesh.isVisible = novaObject.Renderable; babylonMesh.visibility = novaObject.Visibility; babylonMesh.checkCollisions = novaObject.CheckCollisions; babylonMesh.receiveShadows = novaObject.ReceiveShadows; babylonMesh.infiniteDistance = novaObject.InfiniteDistance; if (novaObject.Billboard) { babylonMesh.billboardMode |= (novaObject.BillboardX ? 1 : 0); babylonMesh.billboardMode |= (novaObject.BillboardY ? 2 : 0); babylonMesh.billboardMode |= (novaObject.BillboardZ ? 4 : 0); } if (novaObject.ParticleSystem != null) { particleSystemsToExport.Add(novaObject.ParticleSystem); } // Mirror if (novaObject.IsMirror && novaObject.Material != null) { mirrorsMaterials.Add(novaObject.Material, novaObject); } // World babylonMesh.position = novaObject.Position.ToArray(); babylonMesh.rotation = novaObject.Rotation.ToArray(); babylonMesh.localMatrix = (Matrix.Scaling(novaObject.Scaling) * novaObject.LocalMatrix).ToArray(); // Animations var animations = new List<BabylonAnimation>(); DumpInterpolator("Visibility animation", "visibility", novaObject.VisibilityInterpolator, scene, animations); // Position if (!DumpInterpolator("Position animation", "position", novaObject.PositionInterpolator, scene, animations)) { DumpInterpolator("PositionX animation", "position.x", novaObject.PositionXInterpolator, scene, animations); DumpInterpolator("PositionY animation", "position.y", novaObject.PositionYInterpolator, scene, animations); DumpInterpolator("PositionZ animation", "position.z", novaObject.PositionZInterpolator, scene, animations); } // Rotation if (!DumpInterpolator("Rotation animation", "rotationQuaternion", novaObject.RotationInterpolator, scene, animations)) { DumpInterpolator("RotationX animation", "rotation.x", novaObject.RotationXInterpolator, scene, animations, -novaObject.Determinant); DumpInterpolator("RotationY animation", "rotation.y", novaObject.RotationYInterpolator, scene, animations, -novaObject.Determinant); DumpInterpolator("RotationZ animation", "rotation.z", novaObject.RotationZInterpolator, scene, animations, -novaObject.Determinant); } else { babylonMesh.localMatrix = Matrix.Identity.ToArray(); babylonMesh.scaling = novaObject.Scaling.ToArray(); } // Scaling if (!DumpInterpolator("Scaling animation", "scaling", novaObject.ScalingInterpolator, scene, animations)) { DumpInterpolator("ScalingX animation", "scaling.x", novaObject.ScalingXInterpolator, scene, animations); DumpInterpolator("ScalingY animation", "scaling.y", novaObject.ScalingYInterpolator, scene, animations); DumpInterpolator("ScalingZ animation", "scaling.z", novaObject.ScalingZInterpolator, scene, animations); } else { babylonMesh.localMatrix = novaObject.LocalMatrix.ToArray(); babylonMesh.scaling = novaObject.Scaling.ToArray(); } babylonMesh.animations = animations.ToArray(); babylonMesh.autoAnimate = novaObject.AutoAnimate; if (novaObject.AutoAnimate) { babylonMesh.autoAnimateFrom = novaObject.AnimationStartKey; if (novaObject.AnimationEndKey == -1) { babylonMesh.autoAnimateTo = scene.AnimationKeyMax / scene.AnimationKeyStep; babylonMesh.autoAnimateLoop = true; } else { babylonMesh.autoAnimateTo = novaObject.AnimationEndKey; } } // Vertices & faces var exportedVerticesCount = DumpObjectGeometry(novaObject, babylonMesh, startIndex, endIndex); // Subobjects var subMeshes = new List<BabylonSubMesh>(); if (novaObject.Is32bits) { var subMesh = new BabylonSubMesh(); subMesh.materialIndex = 0; subMesh.verticesStart = 0; subMesh.verticesCount = exportedVerticesCount; subMesh.indexStart = 0; subMesh.indexCount = babylonMesh.indices.Length; subMeshes.Add(subMesh); } else { foreach (NovaSubObject subObject in novaObject.SubObjects) { var subMesh = new BabylonSubMesh(); subMesh.materialIndex = subObject.AttributeRange.AttributeId; subMesh.verticesStart = subObject.AttributeRange.VertexStart; subMesh.verticesCount = subObject.AttributeRange.VertexCount; subMesh.indexStart = subObject.AttributeRange.FaceStart * 3; subMesh.indexCount = subObject.AttributeRange.FaceCount * 3; subMeshes.Add(subMesh); } } babylonMesh.subMeshes = subMeshes.ToArray(); if (novaObject.Material != null) { if (!materialsToExport.Contains(novaObject.Material)) { materialsToExport.Add(novaObject.Material); var multiMat = novaObject.Material as NovaMultiMaterial; if (multiMat != null) { foreach (var mat in multiMat.Materials) { if (!materialsToExport.Contains(mat)) { materialsToExport.Add(mat); } } } } } }
private int DumpObjectGeometry(NovaObject novaObject, BabylonMesh babylonMesh, int startIndex, int endIndex) { var verticesIndices = new int[novaObject.VerticesCount]; for (var index = 0; index < verticesIndices.Length; index++) { verticesIndices[index] = -1; } // Vertices var transformMatrix = Matrix.Identity;//.Scaling(novaObject.Scaling) * novaObject.LocalMatrix; var indicesList = new List <int>(); NovaCustomVertexFormat.GlobalVector3[] vertices = novaObject.InternalMesh.LockVertexBuffer <NovaCustomVertexFormat.GlobalVector3>(NovaLock.ReadOnly, novaObject.VerticesCount); // Faces INovaDataStream data = novaObject.InternalMesh.LockIndexBuffer(NovaLock.ReadOnly); int[] indices; if (novaObject.Is32bits) { indices = data.Read <int>(novaObject.FacesCount * 3 * 4); } else { indices = (data.Read <ushort>(novaObject.FacesCount * 3 * 4)).Select(i => (int)i).ToArray(); } var positions = new List <float>(); var normals = new List <float>(); var uvs = new List <float>(); var uvs2 = new List <float>(); var colors = new List <float>(); int exportedVerticesCount = 0; for (var index = 0; index < novaObject.FacesCount; index++) { var v0 = indices[index * 3]; var v1 = indices[index * 3 + 1]; var v2 = indices[index * 3 + 2]; if (v0 < startIndex || v1 < startIndex || v2 < startIndex) { continue; } if (v0 >= startIndex && v0 < endIndex || v1 >= startIndex && v1 < endIndex || v2 >= startIndex && v2 < endIndex) { if (verticesIndices[v0] == -1) { verticesIndices[v0] = exportedVerticesCount++; DumpVertex(vertices[v0], positions, normals, uvs, uvs2, colors, transformMatrix, novaObject); } if (verticesIndices[v1] == -1) { verticesIndices[v1] = exportedVerticesCount++; DumpVertex(vertices[v1], positions, normals, uvs, uvs2, colors, transformMatrix, novaObject); } if (verticesIndices[v2] == -1) { verticesIndices[v2] = exportedVerticesCount++; DumpVertex(vertices[v2], positions, normals, uvs, uvs2, colors, transformMatrix, novaObject); } indicesList.Add(verticesIndices[v0]); indicesList.Add(verticesIndices[v1]); indicesList.Add(verticesIndices[v2]); } } if (positions.Count > 0) { babylonMesh.positions = positions.ToArray(); } if (normals.Count > 0) { babylonMesh.normals = normals.ToArray(); } if (uvs.Count > 0) { babylonMesh.uvs = uvs.ToArray(); } if (uvs2.Count > 0) { babylonMesh.uvs2 = uvs2.ToArray(); } if (colors.Count > 0) { babylonMesh.colors = colors.ToArray(); } babylonMesh.indices = indicesList.ToArray(); // Invert normal order for (var index = 0; index < babylonMesh.indices.Length; index += 3) { var temp = babylonMesh.indices[index]; babylonMesh.indices[index] = babylonMesh.indices[index + 2]; babylonMesh.indices[index + 2] = temp; } novaObject.InternalMesh.UnlockIndexBuffer(); novaObject.InternalMesh.UnlockVertexBuffer(); return(exportedVerticesCount); }
private void DumpVertex(NovaCustomVertexFormat.GlobalVector3 vertex, List <float> positions, List <float> normals, List <float> uvs, List <float> uvs2, List <float> colors, Matrix transformMatrix, NovaObject novaObject) { var position = Vector3.TransformCoordinate(vertex.Position, transformMatrix); var normal = Vector3.TransformNormal(vertex.Normal, transformMatrix); positions.Add(position.X); positions.Add(position.Y); positions.Add(position.Z); normals.Add(normal.X); normals.Add(normal.Y); normals.Add(normal.Z); uvs.Add(vertex.Tu); uvs.Add(vertex.Tv); if (novaObject.Use2TextureCoordinatesForMeshCreation) { uvs2.Add(vertex.Tu2); uvs2.Add(vertex.Tv2); } if (novaObject.VertexPaint) { var color = RGBAColor.FromArgb((int)vertex.Color); colors.Add(color.Red); colors.Add(color.Green); colors.Add(color.Blue); } }
void DumpObject(NovaObject novaObject, BabylonScene babylonScene, NovaScene scene, int startIndex, int endIndex, string nameIndex = "") { var babylonMesh = new BabylonMesh(); babylonScene.MeshesList.Add(babylonMesh); babylonMesh.name = novaObject.Name + nameIndex; babylonMesh.id = novaObject.ID.ToString(); babylonMesh.materialId = novaObject.Material == null ? "" : novaObject.Material.ID.ToString(); babylonMesh.parentId = novaObject.ParentEntity == null ? "" : novaObject.ParentEntity.ID.ToString(); babylonMesh.isEnabled = novaObject.Enabled; babylonMesh.isVisible = novaObject.Renderable; babylonMesh.visibility = novaObject.Visibility; babylonMesh.checkCollisions = novaObject.CheckCollisions; babylonMesh.receiveShadows = novaObject.ReceiveShadows; if (novaObject.Billboard) { babylonMesh.billboardMode |= (novaObject.BillboardX ? 1 : 0); babylonMesh.billboardMode |= (novaObject.BillboardY ? 2 : 0); babylonMesh.billboardMode |= (novaObject.BillboardZ ? 4 : 0); } if (novaObject.ParticleSystem != null) { particleSystemsToExport.Add(novaObject.ParticleSystem); } // Mirror if (novaObject.IsMirror && novaObject.Material != null) { mirrorsMaterials.Add(novaObject.Material, novaObject); } // World babylonMesh.position = novaObject.Position.ToArray(); babylonMesh.rotation = novaObject.Rotation.ToArray(); babylonMesh.localMatrix = (Matrix.Scaling(novaObject.Scaling) * novaObject.LocalMatrix).ToArray(); // Animations var animations = new List <BabylonAnimation>(); DumpInterpolator("Visibility animation", "visibility", novaObject.VisibilityInterpolator, scene, animations); // Position if (!DumpInterpolator("Position animation", "position", novaObject.PositionInterpolator, scene, animations)) { DumpInterpolator("PositionX animation", "position.x", novaObject.PositionXInterpolator, scene, animations); DumpInterpolator("PositionY animation", "position.y", novaObject.PositionYInterpolator, scene, animations); DumpInterpolator("PositionZ animation", "position.z", novaObject.PositionZInterpolator, scene, animations); } // Rotation if (!DumpInterpolator("Rotation animation", "rotationQuaternion", novaObject.RotationInterpolator, scene, animations)) { DumpInterpolator("RotationX animation", "rotation.x", novaObject.RotationXInterpolator, scene, animations, -novaObject.Determinant); DumpInterpolator("RotationY animation", "rotation.y", novaObject.RotationYInterpolator, scene, animations, -novaObject.Determinant); DumpInterpolator("RotationZ animation", "rotation.z", novaObject.RotationZInterpolator, scene, animations, -novaObject.Determinant); } else { babylonMesh.localMatrix = Matrix.Identity.ToArray(); babylonMesh.scaling = novaObject.Scaling.ToArray(); } // Scaling if (!DumpInterpolator("Scaling animation", "scaling", novaObject.ScalingInterpolator, scene, animations)) { DumpInterpolator("ScalingX animation", "scaling.x", novaObject.ScalingXInterpolator, scene, animations); DumpInterpolator("ScalingY animation", "scaling.y", novaObject.ScalingYInterpolator, scene, animations); DumpInterpolator("ScalingZ animation", "scaling.z", novaObject.ScalingZInterpolator, scene, animations); } else { babylonMesh.localMatrix = novaObject.LocalMatrix.ToArray(); babylonMesh.scaling = novaObject.Scaling.ToArray(); } babylonMesh.animations = animations.ToArray(); babylonMesh.autoAnimate = novaObject.AutoAnimate; if (novaObject.AutoAnimate) { babylonMesh.autoAnimateFrom = novaObject.AnimationStartKey; if (novaObject.AnimationEndKey == -1) { babylonMesh.autoAnimateTo = scene.AnimationKeyMax / scene.AnimationKeyStep; babylonMesh.autoAnimateLoop = true; } else { babylonMesh.autoAnimateTo = novaObject.AnimationEndKey; } } // Vertices & faces var exportedVerticesCount = DumpObjectGeometry(novaObject, babylonMesh, startIndex, endIndex); // Subobjects var subMeshes = new List <BabylonSubMesh>(); if (novaObject.Is32bits) { var subMesh = new BabylonSubMesh(); subMesh.materialIndex = 0; subMesh.verticesStart = 0; subMesh.verticesCount = exportedVerticesCount; subMesh.indexStart = 0; subMesh.indexCount = babylonMesh.indices.Length; subMeshes.Add(subMesh); } else { foreach (NovaSubObject subObject in novaObject.SubObjects) { var subMesh = new BabylonSubMesh(); subMesh.materialIndex = subObject.AttributeRange.AttributeId; subMesh.verticesStart = subObject.AttributeRange.VertexStart; subMesh.verticesCount = subObject.AttributeRange.VertexCount; subMesh.indexStart = subObject.AttributeRange.FaceStart * 3; subMesh.indexCount = subObject.AttributeRange.FaceCount * 3; subMeshes.Add(subMesh); } } babylonMesh.subMeshes = subMeshes.ToArray(); if (novaObject.Material != null) { if (!materialsToExport.Contains(novaObject.Material)) { materialsToExport.Add(novaObject.Material); var multiMat = novaObject.Material as NovaMultiMaterial; if (multiMat != null) { foreach (var mat in multiMat.Materials) { if (!materialsToExport.Contains(mat)) { materialsToExport.Add(mat); } } } } } }