Exemplo n.º 1
0
    public void ComputeSpringForces()
    {
        ClothNode p1node       = P1.GetComponent <ClothNode>();
        ClothNode p2node       = P2.GetComponent <ClothNode>();
        Vector3   displacement = P2.transform.position - P1.transform.position;
        float     distance     = displacement.magnitude;
        Vector3   direction    = displacement / distance;

        // 1 Dimension velocities b/c a spring exists in 1 Dimension      // Used in Dampen Force formula
        float node1Velocity = Vector3.Dot(displacement.normalized, p1node.velocity);
        float node2Velocity = Vector3.Dot(displacement.normalized, p2node.velocity);

        // Spring Force = -spring factor * (distance - rest length)
        float Fspring = -springConstant * (distance - restLength);
        // Dampen Force = -Dampen Factor * (difference of velocity)
        float Fdampen = -damperConstant * (node2Velocity - node1Velocity);

        // 1 Dimension Spring Dampen Force  // Sum of Spring Force and Dampen Force
        float SpringDampenforce = Fspring + Fdampen;

        // Converting it back into a 3 Dimensional force
        Vector3 p2force = SpringDampenforce * direction;
        Vector3 p1force = -p2force;

        // Applying it to nodes
        p1node.force += p1force;
        p2node.force += p2force;
    }
Exemplo n.º 2
0
    public void ComputeTriangleForces(Vector3 air_Velocity, float density, float drag)
    {
        ClothNode a = nodeA.GetComponent <ClothNode>();
        ClothNode b = nodeB.GetComponent <ClothNode>();
        ClothNode c = nodeC.GetComponent <ClothNode>();

        Vector3 triangleVelocity = (a.velocity + b.velocity + c.velocity) / 3;

        triangleVelocity -= air_Velocity;

        Vector3 p1 = a.transform.position;
        Vector3 p2 = b.transform.position;
        Vector3 p3 = c.transform.position;

        Vector3 r2r1crossr3r1 = Vector3.Cross((p1 - p2), (p3 - p2));
        Vector3 normal        = r2r1crossr3r1 / r2r1crossr3r1.magnitude;

        float area = (0.5f * Vector3.Dot(triangleVelocity, normal) * triangleVelocity.magnitude) / r2r1crossr3r1.magnitude;

        Vector3 forceAero = -0.5f * drag * density * area * r2r1crossr3r1;

        forceAero /= 3.0f;
        if (!a.TouchingFloor())
        {
            a.force += forceAero;
        }
        if (!b.TouchingFloor())
        {
            b.force += forceAero;
        }
        if (!c.TouchingFloor())
        {
            c.force += forceAero;
        }
    }
Exemplo n.º 3
0
    void Start()
    {
        nodes = new ClothNode[row * col];
        vert  = new Vector3[row * col];
        uv    = new Vector2[row * col];
        tris  = new int[(row - 1) * (col - 1) * 2 * 3];
        for (int i = 0; i < row; ++i)
        {
            for (int j = 0; j < col; ++j)
            {
                Vector3 initPos = new Vector3(j, -i, 0) / 10;
                vert[i * col + j] = initPos;
                var node = new ClothNode();
                node.r_prev        = initPos;
                node.r_now         = initPos;
                nodes[i * col + j] = node;
                node.isStatic      = (i == 0);

                uv[i * col + j] = new Vector2(map(j, 0, (col - 1), 0, 1), map(-i, 0, -(row - 1), 1, 0));
            }
        }
        gameObject.AddComponent <MeshRenderer>().material = mat;
        var meshFilter = gameObject.AddComponent <MeshFilter>();

        mesh = meshFilter.mesh;
        UpdateMesh();
    }
Exemplo n.º 4
0
        public void Parse(Stream input)
        {
            using (BinaryReader reader = new BinaryReader(input)) {
                Header = reader.Read <ClothHeader>();

                if (Header.Offset > 0)
                {
                    reader.BaseStream.Position = Header.Offset;

                    Descriptors = new ClothDesc[Header.Count];
                    Nodes       = new ClothNode[Header.Count][];
                    NodeBones   = new Dictionary <int, short> [Header.Count];

                    for (ulong i = 0; i < Header.Count; i++)
                    {
                        Descriptors[i] = reader.Read <ClothDesc>();

                        long nextStartPos = reader.BaseStream.Position;

                        if (Descriptors[i].Section8Offset != 4574069944263674675)    // todo: wtf
                        {
                            reader.BaseStream.Position = Descriptors[i].Section8Offset;
                            NodeBones[i] = new Dictionary <int, short>();
                            for (int nodeIndex = 0; nodeIndex < Descriptors[i].DriverNodeCount; nodeIndex++)
                            {
                                NodeBones[i][nodeIndex] = reader.ReadInt16();
                            }
                        }

                        if (Descriptors[i].Section1Offset > 0 && Descriptors[i].Section1Offset != 4692750811720056850)    // todo: wtf2
                        {
                            Nodes[i] = new ClothNode[Descriptors[i].DriverNodeCount];
                            reader.BaseStream.Position = Descriptors[i].Section1Offset;
                            for (int nodeIndex = 0; nodeIndex < Descriptors[i].DriverNodeCount; nodeIndex++)
                            {
                                Nodes[i][nodeIndex] = new ClothNode(reader);
                            }
                        }

                        reader.BaseStream.Position = nextStartPos;
                    }
                }
            }
        }
