//void ParentSprite_GetRenderSceneDataBefore( Component_ObjectInSpace sender, ViewportRenderingContext context, GetRenderSceneDataMode mode )
        //{
        //}

        private void ParentSprite_GetRenderSceneDataAddToFrameData(Component_MeshInSpace sender, ViewportRenderingContext context, GetRenderSceneDataMode mode, ref Component_RenderingPipeline.RenderSceneData.MeshItem item)
        {
            Component_Material material = null;

            var animation = PlayAnimation.Value as Component_SpriteAnimation;

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

                material = animation.Material;

                var frame = animation.GetFrameByTime(currentAnimationTime);
                if (frame != null)
                {
                    var m = frame.Material.Value;
                    if (m != null)
                    {
                        material = m;
                    }
                }
            }

            item.ReplaceMaterial            = material;
            item.ReplaceMaterialSelectively = null;
        }
        internal void CompileDataOfThisObject(Component_Mesh.CompiledData compiledData)          // Component_Mesh mesh, Component_Mesh.CompiledData result )
        {
            VertexElement[] vertexStructureV = VertexStructure;
            UnwrappedUVEnum unwrappedUVV     = UnwrappedUV;

            byte[]             verticesV = Vertices;
            int[]              indicesV  = Indices;
            Component_Material materialV = Material;

            Component_Mesh.StructureClass structure = null;

            OnGetDataOfThisObject(ref vertexStructureV, ref verticesV, ref indicesV, ref materialV, ref structure);
            GetDataOfThisObjectEvent?.Invoke(this, ref vertexStructureV, ref verticesV, ref indicesV, ref materialV, ref structure);

            //add to result
            if (vertexStructureV != null && vertexStructureV.Length != 0 && verticesV != null && verticesV.Length != 0 && (indicesV == null || indicesV.Length != 0))
            {
                vertexStructureV.GetInfo(out var vertexSize, out var holes);
                //if( !holes )
                {
                    int vertexCount = verticesV.Length / vertexSize;

                    var op = new Component_RenderingPipeline.RenderSceneData.MeshDataRenderOperation(this);

                    op.VertexStructure = vertexStructureV;
                    op.VertexStructureContainsColor = op.VertexStructure.Any(e => e.Semantic == VertexElementSemantic.Color0);
                    op.UnwrappedUV = unwrappedUVV;

                    var vertexDeclaration = op.VertexStructure.CreateVertexDeclaration(0);
                    op.VertexBuffers     = new GpuVertexBuffer[] { GpuBufferManager.CreateVertexBuffer(verticesV, vertexDeclaration) };
                    op.VertexStartOffset = 0;
                    op.VertexCount       = vertexCount;

                    if (indicesV != null)
                    {
                        op.IndexBuffer      = GpuBufferManager.CreateIndexBuffer(indicesV);
                        op.IndexStartOffset = 0;
                        op.IndexCount       = indicesV.Length;
                    }

                    //!!!!так?
                    op.Material = materialV;

                    compiledData.MeshData.RenderOperations.Add(op);

                    //!!!!может мержить когда несколько. индексы MeshGeometry в RawVertices
                    if (compiledData.MeshData.Structure == null)
                    {
                        compiledData.MeshData.Structure = structure;
                    }
                }
                //else
                //{
                //	//!!!!!error
                //}
            }
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            Component_Material material = ObjectOfPreview as Component_Material;

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

                var meshInSpace = scene.CreateComponent <Component_MeshInSpace>();
                meshInSpace.Name            = "Mesh In Space";
                meshInSpace.ReplaceMaterial = material;

                UpdatePreviewMesh();
                UpdatePreviewEnvironment();

                scene.Enabled = true;
            }

            SetCameraByBounds(Scene.CalculateTotalBoundsOfObjectsInSpace());
        }
Exemple #4
0
 public abstract void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure);
Exemple #5
0
 protected override void OnGetDataOfThisObject(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
 {
     GetProceduralGeneratedData(ref vertexStructure, ref vertices, ref indices, ref material, ref structure);
 }
Exemple #6
0
        /////////////////////////////////////////

        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            //!!!!!можно было бы не обновлять если такие же параметры

            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            Vector3F[] positions;
            Vector3F[] normals;
            Vector4F[] tangents;
            Vector2F[] texCoords;
            SimpleMeshGenerator.Face[] faces;

            if (SphereType.Value == SphereTypeEnum.GeoSphere)
            {
                SimpleMeshGenerator.GenerateSphere(Radius, SegmentsHorizontal, SegmentsVertical, InsideOut, out positions, out normals, out tangents, out texCoords, out indices, out faces);
            }
            else
            {
                SimpleMeshGenerator.GenerateIcoSphere(Radius, Subdivisions.Value, InsideOut, out positions, out normals, out tangents, out texCoords, out indices, out faces);
            }

            if (faces != null)
            {
                structure = SimpleMeshGenerator.CreateMeshStructure(faces);
            }

            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    = normals[n];
                        pVertex->Tangent   = tangents[n];
                        pVertex->Color     = new ColorValue(1, 1, 1, 1);
                        pVertex->TexCoord0 = texCoords[n];

                        pVertex++;
                    }
                }
            }
        }
