- Main Page
- Packages
- Classes
- Files

- File List
- File Members

# D:/guillaume/guillara/3D/DXGfx/Backup/DXGfxLib/MeshObject.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.IO;
    00024
    00025 namespace DXGfxLib
    00026 {
    00027     public class MeshObject : SceneObject
    00028     {
    00032         public Vector3 barycenter = new Vector3();
    00033
    00037         public float bSphereRadius;
    00038
    00042         protected Mesh originalMesh = null;
    00043
    00044         protected ExtendedMaterial[] extendedMaterials;
    00045
    00050         protected Material[] meshMaterials;
    00051
    00055         protected Texture[] meshTextures;
    00056
    00060         protected EffectInstance[] effects;
    00061
    00065         public float objectRadius = 0.0f;
    00066
    00070         public Vector3 objectCenter;
    00071
    00075         public MeshObject()
    00076         {
    00077             Initialize();
    00078         }
    00079
    00080         public override void Initialize()
    00081         {
    00082             base.Initialize();
    00083         }
    00084
    00089         public MeshObject(string fileName)
    00090         {
    00091             if (DXGfxManager.GetGlobalInstance().d3dDevice == null)
    00092             {
    00093                 throw new Exception("Manager does not have any reference to any valid d3ddevice, this constructor can not be executed");
    00094             }
    00095             LoadFromFile(DXGfxManager.GetGlobalInstance().d3dDevice, fileName);
    00096         }
    00097
    00103         public MeshObject(Device d3ddevice, string fileName)
    00104         {
    00105             LoadFromFile(d3ddevice, fileName);
    00106         }
    00107
    00111         public override void GetPrepared()
    00112         {
    00113             base.GetPrepared();
    00114
    00115             Device dxDevice = DXGfxManager.GetGlobalInstance().d3dDevice;
    00116
    00117             string currDir = Directory.GetCurrentDirectory();
    00118
    00119             if (!File.Exists(fileName))
    00120             {
    00121                 throw new Exception("The ressource file does not exist! There is a problem somewhere.... did you delete or moved any file?");
    00122             }
    00123             else
    00124             {
    00125                 LoadFromFile(dxDevice, fileName);
    00126             }
    00127
    00128         }
    00129
    00130         public override void LoadFromFile(Device d3ddevice, string fileName)
    00131         {
    00132             this.fileName = fileName;
    00133             this.name = StringUtil.GetName(fileName);
    00134
    00135             originalMesh = Mesh.FromFile(fileName, MeshFlags.Managed, d3ddevice, out extendedMaterials);
    00136
    00137             // We need to extract the material properties and texture names
    00138             meshTextures = new Texture[extendedMaterials.Length];
    00139             meshMaterials = new Material[extendedMaterials.Length];
    00140             for (int i = 0; i < extendedMaterials.Length; i++)
    00141             {
    00142                 if (File.Exists(extendedMaterials[i].TextureFilename))
    00143                 {
    00144                     meshMaterials[i] = extendedMaterials[i].Material3D;
    00145                     // Set the ambient color for the material (D3DX does not do this)
    00146                     meshMaterials[i].Ambient = meshMaterials[i].Diffuse;
    00147
    00148                     // Create the texture if there is one
    00149
    00150                     meshTextures[i] = ResourceCache.GetGlobalInstance().CreateTextureFromFile(d3ddevice,
    00151                                                                                       extendedMaterials[i].TextureFilename);
    00152
    00153                 }
    00154             }
    00155
    00156             localBoundingBox = CalculateLocalBBox(originalMesh);
    00157             extents = localBoundingBox.Size();
    00158
    00159             // Find the mesh's center, then generate a centering matrix
    00160             using (VertexBuffer vb = originalMesh.VertexBuffer)
    00161             {
    00162                 using (GraphicsStream stm = vb.Lock(0, 0, LockFlags.NoSystemLock))
    00163                 {
    00164                     try
    00165                     {
    00166                         this.bSphereRadius = Geometry.ComputeBoundingSphere(stm,
    00167                             originalMesh.NumberVertices, originalMesh.VertexFormat, out this.barycenter);
    00168                     }
    00169                     finally
    00170                     {
    00171                         vb.Unlock();
    00172                     }
    00173                 }
    00174             }
    00175         }
    00176
    00181         public MeshObject Clone()
    00182         {
    00183             MeshObject clone = new MeshObject();
    00184             clone.name = name;
    00185             clone.fileName = fileName;
    00186
    00187             clone.originalMesh = originalMesh;
    00188             clone.extendedMaterials = extendedMaterials;
    00189             clone.meshMaterials = meshMaterials;
    00190             clone.meshTextures = meshTextures;
    00191
    00192             clone.associatedEffectGroup = associatedEffectGroup;
    00193             clone.localBoundingBox = localBoundingBox;
    00194             clone.barycenter = barycenter;
    00195             clone.extents = extents;
    00196
    00197             return clone;
    00198         }
    00199
    00204         public virtual void Attach(Mesh mesh)
    00205         {
    00206             originalMesh = mesh;
    00207             localBoundingBox = CalculateLocalBBox(mesh);
    00208             extents = localBoundingBox.Size();
    00209
    00210             // Find the mesh's center, then generate a centering matrix
    00211             using (VertexBuffer vb = mesh.VertexBuffer)
    00212             {
    00213                 using (GraphicsStream stm = vb.Lock(0, 0, LockFlags.NoSystemLock))
    00214                 {
    00215                     try
    00216                     {
    00217                         this.bSphereRadius = Geometry.ComputeBoundingSphere(stm,
    00218                             mesh.NumberVertices, mesh.VertexFormat, out this.barycenter);
    00219                     }
    00220                     finally
    00221                     {
    00222                         vb.Unlock();
    00223                     }
    00224                 }
    00225             }
    00226         }
    00227
    00228
    00234         public override void Draw(Device device)
    00235         {
    00236             device.RenderState.CullMode = Cull.None;
    00237             device.SetTransform(TransformType.World, worldMat);
    00238
    00239             base.Draw(device);
    00240
    00241             for (int i = 0; i < originalMesh.NumberAttributes; i++)
    00242             {
    00243                 device.SetTexture(i, meshTextures[i]);
    00244                 originalMesh.DrawSubset(i);
    00245             }
    00246         }
    00247
    00255         public virtual void DrawSubset(int index)
    00256         {
    00257             originalMesh.DrawSubset(index);
    00258         }
    00259
    00269         public override bool Intersect(Vector3 rayPos, Vector3 rayDir, out IntersectInformation closestHit)
    00270         {
    00271             // Let's transform rayPos and rayDir to local coordinates
    00272             Matrix invWorldMat = Matrix.Invert(worldMat);
    00273             Vector3 rayPosLocal = Vector3.TransformCoordinate(rayPos, invWorldMat);
    00274             Vector3 rayDirLocal = Vector3.TransformNormal(rayDir, invWorldMat);
    00275             rayDirLocal.Normalize();
    00276             bool collision = false;
    00277             if (originalMesh != null)
    00278             {
    00279                 collision = originalMesh.Intersect(rayPosLocal, rayDirLocal, out closestHit);
    00280             }
    00281             else
    00282             {
    00283                 closestHit = new IntersectInformation();
    00284             }
    00285             return collision;
    00286         }
    00287
    00296         public override bool Intersect(Vector3 rayOri, Vector3 rayDir, ref List<SceneObject> collidingSceneObjects)
    00297         {
    00298             // First let's quickly check if we have any chance to collide with anything.
    00299             bool any = false;
    00300
    00301             AABBox aabox = new AABBox(worldAABBox);
    00302             bool collision = true;
    00303             if (((rayOri.X < aabox.vMin.X) && (rayDir.X <= 0))
    00304                 || ((rayOri.X > aabox.vMax.X) && (rayDir.X >= 0)))
    00305                 collision = false;
    00306             if (((rayOri.Y < aabox.vMin.Y) && (rayDir.Y <= 0))
    00307                 || ((rayOri.Y > aabox.vMax.Y) && (rayDir.Y >= 0)))
    00308                 collision = false;
    00309             if (((rayOri.Z < aabox.vMin.Z) && (rayDir.Z <= 0))
    00310                 || ((rayOri.Z > aabox.vMax.Z) && (rayDir.Z >= 0)))
    00311                 collision = false;
    00312
    00313             if (collision)
    00314             {
    00315                 foreach (SceneNode child in children)
    00316                 {
    00317                     if (child.Intersect(rayOri, rayDir, ref collidingSceneObjects))
    00318                         any = true;
    00319                 }
    00320
    00321                 Matrix invWorldMat = Matrix.Invert(worldMat);
    00322                 Vector3 rayPosLocal = Vector3.TransformCoordinate(rayOri, invWorldMat);
    00323                 Vector3 rayDirLocal = Vector3.TransformNormal(rayDir, invWorldMat);
    00324                 rayDirLocal.Normalize();
    00325
    00326                 if (originalMesh != null)
    00327                 {
    00328                     if (originalMesh.Intersect(rayPosLocal, rayDirLocal))
    00329                     {
    00330                         collidingSceneObjects.Add(this);
    00331                         any = true;
    00332                     }
    00333                 }
    00334                 else
    00335                 {
    00336                     collidingSceneObjects.Add(this);
    00337                     any = true;
    00338                 }
    00339             }
    00340
    00341             return any;
    00342         }
    00343
    00353         public override bool Intersect(Vector3 rayOri, Vector3 rayDir, ref List<SceneObject> collidingSceneObjects, System.Type desiredType)
    00354         {
    00355             bool any = false;
    00356
    00357             AABBox aabox = worldAABBox;
    00358             bool collision = true;
    00359             if (((rayOri.X < aabox.vMin.X) && (rayDir.X <= 0))
    00360                 || ((rayOri.X > aabox.vMax.X) && (rayDir.X >= 0)))
    00361                 collision = false;
    00362             if (((rayOri.Y < aabox.vMin.Y) && (rayDir.Y <= 0))
    00363                 || ((rayOri.Y > aabox.vMax.Y) && (rayDir.Y >= 0)))
    00364                 collision = false;
    00365             if (((rayOri.Z < aabox.vMin.Z) && (rayDir.Z <= 0))
    00366                 || ((rayOri.Z > aabox.vMax.Z) && (rayDir.Z >= 0)))
    00367                 collision = false;
    00368
    00369             if (collision)
    00370             {
    00371                 foreach (SceneNode child in children)
    00372                 {
    00373                     if (child.Intersect(rayOri, rayDir, ref collidingSceneObjects))
    00374                         any = true;
    00375                 }
    00376
    00377                 Matrix invWorldMat = Matrix.Invert(worldMat);
    00378                 Vector3 rayPosLocal = Vector3.TransformCoordinate(rayOri, invWorldMat);
    00379                 Vector3 rayDirLocal = Vector3.TransformNormal(rayDir, invWorldMat);
    00380                 rayDirLocal.Normalize();
    00381
    00382                 if (originalMesh != null)
    00383                 {
    00384                     if ((originalMesh.Intersect(rayPosLocal, rayDirLocal)) && (desiredType.IsInstanceOfType(this)))
    00385                     {
    00386                         collidingSceneObjects.Add(this);
    00387                         any = true;
    00388                     }
    00389                 }
    00390                 else
    00391                 {
    00392                     collidingSceneObjects.Add(this);
    00393                     any = true;
    00394                 }
    00395             }
    00396             return any;
    00397         }
    00398     }
    00399 }