示例#1
0
        public void Initialize()
        {
            var importer = new AssimpContext();
            var aScene   = importer.ImportFile(FilePath, PostProcessPreset.TargetRealTimeMaximumQuality);

            Meshes = new List <Mesh>();

            foreach (var aMesh in aScene.Meshes)
            {
                var verticesResult = new List <MeshSkinnedVerticeInfo>();
                var indicesResult  = new List <int>();

                var mesh = new Mesh();
                mesh.Bones = new List <Bone>();

                mesh.Name = aMesh.Name;

                Dictionary <int, List <VerticeWeight> > VerticeWeights = new Dictionary <int, List <VerticeWeight> >();
                foreach (var aBone in aMesh.Bones)
                {
                    Bone bone = GetBone(mesh, aBone);

                    foreach (var vw in aBone.VertexWeights)
                    {
                        if (!VerticeWeights.ContainsKey(vw.VertexID))
                        {
                            VerticeWeights.Add(vw.VertexID, new List <VerticeWeight>());
                        }
                        VerticeWeights[vw.VertexID].Add(new VerticeWeight()
                        {
                            Bone = bone, Weight = vw.Weight
                        });
                    }
                }

                var c = aScene.Materials[aMesh.MaterialIndex].ColorDiffuse;

                for (int faceIndex = 0; faceIndex < aMesh.FaceCount; faceIndex++)
                {
                    for (int vertexNum = 0; vertexNum < 3; vertexNum++)
                    {
                        int     verticeIndice   = aMesh.Faces[faceIndex].Indices[vertexNum];
                        Vector3 verticePosition = AssimpHelper.VectorAssimpToXna(aMesh.Vertices[verticeIndice]);
                        Vector3 verticeNormal   = AssimpHelper.VectorAssimpToXna(aMesh.Normals[verticeIndice]);

                        var uv        = AssimpHelper.VectorAssimpToXna(aMesh.TextureCoordinateChannels[0][verticeIndice]);
                        var verticeUv = new Vector2(uv.X, uv.Y);

                        BlendInfo blendInfo = GetBlendInfo(VerticeWeights, verticeIndice);

                        var vertice = new MeshSkinnedVerticeInfo()
                        {
                            Position          = verticePosition,
                            Normal            = verticeNormal,
                            TextureCoordinate = verticeUv,
                            BoneID            = blendInfo.BoneId,
                            BoneWeight        = blendInfo.Weight
                        };

                        indicesResult.Add(verticesResult.Count);
                        verticesResult.Add(vertice);
                    }
                }

                mesh.TextureFilePath = aScene.Materials[aMesh.MaterialIndex].TextureDiffuse.FilePath;

                mesh.VertexBuffer = new VertexBuffer(GraphicsDevice, typeof(SkinnedModelVertex), verticesResult.Count, BufferUsage.WriteOnly);
                mesh.VertexBuffer.SetData <SkinnedModelVertex>(verticesResult.Select(v => v.ToVertexPositionNormalTextureBones()).ToArray());

                mesh.IndexBuffer = new IndexBuffer(GraphicsDevice, typeof(int), indicesResult.Count, BufferUsage.WriteOnly);
                mesh.IndexBuffer.SetData(indicesResult.ToArray());

                mesh.FaceCount = aMesh.FaceCount;

                Meshes.Add(mesh);
            }
        }
        /*
         * input kernel area naming convention:
         * -------------
         | A | B | C |
         | ----|---|---|
         | D | E | F | //input pixel is at position E
         | ----|---|---|
         | G | H | I |
         | -------------
         */

        private static void _ScalePixel(
            IScaler scaler,
            RotationDegree rotDeg,
            Kernel_3X3 ker,
            sPixel[] trg,
            int trgi,
            int trgWidth,
            byte blendInfo,      //result of preprocessing all four corners of pixel "e"
            IColorEq scalePixelColorEq,
            IColorDist scalePixelColorDist,
            OutputMatrix outputMatrix
            )
        {
            //int a = kernel._[Rot._[(0 << 2) + rotDeg]];
            var b = ker._[Rot._[(1 << 2) + (int)rotDeg]];
            var c = ker._[Rot._[(2 << 2) + (int)rotDeg]];
            var d = ker._[Rot._[(3 << 2) + (int)rotDeg]];
            var e = ker._[Rot._[(4 << 2) + (int)rotDeg]];
            var f = ker._[Rot._[(5 << 2) + (int)rotDeg]];
            var g = ker._[Rot._[(6 << 2) + (int)rotDeg]];
            var h = ker._[Rot._[(7 << 2) + (int)rotDeg]];
            var i = ker._[Rot._[(8 << 2) + (int)rotDeg]];

            var blend = BlendInfo.Rotate(blendInfo, rotDeg);

            if (BlendInfo.GetBottomR(blend) == BlendType.BlendNone)
            {
                return;
            }

            var eq   = scalePixelColorEq;
            var dist = scalePixelColorDist;

            bool doLineBlend;

            if (BlendInfo.GetBottomR(blend) >= BlendType.BlendDominant)
            {
                doLineBlend = true;
            }

            //make sure there is no second blending in an adjacent
            //rotation for this pixel: handles insular pixels, mario eyes
            //but support double-blending for 90? corners
            else if (BlendInfo.GetTopR(blend) != BlendType.BlendNone && !eq._(e, g))
            {
                doLineBlend = false;
            }

            else if (BlendInfo.GetBottomL(blend) != BlendType.BlendNone && !eq._(e, c))
            {
                doLineBlend = false;
            }

            //no full blending for L-shapes; blend corner only (handles "mario mushroom eyes")
            else if (eq._(g, h) && eq._(h, i) && eq._(i, f) && eq._(f, c) && !eq._(e, i))
            {
                doLineBlend = false;
            }

            else
            {
                doLineBlend = true;
            }

            //choose most similar color
            var px = dist._(e, f) <= dist._(e, h) ? f : h;

            var output = outputMatrix;

            output.Move(rotDeg, trgi);

            if (!doLineBlend)
            {
                scaler.BlendCorner(px, output);
                return;
            }

            //test sample: 70% of values max(fg, hc) / min(fg, hc)
            //are between 1.1 and 3.7 with median being 1.9
            var fg = dist._(f, g);
            var hc = dist._(h, c);

            var haveShallowLine = _CONFIGURATION.steepDirectionThreshold * fg <= hc && e != g && d != g;
            var haveSteepLine   = _CONFIGURATION.steepDirectionThreshold * hc <= fg && e != c && b != c;

            if (haveShallowLine)
            {
                if (haveSteepLine)
                {
                    scaler.BlendLineSteepAndShallow(px, output);
                }
                else
                {
                    scaler.BlendLineShallow(px, output);
                }
            }
            else
            {
                if (haveSteepLine)
                {
                    scaler.BlendLineSteep(px, output);
                }
                else
                {
                    scaler.BlendLineDiagonal(px, output);
                }
            }
        }
        public static void ScaleImage(ScaleSize scaleSize, sPixel[] src, sPixel[] trg, int srcWidth, int srcHeight, int xFirst, int yFirst, int xLast, int yLast)
        {
            yFirst = Math.Max(yFirst, 0);
            yLast  = Math.Min(yLast, srcHeight);

            if (yFirst >= yLast || srcWidth <= 0)
            {
                return;
            }

            var trgWidth = srcWidth * scaleSize.size;

            //temporary buffer for "on the fly preprocessing"
            var preProcBuffer = new byte[srcWidth];

            var ker4 = new Kernel_4X4();

            var preProcessCornersColorDist = new ColorDistA();

            //initialize preprocessing buffer for first row:
            //detect upper left and right corner blending
            //this cannot be optimized for adjacent processing
            //stripes; we must not allow for a memory race condition!
            if (yFirst > 0)
            {
                var y = yFirst - 1;

                var sM1 = srcWidth * Math.Max(y - 1, 0);
                var s0  = srcWidth * y;                //center line
                var sP1 = srcWidth * Math.Min(y + 1, srcHeight - 1);
                var sP2 = srcWidth * Math.Min(y + 2, srcHeight - 1);

                for (var x = xFirst; x < xLast; ++x)
                {
                    var xM1 = Math.Max(x - 1, 0);
                    var xP1 = Math.Min(x + 1, srcWidth - 1);
                    var xP2 = Math.Min(x + 2, srcWidth - 1);

                    //read sequentially from memory as far as possible
                    ker4.b = src[sM1 + x];
                    ker4.c = src[sM1 + xP1];

                    ker4.e = src[s0 + xM1];
                    ker4.f = src[s0 + x];
                    ker4.g = src[s0 + xP1];
                    ker4.h = src[s0 + xP2];

                    ker4.i = src[sP1 + xM1];
                    ker4.j = src[sP1 + x];
                    ker4.k = src[sP1 + xP1];
                    ker4.l = src[sP1 + xP2];

                    ker4.n = src[sP2 + x];
                    ker4.o = src[sP2 + xP1];

                    var blendResult = new BlendResult();
                    _PreProcessCorners(ker4, blendResult, preProcessCornersColorDist);                     // writes to blendResult

                    /*
                     * preprocessing blend result:
                     * ---------
                     | F | G | //evalute corner between F, G, J, K
                     | ----|---| //input pixel is at position F
                     | J | K |
                     | ---------
                     */
                    preProcBuffer[x] = BlendInfo.SetTopR(preProcBuffer[x], blendResult.j);

                    if (x + 1 < srcWidth)
                    {
                        preProcBuffer[x + 1] = BlendInfo.SetTopL(preProcBuffer[x + 1], blendResult.k);
                    }
                }
            }

            var eqColorThres = _Square(_CONFIGURATION.equalColorTolerance);

            var scalePixelColorEq   = new ColorEqA(eqColorThres);
            var scalePixelColorDist = new ColorDistA();
            var outputMatrix        = new OutputMatrix(scaleSize.size, trg, trgWidth);

            var ker3 = new Kernel_3X3();

            for (var y = yFirst; y < yLast; ++y)
            {
                //consider MT "striped" access
                var trgi = scaleSize.size * y * trgWidth;

                var sM1 = srcWidth * Math.Max(y - 1, 0);
                var s0  = srcWidth * y;                //center line
                var sP1 = srcWidth * Math.Min(y + 1, srcHeight - 1);
                var sP2 = srcWidth * Math.Min(y + 2, srcHeight - 1);

                byte blendXy1 = 0;

                for (var x = xFirst; x < xLast; ++x, trgi += scaleSize.size)
                {
                    var xM1 = Math.Max(x - 1, 0);
                    var xP1 = Math.Min(x + 1, srcWidth - 1);
                    var xP2 = Math.Min(x + 2, srcWidth - 1);

                    //evaluate the four corners on bottom-right of current pixel
                    //blend_xy for current (x, y) position
                    byte blendXy;
                    {
                        //read sequentially from memory as far as possible
                        ker4.b = src[sM1 + x];
                        ker4.c = src[sM1 + xP1];

                        ker4.e = src[s0 + xM1];
                        ker4.f = src[s0 + x];
                        ker4.g = src[s0 + xP1];
                        ker4.h = src[s0 + xP2];

                        ker4.i = src[sP1 + xM1];
                        ker4.j = src[sP1 + x];
                        ker4.k = src[sP1 + xP1];
                        ker4.l = src[sP1 + xP2];

                        ker4.n = src[sP2 + x];
                        ker4.o = src[sP2 + xP1];

                        var blendResult = new BlendResult();
                        _PreProcessCorners(ker4, blendResult, preProcessCornersColorDist);                         // writes to blendResult

                        /*
                         * preprocessing blend result:
                         * ---------
                         | F | G | //evaluate corner between F, G, J, K
                         | ----|---| //current input pixel is at position F
                         | J | K |
                         | ---------
                         */

                        //all four corners of (x, y) have been determined at
                        //this point due to processing sequence!
                        blendXy = BlendInfo.SetBottomR(preProcBuffer[x], blendResult.f);

                        //set 2nd known corner for (x, y + 1)
                        blendXy1 = BlendInfo.SetTopR(blendXy1, blendResult.j);
                        //store on current buffer position for use on next row
                        preProcBuffer[x] = blendXy1;

                        //set 1st known corner for (x + 1, y + 1) and
                        //buffer for use on next column
                        blendXy1 = BlendInfo.SetTopL(0, blendResult.k);

                        if (x + 1 < srcWidth)
                        {
                            //set 3rd known corner for (x + 1, y)
                            preProcBuffer[x + 1] = BlendInfo.SetBottomL(preProcBuffer[x + 1], blendResult.g);
                        }
                    }

                    //fill block of size scale * scale with the given color
                    //  //place *after* preprocessing step, to not overwrite the
                    //  //results while processing the the last pixel!
                    _FillBlock(trg, trgi, trgWidth, src[s0 + x], scaleSize.size);

                    //blend four corners of current pixel
                    if (blendXy == 0)
                    {
                        continue;
                    }

                    const int a = 0, b = 1, c = 2, d = 3, e = 4, f = 5, g = 6, h = 7, i = 8;

                    //read sequentially from memory as far as possible
                    ker3._[a] = src[sM1 + xM1];
                    ker3._[b] = src[sM1 + x];
                    ker3._[c] = src[sM1 + xP1];

                    ker3._[d] = src[s0 + xM1];
                    ker3._[e] = src[s0 + x];
                    ker3._[f] = src[s0 + xP1];

                    ker3._[g] = src[sP1 + xM1];
                    ker3._[h] = src[sP1 + x];
                    ker3._[i] = src[sP1 + xP1];

                    _ScalePixel(scaleSize.scaler, RotationDegree.Rot0, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix);
                    _ScalePixel(scaleSize.scaler, RotationDegree.Rot90, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix);
                    _ScalePixel(scaleSize.scaler, RotationDegree.Rot180, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix);
                    _ScalePixel(scaleSize.scaler, RotationDegree.Rot270, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix);
                }
            }
        }
        public void WriteToFile(BinaryWriter writer)
        {
            //BEFORE WE WRITE, WE NEED TO COMPILE AND UPDATE THE FRAME.
            UpdateFrameData();
            header.WriteToFile(writer);

            foreach (var Geometry in frameGeometries.Values)
            {
                Geometry.WriteToFile(writer);
            }

            foreach (var Material in frameMaterials.Values)
            {
                Material.WriteToFile(writer);
            }

            foreach (var BlendInfo in frameBlendInfos.Values)
            {
                BlendInfo.WriteToFile(writer);
            }

            foreach (var Skeleton in frameSkeletons.Values)
            {
                Skeleton.WriteToFile(writer);
            }

            foreach (var SkeletonHierarchy in frameSkeletonHierachies.Values)
            {
                SkeletonHierarchy.WriteToFile(writer);
            }

            foreach (var FObject in frameObjects.Values)
            {
                FrameObjectBase entry = (FObject as FrameObjectBase);
                if (entry.GetType() == typeof(FrameObjectJoint))
                {
                    writer.Write((int)ObjectType.Joint);
                }
                else if (entry.GetType() == typeof(FrameObjectSingleMesh))
                {
                    writer.Write((int)ObjectType.SingleMesh);
                }
                else if (entry.GetType() == typeof(FrameObjectFrame))
                {
                    writer.Write((int)ObjectType.Frame);
                }
                else if (entry.GetType() == typeof(FrameObjectLight))
                {
                    writer.Write((int)ObjectType.Light);
                }
                else if (entry.GetType() == typeof(FrameObjectCamera))
                {
                    writer.Write((int)ObjectType.Camera);
                }
                else if (entry.GetType() == typeof(FrameObjectComponent_U005))
                {
                    writer.Write((int)ObjectType.Component_U00000005);
                }
                else if (entry.GetType() == typeof(FrameObjectSector))
                {
                    writer.Write((int)ObjectType.Sector);
                }
                else if (entry.GetType() == typeof(FrameObjectDummy))
                {
                    writer.Write((int)ObjectType.Dummy);
                }
                else if (entry.GetType() == typeof(FrameObjectDeflector))
                {
                    writer.Write((int)ObjectType.ParticleDeflector);
                }
                else if (entry.GetType() == typeof(FrameObjectArea))
                {
                    writer.Write((int)ObjectType.Area);
                }
                else if (entry.GetType() == typeof(FrameObjectTarget))
                {
                    writer.Write((int)ObjectType.Target);
                }
                else if (entry.GetType() == typeof(FrameObjectModel))
                {
                    writer.Write((int)ObjectType.Model);
                }
                else if (entry.GetType() == typeof(FrameObjectCollision))
                {
                    writer.Write((int)ObjectType.Collision);
                }
            }

            foreach (var FObject in frameObjects.Values)
            {
                FrameObjectBase entry = (FObject as FrameObjectBase);
                entry.WriteToFile(writer);
            }
        }