olcPixelGameEngine v2.28
The official distribution of olcPixelGameEngine, a tool used in javidx9's YouTube videos and projects
Loading...
Searching...
No Matches
olcPGEX_Wireframe.h
Go to the documentation of this file.
1/*
2 olcPGEX_Wireframe.h
3
4 +-------------------------------------------------------------+
5 | OneLoneCoder Pixel Game Engine Extension |
6 | Wireframe v1.0 |
7 +-------------------------------------------------------------+
8
9 NOTE: UNDER ACTIVE DEVELOPMENT - THERE ARE BUGS/GLITCHES
10
11 What is this?
12 ~~~~~~~~~~~~~
13 This extension provides drawing routines giving simple wireframe
14 shapes and models constructed in a transform hierachy
15
16 License (OLC-3)
17 ~~~~~~~~~~~~~~~
18
19 Copyright 2018 - 2022 OneLoneCoder.com
20
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 1. Redistributions or derivations of source code must retain the above
26 copyright notice, this list of conditions and the following disclaimer.
27
28 2. Redistributions or derivative works in binary form must reproduce
29 the above copyright notice. This list of conditions and the following
30 disclaimer must be reproduced in the documentation and/or other
31 materials provided with the distribution.
32
33 3. Neither the name of the copyright holder nor the names of its
34 contributors may be used to endorse or promote products derived
35 from this software without specific prior written permission.
36
37 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
38 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
40 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
41 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48
49 Links
50 ~~~~~
51 YouTube: https://www.youtube.com/javidx9
52 Discord: https://discord.gg/WhwHUMV
53 Twitter: https://www.twitter.com/javidx9
54 Twitch: https://www.twitch.tv/javidx9
55 GitHub: https://www.github.com/onelonecoder
56 Homepage: https://www.onelonecoder.com
57
58 Author
59 ~~~~~~
60 David Barr, aka javidx9, ©OneLoneCoder 2019, 2020, 2021, 2022
61
62 Revisions:
63 1.00: Initial Release
64
65*/
66
67#pragma once
68#ifndef OLC_PGEX_WIREFRAME_H
69#define OLC_PGEX_WIREFRAME_H
70
71#include "olcPixelGameEngine.h"
72
73namespace olc
74{
75#ifndef OLC_MAT3_DESC
76#define OLC_MAT3_DESC
77 template<typename T>
79 {
80 std::array<T, 9> m{ 0 };
81 constexpr size_t idx(size_t r, size_t c) const { return r * 3 + c; }
82 T& operator()(size_t row, size_t col) { return m[idx(row, col)]; }
83 const T& operator()(size_t row, size_t col) const { return m[idx(row, col)]; }
85 mat3_generic(const mat3_generic& m) = default;
87
88 void clear() { std::fill(m.begin(), m.end(), T(0)); }
89 void identity() { clear(); (*this)(0, 0) = 1; (*this)(1, 1) = 1; (*this)(2, 2) = 1; }
90
91 void translate(float x, float y) { identity(); auto& m = (*this); m(2, 0) = x; m(2, 1) = y; }
92 void translate(const olc::v2d_generic<T>& v) { translate(v.x, v.y); }
93 void scale(float x, float y) { identity(); auto& m = (*this); m(0, 0) = x; m(1, 1) = y; }
94 void scale(const olc::v2d_generic<T>& v) { return scale(v.x, v.y); }
95 void rotate(float a) { identity(); auto& m = (*this); m(0, 0) = cos(a); m(0, 1) = sin(a); m(1, 0) = -m(0, 1); m(1, 1) = m(0, 0); }
96
97 olc::v2d_generic<T> operator * (const olc::v2d_generic<T>& v) const
98 {
99 auto& m = *this;
100 olc::v2d_generic<T> vOut;
101 vOut.x = m(0, 0) * v.x + m(1, 0) * v.y + m(2, 0) * T(1);
102 vOut.y = m(0, 1) * v.x + m(1, 1) * v.y + m(2, 1) * T(1);
103 T z = m(0, 2) * v.x + m(1, 2) * v.y + m(2, 2) * T(1);
104 return (vOut / z);
105 }
106
108 {
109 auto& m = *this;
110 mat3_generic<T> out;
111 for (size_t c = 0; c < 3; c++)
112 for (size_t r = 0; r < 3; r++)
113 out(r, c) = m(r, 0) * rhs(0, c) + m(r, 1) * rhs(1, c) + m(r, 2) * rhs(2, c);
114 return out;
115 }
116 };
117
119#endif
120
121 namespace wire
122 {
123 typedef std::vector<olc::vf2d> Mesh;
124 //Mesh NullMesh;
125
126 class Model
127 {
128 public:
129 static constexpr uint8_t DRAW_ORIGIN = 0x01;
130 static constexpr uint8_t DRAW_NODES = 0x02;
131 static constexpr uint8_t DRAW_MEASURES = 0x04;
132 public:
133 Model() = default;
134
135 public:
136 void Attach(Model* child, const olc::vf2d& position = { 0.0f, 0.0f }, const float angle = 0.0f);
137 void SetRotation(const float angle);
138 void SetPosition(const olc::vf2d& position);
139 void UpdateInWorld(const Matrix2D& matParent);
141 void SetMesh(const Mesh& mesh);
142 const Mesh& GetWorldPoints() const;
143 const std::vector<Model*>& GetChildren() const;
144
145 protected:
152
153 protected:
154 std::vector<Model*> vChildren;
155 };
156
157
158
159 inline const Mesh MeshCircle(const float fRadius, const int nPoints = 100)
160 {
161 Mesh m;
162 for (int i = 0; i < nPoints; i++)
163 {
164 float fTheta = (float(i) / float(nPoints)) * 2.0f * 3.14159f;
165 m.push_back(olc::vf2d{ cos(fTheta), sin(fTheta) } *fRadius);
166 }
167 return m;
168 }
169
170 inline const Mesh MeshRectangle(const olc::vf2d& size, const olc::vf2d& offset = { 0.0f, 0.0f })
171 {
172 return { -offset, {-offset.x + size.x, -offset.y}, -offset + size, {-offset.x, -offset.y + size.y} };
173 }
174
175 inline const Mesh MeshGear(const int nTeeth, const float fOuterRadius, const float fInnerRadius)
176 {
177 Mesh m;
178 for (int i = 0; i < nTeeth * 4; i++)
179 {
180 float fTheta = (float(i) / float(nTeeth * 4)) * 2.0f * 3.14159f;
181 m.push_back(olc::vf2d{ cos(fTheta), sin(fTheta) } * 2.0f * (float((i / 2) % 2) ? fOuterRadius : fInnerRadius));
182 }
183 return m;
184 }
185
186 template<typename T>
187 void DrawModel(T& render, Model& m, const olc::Pixel col = olc::BLACK, const uint8_t flags = -1)
188 {
189 const auto& points = m.GetWorldPoints();
190 for(size_t i = 0; i < points.size(); i++)
191 render.DrawLine(points[i], points[(i+1)%points.size()], col);
192
193 // Draw Nodes
194 if (flags & Model::DRAW_NODES)
195 for (size_t i = 0; i < points.size(); i++)
196 render.FillCircle(points[i], render.ScaleToWorld({ 3,3 }).x, olc::RED);
197
198 if (flags & Model::DRAW_ORIGIN)
199 {
200 render.FillCircle(m.LocalToWorld({ 0,0 }), render.ScaleToWorld({ 3,3 }).x, olc::BLUE);
201 render.DrawLine(
202 m.LocalToWorld({ 0,0 }),
203 m.LocalToWorld(render.ScaleToWorld({ 10, 0 })),
204 olc::BLUE);
205 }
206
207 // Draw Children
208 for (auto& child : m.GetChildren())
209 DrawModel<T>(render, *child, col, flags);
210 }
211
212
213 }
214}
215
216#ifdef OLC_PGEX_WIREFRAME
217#undef OLC_PGEX_WIREFRAME
218
219namespace olc
220{
221 namespace wire
222 {
223 void Model::SetMesh(const Mesh& mesh)
224 {
225 vLocalPoints = mesh;
226 vWorldPoints.clear();
227 vWorldPoints.resize(vLocalPoints.size());
228 }
229
230 void Model::SetRotation(const float angle)
231 {
234 }
235
236 void Model::SetPosition(const olc::vf2d& position)
237 {
240 }
241
242 void Model::Attach(Model* child, const olc::vf2d& position, const float angle)
243 {
244 if (child != nullptr)
245 {
246 child->SetPosition(position);
247 child->SetRotation(angle);
248 vChildren.push_back(child);
249 }
250 }
251
253 {
254 return matWorld * local;
255 }
256
257 const Mesh& Model::GetWorldPoints() const
258 {
259 return vWorldPoints;
260 }
261
262 const std::vector<Model*>& Model::GetChildren() const
263 {
264 return vChildren;
265 }
266
267 void Model::UpdateInWorld(const Matrix2D& matParent)
268 {
269 // Propagate matrix transform
270 matWorld = matLocal * matParent;
271
272 // Transform vertices
273 for (size_t i = 0; i < vLocalPoints.size(); i++)
274 {
276 }
277
278 // Transform Children
279 for (auto& child : vChildren)
280 child->UpdateInWorld(matWorld);
281 }
282 }
283}
284
285#endif // OLC_PGEX_WIREFRAME
286#endif // OLC_PGEX_WIREFRAME_H
287
Definition olcPGEX_Wireframe.h:127
olc::Matrix2D matLocalRotation
Definition olcPGEX_Wireframe.h:149
olc::Matrix2D matWorld
Definition olcPGEX_Wireframe.h:151
static constexpr uint8_t DRAW_NODES
Definition olcPGEX_Wireframe.h:130
static constexpr uint8_t DRAW_ORIGIN
Definition olcPGEX_Wireframe.h:129
Mesh vLocalPoints
Definition olcPGEX_Wireframe.h:146
Mesh vWorldPoints
Definition olcPGEX_Wireframe.h:147
void Attach(Model *child, const olc::vf2d &position={ 0.0f, 0.0f }, const float angle=0.0f)
void SetRotation(const float angle)
void SetPosition(const olc::vf2d &position)
olc::Matrix2D matLocalTranslation
Definition olcPGEX_Wireframe.h:148
olc::vf2d LocalToWorld(const olc::vf2d &local)
void UpdateInWorld(const Matrix2D &matParent)
olc::Matrix2D matLocal
Definition olcPGEX_Wireframe.h:150
const Mesh & GetWorldPoints() const
void SetMesh(const Mesh &mesh)
const std::vector< Model * > & GetChildren() const
std::vector< Model * > vChildren
Definition olcPGEX_Wireframe.h:154
static constexpr uint8_t DRAW_MEASURES
Definition olcPGEX_Wireframe.h:131
const Mesh MeshRectangle(const olc::vf2d &size, const olc::vf2d &offset={ 0.0f, 0.0f })
Definition olcPGEX_Wireframe.h:170
std::vector< olc::vf2d > Mesh
Definition olcPGEX_Wireframe.h:123
const Mesh MeshCircle(const float fRadius, const int nPoints=100)
Definition olcPGEX_Wireframe.h:159
void DrawModel(T &render, Model &m, const olc::Pixel col=olc::BLACK, const uint8_t flags=-1)
Definition olcPGEX_Wireframe.h:187
const Mesh MeshGear(const int nTeeth, const float fOuterRadius, const float fInnerRadius)
Definition olcPGEX_Wireframe.h:175
Definition olcPixelGameEngine.h:593
static const Pixel BLACK(0, 0, 0)
@ T
Definition olcPixelGameEngine.h:974
static const Pixel BLUE(0, 0, 255)
static const Pixel RED(255, 0, 0)
mat3_generic< float > Matrix2D
Definition olcPGEX_Wireframe.h:118
Definition olcPixelGameEngine.h:924
Definition olcPGEX_Wireframe.h:79
void translate(float x, float y)
Definition olcPGEX_Wireframe.h:91
const T & operator()(size_t row, size_t col) const
Definition olcPGEX_Wireframe.h:83
std::array< T, 9 > m
Definition olcPGEX_Wireframe.h:80
constexpr size_t idx(size_t r, size_t c) const
Definition olcPGEX_Wireframe.h:81
mat3_generic()
Definition olcPGEX_Wireframe.h:84
void scale(const olc::v2d_generic< T > &v)
Definition olcPGEX_Wireframe.h:94
T & operator()(size_t row, size_t col)
Definition olcPGEX_Wireframe.h:82
olc::v2d_generic< T > operator*(const olc::v2d_generic< T > &v) const
Definition olcPGEX_Wireframe.h:97
void clear()
Definition olcPGEX_Wireframe.h:88
void identity()
Definition olcPGEX_Wireframe.h:89
mat3_generic(const mat3_generic &m)=default
void scale(float x, float y)
Definition olcPGEX_Wireframe.h:93
void translate(const olc::v2d_generic< T > &v)
Definition olcPGEX_Wireframe.h:92
mat3_generic & operator=(const mat3_generic &m)=default
void rotate(float a)
Definition olcPGEX_Wireframe.h:95
T x
Definition olcPixelGameEngine.h:604