Exemple #7
0
        ////InsideOut
        //ReferenceField<bool> _insideOut = false;
        //[DefaultValue( false )]
        //[Serialize]
        //public Reference<bool> InsideOut
        //{
        //	get
        //	{
        //		if( _insideOut.BeginGet() )
        //			InsideOut = _insideOut.Get( this );
        //		return _insideOut.value;
        //	}
        //	set
        //	{
        //		if( _insideOut.BeginSet( ref value ) )
        //		{
        //			try
        //			{
        //				InsideOutChanged?.Invoke( this );
        //				ShouldRecompileMesh();
        //			}
        //			finally { _insideOut.EndSet(); }
        //		}
        //	}
        //}
        //public event Action<Component_MeshGeometry_Plane> InsideOutChanged;

        //!!!!!by tesselation modifier?

        ////SegmentsHorizontal
        //Reference<int> segmentsHorizontal = 32;
        //[Serialize]
        //public virtual Reference<int> SegmentsHorizontal
        //{
        //	get
        //	{
        //		if( !string.IsNullOrEmpty( segmentsHorizontal.GetByReference ) )
        //			SegmentsHorizontal = segmentsHorizontal.GetValue( this );
        //		return segmentsHorizontal;
        //	}
        //	set
        //	{
        //		if( segmentsHorizontal == value ) return;
        //		segmentsHorizontal = value;
        //		SegmentsHorizontalChanged?.Invoke( this );
        //	}
        //}
        //public event Action<Component_MeshData_Parallelepiped> SegmentsHorizontalChanged;


        ////SegmentsVertical
        //Reference<int> segmentsVertical = 32;
        //[Serialize]
        //public virtual Reference<int> SegmentsVertical
        //{
        //	get
        //	{
        //		if( !string.IsNullOrEmpty( segmentsVertical.GetByReference ) )
        //			SegmentsVertical = segmentsVertical.GetValue( this );
        //		return segmentsVertical;
        //	}
        //	set
        //	{
        //		if( segmentsVertical == value ) return;
        //		segmentsVertical = value;
        //		SegmentsVerticalChanged?.Invoke( this );
        //	}
        //}
        //public event Action<Component_MeshData_Parallelepiped> SegmentsVerticalChanged;

        /////////////////////////////////////////

        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            var dimensions = Dimensions.Value;

            //if( InsideOut )
            //	dimensions = -dimensions;

            SimpleMeshGenerator.GenerateSegmentedPlane(Axis, dimensions.ToVector2F(), Segments.Value, UVTilesPerUnit.Value.ToVector2F(), UVTilesInTotal.Value.ToVector2F(), out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out indices, out var faces);
