Exemplo n.º 1
0
        private Node CreateNode(NodeType type, agx.Uuid uuid, bool isRoot)
        {
            Node node = new Node()
            {
                Type = type,
                Uuid = uuid
            };

            if (isRoot)
            {
                if (type == NodeType.Constraint)
                {
                    m_constraintRoot.AddChild(node);
                }
                else if (type == NodeType.Material)
                {
                    m_materialRoot.AddChild(node);
                }
                else if (type == NodeType.ContactMaterial)
                {
                    m_contactMaterialRoot.AddChild(node);
                }
                else if (type == NodeType.Wire)
                {
                    m_wireRoot.AddChild(node);
                }
                else if (type == NodeType.Cable)
                {
                    m_cableRoot.AddChild(node);
                }
                else if (type == NodeType.ObserverFrame)
                {
                    m_observerFrameRoot.AddChild(node);
                }
                else if (m_roots.FindIndex(n => n.Uuid == uuid) >= 0)
                {
                    Debug.LogError("Node already present as root.");
                }
                else
                {
                    m_roots.Add(node);
                }
            }

            m_nodeCache.Add(uuid, node);

            return(node);
        }
Exemplo n.º 2
0
        private T AddOrReplaceAsset <T>(T asset, Node node, AGXUnity.IO.AssetType type)
            where T : UnityEngine.Object
        {
            var existingAsset = AssetDatabase.LoadAssetAtPath <T>(FileInfo.GetAssetPath(asset));

            if (existingAsset == null)
            {
                FileInfo.AddAssetToDataDirectory(asset, type);
                existingAsset = asset;
            }
            else
            {
                EditorUtility.CopySerialized(asset, existingAsset);
            }

            return(existingAsset);
        }
Exemplo n.º 3
0
        private GameObject GetOrCreateGameObject(Node node)
        {
            if (node.GameObject != null)
            {
                return(node.GameObject);
            }

            node.GameObject = FileInfo.ObjectDb.GetGameObject(node.Uuid) ?? new GameObject();
            node.GameObject.GetOrCreateComponent <AGXUnity.IO.Uuid>().Native = node.Uuid;

            // Is it safe to exit if the node has a parent?
            // I.e., the node has been read from an existing prefab.
            if (FileInfo.PrefabInstance.HasChild(node.GameObject))
            {
                return(node.GameObject);
            }

            // Passing parents with null game objects - e.g., shapes
            // has geometry as parent but we're not creating objects
            // for geometries.
            Node localParent = node.Parent;

            while (localParent != null && localParent.GameObject == null)
            {
                localParent = localParent.Parent;
            }

            if (localParent != null)
            {
                localParent.GameObject.AddChild(node.GameObject);
            }
            else
            {
                FileInfo.PrefabInstance.AddChild(node.GameObject);
            }

            return(node.GameObject);
        }
Exemplo n.º 4
0
        private void Parse(agxCollide.Geometry geometry, Node parent)
        {
            var geometryNode = GetOrCreateGeometry(geometry, parent == null);

            if (parent != null)
            {
                parent.AddChild(geometryNode);
            }

            foreach (var shape in geometry.getShapes())
            {
                var shapeNode = GetOrCreateShape(shape.get());
                geometryNode.AddChild(shapeNode);
            }

            if (geometry.getMaterial() != null)
            {
                var materialNode = GetOrCreateMaterial(geometry.getMaterial());
                geometryNode.AddReference(materialNode);
            }

            var groupsCollection = geometry.findGroupIdCollection();

            foreach (var name in groupsCollection.getNames())
            {
                geometryNode.AddReference(new Node()
                {
                    Type = NodeType.GroupId, Object = name
                });
            }
            foreach (var id in groupsCollection.getIds())
            {
                geometryNode.AddReference(new Node()
                {
                    Type = NodeType.GroupId, Object = id.ToString()
                });
            }
        }
