//=========================================================================== 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; }
// 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; }
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 ); }
// 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; }
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 spherify(Solid* s) { unsigned n = s->nVerts; Vec3 centroid = { 0,0,0 }; unsigned i; for(i=0;i<n;++i) { vec3Add(centroid,centroid,s->verts[i].loc); } vec3Mult(centroid,centroid,1.0/n); Vec3* diffs = malloc(n*sizeof(Vec3)); float* dists = malloc(n*sizeof(float)); float maxR = 0; for(i=0;i<n;++i) { vec3Sub(diffs[i],s->verts[i].loc,centroid); float r = vec3Mag(diffs[i]); dists[i] = r; if(r > maxR) { maxR = r; } } for(i=0;i<n;++i) { vec3Mult(diffs[i],diffs[i],1.0/dists[i]); vec3Copy(s->verts[i].normal,diffs[i]); vec3Mult(diffs[i],diffs[i],maxR); vec3Add(s->verts[i].loc,centroid,diffs[i]); } free(dists); free(diffs); }
//=========================================================================== // Transforms vertices + lights to Camera Space for this frame void Scene::objectToCameraSpace(cameraData* viewCam) { matrix rotMatrix; matrixIdent(&rotMatrix); invRotMatrixFromVec3(&rotMatrix, &viewCam->dir, &viewCam->up); renderVertices.clear(); for (int i = 0; i < modelCount; i++) { model* currentModel = &sceneModels[i]; for (int j = 0; j < currentModel->vertexCount; j++) { int n = currentModel->vertexIndex + j; renderVertices.push_back(sceneVertices[n]); // Transform verts from model space to world space matrixVec3Rot(&renderVertices[n], ¤tModel->rotation, &sceneVertices[n]); renderVertices[n] = renderVertices[n] + currentModel->position; // Transform verts from world space to camera space renderVertices[n] = renderVertices[n] - viewCam->position; matrixVec3Rot(&renderVertices[n], &rotMatrix, &renderVertices[n]); } } // Transform Lights from world space to camera space vec3Sub(&renderLight.position, &sceneLight.position, &viewCam->position); matrixVec3Rot(&renderLight.position, &rotMatrix, &renderLight.position); vec3Cpy(&renderLight.color, &sceneLight.color); }
static void applyForces(struct particle_system *ps, struct particle *p) { int i = 0; vec3 force; vec3 dir; float m, d, s; vec3Copy(p->dir, p->acc); do { switch(ps->forces[i].type) { case PARTICLE_FORCE_DIRECTIONAL: vec3Copy(ps->forces[i].dir, force); break; case PARTICLE_FORCE_FLUID: s = vec3Mag(p->acc); vec3Copy(p->acc, force); vec3Normalize(force, force); vec3Mul(force, -ps->forces[i].value*s*s, force); break; case PARTICLE_FORCE_ATTRACTION: vec3Sub(ps->forces[i].loc, p->loc, dir); d = vec3Mag(dir); vec3Normalize(dir, dir); m = 0.00001*ps->forces[i].value*p->mass / (d*d); vec3Mul(dir, m, force); break; } vec3Add(p->acc, force, p->acc); } while(++i < ps->nbforces); vec3Div(p->acc, p->mass, p->acc); vec3Add(p->vel, p->acc, p->vel); vec3Add(p->loc, p->vel, p->loc); }
void mtxLookAtRh(float* _result, const float* _eye, const float* _at, const float* _up) { float tmp[4]; vec3Sub(tmp, _eye, _at); float view[4]; vec3Norm(view, tmp); mtxLookAtImpl(_result, _eye, view, _up); }
//=========================================================================== // 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; }
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); }