Ejemplo n.º 1
0
        private static AssetLoadResultByLoader Load(AssetLoadInfo loadInfo, void *dicomManager)
        {
            int width, height, depth;

            CheckSuccess(DicomProject.AnalyzerGetDimensions(dicomManager, 1, &width, &height, &depth));

            var lowerBuffer  = new byte[width * height];
            var higherBuffer = new byte[width * height];
            var vertexList   = new List <VertexPosNormTex>();

            fixed(byte *pBuffer = higherBuffer)
            {
                int bufferSize = higherBuffer.Length;
                int bytesWritten;

                CheckSuccess(DicomProject.AnalyzerGetMonochromePixelDataBufferOfSlice(dicomManager, 1, pBuffer, &bufferSize, &bytesWritten));
            }

            for (int z = 1; z < depth; z++)
            {
                CodingHelper.Swap(ref lowerBuffer, ref higherBuffer);

                fixed(byte *pBuffer = higherBuffer)
                {
                    int bufferSize = higherBuffer.Length;
                    int bytesWritten;

                    CheckSuccess(DicomProject.AnalyzerGetMonochromePixelDataBufferOfSlice(dicomManager, z + 1, pBuffer, &bufferSize, &bytesWritten));
                }

                for (int y = 0; y < height - 1; y++)
                {
                    for (int x = 0; x < width - 1; x++)
                    {
                        var vx = (100f / width) * x - 50f;
                        var vy = (100f / height) * y - 50f;
                        var vz = (100f / depth) * z - 50f;

                        var yStride = width;

                        var mcCube = new MCCubeCornerScalarStruct
                        {
                            CubeDim   = new IrtPtType(100.0 / width, 100.0 / height, 100.0 / depth),
                            Vrtx0Lctn = new IrtPtType(vx, vy, vz)
                        };
                        mcCube.Corners[0] = UNormToDouble(lowerBuffer[yStride * y + x]);
                        mcCube.Corners[1] = UNormToDouble(lowerBuffer[yStride * y + (x + 1)]);
                        mcCube.Corners[2] = UNormToDouble(lowerBuffer[yStride * (y + 1) + (x + 1)]);
                        mcCube.Corners[3] = UNormToDouble(lowerBuffer[yStride * (y + 1) + x]);
                        mcCube.Corners[4] = UNormToDouble(higherBuffer[yStride * y + x]);
                        mcCube.Corners[5] = UNormToDouble(higherBuffer[yStride * y + (x + 1)]);
                        mcCube.Corners[6] = UNormToDouble(higherBuffer[yStride * (y + 1) + (x + 1)]);
                        mcCube.Corners[7] = UNormToDouble(higherBuffer[yStride * (y + 1) + x]);
                        // todo: use ref instead
                        EstimateGradient(&mcCube);
                        var MCPolys = Irit.MCThresholdCube(&mcCube, 0.5);

                        while (MCPolys != null)
                        {
                            var texCoord = new Vector2((float)x / width, (float)z / depth);

                            var vertex0    = MCPolys->GetClarityVertex(0, texCoord);
                            var vertexCurr = MCPolys->GetClarityVertex(1, texCoord);

                            for (var i = 2; i < MCPolys->NumOfVertices; i++)
                            {
                                var vertexPrev = vertexCurr;

                                vertexCurr = MCPolys->GetClarityVertex(i, texCoord);
                                vertexList.Add(vertex0);
                                vertexList.Add(vertexPrev);
                                vertexList.Add(vertexCurr);
                            }

                            //Irit.IritFree(MCPolys);

                            MCPolys = MCPolys->Pnext;
                        }
                    }
                }
            }

            var pack = new ResourcePack(ResourceVolatility.Immutable);

            var rawVerticesData = new RawDataResource(ResourceVolatility.Immutable, vertexList.Count * sizeof(VertexPosNormTex));

            pack.AddSubresource("VertexData", rawVerticesData);
            var pRawData = (VertexPosNormTex *)rawVerticesData.Map();

            for (int i = 0; i < vertexList.Count; i++)
            {
                pRawData[i] = vertexList[i];
            }
            rawVerticesData.Unmap(true);

            var vertexSet = new FlexibleModelVertexSet(ResourceVolatility.Immutable, new[] { new RawDataResSubrange(rawVerticesData, 0) }, VertexPosNormTex.GetElementsInfos(0), null);

            pack.AddSubresource("ModelVertexSet", vertexSet);
            var modelPart = new FlexibleModelPart
            {
                IndexCount        = vertexList.Count,
                PrimitiveTopology = FlexibleModelPrimitiveTopology.TriangleList,
                VertexSetIndex    = 0
            };
            var model = new FlexibleModel(ResourceVolatility.Immutable, new[] { vertexSet }, new[] { modelPart }, new Sphere(Vector3.Zero, 50));

            pack.AddSubresource("Model", model);
            pack.MainSubresource = model;

            CheckSuccess(DicomProject.AnalyzerKillDicomAnalyzer(&dicomManager));

            // todo: calculate hash honestly
            var hash     = AssetHashMd5.Random(new Random());
            var fileName = Path.GetFileName(loadInfo.LoadPath);
            var asset    = new Asset(loadInfo.AssetName, pack, AssetStorageType.ReferenceOriginal, hash, loadInfo.ReferencePath, fileName);

            return(AssetLoadResultByLoader.Success(asset));
        }
