示例#1
0
 public override void Register(SystemRenderer renderer, LibreLancer.Jitter.World physics)
 {
     for (int i = 0; i < fireFx.Count; i++)
     {
         fireFx[i].Effect.Register(renderer);
     }
 }
示例#2
0
 public GameWorld(SystemRenderer render)
 {
     Renderer             = render;
     render.World         = this;
     Physics              = new PhysicsWorld();
     Physics.FixedUpdate += FixedUpdate;
 }
示例#3
0
 public override void Register(SystemRenderer renderer)
 {
     sysr = renderer;
     sysr.Objects.Add(this);
     if (!inited)
     {
         if (Dfm != null)
         {
             Dfm.Initialize(sysr.Game.ResourceManager);
         }
         if (Model != null && Model.Levels.Length > 0)
         {
             Model.Initialize(sysr.Game.ResourceManager);
         }
         else if (Cmp != null)
         {
             Cmp.Initialize(sysr.Game.ResourceManager);
         }
         else if (Sph != null)
         {
             Sph.Initialize(sysr.Game.ResourceManager);
             if (Sph.SideMaterials.Length > 6)
             {
                 radiusAtmosphere = Sph.Radius * Sph.SideMaterials[6].Scale;
             }
             else
             {
                 radiusAtmosphere = Sph.Radius;
             }
         }
         inited = true;
     }
 }
