Esempio n. 1
0
        // Create a physics chain that fits onto the bone chain
        public static void GeneratePhysics(IPXPmxBuilder builder, IPXBone[] bones, PhysicsSettings settings, out IPXBody[] rigidbodies, out IPXJoint[] joints)
        {
            rigidbodies = new IPXBody[bones.Length - 1];
            joints      = new IPXJoint[bones.Length - 2];

            for (int i = 0; i < rigidbodies.Length; ++i)
            {
                // Basic setup
                IPXBody b = rigidbodies[i] = builder.Body();
                b.Position = Vector3.Average(bones[i].Position, bones[i + 1].Position);
                b.Bone     = bones[i];
                b.Name     = b.Bone.Name;
                b.NameE    = b.Bone.NameE;
                b.Mode     = settings.BodyMode;

                // Size
                b.BoxKind = settings.Shape;
                float w = settings.Width;
                float h = settings.Height;
                float length;
                switch (settings.LengthCalculation)
                {
                case PhysicsSettings.LengthCalculationMode.Relative:
                    length = Vector3.Distance(bones[i].Position, bones[i + 1].Position) * settings.Length;
                    break;

                case PhysicsSettings.LengthCalculationMode.DistanceFromEnds:
                    length = Math.Max(Vector3.Distance(bones[i].Position, bones[i + 1].Position) - settings.Length * 2, 0);
                    break;

                default:
                    length = settings.Length;
                    break;
                }
                if (settings.Shape == PEPlugin.Pmd.BodyBoxKind.Sphere)
                {
                    b.BoxSize = new V3(length / 2.0f, 1, 1);
                }
                else
                {
                    b.BoxSize = new Vector3(w, length / 2.0f, h);
                }

                // Angle
                V3 dir = bones[i + 1].Position - bones[i].Position;
                dir.Normalize();
                float heading = Mathf.Atan2(dir.X, dir.Z);
                float theta   = -heading;
                V3    elev    = new V3(Mathf.Cos(theta) * dir.X + Mathf.Sin(theta) * dir.Z, dir.Y, -Mathf.Sin(theta) * dir.X + Mathf.Cos(theta) * dir.Z);
                b.Rotation = new V3(Mathf.Atan2(elev.Z, elev.Y), heading, 0);
            }

            for (int i = 0; i < joints.Length; ++i)
            {
                IPXJoint j = joints[i] = builder.Joint();
                j.Position = bones[i + 1].Position;
                j.BodyA    = rigidbodies[i];
                j.BodyB    = rigidbodies[i + 1];
                j.Name     = j.BodyA.Name;
                j.NameE    = j.BodyA.NameE;
            }
        }