Exemplo n.º 5
0
        private bool CreateCable(Node node)
        {
            var nativeCable = m_tree.GetCable(node.Uuid);

            if (nativeCable == null)
            {
                Debug.LogWarning("Unable to find native instance of cable: " + node.GameObject.name +
                                 " (UUID: " + node.Uuid.str() + ")");
                return(false);
            }

            var cable = node.GameObject.GetOrCreateComponent <Cable>();
            var route = cable.Route;

            route.Clear();

            cable.RestoreLocalDataFrom(nativeCable);
            cable.RouteAlgorithm = Cable.RouteType.Identity;

            var properties = CableProperties.Create <CableProperties>().RestoreLocalDataFrom(nativeCable.getCableProperties(),
                                                                                             nativeCable.getCablePlasticity());

            properties.name  = cable.name + "_properties";
            cable.Properties = properties = AddOrReplaceAsset(properties, node, AGXUnity.IO.AssetType.CableProperties);

            for (var it = nativeCable.getSegments().begin(); !it.EqualWith(nativeCable.getSegments().end()); it.inc())
            {
                var segment = it.get();
                route.Add(segment, attachment =>
                {
                    if (attachment == null || attachment.getRigidBody() == null)
                    {
                        return(FileInfo.PrefabInstance);
                    }
                    var rbNode = m_tree.GetNode(attachment.getRigidBody().getUuid());
                    if (rbNode == null)
                    {
                        Debug.LogWarning("Unable to find rigid body in cable attachment.");
                        return(FileInfo.PrefabInstance);
                    }
                    return(rbNode.GameObject);
                });
            }

            var materials = node.GetReferences(Node.NodeType.Material);

            if (materials.Length > 0)
            {
                cable.Material = materials[0].Asset as ShapeMaterial;
            }

            cable.GetComponent <CableRenderer>().InitializeRenderer();
            cable.GetComponent <CableRenderer>().Material = null;

            // Adding collision group from restored instance since the disabled pair
            // will be read from Space (cable.setEnableCollisions( foo, false ) will
            // work out of the box).
            var collisionGroups = cable.gameObject.GetOrCreateComponent <CollisionGroups>();

            collisionGroups.AddGroup(nativeCable.getUniqueId().ToString(), false);
            var referencedGroups = node.GetReferences(Node.NodeType.GroupId);

            foreach (var group in referencedGroups)
            {
                if (group.Object is string)
                {
                    collisionGroups.AddGroup(group.Object as string, false);
                }
            }

            return(true);
        }