Exemple #8
0
        void MaterialNewObjectCreateShaderGraph(Component_Material material, NewMaterialData data, out Component_FlowGraph graph)
        {
            graph                = material.CreateComponent <Component_FlowGraph>();
            graph.Name           = "Shader graph";
            graph.Specialization = ReferenceUtility.MakeReference(
                MetadataManager.GetTypeOfNetType(typeof(Component_FlowGraphSpecialization_Shader)).Name + "|Instance");

            {
                var node = graph.CreateComponent <Component_FlowGraphNode>();
                node.Name             = "Node " + "Material";    //Name;
                node.Position         = new Vector2I(10, -7);
                node.ControlledObject = ReferenceUtility.MakeThisReference(node, material);
            }

            //configure
            {
                const int step     = 9;
                Vector2I  position = new Vector2I(-20, -data.GetTextureCount() * step / 2);

                //BaseColor
                if (!string.IsNullOrEmpty(data.BaseColorTexture))
                {
                    var node = graph.CreateComponent <Component_FlowGraphNode>();
                    node.Name     = "Node Texture Sample " + "BaseColor";
                    node.Position = position;
                    position.Y   += step;

                    var sample = node.CreateComponent <Component_ShaderTextureSample>();
                    sample.Name    = ComponentUtility.GetNewObjectUniqueName(sample);
                    sample.Texture = new Reference <Component_Image>(null, data.BaseColorTexture);

                    node.ControlledObject = ReferenceUtility.MakeThisReference(node, sample);

                    material.BaseColor = ReferenceUtility.MakeThisReference(material, sample, "RGBA");
                }
                //else if( data.BaseColor.HasValue )
                //	BaseColor = data.BaseColor.Value;

                //Metallic
                if (!string.IsNullOrEmpty(data.MetallicTexture))
                {
                    var node = graph.CreateComponent <Component_FlowGraphNode>();
                    node.Name     = "Node Texture Sample " + "Metallic";
                    node.Position = position;
                    position.Y   += step;

                    var sample = node.CreateComponent <Component_ShaderTextureSample>();
                    sample.Name    = ComponentUtility.GetNewObjectUniqueName(sample);
                    sample.Texture = new Reference <Component_Image>(null, data.MetallicTexture);

                    node.ControlledObject = ReferenceUtility.MakeThisReference(node, sample);

                    material.Metallic = ReferenceUtility.MakeThisReference(material, sample, "R");
                }

                //Roughness
                if (!string.IsNullOrEmpty(data.RoughnessTexture))
                {
                    var node = graph.CreateComponent <Component_FlowGraphNode>();
                    node.Name     = "Node Texture Sample " + "Roughness";
                    node.Position = position;
                    position.Y   += step;

                    var sample = node.CreateComponent <Component_ShaderTextureSample>();
                    sample.Name    = ComponentUtility.GetNewObjectUniqueName(sample);
                    sample.Texture = new Reference <Component_Image>(null, data.RoughnessTexture);

                    node.ControlledObject = ReferenceUtility.MakeThisReference(node, sample);

                    material.Roughness = ReferenceUtility.MakeThisReference(material, sample, "R");
                }

                //Normal
                if (!string.IsNullOrEmpty(data.NormalTexture))
                {
                    var node = graph.CreateComponent <Component_FlowGraphNode>();
                    node.Name     = "Node Texture Sample " + "Normal";
                    node.Position = position;
                    position.Y   += step;

                    var sample = node.CreateComponent <Component_ShaderTextureSample>();
                    sample.Name    = ComponentUtility.GetNewObjectUniqueName(sample);
                    sample.Texture = new Reference <Component_Image>(null, data.NormalTexture);

                    node.ControlledObject = ReferenceUtility.MakeThisReference(node, sample);

                    material.Normal = ReferenceUtility.MakeThisReference(material, sample, "RGBA");
                }

                ////Displacement
                //if( !string.IsNullOrEmpty( data.DisplacementTexture ) )
                //{
                //	var node = graph.CreateComponent<Component_FlowGraphNode>();
                //	node.Name = "Node Texture Sample " + "Displacement";
                //	node.Position = position;
                //	position.Y += step;

                //	var sample = node.CreateComponent<Component_ShaderTextureSample>();
                //	sample.Name = ComponentUtility.GetNewObjectUniqueName( sample );
                //	sample.Texture = new Reference<Component_Image>( null, data.DisplacementTexture );

                //	node.ControlledObject = ReferenceUtility.MakeThisReference( node, sample );

                //	Displacement = ReferenceUtility.MakeThisReference( this, sample, "R" );
                //}

                ////AmbientOcclusion
                //if( !string.IsNullOrEmpty( data.AmbientOcclusionTexture ) )
                //{
                //	var node = graph.CreateComponent<Component_FlowGraphNode>();
                //	node.Name = "Node Texture Sample " + "AmbientOcclusion";
                //	node.Position = position;
                //	position.Y += step;

                //	var sample = node.CreateComponent<Component_ShaderTextureSample>();
                //	sample.Name = ComponentUtility.GetNewObjectUniqueName( sample );
                //	sample.Texture = new Reference<Component_Image>( null, data.AmbientOcclusionTexture );

                //	node.ControlledObject = ReferenceUtility.MakeThisReference( node, sample );

                //	AmbientOcclusion = ReferenceUtility.MakeThisReference( this, sample, "R" );
                //}

                ////Emissive
                //if( !string.IsNullOrEmpty( data.EmissiveTexture ) )
                //{
                //	var node = graph.CreateComponent<Component_FlowGraphNode>();
                //	node.Name = "Node Texture Sample " + "Emissive";
                //	node.Position = position;
                //	position.Y += step;

                //	var sample = node.CreateComponent<Component_ShaderTextureSample>();
                //	sample.Name = ComponentUtility.GetNewObjectUniqueName( sample );
                //	sample.Texture = new Reference<Component_Image>( null, data.EmissiveTexture );

                //	node.ControlledObject = ReferenceUtility.MakeThisReference( node, sample );

                //	Emissive = ReferenceUtility.MakeThisReference( this, sample, "RGBA" );
                //}

                //Opacity
                if (!string.IsNullOrEmpty(data.OpacityTexture))
                {
                    var node = graph.CreateComponent <Component_FlowGraphNode>();
                    node.Name     = "Node Texture Sample " + "Opacity";
                    node.Position = position;
                    position.Y   += step;

                    var sample = node.CreateComponent <Component_ShaderTextureSample>();
                    sample.Name    = ComponentUtility.GetNewObjectUniqueName(sample);
                    sample.Texture = new Reference <Component_Image>(null, data.OpacityTexture);

                    node.ControlledObject = ReferenceUtility.MakeThisReference(node, sample);

                    material.Opacity = ReferenceUtility.MakeThisReference(material, sample, "R");

                    material.BlendMode = Component_Material.BlendModeEnum.Masked;
                }
            }
        }
