protected override void OnCreate()
        {
            base.OnCreate();

            var scene = CreateScene(false);

            Component_Mesh mesh = ObjectOfPreview as Component_Mesh;

            if (mesh != null)
            {
                Component_MeshInSpace objInSpace = scene.CreateComponent <Component_MeshInSpace>();
                objInSpace.Mesh = mesh;
            }

            scene.Enabled = true;

            SetCameraByBounds(scene.CalculateTotalBoundsOfObjectsInSpace());

            if (mesh.EditorCameraTransform != null)
            {
                var tr = mesh.EditorCameraTransform;
                CameraInitialDistance = (tr.Position - CameraLookTo).Length();
                CameraDirection       = SphericalDirection.FromVector(CameraLookTo - tr.Position);
            }
        }
示例#2
0
        void UpdateDisplayObject()
        {
            if (Scene == null)
            {
                return;
            }

            var import = ObjectOfPreview as Component_Import3D;

            if (import != null)
            {
                if (displayObject == null || displayObjectVersion != import.VersionForPreviewDisplay || materialPreviewMeshUsed != ProjectSettings.Get.MaterialPreviewMesh.Value)
                {
                    Scene.Enabled = false;

                    if (displayObject != null)
                    {
                        displayObject.RemoveFromParent(false);
                        displayObject.Dispose();
                    }

                    displayObject        = import.CreateForPreviewDisplay(Scene, out onlyOneMaterial, out _);
                    displayObjectVersion = import.VersionForPreviewDisplay;

                    Scene.Enabled = true;

                    materialPreviewMeshUsed = ProjectSettings.Get.MaterialPreviewMesh.Value;
                }
            }
        }
示例#3
0
 static bool CheckValidMeshWithMessageBox(Component_Mesh mesh)
 {
     if (!CommonFunctions.CheckValidMesh(mesh, out string error))
     {
         EditorMessageBox.ShowWarning(error);
         return(false);
     }
     return(true);
 }
示例#4
0
        /////////////////////////////////////////

        //Component_Skeleton.SkinningModeEnum GetSkinningMode( Component_Skeleton skeleton )
        //{
        //	var _override = OverrideSkinningMode.Value;
        //	if( _override != Component_Skeleton.SkinningModeEnum.Auto )
        //		return _override;

        //	var selected = skeleton.SkinningMode.Value;
        //	if( selected != Component_Skeleton.SkinningModeEnum.Auto )
        //		return selected;

        //	if( !hasScale )
        //		return Component_Skeleton.SkinningModeEnum.DualQuaternion;
        //	else
        //		return Component_Skeleton.SkinningModeEnum.Linear;
        //}

        protected virtual void CalculateCPU(Component_Skeleton skeleton, Component_Mesh originalMesh, Component_Mesh modifiableMesh)
        {
            bool dualQuaternion = false;            // GetSkinningMode( skeleton ) == Component_Skeleton.SkinningModeEnum.DualQuaternion;

            for (int nOper = 0; nOper < modifiableMesh.Result.MeshData.RenderOperations.Count; nOper++)
            {
                var sourceOper = originalMesh.Result.MeshData.RenderOperations[nOper];
                var destOper   = modifiableMesh.Result.MeshData.RenderOperations[nOper];

                var position = new ChannelFloat3(sourceOper, destOper, VertexElementSemantic.Position);
                if (position.Exists)
                {
                    var normal  = new ChannelFloat3(sourceOper, destOper, VertexElementSemantic.Normal);
                    var tangent = new ChannelFloat4(sourceOper, destOper, VertexElementSemantic.Tangent);

                    var blendIndices = new SourceChannel <Vector4I>(sourceOper, VertexElementSemantic.BlendIndices, VertexElementType.Integer4);
                    var blendWeights = new SourceChannel <Vector4F>(sourceOper, VertexElementSemantic.BlendWeights, VertexElementType.Float4);

                    if (!blendIndices.Exists || !blendWeights.Exists)
                    {
                        continue;
                    }

                    if (normal.Exists)
                    {
                        if (tangent.Exists)
                        {
                            TransformVertices(
                                dualQuaternion,
                                position.SourceData, normal.SourceData, tangent.SourceData, blendIndices.SourceData, blendWeights.SourceData,
                                position.DestData, normal.DestData, tangent.DestData
                                );
                        }
                        else
                        {
                            TransformVertices(
                                dualQuaternion,
                                position.SourceData, normal.SourceData, blendIndices.SourceData, blendWeights.SourceData,
                                position.DestData, normal.DestData
                                );
                        }
                    }
                    else
                    {
                        TransformVertices(
                            dualQuaternion,
                            position.SourceData, blendIndices.SourceData, blendWeights.SourceData,
                            position.DestData
                            );
                    }

                    position.WriteChannel();
                    normal.WriteChannel();
                    tangent.WriteChannel();
                }
            }
        }
示例#5
0
        protected override void OnDisabled()
        {
            mesh?.Dispose();
            mesh = null;

            //CreatedCubemapDispose();

            base.OnDisabled();
        }
