/// <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 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); }
/// <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); } }
protected void SetupEntity(SceneManager sceneMgr, ModelBlock block) { // make a new one if it isn't created yet, clone an existing one string meshName = block.GetStringProperty("mesh", null); if (sceneMgr.HasEntity(meshName)) { Entity = sceneMgr.GetEntity(meshName).Clone(meshName + ID); } else { Entity = sceneMgr.CreateEntity(meshName, meshName); } if (block.FloatTokens.ContainsKey("renderingdistance")) Entity.RenderingDistance = block.GetFloatProperty("RenderingDistance", null); // material name string materialName = block.GetStringProperty("material", string.Empty); if (!string.IsNullOrWhiteSpace(materialName)) Entity.SetMaterialName(materialName); // some other properties ThingEnum shad = block.GetEnumProperty("CastsShadows", ThingEnum.Some); if (Options.ShadowDetail == ShadowDetailOption.Many) Entity.CastShadows = (shad == ThingEnum.Many || shad == ThingEnum.Some); else if (Options.ShadowDetail == ShadowDetailOption.Some) Entity.CastShadows = (shad == ThingEnum.Some); else Entity.CastShadows = false; }
/// <summary> /// Only does simple animations for now /// </summary> protected void SetupAnimation(ModelBlock block) { if (block.GetBoolProperty("animated", false)) { int numAnims = Entity.AllAnimationStates.GetAnimationStateIterator().Count(); if (numAnims == 1) { AnimationState = Entity.GetAnimationState(block.GetStringProperty("AnimationName", null)); AnimationState.Loop = block.GetBoolProperty("AnimationLooping", true); AnimationState.Enabled = true; LKernel.GetG<AnimationManager>().Add(AnimationState); } else if (numAnims > 1) { AnimationBlender = new AnimationBlender(Entity); AnimationBlender.Init(block.GetStringProperty("AnimationName", null), block.GetBoolProperty("AnimationLooping", true)); LKernel.GetG<AnimationManager>().Add(AnimationBlender); } } }
/// <summary> /// Model blocks /// </summary> void ParseModel(ThingDefinition thingDef, RuleInstance block) { ModelBlock modelBlock = new ModelBlock(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(modelBlock, rule.Children[0] as RuleInstance); } thingDef.ModelBlocks.Add(modelBlock); }