Exemplo n.º 6
0
        private bool CreateWire(Node node)
        {
            var nativeWire = m_tree.GetWire(node.Uuid);

            if (nativeWire == null)
            {
                Debug.LogWarning("Unable to find native instance of wire: " + node.GameObject.name +
                                 " (UUID: " + node.Uuid.str() + ")");
                return(false);
            }

            Func <agx.RigidBody, GameObject> findRigidBody = (nativeRb) =>
            {
                if (nativeRb == null)
                {
                    return(FileInfo.PrefabInstance);
                }

                // Do not reference lumped nodes!
                if (agxWire.Wire.isLumpedNode(nativeRb))
                {
                    return(FileInfo.PrefabInstance);
                }

                Node rbNode = m_tree.GetNode(nativeRb.getUuid());
                if (rbNode == null)
                {
                    Debug.LogWarning("Unable to find reference rigid body: " + nativeRb.getName() + " (UUID: " + nativeRb.getUuid().str() + ")");
                    return(FileInfo.PrefabInstance);
                }
                if (rbNode.GameObject == null)
                {
                    Debug.LogWarning("Referenced native rigid body hasn't a game object: " + nativeRb.getName() + " (UUID: " + rbNode.Uuid.str() + ")");
                    return(FileInfo.PrefabInstance);
                }

                return(rbNode.GameObject);
            };

            var wire  = node.GameObject.GetOrCreateComponent <Wire>();
            var route = wire.Route;

            route.Clear();

            wire.RestoreLocalDataFrom(nativeWire);

            var nativeIt         = nativeWire.getRenderBeginIterator();
            var nativeEndIt      = nativeWire.getRenderEndIterator();
            var nativeBeginWinch = nativeWire.getWinchController(0u);
            var nativeEndWinch   = nativeWire.getWinchController(1u);

            if (nativeBeginWinch != null)
            {
                route.Add(nativeBeginWinch,
                          findRigidBody(nativeBeginWinch.getRigidBody()));
            }
            // Connecting nodes will show up in render iterators.
            else if (nativeIt.get().getNodeType() != agxWire.WireNode.Type.CONNECTING && nativeWire.getFirstNode().getNodeType() == agxWire.WireNode.Type.BODY_FIXED)
            {
                route.Add(nativeWire.getFirstNode(), findRigidBody(nativeWire.getFirstNode().getRigidBody()));
            }

            while (!nativeIt.EqualWith(nativeEndIt))
            {
                var nativeNode = nativeIt.get();

                // Handing ContactNode and ShapeContactNode parenting.
                GameObject nodeParent = null;
                if (nativeNode.getType() == agxWire.WireNode.Type.CONTACT)
                {
                    var nativeGeometry = nativeNode.getAsContact().getGeometry();
                    var geometryNode   = m_tree.GetNode(nativeGeometry.getUuid());
                    if (geometryNode != null && geometryNode.GetChildren(Node.NodeType.Shape).Length > 0)
                    {
                        nodeParent = geometryNode.GetChildren(Node.NodeType.Shape)[0].GameObject;
                    }
                }
                else if (nativeNode.getType() == agxWire.WireNode.Type.SHAPE_CONTACT)
                {
                    var nativeShape = nativeNode.getAsShapeContact().getShape();
                    var shapeNode   = m_tree.GetNode(nativeShape.getUuid());
                    if (shapeNode != null)
                    {
                        nodeParent = shapeNode.GameObject;
                    }
                }

                if (nodeParent == null)
                {
                    nodeParent = findRigidBody(nativeNode.getRigidBody());
                }

                route.Add(nativeNode, nodeParent);
                nativeIt.inc();
            }

            // Remove last node if we should have a winch or a body fixed node there.
            if (route.Last().Type == Wire.NodeType.FreeNode && nativeWire.getLastNode().getNodeType() == agxWire.WireNode.Type.BODY_FIXED)
            {
                route.Remove(route.Last());
            }

            if (nativeEndWinch != null)
            {
                route.Add(nativeEndWinch,
                          findRigidBody(nativeEndWinch.getRigidBody()));
            }
            else if (nativeIt.prev().get().getNodeType() != agxWire.WireNode.Type.CONNECTING && nativeWire.getLastNode().getNodeType() == agxWire.WireNode.Type.BODY_FIXED)
            {
                route.Add(nativeWire.getLastNode(), findRigidBody(nativeWire.getLastNode().getRigidBody()));
            }

            var materials = node.GetReferences(Node.NodeType.Material);

            if (materials.Length > 0)
            {
                wire.Material = materials[0].Asset as ShapeMaterial;
            }

            wire.GetComponent <WireRenderer>().InitializeRenderer();
            // Reset to assign default material.
            wire.GetComponent <WireRenderer>().Material = null;

            // Adding collision group from restored instance since the disabled pair
            // will be read from Space (wire.setEnableCollisions( foo, false ) will
            // work out of the box).
            var collisionGroups = wire.gameObject.GetOrCreateComponent <CollisionGroups>();

            collisionGroups.AddGroup(nativeWire.getGeometryController().getDisabledCollisionsGroupId().ToString(), false);
            foreach (var id in nativeWire.getGeometryController().getGroupIds())
            {
                collisionGroups.AddGroup(id.ToString(), false);
            }

            return(true);
        }
