00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
00146 meshMaterials[i].Ambient = meshMaterials[i].Diffuse;
00147
00148
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
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
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
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
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 }