Exemplo n.º 5
0
        public void Parse(Stream input)
        {
            using (BinaryReader reader = new BinaryReader(input, Encoding.UTF8, true)) {
                Header = reader.Read <HeaderInfo>();

                if (Header.descCount > 0)
                {
                    Descriptors    = new ClothDesc[Header.descCount];
                    input.Position = Header.descOffset;
                    Nodes          = new ClothNode[Header.descCount][];
                    BoneMap        = new Dictionary <int, int> [Header.descCount];
                    NodeBones      = new Dictionary <int, short> [Header.descCount];
                    for (ulong i = 0; i < Header.descCount; ++i)
                    {
                        Descriptors[i] = reader.Read <ClothDesc>();

                        long afterpos = reader.BaseStream.Position;

                        if (Descriptors[i].section8Offset != 4574069944263674675)
                        {
                            reader.BaseStream.Position = Descriptors[i].section8Offset;
                            NodeBones[i] = new Dictionary <int, short>();
                            for (int nodeIndex = 0; nodeIndex < Descriptors[i].driverNodeCount; nodeIndex++)
                            {
                                NodeBones[i][nodeIndex] = reader.ReadInt16();
                            }
                        }

                        Nodes[i] = new ClothNode[Descriptors[i].driverNodeCount];
                        reader.BaseStream.Position = Descriptors[i].section1Offset;
                        for (int nodeIndex = 0; nodeIndex < Descriptors[i].driverNodeCount; nodeIndex++)
                        {
                            long  nodeStart = reader.BaseStream.Position;
                            float x         = reader.ReadSingle();
                            float y         = reader.ReadSingle();
                            float z         = reader.ReadSingle();
                            uint  zero      = reader.ReadUInt32(); // zero
                            float x2        = reader.ReadSingle();
                            float y2        = reader.ReadSingle();
                            float z2        = reader.ReadSingle();

                            if (zero != 0)
                            {
                                throw new InvalidDataException($"HTLC: zero != 0 ({zero})");
                            }

                            if (Math.Abs(x - x2) > 0.01 || Math.Abs(y - y2) > 0.01 || Math.Abs(z - z2) > 0.01)
                            {
                                throw new InvalidDataException($"HTLC: location is different: {x}:{x2} {y}:{y2} {z}:{z2}");
                            }

                            reader.BaseStream.Position = nodeStart + 0x15c;
                            short ind1 = reader.ReadInt16();
                            short ind2 = reader.ReadInt16();
                            short ind3 = reader.ReadInt16();
                            short ind4 = reader.ReadInt16();

                            reader.BaseStream.Position = nodeStart + 0x170;
                            float weight1 = reader.ReadSingle();
                            float weight2 = reader.ReadSingle();
                            float weight3 = reader.ReadSingle();
                            float weight4 = reader.ReadSingle();

                            reader.BaseStream.Position = nodeStart + 0x140;
                            float verticalParentStrength1 = reader.ReadSingle();

                            reader.BaseStream.Position = nodeStart + 0x148;
                            float verticalParentStrength2 = reader.ReadSingle();

                            reader.BaseStream.Position = nodeStart + 0x154;
                            float diagonalParentStrength = reader.ReadSingle();

                            reader.BaseStream.Position = nodeStart + 0x14c;
                            short verticalParent = reader.ReadInt16();

                            reader.BaseStream.Position = nodeStart + 0x158;
                            short diagonalParent = reader.ReadInt16();

                            reader.BaseStream.Position = nodeStart + 0x150;
                            short chainNumber = reader.ReadInt16();

                            reader.BaseStream.Position = nodeStart + 0x15a;
                            byte isChild = reader.ReadByte();

                            if (isChild == 1 && chainNumber == -1)
                            {
                                throw new InvalidDataException("HTLC: node is child but not in a chain");
                            }

                            reader.BaseStream.Position = nodeStart + 0xC0 + 16;
                            Matrix3x4 ff = reader.Read <Matrix3x4B>().ToOpenTK(); // this is wrong...

                            reader.BaseStream.Position = nodeStart + 0x180;

                            Nodes[i][nodeIndex] = new ClothNode {
                                ID             = nodeIndex, X = x, Y = y, Z = z,
                                ChainNumber    = chainNumber, DiagonalParent = diagonalParent,
                                VerticalParent = verticalParent, Bones = new [] { new ClothNodeWeight(ind1, weight1),
                                                                                  new ClothNodeWeight(ind2, weight2), new ClothNodeWeight(ind3, weight3),
                                                                                  new ClothNodeWeight(ind4, weight4) }, IsChild = isChild == 1, Matrix = ff
                            };
                        }
                        reader.BaseStream.Position = afterpos;
                    }
                }
            }
        }