Exemplo n.º 7
0
        private bool CreateConstraint(Node node)
        {
            var nativeConstraint = m_tree.GetConstraint(node.Uuid);

            if (nativeConstraint == null)
            {
                Debug.LogWarning("Unable to find native constraint instance with name: " +
                                 node.GameObject.name +
                                 " (UUID: " + node.Uuid.str() + ")");
                return(false);
            }

            var bodyNodes = node.GetReferences(Node.NodeType.RigidBody);

            if (bodyNodes.Length < 1 || bodyNodes.Length > 2)
            {
                Debug.LogWarning("Unsupported number of body references to constraint with name: " +
                                 node.GameObject.name +
                                 " (#bodies: " + bodyNodes.Length + ")");
                return(false);
            }

            var constraintType = Constraint.FindType(nativeConstraint);

            if (constraintType == ConstraintType.Unknown)
            {
                Debug.LogWarning("Unknown/unsupported constraint type of constraint with name: " +
                                 node.GameObject.name +
                                 " (UUID: " + node.Uuid.str() + ")");
                return(false);
            }

            Constraint constraint = node.GameObject.GetOrCreateComponent <Constraint>();

            // Is the constraint enabled/active?
            // Somewhat strange though: Why is not only the Constraint component disabled?
            // For RigidBody component, only that component is disabled, but the below code disables the whole constraint GameObject.
            // Works for now
            constraint.gameObject.SetActive(nativeConstraint.isEnabled());

            constraint.SetType(constraintType, true);

            try {
                constraint.TryAddElementaryConstraints(nativeConstraint);
                constraint.VerifyImplementation();
            }
            catch (System.Exception e) {
                Debug.LogException(e);
                return(false);
            }

            // Scaling damping to our (sigh) hard coded time step.
            float fixedStepTime = AGXUnity.Simulation.DefaultTimeStep;
            float readTimeStep  = Convert.ToSingle(Simulation.getTimeStep());
            float timeStepRatio = fixedStepTime / readTimeStep;

            if (!Mathf.Approximately(timeStepRatio, 1.0f))
            {
                foreach (var ec in constraint.ElementaryConstraints)
                {
                    foreach (var rowData in ec.RowData)
                    {
                        if (rowData.Compliance < -float.Epsilon)
                        {
                            Debug.LogWarning("Constraint: " + constraint.name +
                                             " (ec name: " + rowData.ElementaryConstraint.NativeName + ")," +
                                             " has too low compliance: " + rowData.Compliance + ". Setting to zero.");
                            rowData.Compliance = 0.0f;
                        }
                        else if (rowData.Compliance > float.MaxValue)
                        {
                            Debug.LogWarning("Constraint: " + constraint.name +
                                             " (ec name: " + rowData.ElementaryConstraint.NativeName + ")," +
                                             " has too high compliance: " + rowData.Compliance + ". Setting to a large value.");
                            rowData.Compliance = 0.5f * float.MaxValue;
                        }
                        rowData.Damping *= timeStepRatio;
                    }
                }
            }

            constraint.AttachmentPair.ReferenceFrame.SetParent(bodyNodes[0].GameObject);
            constraint.AttachmentPair.ReferenceFrame.LocalPosition = nativeConstraint.getAttachment(0ul).getFrame().getLocalTranslate().ToHandedVector3();
            constraint.AttachmentPair.ReferenceFrame.LocalRotation = nativeConstraint.getAttachment(0ul).getFrame().getLocalRotate().ToHandedQuaternion();

            if (bodyNodes.Length > 1)
            {
                constraint.AttachmentPair.ConnectedFrame.SetParent(bodyNodes[1].GameObject);
            }
            else
            {
                constraint.AttachmentPair.ConnectedFrame.SetParent(FileInfo.PrefabInstance);
            }

            constraint.AttachmentPair.ConnectedFrame.LocalPosition = nativeConstraint.getAttachment(1ul).getFrame().getLocalTranslate().ToHandedVector3();
            constraint.AttachmentPair.ConnectedFrame.LocalRotation = nativeConstraint.getAttachment(1ul).getFrame().getLocalRotate().ToHandedQuaternion();

            constraint.AttachmentPair.Synchronized = constraintType != ConstraintType.DistanceJoint;

            return(true);
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 10
0
        private void Generate(Node node)
        {
            if (node == null)
            {
                return;
            }

            // TODO: Skip if node.GameObject != null means "use Unity configuration".

            switch (node.Type)
            {
            case Node.NodeType.Assembly:
                agx.Frame frame = m_tree.GetAssembly(node.Uuid);
                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName("", node.Type.ToString());

                node.GameObject.transform.position = frame.getTranslate().ToHandedVector3();
                node.GameObject.transform.rotation = frame.getRotate().ToHandedQuaternion();

                node.GameObject.GetOrCreateComponent <Assembly>();

                break;

            case Node.NodeType.RigidBody:
                agx.RigidBody nativeRb = m_tree.GetRigidBody(node.Uuid);
                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeRb.getName(), node.Type.ToString());


                node.GameObject.transform.position = nativeRb.getPosition().ToHandedVector3();
                node.GameObject.transform.rotation = nativeRb.getRotation().ToHandedQuaternion();

                node.GameObject.GetOrCreateComponent <RigidBody>().RestoreLocalDataFrom(nativeRb);


                break;

            case Node.NodeType.Geometry:
                // Ignoring geometries - handling Shape == Geometry.
                // The shapes are children to this node.
                break;

            case Node.NodeType.Shape:
                var nativeGeometry  = m_tree.GetGeometry(node.Parent.Uuid);
                var nativeShape     = m_tree.GetShape(node.Uuid);
                var nativeShapeType = (agxCollide.Shape.Type)nativeShape.getType();

                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeGeometry.getName() +
                                                "_" +
                                                nativeShapeType.ToString().ToLower().FirstCharToUpperCase(),
                                                node.Type.ToString());

                node.GameObject.transform.position = nativeShape.getTransform().getTranslate().ToHandedVector3();
                node.GameObject.transform.rotation = nativeShape.getTransform().getRotate().ToHandedQuaternion();

                if (!CreateShape(node))
                {
                    GameObject.DestroyImmediate(node.GameObject);
                }

                break;

            case Node.NodeType.Material:
                var nativeMaterial = m_tree.GetMaterial(node.Uuid);
                node.Asset      = ScriptAsset.Create <ShapeMaterial>().RestoreLocalDataFrom(nativeMaterial);
                node.Asset.name = FindName(nativeMaterial.getName(), node.Type.ToString());

                node.Asset = AddOrReplaceAsset(node.Asset as ShapeMaterial, node, AGXUnity.IO.AssetType.ShapeMaterial);

                break;

            case Node.NodeType.ContactMaterial:
                var nativeContactMaterial = m_tree.GetContactMaterial(node.Uuid);
                var nativeFrictionModel   = nativeContactMaterial.getFrictionModel();

                var contactMaterial = ScriptAsset.Create <ContactMaterial>().RestoreLocalDataFrom(nativeContactMaterial);
                contactMaterial.name = FindName("ContactMaterial_" +
                                                nativeContactMaterial.getMaterial1().getName() +
                                                "_" +
                                                nativeContactMaterial.getMaterial2().getName(),
                                                node.Type.ToString());

                var materials = node.GetReferences(Node.NodeType.Material);
                if (materials.Length == 0)
                {
                    Debug.LogWarning("No materials referenced to ContactMaterial node.");
                }
                else if (materials.Length == 1)
                {
                    contactMaterial.Material1 = contactMaterial.Material2 = materials[0].Asset as ShapeMaterial;
                }
                else if (materials.Length > 1)
                {
                    contactMaterial.Material1 = materials[0].Asset as ShapeMaterial;
                    contactMaterial.Material2 = materials[1].Asset as ShapeMaterial;
                    if (materials.Length > 2)
                    {
                        Debug.LogWarning("More than two materials referenced to ContactMaterial (" + node.Asset.name + "). First two are used.");
                    }
                }

                if (nativeFrictionModel != null)
                {
                    var frictionModelAsset = ScriptAsset.Create <FrictionModel>().RestoreLocalDataFrom(nativeFrictionModel);
                    frictionModelAsset.name       = "FrictionModel_" + contactMaterial.name;
                    contactMaterial.FrictionModel = AddOrReplaceAsset(frictionModelAsset, node, AGXUnity.IO.AssetType.FrictionModel);
                }

                node.Asset = contactMaterial = AddOrReplaceAsset(contactMaterial, node, AGXUnity.IO.AssetType.ContactMaterial);

                break;

            case Node.NodeType.Constraint:
                var nativeConstraint = m_tree.GetConstraint(node.Uuid);

                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeConstraint.getName(),
                                                "AGXUnity." + Constraint.FindType(nativeConstraint));

                if (!CreateConstraint(node))
                {
                    GameObject.DestroyImmediate(node.GameObject);
                }

                break;

            case Node.NodeType.Wire:
                var nativeWire = m_tree.GetWire(node.Uuid);

                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeWire.getName(), "AGXUnity.Wire");

                if (!CreateWire(node))
                {
                    GameObject.DestroyImmediate(node.GameObject);
                }

                break;

            case Node.NodeType.Cable:
                var nativeCable = m_tree.GetCable(node.Uuid);

                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeCable.getName(), "AGXUnity.Cable");

                if (!CreateCable(node))
                {
                    GameObject.DestroyImmediate(node.GameObject);
                }

                break;
            }

            foreach (var child in node.Children)
            {
                Generate(child);
            }
        }
