예제 #1
0
파일: Context.cs 프로젝트: senny970/2007
 public void RemapSkin(GraphicsStream vertexRemapStream)
 {
     if (SkinInformation != null && vertexRemapStream != null)
     {
         int[] vertexRemap = vertexRemap = vertexRemapStream.Read(typeof(int), new int[] { MeshData.Mesh.NumberVertices }) as int[];
         SkinInformation.Remap(vertexRemap);
     }
 }
예제 #2
0
        private void EncodeProcess()
        {
            try
            {
                // calc info
                int totalFrames = (int)((float)settings.FramesPerSecond * (float)recording.Duration.Seconds);
                // start encoding
                IOutputStream stream = VideoEncodingInterface.CreateVideoStream(outFilename, settings.Codec,
                                                                                settings.Width, settings.Height,
                                                                                16, settings.FramesPerSecond, TimeSpan.MinValue, null);
                // create local buffer
                int     pixels = settings.Width * settings.Height;
                byte[]  buffer = new byte[settings.Width * settings.Height * 4];
                Device  device = renderer.Device;
                Surface bb     = device.GetBackBuffer(0, 0, BackBufferType.Mono);
                Texture t      = new Texture(device, settings.Width, settings.Height, 1, bb.Description.Usage, bb.Description.Format, bb.Description.Pool);
                Surface target = t.GetSurfaceLevel(0);

                Texture sysT      = new Texture(device, settings.Width, settings.Height, 1, bb.Description.Usage, bb.Description.Format, bb.Description.Pool);
                Surface sysTarget = sysT.GetSurfaceLevel(0);

                byte[] pBuf = new byte[4];
                for (int frame = 0; frame < totalFrames; frame++)
                {
                    // Draw frame
                    renderer.Render(0, target);

                    //Bitmap b = new Bitmap(TextureLoader.SaveToStream(ImageFileFormat.Bmp, t));
                    //BitmapData data = b.LockBits(new Rectangle(0, 0, settings.Width, settings.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    device.GetRenderTargetData(target, sysTarget);

                    GraphicsStream gStream = sysTarget.LockRectangle(LockFlags.ReadOnly);
                    // copy over to right format
                    // Format.X8R8G8B8 > RGBA
                    int bIdx = 0;
                    for (int pixel = 0; pixel < pixels; pixel++)
                    {
                        gStream.Read(pBuf, 0, 4);
                        buffer[bIdx++] = pBuf[1]; // r
                        buffer[bIdx++] = pBuf[2]; // g
                        buffer[bIdx++] = pBuf[3]; // b
                        buffer[bIdx++] = pBuf[0]; // a
                    }

                    // encode frame
                    stream.PutFrame(buffer);
                }

                int totalBytes = 0;
                stream.Close(out totalBytes);
            }
            catch (ThreadAbortException) { }

            complete = true;
        }
예제 #3
0
        private static void CopyTextureData(GraphicsStream srcData, int srcWidth, int srcHeight, OpsFormatHelper formatHelp, int srcPitch, GraphicsStream dstData, int dstPitch)
        {
            Byte[] rowData = new Byte[srcWidth * formatHelp.SizeInBytes];
            for (int row = 0; row < srcHeight; row++)
            {
                srcData.Position = row * srcPitch;
                dstData.Position = row * dstPitch;

                srcData.Read(rowData, 0, rowData.Length);
                dstData.Write(rowData, 0, rowData.Length);
            }
        }
