00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 using System;
00018 using System.Collections;
00019 using System.Collections.Generic;
00020 using System.Text;
00021 using System.Diagnostics;
00022 using System.Drawing;
00023 using Microsoft.DirectX;
00024 using Microsoft.DirectX.Direct3D;
00025 using Microsoft.Samples.DirectX.UtilityToolkit;
00026
00027 namespace DXGfxLib
00028 {
00029 public class Scene : IAmScriptable
00030 {
00034 protected static StateBlock defaultState = null;
00035
00039 public Frustrum currentFrustrum = null;
00040
00044 protected SceneNode rootNode = null;
00045
00049 public SceneNode RootNode
00050 {
00051 get { return rootNode; }
00052 }
00053
00058 public List<IDrawable> objectsToBeRendered;
00059
00060
00061
00065 public static Effect defaultEffect;
00066
00067 public string name = "Scene";
00068
00069 public string Name
00070 {
00071 get { return name; }
00072 set { name = value; }
00073 }
00074
00079 public Hashtable sceneContent = null;
00080
00086 public Scene()
00087 {
00088 Initialize();
00089 }
00090
00091 public void Initialize()
00092 {
00093
00094 rootNode = new SceneNode();
00095 rootNode.scene = this;
00096 rootNode.parent = rootNode;
00097 currentFrustrum = new Frustrum();
00098 objectsToBeRendered = new List<IDrawable>();
00099 sceneContent = new Hashtable();
00100
00101 }
00102
00106 public virtual void Dispose()
00107 {
00108 }
00109
00114 public virtual void GetPrepared()
00115 {
00116 IDictionaryEnumerator sceneObjects = sceneContent.GetEnumerator();
00117
00118 while (sceneObjects.MoveNext())
00119 {
00120 SceneObject currObj = sceneObjects.Value as SceneObject;
00121 if (currObj != null)
00122 {
00123 currObj.GetPrepared();
00124 Attach(currObj);
00125 }
00126 }
00127 }
00128
00134 public void DetachAll()
00135 {
00136 rootNode.DetachAll();
00137 }
00138
00142 public void CleanOnLostDevice()
00143 {
00144 if (defaultState != null)
00145 {
00146 defaultState.Dispose();
00147 defaultState = null;
00148 }
00149 }
00150
00154 public void CleanOnDestroyDevice()
00155 {
00156 CleanOnLostDevice();
00157
00158
00159 }
00160
00171 public virtual void Update(double appTime, float elapsedTime, Frustrum frustrum, List<IDrawable> objectsToBeRendered)
00172 {
00173 rootNode.Update(frustrum, elapsedTime, appTime, objectsToBeRendered);
00174 }
00175
00188 public void Update(Device d3ddevice, Matrix matview, Matrix matproj,double appTime, float elapsedTime)
00189 {
00190 objectsToBeRendered.Clear();
00191 currentFrustrum.ExtractFromMatrices(matview, matproj);
00192 Update(appTime, elapsedTime, currentFrustrum, objectsToBeRendered);
00193 objectsToBeRendered.Sort();
00194 }
00195
00202 public virtual void RenderScene(Device d3ddevice, Matrix matView, Matrix matProj)
00203 {
00204 Frustrum frustrum = new Frustrum();
00205 frustrum.ExtractFromMatrices(matView, matProj);
00206
00207 RenderScene(d3ddevice, frustrum);
00208 }
00209
00210 public virtual void Draw(Device d3ddevice, Frustrum frustrum)
00211 {
00212 RenderScene(d3ddevice, frustrum);
00213 }
00214
00221 public virtual void RenderScene(Device d3ddevice, Frustrum frustrum)
00222 {
00223 if (defaultState == null)
00224 {
00225
00226 d3ddevice.Lights[0].Enabled = true;
00227
00228 d3ddevice.RenderState.ZBufferEnable = true;
00229
00230
00231 d3ddevice.RenderState.Ambient = System.Drawing.Color.White;
00232 d3ddevice.RenderState.DitherEnable = true;
00233 d3ddevice.RenderState.SpecularEnable = false;
00234 d3ddevice.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
00235 d3ddevice.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
00236 d3ddevice.TextureState[0].ColorOperation = TextureOperation.Modulate;
00237 d3ddevice.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;
00238 d3ddevice.TextureState[0].AlphaOperation = TextureOperation.SelectArg1;
00239 d3ddevice.SamplerState[0].MinFilter = TextureFilter.Linear;
00240 d3ddevice.SamplerState[0].MagFilter = TextureFilter.Linear;
00241 d3ddevice.SamplerState[1].MinFilter = TextureFilter.Linear;
00242 d3ddevice.SamplerState[1].MagFilter = TextureFilter.Linear;
00243
00244 d3ddevice.RenderState.FogEnable = true;
00245 d3ddevice.RenderState.FogColor = Color.AntiqueWhite;
00246 d3ddevice.RenderState.FogTableMode = FogMode.Linear;
00247 d3ddevice.RenderState.FogStart = 30.0f;
00248 d3ddevice.RenderState.FogEnd = 400.0f;
00249
00250 defaultState = new StateBlock(d3ddevice, StateBlockType.All);
00251 defaultState.Capture();
00252 }
00253 else
00254 {
00255 defaultState.Apply();
00256 }
00257
00258
00259 d3ddevice.SetTransform(TransformType.View, frustrum.matView);
00260 d3ddevice.SetTransform(TransformType.Projection, frustrum.matProj);
00261
00262 if (objectsToBeRendered.Count > 0)
00263 {
00264 foreach (SceneObject obj in objectsToBeRendered)
00265 {
00266 obj.Draw(d3ddevice);
00267 }
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 }
00299
00312 public virtual SceneObject Attach(FrameworkMesh meshToAttach)
00313 {
00314 FrameworkMeshObject newSceneObject = new FrameworkMeshObject();
00315 newSceneObject.Attach(meshToAttach);
00316
00317 Attach(newSceneObject);
00318
00319 return newSceneObject;
00320 }
00321
00334 public virtual SceneObject AttachWithLOD(Device d3ddevice, FrameworkMesh meshToAttach)
00335 {
00336 FrameworkMeshObject newSceneObject = new FrameworkMeshObject();
00337 newSceneObject.AttachWithLOD(d3ddevice, meshToAttach);
00338
00339 Attach(newSceneObject);
00340
00341 return newSceneObject;
00342 }
00343
00351 public virtual void Attach(SceneObject sceneObj)
00352 {
00353 rootNode.AddChild(sceneObj);
00354 }
00355
00361 public virtual void Detach(SceneNode sceneNodeToDetach)
00362 {
00363 if (sceneNodeToDetach == null)
00364 {
00365 throw new ArgumentNullException("sceneObjectToDetach is null, which is wrong!");
00366 }
00367 if (rootNode == null)
00368 {
00369 throw new NullReferenceException("rootNode is null which is not expected here!");
00370 }
00371
00372 sceneNodeToDetach.DetachAll();
00373
00374 rootNode.Detach(sceneNodeToDetach);
00375 }
00376
00383 public virtual bool Collide(SceneNode sceneNode, ref List<SceneObject> collidingSceneObjects)
00384 {
00385 return rootNode.Collide(sceneNode, ref collidingSceneObjects);
00386 }
00387
00394 public virtual bool CollideSolid(SceneNode sceneNode, ref List<SceneObject> collidingSceneObjects)
00395 {
00396 return rootNode.CollideSolid(sceneNode, ref collidingSceneObjects);
00397 }
00398
00406 public virtual bool Collide(SceneNode sceneNode, ref List<SceneObject> collidingSceneObjects, System.Type desiredType)
00407 {
00408 return rootNode.Collide(sceneNode, ref collidingSceneObjects, desiredType);
00409 }
00410
00418 public virtual bool CollideSolid(SceneNode sceneNode, ref List<SceneObject> collidingSceneObjects, System.Type desiredType)
00419 {
00420 return rootNode.CollideSolid(sceneNode, ref collidingSceneObjects, desiredType);
00421 }
00422
00434 public virtual bool Intersect(Vector3 rayOri, Vector3 rayDir, ref List<SceneObject> collidingSceneObjects)
00435 {
00436 return rootNode.Intersect(rayOri, rayDir, ref collidingSceneObjects);
00437 }
00438
00448 public virtual bool Intersect(Vector3 rayOri, Vector3 rayDir, ref List<SceneObject> collidingSceneObject, System.Type desiredType)
00449 {
00450 return rootNode.Intersect(rayOri, rayDir, ref collidingSceneObject, desiredType);
00451 }
00452
00463 public virtual bool Pick(Viewport viewport, Matrix proj, Matrix view, Vector2 screenPos, ref SceneObject[] pickedObjects, ref IntersectInformation[] hits)
00464 {
00465 Vector3 rayOrig;
00466 Vector3 rayDir;
00467 MathUtil.RayFromScreenPos(viewport, proj, view, screenPos, out rayOrig, out rayDir);
00468
00469 List<SceneObject> collidingSceneObjects = new List<SceneObject>();
00470
00471 bool any = Intersect(rayOrig, rayDir, ref collidingSceneObjects);
00472
00473 if (any)
00474 {
00475 if (pickedObjects == null)
00476 pickedObjects = new SceneObject[collidingSceneObjects.Count];
00477
00478 if (hits == null)
00479 hits = new IntersectInformation[collidingSceneObjects.Count];
00480
00481 int index = 0;
00482
00483 foreach (SceneObject sceneObj in collidingSceneObjects)
00484 {
00485 Microsoft.DirectX.Direct3D.IntersectInformation closestHit = new IntersectInformation();
00486
00487 sceneObj.Intersect(rayOrig, rayDir, out closestHit);
00488
00489 pickedObjects[index] = sceneObj;
00490 hits[index] = closestHit;
00491 }
00492 return true;
00493 }
00494 else
00495 return false;
00496 }
00497
00507 public virtual SceneObject PickObject(Viewport viewport, Matrix proj, Matrix view, Vector2 screenPos)
00508 {
00509 return PickObject(viewport, proj, view, screenPos, typeof(SceneObject));
00510 }
00511
00521 public virtual SceneObject PickObject(Viewport viewport, Matrix proj, Matrix view, Vector2 screenPos, Type desiredType)
00522 {
00523 Vector3 rayOrig;
00524 Vector3 rayDir;
00525 MathUtil.RayFromScreenPos(viewport, proj, view, screenPos, out rayOrig, out rayDir);
00526
00527
00528 List<SceneObject> collidingSceneObjects = new List<SceneObject>();
00529
00530 bool any = Intersect(rayOrig, rayDir, ref collidingSceneObjects, desiredType);
00531
00532 SceneObject res = null;
00533
00534 if (any)
00535 {
00536 float refVal = 10000.0f;
00537
00538 foreach (SceneObject sceneObj in collidingSceneObjects)
00539 {
00540 Microsoft.DirectX.Direct3D.IntersectInformation closestHit = new IntersectInformation();
00541
00542 sceneObj.Intersect(rayOrig, rayDir, out closestHit);
00543
00544 if (closestHit.Dist < refVal)
00545 {
00546 res = sceneObj;
00547 refVal = closestHit.Dist;
00548 }
00549 }
00550 }
00551 return res;
00552 }
00553
00558 protected Script script = null;
00559
00563 internal Script OurScript
00564 {
00565 get { return script; }
00566 }
00567
00572 protected TimeLine timeline = null;
00573
00578 public void SetScript(Script script)
00579 {
00580 this.script = script;
00581 this.script.SetParent(null);
00582 this.script.SetScene(this);
00583 }
00584
00589 public Script GetScript()
00590 {
00591 if (script == null)
00592 {
00593 SetScript(new Script());
00594 }
00595 return script;
00596 }
00597
00602 public void SetTimeLine(TimeLine timeLine)
00603 {
00604 this.timeline = timeLine;
00605 this.timeline.SetParent(null);
00606 this.timeline.SetScene(this);
00607 }
00608
00613 public TimeLine GetTimeLine()
00614 {
00615 if (timeline == null)
00616 {
00617 SetTimeLine(new TimeLine());
00618 }
00619 return timeline;
00620 }
00621
00632 public virtual void Evaluate(double appTime, float elapsedTime)
00633 {
00634 if (script != null)
00635 {
00636 script.Evaluate(appTime, elapsedTime);
00637 }
00638 if (timeline != null)
00639 {
00640 timeline.Evaluate(appTime, elapsedTime);
00641 }
00642 }
00643
00648 public void Reset()
00649 {
00650 if (script != null)
00651 {
00652 script.Reset();
00653 }
00654 if (timeline != null)
00655 {
00656 timeline.Reset();
00657 }
00658 }
00659
00660
00666 private List<Event> events = null;
00667
00672 public void AddEvent(Event evt)
00673 {
00674 events.Add(evt);
00675 }
00676
00681 public void RemoveEvent(Event evt)
00682 {
00683 events.Remove(evt);
00684 }
00685
00691 public virtual void Clicked(double appTime, float elapsedTime)
00692 {
00693 if (script != null)
00694 {
00695 script.Clicked(appTime, elapsedTime);
00696 }
00697 }
00698
00706 public virtual void Collision(double appTime, float elapsedTime, SceneObject collidingObject)
00707 {
00708 if (script != null)
00709 {
00710 script.Collision(appTime, elapsedTime, collidingObject);
00711 }
00712 }
00713
00725 public Event[] popEventsByName(string name)
00726 {
00727 List<Event> ret = new List<Event>();
00728
00729 foreach (Event evt in events)
00730 {
00731 if (evt.name.Equals(name))
00732 {
00733 ret.Add(evt);
00734 events.Remove(evt);
00735 }
00736 }
00737
00738 return ret.ToArray();
00739 }
00740
00752 public Event[] popEventsByType(string type)
00753 {
00754 List<Event> ret = new List<Event>();
00755
00756 foreach (Event evt in events)
00757 {
00758 if (evt.type.Equals(type))
00759 {
00760 ret.Add(evt);
00761 events.Remove(evt);
00762 }
00763 }
00764
00765 return ret.ToArray();
00766 }
00767
00779 public Event[] peekEventsByName(string name)
00780 {
00781 List<Event> ret = new List<Event>();
00782
00783 foreach (Event evt in events)
00784 {
00785 if (evt.name.Equals(name))
00786 {
00787 ret.Add(evt);
00788 }
00789 }
00790
00791 return ret.ToArray();
00792 }
00793
00805 public Event[] peekEventsByType(string type)
00806 {
00807 List<Event> ret = new List<Event>();
00808
00809 foreach (Event evt in events)
00810 {
00811 if (evt.type.Equals(type))
00812 {
00813 ret.Add(evt);
00814 }
00815 }
00816
00817 return ret.ToArray();
00818 }
00819
00830 public virtual Vector3 PickEnvironmentPosition(Viewport viewport, Matrix proj, Matrix view, Vector2 screenPos)
00831 {
00832 return new Vector3();
00833 }
00834 }
00835 }