- Main Page
- Packages
- Classes
- Files

- File List
- File Members

# D:/guillaume/guillara/3D/DXGfx/Backup/DXGfxLib/Batch.cs

Go to the documentation of this file.

    00001 //BSD License
    00002 //DXGfx® - http://www.eteractions.com
    00003 //Copyright (c) 2005
    00004 //by Guillaume Randon
    00005 //Permission is hereby granted, free of charge, to any person obtaining a copy of this software
    00006 //and associated documentation files (the "Software"), to deal in the Software without restriction,
    00007 //including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
    00008 //and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
    00009 //subject to the following conditions:
    00010 //The above copyright notice and this permission notice shall be included in all copies or substantial
    00011 //portions of the Software.
    00012 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
    00013 //INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
    00014 //AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    00015 //DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    00016 //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    00017 using System;
    00018 using System.Collections.Generic;
    00019 using System.Text;
    00020 using Microsoft.DirectX;
    00021 using Microsoft.DirectX.Direct3D;
    00022 using Microsoft.Samples.DirectX.UtilityToolkit;
    00023 using System.Drawing;
    00024
    00025 namespace DXGfxLib
    00026 {
    00033     public struct InstanceInfo
    00034     {
    00035         public Vector4 positionRot;
    00036     }
    00037
    00051     public class Batch : IDisposable, IDrawable
    00052     {
    00057         private int maxNumberFaces = 5000;
    00058
    00062         private EffectGroup associatedEffetGroup = null;
    00063
    00067         public EffectGroup AssociatedEffectGroup
    00068         {
    00069             get { return associatedEffetGroup; }
    00070             set { associatedEffetGroup = value; }
    00071         }
    00072
    00076         protected bool hide = false;
    00077
    00081         public bool Hide
    00082         {
    00083             get { return hide; }
    00084             set { hide = value; }
    00085         }
    00086
    00091         public Material[] meshMaterials; // Materials for our mesh
    00092
    00096         public Texture[] meshTextures; // Textures for our mesh
    00097
    00101         public Mesh[] meshes = null;
    00102
    00106         private Mesh initialMesh = null;
    00107
    00111         private Matrix[] worldMatrices = null;
    00112
    00117         public Batch()
    00118         {
    00119             associatedEffetGroup = DXGfxManager.GetGlobalInstance().defaultEffectGroup;
    00120         }
    00121
    00125         public void Dispose()
    00126         {
    00127             if (meshes != null)
    00128             {
    00129                 foreach (Mesh mesh in meshes)
    00130                 {
    00131                     mesh.Dispose();
    00132                 }
    00133             }
    00134             if (meshTextures != null)
    00135             {
    00136                 foreach(Texture tex in meshTextures)
    00137                 {
    00138                     tex.Dispose();
    00139                 }
    00140             }
    00141         }
    00142
    00153         public void SetEffectsValues(Device d3ddevice, Effect eff, int pass)
    00154         {
    00155             d3ddevice.SetTransform(TransformType.World, Matrix.Identity);
    00156         }
    00157
    00158
    00164         public void Draw(Device d3ddevice)
    00165         {
    00166             // Meshes are divided into subsets, one for each material. Render them in
    00167             // a loop
    00168             for (int i = 0; i < meshMaterials.Length; i++)
    00169             {
    00170                 // Set the material and texture for this subset
    00171                 d3ddevice.Material = meshMaterials[i];
    00172                 d3ddevice.SetTexture(0, meshTextures[i]);
    00173
    00174                 // Draw the mesh subset
    00175                 foreach (Mesh mesh in meshes)
    00176                 {
    00177                     mesh.DrawSubset(i);
    00178                 }
    00179             }
    00180         }
    00181
    00191         public void Populate(Mesh initialMesh, Material[] materials, Texture[] textures, Matrix[] matrices)
    00192         {
    00193             this.initialMesh = initialMesh.Clone(initialMesh.Options.Value, CustomVertex.PositionNormalTextured.Format, initialMesh.Device);
    00194             this.worldMatrices = matrices;
    00195
    00196             meshMaterials = materials;
    00197             meshTextures = textures;
    00198
    00199             int max = Math.Max(initialMesh.NumberFaces, initialMesh.NumberVertices);
    00200             // Cannot create meshes with more than 65534 faces or vertices (check doc).
    00201             int maxInstanceInOneMesh = (int)Math.Floor((double)(maxNumberFaces / max));
    00202
    00203             if (matrices.Length > maxInstanceInOneMesh)
    00204             {
    00205                 int nbIter = (int)Math.Ceiling((double)(matrices.Length / maxInstanceInOneMesh));
    00206
    00207                 meshes = new Mesh[nbIter];
    00208
    00209                 for (int i = 0; i < nbIter; i++)
    00210                 {
    00211                     int start = Math.Min(i * maxInstanceInOneMesh, matrices.Length);
    00212                     int end = Math.Min((i + 1) * maxInstanceInOneMesh, matrices.Length);
    00213
    00214                     meshes[i] = BuildOneBigMeshForStaticInstanciating(worldMatrices, start, end);
    00215                 }
    00216             }
    00217             else
    00218             {
    00219                 meshes = new Mesh[1];
    00220                 meshes[0] = BuildOneBigMeshForStaticInstanciating(worldMatrices, 0, matrices.Length);
    00221             }
    00222         }
    00223
    00234         public Mesh BuildOneBigMeshForStaticInstanciating(Matrix[] worldMatrices, int startIndex, int endIndex)
    00235         {
    00236             if (initialMesh == null)
    00237             {
    00238                 throw new Exception("We need a valid initial mesh, please define one before calling this method!");
    00239             }
    00240
    00241             int nbInstance = endIndex - startIndex;
    00242             Mesh mesh = new Mesh(nbInstance * initialMesh.NumberFaces, nbInstance * initialMesh.NumberVertices, initialMesh.Options.Value,
    00243                 CustomVertex.PositionNormalTextured.Format, initialMesh.Device);
    00244
    00245             CustomVertex.PositionNormalTextured[] initialVertices = (CustomVertex.PositionNormalTextured[])initialMesh.LockVertexBuffer(typeof(CustomVertex.PositionNormalTextured),
    00246                 LockFlags.ReadOnly, initialMesh.NumberVertices);
    00247
    00248             GraphicsStream stm = mesh.LockVertexBuffer(LockFlags.NoSystemLock);
    00249
    00250             Int16[] initialIndices = (Int16[])initialMesh.LockIndexBuffer(typeof(Int16), LockFlags.ReadOnly, 3 * initialMesh.NumberFaces);
    00251
    00252             GraphicsStream stmi = mesh.LockIndexBuffer(LockFlags.None);
    00253
    00254             int count = 0;
    00255             for (int i = startIndex; i < endIndex; i++)
    00256             {
    00257                 Matrix mat = worldMatrices[i];
    00258                 CustomVertex.PositionNormalTextured[] instanceVertices = Transform(initialVertices, mat);
    00259
    00260                 stm.Write(instanceVertices);
    00261
    00262
    00263                 Int16[] instanceIndices = AddOffset(initialIndices, (Int16)(count * initialVertices.Length));
    00264
    00265                 stmi.Write(instanceIndices);
    00266
    00267                 count++;
    00268             }
    00269
    00270             initialMesh.UnlockVertexBuffer();
    00271             mesh.UnlockVertexBuffer();
    00272
    00273             initialMesh.UnlockIndexBuffer();
    00274             mesh.UnlockIndexBuffer();
    00275
    00276             //int[] adjacency = new int[3*initialMesh.NumberFaces];
    00277             //initialMesh.GenerateAdjacency(0.05f, adjacency);
    00278             //mesh.Optimize(MeshFlags.Managed, adjacency);
    00279
    00280             mesh.SetAttributeTable(initialMesh.GetAttributeTable());
    00281             int[] initialAttributes = initialMesh.LockAttributeBufferArray(LockFlags.ReadOnly);
    00282
    00283             int[] destAttributes = mesh.LockAttributeBufferArray(LockFlags.NoSystemLock);
    00284
    00285             count = 0;
    00286             for (int i = startIndex; i < endIndex; i++)
    00287             {
    00288                 initialAttributes.CopyTo(destAttributes, count * initialAttributes.Length);
    00289                 count++;
    00290             }
    00291
    00292             initialMesh.UnlockAttributeBuffer();
    00293             mesh.UnlockAttributeBuffer();
    00294
    00295             return mesh;
    00296         }
    00297
    00308         public CustomVertex.PositionNormalTextured[] Transform(CustomVertex.PositionNormalTextured[] vertices, Matrix mat)
    00309         {
    00310             CustomVertex.PositionNormalTextured[] outVertices = new CustomVertex.PositionNormalTextured[vertices.Length];
    00311             int compteur = 0;
    00312
    00313             foreach (CustomVertex.PositionNormalTextured vertex in vertices)
    00314             {
    00315                 Vector3 inVec = new Vector3(vertex.X, vertex.Y, vertex.Z);
    00316                 Vector3 inNorm = new Vector3(vertex.Nx, vertex.Ny, vertex.Nz);
    00317
    00318                 inVec.TransformCoordinate(mat);
    00319                 inNorm.TransformCoordinate(mat);
    00320
    00321                 outVertices[compteur].X = inVec.X;
    00322                 outVertices[compteur].Y = inVec.Y;
    00323                 outVertices[compteur].Z = inVec.Z;
    00324
    00325                 outVertices[compteur].Nx = inNorm.X;
    00326                 outVertices[compteur].Ny = inNorm.Y;
    00327                 outVertices[compteur].Nz = inNorm.Z;
    00328
    00329                 outVertices[compteur].Tu = vertex.Tu;
    00330                 outVertices[compteur].Tv = vertex.Tv;
    00331                 compteur++;
    00332             }
    00333
    00334             return outVertices;
    00335         }
    00336
    00343         public Int16[] AddOffset(Int16[] inIndices, int offset)
    00344         {
    00345             Int16[] outIndices = new Int16[inIndices.Length];
    00346             int compteur = 0;
    00347
    00348             foreach (Int16 index in inIndices)
    00349             {
    00350                 outIndices[compteur] = (Int16)(index + offset);
    00351                 compteur++;
    00352             }
    00353
    00354             return outIndices;
    00355         }
    00356
    00364         public int CompareTo(Object obj)
    00365         {
    00366             int ret = 1;
    00367             IDrawable drawable = obj as IDrawable;
    00368
    00369             if (drawable != null)
    00370             {
    00371                 ret = AssociatedEffectGroup.CompareTo(drawable.AssociatedEffectGroup);
    00372             }
    00373             return ret;
    00374         }
    00375
    00383         public int CompareTo(SceneObject sceneObj)
    00384         {
    00385             return AssociatedEffectGroup.CompareTo(sceneObj.AssociatedEffectGroup);
    00386         }
    00387
    00395         public int CompareTo(IDrawable sceneObj)
    00396         {
    00397             return AssociatedEffectGroup.CompareTo(sceneObj.AssociatedEffectGroup);
    00398         }
    00399     }
    00400 }