]> git.localhorst.tv Git - blank.git/blob - src/model/composite.cpp
split composite model in template and instance
[blank.git] / src / model / composite.cpp
1 #include "CompositeModel.hpp"
2 #include "CompositeInstance.hpp"
3
4 #include "EntityModel.hpp"
5 #include "../graphics/DirectionalLighting.hpp"
6
7 #include <glm/gtx/quaternion.hpp>
8
9
10 namespace blank {
11
12 CompositeModel::CompositeModel()
13 : node_model(nullptr)
14 , position(0.0f)
15 , orientation(1.0f, 0.0f, 0.0f, 0.0f)
16 , parts() {
17
18 }
19
20
21 CompositeModel &CompositeModel::AddPart() {
22         parts.emplace_back();
23         parts.back().parent = this;
24         return parts.back();
25 }
26
27
28 glm::mat4 CompositeModel::LocalTransform() const noexcept {
29         glm::mat4 transform(toMat4(orientation));
30         transform[3].x = position.x;
31         transform[3].y = position.y;
32         transform[3].z = position.z;
33         return transform;
34 }
35
36 glm::mat4 CompositeModel::GlobalTransform() const noexcept {
37         if (HasParent()) {
38                 return Parent().GlobalTransform() * LocalTransform();
39         } else {
40                 return LocalTransform();
41         }
42 }
43
44
45 void CompositeModel::Instantiate(CompositeInstance &inst) const {
46         inst.part_model = this;
47         inst.position = position;
48         inst.orientation = orientation;
49         inst.parts.clear();
50         inst.parts.reserve(parts.size());
51         for (const CompositeModel &part : parts) {
52                 part.Instantiate(inst.AddPart());
53         }
54 }
55
56
57 CompositeInstance::CompositeInstance()
58 : part_model(nullptr)
59 , parent(nullptr)
60 , position(0.0f)
61 , orientation(1.0f, 0.0f, 0.0f, 0.0f)
62 , parts() {
63
64 }
65
66
67 CompositeInstance &CompositeInstance::AddPart() {
68         parts.emplace_back();
69         parts.back().parent = this;
70         return parts.back();
71 }
72
73
74 glm::mat4 CompositeInstance::LocalTransform() const noexcept {
75         glm::mat4 transform(toMat4(orientation));
76         transform[3].x = position.x;
77         transform[3].y = position.y;
78         transform[3].z = position.z;
79         return transform;
80 }
81
82 glm::mat4 CompositeInstance::GlobalTransform() const noexcept {
83         if (HasParent()) {
84                 return Parent().GlobalTransform() * LocalTransform();
85         } else {
86                 return LocalTransform();
87         }
88 }
89
90
91 void CompositeInstance::Render(const glm::mat4 &M, DirectionalLighting &prog) const {
92         glm::mat4 transform(M * LocalTransform());
93         if (part_model->HasNodeModel()) {
94                 prog.SetM(transform);
95                 part_model->NodeModel().Draw();
96         }
97         for (const CompositeInstance &part : parts) {
98                 part.Render(transform, prog);
99         }
100 }
101
102 }