예제 #1
0
    public void Optimize()
    {
        int[]      remapLinks = RemapLinks();
        List <int> remapNodes = new List <int>();

        for (int i = 0; i < remapLinks.Length; ++i)
        {
            TxLinkHandle link = links[remapLinks[i]];
            link.index = i;
            int node0 = remapNodes.IndexOf(link.node0);
            if (node0 == -1)
            {
                node0 = remapNodes.Count; remapNodes.Add(link.node0);
            }
            link.node0 = node0;
            int node1 = remapNodes.IndexOf(link.node1);
            if (node1 == -1)
            {
                node1 = remapNodes.Count; remapNodes.Add(link.node1);
            }
            link.node1 = node1;
        }
        foreach (TxNodeHandle n in nodes)
        {
            int index = remapNodes.IndexOf(n.index);
            if (index == -1)
            {
                index = remapNodes.Count; remapNodes.Add(n.index);
            }
            n.index = index;
        }
        foreach (TxFaceHandle f in faces)
        {
            f.node0 = nodes[f.node0].index;
            f.node1 = nodes[f.node1].index;
            f.node2 = nodes[f.node2].index;
        }
        TxTruss data = trussData;

        foreach (TxTruss.NamedSet s in data.nodesSet)
        {
            for (int i = 0; i < s.indices.Length; ++i)
            {
                s.indices[i] = nodes[s.indices[i]].index;
            }
        }
        foreach (TxTruss.NamedSet s in data.linksSet)
        {
            for (int i = 0; i < s.indices.Length; ++i)
            {
                s.indices[i] = links[s.indices[i]].index;
            }
        }
        UpdateHandles();
        DestroyHandles();
        CreateHandles();
    }
예제 #2
0
    void CreateHandles()
    {
        TxTruss data = trussData;

        if (data == null)
        {
            return;
        }

        nodes = new TxNodeHandle[data.nodeCount];
        for (int i = 0; i < data.nodeCount; ++i)
        {
            TxNodeHandle node = TxNodeHandle.CreateInstance();
            node.index    = i;
            node.name     = string.Format("N({0})", i);
            node.position = data.nodePosition[i];
            node.mass     = data.nodeMass[i];
            nodes[i]      = node;
        }

        links = new TxLinkHandle[data.linkCount];
        for (int i = 0; i < data.linkCount; ++i)
        {
            TxLinkHandle link = TxLinkHandle.CreateInstance();
            link.index      = i;
            link.node0      = data.linkNodes[i * 2 + 0];
            link.node1      = data.linkNodes[i * 2 + 1];
            link.name       = string.Format("L({0},{1})", link.node0, link.node1);
            link.stiffness  = data.linkStiffness[i];
            link.damping    = data.linkDamping[i];
            link.elastic    = data.linkElastic[i];
            link.breaking   = data.linkBreaking[i];
            link.stretching = data.linkStretching.Length > 0 ? data.linkStretching[i] : 1.0f;
            link.resist     = (TxLinkHandle.Resist)(data.linkFlags[i] & 0x3);
            links[i]        = link;
        }

        faces = new TxFaceHandle[data.faceCount];
        for (int i = 0; i < data.faceCount; ++i)
        {
            TxFaceHandle face = TxFaceHandle.CreateInstance();
            face.index     = i;
            face.node0     = data.faceNodes[i * 3 + 0];
            face.node1     = data.faceNodes[i * 3 + 1];
            face.node2     = data.faceNodes[i * 3 + 2];
            face.name      = string.Format("F({0},{1},{2})", face.node0, face.node1, face.node2);
            face.collision = (data.faceFlags[i] & (1 << 0)) != 0;
            face.skinning  = (data.faceFlags[i] & (1 << 1)) != 0;
            face.matter    = data.faceMatter.Length > 0 ? data.faceMatter[i] : 0;
            face.envelope  = data.faceEnvelope[i];
            faces[i]       = face;
        }
    }