Exemple #9
0
        static void ImportScene(ImportContext context)
        {
            var settings = context.settings;
            var scene    = context.scene;

            if (context.settings.component.ForceFrontXAxis)
            {
                //Через такой конструктор не получится создать такие же оси как EPreDefinedAxisSystem.eMax - Front Axis имеет обратное направление, а направление задать нельзя.
                //new FbxAxisSystem( FbxAxisSystem.EUpVector.eZAxis, FbxAxisSystem.EFrontVector.eParityOdd, FbxAxisSystem.ECoordSystem.eRightHanded );
                //FromFBX Docs:
                //The enum values ParityEven and ParityOdd denote the first one and the second one of the remain two axes in addition to the up axis.
                //For example if the up axis is X, the remain two axes will be Y And Z, so the ParityEven is Y, and the ParityOdd is Z ;

                //We desire to convert the scene from Y-Up to Z-Up. Using the predefined axis system: Max (UpVector = +Z, FrontVector = -Y, CoordSystem = +X (RightHanded))
                var maxAxisSystem = new FbxAxisSystem(FbxAxisSystem.EPreDefinedAxisSystem.eMax);

                if (!scene.GetGlobalSettings().GetAxisSystem().eq(maxAxisSystem))
                {
                    maxAxisSystem.ConvertScene(scene);                       //No conversion will take place if the scene current axis system is equal to the new one. So condition can be removed.
                }
            }

            //convert units
            if (!scene.GetGlobalSettings().GetSystemUnit().eq(FbxSystemUnit.m))
            {
                FbxSystemUnit.m.ConvertScene(scene);
            }

            //get materials data
            var materialsData = GetMaterialsData(context);

            //create Materials group
            context.materialsGroup = context.settings.component.GetComponent("Materials");
            if (context.materialsGroup == null /*&& materialsData.Count != 0*/ && settings.updateMaterials)
            {
                context.materialsGroup      = context.settings.component.CreateComponent <Component>();
                context.materialsGroup.Name = "Materials";
            }

            //create materials
            foreach (var data in materialsData)
            {
                Component_Material material = null;
                if (context.settings.updateMaterials)
                {
                    material = CreateMaterial(context.materialsGroup, data);
                }
                else
                {
                    if (context.materialsGroup != null)
                    {
                        material = context.materialsGroup.GetComponent(data.Name) as Component_Material;
                    }
                }
                if (material != null)
                {
                    context.materialByIndex.Add(data.Index, material);
                }
            }

            //-------------------------

            var additionalTransform = new Matrix4(settings.component.Rotation.Value.ToMatrix3() * Matrix3.FromScale(settings.component.Scale), settings.component.Position);

            var options = new ImportOptions
            {
                NormalsOptions         = NormalsAndTangentsLoadOptions.FromFileIfPresentOrCalculate,
                TangentsOptions        = NormalsAndTangentsLoadOptions.FromFileIfPresentOrCalculate,
                ImportPostProcessFlags = ImportPostProcessFlags.FixInfacingNormals
            };

            options.ImportPostProcessFlags |= ImportPostProcessFlags.SmoothNormals | ImportPostProcessFlags.SmoothTangents;
            if (context.settings.component.FlipUVs)
            {
                options.ImportPostProcessFlags |= ImportPostProcessFlags.FlipUVs;
            }

            var sceneLoader = new SceneLoader();

            var mode = settings.component.Mode.Value;

            if (mode == Component_Import3D.ModeEnum.Auto)
            {
                mode = Component_Import3D.ModeEnum.OneMesh;
            }

            //create one mesh (OneMesh mode)
            if (mode == Component_Import3D.ModeEnum.OneMesh && settings.updateMeshes)
            {
                sceneLoader.Load(scene, context.manager, options, additionalTransform);
                Component_Skeleton skeletonComponent = CreateSkeletonComponent(context, sceneLoader.Skeleton, out int[] newIndexFromOldIndex, out SkeletonBone[] oldBoneFromNewIndex, additionalTransform);
        /////////////////////////////////////////

        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            SimpleMeshGenerator.GenerateTorus(Axis, Radius, Segments, Circumference, TubeRadius, TubeSegments, TubeCircumference, /*Smooth, */ InsideOut, out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out indices, out var faces);
        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));
                        }
                    }
                }
            }
        }
        /////////////////////////////////////////

        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            var radius = Radius.Value;
            var height = Height.Value;

            if (InsideOut)
            {
                radius = -radius;
                height = -height;
            }
            SimpleMeshGenerator.GenerateCylinder(Axis, (float)radius, (float)height, Segments, true, true, true, out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out indices, out var faces);
Exemple #13
0
        internal void CompileDataOfThisObject(Component_Mesh.CompiledData compiledData)          // Component_Mesh mesh, Component_Mesh.CompiledData result )
        {
            VertexElement[] vertexStructureV = VertexStructure;
            UnwrappedUVEnum unwrappedUVV     = UnwrappedUV;

            byte[]             verticesV = Vertices;
            int[]              indicesV  = Indices;
            Component_Material materialV = Material;

            Component_Mesh.StructureClass structure = null;

            OnGetDataOfThisObject(ref vertexStructureV, ref verticesV, ref indicesV, ref materialV, ref structure);
            GetDataOfThisObjectEvent?.Invoke(this, ref vertexStructureV, ref verticesV, ref indicesV, ref materialV, ref structure);

            //add to result
            if (vertexStructureV != null && vertexStructureV.Length != 0 && verticesV != null && verticesV.Length != 0 && (indicesV == null || indicesV.Length != 0))
            {
                //!!!!еще чтобы был с позициями?

                vertexStructureV.GetInfo(out var vertexSize, out var holes);
                //if( !holes )
                {
                    int vertexCount = verticesV.Length / vertexSize;

                    var op = new Component_RenderingPipeline.RenderSceneData.MeshDataRenderOperation(this);

                    op.VertexStructure = vertexStructureV;

                    op.VertexStructureContainsColor = op.VertexStructure.Any(e => e.Semantic == VertexElementSemantic.Color0);
                    ////disable if all data equal zero. it is means no data.
                    //if( op.VertexStructureContainsColor )
                    //{
                    //	if( vertexStructureV.GetElementBySemantic( VertexElementSemantic.Color0, out var element ) )
                    //	{
                    //		var size = element.GetSizeInBytes();
                    //		int vertexOffset = element.Offset;
                    //		for( int nVertex = 0; nVertex < vertexCount; nVertex++ )
                    //		{
                    //			for( int n = 0; n < size; n++ )
                    //			{
                    //				if( verticesV[ vertexOffset + n ] != 0 )
                    //				{
                    //					//found non zero
                    //					goto exit;
                    //				}
                    //			}
                    //			vertexOffset += vertexSize;
                    //		}
                    //		op.VertexStructureContainsColor = false;
                    //		exit:;
                    //	}
                    //}

                    op.UnwrappedUV = unwrappedUVV;

                    var vertexDeclaration = op.VertexStructure.CreateVertexDeclaration(0);
                    op.VertexBuffers     = new GpuVertexBuffer[] { GpuBufferManager.CreateVertexBuffer(verticesV, vertexDeclaration) };
                    op.VertexStartOffset = 0;
                    op.VertexCount       = vertexCount;

                    if (indicesV != null)
                    {
                        op.IndexBuffer      = GpuBufferManager.CreateIndexBuffer(indicesV);
                        op.IndexStartOffset = 0;
                        op.IndexCount       = indicesV.Length;
                    }

                    //!!!!так?
                    op.Material = materialV;

                    compiledData.MeshData.RenderOperations.Add(op);

                    //!!!!может мержить когда несколько. индексы MeshGeometry в RawVertices
                    if (compiledData.MeshData.Structure == null)
                    {
                        compiledData.MeshData.Structure = structure;
                    }

                    //var op = new Component_Mesh.CompiledData.RenderOperation();
                    //op.creator = this;

                    //op.vertexStructure = vertexStructureV;
                    //List<GpuVertexBuffer> l = new List<GpuVertexBuffer>();

                    ////!!!!make copy of arrays?

                    //var vertexDeclaration = op.vertexStructure.CreateVertexDeclaration( 0 );

                    //l.Add( GpuBufferManager.CreateVertexBuffer( verticesV, vertexDeclaration, false ) );
                    //op.vertexBuffers = l;
                    //op.vertexStartOffset = 0;
                    //op.vertexCount = vertexCount;

                    //if( indicesV != null )
                    //{
                    //	op.indexBuffer = GpuBufferManager.CreateIndexBuffer( indicesV, false );
                    //	op.indexStartOffset = 0;
                    //	op.indexCount = indicesV.Length;
                    //}

                    ////!!!!так?
                    //op.material = materialV;

                    //var item = new Component_Mesh.CompiledData.RenderOperationItem();
                    //item.operation = op;
                    ////!!!!
                    ////item.transform = TransformOfData;//TransformRelativeToParent;
                    //compiledData.RenderOperations.Add( item );

                    ////op.transform = Transform;
                    ////compiledData.RenderOperations.Add( op );
                }
                //else
                //{
                //	//!!!!!error
                //}
            }
        }
