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 //} } }
public abstract void GetProceduralGeneratedData(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure);
///////////////////////////////////////// protected virtual void OnGetDataOfThisObject(ref VertexElement[] vertexStructure, ref byte[] vertices, ref int[] indices, ref Component_Material material, ref Component_Mesh.StructureClass structure) { }
///////////////////////////////////////// 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++; } } } }
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); }
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);
////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);
///////////////////////////////////////// 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);
//!!!!!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);
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);
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 //} } }
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);
public static Component_Mesh.StructureClass CreateMeshStructure(Face[] faces) { var result = new Component_Mesh.StructureClass(); int vertexMaxIndex = 0; //faces result.Faces = new Component_Mesh.StructureClass.Face[faces.Length]; for (int nFace = 0; nFace < faces.Length; nFace++) { var face = faces[nFace]; var triangles2 = new Component_Mesh.StructureClass.FaceVertex[face.Triangles.Length]; for (int n = 0; n < triangles2.Length; n++) { var faceVertex = face.Triangles[n]; triangles2[n] = new Component_Mesh.StructureClass.FaceVertex(faceVertex.Vertex, 0, faceVertex.RawVertex); vertexMaxIndex = Math.Max(vertexMaxIndex, faceVertex.Vertex); } result.Faces[nFace] = new Component_Mesh.StructureClass.Face(triangles2, null, 0); } //edges var edges = new ESet <Vector2I>(vertexMaxIndex * 3); for (int nFace = 0; nFace < faces.Length; nFace++) { var face = faces[nFace]; var edgeCounts = new Dictionary <Vector2I, int>(face.Triangles.Length); for (int nTriangle = 0; nTriangle < face.Triangles.Length / 3; nTriangle++) { var faceVertex0 = face.Triangles[nTriangle * 3 + 0]; var faceVertex1 = face.Triangles[nTriangle * 3 + 1]; var faceVertex2 = face.Triangles[nTriangle * 3 + 2]; void AddEdge(int vertex1, int vertex2) { int v1, v2; if (vertex1 > vertex2) { v1 = vertex2; v2 = vertex1; } else { v1 = vertex1; v2 = vertex2; } var key = new Vector2I(v1, v2); edgeCounts.TryGetValue(key, out var count); edgeCounts[key] = count + 1; } AddEdge(faceVertex0.Vertex, faceVertex1.Vertex); AddEdge(faceVertex1.Vertex, faceVertex2.Vertex); AddEdge(faceVertex2.Vertex, faceVertex0.Vertex); } foreach (var pair in edgeCounts) { if (pair.Value == 1) { var edge = pair.Key; edges.AddWithCheckAlreadyContained(new Vector2I(edge.X, edge.Y)); } } //for( int nTriangle = 0; nTriangle < face.Triangles.Length / 3; nTriangle++ ) //{ // var faceVertex0 = face.Triangles[ nTriangle * 3 + 0 ]; // var faceVertex1 = face.Triangles[ nTriangle * 3 + 1 ]; // var faceVertex2 = face.Triangles[ nTriangle * 3 + 2 ]; // void AddEdge( int vertex1, int vertex2 ) // { // int v1, v2; // if( vertex1 > vertex2 ) // { // v1 = vertex2; // v2 = vertex1; // } // else // { // v1 = vertex1; // v2 = vertex2; // } // edges.AddWithCheckAlreadyContained( new Vector2I( v1, v2 ) ); // } // AddEdge( faceVertex0.Vertex, faceVertex1.Vertex ); // AddEdge( faceVertex1.Vertex, faceVertex2.Vertex ); // AddEdge( faceVertex2.Vertex, faceVertex0.Vertex ); //} } result.Edges = edges.Select(e => new Component_Mesh.StructureClass.Edge(e.X, e.Y)).ToArray(); //vertices result.Vertices = new Component_Mesh.StructureClass.Vertex[vertexMaxIndex + 1]; return(result); }