private bool CreateRenderData(Node node) { var nativeShape = m_tree.GetShape(node.Uuid); var renderData = nativeShape.getRenderData(); if (renderData == null || !renderData.getShouldRender()) { return(false); } var nativeGeometry = m_tree.GetGeometry(node.Parent.Uuid); var shape = node.GameObject.GetComponent <AGXUnity.Collide.Shape>(); var toWorld = nativeGeometry.getTransform(); var toLocal = shape.transform.worldToLocalMatrix; var meshes = new Mesh[] { }; if (renderData.getVertexArray().Count > UInt16.MaxValue) { Debug.LogWarning("Render data contains more than " + UInt16.MaxValue + " vertices. Splitting it into smaller meshes."); var splitter = MeshSplitter.Split(renderData.getVertexArray(), renderData.getIndexArray(), v => toLocal.MultiplyPoint3x4(toWorld.preMult(v).ToHandedVector3())); meshes = splitter.Meshes; for (int i = 0; i < meshes.Length; ++i) { meshes[i].name = shape.name + "_Visual_Mesh_" + i.ToString(); } } else { var mesh = new Mesh(); mesh.name = shape.name + "_Visual_Mesh"; // Assigning and converting vertices. // Note: RenderData vertices assumed to be given in geometry coordinates. mesh.SetVertices((from v in renderData.getVertexArray() select toLocal.MultiplyPoint3x4(toWorld.preMult(v).ToHandedVector3())).ToList()); // Assigning and converting colors. mesh.SetColors((from c in renderData.getColorArray() select c.ToColor()).ToList()); // Unsure about this one. mesh.SetUVs(0, (from uv in renderData.getTexCoordArray() select uv.ToVector2()).ToList()); // Converting counter clockwise -> clockwise. var triangles = new List <int>(); var indexArray = renderData.getIndexArray(); for (int i = 0; i < indexArray.Count; i += 3) { triangles.Add(Convert.ToInt32(indexArray[i + 0])); triangles.Add(Convert.ToInt32(indexArray[i + 2])); triangles.Add(Convert.ToInt32(indexArray[i + 1])); } mesh.SetTriangles(triangles, 0, false); mesh.RecalculateBounds(); mesh.RecalculateNormals(); mesh.RecalculateTangents(); meshes = new Mesh[] { mesh }; } var shader = Shader.Find("Standard") ?? Shader.Find("Diffuse"); if (shader == null) { Debug.LogError("Unable to find standard shaders."); } var renderMaterial = renderData.getRenderMaterial(); var material = new Material(shader); material.name = shape.name + "_Visual_Material"; if (renderMaterial.hasDiffuseColor()) { var color = renderMaterial.getDiffuseColor().ToColor(); color.a = 1.0f - renderMaterial.getTransparency(); material.SetVector("_Color", color); } if (renderMaterial.hasEmissiveColor()) { material.SetVector("_EmissionColor", renderMaterial.getEmissiveColor().ToColor()); } material.SetFloat("_Metallic", 0.3f); material.SetFloat("_Glossiness", 0.8f); if (renderMaterial.getTransparency() > 0.0f) { material.SetBlendMode(BlendMode.Transparent); } material = AddOrReplaceAsset(material, node, AGXUnity.IO.AssetType.Material); foreach (var mesh in meshes) { AddOrReplaceAsset(mesh, node, AGXUnity.IO.AssetType.RenderMesh); } var shapeVisual = ShapeVisual.Find(shape); if (shapeVisual != null) { // Verify so that the meshes matches the current configuration? } else { ShapeVisual.CreateRenderData(shape, meshes, material); } return(true); }
private bool CreateShape(Node node) { var nativeGeometry = m_tree.GetGeometry(node.Parent.Uuid); var nativeShape = m_tree.GetShape(node.Uuid); var nativeShapeType = (agxCollide.Shape.Type)nativeShape.getType(); if (nativeShapeType == agxCollide.Shape.Type.BOX) { node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Box>().HalfExtents = nativeShape.asBox().getHalfExtents().ToVector3(); } else if (nativeShapeType == agxCollide.Shape.Type.CYLINDER) { var cylinder = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Cylinder>(); cylinder.Radius = Convert.ToSingle(nativeShape.asCylinder().getRadius()); cylinder.Height = Convert.ToSingle(nativeShape.asCylinder().getHeight()); } else if (nativeShapeType == agxCollide.Shape.Type.CAPSULE) { var capsule = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Capsule>(); capsule.Radius = Convert.ToSingle(nativeShape.asCapsule().getRadius()); capsule.Height = Convert.ToSingle(nativeShape.asCapsule().getHeight()); } else if (nativeShapeType == agxCollide.Shape.Type.SPHERE) { var sphere = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Sphere>(); sphere.Radius = Convert.ToSingle(nativeShape.asSphere().getRadius()); } else if (nativeShapeType == agxCollide.Shape.Type.CONVEX || nativeShapeType == agxCollide.Shape.Type.TRIMESH || nativeShapeType == agxCollide.Shape.Type.HEIGHT_FIELD) { var mesh = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Mesh>(); var collisionData = nativeShape.asMesh().getMeshData(); var nativeToWorld = nativeShape.getTransform(); var meshToLocal = mesh.transform.worldToLocalMatrix; if (collisionData.getVertices().Count > UInt16.MaxValue) { var nativeVertices = collisionData.getVertices(); var nativeIndicies = collisionData.getIndices(); var splitter = MeshSplitter.Split(nativeVertices, nativeIndicies, v => meshToLocal.MultiplyPoint3x4(nativeToWorld.preMult(v).ToHandedVector3())); var subMeshes = splitter.Meshes; for (int i = 0; i < subMeshes.Length; ++i) { subMeshes[i].name = "Mesh_" + mesh.name + (i == 0 ? "" : "_Sub_" + i.ToString()); mesh.AddSourceObject(AddOrReplaceAsset(subMeshes[i], node, AGXUnity.IO.AssetType.CollisionMesh)); } } else { var source = new Mesh(); source.name = "Mesh_" + mesh.name; source.SetVertices((from v in collisionData.getVertices() select meshToLocal.MultiplyPoint3x4(nativeToWorld.preMult(v).ToHandedVector3())).ToList()); // Converting counter clockwise -> clockwise. var triangles = new List <int>(); var indexArray = collisionData.getIndices(); triangles.Capacity = indexArray.Count; for (int i = 0; i < indexArray.Count; i += 3) { triangles.Add(Convert.ToInt32(indexArray[i + 0])); triangles.Add(Convert.ToInt32(indexArray[i + 2])); triangles.Add(Convert.ToInt32(indexArray[i + 1])); } source.SetTriangles(triangles, 0, false); source.RecalculateBounds(); source.RecalculateNormals(); source.RecalculateTangents(); source = AddOrReplaceAsset(source, node, AGXUnity.IO.AssetType.CollisionMesh); mesh.SetSourceObject(source); } } else { Debug.LogWarning("Unsupported shape type: " + nativeShapeType); return(false); } var shape = node.GameObject.GetComponent <AGXUnity.Collide.Shape>(); // Is the geometry enabled? shape.gameObject.SetActive(nativeGeometry.isEnabled()); if (nativeGeometry.getMaterial() != null) { var shapeMaterial = m_tree.GetNode(nativeGeometry.getMaterial().getUuid()).Asset as ShapeMaterial; if (shapeMaterial == null) { Debug.LogWarning("Shape material from geometry: " + nativeGeometry.getName() + " isn't found in UUID database."); } shape.Material = shapeMaterial; } shape.CollisionsEnabled = nativeGeometry.getEnableCollisions(); // Groups referenced in geometry node. var groups = node.Parent.GetReferences(Node.NodeType.GroupId); if (groups.Length > 0) { var groupsComponent = shape.gameObject.GetOrCreateComponent <CollisionGroups>(); foreach (var group in groups) { if (group.Object is string) { groupsComponent.AddGroup(group.Object as string, false); } } } CreateRenderData(node); return(true); }
private bool CreateShape(Node node) { var nativeGeometry = m_tree.GetGeometry(node.Parent.Uuid); var nativeShape = m_tree.GetShape(node.Uuid); var nativeShapeType = (agxCollide.Shape.Type)nativeShape.getType(); if (nativeShapeType == agxCollide.Shape.Type.BOX) { node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Box>().HalfExtents = nativeShape.asBox().getHalfExtents().ToVector3(); } else if (nativeShapeType == agxCollide.Shape.Type.CYLINDER) { var cylinder = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Cylinder>(); cylinder.Radius = Convert.ToSingle(nativeShape.asCylinder().getRadius()); cylinder.Height = Convert.ToSingle(nativeShape.asCylinder().getHeight()); } else if (nativeShapeType == agxCollide.Shape.Type.HOLLOW_CYLINDER) { var hollowCylinder = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.HollowCylinder>(); hollowCylinder.Thickness = Convert.ToSingle(nativeShape.asHollowCylinder().getThickness()); hollowCylinder.Radius = Convert.ToSingle(nativeShape.asHollowCylinder().getOuterRadius()); hollowCylinder.Height = Convert.ToSingle(nativeShape.asHollowCylinder().getHeight()); } else if (nativeShapeType == agxCollide.Shape.Type.CONE) { var cone = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Cone>(); cone.BottomRadius = Convert.ToSingle(nativeShape.asCone().getBottomRadius()); cone.TopRadius = Convert.ToSingle(nativeShape.asCone().getTopRadius()); cone.Height = Convert.ToSingle(nativeShape.asCone().getHeight()); } else if (nativeShapeType == agxCollide.Shape.Type.HOLLOW_CONE) { var hollowCone = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.HollowCone>(); hollowCone.Thickness = Convert.ToSingle(nativeShape.asHollowCone().getThickness()); hollowCone.BottomRadius = Convert.ToSingle(nativeShape.asHollowCone().getBottomOuterRadius()); hollowCone.TopRadius = Convert.ToSingle(nativeShape.asHollowCone().getTopOuterRadius()); hollowCone.Height = Convert.ToSingle(nativeShape.asHollowCone().getHeight()); } else if (nativeShapeType == agxCollide.Shape.Type.CAPSULE) { var capsule = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Capsule>(); capsule.Radius = Convert.ToSingle(nativeShape.asCapsule().getRadius()); capsule.Height = Convert.ToSingle(nativeShape.asCapsule().getHeight()); } else if (nativeShapeType == agxCollide.Shape.Type.SPHERE) { var sphere = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Sphere>(); sphere.Radius = Convert.ToSingle(nativeShape.asSphere().getRadius()); } else if (nativeShapeType == agxCollide.Shape.Type.CONVEX || nativeShapeType == agxCollide.Shape.Type.TRIMESH || nativeShapeType == agxCollide.Shape.Type.HEIGHT_FIELD) { var mesh = node.GameObject.GetOrCreateComponent <AGXUnity.Collide.Mesh>(); var collisionData = nativeShape.asMesh().getMeshData(); var nativeToWorld = nativeShape.getTransform(); var meshToLocal = mesh.transform.worldToLocalMatrix; var sourceObjects = mesh.SourceObjects; var meshes = MeshSplitter.Split(collisionData.getVertices(), collisionData.getIndices(), v => meshToLocal.MultiplyPoint3x4(nativeToWorld.preMult(v).ToHandedVector3()), UInt16.MaxValue).Meshes; // Clearing previous sources. mesh.SetSourceObject(null); for (int i = 0; i < meshes.Length; ++i) { var source = FileInfo.ObjectDb.GetOrCreateAsset(i < sourceObjects.Length ? sourceObjects[i] : null, $"Mesh_{mesh.name}{(meshes.Length > 1 ? $"_{i}" : "")}", m => { m.Clear(); EditorUtility.CopySerialized(meshes[i], m); }); mesh.AddSourceObject(source); } } else { Debug.LogWarning("Unsupported shape type: " + nativeShapeType); return(false); } var shape = node.GameObject.GetComponent <AGXUnity.Collide.Shape>(); shape.gameObject.SetActive(nativeGeometry.isEnabled()); shape.IsSensor = nativeGeometry.isSensor(); shape.Material = RestoreShapeMaterial(shape.Material, nativeGeometry.getMaterial()); shape.CollisionsEnabled = nativeGeometry.getEnableCollisions(); // Groups referenced in geometry node. var groups = node.Parent.GetReferences(Node.NodeType.GroupId); if (groups.Length > 0) { var groupsComponent = shape.gameObject.GetOrCreateComponent <CollisionGroups>(); foreach (var group in groups) { if (group.Object is string) { groupsComponent.AddGroup(group.Object as string, false); } } } CreateRenderData(node, shape); return(true); }
private bool CreateRenderData(Node node, AGXUnity.Collide.Shape shape) { if (shape == null) { return(false); } var nativeShape = m_tree.GetShape(node.Uuid); var nativeRenderData = nativeShape.getRenderData(); var shapeVisual = ShapeVisual.Find(shape); if (nativeRenderData == null || !nativeRenderData.getShouldRender()) { if (shapeVisual != null) { UnityEngine.Object.DestroyImmediate(shapeVisual.gameObject); EditorUtility.SetDirty(FileInfo.PrefabInstance); } return(false); } var currentMeshes = shapeVisual == null ? new Mesh[] {} : (from proxy in shapeVisual.GetComponentsInChildren <OnSelectionProxy>() where proxy.Component == shape && proxy.GetComponent <MeshFilter>() != null && proxy.GetComponent <MeshFilter>().sharedMesh != null select proxy.GetComponent <MeshFilter>().sharedMesh).ToArray(); var currentMaterials = shapeVisual == null ? new Material[] { } : (from proxy in shapeVisual.GetComponentsInChildren <OnSelectionProxy>() where proxy.Component == shape && proxy.GetComponent <MeshRenderer>() != null && proxy.GetComponent <MeshRenderer>().sharedMaterial != null select proxy.GetComponent <MeshRenderer>().sharedMaterial).ToArray(); var nativeGeometry = m_tree.GetGeometry(node.Parent.Uuid); var toWorld = nativeGeometry.getTransform(); var toLocal = shape.transform.worldToLocalMatrix; Mesh[] meshes = MeshSplitter.Split(nativeRenderData.getVertexArray(), nativeRenderData.getIndexArray(), nativeRenderData.getTexCoordArray(), v => toLocal.MultiplyPoint3x4(toWorld.preMult(v).ToHandedVector3())).Meshes; // Initial import with currentMeshes.Length == 0 and shape mesh source // matches render data - use shape mesh sources instead. if (shape is AGXUnity.Collide.Mesh && currentMeshes.Length == 0 && meshes.Length == (shape as AGXUnity.Collide.Mesh).SourceObjects.Length) { var shapeMesh = shape as AGXUnity.Collide.Mesh; var matching = true; for (int i = 0; matching && i < meshes.Length; ++i) { matching = meshes[i].vertexCount == shapeMesh.SourceObjects[i].vertexCount; if (!matching) { continue; } var v1 = meshes[i].vertices; var v2 = shapeMesh.SourceObjects[i].vertices; for (int j = 0; matching && j < v1.Length; ++j) { matching = AGXUnity.Utils.Math.Approximately(v1[j], v2[j], 1.0E-5f); } } if (matching) { currentMeshes = new Mesh[meshes.Length]; for (int i = 0; i < meshes.Length; ++i) { shapeMesh.SourceObjects[i].SetUVs(0, meshes[i].uv.ToList()); currentMeshes[i] = meshes[i] = shapeMesh.SourceObjects[i]; } } } // No structural changes from previous read visuals. if (shapeVisual != null && currentMeshes.Length == meshes.Length && currentMaterials.Length == meshes.Length) { for (int i = 0; i < meshes.Length; ++i) { // Meshes and materials are already referenced so we don't have to // assign them again to the ShapeVisuals. FileInfo.ObjectDb.GetOrCreateAsset(currentMeshes[i], $"{shape.name}_Visual_Mesh_{i}", m => { m.Clear(); EditorUtility.CopySerialized(meshes[i], m); }); RestoreRenderMaterial(currentMaterials[i], $"{shape.name}_Visual_Material", nativeRenderData.getRenderMaterial()); EditorUtility.SetDirty(shapeVisual); } } else { if (shapeVisual != null) { UnityEngine.Object.DestroyImmediate(shapeVisual.gameObject, true); EditorUtility.SetDirty(FileInfo.PrefabInstance); shapeVisual = null; } var material = RestoreRenderMaterial(currentMaterials.Length > 0 ? currentMaterials[0] : null, $"{shape.name}_Visual_Material", nativeRenderData.getRenderMaterial()); for (int i = 0; i < meshes.Length; ++i) { meshes[i] = FileInfo.ObjectDb.GetOrCreateAsset(i < currentMeshes.Length ? currentMeshes[i] : null, $"{shape.name}_Visual_Mesh_{i}", m => { m.Clear(); EditorUtility.CopySerialized(meshes[i], m); }); } ShapeVisual.CreateRenderData(shape, meshes, material); } return(true); }
public UnityEngine.Mesh[] CreateRenderMeshes(Transform transform) { // This will convert to left handed and change triangle order. return(MeshSplitter.Split(Vertices, Indices).Meshes); }