Exemple #14
0
        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            SimpleMeshGenerator.GenerateStairs(Axis, Width, Height, Depth, Steps, Curvature, Radius, Sides, InsideOut, out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out indices, out var faces);
        /////////////////////////////////////////

        protected virtual void OnGetDataOfThisObject(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices,
                                                     ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
        }
Exemple #16
0
        //!!!!!by tesselation modifier?

        ////SegmentsHorizontal
        //Reference<int> segmentsHorizontal = 32;
        //[Serialize]
        //public virtual Reference<int> SegmentsHorizontal
        //{
        //	get
        //	{
        //		if( !string.IsNullOrEmpty( segmentsHorizontal.GetByReference ) )
        //			SegmentsHorizontal = segmentsHorizontal.GetValue( this );
        //		return segmentsHorizontal;
        //	}
        //	set
        //	{
        //		if( segmentsHorizontal == value ) return;
        //		segmentsHorizontal = value;
        //		SegmentsHorizontalChanged?.Invoke( this );
        //	}
        //}
        //public event Action<Component_MeshData_Parallelepiped> SegmentsHorizontalChanged;


        ////SegmentsVertical
        //Reference<int> segmentsVertical = 32;
        //[Serialize]
        //public virtual Reference<int> SegmentsVertical
        //{
        //	get
        //	{
        //		if( !string.IsNullOrEmpty( segmentsVertical.GetByReference ) )
        //			SegmentsVertical = segmentsVertical.GetValue( this );
        //		return segmentsVertical;
        //	}
        //	set
        //	{
        //		if( segmentsVertical == value ) return;
        //		segmentsVertical = value;
        //		SegmentsVerticalChanged?.Invoke( this );
        //	}
        //}
        //public event Action<Component_MeshData_Parallelepiped> SegmentsVerticalChanged;


        //!!!!полусферной
        //!!!!закрытость сферы как Shape volume


        /////////////////////////////////////////

        //[StructLayout( LayoutKind.Sequential )]
        //public struct Vertex
        //{
        //	public Vec3F position;
        //	public Vec3F normal;
        //	public Vec2F texCoord;
        //}

        /////////////////////////////////////////

        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
            unsafe
            {
                if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                {
                    Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                }
            }

            SimpleMeshGenerator.GenerateBox(Dimensions.Value.ToVector3F(), InsideOut, out Vector3F[] positions, out Vector3F[] normals, out Vector4F[] tangents, out Vector2F[] texCoords, out indices, out var faces);