Ejemplo n.º 2
0
        private unsafe IAsset BuildAsset(AssetLoadInfo loadInfo)
        {
            var fileData = loadInfo.FileSystem.ReadAllBytes(loadInfo.LoadPath);

            var        objLoaderFactory = new ObjLoaderFactory();
            var        objLoader        = objLoaderFactory.Create(new MyMaterialStreamProvider(Path.GetDirectoryName(loadInfo.LoadPath), loadInfo.FileSystem));
            LoadResult objLoadResult;

            using (var stream = new MemoryStream(fileData))
                objLoadResult = objLoader.Load(stream);

            var anyTextures            = objLoadResult.Textures.Any();
            var initialMediatorIndices = new int?[objLoadResult.Vertices.Count];
            var mediators           = new List <VertexMediator>();
            var faceMediatorIndices = new List <int>();
            var indexList           = new List <int>();
            var materials           = new List <IStandardMaterial>();
            var modelParts          = new List <FlexibleModelPart>();

            foreach (var grp in objLoadResult.Groups)
            {
                var startIndexLocation = indexList.Count;
                foreach (var face in grp.Faces)
                {
                    faceMediatorIndices.Clear();
                    foreach (var fv in face.EnumerateVertices())
                    {
                        var newMediator = new VertexMediator
                        {
                            PositionIndex = fv.VertexIndex - 1,
                            NormalIndex   = fv.NormalIndex - 1,
                            TexCoordIndex = anyTextures ? fv.TextureIndex - 1 : 0
                        };
                        var initialIndex = initialMediatorIndices[newMediator.PositionIndex];
                        if (!initialIndex.HasValue)
                        {
                            var mediatorIndex = mediators.Count;
                            mediators.Add(newMediator);
                            faceMediatorIndices.Add(mediatorIndex);
                            initialMediatorIndices[newMediator.PositionIndex] = mediatorIndex;
                        }
                        else
                        {
                            var mediatorIndex = initialIndex.Value;
                            var oldMediator   = mediators[mediatorIndex];
                            while (true)
                            {
                                if (oldMediator.PositionIndex == newMediator.PositionIndex &&
                                    oldMediator.NormalIndex == newMediator.NormalIndex &&
                                    oldMediator.TexCoordIndex == newMediator.TexCoordIndex)
                                {
                                    break;
                                }
                                if (!oldMediator.NextMediator.HasValue)
                                {
                                    mediatorIndex = mediators.Count;
                                    mediators.Add(newMediator);
                                    oldMediator.NextMediator = mediatorIndex;
                                    break;
                                }
                                mediatorIndex = oldMediator.NextMediator.Value;
                                oldMediator   = mediators[mediatorIndex];
                            }
                            faceMediatorIndices.Add(mediatorIndex);
                        }
                    }
                    if (faceMediatorIndices.Count <= 3)
                    {
                        for (int i = 0; i < faceMediatorIndices.Count - 3; i++)
                        {
                            indexList.Add(faceMediatorIndices[0]);
                        }
                        foreach (var mi in faceMediatorIndices)
                        {
                            indexList.Add(mi);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < faceMediatorIndices.Count - 2; i++)
                        {
                            indexList.Add(faceMediatorIndices[0]);
                            indexList.Add(faceMediatorIndices[i + 1]);
                            indexList.Add(faceMediatorIndices[i + 2]);
                        }
                    }
                }
                var indexCount = indexList.Count - startIndexLocation;
                var color      = grp.Material != null
                    ? new Color4(
                    grp.Material.DiffuseColor.X,
                    grp.Material.DiffuseColor.Y,
                    grp.Material.DiffuseColor.Z)
                    : (Color4?)null;

                // todo: use material

                modelParts.Add(new FlexibleModelPart
                {
                    VertexSetIndex    = 0,
                    ModelMaterialName = grp.Material?.Name ?? "DefaultMaterial",
                    PrimitiveTopology = FlexibleModelPrimitiveTopology.TriangleList,
                    IndexCount        = indexCount,
                    FirstIndex        = startIndexLocation
                });
            }

            VertexPosNormTex[] finalVertices;
            int[] finalIndices;

            if (objLoadResult.Normals.Count > 0)
            {
                var vertices = mediators.Select(m => new VertexPosNormTex()).ToArray();
                for (int i = 0; i < mediators.Count; i++)
                {
                    var mediator = mediators[i];
                    vertices[i].Position = objLoadResult.Vertices[mediator.PositionIndex].ToClarity();
                    vertices[i].Normal   = objLoadResult.Normals[mediator.NormalIndex].ToClarity();
                    if (anyTextures)
                    {
                        vertices[i].TexCoord = objLoadResult.Textures[mediator.TexCoordIndex].ToClarity();
                    }
                }

                finalVertices = vertices;
                finalIndices  = indexList.ToArray();
            }
            else
            {
                var newIndices  = Enumerable.Range(0, indexList.Count).ToArray();
                var newVertices = new VertexPosNormTex[newIndices.Length];
                for (int i = 0; i + 2 < indexList.Count; i += 3)
                {
                    var mediator0 = mediators[indexList[i]];
                    var mediator1 = mediators[indexList[i + 1]];
                    var mediator2 = mediators[indexList[i + 2]];
                    var pos0      = objLoadResult.Vertices[mediator0.PositionIndex].ToClarity();
                    var pos1      = objLoadResult.Vertices[mediator1.PositionIndex].ToClarity();
                    var pos2      = objLoadResult.Vertices[mediator2.PositionIndex].ToClarity();
                    newVertices[i] = new VertexPosNormTex
                    {
                        Position = pos0,
                        Normal   = -Vector3.Cross(pos2 - pos0, pos1 - pos0).Normalize(),
                        TexCoord = new Vector2(0.3f, 0.3f)
                    };
                    newVertices[i + 1] = new VertexPosNormTex
                    {
                        Position = pos1,
                        Normal   = -Vector3.Cross(pos0 - pos1, pos2 - pos1).Normalize(),
                        TexCoord = new Vector2(0.7f, 0.3f)
                    };
                    newVertices[i + 2] = new VertexPosNormTex
                    {
                        Position = pos2,
                        Normal   = -Vector3.Cross(pos1 - pos2, pos0 - pos2).Normalize(),
                        TexCoord = new Vector2(0.5f, 0.7f)
                    };
                }

                finalVertices = newVertices;
                finalIndices  = newIndices;
            }

            var pack = new ResourcePack(ResourceVolatility.Immutable);

            IRawDataResource vertexRawData;

            fixed(VertexPosNormTex *pVertices = finalVertices)
            vertexRawData = new RawDataResource(ResourceVolatility.Immutable, (IntPtr)pVertices, sizeof(VertexPosNormTex) * finalVertices.Length);

            pack.AddSubresource("VertexRawData", vertexRawData);

            IRawDataResource indexRawData;

            fixed(int *pIndices = finalIndices)
            indexRawData = new RawDataResource(ResourceVolatility.Immutable, (IntPtr)pIndices, sizeof(int) * finalIndices.Length);

            pack.AddSubresource("IndexRawData", indexRawData);

            var arraySubranges = new []
            {
                vertexRawData.GetSubrange(0),
                indexRawData.GetSubrange(0)
            };

            var elementInfos = VertexPosNormTex.GetElementsInfos(0);
            var indicesInfo  = new VertexIndicesInfo(1, CommonFormat.R32_UINT);
            var vertexSet    = new FlexibleModelVertexSet(ResourceVolatility.Immutable, arraySubranges, elementInfos, indicesInfo);

            pack.AddSubresource("VertexSet", vertexSet);

            var sphere = Sphere.BoundingSphere(finalVertices, x => x.Position);
            var model  = new FlexibleModel(ResourceVolatility.Immutable, new [] { vertexSet }, modelParts, sphere);

            pack.AddSubresource("Model", model);
            pack.MainSubresource = model;

            var hash     = AssetHashMd5.FromSingleFile(fileData);
            var fileName = Path.GetFileName(loadInfo.LoadPath);

            return(new Asset(loadInfo.AssetName, pack, AssetStorageType.CopyLocal, hash, loadInfo.ReferencePath, fileName));
        }
        private unsafe IFlexibleModel CreateModel(IntSize3 size, float cellSize, int numParticles)
        {
            // todo: add a 'IResourceSource.AttachResource(resource)' method
            var vertexPosElemInfo = new [] { new VertexElementInfo(CommonVertexSemantic.Position, 0, CommonFormat.R32G32B32_SFLOAT, 0, sizeof(Vector3)) };
            var resourcePack      = new ResourcePack(ResourceVolatility.Immutable);

            // Bounds
            var bounds         = new Vector3(size.Width * cellSize, size.Height * cellSize, size.Depth * cellSize);
            var boundsVertices = new[]
            {
                new Vector3(0, 0, 0),
                new Vector3(0, bounds.Y, 0),
                new Vector3(bounds.X, bounds.Y, 0),
                new Vector3(bounds.X, 0, 0),
                new Vector3(0, 0, bounds.Z),
                new Vector3(0, bounds.Y, bounds.Z),
                new Vector3(bounds.X, bounds.Y, bounds.Z),
                new Vector3(bounds.X, 0, bounds.Z),
            };
            var boundsIndices = new ushort[]
            {
                0, 1, 1, 2, 2, 3, 3, 0,
                4, 5, 5, 6, 6, 7, 7, 4,
                0, 4, 1, 5, 2, 6, 3, 7
            };
            RawDataResource boundsVertexBuffer;

            fixed(Vector3 *pBoundsVertexData = boundsVertices)
            boundsVertexBuffer = new RawDataResource(ResourceVolatility.Immutable, (IntPtr)pBoundsVertexData, boundsVertices.Length * sizeof(Vector3));

            resourcePack.AddSubresource("BoundsVertexBuffer", boundsVertexBuffer);
            RawDataResource boundsIndexBuffer;

            fixed(ushort *pBoundsIndices = boundsIndices)
            boundsIndexBuffer = new RawDataResource(ResourceVolatility.Immutable, (IntPtr)pBoundsIndices, boundsIndices.Length * sizeof(ushort));

            resourcePack.AddSubresource("BoundsIndexBuffer", boundsIndexBuffer);
            var boundsVertexSet = new FlexibleModelVertexSet(ResourceVolatility.Immutable,
                                                             new [] { boundsVertexBuffer.AsSubrange(), boundsIndexBuffer.AsSubrange() },
                                                             vertexPosElemInfo,
                                                             new VertexIndicesInfo(1, CommonFormat.R16_UINT));

            resourcePack.AddSubresource("BoundsVertexSet", boundsVertexSet);
            var boundsModelPart = new FlexibleModelPart
            {
                VertexSetIndex    = 0,
                PrimitiveTopology = FlexibleModelPrimitiveTopology.LineList,
                ModelMaterialName = "BoundsMaterial",
                IndexCount        = boundsIndices.Length
            };

            // Particles
            particlesBuffer = new RawDataResource(ResourceVolatility.Volatile, numParticles * sizeof(Vector3));
            var pParticlePositions = (Vector3 *)particlesBuffer.Map();

            for (int i = 0; i < fluidSimulation.Particles.Length; i++)
            {
                pParticlePositions[i] = fluidSimulation.Particles[i].Position;
            }
            particlesBuffer.Unmap(true);
            resourcePack.AddSubresource("ParticlesBuffer", particlesBuffer);

            var particlesVertexSet = new FlexibleModelVertexSet(ResourceVolatility.Immutable,
                                                                new [] { particlesBuffer.AsSubrange() },
                                                                vertexPosElemInfo,
                                                                null);

            resourcePack.AddSubresource("ParticlesVertexSet", particlesVertexSet);

            var particlesModelPart = new FlexibleModelPart
            {
                VertexSetIndex    = 1,
                PrimitiveTopology = FlexibleModelPrimitiveTopology.PointList,
                ModelMaterialName = "ParticlesMaterial",
                IndexCount        = numParticles
            };

            var resultModel = new FlexibleModel(ResourceVolatility.Immutable,
                                                new [] { boundsVertexSet, particlesVertexSet },
                                                new [] { boundsModelPart, particlesModelPart },
                                                new Sphere(bounds / 2, bounds.Length() / 2));

            resourcePack.AddSubresource("Model", resultModel);
            return(resultModel);
        }