Exemplo n.º 1
0
        // Returns meshes in meters, in the proper basis, with proper winding
        static IEnumerable <ModelMesh> GetModelMeshesFromGameObject(GameObject obj,
                                                                    SceneStatePayload payload,
                                                                    bool reverseWinding)
        {
            int    i          = -1;
            string exportName = obj.name;

            foreach (MeshData data in VisitMeshes(obj))
            {
                i++;
                var mesh = data.mesh;
                for (int sm = 0; sm < mesh.subMeshCount; sm++)
                {
                    var exportableMaterial = GetMaterialForMeshData(data);

                    // TODO: The geometry pools could be aggregated, for faster downstream rendering.
                    var geo = new GeometryPool();
                    geo.Layout = exportableMaterial.VertexLayout;
                    geo.Append(mesh, geo.Layout);

                    // Important: This transform should only be applied once, since the pools are shared, and
                    // cannot include any mesh-local transformations.
                    ExportUtils.ConvertToMetersAndChangeBasis(geo, ExportUtils.GetBasisMatrix(payload));

                    if (reverseWinding)
                    {
                        // Note: this triangle flip intentionally un-does the Unity FBX import flip.
                        ExportUtils.ReverseTriangleWinding(geo, 1, 2);
                    }

                    var objectMesh = new ModelMesh {
                        model = null, // The model is only used for uniquefying the texture names.
                        name  = exportName + "_" + i + "_" + sm,
                        id    = data.renderer.gameObject.GetInstanceID(),
                        pool  = geo,
                        xform = ExportUtils.ChangeBasisNonUniformScale(payload, data.renderer.localToWorldMatrix),
                        exportableMaterial = exportableMaterial,
                        meshIndex          = i
                    };

                    yield return(objectMesh);
                }
            }
        }
Exemplo n.º 2
0
        // Unused and untested
#if false
        /// Converts the existing payload to the new color space and vector basis.
        /// Note that scale is never converted and only gamma -> linear is currently supported.
        public static void ConvertPayload(ColorSpace newColorSpace,
                                          Vector3[] newVectorBasis,
                                          SceneStatePayload payload)
        {
            // We don't handle uninitialized color spaces or linear -> srgb conversions.
            // This is just not currently part of the export logic, so it's not implemented here.
            if (newColorSpace == ColorSpace.Uninitialized ||
                payload.colorSpace == ColorSpace.Uninitialized ||
                (payload.colorSpace == ColorSpace.Linear && newColorSpace == ColorSpace.Gamma))
            {
                throw new NotImplementedException();
            }

            if (newColorSpace != payload.colorSpace)
            {
                ExportUtils.ConvertToLinearColorspace(payload.env);
                ExportUtils.ConvertToLinearColorspace(payload.lights);
                foreach (var group in payload.groups)
                {
                    ExportUtils.ConvertToLinearColorspace(group.brushMeshes);
                }
                ExportUtils.ConvertToLinearColorspace(payload.modelMeshes);
            }

            if (newVectorBasis[0] != payload.vectorBasis[0] ||
                newVectorBasis[1] != payload.vectorBasis[1] ||
                newVectorBasis[2] != payload.vectorBasis[2])
            {
                // Never apply a scale change when changing basis.
                Matrix4x4 basis = ExportUtils.GetBasisMatrix(payload);
                foreach (var group in payload.groups)
                {
                    ExportUtils.ChangeBasis(group.brushMeshes, basis);
                }
                ExportUtils.ChangeBasis(payload.modelMeshes, basis);
                ExportUtils.ChangeBasis(payload.referenceImages, basis);
                ExportUtils.ChangeBasis(payload.referenceModels, basis);
            }

            payload.colorSpace  = newColorSpace;
            payload.vectorBasis = newVectorBasis;
        }