예제 #3
0
    void UpdateHandles()
    {
        TxTruss data = trussData;

        if (data == null)
        {
            return;
        }

        data.nodeCount = nodes.Length;
        foreach (TxNodeHandle n in nodes)
        {
            data.nodePosition[n.index] = n.position;
            data.nodeMass[n.index]     = n.mass;
        }

        data.linkCount = links.Length;
        foreach (TxLinkHandle l in links)
        {
            data.linkNodes[l.index * 2 + 0] = l.node0;
            data.linkNodes[l.index * 2 + 1] = l.node1;
            data.linkLength[l.index]        = Vector3.Distance(data.nodePosition[l.node0], data.nodePosition[l.node1]);
            data.linkStiffness[l.index]     = l.stiffness;
            data.linkDamping[l.index]       = l.damping;
            data.linkElastic[l.index]       = l.elastic;
            data.linkBreaking[l.index]      = l.breaking;
            data.linkStretching[l.index]    = l.stretching;
            data.linkFlags[l.index]         = (int)l.resist;
        }

        data.faceCount = faces.Length;
        foreach (TxFaceHandle f in faces)
        {
            data.faceNodes[f.index * 3 + 0] = f.node0;
            data.faceNodes[f.index * 3 + 1] = f.node1;
            data.faceNodes[f.index * 3 + 2] = f.node2;
            data.faceFlags[f.index]         = (f.collision ? (1 << 0) : 0) | (f.skinning ? (1 << 1) : 0);
            data.faceMatter[f.index]        = f.matter;
            data.faceEnvelope[f.index]      = f.envelope;
        }
    }
