void InitWithDrawable(IDrawable drawable, ResourceManager res, bool draw, bool staticpos, bool havePhys = true) { Resources = res; dr = drawable; PhysicsComponent phys = null; bool isCmp = false; string name = ""; if (draw) { drawable?.Initialize(res); } if (dr is SphFile) { var radius = ((SphFile)dr).Radius; phys = new PhysicsComponent(this) { SphereRadius = radius }; name = ((SphFile)dr).SideMaterialNames[0]; RigidModel = ((SphFile)dr).CreateRigidModel(draw); } else if (dr is IRigidModelFile mdl) { //var mdl = dr as ModelFile; RigidModel = mdl.CreateRigidModel(draw); var path = Path.ChangeExtension(RigidModel.Path, "sur"); name = Path.GetFileNameWithoutExtension(RigidModel.Path); if (File.Exists(path)) { phys = new PhysicsComponent(this) { SurPath = path } } ; if (RigidModel.Animation != null) { AnimationComponent = new AnimationComponent(this, RigidModel.Animation); Components.Add(AnimationComponent); } } if (havePhys && phys != null) { PhysicsComponent = phys; Components.Add(phys); } PopulateHardpoints(); if (draw && RigidModel != null) { RenderComponent = new ModelRenderer(RigidModel) { Name = name }; } }
void ProcessNextCutscene() { var ct = toPlay.Dequeue(); int position = 0; int i = 0; foreach (var npc in ct.Chars) { var obj = new GameObject() { Nickname = npc.Actor }; var costumeName = Game.GameData.GetCostumeForNPC(npc.Npc); Game.GameData.GetCostume(costumeName, out var body, out var head, out var lh, out var rh); var skel = new DfmSkeletonManager(body, head, lh, rh); obj.RenderComponent = new CharacterRenderer(skel); var anmComponent = new AnimationComponent(obj, Game.GameData.GetCharacterAnimations()); obj.AnimationComponent = anmComponent; obj.Components.Add(anmComponent); string spot = npc.Spot; if (string.IsNullOrEmpty(spot)) { spot = ct.Reserves[0].Spot[position++]; } var pos = scene.GetObject(spot).Translate; obj.SetLocalTransform(Matrix4x4.CreateTranslation(pos)); var thnObj = new ThnObject(); thnObj.Name = npc.Actor; thnObj.Rotate = Matrix4x4.Identity; thnObj.Translate = pos; thnObj.Object = obj; scene.AddObject(thnObj); scene.FidgetScript(new ThnScript(session.Game.GameData.ResolveDataPath(npc.Fidget))); if (i == 0) { hotspots.Add(new RTCHotspot() { ini = ct, obj = thnObj, npc = npc.Npc }); } i++; } }
void InitWithDrawable(IDrawable drawable, ResourceManager res, bool draw, bool staticpos, bool havePhys = true) { Resources = res; dr = drawable; PhysicsComponent phys = null; bool isCmp = false; string name = ""; if (dr is SphFile) { var radius = ((SphFile)dr).Radius; phys = new PhysicsComponent(this) { SphereRadius = radius }; name = ((SphFile)dr).SideMaterialNames[0]; } else if (dr is ModelFile) { var mdl = dr as ModelFile; var path = Path.ChangeExtension(mdl.Path, "sur"); name = Path.GetFileNameWithoutExtension(mdl.Path); if (File.Exists(path)) { phys = new PhysicsComponent(this) { SurPath = path } } ; } else if (dr is CmpFile) { isCmp = true; var cmp = dr as CmpFile; CmpParts = new List <Part>(); CmpConstructs = cmp.Constructs.CloneAll(); foreach (var part in cmp.Parts) { CmpParts.Add(part.Clone(CmpConstructs)); } if (cmp.Animation != null) { AnimationComponent = new AnimationComponent(this, cmp.Animation); Components.Add(AnimationComponent); } var path = Path.ChangeExtension(cmp.Path, "sur"); name = Path.GetFileNameWithoutExtension(cmp.Path); if (File.Exists(path)) { phys = new PhysicsComponent(this) { SurPath = path } } ; } if (havePhys && phys != null) { PhysicsComponent = phys; Components.Add(phys); } PopulateHardpoints(dr); if (draw) { if (isCmp) { RenderComponent = new ModelRenderer(CmpParts, (dr as CmpFile)) { Name = name } } ; else { RenderComponent = new ModelRenderer(dr) { Name = name } }; } }
void InitWithDrawable(IDrawable drawable, ResourceManager res, bool staticpos, bool havePhys = true) { Resources = res; dr = drawable; PhysicsComponent phys = null; bool isCmp = false; string name = ""; if (dr is SphFile) { var radius = ((SphFile)dr).Radius; phys = new PhysicsComponent(this) { SphereRadius = radius }; name = ((SphFile)dr).SideMaterialNames[0]; } else if (dr is ModelFile) { var mdl = dr as ModelFile; var path = Path.ChangeExtension(mdl.Path, "sur"); name = Path.GetFileNameWithoutExtension(mdl.Path); if (File.Exists(path)) { phys = new PhysicsComponent(this) { SurPath = path } } ; } else if (dr is CmpFile) { isCmp = true; var cmp = dr as CmpFile; CmpParts = new List <Part>(); CmpConstructs = cmp.Constructs.CloneAll(); foreach (var part in cmp.Parts) { CmpParts.Add(part.Clone(CmpConstructs)); } if (cmp.Animation != null) { AnimationComponent = new AnimationComponent(this, cmp.Animation); Components.Add(AnimationComponent); } var path = Path.ChangeExtension(cmp.Path, "sur"); name = Path.GetFileNameWithoutExtension(cmp.Path); if (File.Exists(path)) { phys = new PhysicsComponent(this) { SurPath = path } } ; /*if (File.Exists(path)) * { * SurFile sur = res.GetSur(path); * var shapes = new List<CompoundSurShape.TransformedShape>(); * foreach (var part in CmpParts) * { * var crc = CrcTool.FLModelCrc(part.ObjectName); * if (!sur.HasShape(crc)) * { * FLLog.Warning("Sur", "No hitbox for " + part.ObjectName); * continue; * } * var colshape = sur.GetShape(crc); * if (part.Construct == null) * { * foreach (var s in colshape) * shapes.Add(new CompoundSurShape.TransformedShape(s, Matrix3.Identity, Vector3.Zero)); } * else * { * var tr = part.Construct.Transform; * var pos = tr.ExtractTranslation(); * var q = tr.ExtractRotation(true); * var rot = Matrix3.CreateFromQuaternion(q); * foreach (var s in colshape) * shapes.Add(new CompoundSurShape.TransformedShape(s, rot, pos) { Tag = part.Construct }); * } * } * collisionShape = new CompoundSurShape(shapes); * }*/ } if (havePhys && phys != null) { PhysicsComponent = phys; Components.Add(phys); } PopulateHardpoints(dr); if (isCmp) { RenderComponent = new ModelRenderer(CmpParts, (dr as CmpFile)) { Name = name } } ; else { RenderComponent = new ModelRenderer(dr) { Name = name } }; }
void AddEntities(ThnScript thn) { foreach (var kv in thn.Entities) { if (Objects.ContainsKey(kv.Key)) { continue; } 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 ?? Matrix4x4.Identity; //PlayerShip object if (spawnObjects && scriptContext.PlayerShip != null && kv.Value.Type == EntityTypes.Compound && kv.Value.Template.Equals("playership", StringComparison.InvariantCultureIgnoreCase)) { obj.Object = scriptContext.PlayerShip; obj.Object.RenderComponent.LitDynamic = (kv.Value.ObjectFlags & ThnObjectFlags.LitDynamic) == ThnObjectFlags.LitDynamic; obj.Object.RenderComponent.LitAmbient = (kv.Value.ObjectFlags & ThnObjectFlags.LitAmbient) == ThnObjectFlags.LitAmbient; obj.Object.RenderComponent.NoFog = kv.Value.NoFog; ((ModelRenderer)obj.Object.RenderComponent).LightGroup = kv.Value.LightGroup; obj.Entity = kv.Value; Vector3 transform = kv.Value.Position ?? Vector3.Zero; obj.Object.Transform = (kv.Value.RotationMatrix ?? Matrix4x4.Identity) * Matrix4x4.CreateTranslation(transform); obj.HpMount = scriptContext.PlayerShip.GetHardpoint("HpMount"); World.Objects.Add(obj.Object); Objects.Add(kv.Key, obj); continue; } var template = kv.Value.Template; string replacement; if (scriptContext != null && scriptContext.Substitutions.TryGetValue(kv.Value.Template, out replacement)) { template = replacement; } var resman = game.GetService <ResourceManager>(); if (spawnObjects && kv.Value.Type == EntityTypes.Compound) { bool getHpMount = false; //Fetch model IDrawable drawable = null; if (!string.IsNullOrEmpty(template)) { switch (kv.Value.MeshCategory.ToLowerInvariant()) { case "solar": drawable = gameData.GetSolar(template); break; case "ship": case "spaceship": getHpMount = true; var sh = gameData.GetShip(template); drawable = sh.ModelFile.LoadFile(resman); break; case "prop": drawable = gameData.GetProp(template); break; case "room": drawable = gameData.GetRoom(template); break; case "equipment cart": drawable = gameData.GetCart(template); break; case "equipment": var eq = gameData.GetEquipment(template); drawable = eq?.ModelFile.LoadFile(resman); break; case "asteroid": drawable = gameData.GetAsteroid(kv.Value.Template); break; default: throw new NotImplementedException("Mesh Category " + kv.Value.MeshCategory); } } else { FLLog.Warning("Thn", $"object '{kv.Value.Name}' has empty template, category " + $"'{kv.Value.MeshCategory}'"); } drawable?.Initialize(resman); if (kv.Value.UserFlag != 0) { //This is a starsphere layers.Add(new Tuple <IDrawable, ThnObject>(drawable, obj)); } else { obj.Object = new GameObject(drawable, game.GetService <ResourceManager>(), true, false, false); obj.Object.Name = kv.Value.Name; obj.Object.PhysicsComponent = null; //Jitter seems to interfere with directly setting orientation if (getHpMount) { obj.HpMount = obj.Object.GetHardpoint("HpMount"); } var r = (ModelRenderer)obj.Object.RenderComponent; if (r != null) { 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 = gameData.GetEffect(kv.Value.Template); if (fx != null) { obj.Object = new GameObject(); obj.Object.RenderComponent = new ParticleEffectRenderer(fx.GetEffect(resman)) { Active = false }; } } else if (kv.Value.Type == EntityTypes.Scene) { if (kv.Value.DisplayText != null) { text = kv.Value.DisplayText; } 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; obj.LightDir = lt.Light.Direction; if (kv.Value.RotationMatrix.HasValue) { var m = kv.Value.RotationMatrix.Value; lt.Light.Direction = Vector3.TransformNormal(lt.Light.Direction, m); } if (Renderer != null) { 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 ?? Matrix4x4.Identity; obj.Camera.FovH = kv.Value.FovH ?? obj.Camera.FovH; obj.Camera.AspectRatio = kv.Value.HVAspect ?? obj.Camera.AspectRatio; if (kv.Value.NearPlane != null) { obj.Camera.Znear = kv.Value.NearPlane.Value; } if (kv.Value.FarPlane != null) { obj.Camera.Zfar = kv.Value.FarPlane.Value; } } else if (kv.Value.Type == EntityTypes.Marker) { obj.Object = new GameObject(); obj.Object.Name = "Marker"; obj.Object.Nickname = ""; } else if (kv.Value.Type == EntityTypes.Deformable) { obj.Object = new GameObject(); gameData.GetCostume(template, out DfmFile body, out DfmFile head, out DfmFile leftHand, out DfmFile rightHand); var skel = new DfmSkeletonManager(body, head, leftHand, rightHand); obj.Object.RenderComponent = new CharacterRenderer(skel); var anmComponent = new AnimationComponent(obj.Object, gameData.GetCharacterAnimations()); obj.Object.AnimationComponent = anmComponent; obj.Object.Components.Add(anmComponent); } else if (kv.Value.Type == EntityTypes.Sound) { obj.Sound = new ThnSound(kv.Value.Template, game.GetService <SoundManager>(), kv.Value.AudioProps, obj); obj.Sound.Spatial = (kv.Value.ObjectFlags & ThnObjectFlags.SoundSpatial) == ThnObjectFlags.SoundSpatial; } if (obj.Object != null) { Vector3 transform = kv.Value.Position ?? Vector3.Zero; obj.Object.Transform = (kv.Value.RotationMatrix ?? Matrix4x4.Identity) * Matrix4x4.CreateTranslation(transform); World.Objects.Add(obj.Object); } obj.Entity = kv.Value; Objects[kv.Key] = obj; } }
void InitWithDrawable(IDrawable drawable, ResourceManager res, bool staticpos) { Resources = res; dr = drawable; Shape collisionShape = null; bool isCmp = false; if (dr is SphFile) { var radius = ((SphFile)dr).Radius; collisionShape = new SphereShape(radius); } else if (dr is ModelFile) { var mdl = dr as ModelFile; var path = Path.ChangeExtension(mdl.Path, "sur"); if (File.Exists(path)) { SurFile sur = res.GetSur(path); var shs = new List <CompoundSurShape.TransformedShape>(); foreach (var s in sur.GetShape(0)) { shs.Add(new CompoundSurShape.TransformedShape(s, Matrix3.Identity, Vector3.Zero)); } collisionShape = new CompoundSurShape(shs); } } else if (dr is CmpFile) { isCmp = true; var cmp = dr as CmpFile; CmpParts = new List <Part>(); CmpConstructs = cmp.Constructs.CloneAll(); foreach (var part in cmp.Parts.Values) { CmpParts.Add(part.Clone(CmpConstructs)); } if (cmp.Animation != null) { AnimationComponent = new AnimationComponent(this, cmp.Animation); Components.Add(AnimationComponent); } var path = Path.ChangeExtension(cmp.Path, "sur"); if (File.Exists(path)) { SurFile sur = res.GetSur(path); var shapes = new List <CompoundSurShape.TransformedShape>(); foreach (var part in CmpParts) { var crc = CrcTool.FLModelCrc(part.ObjectName); if (!sur.HasShape(crc)) { FLLog.Warning("Sur", "No hitbox for " + part.ObjectName); continue; } var colshape = sur.GetShape(crc); if (part.Construct == null) { foreach (var s in colshape) { shapes.Add(new CompoundSurShape.TransformedShape(s, Matrix3.Identity, Vector3.Zero)); } } else { var tr = part.Construct.Transform; var pos = tr.ExtractTranslation(); var q = tr.ExtractRotation(true); var rot = Matrix3.CreateFromQuaternion(q); foreach (var s in colshape) { shapes.Add(new CompoundSurShape.TransformedShape(s, rot, pos) { Tag = part.Construct }); } } } collisionShape = new CompoundSurShape(shapes); } } if (collisionShape != null) { PhysicsComponent = new RigidBody(collisionShape); PhysicsComponent.Tag = this; PhysicsComponent.IsStatic = staticpos; if (staticpos) { PhysicsComponent.Material.Restitution = 1; } } PopulateHardpoints(dr); if (isCmp) { RenderComponent = new ModelRenderer(CmpParts, (dr as CmpFile)); } else { RenderComponent = new ModelRenderer(dr); } }