3#include <glm/gtc/constants.hpp>
4#include <glm/gtc/quaternion.hpp>
5#include <glm/gtc/matrix_transform.hpp>
6#include <glm/ext/matrix_relational.hpp>
7#include <glm/ext/vector_relational.hpp>
8#include <glm/ext/scalar_relational.hpp>
9#include <glm/gtc/type_ptr.hpp>
18inline __m128 loadFloat3(
const glm::vec3 &pos )
20 static_assert(
sizeof( glm::vec3 ) == 12,
"Expected to be 12 bytes (3 floats)" );
21 __m128 low = _mm_castpd_ps( _mm_load_sd( (
const double *)&pos ) );
23 __m128 high = _mm_load_ss( ( (
const float *)&pos ) + 2 );
24 return _mm_insert_ps( low, high, 0x27 );
28inline void storeFloat3( glm::vec3 &pos, __m128 vec )
30 _mm_store_sd( (
double *)&pos, _mm_castps_pd( vec ) );
31 ( (
int *)( &pos ) )[ 2 ] = _mm_extract_ps( vec, 2 );
35inline __m128 vector3Normalize( __m128 vec )
38 __m128 dp = _mm_dp_ps( vec, vec, 0b01111111 );
40 __m128 res = _mm_div_ps( vec, _mm_sqrt_ps( dp ) );
42 __m128 positiveLength = _mm_cmpgt_ps( dp, _mm_setzero_ps() );
44 return _mm_and_ps( res, positiveLength );
50#define XM_PERMUTE_PS( v, c ) _mm_permute_ps( v, c )
52#define XM_PERMUTE_PS( v, c ) _mm_shuffle_ps( v, v, c )
56#define XM_FNMADD_PS( a, b, c ) _mm_fnmadd_ps((a), (b), (c))
58#define XM_FNMADD_PS( a, b, c ) _mm_sub_ps((c), _mm_mul_ps((a), (b)))
61inline __m128 vector3Cross( __m128 V1, __m128 V2 )
64 __m128 vTemp1 = XM_PERMUTE_PS( V1, _MM_SHUFFLE( 3, 0, 2, 1 ) );
66 __m128 vTemp2 = XM_PERMUTE_PS( V2, _MM_SHUFFLE( 3, 1, 0, 2 ) );
68 __m128 vResult = _mm_mul_ps( vTemp1, vTemp2 );
70 vTemp1 = XM_PERMUTE_PS( vTemp1, _MM_SHUFFLE( 3, 0, 2, 1 ) );
72 vTemp2 = XM_PERMUTE_PS( vTemp2, _MM_SHUFFLE( 3, 1, 0, 2 ) );
74 vResult = XM_FNMADD_PS( vTemp1, vTemp2, vResult );
80#define VEC3_SUB(a, b, out) out.x = a.x - b.x; \
84#define VEC3_ADD(a, b, out) out.x = a.x + b.x; \
97inline float Q_rsqrt(
float number)
101 const float threehalfs = 1.5F;
105 i = 0x5f3759df - (i >> 1);
107 y = y * (threehalfs - (x2 * y * y));
112#define VEC3_NORMALIZE(v, out) \
115 float tempLength = ( (v.x) * (v.x) ) + ( (v.y) * (v.y) ) +( (v.z) * (v.z) ); \
116 float lengthSqrauedI = Q_rsqrt(tempLength); \
117 out.x = (v.x) * lengthSqrauedI; \
118 out.y = (v.y) * lengthSqrauedI; \
119 out.z = (v.z) * lengthSqrauedI; \
122#define VEC3_CROSS(a, b, out) \
124 out.x = ( (a.y) * (b.z) ) - ( (a.z) * (b.y) ); \
125 out.y = ( (a.z) * (b.x) ) - ( (a.x) * (b.z) ); \
126 out.z = ( (a.x) * (b.y) ) - ( (a.y) * (b.x) ); \
139 if (deleteOnDestruction)
153void Mesh::ClearNormals()
155 for(
int i = 0 ; i < vertexCount ; i++)
157 vert[i].normal.x = 0.0f;
158 vert[i].normal.y = 0.0f;
159 vert[i].normal.z = 0.0f;
163void Mesh::RecalculateNormals()
170 for (
int i = 0; i < indexCount; i += 3)
172 iabc[0] = indices[i];
173 iabc[1] = indices[i + 1];
174 iabc[2] = indices[i + 2];
175 glm::vec4 &tmp4a = vert[iabc[0]].position;
176 glm::vec4 &tmp4b = vert[iabc[1]].position;
177 glm::vec4 &tmp4c = vert[iabc[2]].position;
178 VEC3_SUB(tmp4a, tmp4b, e1);
179 VEC3_SUB(tmp4c, tmp4b, e2);
180 VEC3_CROSS(e1, e2, no);
181 VEC3_ADD(vert[iabc[0]].normal, no, vert[iabc[0]].normal);
182 VEC3_ADD(vert[iabc[1]].normal, no, vert[iabc[1]].normal);
183 VEC3_ADD(vert[iabc[2]].normal, no, vert[iabc[2]].normal);
186 for (
int i = 0; i < vertexCount; i++)
188 VEC3_NORMALIZE(vert[i].normal, vert[i].normal);
192void Mesh::GenerateIcoSphere(
int resolution,
float radius,
float textureScale)
194 currType = MeshType::Icosphere;
217 for (
int i = 0; i <
sizeof(vertis)/
sizeof(glm::vec3); i++)
222 vertexCount =
sizeof(vertis)/
sizeof(
int);
223 vert =
new Vert[
sizeof(vertis) /
sizeof(
int)];
224 memset(vert, 0,
sizeof(
Vert) * vertexCount);
226 for (
int i = 0; i < vertexCount; i++)
229 vert[i].position = glm::vec4(vertis[i], 1);
232 indexCount =
sizeof(triangles)/
sizeof(
int);
233 indices =
new int[indexCount];
234 memcpy(indices, triangles,
sizeof(
int) * indexCount);
237void Mesh::GeneratePlane(
int resolution,
float scale,
float textureScale)
239 currType = MeshType::Plane;
244 texSc = textureScale;
245 Vert *vertices =
new Vert[resolution * resolution];
246 int *inds =
new int[(resolution-1) * (resolution-1) * 6];
249 for (
int y = 0; y < resolution; y++)
251 for (
int x = 0; x < resolution; x++)
253 int i = x + y * resolution;
254 glm::vec2 percent = glm::vec2(x, y) / ((float)resolution - 1);
255 glm::vec3 pointOnPlane = (percent.x - .5f) * 2 * right + (percent.y - .5f) * 2 * front;
256 pointOnPlane *= scale;
257 vertices[i] =
Vert();
258 vertices[i].position = glm::vec4(0.0f);
259 vertices[i].position.x = (float)pointOnPlane.x;
260 vertices[i].position.y = (
float)pointOnPlane.y;
261 vertices[i].position.z = (float)pointOnPlane.z;
262 vertices[i].texCoord = glm::vec2(percent.x, percent.y)*textureScale;
263 vertices[i].normal = glm::vec4(0.0f);
265 if (x != resolution - 1 && y != resolution - 1)
268 inds[triIndex + 1] = i + resolution + 1;
269 inds[triIndex + 2] = i + resolution;
270 inds[triIndex + 3] = i;
271 inds[triIndex + 4] = i + 1;
272 inds[triIndex + 5] = i + resolution + 1;
276 vertices[i].extras1 = glm::vec4(0.0f);
290 vertexCount = resolution * resolution;
291 vert =
new Vert[resolution * resolution];
292 memset(vert, 0,
sizeof(
Vert) * vertexCount);
293 memcpy(vert, vertices,
sizeof(
Vert)*vertexCount);
294 indexCount = (resolution - 1) * (resolution - 1) * 6;
295 indices =
new int[(resolution - 1) * (resolution - 1) * 6];
296 memset(indices, 0, indexCount);
297 memcpy(indices, inds,
sizeof(
int) * indexCount);
302void Mesh::GenerateScreenQuad(
float dist)
316 v.position = glm::vec4(-1, -1, dist, 0);
317 v.texCoord = glm::vec2(0, 0);
319 v.position = glm::vec4(-1, 1, dist, 0);
320 v.texCoord = glm::vec2(0, 1);
322 v.position = glm::vec4(1, 1, dist, 0);
323 v.texCoord = glm::vec2(1, 1);
325 v.position = glm::vec4(1, -1, dist, 0);
326 v.texCoord = glm::vec2(1, 0);
330 indices =
new int[6];
339void Mesh::SetElevation(
float elevation,
int x,
int y)
353 if (elevation > maxHeight)
355 maxHeight = elevation;
358 if (elevation < minHeight)
360 minHeight = elevation;
363 vert[i].position.y = elevation;
364 vert[i].extras1.x = elevation;
367float Mesh::GetElevation(
int x,
int y)
381 return vert[i].position.y;
384glm::vec3 Mesh::GetNormals(
int x,
int y)
398 return glm::vec3(vert[i].normal.x, vert[i].normal.y, vert[i].normal.z);
401void Mesh::AddElevation(
float elevation,
int x,
int y)
415 vert[i].position.y += elevation;
418glm::vec2 Mesh::GetTexCoord(
float x,
float y,
float z)
420 if (currType == MeshType::Plane)
422 return (glm::vec2(x, y) / ((
float)res - 1)) * texSc;
427 return glm::vec2(1.0f);
434 cloneMesh->res = res;
436 cloneMesh->maxHeight = maxHeight;
437 cloneMesh->vertexCount = vertexCount;
438 cloneMesh->indexCount = indexCount;
439 cloneMesh->vert =
new Vert[vertexCount];
440 memcpy(cloneMesh->vert, vert,
sizeof(
Vert) * vertexCount);
441 cloneMesh->indices =
new int[indexCount];
442 memcpy(cloneMesh->indices, indices,
sizeof(
int) * indexCount);