예제 #4
0
    void OnSceneGUI()
    {
        Color yellow = new Color(1.0f, 0.5f, 0.0f);
        Color green  = new Color(0.0f, 0.5f, 0.0f);
        Color blue   = new Color(0.0f, 0.5f, 1.0f);
        Color red    = new Color(0.5f, 0.0f, 0.0f);
        float size   = 0.1f;

        foreach (TxConstraint constraint in m_targets)
        {
            if (!constraint.enabled || constraint.isBroken)
            {
                continue;
            }
            TxSoftBody bodyA  = constraint.attachedBody;
            TxTruss    trussA = bodyA.truss;
            if (trussA == null)
            {
                continue;
            }
            if (constraint.enableMotor)
            {
                int[] motorAxis = trussA.FindNodeSet(constraint.motorAxis);
                if (motorAxis != null && motorAxis.Length == 2)
                {
                    Vector3 axis0 = bodyA.nodePosition[motorAxis[0]];
                    Vector3 axis1 = bodyA.nodePosition[motorAxis[1]];
                    Handles.color = red;
                    Handles.DrawLine(axis0, axis1);
                }
            }
            if (constraint.baseBody is TxSoftBody)
            {
                Handles.color = yellow;
                TxSoftBody bodyB  = constraint.baseBody as TxSoftBody;
                TxTruss    trussB = bodyB.truss;
                if (trussB == null)
                {
                    continue;
                }
                TxConstraint.Snap[] snaps = constraint.snaps;
                foreach (var s in snaps)
                {
                    if (!s.show)
                    {
                        continue;
                    }
                    int[] indicesA = trussA.FindNodeSet(s.node);
                    if (indicesA != null && indicesA.Length == 1)
                    {
                        Vector3 positionA = bodyA.nodePosition[indicesA[0]];
                        int[]   indicesB  = trussB.FindNodeSet(s.featureB);
                        if (indicesB != null)
                        {
                            switch (s.type)
                            {
                            case TxConstraint.SnapType.Node:
                                if (indicesB.Length == 1)
                                {
                                    Matrix4x4 matrixB   = bodyB.transform.localToWorldMatrix;
                                    Vector3   positionB = bodyB.nodePosition[indicesB[0]];
                                    if (Vector3.Distance(positionA, positionB) > 0.001f)
                                    {
                                        Handles.color = yellow;
                                        size          = HandleUtility.GetHandleSize(positionA) * 0.08f;
                                        Handles.SphereCap(-1, positionA, Quaternion.identity, size);
                                        Handles.color = blue;
                                        size          = HandleUtility.GetHandleSize(positionB) * 0.08f;
                                        Handles.SphereCap(-1, positionB, Quaternion.identity, size);
                                        Handles.color = green;
                                        Handles.DrawLine(positionA, positionB);
                                    }
                                    else
                                    {
                                        Handles.color = green;
                                        size          = HandleUtility.GetHandleSize(positionA) * 0.08f;
                                        Handles.SphereCap(-1, positionA, Quaternion.identity, size);
                                    }
                                    if (s.maxLimit > 0.001f)
                                    {
                                        if (s.minLimit < s.maxLimit - 0.001f)
                                        {
                                            Handles.color = blue;
                                            Handles.DrawWireDisc(positionB, matrixB.GetColumn(0), s.minLimit);
                                            Handles.DrawWireDisc(positionB, matrixB.GetColumn(1), s.minLimit);
                                            Handles.DrawWireDisc(positionB, matrixB.GetColumn(2), s.minLimit);
                                            Handles.color = yellow;
                                            Handles.DrawWireDisc(positionB, matrixB.GetColumn(0), s.maxLimit);
                                            Handles.DrawWireDisc(positionB, matrixB.GetColumn(1), s.maxLimit);
                                            Handles.DrawWireDisc(positionB, matrixB.GetColumn(2), s.maxLimit);
                                        }
                                        else
                                        {
                                            Handles.color = green;
                                            Handles.DrawWireDisc(positionB, matrixB.GetColumn(0), s.maxLimit);
                                            Handles.DrawWireDisc(positionB, matrixB.GetColumn(1), s.maxLimit);
                                            Handles.DrawWireDisc(positionB, matrixB.GetColumn(2), s.maxLimit);
                                        }
                                    }
                                }
                                break;

                            case TxConstraint.SnapType.Edge:
                                if (indicesB.Length == 2)
                                {
                                    Vector3 positionB0 = bodyB.nodePosition[indicesB[0]];
                                    Vector3 positionB1 = bodyB.nodePosition[indicesB[1]];
                                    Handles.color = blue;
                                    size          = HandleUtility.GetHandleSize(positionB0) * 0.08f;
                                    Handles.SphereCap(-1, positionB0, Quaternion.identity, size);
                                    size = HandleUtility.GetHandleSize(positionB1) * 0.08f;
                                    Handles.SphereCap(-1, positionB1, Quaternion.identity, size);
                                    Handles.DrawLine(positionB0, positionB1);
                                    Vector3 positionB = positionB0 + (positionB1 - positionB0) * Vector3.Dot(positionB1 - positionB0, positionA - positionB0) / (positionB1 - positionB0).sqrMagnitude;
                                    if (Vector3.Distance(positionA, positionB) > 0.001f)
                                    {
                                        Handles.color = yellow;
                                        size          = HandleUtility.GetHandleSize(positionA) * 0.08f;
                                        Handles.SphereCap(-1, positionA, Quaternion.identity, size);
                                        Handles.color = blue;
                                        size          = HandleUtility.GetHandleSize(positionB) * 0.08f;
                                        Handles.SphereCap(-1, positionB, Quaternion.identity, size);
                                        Handles.color = green;
                                        Handles.DrawLine(positionA, positionB);
                                    }
                                    else
                                    {
                                        Handles.color = green;
                                        size          = HandleUtility.GetHandleSize(positionA) * 0.08f;
                                        Handles.SphereCap(-1, positionA, Quaternion.identity, size);
                                    }
                                    if (s.maxLimit > 0.001f)
                                    {
                                        Vector3 normal = (positionB1 - positionB0).normalized;
                                        if (s.minLimit < s.maxLimit - 0.001f)
                                        {
                                            Handles.color = blue;
                                            Handles.DrawWireDisc(positionB0, normal, s.minLimit);
                                            Handles.DrawWireDisc((positionB0 + positionB1) * 0.5f, normal, s.minLimit);
                                            Handles.DrawWireDisc(positionB1, normal, s.minLimit);
                                            Handles.color = yellow;
                                            Handles.DrawWireDisc(positionB0, normal, s.maxLimit);
                                            Handles.DrawWireDisc((positionB0 + positionB1) * 0.5f, normal, s.maxLimit);
                                            Handles.DrawWireDisc(positionB1, normal, s.maxLimit);
                                        }
                                        else
                                        {
                                            Handles.color = green;
                                            Handles.DrawWireDisc(positionB0, normal, s.maxLimit);
                                            Handles.DrawWireDisc((positionB0 + positionB1) * 0.5f, normal, s.maxLimit);
                                            Handles.DrawWireDisc(positionB1, normal, s.maxLimit);
                                        }
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                TxBody              bodyB   = constraint.baseBody;
                Matrix4x4           matrixA = Application.isPlaying ? constraint.startMatrix : bodyB ? bodyB.transform.worldToLocalMatrix * bodyA.transform.localToWorldMatrix : bodyA.transform.localToWorldMatrix;
                Matrix4x4           matrixB = bodyB ? bodyB.transform.localToWorldMatrix : Matrix4x4.identity;
                TxConstraint.Snap[] snaps   = constraint.snaps;
                foreach (var s in snaps)
                {
                    if (!s.show)
                    {
                        continue;
                    }
                    int[] indices = trussA.FindNodeSet(s.node);
                    if (indices != null)
                    {
                        foreach (var i in indices)
                        {
                            if (s.maxLimit > 0.001f)
                            {
                                Vector3 positionA = bodyA.nodePosition[i];
                                Vector3 positionB = matrixB.MultiplyPoint(matrixA.MultiplyPoint(trussA.nodePosition[i]));
                                if (Vector3.Distance(positionA, positionB) > 0.001f)
                                {
                                    Handles.color = yellow;
                                    size          = HandleUtility.GetHandleSize(positionA) * 0.08f;
                                    Handles.SphereCap(-1, positionA, Quaternion.identity, size);
                                    Handles.color = blue;
                                    size          = HandleUtility.GetHandleSize(positionB) * 0.08f;
                                    Handles.SphereCap(-1, positionB, Quaternion.identity, size);
                                }
                                else
                                {
                                    Handles.color = green;
                                    size          = HandleUtility.GetHandleSize(positionA) * 0.08f;
                                    Handles.SphereCap(-1, positionA, Quaternion.identity, size);
                                }
                                Handles.color = green;
                                Handles.DrawWireDisc(positionB, matrixB.GetColumn(0), s.maxLimit);
                                Handles.DrawWireDisc(positionB, matrixB.GetColumn(1), s.maxLimit);
                                Handles.DrawWireDisc(positionB, matrixB.GetColumn(2), s.maxLimit);
                            }
                            else
                            {
                                Vector3 position = matrixB.MultiplyPoint(matrixA.MultiplyPoint(trussA.nodePosition[i]));
                                Handles.color = green;
                                size          = HandleUtility.GetHandleSize(position) * 0.08f;
                                Handles.SphereCap(-1, position, Quaternion.identity, size);
                            }
                        }
                    }
                }
            }
        }
        Handles.color = Color.white;
    }
    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        TxEditor.LookLikeControls();

        bool isPlaying = Application.isPlaying;

        TxTrussDesigner trussDesigner = m_targets[0].GetComponent <TxTrussDesigner>();

        GUI.enabled = (trussDesigner == null && !Application.isPlaying) && !isPlaying;
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.PropertyField(truss);
        GUI.enabled = (truss.objectReferenceValue != null && !Application.isPlaying);
        if (GUILayout.Button("Edit", (trussDesigner != null) ? TxEditor.MiniPressedStyle() : TxEditor.MiniUnpressedStyle(), GUILayout.MaxWidth(40)))
        {
            if (trussDesigner)
            {
                EditorApplication.delayCall += () => Undo.DestroyObjectImmediate(trussDesigner);
            }
            else
            {
                Undo.AddComponent <TxTrussDesigner>(m_targets[0].gameObject);
            }
        }
        EditorGUILayout.EndHorizontal();

        GUI.enabled = true;
        EditorGUILayout.PropertyField(massScale);
        if (truss.objectReferenceValue == null || truss.hasMultipleDifferentValues || massScale.hasMultipleDifferentValues)
        {
            GUI.enabled = false;
            EditorGUILayout.TextField("Scaled Mass", "-");
        }
        else
        {
            TxTruss trussAsset = truss.objectReferenceValue as TxTruss;
            if (trussAsset != null)
            {
                float scaledMass = 0;
                foreach (var m in trussAsset.nodeMass)
                {
                    scaledMass += m;
                }
                GUI.enabled = false;
                EditorGUILayout.FloatField("Scaled Mass", scaledMass * massScale.floatValue);
            }
        }

        GUI.enabled = true && !isPlaying;
        EditorGUILayout.PropertyField(collision);

        EditorGUI.indentLevel++;
        GUI.enabled = collision.boolValue && !isPlaying;
        EditorGUILayout.PropertyField(margin);
        EditorGUILayout.PropertyField(matters, true);
        EditorGUI.indentLevel--;

        BodyGroupUI();

        GUI.enabled = true && !isPlaying;
        EditorGUILayout.PropertyField(skinning);

        GUI.enabled = true && !isPlaying;
        SpawnEnabledUI();
        EditorGUI.indentLevel++;
        EditorGUILayout.PropertyField(spawnActive);
        EditorGUI.indentLevel--;
        GUI.enabled = true;
        EditorGUILayout.PropertyField(deactivation);
        EditorGUI.indentLevel++;
        GUI.enabled = deactivation.boolValue;
        EditorGUILayout.PropertyField(deactivationSpeed, new GUIContent("Speed"));
        EditorGUILayout.PropertyField(deactivationTime, new GUIContent("Time"));
        EditorGUI.indentLevel--;

        GUI.enabled = true;
        EditorGUILayout.PropertyField(filling);
        EditorGUI.indentLevel++;
        GUI.enabled = filling.boolValue;
        EditorGUILayout.PropertyField(internalPressure);
        EditorGUILayout.PropertyField(adiabaticIndex);
        EditorGUI.indentLevel--;

        if (GUI.changed)
        {
            serializedObject.ApplyModifiedProperties();
        }
    }