Exemplo n.º 11
0
        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);
        }
Exemplo n.º 12
0
        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);
        }
Exemplo n.º 13
0
        private void Generate(Node node)
        {
            if (node == null)
            {
                return;
            }

            switch (node.Type)
            {
            case Node.NodeType.Assembly:
                agx.Frame frame = m_tree.GetAssembly(node.Uuid);
                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName("", node.Type.ToString());

                node.GameObject.transform.position = frame.getTranslate().ToHandedVector3();
                node.GameObject.transform.rotation = frame.getRotate().ToHandedQuaternion();

                node.GameObject.GetOrCreateComponent <Assembly>();

                break;

            case Node.NodeType.RigidBody:
                agx.RigidBody nativeRb = m_tree.GetRigidBody(node.Uuid);
                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeRb.getName(), node.Type.ToString());


                node.GameObject.transform.position = nativeRb.getPosition().ToHandedVector3();
                node.GameObject.transform.rotation = nativeRb.getRotation().ToHandedQuaternion();

                node.GameObject.GetOrCreateComponent <RigidBody>().RestoreLocalDataFrom(nativeRb);

                break;

            case Node.NodeType.Geometry:
                // Ignoring geometries - handling Shape == Geometry.
                // The shapes are children to this node.
                break;

            case Node.NodeType.Shape:
                var nativeGeometry  = m_tree.GetGeometry(node.Parent.Uuid);
                var nativeShape     = m_tree.GetShape(node.Uuid);
                var nativeShapeType = (agxCollide.Shape.Type)nativeShape.getType();

                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeGeometry.getName() +
                                                "_" +
                                                nativeShapeType.ToString().ToLower().FirstCharToUpperCase(),
                                                node.Type.ToString());

                node.GameObject.transform.position = nativeShape.getTransform().getTranslate().ToHandedVector3();
                node.GameObject.transform.rotation = nativeShape.getTransform().getRotate().ToHandedQuaternion();

                if (!CreateShape(node))
                {
                    GameObject.DestroyImmediate(node.GameObject);
                }

                break;

            case Node.NodeType.Material:
                // Ignoring materials - the referenced materials should have been restored
                // by now using RestoreShapeMaterial.
                break;

            case Node.NodeType.ContactMaterial:
                var           materialNodes = node.GetReferences(Node.NodeType.Material);
                Func <string> contactMaterialMaterialNames = () =>
                {
                    return(m_tree.GetMaterial(materialNodes[0].Uuid).getName() + " <-> " +
                           m_tree.GetMaterial(materialNodes[1].Uuid).getName());
                };
                if (materialNodes.Length == 0)
                {
                    Debug.LogWarning("No materials referenced to ContactMaterial node - ignoring contact material.");
                    break;
                }
                else if (materialNodes.Length > 2)
                {
                    Debug.LogWarning("More than two materials referenced to contact material - first two will be used: " +
                                     contactMaterialMaterialNames());
                }

                var materials = new ShapeMaterial[2]
                {
                    materialNodes[0].Asset as ShapeMaterial,
                    materialNodes.Length > 1 ?
                    materialNodes[1].Asset as ShapeMaterial :
                    materialNodes[0].Asset as ShapeMaterial
                };

                var nativeContactMaterial = m_tree.GetContactMaterial(node.Uuid);
                var nativeFrictionModel   = nativeContactMaterial.getFrictionModel();
                if (materials[0] == null || materials[1] == null)
                {
                    Debug.LogWarning($"Unreferenced ShapeMaterial(s) in ContactMaterial: {contactMaterialMaterialNames()} - ignoring contact material.");
                    break;
                }
                Predicate <ContactMaterial> materialsMatcher = cm => (cm.Material1 == materials[0] && cm.Material2 == materials[1]) ||
                                                               (cm.Material2 == materials[0] && cm.Material1 == materials[1]);
                var contactMaterial = FileInfo.ObjectDb.GetOrCreateAsset(materialsMatcher,
                                                                         FindName($"ContactMaterial_{materials[ 0 ].name}_{materials[ 1 ].name}",
                                                                                  node.Type.ToString()),
                                                                         cm =>
                {
                    cm.Material1 = materials[0];
                    cm.Material2 = materials[1];
                    cm.RestoreLocalDataFrom(nativeContactMaterial);
                });
                if (nativeFrictionModel != null)
                {
                    contactMaterial.FrictionModel = FileInfo.ObjectDb.GetOrCreateAsset(contactMaterial.FrictionModel,
                                                                                       $"FrictionModel_{contactMaterial.name}",
                                                                                       fm => fm.RestoreLocalDataFrom(nativeFrictionModel));
                }

                node.Asset = contactMaterial;

                break;

            case Node.NodeType.Constraint:
                var nativeConstraint = m_tree.GetConstraint(node.Uuid);

                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeConstraint.getName(),
                                                "AGXUnity." + Constraint.FindType(nativeConstraint));

                if (!CreateConstraint(node))
                {
                    GameObject.DestroyImmediate(node.GameObject);
                }

                break;

            case Node.NodeType.Wire:
                var nativeWire = m_tree.GetWire(node.Uuid);

                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeWire.getName(), "AGXUnity.Wire");

                if (!CreateWire(node))
                {
                    GameObject.DestroyImmediate(node.GameObject);
                }

                break;

            case Node.NodeType.Cable:
                var nativeCable = m_tree.GetCable(node.Uuid);

                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeCable.getName(), "AGXUnity.Cable");

                if (!CreateCable(node))
                {
                    GameObject.DestroyImmediate(node.GameObject);
                }

                break;

            case Node.NodeType.ObserverFrame:
                var nativeObserverFrame = m_tree.GetObserverFrame(node.Uuid);

                node.GameObject      = GetOrCreateGameObject(node);
                node.GameObject.name = FindName(nativeObserverFrame.getName(), "AGXUnity.ObserverFrame");

                var rbNode = node.GetReferences(Node.NodeType.RigidBody).FirstOrDefault();
                node.GameObject.GetOrCreateComponent <ObserverFrame>().RestoreLocalDataFrom(nativeObserverFrame,
                                                                                            rbNode != null ? rbNode.GameObject : null);

                break;
            }

            foreach (var child in node.Children)
            {
                Generate(child);
            }
        }