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; }
// TODO: alot of slow stuff in it b32 cameraIsPointInFrustum(Camera *cam, Vec3 worldPos) { Plane frustumPlanes[6]; getFrustumPlanes(&cam->perspectiveMatrix, frustumPlanes); for(int i = 0; i < 6; i++) { Vec4 thing = vec4(frustumPlanes[i].a,frustumPlanes[i].b,frustumPlanes[i].c,0.0f); Mat4 mat = cameraCalculateInverseViewMatrix(cam); Vec4 res; mat4Vec4Mul(&res, &mat, &thing); frustumPlanes[i] = planeFromVec4(&res); } Vec3 n[6]; r32 d[6]; for(int planeId = 0; planeId < 6; planeId++) { Vec3 idk = vec3(frustumPlanes[planeId].a,frustumPlanes[planeId].b,frustumPlanes[planeId].c); n[planeId] = vec3Normalized(&idk); d[planeId] = frustumPlanes[planeId].d; } // TODO: check for all 6 planes? Vec3 pos; vec3Sub(&pos, &worldPos, &cam->position); r32 res = vec3Dot(&pos, &n[0]) + d[0] + 141.0f; r32 res2 = vec3Dot(&pos, &n[1]) + d[1] + 141.0f; if(res <= 0.f || res2 <= 0.f) return false; return true; }
//=========================================================================== // Takes Ray and Intersect data and calculates the colour of that light ray color3f Scene::getRayColor(rayData& ray, polygon* closestPoly, point3* closestPoint, float u, float v) { color3f pixCol(0.f, 0.f, 0.f); PROFILE_BEGIN(PROFILE_LIGHT) if (closestPoly) { #if LIGHTING_ENABLE color3f tmpColor; vec3Cpy(&tmpColor, &renderLight.color); vec3 displacement; vec3Sub(&displacement, &renderLight.position, closestPoint); float scale = 1.f; { #if LIGHTING_DISTANCE_BASED scale = 1/(vec3LenSq(&displacement)+1.f); #endif // LIGHTING_DISTANCE_BASED #if LIGHTING_NORMAL_BASED scale *= vec3Dot(&closestPoly->normal, &displacement); #endif // LIGHTING_NORMAL_BASED #if LIGHTING_SPECULAR_ENABLED vec3 reflection; vec3Reflect(&reflection, &displacement, &closestPoly->normal); vec3Unit(&reflection); vec3Unit(closestPoint); float specular = vec3Dot(&reflection, closestPoint); specular = (-specular * SPECULAR_BRIGHTNESS) - SPECULAR_FALLOFF; specular = fmax(0.f, specular); scale += specular; #endif // LIGHTING_SPECULAR_ENABLED } #if LIGHTING_AMBIENT_ENABLED scale += AMBIENT_BRIGHTNESS; #endif // LIGHTING_AMBIENT_ENABLED vec3Scale(&tmpColor, scale); // color3f* pColor = &closestPoly->color; color3f texColor; texture->Sample(u, v, texColor); tmpColor.x *= texColor.x; tmpColor.y *= texColor.y; tmpColor.z *= texColor.z; colorFloatTrunc(&tmpColor); pixCol = tmpColor; #else pixCol = closestPoly->color; #endif } PROFILE_END(PROFILE_LIGHT) return pixCol; }
bool IntersectFromTo(HitInfo_s &hi, float f[3], float t[3], map_s *map, unsigned int mask ) { float d[3], nd[3]; vec3Sub( d, t, f ); vec3Norm( nd, d ); return IntersectRay( hi, f, nd, sqrtf(vec3Dot(d,d)), map, mask ); }
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; }
double vec3ClosestOnSegment(GLfloat *result, const GLfloat *p, const GLfloat *a, const GLfloat *b) { GLfloat pa[3], ba[3]; vec3Sub(pa, p, a); vec3Sub(ba, b, a); double dotbaba = vec3Length2(ba); double t = 0; if (dotbaba != 0) { t = vec3Dot(pa, ba) / dotbaba; if (t < 0) t = 0; else if (t > 1) t = 1; } vec3MulScalar(ba, ba, t); vec3Add(result, a, ba); return t; }
//=========================================================================== void Scene::prepareModelRenderData(cameraData* viewCam) { matrix rotMatrix; matrixIdent(&rotMatrix); invRotMatrixFromVec3(&rotMatrix, &viewCam->dir, &viewCam->up); int newPolyIndex = 0; renderModels.clear(); renderPolygons.clear(); for (int i = 0; i < modelCount; i++) { renderModels.push_back(sceneModels[i]); model* mdl = &renderModels.back(); int newPolyCount = 0; // For every polygon in each model for (int j = 0; j < mdl->polyCount; j++) { int n = j + mdl->polyIndex; // Copy scene polygon to render polygons renderPolygons.push_back(scenePolygons[n]); polygon* poly = &renderPolygons.back(); // Transform normals to camera space matrixVec3Rot(&poly->normal, &mdl->rotation, &poly->normal); matrixVec3Rot(&poly->normal, &rotMatrix, &poly->normal); poly->normal.Normalize(); poly->point[0] = &renderVertices[poly->pointIndex[0]]; poly->point[1] = &renderVertices[poly->pointIndex[1]]; poly->point[2] = &renderVertices[poly->pointIndex[2]]; // TODO - Store points B and C as vectors from A poly->d = vec3Dot(&poly->normal, poly->point[0]); newPolyCount++; } mdl->polyIndex = newPolyIndex; mdl->polygons = renderPolygons.begin() += newPolyIndex; mdl->polyCount = newPolyCount; newPolyIndex += newPolyCount; } polyCount = newPolyIndex; }
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; }
double vec3Length2(const GLfloat *a) { return vec3Dot(a, a); }
// Calculate Surface Area float volume3::SurfaceArea() { // Assume max > min ? float w = max.x - min.x; float h = max.y - min.y; float d = max.z - min.z; return (2 * w * h) + (2 * w * d) + (2 * h * d); } //=========================================================================== // Find the point at which a ray intersects a plane, based on a poly bool intersect(polygon& __restrict poly, rayData& __restrict ray, point3& intersection, float& distance, float& u, float& v) { float B = vec3Dot(ray.direction, poly.normal); #if OPTIMIZE_USE_BACKFACE_CULLING if (B > 0.f) return false; #endif // OPTIMIZE_USE_BACKFACE_CULLING float A = vec3Dot(ray.origin, poly.normal); // Can do this test after backface cull // Find the depth of the poly from the ray origin, in terms of ray direction float depth = (poly.d - A) / B; if ((depth < 0.f) || (depth > distance)) return false; distance = depth;
memset(mtxScale, 0, sizeof(float)*16); mtxScale[0] = _scaleX; mtxScale[5] = _scaleY; mtxScale[10] = _scaleZ; mtxScale[15] = 1.0f; mtxMul(_result, mtxScale, mtxRotateTranslate); } void mtxReflected(float*__restrict _result , const float* __restrict _p /* plane */ , const float* __restrict _n /* normal */ ) { float dot = vec3Dot(_p, _n); _result[ 0] = 1.0f - 2.0f * _n[0] * _n[0]; //1-2Nx^2 _result[ 1] = -2.0f * _n[0] * _n[1]; //-2*Nx*Ny _result[ 2] = -2.0f * _n[0] * _n[2]; //-2*NxNz _result[ 3] = 0.0f; //0 _result[ 4] = -2.0f * _n[0] * _n[1]; //-2*NxNy _result[ 5] = 1.0f - 2.0f * _n[1] * _n[1]; //1-2*Ny^2 _result[ 6] = -2.0f * _n[1] * _n[2]; //-2*NyNz _result[ 7] = 0.0f; //0 _result[ 8] = -2.0f * _n[0] * _n[2]; //-2*NxNz _result[ 9] = -2.0f * _n[1] * _n[2]; //-2NyNz _result[10] = 1.0f - 2.0f * _n[2] * _n[2]; //1-2*Nz^2 _result[11] = 0.0f; //0