Exemplo n.º 3
0
        /// Returns a matrix:
        /// - with units converted by the scale specified in the payload
        /// - with basis changed by the axis convention in the payload
        /// - with the scene transform subtracted out (so, converts from room to scene), but
        ///   only if the app is running.
        /// This version also handles non-uniform scale (but stemming from what? the scene xf?)
        public static Matrix4x4 ChangeBasisNonUniformScale(SceneStatePayload payload, Matrix4x4 root)
        {
            Matrix4x4 basis = ExportUtils.GetBasisMatrix(payload);

            // Pre- and post-multiplying by the following matrix operations is the equivalent of
            // .TransformBy(TrTransform.S(payload.exportUnitsFromAppUnits)).
            Matrix4x4 xfScale        = Matrix4x4.Scale(Vector3.one * payload.exportUnitsFromAppUnits);
            Matrix4x4 xfScaleInverse = Matrix4x4.Scale(Vector3.one / payload.exportUnitsFromAppUnits);

            if (Application.isPlaying)
            {
                // The world to scene matrix here performs the equivalent of App.Scene.AsScene[root]
                // but works for non-uniform scale.
                Matrix4x4 worldToSceneMatrix = App.Scene.transform.worldToLocalMatrix;
                return(xfScale * basis * worldToSceneMatrix * root * basis.inverse * xfScaleInverse);
            }
            else
            {
                return(xfScale * basis * root * basis.inverse * xfScaleInverse);
            }
        }
Exemplo n.º 4
0
        public static SceneStatePayload GetExportPayloadForGameObject(GameObject gameObject,
                                                                      AxisConvention axes,
                                                                      Environment env)
        {
            var payload = new SceneStatePayload(axes);

            payload.env.skyCubemap = env == null ? null : env.m_RenderSettings.m_SkyboxCubemap;
            payload.lights         = new ExportUtils.LightsPayload();
            // unused test code
#if TEST_ENVIRONMENTS_WITH_SCENE_LIGHTS
            {
                var lights = payload.lights;
                lights.ambientColor = RenderSettings.ambientLight;

#if true
                // Scene lights from Standard enviroment
                lights.elements.Add(new ExportUtils.Light {
                    name       = "SceneLight0",
                    id         = 0,
                    type       = LightType.Directional,
                    lightColor = new Color32(198, 208, 253),
                    xform      = ExportUtils.ChangeBasisNonUniformScale(
                        payload, Matrix4x4.TRS(
                            new Vector3(0f, 0.21875f, -.545875f),
                            Quaternion.Euler(60, 0, 26),
                            Vector3.one))
                });

                lights.elements.Add(new ExportUtils.Light {
                    name       = "SceneLight1",
                    id         = 1,
                    type       = LightType.Directional,
                    lightColor = new Color32(109, 107, 88),
                    xform      = ExportUtils.ChangeBasisNonUniformScale(
                        payload,
                        Matrix4x4.TRS(
                            new Vector3(0f, 0.21875f, -.545875f),
                            Quaternion.Euler(140, 0, 40),
                            Vector3.one)),
                });
#else
                // Scene lights from Dress Form environment
                lights.elements.Add(new ExportUtils.Light {
                    name       = "SceneLight0",
                    id         = 0,
                    type       = LightType.Directional,
                    lightColor = new Color32(255, 234, 198),
                    xform      = ExportUtils.ChangeBasisNonUniformScale(
                        payload, Matrix4x4.TRS(
                            new Vector3(0f, 0.7816665f, -.220875f),
                            Quaternion.Euler(50, 42, 26),
                            Vector3.one))
                });

                lights.elements.Add(new ExportUtils.Light {
                    name       = "SceneLight1",
                    id         = 1,
                    type       = LightType.Directional,
                    lightColor = new Color32(91, 90, 74),
                    xform      = ExportUtils.ChangeBasisNonUniformScale(
                        payload,
                        Matrix4x4.TRS(
                            new Vector3(0f, .636532f, -.6020539f),
                            Quaternion.Euler(140, 47, 40),
                            Vector3.one)),
                });
#endif
            }
#endif

            // The determinant can be used to detect if the basis-change has a mirroring.
            // This matters because a mirroring turns the triangles inside-out, requiring
            // us to flip their winding to preserve the surface orientation.
            bool reverseTriangleWinding = (ExportUtils.GetBasisMatrix(payload).determinant < 0);

            BuildModelMeshesFromGameObject(gameObject, payload, reverseTriangleWinding);
            return(payload);
        }