mat4* lookAt(mat4* pOut, const vec3* pEye, const vec3* pCenter, const vec3* pUp) { vec3 f; avec3_subtract(&f, pCenter, pEye); vec3Normalize(&f, &f); vec3 s; vec3Cross(&s, &f, pUp); vec3Normalize(&s, &s); vec3 u; vec3Cross(&u, &s, &f); pOut->mat[0] = s.x; pOut->mat[1] = u.x; pOut->mat[2] = -f.x; pOut->mat[3] = 0.0; pOut->mat[4] = s.y; pOut->mat[5] = u.y; pOut->mat[6] = -f.y; pOut->mat[7] = 0.0; pOut->mat[8] = s.z; pOut->mat[9] = u.z; pOut->mat[10] = -f.z; pOut->mat[11] = 0.0; pOut->mat[12] = -vec3Dot(&s, pEye); pOut->mat[13] = -vec3Dot(&u, pEye); pOut->mat[14] = vec3Dot(&f, pEye); pOut->mat[15] = 1.0; return pOut; }
// Inverse edge length weighted method. As described in Real-time rendering (3rd ed.) p.546. // Ref: Max, N. L., (1999) 'Weights for computing vertex normals from facet normals' // in Journal of grahics tools, vol.4, no.2, pp.1-6. static GLfloat* meshGenerateNormals(int num_verts, int num_elems, const GLfloat *verts, const GLushort *elems) { GLfloat *norms = (GLfloat*) calloc(3*num_verts, sizeof(GLfloat)); GLfloat e1[3], e2[3], no[3]; for (int i = 0; i < num_elems; i += 3) { for (int j = 0; j < 3; ++j) { int a = 3*elems[i+j]; int b = 3*elems[i+((j+1)%3)]; int c = 3*elems[i+((j+2)%3)]; vec3Sub(e1, &verts[c], &verts[b]); vec3Sub(e2, &verts[a], &verts[b]); vec3Cross(no, e1, e2); double d = vec3Length2(e1) * vec3Length2(e2); vec3DivScalar(no, no, d); vec3Add(&norms[b], &norms[b], no); } } for (int i = 0; i < 3*num_verts; i += 3) { vec3Normalize(&norms[i], &norms[i]); } return norms; }
//=========================================================================== int Scene::addPolygon(int* inVerts) { manta_assert(polyCount < MAX_SCENE_POLYS, "Error, attempting to add too many Polygons!\n"); color3f white; vec3Set(&white, 1.f, 1.f, 1.f); vec3 edgeA, edgeB, normal; vec3* verts[3]; verts[0] = &sceneVertices[inVerts[0]]; verts[1] = &sceneVertices[inVerts[1]]; verts[2] = &sceneVertices[inVerts[2]]; vec3Sub(&edgeA, verts[0], verts[1]); vec3Sub(&edgeB, verts[0], verts[2]); vec3Cross(&normal, &edgeB, &edgeA); vec3Unit(&normal); scenePolygons[polyCount].pointIndex[0] = inVerts[0]; scenePolygons[polyCount].pointIndex[1] = inVerts[1]; scenePolygons[polyCount].pointIndex[2] = inVerts[2]; debugBuildPoly(&scenePolygons[polyCount++], verts[0], verts[1], verts[2], &normal, &white); return polyCount-1; }
void invRotMatrixFromVec3(matrix* out, vec3* dir, vec3* up) { vec3 right; vec3Cross(&right, dir, up); vec3Cpy((vec3*)&out->row[0], &right); vec3Cpy((vec3*)&out->row[1], up); vec3Cpy((vec3*)&out->row[2], dir); }
Matrix4 mat4LookAt(const Vector3 &eye, const Vector3 ¢er, const Vector3 &up) { // Forward vector Vector3 f = eye - center; f.normalize(); // Right vector Vector3 r = vec3Cross(up, f); r.normalize(); // Up vector Vector3 u = vec3Cross(f, r); u.normalize(); // Create matrix Matrix4 mat(r.x, r.y, r.z, 0.0f, u.x, u.y, u.z, 0.0f, f.x, f.y, f.z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); return mat * mat4Translation(-eye); }
void mtxLookAtImpl(float* _result, const float* _eye, const float* _view, const float* _up) { float up[3] = { 0.0f, 1.0f, 0.0f }; if (NULL != _up) { up[0] = _up[0]; up[1] = _up[1]; up[2] = _up[2]; } float tmp[4]; vec3Cross(tmp, up, _view); float right[4]; vec3Norm(right, tmp); vec3Cross(up, _view, right); memSet(_result, 0, sizeof(float)*16); _result[ 0] = right[0]; _result[ 1] = up[0]; _result[ 2] = _view[0]; _result[ 4] = right[1]; _result[ 5] = up[1]; _result[ 6] = _view[1]; _result[ 8] = right[2]; _result[ 9] = up[2]; _result[10] = _view[2]; _result[12] = -vec3Dot(right, _eye); _result[13] = -vec3Dot(up, _eye); _result[14] = -vec3Dot(_view, _eye); _result[15] = 1.0f; }
void rotMatrixFromVec3(matrix* out, vec3* dir, vec3* up) { vec3 right; vec3Cross(&right, dir, up); out->row[0].x = right.x; out->row[1].x = right.y; out->row[2].x = right.z; out->row[0].y = up->x; out->row[1].y = up->y; out->row[2].y = up->z; out->row[0].z = dir->x; out->row[1].z = dir->y; out->row[2].z = dir->z; }
void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices) { struct PosTexcoord { float m_x; float m_y; float m_z; float m_pad0; float m_u; float m_v; float m_pad1; float m_pad2; }; float* tangents = new float[6*_numVertices]; memset(tangents, 0, 6*_numVertices*sizeof(float) ); PosTexcoord v0; PosTexcoord v1; PosTexcoord v2; for (uint32_t ii = 0, num = _numIndices/3; ii < num; ++ii) { const uint16_t* indices = &_indices[ii*3]; uint32_t i0 = indices[0]; uint32_t i1 = indices[1]; uint32_t i2 = indices[2]; bgfx::vertexUnpack(&v0.m_x, bgfx::Attrib::Position, _decl, _vertices, i0); bgfx::vertexUnpack(&v0.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i0); bgfx::vertexUnpack(&v1.m_x, bgfx::Attrib::Position, _decl, _vertices, i1); bgfx::vertexUnpack(&v1.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i1); bgfx::vertexUnpack(&v2.m_x, bgfx::Attrib::Position, _decl, _vertices, i2); bgfx::vertexUnpack(&v2.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i2); const float bax = v1.m_x - v0.m_x; const float bay = v1.m_y - v0.m_y; const float baz = v1.m_z - v0.m_z; const float bau = v1.m_u - v0.m_u; const float bav = v1.m_v - v0.m_v; const float cax = v2.m_x - v0.m_x; const float cay = v2.m_y - v0.m_y; const float caz = v2.m_z - v0.m_z; const float cau = v2.m_u - v0.m_u; const float cav = v2.m_v - v0.m_v; const float det = (bau * cav - bav * cau); const float invDet = 1.0f / det; const float tx = (bax * cav - cax * bav) * invDet; const float ty = (bay * cav - cay * bav) * invDet; const float tz = (baz * cav - caz * bav) * invDet; const float bx = (cax * bau - bax * cau) * invDet; const float by = (cay * bau - bay * cau) * invDet; const float bz = (caz * bau - baz * cau) * invDet; for (uint32_t jj = 0; jj < 3; ++jj) { float* tanu = &tangents[indices[jj]*6]; float* tanv = &tanu[3]; tanu[0] += tx; tanu[1] += ty; tanu[2] += tz; tanv[0] += bx; tanv[1] += by; tanv[2] += bz; } } for (uint32_t ii = 0; ii < _numVertices; ++ii) { const float* tanu = &tangents[ii*6]; const float* tanv = &tangents[ii*6 + 3]; float normal[4]; bgfx::vertexUnpack(normal, bgfx::Attrib::Normal, _decl, _vertices, ii); float ndt = vec3Dot(normal, tanu); float nxt[3]; vec3Cross(nxt, normal, tanu); float tmp[3]; tmp[0] = tanu[0] - normal[0] * ndt; tmp[1] = tanu[1] - normal[1] * ndt; tmp[2] = tanu[2] - normal[2] * ndt; float tangent[4]; vec3Norm(tangent, tmp); tangent[3] = vec3Dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f; bgfx::vertexPack(tangent, true, bgfx::Attrib::Tangent, _decl, _vertices, ii); } delete [] tangents; }
void update(float _deltaTime) { if (m_mouseDown) { int32_t deltaX = m_mouseNow.m_mx - m_mouseLast.m_mx; int32_t deltaY = m_mouseNow.m_my - m_mouseLast.m_my; m_horizontalAngle += m_mouseSpeed * float(deltaX); m_verticalAngle -= m_mouseSpeed * float(deltaY); m_mouseLast.m_mx = m_mouseNow.m_mx; m_mouseLast.m_my = m_mouseNow.m_my; } float direction[3] = { cosf(m_verticalAngle) * sinf(m_horizontalAngle), sinf(m_verticalAngle), cosf(m_verticalAngle) * cosf(m_horizontalAngle), }; float right[3] = { sinf(m_horizontalAngle - float(M_PI)/2.0f), 0, cosf(m_horizontalAngle - float(M_PI)/2.0f), }; if (m_keys & CAMERA_KEY_UP) { // m_eye += direction * _deltaTime * m_moveSpeed float tmpRhs[3]; float tmpPos[3]; memcpy(tmpPos, m_eye, sizeof(float)*3); vec3Mul(tmpRhs, direction, _deltaTime * m_moveSpeed); vec3Add(m_eye, tmpPos, tmpRhs); setKeyState(CAMERA_KEY_UP, false); } if (m_keys & CAMERA_KEY_DOWN) { // m_eye -= direction * _deltaTime * m_moveSpeed float tmpRhs[3]; float tmpPos[3]; memcpy(tmpPos, m_eye, sizeof(float)*3); vec3Mul(tmpRhs, direction, _deltaTime * m_moveSpeed); vec3Sub(m_eye, tmpPos, tmpRhs); setKeyState(CAMERA_KEY_DOWN, false); } if (m_keys & CAMERA_KEY_LEFT) { // m_eye += right * _deltaTime * m_moveSpeed float tmpRhs[3]; float tmpPos[3]; memcpy(tmpPos, m_eye, sizeof(float)*3); vec3Mul(tmpRhs, right, _deltaTime * m_moveSpeed); vec3Add(m_eye, tmpPos, tmpRhs); setKeyState(CAMERA_KEY_LEFT, false); } if (m_keys & CAMERA_KEY_RIGHT) { // m_eye -= right * _deltaTime * m_moveSpeed float tmpRhs[3]; float tmpPos[3]; memcpy(tmpPos, m_eye, sizeof(float)*3); vec3Mul(tmpRhs, right, _deltaTime * m_moveSpeed); vec3Sub(m_eye, tmpPos, tmpRhs); setKeyState(CAMERA_KEY_RIGHT, false); } vec3Add(m_at, m_eye, direction); vec3Cross(m_up, right, direction); }