예제 #4
0
        /// <summary>
        /// Method to load in a directx mesh.
        /// </summary>
        /// <param name="filename">Path of the model to load.</param>
        /// <returns></returns>
        public Mesh LoadModel(string filename)
        {
            Mesh mesh;

            VertexElement[] vElements = new VertexElement[]
            {
                new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
                new VertexElement(0, 12, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
                new VertexElement(0, 20, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0),
                new VertexElement(0, 32, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.Tangent, 0),
                VertexElement.VertexDeclarationEnd
            };

            // Load the mesh from file.
            mesh = Mesh.FromFile(filename, MeshFlags.Managed | MeshFlags.Use32Bit, device);

            // Clone the mesh.
            mesh = mesh.Clone(MeshFlags.Managed | MeshFlags.Use32Bit, vElements, device);

            // Generates a list of adjacent faces used for generating normals.
            int[] adjacency = new int[mesh.NumberFaces * 3];
            mesh.GenerateAdjacency(0, adjacency);

            //mesh.ComputeTangentFrame(TangentOptions.GenerateInPlace | TangentOptions.CalculateNormals);
            mesh.ComputeNormals(adjacency);

            // Create the variables needed to convert the mesh to right handed coordinates.
            GraphicsStream gStream  = mesh.LockVertexBuffer(LockFlags.None);
            List <Vertex>  vertices = new List <Vertex>();
            Vertex         vertex;

            // Convert the mesh to right handed coordinates.
            for (int i = 0; i < mesh.NumberVertices; i++)
            {
                vertex = (Vertex)gStream.Read(typeof(Vertex));

                vertex.Position.Z *= -1.0f;
                vertex.Normal      = Vector3.TransformNormal(vertex.Normal, Matrix.Scaling(1.0f, 1.0f, -1.0f));

                vertices.Add(vertex);
            }

            // Set the vertex buffer
            mesh.SetVertexBufferData(vertices.ToArray(), LockFlags.None);

            // Calculate the tangents
            TangentBuilder.CalculateTangents(mesh);

            return(mesh);
        }
예제 #5
0
        Color avcs(GraphicsStream gs, Collection <long> positions)
        {
            byte[] bu = new byte[4];
            int    r  = 0;
            int    g  = 0;
            int    b  = 0;
            int    i  = 0;

            foreach (long pos in positions)
            {
                gs.Position = pos;
                if (gs.Length > positions[positions.Count - 1])
                {
                    if (gs.CanRead)
                    {
                        try { gs.Read(bu, 0, 4); }
                        catch { }
                    }
                }
                r += bu[2];
                g += bu[1];
                b += bu[0];
                i++;
            }
            if (i == 0)
            {
                return(Color.Black);
            }
            else
            {
                int r_Usr = r / i;
                int g_Usr = g / i;
                int b_Usr = b / i;
                if (r_Usr == 0xAA)
                {
                    r_Usr += 1;
                }
                if (g_Usr == 0xAA)
                {
                    g_Usr += 1;
                }
                if (b_Usr == 0xAA)
                {
                    b_Usr += 1;
                }
                return(Color.FromArgb(r_Usr, g_Usr, b_Usr));
            }
        }
예제 #6
0
        //Swizzlin'
        private static void SwizzleImage(GraphicsStream gs, int width, int height, bool b32BPP)
        {
            //since swizzling is only for normals, and those must be saved in dxt5 (or argb8), might as well ensure the texture is in the correct format.
            if (!b32BPP)
            {
                var tTemp = TextureLoader.FromStream(dev, gs, width, height, 1, Usage.None, Format.A8B8G8R8, Pool.SystemMemory, Filter.None, Filter.None,
                                                     0);
                gs = TextureLoader.SaveToStream(ImageFileFormat.Tga, tTemp);
                tTemp.Dispose();
            }

            var bOri = new byte[gs.Length];
            //byte array from original stream
            var bSwizzled = new byte[gs.Length];

            //swizzled array
            gs.Read(bOri, 0, (int)gs.Length);
            const int headerSize = 0x1f;

            //a header for a tga file is usually 18bytes long, but for a reason I don't get, here it start at 0x1F...
            // Dim headerSize As Integer = 18
            for (var i = 0; i <= headerSize - 1; i++)
            {
                bSwizzled[i] = bOri[i];
            }
            //there's probably a better way to do that, but this one is self-explanatory...
            for (var y = 0; y <= height - 1; y++)
            {
                for (var x = 0; x <= width - 1; x++)
                {
                    var pos = (((y * width) + x) * 4) + headerSize;

                    //b = bOri(pos)
                    var g = bOri[pos + 1];
                    var r = bOri[pos + 2];
                    //a = bOri(pos + 3)

                    bSwizzled[pos]     = 255;
                    bSwizzled[pos + 1] = g;
                    bSwizzled[pos + 2] = 255;
                    bSwizzled[pos + 3] = r;
                }
            }
            gs.Position = 0;
            gs.Write(bSwizzled, 0, bSwizzled.Length);
            gs.Position = 0;
        }
예제 #7
0
        private static GraphicsStream swizzleTga(Stream st, int width, int height)
        {
            System.Console.WriteLine("Swizzling normal map");
            st.Position = 0;
            Texture        tex = TextureLoader.FromStream(device, st);
            GraphicsStream gs  = TextureLoader.SaveToStream(ImageFileFormat.Tga, tex);

            var bOri = new byte[gs.Length];
            //byte array from original stream
            var bSwizzled = new byte[gs.Length];

            //swizzled array
            gs.Read(bOri, 0, (int)gs.Length);
            const int headerSize = 0x1f;

            //a header for a tga file is usually 18bytes long, but for a reason I don't get, here it start at 0x1F...
            // Dim headerSize As Integer = 18
            for (var i = 0; i <= headerSize - 1; i++)
            {
                bSwizzled[i] = bOri[i];
            }
            //there's probably a better way to do that, but this one is self-explanatory...
            for (var y = 0; y <= height - 1; y++)
            {
                for (var x = 0; x <= width - 1; x++)
                {
                    var pos = (((y * width) + x) * 4) + headerSize;
                    //b = bOri(pos)
                    var g = bOri[pos + 1];
                    var r = bOri[pos + 2];
                    //a = bOri(pos + 3)
                    bSwizzled[pos]     = 255;
                    bSwizzled[pos + 1] = g;
                    bSwizzled[pos + 2] = 255;
                    bSwizzled[pos + 3] = r;
                }
            }
            gs.Position = 0;
            gs.Write(bSwizzled, 0, bSwizzled.Length);
            gs.Position = 0;
            st.Dispose();
            st.Close();
            System.Console.WriteLine("Swizzle done");
            return(gs);
        }
예제 #8
0
        /// <summary>
        /// Calculates the largest and smallest values.
        /// </summary>
        public void calcSize()
        {
            min = max = 0;
            Vertex         vertex;
            GraphicsStream gStream = model.LockVertexBuffer(LockFlags.None);

            // Iterates through the vertex list to find the minimum and maximum position values.
            for (int i = 0; i < model.NumberVertices; i++)
            {
                vertex = (Vertex)gStream.Read(typeof(Vertex));

                if (vertex.Position.Y > max)
                {
                    max = vertex.Position.Y;
                }

                if (vertex.Position.Y < min)
                {
                    min = vertex.Position.Y;
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Read a Matrix from an XFile node
        /// </summary>
        /// <param name="stream">GraphicsStream obtained from locking the Xfile data object</param>
        public Matrix MatrixFromXFile(GraphicsStream stream)
        {
            float v = 0;													// elements are floats
            Matrix m = Matrix.Identity;

            m.M11 = (float)stream.Read(v.GetType());		// read the matrix
            m.M12 = (float)stream.Read(v.GetType());
            m.M13 = (float)stream.Read(v.GetType());
            m.M14 = (float)stream.Read(v.GetType());
            m.M21 = (float)stream.Read(v.GetType());
            m.M22 = (float)stream.Read(v.GetType());
            m.M23 = (float)stream.Read(v.GetType());
            m.M24 = (float)stream.Read(v.GetType());
            m.M31 = (float)stream.Read(v.GetType());
            m.M32 = (float)stream.Read(v.GetType());
            m.M33 = (float)stream.Read(v.GetType());
            m.M34 = (float)stream.Read(v.GetType());
            m.M41 = (float)stream.Read(v.GetType());
            m.M42 = (float)stream.Read(v.GetType());
            m.M43 = (float)stream.Read(v.GetType());
            m.M44 = (float)stream.Read(v.GetType());

            return m;
        }
예제 #10
0
        private void ExportThread()
        {
            //create timer so we can check how long it takes to create the whole file
            Stopwatch stopwatch = new Stopwatch();

            // Begin timing
            stopwatch.Start();

            //for (int i = 0; i < _refLibrary.Count; i++)
            for (int i = Convert.ToInt16(text_test_framemin.Text); i < Convert.ToInt16(text_test_framemax.Text); i++)
            {
                showRefImage     = false;       //turns off the ref image while we render the new library
                nud_frame.Value  = i;           //just setting this value and then calling Render() is enough to cycle through the frames
                backgroundColour = Color.Black; //set the background to black so the crop code can detect the blank areas and remove pure black pixels from the image, if set to any other colour the image will have a solid colour background and not become transparent
                UpdateTextBoxes();              //this will set the _selectedRefImage for the current frame
                Render();

                #region Save Snapshot of the Directx panel
                try
                {
                    Surface backbuffer = device.GetBackBuffer(0, 0, BackBufferType.Mono);
                    //SurfaceLoader.Save("Screenshot.bmp", ImageFileFormat.Bmp, backbuffer); //saves file (to test it is working)

                    //if you continue to Render the DirectX panel while updating the GraphicsStream it causes the device to be lost and crashes
                    //so I just call Render(); when I need to update the panel instead of using the infinite loop thread
                    #region Graphics Lock
                    GraphicsStream gs = backbuffer.LockRectangle(LockFlags.Discard);

                    gs.Position = 0; //set start position
                    int bytesPerPixel   = 4;
                    int currentPosition = 0;
                    int heightInPixels  = 250;
                    int widthInPixels   = 250;

                    //Crop offsets
                    int XMin = 249;
                    int XMax = 0;
                    int YMin = 249;
                    int YMax = 0;

                    for (int y = 0; y < heightInPixels; y++)
                    {
                        //couldn't use the Parallel.For loop as it would overwrite the GraphicsStream.Position because it was working on two or
                        //more pixels at once causing a speckled effect as it misses pixels (well I think that is what was causing the errors I was having)
                        //Parallel.For(0, heightInPixels, y =>
                        //{
                        //int currentLine = (y * ((widthInPixels * bytesPerPixel) + (4 *12))); //4*12 is how many pixels (12 for 500pixel image) was missing from each row (not sure why 12 but I guess the backbuffer extends beyond the screen)
                        int currentLine = (y * (widthInPixels * bytesPerPixel) + (y * (4 * 6))); //4*6 is how many pixels (6 for 250pixel image) was missing from each row (not sure why 6 but I guess the backbuffer extends beyond the screen)

                        for (int x = 0; x < widthInPixels; x++)
                        {
                            byte[] bu = new byte[4];                             //new byte to store current pixel data
                            currentPosition = currentLine + (x * bytesPerPixel); //calculate current position
                            gs.Position     = currentPosition;                   //set pixel position in GraphicsStream
                            gs.Read(bu, 0, 4);                                   //read image pixel data

                            //gets RGB values
                            int   r = bu[2];
                            int   g = bu[1];
                            int   b = bu[0];
                            Color c = Color.FromArgb(r, g, b);

                            if (c.R != backgroundColour.R && c.G != backgroundColour.G && c.B != backgroundColour.B) //if not the same as backgroundColour set the min/max values
                            {
                                if (XMin > x)
                                {
                                    XMin = x;
                                }
                                if (XMax < x)
                                {
                                    XMax = x;
                                }
                                if (YMin > y)
                                {
                                    YMin = y;
                                }
                                if (YMax < y)
                                {
                                    YMax = y;
                                }
                            }

                            //if (y == YMin) //this is a way to show where the image is cropped
                            //{
                            //    bu[2] = 255;
                            //    bu[1] = 0;
                            //    bu[0] = 0;
                            //}

                            gs.Position = currentPosition; //sets the position back to the starting pixel
                            gs.Write(bu, 0, 4);            //updates the GraphicsStream with the new changes
                        }
                        //}); //end of Parallel.For loop
                    }

                    //Shows the detected bounds of the image for testing
                    //MessageBox.Show("XMin: " + XMin
                    //    + Environment.NewLine + "XMax: " + XMax
                    //    + Environment.NewLine + "YMin: " + YMin
                    //    + Environment.NewLine + "YMax: " + YMax
                    //    + Environment.NewLine + "Width: " + (XMax - XMin)
                    //    + Environment.NewLine + "Height: " + (YMax - YMin));

                    backbuffer.UnlockRectangle();
                    gs.Dispose();
                    #endregion

                    Bitmap Preview = new Bitmap(SurfaceLoader.SaveToStream(ImageFileFormat.Bmp, backbuffer));

                    #region crop

                    //create target image and draw cropped part of the Preview image to the target image
                    Bitmap target = new Bitmap((XMax - XMin) + 1, (YMax - YMin) + 1, PixelFormat.Format32bppArgb);
                    using (Graphics g = Graphics.FromImage(target))
                    {
                        g.DrawImage(Preview, new RectangleF(0, 0, target.Width, target.Height), new RectangleF(XMin, YMin, (XMax - XMin) + 1, (YMax - YMin) + 1), GraphicsUnit.Pixel);
                    }

                    #endregion

                    //Add Image and offsets to the _library
                    _library.AddImage(target,
                                      (short)(XMin - characterGlobalOffsetX),
                                      (short)(YMin - characterGlobalOffsetY));

                    //target.Save("Test1.PNG", ImageFormat.Png); //testing screen capture and crop image from directx works by saving to file

                    target.Dispose();
                    Preview.Dispose();
                    backbuffer.Dispose();
                }
                catch (Direct3DXException ee) //Display error Messages with the DirectX code
                {
                    MessageBox.Show("Message: " + ee.Message
                                    + Environment.NewLine + "ErrorString: " + ee.ErrorString
                                    + Environment.NewLine + "ErrorCode: " + ee.ErrorCode
                                    + Environment.NewLine + "StackTrace: " + ee.StackTrace
                                    );
                }
                #endregion


                toolStripProgressBar.Value = i + 1;
            }

            //save file as normal .lib (true = reference file, false = normal .lib)
            _library.Save(false);

            stopwatch.Stop();
            MessageBox.Show(string.Format("Time Taken: {0:n0} Seconds", stopwatch.Elapsed.TotalMilliseconds / 1000));
            toolStripProgressBar.Value = 0;
            showRefImage    = true;
            nud_frame.Value = 0;
            Render();
        }
예제 #11
0
        //IOpsCommand
        public void Run(OpsContext context, OpsStatement statement)
        {
            OpsConsole.WriteLine("Cleaning models");

            foreach (OpsModel model in statement.GetContent(context))
            {
                foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator())
                {
                    string errorsAndWarnings;
                    meshContainer.MeshData.Mesh.Validate(meshContainer.GetAdjacencyStream(), out errorsAndWarnings);
                    if (errorsAndWarnings == null || errorsAndWarnings.Length == 0)
                    {
                        continue;
                    }
                    else
                    {
                        OpsConsole.WriteLine("Cleaning '{0}'", meshContainer.FriendlyName(model));
                        OpsConsole.WriteLine(errorsAndWarnings);
                    }

                    VertexElement[] OldVEs        = null;
                    int             offsetOfIndex = -1;
                    Mesh            dirtyMesh     = meshContainer.MeshData.Mesh;
                    if (meshContainer.SkinInformation != null)
                    {
                        int psizeUsageIdx = -1;
                        int remapIdx      = -1;
                        OldVEs = meshContainer.MeshData.Mesh.Declaration.Clone() as VertexElement[];

                        if (!MeshDeclarationHelper.FindValidUsageIndex(OldVEs, DeclarationUsage.PointSize, out psizeUsageIdx))
                        {
                            throw new OpsException("Could not add remapping-indexing vertex element to declaration");
                        }

                        VertexElement[] VEs = MeshDeclarationHelper.AddElement(OldVEs, DeclarationType.Float1, DeclarationUsage.PointSize, psizeUsageIdx, out remapIdx);

                        dirtyMesh = meshContainer.MeshData.Mesh.Clone(meshContainer.MeshData.Mesh.Options.Value, VEs, meshContainer.MeshData.Mesh.Device);

                        offsetOfIndex = VEs[remapIdx].Offset;
                        VertexBuffer   vb = dirtyMesh.VertexBuffer;
                        GraphicsStream gs = vb.Lock(0, 0, LockFlags.None);
                        for (int iVertex = 0; iVertex < dirtyMesh.NumberVertices; iVertex++)
                        {
                            gs.Seek(dirtyMesh.NumberBytesPerVertex * iVertex + offsetOfIndex, SeekOrigin.Begin);
                            gs.Write(iVertex);
                        }
                        vb.Unlock();
                        gs = null;
                        vb = null;
                    }

                    int[] adjOut;
                    Mesh  cleanedMesh = Mesh.Clean(CleanType.BackFacing | CleanType.BowTies, dirtyMesh, meshContainer.GetAdjacency(), out adjOut, out errorsAndWarnings);

                    if (errorsAndWarnings != null && errorsAndWarnings.Length != 0)
                    {
                        OpsConsole.WriteLine("Remaining Errors and Warnings:");
                        OpsConsole.WriteLine(errorsAndWarnings);
                    }

                    if (meshContainer.SkinInformation != null)
                    {
                        int[] vertexRemap = new int[cleanedMesh.NumberVertices];

                        VertexBuffer   vb = cleanedMesh.VertexBuffer;
                        GraphicsStream gs = vb.Lock(0, 0, LockFlags.None);
                        for (int iVertex = 0; iVertex < cleanedMesh.NumberVertices; iVertex++)
                        {
                            gs.Seek(cleanedMesh.NumberBytesPerVertex * iVertex + offsetOfIndex, SeekOrigin.Begin);
                            vertexRemap[iVertex] = (int)gs.Read(typeof(int));
                        }
                        vb.Unlock();

                        meshContainer.RemapSkin(vertexRemap);

                        cleanedMesh = cleanedMesh.Clone(cleanedMesh.Options.Value, OldVEs, cleanedMesh.Device);
                    }

                    meshContainer.SetAdjacency(adjOut);


                    meshContainer.ReplaceMesh(cleanedMesh);
                }
            }
        }
예제 #12
0
 public void RemapSkin( GraphicsStream vertexRemapStream )
 {
     if(SkinInformation != null && vertexRemapStream != null)
     {
         int[] vertexRemap= vertexRemap= vertexRemapStream.Read( typeof(int), new int[]{ MeshData.Mesh.NumberVertices } ) as int[];
         SkinInformation.Remap(vertexRemap);
     }
 }
예제 #13
0
 /// <summary>
 /// Read a vector from open xfile stream
 /// </summary>
 /// <param name="stream"></param>
 /// <returns></returns>
 private static Vector3 ReadVector(GraphicsStream stream)
 {
     Vector3 v = new Vector3();
     //			v = (Vector3)stream.Read(v.GetType());
     v.X = (float)stream.Read(v.X.GetType());
     v.Y = (float)stream.Read(v.X.GetType());
     v.Z = (float)stream.Read(v.X.GetType());
     return v;
 }
예제 #14
0
 /// <summary>
 /// Read a quaternion from open xfile stream
 /// </summary>
 /// <param name="stream"></param>
 /// <returns></returns>
 private static Quaternion ReadQuaternion(GraphicsStream stream)
 {
     Quaternion q = new Quaternion();
     q.W = (float)stream.Read(q.W.GetType());				// must read element by element to get WXYZ order
     q.X = (float)stream.Read(q.X.GetType());
     q.Y = (float)stream.Read(q.Y.GetType());
     q.Z = (float)stream.Read(q.Z.GetType());
     q.Normalize();
     //Debug.WriteLine(ThreeDee.DecodeQuaternion(q));
     return q;
 }
예제 #15
0
        /// <summary>
        /// Static method to calculate tangents along with the handedness of the tangents.
        /// </summary>
        /// <param name="model">Model to calculate the tangents on.</param>
        public static void CalculateTangents(Mesh model)
        {
            // Get a copy of the buffers.
            GraphicsStream ib = model.LockIndexBuffer(LockFlags.None);
            GraphicsStream vb = model.LockVertexBuffer(LockFlags.None);

            // List of the final vertex list.
            List <Vertex> final = new List <Vertex>();

            // Temperary lists to store vectors in.
            List <Vector3> tan1 = new List <Vector3>(model.NumberVertices);
            List <Vector3> tan2 = new List <Vector3>(model.NumberVertices);

            // Loop through and copy the vertex list from the vertex buffer
            // and to also add empty values to tan1 and tan2.
            for (int i = 0; i < model.NumberVertices; i++)
            {
                final.Add((Vertex)vb.Read(typeof(Vertex)));
                tan1.Add(new Vector3());
                tan2.Add(new Vector3());
            }

            // Various variables used in the calculation.
            int     i1, i2, i3;
            Vector3 v1, v2, v3;
            Vector2 w1, w2, w3;

            float x1, x2, y1, y2, z1, z2;
            float s1, s2, t1, t2, r;

            // Loop through and calculate the tangent information.
            for (int i = 0; i < model.NumberFaces; i++)
            {
                i1 = (int)ib.Read(typeof(int));
                i2 = (int)ib.Read(typeof(int));
                i3 = (int)ib.Read(typeof(int));

                // Get the vertex values for the 3 vertices of a face.
                Vertex vertex1 = final[i1];
                Vertex vertex2 = final[i2];
                Vertex vertex3 = final[i3];

                // Get the positions.
                v1 = vertex1.Position;
                v2 = vertex2.Position;
                v3 = vertex3.Position;

                // Get the texture coordinates.
                w1 = vertex1.TexCoord;
                w2 = vertex2.TexCoord;
                w3 = vertex3.TexCoord;

                x1 = v2.X - v1.X;
                x2 = v3.X - v1.X;
                y1 = v2.Y - v1.Y;
                y2 = v3.Y - v1.Y;
                z1 = v2.Z - v1.Z;
                z2 = v3.Z - v1.Z;

                s1 = w2.X - w1.X;
                s2 = w3.X - w1.X;
                t1 = w2.Y - w1.Y;
                t2 = w3.Y - w1.Y;

                r = 1.0F / (s1 * t2 - s2 * t1);

                // Calculate the direction of the vector
                Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r,
                                           (t2 * y1 - t1 * y2) * r,
                                           (t2 * z1 - t1 * z2) * r);
                // Calculate the direction of the uv
                Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r,
                                           (s1 * y2 - s2 * y1) * r,
                                           (s1 * z2 - s2 * z1) * r);

                Vector3 temp1 = tan1[i1];
                Vector3 temp2 = tan1[i2];
                Vector3 temp3 = tan1[i3];
                Vector3 temp4 = tan2[i1];
                Vector3 temp5 = tan2[i2];
                Vector3 temp6 = tan2[i3];

                tan1[i1] = temp1 + sdir;
                tan1[i2] = temp2 + sdir;
                tan1[i3] = temp3 + sdir;

                tan2[i1] = temp4 + tdir;
                tan2[i2] = temp5 + tdir;
                tan2[i3] = temp6 + tdir;
            }

            for (int i = 0; i < model.NumberVertices; i++)
            {
                Vertex tempVertex = final[i];

                Vector3 n = tempVertex.Normal;
                Vector3 t = tan1[i];

                Vector3 temp = (t - n * Vector3.Dot(n, t));
                temp.Normalize();

                // Gram-Schmidt orthogonalize
                tempVertex.Tangent = new Vector4(temp.X, temp.Y, temp.Z, 1.0f);

                // Calculate the handedness
                tempVertex.Tangent.W = (Vector3.Dot(Vector3.Cross(n, t), tan2[i]) < 0.0F) ? -1.0F : 1.0F;

                final[i] = tempVertex;
            }

            ib.Close();
            vb.Close();

            model.SetVertexBufferData(final.ToArray(), LockFlags.None);
        }
예제 #16
0
        //IOpsCommand
        public void Run(OpsContext context, OpsStatement statement)
        {
            CloneVDataArguments arguments = statement.Arguments as CloneVDataArguments;

            OpsConsole.WriteLine(String.Format("Cloning vertex element {0} as {1}", arguments.FriendlySrcName, arguments.FriendlyDstName));

            foreach (OpsModel model in statement.GetContent(context))
            {
                foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator())
                {
                    int srcIdx;
                    int dstIdx;

                    VertexElement[] OldVEs = meshContainer.MeshData.Mesh.Declaration.Clone() as VertexElement[];


                    int srcUsageIdx = arguments.srcUsageIdx;
                    if (arguments.hasSrcUsageIdx == false)
                    {
                        for (int i = 0; i < OldVEs.Length; i++)
                        {
                            if (OldVEs[i].DeclarationUsage == arguments.srcUsage)
                            {
                                srcUsageIdx = OldVEs[i].UsageIndex;
                                break;
                            }
                        }
                    }

                    if (srcUsageIdx < 0)
                    {
                        continue;
                    }

                    if (!MeshDeclarationHelper.FindElement(OldVEs, arguments.srcUsage, srcUsageIdx, out srcIdx))
                    {
                        throw new OpsException("Could not find source vertex element");
                    }

                    int dstUsageIdxPerMesh = arguments.dstUsageIdx;
                    if (!arguments.hasDstUsageIdx)
                    {
                        if (MeshDeclarationHelper.FindValidUsageIndex(OldVEs, arguments.dstUsage, out dstUsageIdxPerMesh, out dstIdx))
                        {
                            throw new OpsException("Could not find open usage index for destination vertex element");
                        }
                    }

                    int             copyIdx;
                    VertexElement[] VEs = MeshDeclarationHelper.AddElement(OldVEs, OldVEs[srcIdx].DeclarationType, arguments.dstUsage, dstUsageIdxPerMesh, out copyIdx);

                    if (!MeshDeclarationHelper.FindElement(VEs, arguments.srcUsage, srcUsageIdx, out srcIdx))
                    {
                        throw new OpsException("Could not find source vertex element");
                    }

                    if (!MeshDeclarationHelper.FindElement(VEs, arguments.dstUsage, dstUsageIdxPerMesh, out dstIdx))
                    {
                        throw new OpsException("Could not find destination vertex element");
                    }



                    Mesh newMesh = meshContainer.MeshData.Mesh.Clone(meshContainer.MeshData.Mesh.Options.Value, VEs, meshContainer.MeshData.Mesh.Device);

                    int    sizeInBytes = MeshDeclarationHelper.GetTypeSize(VEs[srcIdx].DeclarationType);
                    int    srcOffset   = VEs[srcIdx].Offset;
                    int    dstOffset   = VEs[dstIdx].Offset;
                    byte[] copyBuffer  = new byte[sizeInBytes];

                    VertexBuffer   vb = newMesh.VertexBuffer;
                    GraphicsStream gs = vb.Lock(0, 0, LockFlags.None);
                    for (int iVertex = 0; iVertex < newMesh.NumberVertices; iVertex++)
                    {
                        gs.Seek(newMesh.NumberBytesPerVertex * iVertex + srcOffset, SeekOrigin.Begin);
                        gs.Read(copyBuffer, 0, sizeInBytes);

                        gs.Seek(newMesh.NumberBytesPerVertex * iVertex + dstOffset, SeekOrigin.Begin);
                        gs.Write(copyBuffer, 0, sizeInBytes);
                    }
                    vb.Unlock();
                    gs = null;
                    vb = null;

                    meshContainer.ReplaceMesh(newMesh);
                }
            }
        }
예제 #17
0
        private static void CopyTextureData(GraphicsStream srcData, int srcWidth, int srcHeight, OpsFormatHelper formatHelp, int srcPitch, GraphicsStream dstData, int dstPitch)
        {
            Byte[] rowData = new Byte[srcWidth * formatHelp.SizeInBytes];
            for (int row = 0; row < srcHeight; row++)
            {
                srcData.Position = row * srcPitch;
                dstData.Position = row * dstPitch;

                srcData.Read(rowData, 0, rowData.Length);
                dstData.Write(rowData, 0, rowData.Length);
            }
        }