示例#6
0
        protected override void OnEnabled()
        {
            base.OnEnabled();

            mesh = ComponentUtility.CreateComponent <Component_Mesh>(null, true, false);
            mesh.CreateComponent <Component_MeshGeometry_Box>();
            mesh.Enabled = true;

            processedCubemapNeedUpdate = true;
        }
示例#7
0
        /////////////////////////////////////////

        //detect what LOD is need. can be -1 when skip by visibility distance
        static int DetectDemandedLOD(ViewportRenderingContext context, Component_Mesh mesh, double objectVisibilityDistance, ref Vector3 objectPosition)
        {
            int demandLOD;

            var cameraSettings = context.Owner.CameraSettings;

            double maxDistance;

            if (mesh != null)
            {
                maxDistance = Math.Min(objectVisibilityDistance, mesh.VisibilityDistance);
            }
            else
            {
                maxDistance = objectVisibilityDistance;
            }

            if (maxDistance < cameraSettings.FarClipDistance && (cameraSettings.Position - objectPosition).LengthSquared() > maxDistance * maxDistance)
            {
                demandLOD = -1;
            }
            else
            {
                demandLOD = 0;

                if (mesh != null)
                {
                    var lods = mesh.Result.MeshData.LODs;
                    if (lods != null)
                    {
                        //!!!!что про дребежжание когда быстро туда сюда переключаться нужно?

                        var distanceSquared = (float)(objectPosition - cameraSettings.Position).LengthSquared() * context.renderingPipeline.LODScale.Value;
                        var range           = context.renderingPipeline.LODRange.Value.ToVector2I() - new Vector2I(1, 1);

                        for (int n = Math.Min(lods.Length - 1, range.Y); n >= 0; n--)
                        {
                            ref var lod = ref lods[n];

                            var lodDistanceSquared = lod.DistanceSquared;
                            if (distanceSquared > lodDistanceSquared || n <= range.X)
                            {
                                var lodMeshData = lod.Mesh?.Result?.MeshData;
                                if (lodMeshData != null)
                                {
                                    demandLOD = n + 1;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
示例#8
0
        protected override void OnEnabledInSimulation()
        {
            //create a mesh
            mesh      = CreateComponent <Component_Mesh>(enabled: false);
            mesh.Name = "Mesh 1";

            //generate vertices. use StandardVertex to make it easier
            StandardVertex.StaticOneTexCoord[] vertices = new StandardVertex.StaticOneTexCoord[4];

            var v = new StandardVertex.StaticOneTexCoord();

            v.Position = new Vector3F(-0.4f, -0.4f, 0f);
            v.Normal   = new Vector3F(0, 0, 1);
            v.Tangent  = new Vector4F(1, 0, 0, 0);
            v.Color    = new ColorValue(1, 1, 1);
            //v.TexCoord0 = new Vector2F(-1, -1);

            vertices[0] = v;

            v.Position  = new Vector3F(0.4f, -0.4f, 0);
            vertices[1] = v;

            v.Position  = new Vector3F(0.4f, 0.4f, 0);
            vertices[2] = v;

            v.Position  = new Vector3F(-0.4f, 0.4f, 0);
            vertices[3] = v;

            //generate indices
            var indices = new int[] { 0, 1, 2, 2, 3, 0 };

            //create geometry of the mesh
            geometry = mesh.CreateComponent <Component_MeshGeometry>();
            geometry.VertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            geometry.Vertices        = ConvertVertices(vertices);
            geometry.Indices         = indices;


            //mesh has been created, now we can enable it
            mesh.Enabled = true;

            meshInSpace           = CreateComponent <Component_MeshInSpace>(enabled: false);
            meshInSpace.Transform = new Transform(new Vector3(1, 1, 1));

            //make reference to the mesh. 'Root' reference - global path from scene root.
            meshInSpace.Mesh = ReferenceUtility.MakeRootReference(mesh);

            meshInSpace.Color   = new ColorValue(1, 0, 0);
            meshInSpace.Enabled = true;
        }
        private void ParentSprite_MeshOutputOverride(Component_MeshInSpace sender, ref Component_Mesh result)
        {
            var animation = PlayAnimation.Value as Component_SpriteAnimation;

            if (animation != null)
            {
                UpdateAnimationTime();

                var frame = animation.GetFrameByTime(currentAnimationTime);
                if (frame != null)
                {
                    result = SpriteMeshManager.GetMesh(frame.UV.Value.ToRectangleF());
                }
            }
        }
        protected override void CalculateCPU(Component_Skeleton skeleton, Component_Mesh originalMesh, Component_Mesh modifiableMesh)
        {
            if (EngineApp.ApplicationType == EngineApp.ApplicationTypeEnum.Simulation)
            {
                if (Component_Scene.All != null && Component_Scene.All.Length > 0)
                {
//					Component_MeshInSpace[] sphs = new Component_MeshInSpace[2];
//					Component_MeshInSpace sph = Component_Scene.All[0]?.GetComponent<Component_MeshInSpace>("chest");
//					sphs[0] = sph?.GetComponent<Component_MeshInSpace>("upper_arm.R");
//					sphs[1] = sphs[0]?.GetComponent<Component_MeshInSpace>("forearm.R");

//					var bones = skeleton?.GetBones(false);
//					if (bones != null)
//					{
//						var sR = Array.Find(bones, item => item.Name == "upper_arm.R");
//						sR.Transform = new Transform(sphs[0].TransformV.Position, sphs[0].TransformV.Rotation, sR.Transform.Value.Scale);
//						var sR1 = Array.Find(bones, item => item.Name == "forearm.R");
//						sR1.Transform = new Transform(sphs[1].TransformV.Position, sphs[1].TransformV.Rotation, sR1.Transform.Value.Scale);

//					}

                    Component_MeshInSpace sph = Component_Scene.All[0]?.GetComponent <Component_MeshInSpace>("chest");
                    var sphch = sph.GetComponents <Component_MeshInSpace>(false, true, false);

                    var bones = skeleton?.GetBones(false);
                    if (bones != null)
                    {
                        var sR = Array.Find(bones, item => item.Name == "chest");
                        sR.Transform = new Transform(sph.TransformV.Position, sph.TransformV.Rotation, sR.Transform.Value.Scale);
                        var chB = sR.GetComponents <Component_SkeletonBone>(false, true, false);

                        for (int i = 0; i < chB.Length; i = i + 1)
                        {
                            var cursph = Array.Find(sphch, item => item.Name == chB[i].Name);
                            if (cursph != null)
                            {
                                chB[i].Transform = new Transform(cursph.TransformV.Position, cursph.TransformV.Rotation, chB[i].Transform.Value.Scale);
                            }
                        }
                    }
                }

                MainViewport_UpdateBeforeOutput(Project.SimulationApp.MainViewport, skeleton);
                base.CalculateCPU(skeleton, originalMesh, modifiableMesh);
            }
        }
示例#11
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            var scene = CreateScene(false);

            Component_Mesh mesh = ObjectForPreview as Component_Mesh;

            if (mesh != null)
            {
                Component_MeshInSpace objInSpace = scene.CreateComponent <Component_MeshInSpace>();
                objInSpace.Mesh = mesh;
            }

            scene.Enabled = true;

            SetCameraByBounds(scene.CalculateTotalBoundsOfObjectsInSpace());
        }
示例#12
0
        public static Component_Mesh GetBillboardMesh()
        {
            if (billboardMesh == null || billboardMesh.Disposed)
            {
                billboardMesh = null;
            }

            if (billboardMesh == null)
            {
                var mesh     = ComponentUtility.CreateComponent <Component_Mesh>(null, true, false);
                var geometry = mesh.CreateComponent <Component_MeshGeometry_Plane>();
                geometry.Axis  = 1;
                mesh.Billboard = true;
                mesh.Enabled   = true;

                billboardMesh = mesh;
            }

            return(billboardMesh);
        }
示例#13
0
            public void Generate(Component_Mesh mesh, string writeRealFileName)
            {
                this.mesh = mesh;
                Init();

                //create scene
                var scene = CreateScene(false);

                if (mesh != null)
                {
                    var objInSpace = scene.CreateComponent <Component_MeshInSpace>();
                    objInSpace.Mesh = mesh;
                }
                scene.Enabled = true;

                //generate an image
                {
                    viewport.Update(true);

                    //clear temp data
                    viewport.RenderingContext.MultiRenderTarget_DestroyAll();
                    viewport.RenderingContext.DynamicTexture_DestroyAll();

                    texture.Result.GetRealObject(true).BlitTo(viewport.RenderingContext.CurrentViewNumber, textureRead.Result.GetRealObject(true), 0, 0);

                    var demandedFrame = textureRead.Result.GetRealObject(true).Read(imageData, 0);

                    while (RenderingSystem.CallBgfxFrame() < demandedFrame)
                    {
                    }
                }

                //write png
                if (!ImageUtility.Save(writeRealFileName, imageData, imageSizeRender, 1, imageFormat, 1, 0, out var error))
                {
                    throw new Exception(error);
                }

                DetachAndOrDestroyScene();
                Shutdown();
            }
示例#14
0
            //

            public Item(RectangleF uv)
            {
                UV         = uv;
                EngineTime = Time.Current;

                var vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);

                var positions = new Vector3F[] { new Vector3F(-0.5f, -0.5f, 0), new Vector3F(0.5f, -0.5f, 0), new Vector3F(0.5f, 0.5f, 0), new Vector3F(-0.5f, 0.5f, 0) };
                var texCoords = new Vector2F[] { uv.LeftTop, uv.RightTop, uv.RightBottom, uv.LeftBottom };

                var vertices = new byte[vertexSize * positions.Length];

                unsafe
                {
                    fixed(byte *pVertices = vertices)
                    {
                        StandardVertex.StaticOneTexCoord *pVertex = (StandardVertex.StaticOneTexCoord *)pVertices;

                        for (int n = 0; n < positions.Length; n++)
                        {
                            pVertex->Position  = positions[n];
                            pVertex->Normal    = new Vector3F(0, 0, 1);
                            pVertex->Tangent   = new Vector4F(1, 0, 0, -1);
                            pVertex->Color     = new ColorValue(1, 1, 1, 1);
                            pVertex->TexCoord0 = texCoords[n];

                            pVertex++;
                        }
                    }
                }

                var mesh     = ComponentUtility.CreateComponent <Component_Mesh>(null, true, false);
                var geometry = mesh.CreateComponent <Component_MeshGeometry>();

                geometry.VertexStructure = vertexStructure;
                geometry.Vertices        = vertices;
                geometry.Indices         = new int[] { 0, 1, 2, 2, 3, 0 };
                mesh.Enabled             = true;

                Mesh = mesh;
            }
示例#15
0
        static void ResetToOriginalMesh(Component_Mesh originalMesh, Component_Mesh modifiableMesh)
        {
            for (int nOper = 0; nOper < modifiableMesh.Result.MeshData.RenderOperations.Count; nOper++)
            {
                var sourceOper = originalMesh.Result.MeshData.RenderOperations[nOper];
                var destOper   = modifiableMesh.Result.MeshData.RenderOperations[nOper];

                var channelsSemantic = new[] { VertexElementSemantic.Position, VertexElementSemantic.Normal, VertexElementSemantic.Tangent, VertexElementSemantic.Bitangent };
                foreach (var semantic in channelsSemantic)
                {
                    var channel = new ChannelFloat3(sourceOper, destOper, semantic);
                    if (channel.Exists)
                    {
                        for (int n = 0; n < channel.DestData.Length; n++)
                        {
                            channel.DestData[n] = channel.SourceData[n];
                        }
                        channel.WriteChannel();
                    }
                }
            }
        }
        void UpdatePreviewMesh()
        {
            var mesh = ProjectSettings.Get.MaterialPreviewMesh.Value;

            previewMeshUsed = mesh;

            if (mesh == null)
            {
                if (defaultMesh == null)
                {
                    //sphere if null
                    defaultMesh = Scene.CreateComponent <Component_Mesh>(enabled: false);
                    var sphere = defaultMesh.CreateComponent <Component_MeshGeometry_Sphere>();
                    sphere.SegmentsHorizontal = 64;
                    sphere.SegmentsVertical   = 64;
                    defaultMesh.Enabled       = true;
                }
                mesh = defaultMesh;
            }

            var meshInSpace = (Component_MeshInSpace)Scene.GetComponent("Mesh In Space");

            meshInSpace.Mesh = mesh;
        }
示例#17
0
        unsafe static void MeshGetIsBillboard(ImportContext context, Component_Mesh destinationMesh)
        {
            bool isBillboard = false;

            var geometries = destinationMesh.GetComponents <Component_MeshGeometry>();

            if (geometries.Length == 1)
            {
                var geometry = geometries[0];

                try
                {
                    var vertexStructure = geometry.VertexStructure.Value;
                    var vertices        = geometry.Vertices.Value;
                    var indices         = geometry.Indices.Value;

                    if (vertexStructure?.Length != 0 && vertices?.Length != 0 && indices?.Length != 0)
                    {
                        vertexStructure.GetInfo(out var vertexSize, out _);
                        int vertexCount = vertices.Length / vertexSize;

                        if (indices.Length >= 3)
                        {
                            if (vertexStructure.GetElementBySemantic(VertexElementSemantic.Position, out var positionElement))
                            {
                                if (positionElement.Type == VertexElementType.Float3 && positionElement.Source == 0)
                                {
                                    int offset = positionElement.Offset;

                                    var p = new Vector3[vertexCount];
                                    for (int nVertex = 0; nVertex < vertexCount; nVertex++)
                                    {
                                        fixed(byte *pVertices = vertices)
                                        p[nVertex] = *(Vector3F *)(pVertices + nVertex * vertexSize + offset);
                                    }

                                    var normal1 = Plane.FromPoints(p[indices[0]], p[indices[1]], p[indices[2]]).Normal;
                                    if (Math.Abs(normal1.X) > 0.95f || Math.Abs(normal1.Y) > 0.95f)
                                    {
                                        bool canBeBillboard = true;

                                        for (int nTriangle = 0; nTriangle < indices.Length / 3; nTriangle++)
                                        {
                                            var index0  = indices[nTriangle * 3 + 0];
                                            var index1  = indices[nTriangle * 3 + 1];
                                            var index2  = indices[nTriangle * 3 + 2];
                                            var normal2 = Plane.FromPoints(p[index0], p[index1], p[index2]).Normal;

                                            if (!normal1.Equals(normal2, 0.01))
                                            {
                                                canBeBillboard = false;
                                                break;
                                            }
                                        }

                                        if (canBeBillboard)
                                        {
                                            isBillboard = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.Warning(e.Message);
                }
            }

            if (isBillboard)
            {
                destinationMesh.Billboard = true;

                foreach (var geometry in geometries)
                {
                    if (context.materialByIndex.TryGetValue(-1, out var material))
                    {
                        geometry.Material = ReferenceUtility.MakeRootReference(material);
                    }
                }
            }
        }
示例#18
0
        //Component_MeshInSpace contains only one Component_Mesh.
        static void MergeGeometries(Component_Mesh mesh, DocumentInstance document, UndoMultiAction undo)
        {
            Component_MeshGeometry[] geometries = mesh.GetComponents <Component_MeshGeometry>();
            if (geometries == null || geometries.Length < 2)
            {
                return;
            }

            Reference <Component_Material> material = geometries[0].Material;
            //for( int i = 1; i < geometries.Length; i++ )
            //{
            //	if( !( material.Value == null && geometries[ i ].Material.Value == null || material.Equals( geometries[ i ].Material ) ) )
            //	{
            //		//??? Если разные Material какой вариант лучше: 1) Брать из первого geometry с вопросом в MessageBox; 2) Disable в меню для Action. 3) Соединять те, которые с одинаковым материалом.
            //		if( EditorMessageBox.ShowQuestion( "Mesh geometries have different materials. Merge them using a material from the first geometry?", MessageBoxButtons.OKCancel ) == DialogResult.Cancel )
            //		{
            //			return;
            //		}
            //	}
            //}

            var extracted = mesh.ExtractStructure();

            var newIndices         = new List <int>();
            var newVertices        = new List <byte>();
            var newVertexStructure = extracted.MeshGeometries[0].VertexStructure;
            var newVertexFormat    = new MeshData.MeshGeometryFormat(newVertexStructure);

            for (int geomIndex = 0; geomIndex < extracted.MeshGeometries.Length; geomIndex++)
            {
                var g = extracted.MeshGeometries[geomIndex];


                if (g.Vertices == null || g.Indices == null)
                {
                    continue;
                }
                int indexOffset = newVertices.Count / newVertexFormat.vertexSize;

                for (int i = 0; i < g.Indices.Length; i++)
                {
                    newIndices.Add(g.Indices[i] + indexOffset);
                }

                if (!CommonFunctions.IsSameVertexStructure(newVertexStructure, g.VertexStructure))
                {
                    g.Vertices = MeshData.ConvertToFormat(new MeshData.MeshGeometryFormat(g.VertexStructure), g.Vertices, newVertexFormat);
                }

                newVertices.AddRange(g.Vertices);

                foreach (var face in extracted.Structure.Faces)
                {
                    for (int i = 0; i < face.Triangles.Length; i++)
                    {
                        if (face.Triangles[i].RawGeometry == geomIndex)
                        {
                            face.Triangles[i].RawGeometry = 0;
                            face.Triangles[i].RawVertex  += indexOffset;
                        }
                    }
                }
            }

            // changes in the mesh

            if (undo != null)
            {
                //add structure update to undo
                var property = (Metadata.Property)mesh.MetadataGetMemberBySignature("property:" + nameof(Component_Mesh.Structure));
                undo.AddAction(new UndoActionPropertiesChange(new UndoActionPropertiesChange.Item(mesh, property, mesh.Structure?.Clone())));
            }

            bool meshWasEnabled = mesh.Enabled;

            mesh.Enabled = false;
            try
            {
                var newGeometry = mesh.CreateComponent <Component_MeshGeometry>();
                newGeometry.Material = material;

                newGeometry.Vertices        = newVertices.ToArray();
                newGeometry.Indices         = newIndices.ToArray();
                newGeometry.VertexStructure = newVertexStructure;

                //add created geometry to undo
                undo?.AddAction(new UndoActionComponentCreateDelete(document, new Component[] { newGeometry }, create: true));

                mesh.Structure = extracted.Structure;

                //delete old mesh geometry
                undo?.AddAction(new UndoActionComponentCreateDelete(document, geometries, create: false));

                newGeometry.Name = CommonFunctions.GetUniqueFriendlyName(newGeometry);
            }
            finally
            {
                mesh.Enabled = meshWasEnabled;
            }
        }
示例#19
0
        public unsafe static void GetDemandedLODs(ViewportRenderingContext context, Component_Mesh mesh, float cameraDistanceMinSquared, float cameraDistanceMaxSquared, out LodState lodState)
        {
            //var cameraDistanceMinSquared2 = cameraDistanceMinSquared;
            //var cameraDistanceMaxSquared2 = cameraDistanceMaxSquared;

            ////!!!!fix for shadows. в случае простых билбордов тень рисуется дальше объекта другого лода, резко пропадает
            //cameraDistanceRangeSquared2.Maximum *= 1.1f;


            lodState = new LodState();

            var lods = mesh.Result.MeshData.LODs;

            if (lods != null)
            {
                RangeF GetLodRange(int lodIndex)
                {
                    if (lodIndex == 0)
                    {
                        return(new RangeF(0, lods[0].Distance));
                    }
                    else
                    {
                        var arrayIndex = lodIndex - 1;

                        var lod = lods[arrayIndex];

                        float far;
                        if (arrayIndex + 1 < lods.Length)
                        {
                            far = lods[arrayIndex + 1].Distance;
                        }
                        else
                        {
                            far = 1000000.0f;
                        }

                        return(new RangeF(lod.Distance, far));
                    }
                }

                var lodCount = lods.Length + 1;

                var pipeline        = context.renderingPipeline;
                var contextLodRange = pipeline.LODRange.Value;
                var contextLodScale = (float)pipeline.LODScale.Value;

                var lodStart = contextLodRange.Minimum;
                var lodEnd   = Math.Min(lodCount - 1, contextLodRange.Maximum);
                if (lodStart > lodEnd)
                {
                    lodStart = lodEnd;
                }

                for (int lodIndex = lodStart; lodIndex <= lodEnd; lodIndex++)
                {
                    var lodRange = GetLodRange(lodIndex) * contextLodScale;
                    if (lodIndex == lodStart)
                    {
                        lodRange.Minimum = 0;
                    }
                    if (lodIndex == lodEnd)
                    {
                        lodRange.Maximum = 1000000;
                    }

                    var min        = lodRange.Minimum * 0.9f;
                    var minSquared = min * min;

                    var max        = lodRange.Maximum;
                    var maxSquared = max * max;

                    //early exit
                    if (minSquared > cameraDistanceMaxSquared)
                    {
                        break;
                    }

                    if (cameraDistanceMaxSquared >= minSquared && cameraDistanceMinSquared < maxSquared)
                    {
                        lodState.Add(lodIndex, lodRange);
                    }
                }

                if (lodState.Count == 0)
                {
                    lodState.Add(lodEnd, new RangeF(0, 1000000));
                }

                lodState.FixMinMax();
            }
            else
            {
                lodState.Add(0, new RangeF(0, 1000000));
            }
        }
示例#20
0
        public static bool ExportToFBX(Component_Mesh sourceMesh, string realFileName, out string error)
        {
            //!!!!как для Vegetation. оверрайдить в Component_Mesh?

            //get mesh data
            var operations = new List <Component_RenderingPipeline.RenderSceneData.MeshDataRenderOperation>();

            foreach (var geometry in sourceMesh.GetComponents <Component_MeshGeometry>())
            {
                if (geometry.Enabled)
                {
                    geometry.CompileDataOfThisObject(out var operation);
                    if (operation != null)
                    {
                        operations.Add(operation);
                    }
                }
            }
            //foreach( var geometry in mesh.Result.MeshData.RenderOperations )
            //{
            //}

            FbxManager    manager  = null;
            FbxIOSettings setting  = null;
            FbxExporter   exporter = null;
            FbxScene      scene    = null;

            try
            {
                //init FBX manager
                manager = FbxManager.Create();
                setting = FbxIOSettings.Create(manager, "IOSRoot");
                manager.SetIOSettings(setting);

                scene = FbxScene.Create(manager, "scene");
                scene.GetGlobalSettings().SetAxisSystem(new FbxAxisSystem(FbxAxisSystem.EPreDefinedAxisSystem.eMax));
                scene.GetGlobalSettings().SetSystemUnit(new FbxSystemUnit(100));

                //init FBX scene
                for (int nOper = 0; nOper < operations.Count; nOper++)
                {
                    var oper = operations[nOper];

                    //get data

                    Vector3F[]   positions = null;
                    Vector3F[]   normals   = null;
                    var          texCoords = new List <Vector2F[]>();
                    ColorValue[] colors    = null;
                    Vector3F[]   tangents  = null;
                    Vector3F[]   binormals = null;

                    //Position
                    {
                        if (oper.VertexStructure.GetElementBySemantic(VertexElementSemantic.Position, out VertexElement element) && element.Type == VertexElementType.Float3)
                        {
                            var buffer = oper.VertexBuffers[element.Source];
                            positions = buffer.ExtractChannel <Vector3F>(element.Offset);
                        }
                    }

                    //Normal
                    {
                        if (oper.VertexStructure.GetElementBySemantic(VertexElementSemantic.Normal, out VertexElement element) && element.Type == VertexElementType.Float3)
                        {
                            var buffer = oper.VertexBuffers[element.Source];
                            normals = buffer.ExtractChannel <Vector3F>(element.Offset);
                        }
                    }

                    //TexCoord
                    for (var channel = VertexElementSemantic.TextureCoordinate0; channel <= VertexElementSemantic.TextureCoordinate3; channel++)
                    {
                        if (oper.VertexStructure.GetElementBySemantic(channel, out VertexElement element) && element.Type == VertexElementType.Float2)
                        {
                            var buffer = oper.VertexBuffers[element.Source];
                            texCoords.Add(buffer.ExtractChannel <Vector2F>(element.Offset));
                        }
                    }

                    //Color
                    {
                        if (oper.VertexStructure.GetElementBySemantic(VertexElementSemantic.Color0, out VertexElement element))
                        {
                            if (element.Type == VertexElementType.Float4)
                            {
                                var buffer = oper.VertexBuffers[element.Source];
                                var values = buffer.ExtractChannel <Vector4F>(element.Offset);
                                colors = new ColorValue[positions.Length];
                                int destIndex = 0;
                                foreach (var p in values)
                                {
                                    colors[destIndex++] = p.ToColorValue();
                                }
                            }
                            else if (element.Type == VertexElementType.ColorABGR)
                            {
                                //!!!!check

                                var buffer = oper.VertexBuffers[element.Source];
                                var values = buffer.ExtractChannel <uint>(element.Offset);
                                colors = new ColorValue[positions.Length];
                                int destIndex = 0;
                                foreach (var p in values)
                                {
                                    colors[destIndex++] = new ColorValue(ColorByte.FromABGR(p));
                                }
                            }
                            else if (element.Type == VertexElementType.ColorARGB)
                            {
                                //!!!!check

                                var buffer = oper.VertexBuffers[element.Source];
                                var values = buffer.ExtractChannel <uint>(element.Offset);
                                colors = new ColorValue[positions.Length];
                                int destIndex = 0;
                                foreach (var p in values)
                                {
                                    colors[destIndex++] = new ColorValue(ColorByte.FromARGB(p));
                                }
                            }
                        }
                    }

                    //Tangent, Binormal
                    if (normals != null)
                    {
                        if (oper.VertexStructure.GetElementBySemantic(VertexElementSemantic.Tangent, out VertexElement element) && element.Type == VertexElementType.Float4)
                        {
                            var buffer    = oper.VertexBuffers[element.Source];
                            var tangents4 = buffer.ExtractChannel <Vector4F>(element.Offset);

                            tangents  = new Vector3F[tangents4.Length];
                            binormals = new Vector3F[tangents4.Length];

                            int destIndex = 0;
                            foreach (var p in tangents4)
                            {
                                tangents[destIndex]  = p.ToVector3F();
                                binormals[destIndex] = Vector3F.Cross(p.ToVector3F(), normals[destIndex]) * p.W;
                                destIndex++;
                            }
                        }
                    }

                    //indices
                    int[] indices = null;
                    if (oper.IndexBuffer != null)
                    {
                        indices = oper.IndexBuffer.Indices;
                    }


                    //create geometry

                    var geometryName = "Geometry " + nOper.ToString();
                    var mesh         = FbxMesh.Create(scene, geometryName);

                    mesh.InitControlPoints(positions.Length);

                    FbxLayerElementNormal elementNormals = null;
                    if (normals != null)
                    {
                        elementNormals = mesh.CreateElementNormal();
                        elementNormals.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);
                        elementNormals.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);
                    }

                    FbxLayerElementVertexColor elementColors = null;
                    if (colors != null)
                    {
                        elementColors = mesh.CreateElementVertexColor();
                        elementColors.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);
                        elementColors.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);
                    }

                    FbxLayerElementTangent elementTangents = null;
                    if (tangents != null)
                    {
                        elementTangents = mesh.CreateElementTangent();
                        elementTangents.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);
                        elementTangents.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);
                    }

                    FbxLayerElementBinormal elementBinormals = null;
                    if (binormals != null)
                    {
                        elementBinormals = mesh.CreateElementBinormal();
                        elementBinormals.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);
                        elementBinormals.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);
                    }

                    var uvElements = new List <FbxLayerElementUV>();
                    for (int uvIndex = 0; uvIndex < texCoords.Count; uvIndex++)
                    {
                        var pUVElement = mesh.CreateElementUV("texcoord" + uvIndex.ToString());
                        pUVElement.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);
                        pUVElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);

                        uvElements.Add(pUVElement);
                    }

                    for (int n = 0; n < positions.Length; n++)
                    {
                        mesh.SetControlPointAt(ToFbxVector4(positions[n]), n);

                        if (normals != null)
                        {
                            elementNormals.GetDirectArray().Add(ToFbxVector4(normals[n]));
                        }

                        for (int uvIndex = 0; uvIndex < texCoords.Count; uvIndex++)
                        {
                            var texCoord = texCoords[uvIndex][n];
                            texCoord.Y = 1.0f - texCoord.Y;
                            uvElements[uvIndex].GetDirectArray().Add(ToFbxVector2(texCoord));
                        }

                        if (colors != null)
                        {
                            elementColors.GetDirectArray().Add(ToFbxColor(colors[n]));
                        }

                        if (tangents != null)
                        {
                            elementTangents.GetDirectArray().Add(ToFbxVector4(tangents[n]));
                        }

                        if (binormals != null)
                        {
                            elementBinormals.GetDirectArray().Add(ToFbxVector4(binormals[n]));
                        }
                    }

                    if (normals != null)
                    {
                        mesh.GetLayer(0).SetNormals(elementNormals);
                    }
                    if (colors != null)
                    {
                        mesh.GetLayer(0).SetVertexColors(elementColors);
                    }
                    if (tangents != null)
                    {
                        mesh.GetLayer(0).SetTangents(elementTangents);
                    }
                    if (binormals != null)
                    {
                        mesh.GetLayer(0).SetBinormals(elementBinormals);
                    }


                    int polygonCount = indices.Length / 3;
                    for (int i = 0; i < polygonCount; i++)
                    {
                        mesh.BeginPolygon(-1, -1, -1, false);
                        for (int j = 0; j < 3; j++)
                        {
                            int currentIndex = i * 3 + j;
                            int vertexIndex  = indices[currentIndex];
                            mesh.AddPolygon(vertexIndex);
                        }
                        mesh.EndPolygon();
                    }

                    var node = FbxNode.Create(scene, geometryName);
                    node.SetNodeAttribute(mesh);

                    scene.GetRootNode().AddChild(mesh.GetNode());
                }

                //save

                exporter = FbxExporter.Create(manager, "");
                if (!exporter.Initialize(realFileName, -1, manager.GetIOSettings()))
                {
                    error = "Can't initialize FBX exporter.";
                    return(false);
                }

                if (!exporter.Export(scene))
                {
                    error = "Export to FBX failed.";
                    return(false);
                }
            }
            finally
            {
                try { scene?.Destroy(); } catch { }
                try { exporter?.Destroy(); } catch { }
                try { setting?.Destroy(); } catch { }
                try { manager?.Destroy(); } catch { }
            }

            foreach (var op in operations)
            {
                op.DisposeBuffers();
            }

            error = "";
            return(true);
        }
        static void ConvertProceduralMeshGeometries(DocumentInstance document, Component_Mesh mesh, UndoMultiAction undoMultiAction, ref bool needUndoForNextActions)
        {
            //needUndoForNextActions = true;

            var meshGeometries = mesh.GetComponents <Component_MeshGeometry>();

            if (meshGeometries.Any(g => g is Component_MeshGeometry_Procedural))
            {
                //!!!!?
                bool hasOrdinary = meshGeometries.Any(g => !(g is Component_MeshGeometry_Procedural));
                if (!hasOrdinary)
                {
                    needUndoForNextActions = false;                     //??? Если были и обычные geometry и procedural? Как правильно needUndoForNextActions? Пока так: undo не нужен только если все procedural
                }
                //!!!!right? !needUndoForNextActions
                if (undoMultiAction != null && !needUndoForNextActions)
                {
                    //add structure update to undo
                    var property = (Metadata.Property)mesh.MetadataGetMemberBySignature("property:" + nameof(Component_Mesh.Structure));
                    undoMultiAction.AddAction(new UndoActionPropertiesChange(new UndoActionPropertiesChange.Item(mesh, property, mesh.Structure?.Clone())));
                }

                for (int i = 0; i < meshGeometries.Length; i++)
                {
                    var meshGeometry = meshGeometries[i];

                    //convert to usual Component_MeshGeometry
                    if (meshGeometry is Component_MeshGeometry_Procedural meshGeometryProcedural)
                    {
                        VertexElement[]               vertexStructure = null;
                        byte[]                        vertices        = null;
                        int[]                         indices         = null;
                        Component_Material            material        = null;
                        Component_Mesh.StructureClass structure       = null;
                        meshGeometryProcedural.GetProceduralGeneratedData(ref vertexStructure, ref vertices, ref indices, ref material, ref structure);

                        var insertIndex = meshGeometryProcedural.Parent.Components.IndexOf(meshGeometryProcedural);

                        var meshGeometryNew = mesh.CreateComponent <Component_MeshGeometry>(insertIndex);
                        meshGeometryNew.Name            = meshGeometry.Name;
                        meshGeometryNew.VertexStructure = vertexStructure;
                        meshGeometryNew.Vertices        = vertices;
                        meshGeometryNew.Indices         = indices;

                        meshGeometryNew.Material = meshGeometryProcedural.Material;

                        //concut structures. If the geometry is procedural it is not in a structure yet.
                        mesh.Structure = Component_Mesh.StructureClass.Concat(mesh.Structure, structure, i);

                        //delete old mesh geometry
                        if (undoMultiAction != null)
                        {
                            undoMultiAction.AddAction(new UndoActionComponentCreateDelete(document, new Component[] { meshGeometry }, create: false));
                        }
                        else
                        {
                            meshGeometry.Dispose();
                        }

                        //add created geometry to undo
                        if (undoMultiAction != null)
                        {
                            undoMultiAction.AddAction(new UndoActionComponentCreateDelete(document, new Component[] { meshGeometryNew }, create: true));
                        }
                    }
                }
            }
        }