-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathModel.cpp
More file actions
116 lines (101 loc) · 2.51 KB
/
Copy pathModel.cpp
File metadata and controls
116 lines (101 loc) · 2.51 KB
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
#include "Model.h"
#include <cmath>
void Model::UpdateCullExtent()
{
if (!m_hasBounds) {
m_cullExtent = 50.0f;
return;
}
float centerLen = sqrtf(
m_boundCenterX * m_boundCenterX +
m_boundCenterY * m_boundCenterY +
m_boundCenterZ * m_boundCenterZ
);
m_cullExtent = centerLen + m_boundRadius;
if (m_cullExtent < 1.0f)
m_cullExtent = 1.0f;
}
void Model::IncludeBoundingSphere(float x, float y, float z, float radius)
{
if (radius < 0.0f)
radius = 0.0f;
if (!m_hasBounds) {
m_boundCenterX = x;
m_boundCenterY = y;
m_boundCenterZ = z;
m_boundRadius = radius;
m_hasBounds = true;
UpdateCullExtent();
return;
}
float dx = x - m_boundCenterX;
float dy = y - m_boundCenterY;
float dz = z - m_boundCenterZ;
float dist = sqrtf(dx * dx + dy * dy + dz * dz);
if (dist + radius <= m_boundRadius) {
UpdateCullExtent();
return;
}
if (dist + m_boundRadius <= radius) {
m_boundCenterX = x;
m_boundCenterY = y;
m_boundCenterZ = z;
m_boundRadius = radius;
UpdateCullExtent();
return;
}
float newRadius = (m_boundRadius + radius + dist) * 0.5f;
float k = (newRadius - m_boundRadius) / dist;
m_boundCenterX += dx * k;
m_boundCenterY += dy * k;
m_boundCenterZ += dz * k;
m_boundRadius = newRadius;
UpdateCullExtent();
}
void Model::GetWorldCullSphere(
float x, float y, float z,
float sx, float sy, float sz,
float* outX, float* outY, float* outZ, float* outRadius
) const
{
float absSx = fabsf(sx);
float absSy = fabsf(sy);
float absSz = fabsf(sz);
float maxScale = absSx;
if (absSy > maxScale) maxScale = absSy;
if (absSz > maxScale) maxScale = absSz;
if (maxScale < 0.0001f)
maxScale = 1.0f;
*outX = x;
*outY = y;
*outZ = z;
*outRadius = m_cullExtent * maxScale;
}
void Model::SetPosition(float x, float y, float z, float sx, float sy, float sz, float rx, float ry, float rz, float rr)
{
XMMATRIX world =
XMMatrixRotationQuaternion(XMVectorSet(rx, ry, rz, rr)) *
XMMatrixScaling(sx, sy, sz) *
XMMatrixTranslation(x, y, z);
for (int i = 0; i < (int)m_pMeshes.size(); i++) {
m_pMeshes[i]->SetWorld(world);
}
}
void Model::Render(DXRender* pRender, MeshRenderContext& ctx, int alphaFilter)
{
for (int i = 0; i < (int)m_pMeshes.size(); i++) {
Mesh* mesh = m_pMeshes[i];
bool isAlpha = mesh->GetAlpha();
if (alphaFilter < 0) {
if (isAlpha)
continue;
} else if (alphaFilter == 1) {
if (!isAlpha || !mesh->IsAlphaCutout())
continue;
} else if (alphaFilter == 2) {
if (!isAlpha || mesh->IsAlphaCutout())
continue;
}
mesh->Render(pRender, ctx);
}
}