/// <summary>
        /// Peek at a temporary native instance or the current (if initialized).
        /// </summary>
        /// <param name="callback">Callback with temporary or already initialized native instance. Callback signature ( nativeRb, isTemporary ).</param>
        /// <remarks>
        /// Always assume the native instance to be temporary. It's never safe to cache an instance to the native object.
        /// </remarks>
        public void PeekTemporaryNativeOrGetNative(Action <agx.RigidBody, bool> callback)
        {
            if (callback == null)
            {
                return;
            }

            if (m_rb != null)
            {
                callback(m_rb, false);
            }
            else
            {
                Shape[] shapes = GetComponentsInChildren <Shape>();

                using (agx.RigidBody rb = new agx.RigidBody()) {
                    foreach (Shape shape in shapes)
                    {
                        agxCollide.Shape nativeShape = shape.CreateTemporaryNative();
                        if (nativeShape != null)
                        {
                            agxCollide.Geometry geometry = new agxCollide.Geometry(nativeShape);

                            geometry.setEnable(shape.IsEnabled);

                            if (shape.Material != null)
                            {
                                geometry.setMaterial(shape.Material.CreateTemporaryNative());
                            }
                            rb.add(geometry, shape.GetNativeRigidBodyOffset(this));
                        }
                    }

                    // For center of mass position/rotation to be correct we have to
                    // synchronize the native transform given current game object transform.
                    SyncNativeTransform(rb);

                    callback(rb, true);

                    // Hitting "Update" (mass or inertia in the Inspector) several times
                    // will crash agx if we don't remove the geometries and shapes.
                    while (rb.getGeometries().Count > 0)
                    {
                        agxCollide.Geometry geometry = rb.getGeometries()[0].get();
                        if (geometry.getShapes().Count > 0)
                        {
                            geometry.remove(geometry.getShapes()[0].get());
                        }
                        rb.remove(geometry);
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Merges all source objects to one mesh and creates a native trimesh.
        /// </summary>
        /// <param name="meshes">Source meshes.</param>
        /// <returns>Native trimesh.</returns>
        private agxCollide.Geometry Create(UnityEngine.Mesh[] meshes)
        {
            var geometry = new agxCollide.Geometry();

            if (m_precomputedCollisionMeshes.Count > 0)
            {
                // The vertices are assumed to be stored in local coordinates of the
                // given transform. For the scale to be correct w
                var toWorld = transform.localToWorldMatrix;
                Func <Vector3, Vector3> transformer = v =>
                {
                    return(transform.InverseTransformDirection(toWorld * v.ToLeftHanded()));
                };

                var mode = Options != null ? Options.Mode : CollisionMeshOptions.MeshMode.Trimesh;
                for (int i = 0; i < m_precomputedCollisionMeshes.Count; ++i)
                {
                    var collisionMesh = m_precomputedCollisionMeshes[i];
                    if (collisionMesh == null)
                    {
                        Debug.LogWarning($"AGXUnity.Collide.Mesh: Null precomputed collision mesh at index {i}.", this);
                        continue;
                    }

                    var shape = collisionMesh.CreateShape(transformer, mode);
                    if (shape == null)
                    {
                        Debug.LogWarning($"AGXUnity.Collide.Mesh: Precomputed collision mesh at index {i} resulted in an invalid shape.", this);
                        continue;
                    }

                    geometry.add(shape, GetNativeGeometryOffset());
                }
            }
            else
            {
                if (m_precomputedCollisionMeshes.Count > 0)
                {
                    Debug.LogWarning("AGXUnity.Mesh: Failed to create shapes from precomputed data - using Trimesh as fallback.", this);
                }

                var merger = MeshMerger.Merge(transform, meshes);
                geometry.add(new agxCollide.Trimesh(merger.Vertices,
                                                    merger.Indices,
                                                    "AGXUnity.Mesh: Trimesh"),
                             GetNativeGeometryOffset());
            }

            if (geometry.getShapes().Count == 0)
            {
                geometry.Dispose();
                geometry = null;
            }

            return(geometry);
        }
Beispiel #3
0
        /// <summary>
        /// Add shape to a rigid body instance.
        /// NOTE: This method is used by the RigidBody object.
        /// </summary>
        /// <param name="rb"></param>
        public void SetRigidBody(RigidBody rb)
        {
            if (m_geometry == null || m_geometry.getShapes().Count == 0 || m_geometry.getRigidBody() != null)
            {
                return;
            }

            // Search in our game object for rigid body and remove this?
            if (!rb.gameObject.HasChild(gameObject))
            {
                throw new Exception("RigidBody not parent to Shape.");
            }

            m_geometry.setEnable(IsEnabled);

            rb.Native.add(m_geometry, GetNativeRigidBodyOffset(rb));
        }
Beispiel #4
0
        /// <summary>
        /// Add shape to a rigid body instance.
        /// NOTE: This method is used by the RigidBody object.
        /// </summary>
        /// <param name="rb"></param>
        public void SetRigidBody(RigidBody rb)
        {
            if (m_geometry == null || m_geometry.getShapes().Count == 0 || m_geometry.getRigidBody() != null)
            {
                return;
            }

            // Search in our game object for rigid body and remove this?
            if (!rb.gameObject.HasChild(gameObject))
            {
                throw new Exception("RigidBody not parent to Shape.");
            }

            m_geometry.setEnable(IsEnabled);

            rb.Native.add(m_geometry, GetNativeRigidBodyOffset(rb));

            // Removing us from synchronization the transform since
            // we're implicitly updated from the synchronization of
            // the body.
            Simulation.Instance.StepCallbacks.PostSynchronizeTransforms -= OnPostSynchronizeTransformsCallback;
        }
        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()
                });
            }
        }