Leviathan  0.8.0.0
Leviathan game engine
Components.cpp
Go to the documentation of this file.
1 // ------------------------------------ //
2 #include "Components.h"
3 
4 #include "FileSystem.h"
5 #include "GameWorld.h"
6 #include "Generated/ComponentStates.h"
7 #include "Handlers/IDFactory.h"
10 #include "Physics/PhysicalWorld.h"
11 #include "Utility/Convert.h"
12 
13 #include "Engine.h"
14 #include "Rendering/Graphics.h"
15 
16 #include <limits>
17 using namespace Leviathan;
18 // ------------------------------------ //
19 // Position
20 DLLEXPORT void Position::ApplyState(const PositionState& state)
21 {
22  Members._Orientation = state._Orientation;
23  Members._Position = state._Position;
24  Marked = true;
25 }
26 
27 // ------------------ RenderNode ------------------ //
28 DLLEXPORT RenderNode::RenderNode(const Scene::pointer& scene) : Component(TYPE)
29 {
30  Marked = false;
31 
32  // Skip if no graphics
34  return;
35 
36  Node = scene->CreateSceneNode();
37 }
38 
39 DLLEXPORT void RenderNode::Release(const Scene::pointer& worldsscene)
40 {
41  if(Node)
42  worldsscene->DestroySceneNode(Node);
43  Node = nullptr;
44 }
45 // ------------------------------------ //
46 DLLEXPORT RenderNode::RenderNode(const Test::TestComponentCreation& test) : Component(TYPE)
47 {
48  Marked = false;
49  Node = nullptr;
50 }
51 
52 // // ------------------------------------ //
53 // // Plane
54 // DLLEXPORT Plane::Plane(bs::Scene* scene, Ogre::SceneNode* parent, const std::string&
55 // material,
56 // const Ogre::Plane& plane, const Float2& size,
57 // const Ogre::Vector3& uvupvector /*= Ogre::Vector3::UNIT_Y*/) :
58 // Component(TYPE),
59 // GeneratedMeshName("Plane_Component_Mesh_" + std::to_string(IDFactory::GetID())),
60 // Material(material), PlaneDefinition(plane), Size(size), UpVector(uvupvector)
61 // {
62 // const auto mesh = Ogre::v1::MeshManager::getSingleton().createPlane(
63 // GeneratedMeshName + "_v1", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
64 // plane, size.X, size.Y, 1, 1,
65 // // Normals
66 // true, 1, 1.0f, 1.0f, uvupvector, Ogre::v1::HardwareBuffer::HBU_STATIC_WRITE_ONLY,
67 // Ogre::v1::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false, false);
68 
69 // const auto mesh2 = Ogre::MeshManager::getSingleton().createManual(
70 // GeneratedMeshName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
71 
72 // // Fourth true is qtangent encoding which is not needed if we don't do normal mapping
73 // mesh2->importV1(mesh.get(), true, true, true);
74 
75 // Ogre::v1::MeshManager::getSingleton().remove(mesh);
76 
77 // GraphicalObject = scene->createItem(mesh2);
78 // parent->attachObject(GraphicalObject);
79 
80 // // This DOESN'T seem to throw if material is invalid
81 // GraphicalObject->setDatablockOrMaterialName(material);
82 
83 // GraphicalObject->setRenderQueueGroup(DEFAULT_RENDER_QUEUE);
84 // }
85 
86 // DLLEXPORT void Plane::Release(bs::Scene* scene)
87 // {
88 // scene->destroyItem(GraphicalObject);
89 
90 // Ogre::MeshManager::getSingleton().remove(GeneratedMeshName);
91 // }
92 // ------------------ Physics ------------------ //
94 {
95  if(Body) {
96  LOG_FATAL("Physics: Release not called before destructor!");
97  }
98 }
99 
101 {
102  if(Body) {
103  Body->SetOwningEntity(NULL_OBJECT);
104  world->DestroyBody(Body.get());
105  }
106 
107  Body.reset();
108 }
109 // ------------------------------------ //
111 {
112  if(Body)
113  Body->SetPosition(target.Members._Position, target.Members._Orientation);
114 }
115 // ------------------------------------ //
117  const PhysicsShape::pointer& shape, float mass, int physicsmaterialid /*= -1*/)
118 {
119  if(!world || !shape)
120  return nullptr;
121 
122  // Destroy old if there is one //
123  if(Body)
124  world->DestroyBody(Body.get());
125 
126  Body = world->CreateBodyFromCollision(shape, mass, &_Position, physicsmaterialid);
127 
128  if(!Body)
129  return nullptr;
130 
131  Body->SetOwningEntity(ThisEntity);
132 
133  return Body;
134 }
135 
136 DLLEXPORT bool Physics::ChangeShape(PhysicalWorld* world, const PhysicsShape::pointer& shape)
137 {
138  if(!world || !shape)
139  return false;
140 
141  return world->ChangeBodyShape(Body, shape);
142 }
143 
144 // ------------------ Received ------------------ //
145 // DLLEXPORT void Received::GetServerSentStates(
146 // StoredState const** first, StoredState const** second, int tick, float& progress) const
147 // {
148 // // Used to find the first tick before or on tick //
149 // int firstinpast = std::numeric_limits<int>::max();
150 // int secondfound = 0;
151 
152 // for(auto& obj : ClientStateBuffer) {
153 
154 // if(tick - obj.Tick < firstinpast && tick - obj.Tick >= 0) {
155 
156 // // This is (potentially) the first state //
157 // firstinpast = tick - obj.Tick;
158 
159 // *first = &obj;
160 // }
161 
162 // // For this to be found the client should be around 50-100 milliseconds in the past
163 // if(obj.Tick > tick && (secondfound == 0 || obj.Tick - tick < secondfound)) {
164 
165 // // The second state //
166 // *second = &obj;
167 
168 // secondfound = obj.Tick - tick;
169 // continue;
170 // }
171 // }
172 
173 // if(firstinpast == std::numeric_limits<int>::max() || secondfound == 0) {
174 
175 // throw InvalidState("No stored server states around tick");
176 // }
177 
178 // // If the range is not 1, meaning firstinpast != 0 || secondfound > 1 we need to adjust
179 // // progress
180 // int range = firstinpast + secondfound;
181 
182 // if(range == 1)
183 // return;
184 
185 // progress = ((tick + progress) - (*first)->Tick) / range;
186 // }
187 // // ------------------ Trail ------------------ //
188 // DLLEXPORT bool Trail::SetTrailProperties(const Properties &variables, bool force /*=
189 // false*/){
190 
191 //
192 
193 // if(!TrailEntity || !_RenderNode)
194 // return false;
195 
196 // // Set if we unconnected the node and we should reconnect it afterwards //
197 // bool ConnectAgain = false;
198 
199 // // Determine if we need to unconnect the node //
200 // if(force || variables.MaxChainElements != CurrentSettings.MaxChainElements){
201 
202 // // This to avoid Ogre bug //
203 // TrailEntity->removeNode(_RenderNode->Node);
204 // ConnectAgain = true;
205 
206 // // Apply the properties //
207 // TrailEntity->setUseVertexColours(true);
208 // TrailEntity->setRenderingDistance(variables.MaxDistance);
209 // TrailEntity->setMaxChainElements(variables.MaxChainElements);
210 // TrailEntity->setCastShadows(variables.CastShadows);
211 // TrailEntity->setTrailLength(variables.TrailLenght);
212 // }
213 
214 // // Update cached settings //
215 // CurrentSettings = variables;
216 
217 // // Apply per element properties //
218 // for(size_t i = 0; i < variables.Elements.size(); i++){
219 // // Apply settings //
220 // const ElementProperties& tmp = variables.Elements[i];
221 
222 // TrailEntity->setInitialColour(i, tmp.InitialColour);
223 // TrailEntity->setInitialWidth(i, tmp.InitialSize);
224 // TrailEntity->setColourChange(i, tmp.ColourChange);
225 // TrailEntity->setWidthChange(i, tmp.SizeChange);
226 // }
227 
228 // // More bug avoiding //
229 // if(ConnectAgain)
230 // TrailEntity->addNode(_RenderNode->Node);
231 
232 // return true;
233 // }
234 // // ------------------------------------ //
235 // DLLEXPORT void Trail::Release(bs::Scene* scene){
236 
237 // if(TrailEntity){
238 
239 // scene->destroyRibbonTrail(TrailEntity);
240 // TrailEntity = nullptr;
241 // }
242 // }
243 // ------------------ Sendable ------------------ //
245 {
246  if(SentPackets.empty())
247  return;
248 
249  // Looped in reverse to hopefully remove only last elements //
250  for(int i = static_cast<int>(SentPackets.size() - 1); i >= 0;) {
251 
252  auto& tuple = SentPackets[i];
253 
254  if(std::get<2>(tuple)->IsFinalized()) {
255 
256  if(std::get<2>(tuple)->GetStatus()) {
257 
258  // Succeeded //
259  if(std::get<0>(tuple) > LastConfirmedTickNumber) {
260 
261  LastConfirmedTickNumber = std::get<0>(tuple);
262 
263  // This is always erased (a few lines later) so it's fine to swap
264  LastConfirmedData = std::move(std::get<1>(tuple));
265  }
266  }
267 
268  SentPackets.erase(SentPackets.begin() + i);
269 
270  if(SentPackets.empty())
271  break;
272 
273  } else {
274 
275  i--;
276  }
277  }
278 
279  if(SentPackets.capacity() > 10) {
280 
281  LOG_WARNING("Sendable::ActiveConnection: SentPackets has space for over 10 "
282  "sent packets");
283  SentPackets.shrink_to_fit();
284  }
285 }
286 // ------------------------------------ //
287 DLLEXPORT Model::Model(const Scene::pointer& scene, RenderNode& parent,
288  const std::string& meshname, const Material::pointer& material) :
289  Component(TYPE),
290  MeshName(meshname), ObjectMaterial(material)
291 {
292  Marked = false;
293 
294  // Skip if no graphics
295  if(!parent.Node)
296  return;
297 
298  GraphicalObject = Renderable::MakeShared<Renderable>(*parent.Node);
299 
300  ApplyMeshName();
301 
302  GraphicalObject->SetMaterial(ObjectMaterial);
303 }
304 
306 {
307  if(GraphicalObject)
308  GraphicalObject->DetachFromParent();
309 }
310 
312 {
313  if(MeshName.empty()) {
314  GraphicalObject->SetMesh(nullptr);
315  return;
316  }
317 
318  // Find the mesh
319  auto mesh = Engine::Get()->GetGraphics()->LoadMeshByName(MeshName);
320 
321  GraphicalObject->SetMesh(Mesh::MakeShared<Mesh>(mesh));
322 }
323 
324 // // ------------------ ManualObject ------------------ //
325 // DLLEXPORT ManualObject::ManualObject(bs::Scene* scene) : Component(TYPE)
326 // {
327 // Object = scene->createManualObject();
328 // Object->setRenderQueueGroup(DEFAULT_RENDER_QUEUE);
329 // }
330 
331 // DLLEXPORT void ManualObject::Release(bs::Scene* scene)
332 // {
333 // if(Object) {
334 
335 // scene->destroyManualObject(Object);
336 // Object = nullptr;
337 // }
338 
339 // CreatedMesh.clear();
340 // }
341 
342 // ------------------------------------ //
343 // Animated
345 {
346  Animation = ObjectAnimationHandler::MakeShared<ObjectAnimationHandler>(*node.Node);
347 }
348 
350 {
351  if(Animation)
352  Animation->DetachFromParent();
353  Animation = nullptr;
354 }
DLLEXPORT void CheckReceivedPackets()
Checks has any packet been successfully received and updates last confirmed.
Definition: Components.cpp:244
ObjectID ThisEntity
For passing to PhysicsBody::SetOwningEntity.
Definition: Components.h:489
DLLEXPORT bs::HMesh LoadMeshByName(const std::string &name)
Works the same as LoadShaderByName.
Definition: Graphics.cpp:611
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
#define LOG_FATAL(x)
Definition: Define.h:94
ObjectAnimationHandler::pointer Animation
Created animation component for this entity.
Definition: Components.h:305
DLLEXPORT bool ChangeBodyShape(const PhysicsBody::pointer &body, const PhysicsShape::pointer &shape)
Applies a changed shape to a body.
DLLEXPORT void Release(const Scene::pointer &worldsscene)
Gracefully releases while world is still valid.
Definition: Components.cpp:39
Material::pointer ObjectMaterial
Material set on the object.
Definition: Components.h:251
std::string MeshName
Changing this loads a different mesh.
Definition: Components.h:248
DLLEXPORT PhysicsBody::pointer CreateBodyFromCollision(const PhysicsShape::pointer &shape, float mass, PhysicsPositionProvider *positionsynchronization, int physicsmaterialid=-1)
Constraints body to a 2d plane of movement specified by its normal.
DLLEXPORT void ApplyState(const PositionState &state)
Applies the state and marks this as changed. Doesn't check if the state is actually different.
Definition: Components.cpp:20
#define LOG_WARNING(x)
Definition: Define.h:91
std::vector< std::tuple< int, std::shared_ptr< EntityState >, std::shared_ptr< SentNetworkThing > > > SentPackets
Holds packets sent to this connection that haven't failed or been received yet.
Definition: Components.h:153
DLLEXPORT bool ChangeShape(PhysicalWorld *world, const PhysicsShape::pointer &shape)
Updates the shape. This can be the same pointer as before. BUT if the shape is modified this MUST be ...
Definition: Components.cpp:136
DLLEXPORT bool DestroyBody(PhysicsBody *body)
Destroys a physics body.
std::shared_ptr< EntityState > LastConfirmedData
Definition: Components.h:143
DLLEXPORT Model(const Scene::pointer &scene, RenderNode &parent, const std::string &meshname, const Material::pointer &material)
Definition: Components.cpp:287
Entity has position and direction it is looking at.
Definition: Components.h:36
Entity has a scene node.
Definition: Components.h:82
DLLEXPORT void Release()
Definition: Components.cpp:305
DLLEXPORT ~Physics()
Definition: Components.cpp:93
Renderable::pointer GraphicalObject
The rendebale that has this model's mesh loaded.
Definition: Components.h:245
Graphics * GetGraphics()
Definition: Engine.h:185
SceneNode::pointer Node
Definition: Components.h:94
static constexpr auto TYPE
Definition: Components.h:164
DLLEXPORT void Release()
Definition: Components.cpp:349
DLLEXPORT PhysicsBody::pointer CreatePhysicsBody(PhysicalWorld *world, const PhysicsShape::pointer &shape, float mass, int physicsmaterialid=-1)
Use this to create a body for this component once Collision is set.
Definition: Components.cpp:116
bool IsInGraphicalMode()
DLLEXPORT void Release(PhysicalWorld *world)
Destroys the physical body.
Definition: Components.cpp:100
DLLEXPORT void JumpTo(Position &target)
Syncs this physics body to a changed position.
Definition: Components.cpp:110
DLLEXPORT RenderNode(const Scene::pointer &scene)
Definition: Components.cpp:28
DLLEXPORT Animated(RenderNode &node)
Definition: Components.cpp:344
#define DLLEXPORT
Definition: Include.h:84
Base class for all components.
Definition: Component.h:52
Position & _Position
Physics object requires a position.
Definition: Components.h:495
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:86
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
DLLEXPORT void ApplyMeshName()
Definition: Components.cpp:311