Exemplo n.º 1
0
    private GameObject HandleVisualGeometry(XElement geometry, GameObject parentLink)
    {
        GameObject visual = null;

        foreach (var childElement in geometry.Elements())
        {
            var scale    = Vector3.one;
            var rotation = Quaternion.identity;
            visual = null;
            switch (childElement.Name.ToString())
            {
            case "mesh":
                var scaleElem = childElement.Element("scale");
                if (scaleElem != null)
                {
                    scale = ParseSDFSize(scaleElem);
                }

                var uri    = childElement.Element("uri").Value;
                var prefab = document.LoadAsset <GameObject>(uri);
                if (prefab != null)
                {
                    visual   = PrefabUtility.InstantiatePrefab(prefab, parentLink.transform) as GameObject;
                    rotation = Quaternion.Euler(-90, 90, 0);
                    if (uri.ToLower().EndsWith(".stl"))
                    {
                        // STL import package has weird behaviour wrt right handed coordinate system
                        scale.Scale(new Vector3(-1, 1, 1));
                    }
                }
                break;

            case "box":
                visual = GameObject.CreatePrimitive(PrimitiveType.Cube);
                scale  = ParseSDFSize(childElement.Element("size"));
                break;

            case "sphere":
                visual = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                var r = ParseSingle(childElement.Element("radius"), 1.0f);
                scale = new Vector3(r, r, r);
                break;

            case "cylinder":
                visual = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                var radius = ParseSingle(childElement.Element("radius"), 1.0f);
                var length = ParseSingle(childElement.Element("length"), 1.0f);
                scale = new Vector3(radius * 2.0f, length * 0.5f, radius * 2.0f);
                break;

            case "plane":
                visual = GameObject.CreatePrimitive(PrimitiveType.Plane);
                var normal = ParseSDFVector(childElement.Element("normal"));
                var(scaleX, scaleZ) = ParseXY(childElement.Element("size"), (1.0f, 1.0f));
                scale    = new Vector3(scaleX, 1.0f, scaleZ);
                rotation = Quaternion.LookRotation(normal != Vector3.forward ? Vector3.forward : Vector3.left, normal);
                break;

            default:
                Debug.Log("unhandled visual type " + childElement + " in " + geometry);
                break;
            }

            if (visual != null)
            {
                foreach (var collider in visual.GetComponentsInChildren <Collider>())
                {
                    GameObject.DestroyImmediate(collider);
                }
                visual.isStatic = parentLink.isStatic;
                visual.transform.SetParent(parentLink.transform, false);
                visual.transform.localPosition = Vector3.zero;
                visual.transform.localScale    = scale;
                visual.transform.localRotation = rotation;
            }
        }
        return(visual);
    }
Exemplo n.º 2
0
    private void HandleCollisionGeometry(XElement geometryElement, GameObject collisionObject)
    {
        var scale    = Vector3.one;
        var rotation = Quaternion.identity;

        var box      = geometryElement.Element("box");
        var cylinder = geometryElement.Element("cylinder");
        var mesh     = geometryElement.Element("mesh");
        var plane    = geometryElement.Element("plane");

        if (mesh != null)
        {
            var scaleElem = mesh.Element("scale");

            if (scaleElem != null)
            {
                var parts = scaleElem.Value.Split(' ');
                scale = new Vector3(
                    Convert.ToSingle(parts[0], CultureInfo.InvariantCulture),
                    Convert.ToSingle(parts[1], CultureInfo.InvariantCulture),
                    Convert.ToSingle(parts[2], CultureInfo.InvariantCulture));
            }

            var meshAsset = document.LoadAsset <Mesh>(mesh.Element("uri"));
            if (meshAsset != null)
            {
                var collider = collisionObject.AddComponent <MeshCollider>();
                collider.sharedMesh = meshAsset;
                collider.convex     = !collisionObject.isStatic;
                rotation            = Quaternion.Euler(-90, 90, 0);
            }
        }
        else if (box != null)
        {
            var collider = collisionObject.AddComponent <BoxCollider>();
            var parts    = box.Element("size")?.Value.Split(' ');
            collider.size = new Vector3(
                Convert.ToSingle(parts[0], CultureInfo.InvariantCulture),
                Convert.ToSingle(parts[1], CultureInfo.InvariantCulture),
                Convert.ToSingle(parts[2], CultureInfo.InvariantCulture));
        }
        else if (cylinder != null)
        {
            float length = Convert.ToSingle(cylinder.Element("length")?.Value, CultureInfo.InvariantCulture);
            float radius = Convert.ToSingle(cylinder.Element("radius")?.Value, CultureInfo.InvariantCulture);
            if (length < radius * SDFDocument.cylinderUseMeshRadiusLengthFactor)
            {
                var collider = collisionObject.AddComponent <MeshCollider>();
                var helper   = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                collider.sharedMesh = helper.GetComponent <MeshFilter>().sharedMesh;
                GameObject.DestroyImmediate(helper);
                collider.convex = !collisionObject.isStatic;
                scale           = new Vector3(2 * radius, length * 0.5f, 2 * radius);
            }
            else
            {
                // FIXME a cylinder is not a capsule actually
                var collider = collisionObject.AddComponent <CapsuleCollider>();
                collider.height = length;
                collider.radius = radius;
            }
        }
        else if (plane != null)
        {
            var helper   = GameObject.CreatePrimitive(PrimitiveType.Plane);
            var collider = collisionObject.AddComponent <MeshCollider>();
            collider.sharedMesh = helper.GetComponent <MeshFilter>().sharedMesh;
            GameObject.DestroyImmediate(helper);

            var normal = ParseSDFVector(plane.Element("normal"));
            var(scaleX, scaleZ) = ParseXY(plane.Element("size"), (1.0f, 1.0f));
            scale    = new Vector3(scaleX, 1.0f, scaleZ);
            rotation = Quaternion.LookRotation(normal != Vector3.forward ? Vector3.forward : Vector3.left, normal);
        }
        else
        {
            Debug.Log("unhandled collision type in " + geometryElement);
        }

        if (collisionObject.GetComponent <Collider>() != null)
        {
            ApplyPose(geometryElement.Parent, collisionObject);
            collisionObject.transform.localScale = scale;
            collisionObject.transform.rotation  *= rotation;
        }
    }