public ItemBox(ThingBlock block, ThingDefinition def, string _itemName) : base(block, def) { LKernel.GetG<CollisionReporter>().AddEvent(PonykartCollisionGroups.Karts, PonykartCollisionGroups.Default, OnCol); //contents = LKernel.GetG<ItemManager>().SpawnItem(null, _itemName); itemName = _itemName; }
/// <summary> /// Adds all of the geometry used by a model component to the static geometry. /// This is used by the ModelComponent. /// </summary> public void Add(ModelComponent mc, ThingBlock template, ModelBlock block, ThingDefinition def) { // if the model detail option is low and this model wants imposters, don't even make any static geometry of it if (Options.ModelDetail == ModelDetailOption.Low) { if (def.GetBoolProperty("Imposters", false)) return; } var sceneMgr = LKernel.GetG<SceneManager>(); string meshName = block.GetStringProperty("mesh", null); // map region goes first string sgeomName = template.GetStringProperty("MapRegion", "(Default)"); // static group can override map region sgeomName = block.GetStringProperty("StaticGroup", sgeomName); Entity ent; // get our entity if it already exists if (!ents.TryGetValue(meshName, out ent)) { // getting the entity was not successful, so we have to create it ent = sceneMgr.CreateEntity(meshName + mc.ID, meshName); string material; if (block.StringTokens.TryGetValue("material", out material)) ent.SetMaterialName(material); ents.Add(meshName, ent); } Vector3 pos; // two ways to get the position // inherit it from the lthing, the default (if we were using nodes, this would be the default too) if (block.GetBoolProperty("InheritOrientation", true)) { pos = (mc.Owner.SpawnOrientation * block.GetVectorProperty("position", Vector3.ZERO)) + template.VectorTokens["position"]; } // or we can choose not to inherit it for whatever reason else { pos = block.GetVectorProperty("position", Vector3.ZERO) + template.VectorTokens["position"]; } Quaternion orient = block.GetQuatProperty("orientation", Quaternion.IDENTITY) * template.GetQuatProperty("orientation", Quaternion.IDENTITY); Vector3 sca = block.GetVectorProperty("scale", Vector3.UNIT_SCALE); StaticGeometry sg; if (!sgeoms.TryGetValue(sgeomName, out sg)) { sg = LKernel.GetG<SceneManager>().CreateStaticGeometry(sgeomName); sg.RegionDimensions = regionDimensions; sg.RenderingDistance = 300 / 5f; sgeoms.Add(sgeomName, sg); } sg.AddEntity(ent, pos, orient, sca); }
public TwiCutlass(ThingBlock block, ThingDefinition def) : base(block, def) { // sounds soundMain = LKernel.GetG<SoundMain>(); idleSound = SoundComponents[0].Sound; fullSound = SoundComponents[1].Sound; // convert from linear velocity to KPH topSpeedKmHour = DefaultMaxSpeed * 3.6f; LKernel.GetG<Root>().FrameStarted += FrameStarted; }
public void Add(ModelComponent mc, ThingBlock template, ModelBlock block, ThingDefinition def) { // if the model detail option is low and this model wants imposters, don't even make any instanced geometry of it if (Options.ModelDetail == ModelDetailOption.Low) { if (def.GetBoolProperty("Imposters", false)) return; } var sceneMgr = LKernel.GetG<SceneManager>(); string meshName = block.GetStringProperty("mesh", null); string mapRegion = template.GetStringProperty("MapRegion", string.Empty); string key = mapRegion + meshName; // create our entity if it doesn't exist if (!ents.ContainsKey(key)) { Entity ent = sceneMgr.CreateEntity(mc.Name + mc.ID, meshName); ent.SetMaterialName(block.GetStringProperty("Material", string.Empty)); // then add it to our dictionary ents.Add(key, ent); } // get our transforms Vector3 pos; // two ways to get the position // inherit it from the lthing, the default (if we were using nodes, this would be the default too) if (block.GetBoolProperty("InheritOrientation", true)) { pos = (mc.Owner.SpawnOrientation * block.GetVectorProperty("position", Vector3.ZERO)) + template.VectorTokens["position"]; } // or we can choose not to inherit it for whatever reason else { pos = block.GetVectorProperty("position", Vector3.ZERO) + template.VectorTokens["position"]; } Quaternion orient = block.GetQuatProperty("orientation", Quaternion.IDENTITY) * template.GetQuatProperty("orientation", Quaternion.IDENTITY); Vector3 sca = block.GetVectorProperty("scale", Vector3.UNIT_SCALE); // put them in one class Transform trans = new Transform { Position = pos, Orientation = orient, Scale = sca, }; // if the transforms dictionary doesn't contain the mesh yet, add a new one if (!transforms.ContainsKey(key)) { transforms.Add(key, new List<Transform>()); } // then put our transform into the dictionary transforms[key].Add(trans); }
public Kart(ThingBlock block, ThingDefinition def) : base(block, def) { DefaultMaxSpeed = MaxSpeed = def.GetFloatProperty("maxspeed", 180f); MaxReverseSpeed = def.GetFloatProperty("maxreversespeed", 4f); MaxSpeedSquared = MaxSpeed * MaxSpeed; MaxReverseSpeedSquared = MaxReverseSpeed * MaxReverseSpeed; IsInAir = false; FrontDriftAngle = new Degree(def.GetFloatProperty("FrontDriftAngle", 46)).ValueRadians; BackDriftAngle = new Degree(def.GetFloatProperty("BackDriftAngle", 55)).ValueRadians; DriftTransitionAngle = new Degree(def.GetFloatProperty("DriftTransitionAngle", 40)); }
public Derpy(ThingBlock block, ThingDefinition def) : base(block, def) { bodyComponent = ModelComponents[0]; flagComponent = ModelComponents[1]; startLightComponent = ModelComponents[2]; bodyFacing = new Euler(0, 0, 0); neckFacing = new Euler(0, 0, 0); Skeleton skeleton = bodyComponent.Entity.Skeleton; skeleton.BlendMode = SkeletonAnimationBlendMode.ANIMBLEND_CUMULATIVE; blinkState = bodyComponent.Entity.GetAnimationState("Blink2"); blinkState.Enabled = true; blinkState.Loop = true; blinkState.Weight = 1f; blinkState.AddTime(ID); neckBone = skeleton.GetBone("Neck"); neckBone.SetManuallyControlled(true); foreach (var state in bodyComponent.Entity.AllAnimationStates.GetAnimationStateIterator()) { // don't add a blend mask to the blink state because we'll make a different one for it if (state == blinkState) continue; state.CreateBlendMask(skeleton.NumBones); state.SetBlendMaskEntry(neckBone.Handle, 0f); } neckBone.InheritOrientation = false; blinkState.CreateBlendMask(skeleton.NumBones, 0f); ushort handle = skeleton.GetBone("EyeBrowTop.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowTop.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); LKernel.GetG<AnimationManager>().Add(blinkState); interpNode = LKernel.GetG<SceneManager>().RootSceneNode.CreateChildSceneNode("DerpyInterpNode" + ID, Vector3.ZERO); anim = DerpyAnimation.Hover1; }
/// <summary> /// Constructor woo! /// </summary> /// <param name="template"> /// This is the part that comes from the .muffin file (if we used one) or somewhere else in the program. It has basic information needed for constructing this /// lthing, such as where it should be in the world, its rotation, etc. /// </param> /// <param name="def"> /// This is the part that comes from the .thing file. It's got all of the properties that specifies what this lthing is, what it should look like, and /// information about all of its components. /// </param> public LThing(ThingBlock template, ThingDefinition def) { ID = IDs.Incremental; Name = template.ThingName; // get our three basic transforms SpawnPosition = template.GetVectorProperty("position", null); SpawnOrientation = template.GetQuatProperty("orientation", Quaternion.IDENTITY); if (SpawnOrientation == Quaternion.IDENTITY) SpawnOrientation = template.GetVectorProperty("rotation", Vector3.ZERO).DegreeVectorToGlobalQuaternion(); SpawnScale = template.GetVectorProperty("scale", Vector3.UNIT_SCALE); // and start setting up this thing! PreSetup(template, def); SetupMogre(template, def); InitialiseComponents(template, def); RootNode.Position = SpawnPosition; RootNode.Orientation = SpawnOrientation; // only scale up the root node if it doesn't have any physics things attached - bullet really does not like scaling. // Need a few variations of identical objects with different scales? Gonna have to make different .things for them. // Though it might be easier to just have one general .thing for them, and all it does is run a script that randomly // gets one of the others. if (ShapeComponents == null) RootNode.Scale(SpawnScale); RootNode.SetInitialState(); PostInitialiseComponents(template, def); SetupPhysics(template, def); // get our script token and run it, if it has one and if this thing was created on the fly instead // of through a .muffin file string script; if (def.StringTokens.TryGetValue("script", out script)) { this.Script = script; RunScript(); } DisposeIfStaticOrInstanced(def); }
public ThingDefinition Parse(string nameOfThing) { PrepareFileList(); string fileContents = string.Empty; // make the file path // this just searches for "media/things/foo.thing" string filePath; // this searches subfolders for .things if (!fileList.TryGetValue(nameOfThing, out filePath)) { throw new FileNotFoundException(nameOfThing + ".thing does not exist!", nameOfThing); } LogManager.Singleton.LogMessage("[ThingImporter] Importing and parsing thing: " + filePath); Debug.WriteLine("[ThingImporter] Importing and parsing thing: " + filePath); // read stuff using (var fileStream = File.Open(filePath, FileMode.Open)) { using (var reader = new StreamReader(fileStream)) { // for each line in the file while (!reader.EndOfStream) { fileContents += reader.ReadLine() + Environment.NewLine; } reader.Close(); } fileStream.Close(); } Parser p = new Parser(); root = p.Parse(fileContents); ThingDefinition thingDef = new ThingDefinition(nameOfThing); Parse(thingDef); thingDef.Finish(); return thingDef; }
/// <summary> /// Creates a CollisionShape from the ShapeComponents of the given thing. If the shape already exists, we'll just return that instead. /// </summary> public CollisionShape CreateAndRegisterShape(LThing thing, ThingDefinition def) { CollisionShape shape; if (!Shapes.TryGetValue(thing.Name, out shape)) { // create the shape bool forceCompound = def.GetBoolProperty("forcecompound", false); // if we only have one shape we don't have to do as much if (thing.ShapeComponents.Count == 1) { // force us to use a compound shape? if (forceCompound) { CompoundShape comp = new CompoundShape(); comp.AddChildShape(thing.ShapeComponents[0].Transform, CreateShapeForComponent(thing.ShapeComponents[0])); shape = comp; } // one component, no compound is the easiest else { shape = CreateShapeForComponent(thing.ShapeComponents[0]); } } // otherwise, make all of our shapes and stick them in a compound shape else { CompoundShape comp = new CompoundShape(); foreach (ShapeComponent component in thing.ShapeComponents) { comp.AddChildShape(component.Transform, CreateShapeForComponent(component)); } shape = comp; } // then put the shape in our dictionary Shapes.Add(thing.Name, shape); } return shape; }
public DashJavelin(ThingBlock block, ThingDefinition def) : base(block, def) { ModelComponent chassis = ModelComponents[0]; // first get rid of the existing animation blender it creates automatically LKernel.GetG<AnimationManager>().Remove(chassis.AnimationBlender); chassis.AnimationBlender = null; Entity chassisEnt = chassis.Entity; // get our two animation states jetMax = chassisEnt.GetAnimationState("JetMax"); jetMax.Enabled = true; jetMax.Weight = 0f; jetMin = chassisEnt.GetAnimationState("JetMin"); jetMin.Enabled = true; jetMin.Weight = 1f; // we want the two animations to blend together, not add to each other chassisEnt.Skeleton.BlendMode = SkeletonAnimationBlendMode.ANIMBLEND_AVERAGE; jetRibbon = RibbonComponents[0].Ribbon; // sounds soundMain = LKernel.GetG<SoundMain>(); idleSound = SoundComponents[0].Sound; fullSound = SoundComponents[1].Sound; revDownSound = soundMain.GetSource("RD_Kart_Rev_Down.ogg"); revUpSound = soundMain.GetSource("RD_Kart_Rev_Up.ogg"); // convert from linear velocity to KPH topSpeedKmHour = DefaultMaxSpeed * 3.6f; idleState = true; LKernel.GetG<Root>().FrameStarted += FrameStarted; }
/// <summary> /// Make our components /// </summary> protected virtual void InitialiseComponents(ThingBlock template, ThingDefinition def) { // ogre stuff if (def.ModelBlocks.Count > 0) { ModelComponents = new List<ModelComponent>(def.ModelBlocks.Count); foreach (var mblock in def.ModelBlocks) ModelComponents.Add(new ModelComponent(this, template, mblock, def)); } // bullet stuff if (def.ShapeBlocks.Count > 0) { ShapeComponents = new List<ShapeComponent>(def.ShapeBlocks.Count); foreach (var sblock in def.ShapeBlocks) ShapeComponents.Add(new ShapeComponent(this, sblock)); } // ribbons if (def.RibbonBlocks.Count > 0) { RibbonComponents = new List<RibbonComponent>(def.RibbonBlocks.Count); foreach (var rblock in def.RibbonBlocks) RibbonComponents.Add(new RibbonComponent(this, template, rblock)); } // billboard sets if (def.BillboardSetBlocks.Count > 0) { BillboardSetComponents = new List<BillboardSetComponent>(def.BillboardSetBlocks.Count); foreach (var bblock in def.BillboardSetBlocks) BillboardSetComponents.Add(new BillboardSetComponent(this, template, bblock)); } // sounds if (def.SoundBlocks.Count > 0) { SoundComponents = new List<SoundComponent>(def.SoundBlocks.Count); foreach (var sblock in def.SoundBlocks) SoundComponents.Add(new SoundComponent(this, template, sblock)); } }
/// <summary> /// BillboardSet blocks /// </summary> void ParseBillboardSet(ThingDefinition thingDef, RuleInstance block) { BillboardSetBlock billboardSetBlock = new BillboardSetBlock(thingDef); for (int a = 2; a < block.Children.Length - 1; a++) { RuleInstance rule = block.Children[a] as RuleInstance; if (rule.Type == NodeType.Rule_Property) ParseProperty(billboardSetBlock, rule.Children[0] as RuleInstance); else if (rule.Type == NodeType.Rule_Billboard) ParseBillboard(billboardSetBlock, rule); } thingDef.BillboardSetBlocks.Add(billboardSetBlock); }
/// <summary> /// Sound blocks /// </summary> void ParseSound(ThingDefinition thingDef, RuleInstance block) { SoundBlock soundBlock = new SoundBlock(thingDef); for (int a = 2; a < block.Children.Length - 1; a++) { RuleInstance rule = block.Children[a] as RuleInstance; if (rule.Type == NodeType.Rule_Property) ParseProperty(soundBlock, rule.Children[0] as RuleInstance); } thingDef.SoundBlocks.Add(soundBlock); }
/// <summary> /// Creates the body and makes it static/kinematic if specified. /// </summary> private void CreateBody(ThingDefinition def) { Body = new RigidBody(Info); // stick on our flags ThingEnum te = def.GetEnumProperty("physics", null); if (te.HasFlag(ThingEnum.Static)) Body.CollisionFlags |= CollisionFlags.StaticObject; else if (te.HasFlag(ThingEnum.Kinematic)) Body.CollisionFlags |= CollisionFlags.KinematicObject; if (def.GetBoolProperty("CollisionEvents", false)) Body.CollisionFlags |= CollisionFlags.CustomMaterialCallback; if (def.GetBoolProperty("DisableVisualization", false)) Body.CollisionFlags |= CollisionFlags.DisableVisualizeObject; Body.WorldTransform = Info.StartWorldTransform; LKernel.GetG<PhysicsMain>().World.AddRigidBody(Body, CollisionGroup, CollidesWith); if (def.GetBoolProperty("Deactivated", false)) Body.ForceActivationState(ActivationState.WantsDeactivation); }
/// <summary> /// Parses right from the root /// </summary> void Parse(ThingDefinition thingDef) { for (int a = 0; a < root.Children.Length; a++) { Node prop = root.Children[a]; switch (prop.Type) { case NodeType.Rule_Property: ParseProperty(thingDef, (prop as RuleInstance).Children[0] as RuleInstance); break; case NodeType.Rule_Shape: ParseShape(thingDef, prop as RuleInstance); break; case NodeType.Rule_Model: ParseModel(thingDef, prop as RuleInstance); break; case NodeType.Rule_Ribbon: ParseRibbon(thingDef, prop as RuleInstance); break; case NodeType.Rule_BillboardSet: ParseBillboardSet(thingDef, prop as RuleInstance); break; case NodeType.Rule_Sound: ParseSound(thingDef, prop as RuleInstance); break; } } }
protected virtual void PostInitialiseComponents(ThingBlock template, ThingDefinition def) { }
/// <summary> /// Override this if you want to do more to the rigid body /// </summary> protected virtual void PostCreateBody(ThingDefinition td) { }
/// <summary> /// Make some nodes for us to attach wheel particles to /// </summary> protected override void PostInitialiseComponents(ThingBlock template, ThingDefinition def) { Vector3 frontleft = def.GetVectorProperty("FrontLeftWheelPosition", null); Vector3 frontright = def.GetVectorProperty("FrontRightWheelPosition", null); Vector3 backleft = def.GetVectorProperty("BackLeftWheelPosition", null); Vector3 backright = def.GetVectorProperty("BackRightWheelPosition", null); LeftParticleNode = RootNode.CreateChildSceneNode(frontleft.MidPoint(backleft)); RightParticleNode = RootNode.CreateChildSceneNode(frontright.MidPoint(backright)); }
/// <summary> /// If this is a static/instanced thing with no ribbons, billboards, or sounds, we can clean up a whole bunch of stuff /// to make it faster for ogre. /// </summary> private void DisposeIfStaticOrInstanced(ThingDefinition def) { if (def.GetBoolProperty("Static", false) || def.GetBoolProperty("Instanced", false)) { if (IsDisposed) return; var sceneMgr = LKernel.GetG<SceneManager>(); // this bool is to check we only fully dispose lthings if ALL of their model components are static/instanced bool removedAllModelComponents = true; // dispose of all of the model components if (ModelComponents != null) { foreach (ModelComponent mc in ModelComponents) { if (mc.Entity == null) { mc.Dispose(); } else { removedAllModelComponents = false; } } } // if we have no ribbons, billboards, or sounds, we can get rid of the root node if (removedAllModelComponents && RibbonComponents == null && BillboardSetComponents == null && SoundComponents == null) { // if we have no shapes, we can get rid of everything if (ShapeComponents == null/*.Count == 0*/) { Dispose(true); } // but otherwise we can still get rid of the root scene node else { sceneMgr.DestroySceneNode(RootNode); RootNode.Dispose(); RootNode = null; } } } }
/// <summary> /// Set up all of the stuff needed before we create our body /// </summary> private void SetUpBodyInfo(ThingDefinition def) { // set up our collision shapes CollisionShape shape = LKernel.GetG<CollisionShapeManager>().CreateAndRegisterShape(this, def); // get the physics type and set up the mass of the body ThingEnum physicsType = def.GetEnumProperty("physics", null); float mass = physicsType.HasFlag(ThingEnum.Static) ? 0 : def.GetFloatProperty("mass", 1); // create our construction info thingy Vector3 inertia; shape.CalculateLocalInertia(mass, out inertia); // if it's static and doesn't have a sound, we don't need a mogre motion state because we'll be disposing of the root node afterwards if (def.GetBoolProperty("Static", false) && SoundComponents == null) MotionState = new DefaultMotionState(); else MotionState = InitializationMotionState; Info = new RigidBodyConstructionInfo(mass, MotionState, shape, inertia); // physics material stuff from a .physmat file string physmat = def.GetStringProperty("PhysicsMaterial", "Default"); LKernel.GetG<PhysicsMaterialFactory>().ApplyMaterial(Info, physmat); // we can override some of them in the .thing file if (def.FloatTokens.ContainsKey("bounciness")) Info.Restitution = def.GetFloatProperty("bounciness", PhysicsMaterial.DEFAULT_BOUNCINESS); if (def.FloatTokens.ContainsKey("friction")) Info.Friction = def.GetFloatProperty("friction", PhysicsMaterial.DEFAULT_FRICTION); if (def.FloatTokens.ContainsKey("angulardamping")) Info.AngularDamping = def.GetFloatProperty("angulardamping", PhysicsMaterial.DEFAULT_ANGULAR_DAMPING); if (def.FloatTokens.ContainsKey("lineardamping")) Info.LinearDamping = def.GetFloatProperty("lineardamping", PhysicsMaterial.DEFAULT_LINEAR_DAMPING); // choose which group to use for a default ThingEnum defaultGroup; if (physicsType.HasFlag(ThingEnum.Dynamic)) defaultGroup = ThingEnum.Default; else if (physicsType.HasFlag(ThingEnum.Static)) defaultGroup = ThingEnum.Environment; else // kinematic defaultGroup = ThingEnum.Default; // collision group ThingEnum collisionGroup = def.GetEnumProperty("CollisionGroup", defaultGroup); PonykartCollisionGroups pcg; if (!Enum.TryParse<PonykartCollisionGroups>(collisionGroup + String.Empty, true, out pcg)) throw new FormatException("Invalid collision group!"); CollisionGroup = pcg; // collides-with group ThingEnum collidesWith = def.GetEnumProperty("CollidesWith", defaultGroup); PonykartCollidesWithGroups pcwg; if (!Enum.TryParse<PonykartCollidesWithGroups>(collidesWith + String.Empty, true, out pcwg)) throw new FormatException("Invalid collides-with group!"); CollidesWith = pcwg; // update the transforms Matrix4 transform = new Matrix4(); transform.MakeTransform(SpawnPosition, SpawnScale, SpawnOrientation); Info.StartWorldTransform = transform; MotionState.WorldTransform = transform; }
public Lyra(ThingBlock block, ThingDefinition def) : base(block, def) { foreach (ModelComponent mc in ModelComponents) { if (mc.Name.EndsWith("Body")) bodyComponent = mc; else if (mc.Name.EndsWith("Mane")) maneComponent = mc; else if (mc.Name.EndsWith("Tail")) tailComponent = mc; } // make sure our animations add their weights and don't just average out. The AnimationBlender already handles averaging between two anims. Skeleton skeleton = bodyComponent.Entity.Skeleton; skeleton.BlendMode = SkeletonAnimationBlendMode.ANIMBLEND_CUMULATIVE; // set up the blink animation state with some stuff blinkState = bodyComponent.Entity.GetAnimationState("Blink2"); blinkState.Enabled = true; blinkState.Loop = true; blinkState.Weight = 1; blinkState.AddTime(ID); // set up all of the animation states to not use the neck bone neckbone = skeleton.GetBone("Neck"); neckbone.SetManuallyControlled(true); foreach (var state in bodyComponent.Entity.AllAnimationStates.GetAnimationStateIterator()) { // don't add a blend mask to the blink state because we'll make a different one for it if (state == blinkState) continue; state.CreateBlendMask(skeleton.NumBones); state.SetBlendMaskEntry(neckbone.Handle, 0f); } neckbone.InheritOrientation = false; neckFacing = new Euler(0, 0, 0); // set up a blend mask so only the eyebrow bones have any effect on the blink animation blinkState.CreateBlendMask(skeleton.NumBones, 0f); ushort handle = skeleton.GetBone("EyeBrowTop.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowTop.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); // add the blink state to the animation manager so it has time added to it LKernel.GetG<AnimationManager>().Add(blinkState); // set up some timers to handle animation changing random = new Random(IDs.Random); animTimer = new System.Threading.Timer(new TimerCallback(AnimTimerTick), null, random.Next(ANIMATION_TIMESPAN_MINIMUM, ANIMATION_TIMESPAN_MAXIMUM), Timeout.Infinite); // add a bit of time to things so the animations aren't all synced at the beginning float rand = (float) random.NextDouble(); bodyComponent.AnimationBlender.AddTime(rand); tailComponent.AnimationState.AddTime(rand); followKart = LKernel.GetG<PlayerManager>().MainPlayer.Kart; LKernel.GetG<Root>().FrameStarted += FrameStarted; }
/// <summary> /// Use this method if you need some more stuff to happen before the constructor starts setting everything up. /// For example if you need to get more things out of the ThingTemplate, you can use this for that. /// </summary> protected virtual void PreSetup(ThingBlock template, ThingDefinition def) { }
private void SetupPhysics(ThingBlock template, ThingDefinition def) { // if we have no shape components then we don't set up physics if (ShapeComponents == null) return; PreSetUpBodyInfo(def); SetUpBodyInfo(def); PostSetUpBodyInfo(def); CreateBody(def); PostCreateBody(def); SetBodyUserObject(); }
/// <summary> /// Sets up mogre stuff, like our root scene node /// </summary> private void SetupMogre(ThingBlock template, ThingDefinition def) { var sceneMgr = LKernel.GetG<SceneManager>(); // create our root node // need to check for map regions string mapRegion = template.GetStringProperty("MapRegion", string.Empty); if (string.IsNullOrEmpty(mapRegion)) { // no map region, continue on as normal this.RootNode = sceneMgr.RootSceneNode.CreateChildSceneNode(Name + ID); } else { string mapRegionNodeName = mapRegion + "Node"; // there is a map region, make our root node a child of a node with the region's name // first check to see if that node exists already if (sceneMgr.HasSceneNode(mapRegionNodeName)) { // if it does, just attach our node to it this.RootNode = sceneMgr.GetSceneNode(mapRegionNodeName).CreateChildSceneNode(Name + ID); } else { // if it doesn't, create it first, then attach our node to it SceneNode newSceneNode = sceneMgr.RootSceneNode.CreateChildSceneNode(mapRegionNodeName); this.RootNode = newSceneNode.CreateChildSceneNode(Name + ID); } } }
/// <summary> /// After we create our RigidBody, we turn it into a vehicle /// </summary> protected override void PostCreateBody(ThingDefinition def) { kartMotionState = MotionState as KartMotionState; Body.CcdMotionThreshold = 0.001f; Body.CcdSweptSphereRadius = 0.04f; Raycaster = new DefaultVehicleRaycaster(LKernel.GetG<PhysicsMain>().World); Tuning = new RaycastVehicle.VehicleTuning(); _vehicle = new RaycastVehicle(Tuning, Body, Raycaster); _vehicle.SetCoordinateSystem(0, 1, 2); // I have no idea what this does... I'm assuming something to do with a rotation matrix? LKernel.GetG<PhysicsMain>().World.AddAction(_vehicle); var wheelFac = LKernel.GetG<WheelFactory>(); string frontWheelName = def.GetStringProperty("FrontWheel", null); string backWheelName = def.GetStringProperty("BackWheel", null); WheelFL = wheelFac.CreateWheel(frontWheelName, WheelID.FrontLeft, this, def.GetVectorProperty("FrontLeftWheelPosition", null), def.GetStringProperty("FrontLeftWheelMesh", null)); WheelFR = wheelFac.CreateWheel(frontWheelName, WheelID.FrontRight, this, def.GetVectorProperty("FrontRightWheelPosition", null), def.GetStringProperty("FrontRightWheelMesh", null)); WheelBL = wheelFac.CreateWheel(backWheelName, WheelID.BackLeft, this, def.GetVectorProperty("BackLeftWheelPosition", null), def.GetStringProperty("BackLeftWheelMesh", null)); WheelBR = wheelFac.CreateWheel(backWheelName, WheelID.BackRight, this, def.GetVectorProperty("BackRightWheelPosition", null), def.GetStringProperty("BackRightWheelMesh", null)); LeftParticleNode.Position -= new Vector3(0, WheelBL.DefaultRadius * 0.7f, 0); RightParticleNode.Position -= new Vector3(0, WheelBR.DefaultRadius * 0.7f, 0); Body.LinearVelocity = new Vector3(0, 1, 0); PhysicsMain.FinaliseBeforeSimulation += FinaliseBeforeSimulation; RaceCountdown.OnCountdown += OnCountdown; }
public BackgroundPony(string bgPonyName, ThingBlock block, ThingDefinition def) : base(block, def) { AnimPose = Pose.Standing; if (bgPonyName == null) nameOfPonyCharacter = loader.GetRandomLine(); else nameOfPonyCharacter = bgPonyName; // get a line to parse string _line; if (!loader.BackgroundPonyDict.TryGetValue(nameOfPonyCharacter, out _line)) { // if the line doesn't exist, make a random one _line = loader.GetRandomLine(); Launch.Log("[WARNING] The specified background pony (" + nameOfPonyCharacter + ") does not exist, using random one instead..."); } // split up the data string[] _data = _line.Split(' '); // get our hairstyle ID number int hairstyleID = int.Parse(_data[1], culture); // set the pony type if (_data[2] == "pegasus") PonyType = Type.Pegasus; else if (_data[2] == "flyingpegasus") PonyType = Type.FlyingPegasus; else if (_data[2] == "earth") PonyType = Type.Earth; else if (_data[2] == "unicorn") PonyType = Type.Unicorn; // create nodes and stuff var sceneMgr = LKernel.Get<SceneManager>(); #region creation bodyEnt = sceneMgr.CreateEntity("BgPonyBody.mesh"); RootNode.AttachObject(bodyEnt); eyesEnt = sceneMgr.CreateEntity("BgPonyEyes.mesh"); if (PonyType == Type.Unicorn) hornEnt = sceneMgr.CreateEntity("BgPonyHorn.mesh"); else if (PonyType == Type.FlyingPegasus) wingsEnt = sceneMgr.CreateEntity("BgPonyWings.mesh"); else if (PonyType == Type.Pegasus) foldedWingsEnt = sceneMgr.CreateEntity("BgPonyWingsFolded.mesh"); // create hair hairEnt = sceneMgr.CreateEntity("BgPonyHair" + hairstyleID + ".mesh"); maneEnt = sceneMgr.CreateEntity("BgPonyMane" + hairstyleID + ".mesh"); tailEnt = sceneMgr.CreateEntity("BgPonyTail" + hairstyleID + ".mesh"); // attach stuff bodyEnt.AttachObjectToBone("Eyes", eyesEnt); bodyEnt.AttachObjectToBone("Hair", hairEnt); bodyEnt.AttachObjectToBone("Mane", maneEnt); bodyEnt.AttachObjectToBone("Tail", tailEnt); if (PonyType == Type.Unicorn) bodyEnt.AttachObjectToBone("Horn", hornEnt); else if (PonyType == Type.Pegasus) bodyEnt.AttachObjectToBone("Wings", foldedWingsEnt); else if (PonyType == Type.FlyingPegasus) bodyEnt.AttachObjectToBone("Wings", wingsEnt); #endregion #region setting up colors in materials // body colour { ColourValue bodyColour = new ColourValue(float.Parse(_data[3], culture), float.Parse(_data[4], culture), float.Parse(_data[5], culture)); ColourValue bodyAOColour = new ColourValue(float.Parse(_data[6], culture), float.Parse(_data[7], culture), float.Parse(_data[8], culture)); MaterialPtr bodyMat = SetBodyPartMaterialColours("BgPony", bodyColour, bodyAOColour); bodyMat.GetTechnique(0).GetPass(1).GetTextureUnitState(1).SetTextureName(_data[18].Substring(1, _data[18].Length - 2)); bodyEnt.SetMaterial(bodyMat); // extra body parts if (PonyType == Type.Unicorn) { bodyMat = SetBodyPartMaterialColours("BgPonyHorn", bodyColour, bodyAOColour); hornEnt.SetMaterial(bodyMat); } else if (PonyType == Type.Pegasus) { bodyMat = SetBodyPartMaterialColours("BgPonyWingsFolded", bodyColour, bodyAOColour); foldedWingsEnt.SetMaterial(bodyMat); } else if (PonyType == Type.FlyingPegasus) { bodyMat = SetBodyPartMaterialColours("BgPonyWings", bodyColour, bodyAOColour); wingsEnt.SetMaterial(bodyMat); } } // eye colours { ColourValue eyeColour1 = new ColourValue(float.Parse(_data[9], culture), float.Parse(_data[10], culture), float.Parse(_data[11], culture)); ColourValue eyeColour2 = new ColourValue(float.Parse(_data[12], culture), float.Parse(_data[13], culture), float.Parse(_data[14], culture)); ColourValue eyeHighlightColour = new ColourValue(float.Parse(_data[15], culture), float.Parse(_data[16], culture), float.Parse(_data[17], culture)); MaterialPtr originalMat = MaterialManager.Singleton.GetByName("BgPonyEyes"); MaterialPtr newMat = MaterialManager.Singleton.GetByName("BgPonyEyes" + nameOfPonyCharacter); if (newMat == null) { newMat = originalMat.Clone("BgPonyEyes" + nameOfPonyCharacter); var ps = newMat.GetTechnique(0).GetPass(0).GetFragmentProgramParameters(); ps.SetNamedConstant("TopIrisColour", eyeColour1); ps.SetNamedConstant("BottomIrisColour", eyeColour2); ps.SetNamedConstant("HighlightColour", eyeHighlightColour); newMat.GetTechnique(0).GetPass(0).SetFragmentProgramParameters(ps); } eyesEnt.SetMaterial(newMat); } // hair colours { ColourValue hairColour1 = new ColourValue(float.Parse(_data[20], culture), float.Parse(_data[21], culture), float.Parse(_data[22], culture)); ColourValue hairAOColour1 = new ColourValue(float.Parse(_data[23], culture), float.Parse(_data[24], culture), float.Parse(_data[25], culture)); // two hair colours if (bool.Parse(_data[19])) { ColourValue hairColour2 = new ColourValue(float.Parse(_data[26], culture), float.Parse(_data[27], culture), float.Parse(_data[28], culture)); ColourValue hairAOColour2 = new ColourValue(float.Parse(_data[29], culture), float.Parse(_data[30], culture), float.Parse(_data[31], culture)); MaterialPtr originalMat = MaterialManager.Singleton.GetByName("BgPonyHair_Double_" + hairstyleID); MaterialPtr newMat = MaterialManager.Singleton.GetByName("BgPonyHair_Double_" + hairstyleID + nameOfPonyCharacter); if (newMat == null) { newMat = originalMat.Clone("BgPonyHair_Double_" + hairstyleID + nameOfPonyCharacter); var ps = newMat.GetTechnique(0).GetPass(1).GetFragmentProgramParameters(); ps.SetNamedConstant("HairColour1", hairColour1); ps.SetNamedConstant("AOColour1", hairAOColour1); ps.SetNamedConstant("HairColour2", hairColour2); ps.SetNamedConstant("AOColour2", hairAOColour2); newMat.GetTechnique(0).GetPass(1).SetFragmentProgramParameters(ps); if (int.Parse(_data[32], culture) == 2) SetMaterialFragmentParameter(newMat, 0, "OutlineColour", hairAOColour2); else if (int.Parse(_data[32], culture) == 1) SetMaterialFragmentParameter(newMat, 0, "OutlineColour", hairAOColour1); } hairEnt.SetMaterial(newMat); maneEnt.SetMaterial(newMat); tailEnt.SetMaterial(newMat); } // one colour else { MaterialPtr originalMat = MaterialManager.Singleton.GetByName("BgPonyHair_Single_" + hairstyleID); MaterialPtr newMat = MaterialManager.Singleton.GetByName("BgPonyHair_Single_" + hairstyleID + nameOfPonyCharacter); if (newMat == null) { newMat = originalMat.Clone("BgPonyHair_Single_" + hairstyleID + nameOfPonyCharacter); var ps = newMat.GetTechnique(0).GetPass(1).GetFragmentProgramParameters(); ps.SetNamedConstant("HairColour", hairColour1); ps.SetNamedConstant("AOColour", hairAOColour1); newMat.GetTechnique(0).GetPass(1).SetFragmentProgramParameters(ps); SetMaterialFragmentParameter(newMat, 0, "OutlineColour", hairAOColour1); } hairEnt.SetMaterial(newMat); maneEnt.SetMaterial(newMat); tailEnt.SetMaterial(newMat); } } #endregion #region animation // make sure our animations add their weights and don't just average out. The AnimationBlender already handles averaging between two anims. Skeleton skeleton = bodyEnt.Skeleton; skeleton.BlendMode = SkeletonAnimationBlendMode.ANIMBLEND_CUMULATIVE; // set up the blink animation state with some stuff blinkState = bodyEnt.GetAnimationState("Blink2"); blinkState.Enabled = true; blinkState.Loop = true; blinkState.Weight = 1; blinkState.AddTime(ID); // set up all of the animation states to not use the neck bone neckbone = skeleton.GetBone("Neck"); neckbone.SetManuallyControlled(true); foreach (var state in bodyEnt.AllAnimationStates.GetAnimationStateIterator()) { // don't add a blend mask to the blink state because we'll make a different one for it if (state == blinkState) continue; state.CreateBlendMask(skeleton.NumBones); state.SetBlendMaskEntry(neckbone.Handle, 0f); } neckbone.InheritOrientation = false; neckFacing = new Euler(0, 0, 0); // set up a blend mask so only the eyebrow bones have any effect on the blink animation blinkState.CreateBlendMask(skeleton.NumBones, 0f); ushort handle = skeleton.GetBone("EyeBrowTop.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.R").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowTop.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); handle = skeleton.GetBone("EyeBrowBottom.L").Handle; blinkState.SetBlendMaskEntry(handle, 1f); // add the blink state to the animation manager so it has time added to it AnimationManager animMgr = LKernel.GetG<AnimationManager>(); animMgr.Add(blinkState); // set up other animated things bodyBlender = new AnimationBlender(bodyEnt); bodyBlender.Init("Stand1", true); animMgr.Add(bodyBlender); maneBlender = new AnimationBlender(maneEnt); maneBlender.Init("Stand1", true); animMgr.Add(maneBlender); tailBlender = new AnimationBlender(tailEnt); tailBlender.Init("Stand1", true); animMgr.Add(tailBlender); if (PonyType == Type.FlyingPegasus) { wingsBlender = new AnimationBlender(wingsEnt); wingsBlender.Init("Flap1", true); animMgr.Add(wingsBlender); } // set up some timers to handle animation changing animTimer = new Timer(new TimerCallback(AnimTimerTick), null, random.Next(ANIMATION_TIMESPAN_MINIMUM, ANIMATION_TIMESPAN_MAXIMUM), Timeout.Infinite); // add a bit of time to things so the animations aren't all synced at the beginning AddTimeToBodyManeAndTail(); #endregion followKart = LKernel.GetG<PlayerManager>().MainPlayer.Kart; LKernel.GetG<Root>().FrameStarted += FrameStarted; }
public Driver(ThingBlock block, ThingDefinition def) : base(block, def) { }
/// <summary> /// If you need anything before we set up the body info /// </summary> protected virtual void PreSetUpBodyInfo(ThingDefinition def) { }
/// <summary> /// Creates a model component for a Thing. /// </summary> /// <param name="lthing">The Thing this component is attached to</param> /// <param name="template">The template from the Thing</param> /// <param name="block">The block we're creating this component from</param> public ModelComponent(LThing lthing, ThingBlock template, ModelBlock block, ThingDefinition def) { ID = IDs.Incremental; Owner = lthing; var sceneMgr = LKernel.GetG<SceneManager>(); Name = block.GetStringProperty("name", template.ThingName); // set these up here because static/instanced geometry might need them // position SpawnPosition = block.GetVectorProperty("position", Vector3.ZERO); // orientation SpawnOrientation = block.GetQuatProperty("orientation", Quaternion.IDENTITY); // if orientation was not found, we fall back to rotation if (SpawnOrientation == Quaternion.IDENTITY) { Vector3 rot = block.GetVectorProperty("rotation", Vector3.ZERO); if (rot != Vector3.ZERO) SpawnOrientation = rot.DegreeVectorToGlobalQuaternion(); } // scale SpawnScale = block.GetVectorProperty("scale", Vector3.UNIT_SCALE); ThingEnum shad = block.GetEnumProperty("CastsShadows", ThingEnum.Some); // if we're static, set up the static geometry // don't set up static geometry if we want to cast shadows though, since static geometry doesn't work with shadows if ((block.GetBoolProperty("static", false) || def.GetBoolProperty("static", false)) // make static if we never want shadows && (shad == ThingEnum.None // or if the mesh has "some" shadows but we don't want any || (shad == ThingEnum.Some && Options.ShadowDetail == ShadowDetailOption.None) // or if the mesh has "many" shadows but we only want those with "some" || (shad == ThingEnum.Many && Options.ShadowDetail != ShadowDetailOption.Many))) { LKernel.GetG<StaticGeometryManager>().Add(this, template, block, def); Entity = null; } else if (block.GetBoolProperty("instanced", false) || def.GetBoolProperty("instanced", false)) { LKernel.GetG<InstancedGeometryManager>().Add(this, template, block, def); Entity = null; } // for attachments else if (block.GetBoolProperty("Attached", false)) { SetupEntity(sceneMgr, block); SetupAnimation(block); string boneName = block.GetStringProperty("AttachBone", null); int modelComponentID = (int) block.GetFloatProperty("AttachComponentID", null); Quaternion offsetQuat = block.GetQuatProperty("AttachOffsetOrientation", Quaternion.IDENTITY); Vector3 offsetVec = block.GetVectorProperty("AttachOffsetPosition", Vector3.ZERO); lthing.ModelComponents[modelComponentID].Entity.AttachObjectToBone(boneName, Entity, offsetQuat, offsetVec); } // otherwise continue as normal else { Node = lthing.RootNode.CreateChildSceneNode(Name + "Node" + ID); Node.Position = SpawnPosition; Node.Orientation = SpawnOrientation; Node.Scale(SpawnScale); Node.InheritScale = block.GetBoolProperty("InheritScale", true); Node.InheritOrientation = block.GetBoolProperty("InheritOrientation", true); Node.SetInitialState(); // make our entity SetupEntity(sceneMgr, block); SetupAnimation(block); // then attach it to the node! Node.AttachObject(Entity); } }
public BillboardSetBlock(ThingDefinition owner) { Owner = owner; SetUpDictionaries(); }