- Main Page
- Packages
- Classes
- Files

- File List
- File Members

# D:/guillaume/guillara/3D/DXGfx/Backup/DXGfxLib/Scene.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;
    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         //public List<SceneSprite> spritesToBeRendered;
    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             //spritesToBeRendered = new List<SceneSprite>();
    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             // TODO : We should also clean everything which is in the managed pool.
    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                 // Let's put some default settings  for the rendering of our scene
    00226                 d3ddevice.Lights[0].Enabled = true;
    00227                 // Turn on the zbuffer
    00228                 d3ddevice.RenderState.ZBufferEnable = true;
    00229
    00230                 // Turn on ambient lighting
    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             //List<Billboard> billboards = new List<Billboard>();
    00271             //foreach (SceneObject obj in objectsToBeRendered)
    00272             //{
    00273             //    Billboard bb = obj as Billboard;
    00274             //    if (bb == null)
    00275             //    {
    00276             //        obj.Draw(d3ddevice);
    00277             //    }
    00278             //    else
    00279             //    {
    00280             //        billboards.Add(bb);
    00281             //    }
    00282             //}
    00283
    00284             //billboards.Sort();
    00285             //if (Billboard.billboardRenderState!=null)
    00286             //{
    00287             //    Billboard.billboardRenderState.Apply();
    00288             //    d3ddevice.SetTransform(TransformType.View, currentFrustrum.matView);
    00289             //    d3ddevice.SetTransform(TransformType.Projection, currentFrustrum.matProj);
    00290             //}
    00291
    00292             //foreach (Billboard bb in billboards)
    00293             //{
    00294             //    bb.Draw(d3ddevice);
    00295             //}
    00296
    00297             //billboards.Clear();
    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 }