Exemple #17
0
        public override void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure)
        {
            var meshInSpace = Parent?.Parent as Component_MeshInSpace;
            var points      = GetPointPositions();

            if (meshInSpace != null && points.Length >= 3)
            {
                vertexStructure = StandardVertex.MakeStructure(StandardVertex.Components.StaticOneTexCoord, true, out int vertexSize);
                unsafe
                {
                    if (vertexSize != sizeof(StandardVertex.StaticOneTexCoord))
                    {
                        Log.Fatal("vertexSize != sizeof( StandardVertexF )");
                    }
                }

                SimpleMeshGenerator.GeneratePolygonBasedPolyhedron(points, Clockwise, Height, InsideOut, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out indices, out var faces);
Exemple #18
0
        //??? Для объединенного MeshInSpace transform выбирать как у первого MeshInSpace или лучше считать средний transform?
        //??? MeshInSpace.ReplaceMeterial,ReplaceMeterialSelectively ? отбрасывать или выбирать первый. Как с geometry?
        static Component_MeshInSpace MergeMeshInSpaces(Component_MeshInSpace[] meshInSpaces, DocumentInstance document, UndoMultiAction undo)
        {
            if (meshInSpaces.Length < 2)
            {
                return(null);
            }

            var newTransform       = meshInSpaces[0].Transform.Value;
            var newMatrixInverse   = newTransform.ToMatrix4().GetInverse();
            var newRotationInverse = newTransform.Rotation.GetInverse();

            Component_Mesh.StructureClass newStructure = null;
            var newGeometries = new List <Component_MeshGeometry>();

            for (int i = 0; i < meshInSpaces.Length; i++)
            {
                var m = meshInSpaces[i].Mesh.Value;
                if (m == null)
                {
                    continue;
                }
                var oldTransform    = meshInSpaces[i].Transform.Value;
                var transformMatrix = newMatrixInverse * oldTransform.ToMatrix4();
                var rotation        = newRotationInverse * oldTransform.Rotation;

                var geometries = m.GetComponents <Component_MeshGeometry>();
                newStructure = Component_Mesh.StructureClass.Concat(newStructure, m.ExtractStructure().Structure, newGeometries.Count);
                foreach (var g in geometries)
                {
                    if (g 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 newMeshGeometry = new Component_MeshGeometry();
                        newMeshGeometry.Name            = meshGeometryProcedural.Name;
                        newMeshGeometry.VertexStructure = vertexStructure;
                        newMeshGeometry.Vertices        = vertices;
                        newMeshGeometry.Indices         = indices;

                        newMeshGeometry.Material = meshGeometryProcedural.Material;
                        //newMeshGeometry.Material = material;

                        TransformVertices(newMeshGeometry.Vertices.Value, new MeshData.MeshGeometryFormat(newMeshGeometry.VertexStructure), transformMatrix, rotation);
                        newGeometries.Add(newMeshGeometry);
                    }
                    else
                    {
                        //??? Проверять CloneSupport?
                        var newMeshGeometry = (Component_MeshGeometry)g.Clone();
                        if (newMeshGeometry.Vertices.Value != null)
                        {
                            newMeshGeometry.Vertices = (byte[])newMeshGeometry.Vertices.Value.Clone();
                            TransformVertices(newMeshGeometry.Vertices.Value, new MeshData.MeshGeometryFormat(newMeshGeometry.VertexStructure), transformMatrix, rotation);
                        }
                        newGeometries.Add(newMeshGeometry);
                    }
                }
            }

            //changes

            var parent = meshInSpaces[0].Parent;

            undo.AddAction(new UndoActionComponentCreateDelete(document, meshInSpaces, create: false));
            Component_MeshInSpace newMeshInSpace = parent.CreateComponent <Component_MeshInSpace>();
            bool wasEnabled = newMeshInSpace.Enabled;

            try
            {
                newMeshInSpace.Enabled   = false;
                newMeshInSpace.Name      = CommonFunctions.GetUniqueFriendlyName(newMeshInSpace);
                newMeshInSpace.Transform = newTransform;

                var newMesh = newMeshInSpace.CreateComponent <Component_Mesh>();
                newMesh.Name        = CommonFunctions.GetUniqueFriendlyName(newMesh);
                newMesh.Structure   = newStructure;
                newMeshInSpace.Mesh = ReferenceUtility.MakeReference <Component_Mesh>(null, ReferenceUtility.CalculateRootReference(newMesh));

                foreach (var g in newGeometries)
                {
                    newMesh.AddComponent(g);
                    CommonFunctions.EnsureNameIsUnique(g);
                }
            }
            finally
            {
                newMeshInSpace.Enabled = wasEnabled;
            }

            undo.AddAction(new UndoActionComponentCreateDelete(document, new[] { newMeshInSpace }, create: true));
            return(newMeshInSpace);
        }
Exemple #19
0
        static void ImportJson(ImportContext context, out string error)
        {
            error = "";

            var settings = context.settings;
            var json     = context.json;

            bool onlyOneMaterial = /*json.Maps != null &&*/ json.Models == null && json.Meshes == null;            // && json.Components == null;

            if (onlyOneMaterial)
            {
                settings.disableDeletionUnusedMaterials = true;
            }

            //get materials data
            var materialsData = GetMaterialsData(context, onlyOneMaterial);

            //init materials group
            if (!onlyOneMaterial)
            {
                context.materialsGroup = context.settings.component.GetComponent("Materials");
                if (context.materialsGroup == null && materialsData.Count != 0 && settings.updateMaterials)
                {
                    context.materialsGroup      = context.settings.component.CreateComponent <Component>();
                    context.materialsGroup.Name = "Materials";
                }
            }
            else
            {
                context.materialsGroup = context.settings.component;
            }

            //create materials
            foreach (var data in materialsData)
            {
                Component_Material material = null;
                if (context.settings.updateMaterials)
                {
                    material = CreateMaterial(context.materialsGroup, data);
                }
                else
                {
                    if (context.materialsGroup != null)
                    {
                        material = context.materialsGroup.GetComponent(data.Name) as Component_Material;
                    }
                }
                if (material != null)
                {
                    context.materialByIndex.Add(data.Index, material);
                }
            }

            if (settings.updateMeshes)
            {
                var variations       = new Dictionary <int, Variation>();
                var geometriesByFile = new Dictionary <string, List <MeshData> >();

                //meshes
                if (json.Meshes != null)
                {
                    //!!!!add Mode = OneMesh support?

                    var fileNames = new List <string>();
                    foreach (var mesh in json.Meshes)
                    {
                        if (mesh.Uris != null)
                        {
                            foreach (var uri in mesh.Uris)
                            {
                                var fileName = Path.Combine(context.directoryName, VirtualPathUtility.NormalizePath(uri.Uri));
                                if (VirtualFile.Exists(fileName))
                                {
                                    fileNames.Add(fileName);
                                }
                            }
                        }
                    }

                    if (fileNames.Count != 0)
                    {
                        var lodRange = settings.component.LODRange.Value;

                        for (int lodIndex = 0; lodIndex < fileNames.Count; lodIndex++)
                        {
                            if (lodIndex >= lodRange.Minimum && lodIndex <= lodRange.Maximum)
                            {
                                var fileName = fileNames[lodIndex];
                                if (!LoadFBX(context, fileName, out var geometries))
                                {
                                    error = $"Unable to load \"{fileName}\".";
                                    return;
                                }

                                for (int nGeometry = 0; nGeometry < geometries.Count; nGeometry++)
                                {
                                    var geometry = geometries[nGeometry];

                                    int variationIndex = nGeometry + 1;
                                    if (!variations.TryGetValue(variationIndex, out var variation))
                                    {
                                        variation = new Variation();
                                        variations[variationIndex] = variation;
                                    }

                                    var lod = new LOD();
                                    lod.geometries.Add(geometry);
                                    var indexToAdd = lodIndex - lodRange.Minimum;
                                    while (indexToAdd >= variation.lods.Count)
                                    {
                                        variation.lods.Add(new LOD());
                                    }
                                    variation.lods[indexToAdd] = lod;
                                }
                            }
                        }
                    }
                }

                //models
                if (json.Models != null)
                {
                    var lodRange = settings.component.LODRange.Value;

                    foreach (var model in json.Models)
                    {
                        var lodIndex = (int)model.Lod;
                        if (lodIndex >= lodRange.Minimum && lodIndex <= lodRange.Maximum)
                        {
                            var variationIndex = (int)model.Variation;

                            if (!variations.TryGetValue(variationIndex, out var variation))
                            {
                                variation = new Variation();
                                variations[variationIndex] = variation;
                            }

                            var fileName = Path.Combine(context.directoryName, VirtualPathUtility.NormalizePath(model.Uri));
                            if (VirtualFile.Exists(fileName))
                            {
                                if (!geometriesByFile.TryGetValue(fileName, out var geometries))
                                {
                                    if (!LoadFBX(context, fileName, out geometries))
                                    {
                                        error = $"Unable to load \"{fileName}\".";
                                        return;
                                    }
                                    geometriesByFile[fileName] = geometries;
                                }

                                var lod = new LOD();
                                lod.geometries.AddRange(geometries);
                                var indexToAdd = lodIndex - lodRange.Minimum;
                                while (indexToAdd >= variation.lods.Count)
                                {
                                    variation.lods.Add(new LOD());
                                }
                                variation.lods[indexToAdd] = lod;
                            }
                        }
                    }
                }

                int meshCount = variations.Count;
                if (meshCount > 0)
                {
                    //init meshes group
                    Component meshesGroup = null;
                    if (meshCount > 1)
                    {
                        meshesGroup = context.settings.component.GetComponent("Meshes");
                        if (meshesGroup == null)
                        {
                            meshesGroup      = context.settings.component.CreateComponent <Component>();
                            meshesGroup.Name = "Meshes";
                        }
                    }
                    else if (meshCount == 1)
                    {
                        meshesGroup = context.settings.component;
                    }

                    //create meshes
                    foreach (var pair in variations)
                    {
                        var variationIndex = pair.Key;
                        var variation      = pair.Value;

                        if (variation.lods.Count != 0)
                        {
                            string name;
                            if (meshCount != 1)
                            {
                                name = $"Mesh {variationIndex}";
                            }
                            else
                            {
                                name = "Mesh";
                            }

                            CreateMesh(context, variation.lods, name, meshesGroup);
                        }
                    }
                }



                //var fileNames = new List<string>();
                //foreach( var mesh in json.Meshes )
                //{
                //	if( mesh.Uris != null )
                //	{
                //		foreach( var uri in mesh.Uris )
                //		{
                //			var fileName = Path.Combine( context.directoryName, VirtualPathUtility.NormalizePath( uri.Uri ) );
                //			if( VirtualFile.Exists( fileName ) )
                //				fileNames.Add( fileName );
                //		}
                //	}
                //}

                //if( fileNames.Count != 0 )
                //{
                //	var lods = new List<LOD>();

                //	for( int nLod = 0; nLod < fileNames.Count; nLod++ )
                //	{
                //		if( nLod < settings.component.LODCount )
                //		{
                //			var fileName = fileNames[ nLod ];
                //			if( !LoadFBX( context, fileName, out var geometries ) )
                //			{
                //				error = $"Unable to load \"{fileName}\".";
                //				return;
                //			}

                //			var lod = new LOD();
                //			lod.geometries = geometries;
                //			lods.Add( lod );
                //		}
                //	}

                //	CreateMesh( context, lods, "Mesh", context.settings.component );
                //}



                ////load data
                //{
                //	//models
                //	if( json.Models != null )
                //	{
                //		var variations = new EDictionary<int, List<string>>();
                //		foreach( var model in json.Models )
                //		{
                //			var fileName = Path.Combine( context.directoryName, VirtualPathUtility.NormalizePath( model.Uri ) );
                //			if( VirtualFile.Exists( fileName ) )
                //			{
                //				if( !LoadFBXToMesh( context, fileName, out var geometries ) )
                //				{
                //					error = $"Unable to load \"{fileName}\".";
                //					return;
                //				}
                //				loadedData[ fileName ] = geometries;
                //				//fileNames.Add( fileName );
                //			}
                //		}
                //	}

                //}

                //xx xx;


                ////calculate mesh count
                //int meshCount = 0;
                //{
                //	//models
                //	if( json.Models != null )
                //	{
                //		var variations = new EDictionary<int, List<string>>();
                //		foreach( var model in json.Models )
                //		{
                //			var variation = (int)model.Variation;
                //			if( !variations.TryGetValue( variation, out var fileNames ) )
                //			{
                //				fileNames = new List<string>();
                //				variations[ variation ] = fileNames;
                //			}

                //			var fileName = Path.Combine( context.directoryName, VirtualPathUtility.NormalizePath( model.Uri ) );
                //			if( VirtualFile.Exists( fileName ) )
                //			{
                //				xx xx;

                //				fileNames.Add( fileName );
                //			}
                //		}

                //		foreach( var pair in variations )
                //		{
                //			var fileNames = pair.Value;

                //			if( fileNames.Count != 0 )
                //				meshCount++;
                //		}
                //	}

                //	//one mesh in the source
                //	if( json.Meshes != null )
                //	{
                //		var fileNames = new List<string>();

                //		foreach( var mesh in json.Meshes )
                //		{
                //			if( mesh.Uris != null )
                //			{
                //				foreach( var uri in mesh.Uris )
                //				{
                //					var fileName = Path.Combine( context.directoryName, VirtualPathUtility.NormalizePath( uri.Uri ) );
                //					if( VirtualFile.Exists( fileName ) )
                //						fileNames.Add( fileName );
                //				}
                //			}
                //		}

                //		if( fileNames.Count != 0 )
                //			meshCount++;
                //	}
                //}

                ////init meshes group
                //Component meshesGroup = null;
                //if( meshCount > 1 )
                //{
                //	meshesGroup = context.settings.component.GetComponent( "Meshes" );
                //	if( meshesGroup == null )
                //	{
                //		meshesGroup = context.settings.component.CreateComponent<Component>();
                //		meshesGroup.Name = "Meshes";
                //	}
                //}
                //else if( meshCount == 1 )
                //	meshesGroup = context.settings.component;

                ////models
                //if( json.Models != null )
                //{
                //	var variations = new EDictionary<int, List<string>>();
                //	foreach( var model in json.Models )
                //	{
                //		var variation = (int)model.Variation;
                //		if( !variations.TryGetValue( variation, out var fileNames ) )
                //		{
                //			fileNames = new List<string>();
                //			variations[ variation ] = fileNames;
                //		}

                //		var fileName = Path.Combine( context.directoryName, VirtualPathUtility.NormalizePath( model.Uri ) );
                //		if( VirtualFile.Exists( fileName ) )
                //			fileNames.Add( fileName );
                //	}

                //	foreach( var pair in variations )
                //	{
                //		var variation = pair.Key;
                //		var fileNames = pair.Value;

                //		if( fileNames.Count != 0 )
                //		{
                //			if( !CreateMesh( context, fileNames, $"Mesh {variation}", meshesGroup, out error ) )
                //				return;
                //		}
                //	}
                //}

                ////one mesh in the source
                //if( json.Meshes != null )
                //{
                //	var fileNames = new List<string>();

                //	foreach( var mesh in json.Meshes )
                //	{
                //		if( mesh.Uris != null )
                //		{
                //			foreach( var uri in mesh.Uris )
                //			{
                //				var fileName = Path.Combine( context.directoryName, VirtualPathUtility.NormalizePath( uri.Uri ) );
                //				if( VirtualFile.Exists( fileName ) )
                //					fileNames.Add( fileName );
                //			}
                //		}
                //	}

                //	if( fileNames.Count != 0 )
                //	{
                //		if( !CreateMesh( context, fileNames, "Mesh", context.settings.component, out error ) )
                //			return;
                //	}
                //}
            }


            //	//Object In Space
            //	if( settings.updateObjectsInSpace && meshesGroup != null )
            //	{
            //		var objectInSpace = settings.component.CreateComponent<Component_ObjectInSpace>( enabled: false );
            //		objectInSpace.Name = "Object In Space";

            //		foreach( var mesh in meshesGroup.Components )
            //		{
            //			var meshInSpace = objectInSpace.CreateComponent<Component_MeshInSpace>();
            //			meshInSpace.Name = mesh.Name;
            //			meshInSpace.CanBeSelected = false;
            //			meshInSpace.Mesh = ReferenceUtility.MakeReference<Component_Mesh>( null, ReferenceUtility.CalculateRootReference( mesh ) );

            //			//Transform
            //			//!!!!transform?
            //			var pos = Vector3.Zero;
            //			var rot = Quaternion.Identity;
            //			var scl = Vector3.One;
            //			//( globalTransform * node.Transform.ToMat4() ).Decompose( out var pos, out Quat rot, out var scl );

            //			var transformOffset = meshInSpace.CreateComponent<Component_TransformOffset>();
            //			transformOffset.Name = "Transform Offset";
            //			transformOffset.PositionOffset = pos;
            //			transformOffset.RotationOffset = rot;
            //			transformOffset.ScaleOffset = scl;

            //			transformOffset.Source = ReferenceUtility.MakeThisReference( transformOffset, objectInSpace, "Transform" );
            //			meshInSpace.Transform = ReferenceUtility.MakeThisReference( meshInSpace, transformOffset, "Result" );
            //			//transformOffset.Source = ReferenceUtils.CreateReference<Transform>(null, ReferenceUtils.CalculateThisReference(transformOffset, objectInSpace, "Transform"));
            //			//meshInSpace.Transform = ReferenceUtils.CreateReference<Transform>(null, ReferenceUtils.CalculateThisReference(meshInSpace, transformOffset, "Result"));
            //		}

            //		objectInSpace.Enabled = true;
            //	}
            //}
        }