示例#1
0
    public void CollisionStay(PhysXCollision collision)
    {
        // float penCoefficientA = (penForMaxImpulseScale - penForUnitImpulseScale * maxImpulseScale) / (penForUnitImpulseScale * penForUnitImpulseScale * penForMaxImpulseScale - penForUnitImpulseScale * penForMaxImpulseScale * penForMaxImpulseScale);
        // float penCoefficientB = maxImpulseScale / penForMaxImpulseScale - penCoefficientA * penForMaxImpulseScale;
        if (collision.rigidBody != null)
        {
            velocity = (rigidBody.velocity - collision.rigidBody.velocity).magnitude;
        }
        else
        {
            velocity = rigidBody.velocity.magnitude;
        }
        velocity -= velocityOffset;
        if (velocity < 0)
        {
            velocity = 0;
        }


        float penExp = velocityScale / velocity;

        if (penExp > maxPenExp)
        {
            penExp = maxPenExp;
        }

        float penCoefficient = 1 / Mathf.Pow(penForUnitImpulseScale, penExp);

        for (int i = 0; i < collision.contactCount; i++)
        {
            PhysXContactPoint contactPoint = collision.GetContact(i);

            if (contactPoint.ownShape == collider.shape)
            {
                float penetration = -contactPoint.separation;
                if (penetration < 0)
                {
                    penetration = 0;
                }

                //Debug.Log("penetration: " + penetration);

                Vector3 impulse = contactPoint.impulse;
                // float impulseScale = penCoefficientA * penetration * penetration + penCoefficientB * penetration;
                float impulseScale = penCoefficient * Mathf.Pow(penetration, penExp);
                if (impulseScale > maxImpulseScale)
                {
                    impulseScale = maxImpulseScale;
                }
                impulse *= impulseScale;

                rigidBody.AddGhostImpulse(impulse, contactPoint.point);
            }
        }
    }
示例#2
0
    public void CollisionStay(PhysXCollision collision)
    {
        if (collision.contactCount > 0 && collision.GetContact(0).separation < -minPenetration)
        {
            if ((collision.rigidBody == null || collision.rigidBody.mass >= minDeformationMass) &&
                !collision.collider.gameObject.CompareTag("DustGround"))
            {
                meshDeformationMarker.Begin();

                bool isInconvenient = collision.collider is PhysXMeshCollider && !((PhysXMeshCollider)collision.collider).convex;

                Vector3 collisionSurfaceNormal = Vector3.zero;
                Vector3 collisionSurfacePoint  = Vector3.zero;

                for (int i = 0; i < collision.contactCount; i++)
                {
                    PhysXContactPoint contactPoint     = collision.GetContact(i);
                    float             impulseMagnitude = contactPoint.impulse.magnitude;

                    collisionSurfaceNormal += contactPoint.normal;
                    collisionSurfacePoint  += contactPoint.point;
                }



                collisionSurfaceNormal /= collision.contactCount;
                collisionSurfacePoint  /= collision.contactCount;

                collisionSurfaceNormal = transform.InverseTransformDirection(collisionSurfaceNormal);
                collisionSurfacePoint  = transform.InverseTransformPoint(collisionSurfacePoint);

                gizmoSurfaceNormal = collisionSurfaceNormal;
                gizmoSurfacePoint  = collisionSurfacePoint;

                Vector3    oldPosition = collision.body.position;
                Quaternion oldRotation = collision.body.rotation;
                collision.body.position = transform.InverseTransformPoint(collision.body.position);
                collision.body.rotation = Quaternion.Inverse(transform.rotation) * collision.body.rotation;

                VertexGroup[] groups = meshGraph.groups;
                for (int i = 0; i < groups.Length; i++)
                {
                    VertexGroup current = groups[i];
                    Vector3     vertex  = current.pos;

                    if (IsBeyondCollisionSurface(collisionSurfaceNormal, collisionSurfacePoint, vertex))
                    {
                        if (isInconvenient || collision.collider.ClosestPoint(vertex) == vertex)
                        {
                            Vector3 deformation = DeformationFromCollisionSurface(collisionSurfaceNormal, collisionSurfacePoint, vertex);

                            // if (addNoise) deformation *= Random.value * multiplier + addition;

                            current.MoveBy(vertices, deformation, false);
                            current.SetWasMoved(teamId, true);

                            if (!current.GetEnqueued(teamId))
                            {
                                vertexQueue.Enqueue(current);
                                current.SetEnqueued(teamId, true);
                                // Debug.Log("Vertex group " + current.vertexIndices[0] + " enqueued due to collision");
                            }
                        }
                    }
                }

                collision.body.position = oldPosition;
                collision.body.rotation = oldRotation;

                dissipationNeeded = true;

                meshDeformationMarker.End();
            }
        }
    }