示例#4
0
        public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
        {
            var visible = (
                LightOn &&
                Vector3.DistanceSquared(camera.Position, pos) < CULL &&
                camera.Frustum.Intersects(new BoundingSphere(pos, equip.BulbSize * 3))
                );

            this.sys = sys;
            bool showLight = !equip.Animated || !lt_on;

            if (equip.EmitRange > 0 && showLight && camera.Frustum.Intersects(new BoundingSphere(pos, equip.EmitRange)))
            {
                sys.PointLightDX(pos, equip.EmitRange, new Color4(equip.GlowColor, 1), equip.EmitAttenuation);
            }
            if (visible)
            {
                sys.AddObject(this);
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#5
0
        public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
        {
            _worldSph = World;
            if (Spin != Vector3.Zero)
            {
                _worldSph = (Matrix4x4.CreateRotationX((float)spinX) *
                             Matrix4x4.CreateRotationY((float)spinY) *
                             Matrix4x4.CreateRotationZ((float)spinZ)) * World;
            }
            this.sysr = sys;
            if (Nebula != null && nr != Nebula)
            {
                return(false);
            }
            var dsq = Vector3.DistanceSquared(pos, camera.Position);

            if (LODRanges != null)             //Fastest cull
            {
                var maxd = LODRanges[LODRanges.Length - 1] * sysr.LODMultiplier;
                maxd *= maxd;
                if (dsq > maxd)
                {
                    CurrentLevel = -1;
                    return(false);
                }
            }

            bool visible = false;

            if (Model != null)
            {
                visibleParts = new BitArray128();
                for (int i = 0; i < Model.AllParts.Length; i++)
                {
                    var part = Model.AllParts[i];
                    if (!part.Active || part.Mesh == null)
                    {
                        continue;
                    }
                    var center = Vector3.Transform(part.Mesh.Center, part.LocalTransform * World);
                    var lvl    = GetLevel(part, center, camera.Position);
                    if (lvl != -1)
                    {
                        var bsphere = new BoundingSphere(center, part.Mesh.Radius);
                        if (camera.Frustum.Intersects(bsphere))
                        {
                            visible         = true;
                            visibleParts[i] = true;
                        }
                    }
                }
            }

            if (visible)
            {
                sysr.AddObject(this);
            }
            return(visible);
        }
示例#6
0
 public GameWorld(SystemRenderer render)
 {
     Renderer             = render;
     render.World         = this;
     Physics              = new PhysicsWorld();
     Physics.FixedUpdate += FixedUpdate;
     Projectiles          = new ProjectileManager(this);
 }
示例#7
0
 public override void Unregister()
 {
     if (sys != null)
     {
         sys.Objects.Remove(this);
     }
     sys = null;
 }
示例#8
0
 public GameWorld(SystemRenderer render)
 {
     Renderer = render;
     Physics  = new World(new CollisionSystemSAP());
     Physics.CollisionSystem.EnableSpeculativeContacts = true;
     Physics.Gravity = Vector3.Zero;
     Physics.SetDampingFactors(1, 1);
     Physics.Events.PreStep += Events_PreStep;
 }
示例#9
0
 public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
 {
     this.sys     = sys;
     dist         = VectorMath.DistanceSquared(pos, camera.Position);
     fx.Resources = sys.Game.ResourceManager;
     if (Active && dist < (20000 * 20000))
     {
         sys.AddObject(this);
         return(true);
     }
     return(false);
 }
示例#10
0
        public Cutscene(ThnScriptContext context, GameDataManager gameData, Viewport viewport, Game game)
        {
            this.game     = game;
            this.gameData = gameData;
            scriptContext = context;
            camera        = new ThnCamera(viewport);

            Renderer = new SystemRenderer(camera, gameData, game.GetService <GameResourceManager>(), game);
            World    = new GameWorld(Renderer, false);
            //thn = script;
            var evs = new List <ThnEvent>();

            foreach (var thn in context.Scripts)
            {
                totalDuration = Math.Max(totalDuration, thn.Duration);
                foreach (var ev in thn.Events)
                {
                    ev.TimeOffset = 0;
                    evs.Add(ev);
                }
                AddEntities(thn);
            }
            //work around SET_CAMERA not being called in disco (match vanilla behaviour)
            var firstCamera = Objects.Values.Where(x => x.Camera != null).FirstOrDefault();

            if (firstCamera != null)
            {
                camera.Transform = firstCamera.Camera;
            }
            evs.Sort((x, y) => x.Time.CompareTo(y.Time));
            foreach (var item in evs)
            {
                events.Enqueue(item);
            }
            //Add starspheres in the right order
            var sorted = ((IEnumerable <Tuple <IDrawable, ThnObject> >)layers).Reverse().OrderBy(x => x.Item2.Entity.SortGroup).ToArray();

            Renderer.StarSphereModels    = new RigidModel[sorted.Length];
            Renderer.StarSphereWorlds    = new Matrix4x4[sorted.Length];
            Renderer.StarSphereLightings = new Lighting[sorted.Length];
            starSphereObjects            = new ThnObject[sorted.Length];
            for (int i = 0; i < sorted.Length; i++)
            {
                Renderer.StarSphereModels[i]    = (sorted[i].Item1 as IRigidModelFile).CreateRigidModel(true);
                Renderer.StarSphereWorlds[i]    = sorted[i].Item2.Rotate * Matrix4x4.CreateTranslation(sorted[i].Item2.Translate);
                Renderer.StarSphereLightings[i] = Lighting.Empty;
                starSphereObjects[i]            = sorted[i].Item2;
            }
            //Add objects to the renderer
            World.RegisterAll();
        }
示例#11
0
 public void PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
 {
     if (RenderComponent == null || RenderComponent.PrepareRender(camera, nr, sys))
     {
         foreach (var child in Children)
         {
             child.PrepareRender(camera, nr, sys);
         }
     }
     foreach (var child in ForceRenderCheck)
     {
         child.PrepareRender(camera, nr, sys);
     }
 }
示例#12
0
 public GameWorld(SystemRenderer render)
 {
     Physics = new PhysicsWorld();
     if (render != null)
     {
         Renderer             = render;
         render.World         = this;
         Renderer.PhysicsHook = () =>
         {
             Physics.DrawWorld();
         };
     }
     Physics.FixedUpdate += FixedUpdate;
     Projectiles          = new ProjectileManager(this);
 }
示例#13
0
        public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
        {
            var position = Vector3.Transform(Vector3.Zero, transform);
            var bsphere  = new BoundingSphere(position, RADIUS);

            if (camera.Frustum.Intersects(bsphere))
            {
                sys.AddObject(this);
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#14
0
 public void PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
 {
     if(RenderComponent == null || RenderComponent.PrepareRender(camera,nr,sys))
     {
         //Guns etc. aren't drawn when parent isn't on LOD0
         var isZero = RenderComponent == null || RenderComponent.CurrentLevel == 0;
         foreach (var child in Children) {
             if((child.RenderComponent != null && !child.RenderComponent.InheritCull) ||
                isZero)
             child.PrepareRender(camera, nr, sys);
         }
     }
     foreach (var child in ForceRenderCheck)
         child.PrepareRender(camera, nr, sys);
 }
示例#15
0
        public Cutscene(IEnumerable <ThnScript> scripts, FreelancerGame game, GameObject playerShip = null)
        {
            this.playerShip = playerShip;
            this.game       = game;

            camera = new ThnCamera(game.Viewport);

            Renderer = new SystemRenderer(camera, game.GameData, game.ResourceManager, game);
            World    = new GameWorld(Renderer);
            //thn = script;
            var evs = new List <ThnEvent>();

            foreach (var thn in scripts)
            {
                totalDuration = Math.Max(totalDuration, thn.Duration);
                foreach (var ev in thn.Events)
                {
                    ev.TimeOffset = 0;
                    evs.Add(ev);
                }
                AddEntities(thn);
            }
            //work around SET_CAMERA not being called in disco (match vanilla behaviour)
            var firstCamera = Objects.Values.Where(x => x.Camera != null).FirstOrDefault();

            if (firstCamera != null)
            {
                camera.Transform = firstCamera.Camera;
            }
            evs.Sort((x, y) => x.Time.CompareTo(y.Time));
            foreach (var item in evs)
            {
                events.Enqueue(item);
            }
            //Add starspheres in the right order
            var sorted = ((IEnumerable <Tuple <IDrawable, Matrix4, int> >)layers).Reverse().OrderBy(x => x.Item3).ToArray();

            Renderer.StarSphereModels = new IDrawable[sorted.Length];
            Renderer.StarSphereWorlds = new Matrix4[sorted.Length];
            for (int i = 0; i < sorted.Length; i++)
            {
                Renderer.StarSphereModels[i] = sorted[i].Item1;
                Renderer.StarSphereWorlds[i] = sorted[i].Item2;
            }
            //Add objects to the renderer
            World.RegisterAll();
        }
 public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
 {
     beams       = sys.Beams;
     renderCount = 0;
     for (int i = 0; i < Projectiles.Projectiles.Length; i++)
     {
         if (Projectiles.Projectiles[i].Alive)
         {
             toRender[renderCount++] = Projectiles.Projectiles[i];
         }
     }
     if (renderCount > 0)
     {
         sys.AddObject(this);
     }
     return(true);
 }
示例#17
0
        public DemoSystemView(FreelancerGame g) : base(g)
        {
            FLLog.Info("Game", "Starting System Viewer Demo");
            sys         = g.GameData.GetSystem("li01");
            camera      = new DebugCamera(g.Viewport);
            camera.Zoom = 5000;
            sysrender   = new SystemRenderer(camera, g.GameData, g.ResourceManager, g);
            world       = new GameWorld(sysrender);
            world.LoadSystem(sys, g.ResourceManager);
            g.Sound.PlayMusic(sys.MusicSpace);
            camera.UpdateProjection();

            trender               = new Renderer2D(Game.RenderState);
            font                  = g.Fonts.GetSystemFont("Agency FB");
            g.Keyboard.KeyDown   += G_Keyboard_KeyDown;
            g.Keyboard.TextInput += G_Keyboard_TextInput;
        }
示例#18
0
 public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
 {
     if (fx == null)
     {
         return(false);
     }
     this.sys     = sys;
     cameraPos    = camera.Position;
     dist         = VectorMath.DistanceSquared(pos, camera.Position);
     fx.Resources = sys.ResourceManager;
     if (Active && dist < (20000 * 20000))
     {
         sys.AddObject(this);
         fx.Pool = sys.FxPool;
         return(true);
     }
     fx.Pool = null;
     return(false);
 }
示例#19
0
 public void Register(SystemRenderer renderer, World physics)
 {
     if (RenderComponent != null)
     {
         RenderComponent.Register(renderer);
     }
     if (PhysicsComponent != null)
     {
         physics.AddBody(PhysicsComponent);
     }
     foreach (var child in Children)
     {
         child.Register(renderer, physics);
     }
     foreach (var component in Components)
     {
         component.Register(renderer, physics);
     }
 }
示例#20
0
 public GameWorld(SystemRenderer render, bool initPhys = true)
 {
     if (initPhys)
     {
         Physics = new PhysicsWorld();
     }
     if (render != null)
     {
         Renderer     = render;
         render.World = this;
         if (initPhys)
         {
             Renderer.PhysicsHook = () => { Physics.DrawWorld(); };
         }
     }
     if (initPhys)
     {
         Physics.FixedUpdate += FixedUpdate;
     }
     Projectiles = new ProjectileManager(this);
 }
示例#21
0
        public Cutscene(IEnumerable <ThnScript> scripts, FreelancerGame game, GameObject playerShip = null)
        {
            this.playerShip = playerShip;
            this.game       = game;

            camera = new ThnCamera(game.Viewport);

            Renderer = new SystemRenderer(camera, game.GameData, game.ResourceManager, game);
            World    = new GameWorld(Renderer);
            //thn = script;
            var evs = new List <ThnEvent>();

            foreach (var thn in scripts)
            {
                totalDuration = Math.Max(totalDuration, thn.Duration);
                foreach (var ev in thn.Events)
                {
                    ev.TimeOffset = 0;
                    evs.Add(ev);
                }
                AddEntities(thn);
            }

            evs.Sort((x, y) => x.Time.CompareTo(y.Time));
            foreach (var item in evs)
            {
                events.Enqueue(item);
            }
            //Add starspheres in the right order
            layers.Sort((x, y) => x.Item3.CompareTo(y.Item3));
            Renderer.StarSphereModels = new IDrawable[layers.Count];
            Renderer.StarSphereWorlds = new Matrix4[layers.Count];
            for (int i = 0; i < layers.Count; i++)
            {
                Renderer.StarSphereModels[i] = layers[i].Item1;
                Renderer.StarSphereWorlds[i] = layers[i].Item2;
            }
            //Add objects to the renderer
            World.RegisterAll();
        }
 public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
 {
     beams       = sys.Beams;
     renderCount = 0;
     for (int i = 0; i < Projectiles.Projectiles.Length; i++)
     {
         if (Projectiles.Projectiles[i].Alive)
         {
             if (Projectiles.Projectiles[i].Effect != null)
             {
                 Projectiles.Projectiles[i].Effect.Resources = sys.ResourceManager;
                 Projectiles.Projectiles[i].Effect.Pool      = sys.FxPool;
             }
             toRender[renderCount++] = Projectiles.Projectiles[i];
         }
     }
     if (renderCount > 0)
     {
         sys.AddObject(this);
     }
     return(true);
 }
示例#23
0
        public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
        {
            var visible = (
                VectorMath.DistanceSquared(camera.Position, pos) < CULL &&
                camera.Frustum.Intersects(new BoundingSphere(pos, equip.BulbSize * 3))
                );

            this.sys = sys;
            if (visible)
            {
                sys.AddObject(this);
                return(true);
            }
            else
            {
                return(false);
            }

            /*if (lt_on && camera.Frustum.Intersects(new BoundingSphere(pos, 100)))
             *          {
             *                  sys.PointLightDX(pos, 50, new Color4(equip.GlowColor, 1), new Vector3(1, 0.01f, 0.000055f));
             *          }*///TODO: Configurable
        }
示例#24
0
 public NebulaRenderer(Nebula n, ICamera c, Game g, SystemRenderer sysr)
 {
     Nebula     = n;
     camera     = c;
     game       = g;
     nverts     = g.GetService <NebulaVertices>();
     render2D   = g.GetService <Renderer2D>();
     resman     = g.GetService <ResourceManager>();
     billboards = g.GetService <Billboards>();
     this.sysr  = sysr;
     rand       = new Random();
     if (n.HasInteriorClouds)
     {
         puffsinterior = new InteriorPuff[n.InteriorCloudCount];
         for (int i = 0; i < n.InteriorCloudCount; i++)
         {
             puffsinterior[i].Spawned = false;
         }
     }
     GenerateExteriorPuffs();
     //Set Timers
     dynLightningTimer = Nebula.DynamicLightningGap;
     bckLightningTimer = Nebula.BackgroundLightningGap;
 }
示例#25
0
        public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
        {
            this.sysr = sys;
            if (Nebula != null && nr != Nebula)
            {
                return(false);
            }
            var dsq = VectorMath.DistanceSquared(pos, camera.Position);

            if (LODRanges != null)             //Fastest cull
            {
                var maxd = LODRanges[LODRanges.Length - 1] * sysr.LODMultiplier;
                maxd *= maxd;
                if (dsq > maxd)
                {
                    return(false);
                }
            }
            if (Model != null)
            {
                if (Model.Levels.Length != 0)
                {
                    var center = VectorMath.Transform(Model.Levels[0].Center, World);
                    var lvl    = GetLevel(Model, center, camera.Position);
                    if (lvl == null)
                    {
                        return(false);
                    }
                    var bsphere = new BoundingSphere(
                        center,
                        Model.Levels[0].Radius
                        );
                    if (!camera.Frustum.Intersects(bsphere))
                    {
                        return(false);                                     //Culled
                    }
                    sys.AddObject(this);
                    return(true);
                }
            }
            else if (Cmp != null || CmpParts != null)
            {
                //Check if -something- renders
                var  partCol  = (IEnumerable <Part>)CmpParts ?? Cmp.Parts;
                bool cmpParts = CmpParts != null;
                foreach (Part p in partCol)
                {
                    if (cmpParts)
                    {
                        p.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime));
                    }
                    var     model = p.Model;
                    Matrix4 w     = World;
                    if (p.Construct != null)
                    {
                        w = p.Construct.Transform * World;
                    }
                    if (model.Levels.Length > 0)
                    {
                        var center = VectorMath.Transform(model.Levels[0].Center, w);
                        var lvl    = GetLevel(model, center, camera.Position);
                        if (lvl == null)
                        {
                            continue;
                        }
                        var bsphere = new BoundingSphere(
                            center,
                            model.Levels[0].Radius
                            );
                        if (camera.Frustum.Intersects(bsphere))
                        {
                            sys.AddObject(this);
                            return(true);
                        }
                    }
                }
                return(false);
            }
            else if (Sph != null)
            {
                var bsphere = new BoundingSphere(
                    pos,
                    Math.Max(Sph.Radius, radiusAtmosphere));
                if (!camera.Frustum.Intersects(bsphere))
                {
                    return(false);
                }
                sys.AddObject(this);
                return(true);
            }
            return(false);
        }
示例#26
0
 public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys)
 {
     sysr = sys;
     sys.AddObject(this);
     return(true);
 }
示例#27
0
        void FinishLoad()
        {
            Game.Saves.Selected = -1;
            ui.OpenScene("hud");
            var shp = Game.GameData.GetShip(session.PlayerShip);

            //Set up player object + camera
            player       = new GameObject(shp.ModelFile.LoadFile(Game.ResourceManager), Game.ResourceManager);
            control      = new ShipPhysicsComponent(player);
            control.Ship = shp;
            shipInput    = new ShipInputComponent(player);
            player.Components.Add(shipInput);
            player.Components.Add(control);
            weapons = new WeaponControlComponent(player);
            player.Components.Add(weapons);
            player.Components.Add(new CDamageFuseComponent(player, shp.Fuses));

            player.SetLocalTransform(session.PlayerOrientation * Matrix4x4.CreateTranslation(session.PlayerPosition));
            player.PhysicsComponent.Mass = shp.Mass;
            playerHealth               = new CHealthComponent(player);
            playerHealth.MaxHealth     = shp.Hitpoints;
            playerHealth.CurrentHealth = shp.Hitpoints;
            player.Components.Add(playerHealth);
            if (shp.Mass < 0)
            {
                FLLog.Error("Ship", "Mass < 0");
            }

            player.Tag = GameObject.ClientPlayerTag;
            foreach (var equipment in session.Items.Where(x => !string.IsNullOrEmpty(x.Hardpoint)))
            {
                EquipmentObjectManager.InstantiateEquipment(player, Game.ResourceManager, EquipmentType.LocalPlayer, equipment.Hardpoint, equipment.Equipment);
            }
            powerCore = player.GetComponent <PowerCoreComponent>();
            if (powerCore == null)
            {
                throw new Exception("Player launched without a powercore equipped!");
            }
            camera = new ChaseCamera(Game.RenderContext.CurrentViewport, Game.GameData.Ini.Cameras);
            camera.ChasePosition    = session.PlayerPosition;
            camera.ChaseOrientation = player.LocalTransform.ClearTranslation();
            var offset = shp.ChaseOffset;

            camera.DesiredPositionOffset = offset;
            if (shp.CameraHorizontalTurnAngle > 0)
            {
                camera.HorizontalTurnAngle = shp.CameraHorizontalTurnAngle;
            }
            if (shp.CameraVerticalTurnUpAngle > 0)
            {
                camera.VerticalTurnUpAngle = shp.CameraVerticalTurnUpAngle;
            }
            if (shp.CameraVerticalTurnDownAngle > 0)
            {
                camera.VerticalTurnDownAngle = shp.CameraVerticalTurnDownAngle;
            }
            camera.Reset();

            sysrender           = new SystemRenderer(camera, Game.GameData, Game.ResourceManager, Game);
            sysrender.ZOverride = true; //Draw all with regular Z
            world = new GameWorld(sysrender);
            world.LoadSystem(sys, Game.ResourceManager, false, session.SpawnTime);
            session.WorldReady();
            player.World = world;
            world.AddObject(player);
            world.RenderUpdate  += World_RenderUpdate;
            world.PhysicsUpdate += World_PhysicsUpdate;
            player.Register(world.Physics);
            Game.Sound.PlayMusic(sys.MusicSpace);
            //world.Physics.EnableWireframes(debugphysics);
            cur_arrow                = Game.ResourceManager.GetCursor("arrow");
            cur_cross                = Game.ResourceManager.GetCursor("cross");
            cur_reticle              = Game.ResourceManager.GetCursor("fire_neutral");
            current_cur              = cur_cross;
            Game.Keyboard.TextInput += Game_TextInput;
            Game.Keyboard.KeyDown   += Keyboard_KeyDown;
            Game.Mouse.MouseDown    += Mouse_MouseDown;
            Game.Mouse.MouseUp      += Mouse_MouseUp;
            input = new InputManager(Game);
            input.ToggleActivated += Input_ToggleActivated;
            input.ToggleUp        += Input_ToggleUp;
            pilotcomponent         = new AutopilotComponent(player);
            player.Components.Add(pilotcomponent);
            player.World              = world;
            world.MessageBroadcasted += World_MessageBroadcasted;
            Game.Sound.ResetListenerVelocity();
            FadeIn(0.5, 0.5);
        }
示例#28
0
 public override void Unregister()
 {
     sysr.Objects.Remove(this);
     sysr = null;
 }
示例#29
0
 public override void Register(SystemRenderer renderer)
 {
     sysr = renderer;
     sysr.Objects.Add(this);
 }
示例#30
0
        public Cutscene(IEnumerable <ThnScript> scripts, FreelancerGame game)
        {
            camera = new ThnCamera(game.Viewport);

            Renderer = new SystemRenderer(camera, game.GameData, game.ResourceManager);
            World    = new GameWorld(Renderer);

            //thn = script;
            var  evs      = new List <ThnEvent>();
            bool hasScene = false;
            List <Tuple <IDrawable, Matrix4, int> > layers = new List <Tuple <IDrawable, Matrix4, int> >();

            foreach (var thn in scripts)
            {
                foreach (var ev in thn.Events)
                {
                    evs.Add(ev);
                }
                foreach (var kv in thn.Entities)
                {
                    if ((kv.Value.ObjectFlags & ThnObjectFlags.Reference) == ThnObjectFlags.Reference)
                    {
                        continue;
                    }
                    var obj = new ThnObject();
                    obj.Name      = kv.Key;
                    obj.Translate = kv.Value.Position ?? Vector3.Zero;
                    obj.Rotate    = kv.Value.RotationMatrix ?? Matrix4.Identity;
                    if (kv.Value.Type == EntityTypes.Compound)
                    {
                        //Fetch model
                        IDrawable drawable;
                        switch (kv.Value.MeshCategory.ToLowerInvariant())
                        {
                        case "solar":
                            drawable = game.GameData.GetSolar(kv.Value.Template);
                            break;

                        case "spaceship":
                            var sh = game.GameData.GetShip(kv.Value.Template);
                            drawable = sh.Drawable;
                            break;

                        case "prop":
                            drawable = game.GameData.GetProp(kv.Value.Template);
                            break;

                        case "room":
                            drawable = game.GameData.GetRoom(kv.Value.Template);
                            break;

                        case "equipment cart":
                            drawable = game.GameData.GetCart(kv.Value.Template);
                            break;

                        case "equipment":
                            var eq = game.GameData.GetEquipment(kv.Value.Template);
                            drawable = eq.GetDrawable();
                            break;

                        case "asteroid":
                            drawable = game.GameData.GetAsteroid(kv.Value.Template);
                            break;

                        default:
                            throw new NotImplementedException("Mesh Category " + kv.Value.MeshCategory);
                        }
                        if (kv.Value.UserFlag != 0)
                        {
                            //This is a starsphere
                            var transform = (kv.Value.RotationMatrix ?? Matrix4.Identity) * Matrix4.CreateTranslation(kv.Value.Position ?? Vector3.Zero);
                            layers.Add(new Tuple <IDrawable, Matrix4, int>(drawable, transform, kv.Value.SortGroup));
                        }
                        else
                        {
                            obj.Object = new GameObject(drawable, game.ResourceManager, false);
                            obj.Object.PhysicsComponent = null;                             //Jitter seems to interfere with directly setting orientation
                            var r = (ModelRenderer)obj.Object.RenderComponent;
                            r.LightGroup = kv.Value.LightGroup;
                            r.LitDynamic = (kv.Value.ObjectFlags & ThnObjectFlags.LitDynamic) == ThnObjectFlags.LitDynamic;
                            r.LitAmbient = (kv.Value.ObjectFlags & ThnObjectFlags.LitAmbient) == ThnObjectFlags.LitAmbient;
                            //HIDDEN just seems to be an editor flag?
                            //r.Hidden = (kv.Value.ObjectFlags & ThnObjectFlags.Hidden) == ThnObjectFlags.Hidden;
                            r.NoFog = kv.Value.NoFog;
                        }
                    }
                    else if (kv.Value.Type == EntityTypes.PSys)
                    {
                        var fx = game.GameData.GetEffect(kv.Value.Template);
                        obj.Object = new GameObject();
                        obj.Object.RenderComponent = new ParticleEffectRenderer(fx)
                        {
                            Active = false
                        };
                    }
                    else if (kv.Value.Type == EntityTypes.Scene)
                    {
                        if (hasScene)
                        {
                            //throw new Exception("Thn can only have one scene");
                            //TODO: This needs to be handled better
                            continue;
                        }
                        var amb = kv.Value.Ambient.Value;
                        if (amb.X == 0 && amb.Y == 0 && amb.Z == 0)
                        {
                            continue;
                        }
                        hasScene = true;
                        Renderer.SystemLighting.Ambient = new Color4(amb.X / 255f, amb.Y / 255f, amb.Z / 255f, 1);
                    }
                    else if (kv.Value.Type == EntityTypes.Light)
                    {
                        var lt = new DynamicLight();
                        lt.LightGroup = kv.Value.LightGroup;
                        lt.Active     = kv.Value.LightProps.On;
                        lt.Light      = kv.Value.LightProps.Render;
                        obj.Light     = lt;
                        if (kv.Value.RotationMatrix.HasValue)
                        {
                            var m = kv.Value.RotationMatrix.Value;
                            lt.Light.Direction = (new Vector4(lt.Light.Direction.Normalized(), 0) * m).Xyz.Normalized();
                        }
                        Renderer.SystemLighting.Lights.Add(lt);
                    }
                    else if (kv.Value.Type == EntityTypes.Camera)
                    {
                        obj.Camera             = new ThnCameraTransform();
                        obj.Camera.Position    = kv.Value.Position.Value;
                        obj.Camera.Orientation = kv.Value.RotationMatrix ?? Matrix4.Identity;
                        obj.Camera.FovH        = kv.Value.FovH ?? obj.Camera.FovH;
                        obj.Camera.AspectRatio = kv.Value.HVAspect ?? obj.Camera.AspectRatio;
                    }
                    else if (kv.Value.Type == EntityTypes.Marker)
                    {
                        obj.Object          = new GameObject();
                        obj.Object.Name     = "Marker";
                        obj.Object.Nickname = "";
                    }
                    if (obj.Object != null)
                    {
                        Vector3 transform = kv.Value.Position ?? Vector3.Zero;
                        obj.Object.Transform = (kv.Value.RotationMatrix ?? Matrix4.Identity) * Matrix4.CreateTranslation(transform);
                        World.Objects.Add(obj.Object);
                    }
                    obj.Entity = kv.Value;
                    Objects.Add(kv.Key, obj);
                }
            }
            evs.Sort((x, y) => x.Time.CompareTo(y.Time));
            foreach (var item in evs)
            {
                events.Enqueue(item);
            }
            //Add starspheres in the right order
            layers.Sort((x, y) => x.Item3.CompareTo(y.Item3));
            Renderer.StarSphereModels = new IDrawable[layers.Count];
            Renderer.StarSphereWorlds = new Matrix4[layers.Count];
            for (int i = 0; i < layers.Count; i++)
            {
                Renderer.StarSphereModels[i] = layers[i].Item1;
                Renderer.StarSphereWorlds[i] = layers[i].Item2;
            }
            //Add objects to the renderer
            World.RegisterAll();
        }