-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsprite.cpp
executable file
·142 lines (125 loc) · 4.52 KB
/
sprite.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "sprite.hpp"
#include <stdio.h>
#include <assert.h>
#include "util.hpp"
#define _USE_MATH_DEFINES
#include <math.h>
void Sprite::Update(float sec) {
pos += vel * sec;
float rad_sq = glm::dot(omega, omega);
if (glm::dot(omega, omega) > 0) {
RotateAroundGlobalAxis(glm::normalize(omega), sqrtf(rad_sq)*180/M_PI);
}
}
void ChunkSprite::Init() {
orientation = glm::mat3(1);
scale = glm::vec3(1,1,1);
// Default Anchor: centered
anchor = chunk->Size() * 0.5f;
pos = glm::vec3(0, 0, 0);
}
void Sprite::RotateAroundGlobalAxis(const glm::vec3& axis, const float deg) {
glm::mat4 o4(orientation);
o4 = glm::rotate(o4, deg*3.14159f/180.0f, glm::inverse(orientation)*axis);
orientation = glm::mat3(o4);
}
void Sprite::RotateAroundLocalAxis(const glm::vec3& axis, const float deg) {
glm::mat4 o4(orientation);
o4 = glm::rotate(o4, deg*3.14159f/180.0f, axis);
orientation = glm::mat3(o4);
}
void ChunkSprite::Render() {
chunk->Render(pos, scale, orientation, anchor);
}
#ifdef WIN32
void ChunkSprite::Render_D3D11() {
chunk->Render_D3D11(pos, scale, orientation, anchor);
}
void ChunkSprite::RecordRenderCommand_D3D12(
ChunkPass* chunk_pass,
const DirectX::XMMATRIX& V,
const DirectX::XMMATRIX& P) {
chunk->RecordRenderCommand_D3D12(chunk_pass, pos, scale, orientation, anchor, V, P);
}
#endif
glm::vec3 Sprite::GetVoxelCoord(const glm::vec3& p_world) {
glm::vec3 p_local = glm::inverse(orientation) * (p_world - pos);
glm::vec3 pc = (p_local / scale) + anchor; // pc = point_chunk
return pc;
}
bool ChunkSprite::IntersectPoint(const glm::vec3& p_world) {
glm::vec3 pc = GetVoxelCoord(p_world);
return (chunk->GetVoxel(unsigned(pc.x), unsigned(pc.y), unsigned(pc.z)) > 0);
}
bool ChunkSprite::IntersectPoint(const glm::vec3& p_world, int tolerance) {
glm::vec3 p_local = glm::inverse(orientation) * (p_world - pos);
glm::vec3 pc = p_local / scale + anchor; // pc = point_chunk
for (int dx=-tolerance; dx<=tolerance; dx++) {
for (int dy=-tolerance; dy<=tolerance; dy++) {
for (int dz=-tolerance; dz<=tolerance; dz++) {
int xx = int(pc.x) + dx, yy = int(pc.y) + dy, zz = int(pc.z) + dz;
if (xx >= 0 && yy >= 0 && zz >= 0) {
if (chunk->GetVoxel(unsigned(xx), unsigned(yy), unsigned(zz)) > 0) {
return true;
}
}
}
}
}
return false;
}
glm::vec3 Sprite::GetWorldCoord(const glm::vec3& p_voxel) {
return pos + orientation * (p_voxel * scale - anchor);
}
AABB ChunkSprite::GetAABBInWorld() {
glm::vec3 p[8];
p[0] = GetWorldCoord(glm::vec3(0, 0, 0));
p[1] = GetWorldCoord(glm::vec3(chunk->x_len, 0, 0));
p[2] = GetWorldCoord(glm::vec3(0, chunk->y_len, 0));
p[3] = GetWorldCoord(glm::vec3(chunk->x_len, chunk->y_len, 0));
p[4] = GetWorldCoord(glm::vec3(0, 0, chunk->z_len));
p[5] = GetWorldCoord(glm::vec3(chunk->x_len, 0, chunk->z_len));
p[6] = GetWorldCoord(glm::vec3(0, chunk->y_len, chunk->z_len));
p[7] = GetWorldCoord(glm::vec3(chunk->x_len, chunk->y_len, chunk->z_len));
glm::vec3 ub(-1e20, -1e20, -1e20), lb(1e20, 1e20, 1e20);
for (int i=0; i<8; i++) {
ub.x = std::max(ub.x, p[i].x); ub.y = std::max(ub.y, p[i].y); ub.z = std::max(ub.z, p[i].z);
lb.x = std::min(lb.x, p[i].x); lb.y = std::min(lb.y, p[i].y); lb.z = std::min(lb.z, p[i].z);
}
return AABB(lb, ub);
}
//============CHUNK ANIM SPRITE===================
ChunkAnimSprite::ChunkAnimSprite(std::vector<ChunkIndex*>* _c, std::vector<float>* _ts) {
orientation = glm::mat3(1);
curr_secs = 0;
scale = glm::vec3(1,1,1);
assert (_c->size() == _ts->size());
for (unsigned i=0; i<_ts->size(); i++) {
frames[_ts->at(i)] = std::make_pair(
_c->at(i), _c->at(i)->GetCentroid());
}
}
ChunkIndex* ChunkAnimSprite::GetCurrChunk() {
std::map<float, std::pair<ChunkIndex*, glm::vec3> >::iterator itr =
frames.upper_bound(curr_secs);
return itr->second.first;
}
void ChunkAnimSprite::Render() {
std::map<float, std::pair<ChunkIndex*, glm::vec3> >::iterator itr =
frames.upper_bound(curr_secs);
ChunkIndex* c = itr->second.first;
glm::vec3 a = itr->second.second;
c->Render(pos, scale, orientation, a);
}
void ChunkAnimSprite::Update(const float secs) {
curr_secs += secs;
if (curr_secs >= frames.rbegin()->first) curr_secs = 0; // reset
pos += vel * secs;
}
// DUMMY
bool ChunkAnimSprite::IntersectPoint(const glm::vec3& p_world) {
return false;
}
bool ChunkAnimSprite::IntersectPoint(const glm::vec3& p_world, int tolerance) {
return false;
}