kmVec3* kmPlaneGetIntersection(kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3) { kmVec3 n1, n2, n3, cross; kmVec3 r1, r2, r3; double denom = 0; kmVec3Fill(&n1, p1->a, p1->b, p1->c); kmVec3Fill(&n2, p2->a, p2->b, p2->c); kmVec3Fill(&n3, p3->a, p3->b, p3->c); kmVec3Cross(&cross, &n2, &n3); denom = kmVec3Dot(&n1, &cross); if (kmAlmostEqual(denom, 0.0)) { return NULL; } kmVec3Cross(&r1, &n2, &n3); kmVec3Cross(&r2, &n3, &n1); kmVec3Cross(&r3, &n1, &n2); kmVec3Scale(&r1, &r1, -p1->d); kmVec3Scale(&r2, &r2, p2->d); kmVec3Scale(&r3, &r3, p3->d); kmVec3Subtract(pOut, &r1, &r2); kmVec3Subtract(pOut, pOut, &r3); kmVec3Scale(pOut, pOut, 1.0 / denom); /*p = -d1 * ( n2.Cross ( n3 ) ) – d2 * ( n3.Cross ( n1 ) ) – d3 * ( n1.Cross ( n2 ) ) / denom;*/ return pOut; }
/** * Creates a plane from 3 points. The result is stored in pOut. * pOut is returned. */ kmPlane* const kmPlaneFromPoints(kmPlane* pOut, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3) { /* v = (B − A) × (C − A) n = 1⁄|v| v Outa = nx Outb = ny Outc = nz Outd = −n⋅A */ kmVec3 n, v1, v2; kmVec3Subtract(&v1, p2, p1); //Create the vectors for the 2 sides of the triangle kmVec3Subtract(&v2, p3, p1); kmVec3Cross(&n, &v1, &v2); //Use the cross product to get the normal kmVec3Normalize(&n, &n); //Normalize it and assign to pOut->m_N pOut->a = n.x; pOut->b = n.y; pOut->c = n.z; pOut->d = kmVec3Dot(kmVec3Scale(&n, &n, -1.0), p1); return pOut; }
kmBool kmRay3IntersectTriangle(const kmRay3* ray, const kmVec3* v0, const kmVec3* v1, const kmVec3* v2, kmVec3* intersection, kmVec3* normal, kmScalar* distance) { kmVec3 e1, e2, pvec, tvec, qvec, dir; kmScalar det, inv_det, u, v, t; kmVec3Normalize(&dir, &ray->dir); kmVec3Subtract(&e1, v1, v0); kmVec3Subtract(&e2, v2, v0); kmVec3Cross(&pvec, &dir, &e2); det = kmVec3Dot(&e1, &pvec); /* Backfacing, discard. */ if(det < kmEpsilon) { return KM_FALSE; } if(kmAlmostEqual(det, 0)) { return KM_FALSE; } inv_det = 1.0 / det; kmVec3Subtract(&tvec, &ray->start, v0); u = inv_det * kmVec3Dot(&tvec, &pvec); if(u < 0.0 || u > 1.0) { return KM_FALSE; } kmVec3Cross(&qvec, &tvec, &e1); v = inv_det * kmVec3Dot(&dir, &qvec); if(v < 0.0 || (u + v) > 1.0) { return KM_FALSE; } t = inv_det * kmVec3Dot(&e2, &qvec); if(t > kmEpsilon && (t*t) <= kmVec3LengthSq(&ray->dir)) { kmVec3 scaled; *distance = t; /* Distance */ kmVec3Cross(normal, &e1, &e2); /* Surface normal of collision */ kmVec3Normalize(normal, normal); kmVec3Normalize(&scaled, &dir); kmVec3Scale(&scaled, &scaled, *distance); kmVec3Add(intersection, &ray->start, &scaled); return KM_TRUE; } return KM_FALSE; }
/** * Reflects a vector about a given surface normal. The surface normal is * assumed to be of unit length. */ kmVec3* kmVec3Reflect(kmVec3* pOut, const kmVec3* pIn, const kmVec3* normal) { kmVec3 tmp; kmVec3Scale(&tmp, normal, 2.0f * kmVec3Dot(pIn, normal)); kmVec3Subtract(pOut, pIn, &tmp); return pOut; }
/* Added by tlensing (http://icedcoffee-framework.org)*/ kmVec3* kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2) { /* n = (Planea, Planeb, Planec) d = V − U Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0] */ kmVec3 d; /* direction from V1 to V2*/ kmScalar nt; kmScalar dt; kmScalar t; kmVec3 n; /* plane normal*/ kmVec3Subtract(&d, pV2, pV1); /* Get the direction vector*/ n.x = pP->a; n.y = pP->b; n.z = pP->c; kmVec3Normalize(&n, &n); nt = -(n.x * pV1->x + n.y * pV1->y + n.z * pV1->z + pP->d); dt = (n.x * d.x + n.y * d.y + n.z * d.z); if (fabs(dt) < kmEpsilon) { pOut = NULL; return pOut; /* line parallel or contained*/ } t = nt/dt; pOut->x = pV1->x + d.x * t; pOut->y = pV1->y + d.y * t; pOut->z = pV1->z + d.z * t; return pOut; }
kmMat3* kmMat3LookAt(kmMat3* pOut, const kmVec3* pEye, const kmVec3* pCenter, const kmVec3* pUp) { kmVec3 f, up, s, u; kmVec3Subtract(&f, pCenter, pEye); kmVec3Normalize(&f, &f); kmVec3Assign(&up, pUp); kmVec3Normalize(&up, &up); kmVec3Cross(&s, &f, &up); kmVec3Normalize(&s, &s); kmVec3Cross(&u, &s, &f); kmVec3Normalize(&s, &s); pOut->mat[0] = s.x; pOut->mat[3] = s.y; pOut->mat[6] = s.z; pOut->mat[1] = u.x; pOut->mat[4] = u.y; pOut->mat[7] = u.z; pOut->mat[2] = -f.x; pOut->mat[5] = -f.y; pOut->mat[8] = -f.z; return pOut; }
kmQuaternion *sls_trackball_calc_quat(kmQuaternion *out, float trackball_radius, float trackball_speed, kmVec2 const *p1, kmVec2 const *p2) { //sls_log_info("p1 %f %f, p2 %f %f", p1->x, p1->y, p2->x, p2->y); kmVec3 axis; kmVec3 _p1, _p2, dir; float phi; float t; float epsilon = 0.001; if (sls_vec2_near(p1, p2, epsilon)) { // zero rotation kmQuaternionIdentity(out); return out; } _p1 = (kmVec3){p1->x, p1->y, sls_tb_project_to_sphere(trackball_radius, p1)}; _p2 = (kmVec3){p2->x, p2->y, sls_tb_project_to_sphere(trackball_radius, p2)}; kmVec3Subtract(&dir, &_p1, &_p2); kmVec3Cross(&axis, &_p2, &_p1); t = kmVec3Length(&dir) / (2.0f * trackball_radius); t = fminf(fmaxf(-1.f, t), 1.f); phi = 2.0f * asinf(t) * trackball_speed; kmQuaternion tmp_a, tmp_b; kmQuaternionRotationAxisAngle(&tmp_a, &axis, phi); tmp_b = *out; return kmQuaternionMultiply(out, &tmp_a, &tmp_b); ; }
kmVec3* const kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2) { /* n = (Planea, Planeb, Planec) d = V − U Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0] */ kmVec3 d; assert(0 && "Not implemented"); kmVec3Subtract(&d, pV2, pV1); //Get the direction vector //TODO: Continue here! /*if (fabs(kmVec3Dot(&pP->m_N, &d)) > kmEpsilon) { //If we get here then the plane and line are parallel (i.e. no intersection) pOut = nullptr; //Set to nullptr return pOut; } */ return NULL; }
std::vector<LightID> NullPartitioner::lights_within_range(const kmVec3& location) { std::vector<std::pair<LightID, float> > lights_in_range; //Find all the lights within range of the location for(LightID light_id: all_lights_) { Light& light = scene().light(light_id); kmVec3 diff; kmVec3Subtract(&diff, &location, &light.position()); float dist = kmVec3Length(&diff); //if(dist < light.range()) { lights_in_range.push_back(std::make_pair(light_id, dist)); //} } //Sort them by distance std::sort(lights_in_range.begin(), lights_in_range.end(), [](std::pair<LightID, float> lhs, std::pair<LightID, float> rhs) { return lhs.second < rhs.second; }); //Return the LightIDs only std::vector<LightID> result; for(std::pair<LightID, float> p: lights_in_range) { result.push_back(p.first); } return result; }
void kmVec3OrthoNormalize(kmVec3* normal, kmVec3* tangent) { kmVec3 proj; kmVec3Normalize(normal, normal); kmVec3Scale(&proj, normal, kmVec3Dot(tangent, normal)); kmVec3Subtract(tangent, tangent, &proj); kmVec3Normalize(tangent, tangent); }
void BoundingBox::getCenter(kmVec3* dst) const { GP_ASSERT(dst); kmVec3Subtract(dst, &max, &min); //dst->set(min, max); //dst->scale(0.5f); kmVec3Scale(dst, dst, 0.5f); //dst->add(min); kmVec3Add(dst, dst, &min); return; }
void ViewTransform::LazyAdjust() const { if(!_dirty) return; kmVec3Subtract(&_adjustDir, &_focus, &_position); kmVec3Normalize(&_adjustDir, &_adjustDir); kmVec3Cross(&_adjustRight, &_adjustDir, &_up); kmVec3Normalize(&_adjustRight, &_adjustRight); kmVec3Cross(&_adjustUp, &_adjustRight, &_adjustDir); kmVec3Normalize(&_adjustUp, &_adjustUp); _dirty = false; }
/* \brief cast a ray from camera at specified relative coordinate */ GLHCKAPI kmRay3* glhckCameraCastRayFromPoint(glhckCamera *object, kmRay3 *pOut, const kmVec2 *point) { CALL(2, "%p, "VEC2S, pOut, VEC2(point)); glhckFrustum *frustum = glhckCameraGetFrustum(object); kmVec3 nu, nv, fu, fv; kmVec3Subtract(&nu, &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_RIGHT], &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_LEFT]); kmVec3Subtract(&nv, &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_TOP_LEFT], &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_LEFT]); kmVec3Subtract(&fu, &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_RIGHT], &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_LEFT]); kmVec3Subtract(&fv, &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_TOP_LEFT], &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_LEFT]); kmVec3Scale(&nu, &nu, point->x); kmVec3Scale(&nv, &nv, point->y); kmVec3Scale(&fu, &fu, point->x); kmVec3Scale(&fv, &fv, point->y); pOut->start = frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_LEFT]; pOut->dir = frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_LEFT]; kmVec3Add(&pOut->start, &pOut->start, &nu); kmVec3Add(&pOut->start, &pOut->start, &nv); kmVec3Add(&pOut->dir, &pOut->dir, &fu); kmVec3Add(&pOut->dir, &pOut->dir, &fv); kmVec3Subtract(&pOut->dir, &pOut->dir, &pOut->start); RET(2, "%p", pOut); return pOut; }
/* Target camera */ void dlTargetCamera( dlCamera *object, kmVec3 *target ) { kmVec3 toTarget; CALL("%p, vec3[%f, %f, %f]", object, target->x, target->y, target->z); if(!object) return; object->target = *target; kmVec3Subtract( &toTarget, &object->target, &object->translation ); /* update rotation */ kmVec3GetHorizontalAngle( &object->rotation, &toTarget ); object->transform_changed = 1; }
/** * Builds a translation matrix in the same way as gluLookAt() * the resulting matrix is stored in pOut. pOut is returned. */ kmMat4* const kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye, const kmVec3* pCenter, const kmVec3* pUp) { kmVec3 f, up, s, u; kmMat4 translate; kmVec3Subtract(&f, pCenter, pEye); kmVec3Normalize(&f, &f); kmVec3Assign(&up, pUp); kmVec3Normalize(&up, &up); kmVec3Cross(&s, &f, &up); kmVec3Normalize(&s, &s); kmVec3Cross(&u, &s, &f); kmVec3Normalize(&s, &s); kmMat4Identity(pOut); pOut->mat[0] = s.x; pOut->mat[4] = s.y; pOut->mat[8] = s.z; pOut->mat[1] = u.x; pOut->mat[5] = u.y; pOut->mat[9] = u.z; pOut->mat[2] = -f.x; pOut->mat[6] = -f.y; pOut->mat[10] = -f.z; kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z); kmMat4Multiply(pOut, pOut, &translate); return pOut; }
/** * Builds a translation matrix in the same way as gluLookAt() * the resulting matrix is stored in pOut. pOut is returned. */ kmMat4* kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye, const kmVec3* pCenter, const kmVec3* pUp) { kmVec3 f; kmVec3 s; kmVec3 u; kmVec3Subtract(&f, pCenter, pEye); kmVec3Normalize(&f, &f); kmVec3Cross(&s, &f, pUp); kmVec3Normalize(&s, &s); kmVec3Cross(&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] = -kmVec3Dot(&s, pEye); pOut->mat[13] = -kmVec3Dot(&u, pEye); pOut->mat[14] = kmVec3Dot(&f, pEye); pOut->mat[15] = 1.0; return pOut; }
/* \brief calculate projection matrix */ static void _glhckCameraProjectionMatrix(glhckCamera *object) { kmScalar w, h, distanceFromTarget; kmVec3 toTarget; CALL(2, "%p", object); assert(object); assert(object->view.viewport.w > 0.0f && object->view.viewport.h > 0.0f); switch(object->view.projectionType) { case GLHCK_PROJECTION_ORTHOGRAPHIC: w = object->view.viewport.w > object->view.viewport.h ? 1 : object->view.viewport.w / object->view.viewport.h; h = object->view.viewport.w < object->view.viewport.h ? 1 : object->view.viewport.h / object->view.viewport.w; kmVec3Subtract(&toTarget, &object->object->view.translation, &object->object->view.target); distanceFromTarget = kmVec3Length(&toTarget); w *= (distanceFromTarget+object->view.near)/2; h *= (distanceFromTarget+object->view.near)/2; kmMat4OrthographicProjection(&object->view.projection, -w, w, -h, h, object->view.near, object->view.far); break; case GLHCK_PROJECTION_PERSPECTIVE: default: kmMat4PerspectiveProjection( &object->view.projection, object->view.fov, (float)object->view.viewport.w/(float)object->view.viewport.h, object->view.near, object->view.far); break; } }
/* Calculate view matrix */ static void dlCameraCalculateViewMatrix( dlCamera *object ) { kmVec3 tgtv, upvector; kmScalar dp; CALL("%p", object); kmVec3Subtract( &tgtv, &object->target, &object->translation ); kmVec3Normalize( &tgtv, &tgtv ); kmVec3Normalize( &upvector, &object->upVector ); dp = kmVec3Dot( &tgtv, &upvector ); if( dp == 1.f ) { upvector.x += 0.5f; } kmMat4LookAt( &object->view, &object->translation, &object->target, &upvector ); /* Frustum recalculation here */ kmMat4Multiply( &object->matrix, &object->projection, &object->view ); }
void Frustum::setupProjectionPerspective(const ViewTransform& view, float left, float right, float top, float bottom, float nearPlane, float farPlane) { kmVec3 cc = view.getPosition(); kmVec3 cDir = view.getDirection(); kmVec3 cRight = view.getRight(); kmVec3 cUp = view.getUp(); kmVec3Normalize(&cDir, &cDir); kmVec3Normalize(&cRight, &cRight); kmVec3Normalize(&cUp, &cUp); kmVec3 nearCenter; kmVec3 farCenter; kmVec3Scale(&nearCenter, &cDir, nearPlane); kmVec3Add(&nearCenter, &nearCenter, &cc); kmVec3Scale(&farCenter, &cDir, farPlane); kmVec3Add(&farCenter, &farCenter, &cc); //near { kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &nearCenter, &cDir); } //far { kmVec3 normal; kmVec3Scale(&normal, &cDir, -1); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &farCenter, &normal); } //left { kmVec3 point; kmVec3Scale(&point, &cRight, left); kmVec3Add(&point, &point, &nearCenter); kmVec3 normal; kmVec3Subtract(&normal, &point, &cc); kmVec3Cross(&normal, &normal, &cUp); kmVec3Normalize(&normal, &normal); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal); } //right { kmVec3 point; kmVec3Scale(&point, &cRight, right); kmVec3Add(&point, &point, &nearCenter); kmVec3 normal; kmVec3Subtract(&normal, &point, &cc); kmVec3Cross(&normal, &cUp, &normal); kmVec3Normalize(&normal, &normal); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal); } //bottom { kmVec3 point; kmVec3Scale(&point, &cUp, bottom); kmVec3Add(&point, &point, &nearCenter); kmVec3 normal; kmVec3Subtract(&normal, &point, &cc); kmVec3Cross(&normal, &cRight, &normal); kmVec3Normalize(&normal, &normal); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal); } //top { kmVec3 point; kmVec3Scale(&point, &cUp, top); kmVec3Add(&point, &point, &nearCenter); kmVec3 normal; kmVec3Subtract(&normal, &point, &cc); kmVec3Cross(&normal, &normal, &cRight); kmVec3Normalize(&normal, &normal); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal); } }
void CComponentGraphic_GL::DrawDependencyLine( float /*cellSize*/, const CDependencyDescription* pDependency ) { CreateMaterials(); CQuadBatchRenderGroup *renderGroup = dynamic_cast<CQuadBatchRenderGroup *>( CRenderGroupManager::GetInstance()->GetRenderGroup(CRenderGroupManager::LAYER_GUI)); BEATS_ASSERT(renderGroup); BEATS_ASSERT(pDependency != NULL); if (pDependency->IsVisible()) { size_t uDependencyLineCount = pDependency->GetDependencyLineCount(); for (size_t i = 0; i < uDependencyLineCount; ++i) { CDependencyDescriptionLine* pDependencyLine = pDependency->GetDependencyLine(i); const SVertex* pData = pDependencyLine->GetRectArray(); static const size_t SVERTEX_SIZE = 24; CSerializer serializer(SVERTEX_SIZE * 4, (void*)pData); DWORD tmpColor = 0; CQuadPTC dependencyLine; serializer >> dependencyLine.br.position.x; serializer >> dependencyLine.br.position.y; serializer >> dependencyLine.br.position.z; serializer >> tmpColor; serializer >> dependencyLine.br.tex.u; serializer >> dependencyLine.br.tex.v; serializer >> dependencyLine.bl.position.x; serializer >> dependencyLine.bl.position.y; serializer >> dependencyLine.bl.position.z; serializer >> tmpColor; serializer >> dependencyLine.bl.tex.u; serializer >> dependencyLine.bl.tex.v; serializer >> dependencyLine.tr.position.x; serializer >> dependencyLine.tr.position.y; serializer >> dependencyLine.tr.position.z; serializer >> tmpColor; serializer >> dependencyLine.tr.tex.u; serializer >> dependencyLine.tr.tex.v; serializer >> dependencyLine.tl.position.x; serializer >> dependencyLine.tl.position.y; serializer >> dependencyLine.tl.position.z; serializer >> tmpColor; serializer >> dependencyLine.tl.tex.u; serializer >> dependencyLine.tl.tex.v; renderGroup->AddQuad(dependencyLine, m_pMaterials[pDependencyLine->IsSelected() ? eCT_SelectedLine : eCT_NormalLine]); const SVertex* pArrowData = pDependencyLine->GetArrowRectArray(); CSerializer serializerArrow(SVERTEX_SIZE * 4, (void*)pArrowData); CQuadPTC arrow; serializerArrow >> arrow.br.position.x; serializerArrow >> arrow.br.position.y; serializerArrow >> arrow.br.position.z; serializerArrow >> tmpColor; serializerArrow >> arrow.br.tex.u; serializerArrow >> arrow.br.tex.v; serializerArrow >> arrow.bl.position.x; serializerArrow >> arrow.bl.position.y; serializerArrow >> arrow.bl.position.z; serializerArrow >> tmpColor; serializerArrow >> arrow.bl.tex.u; serializerArrow >> arrow.bl.tex.v; serializerArrow >> arrow.tr.position.x; serializerArrow >> arrow.tr.position.y; serializerArrow >> arrow.tr.position.z; serializerArrow >> tmpColor; serializerArrow >> arrow.tr.tex.u; serializerArrow >> arrow.tr.tex.v; serializerArrow >> arrow.tl.position.x; serializerArrow >> arrow.tl.position.y; serializerArrow >> arrow.tl.position.z; serializerArrow >> tmpColor; serializerArrow >> arrow.tl.tex.u; serializerArrow >> arrow.tl.tex.v; renderGroup->AddQuad(arrow, m_pMaterials[pDependencyLine->IsSelected() ? eCT_SelectedArrow : eCT_NormalArrow]); //Render index number for dependency list. if (pDependency->IsListType()) { kmVec3 deltaDirection; kmVec3Subtract(&deltaDirection, &dependencyLine.tr.position, &dependencyLine.tl.position); float fXPos = (dependencyLine.tl.position.x + deltaDirection.x * 0.15f); static const float fHardCodeOffset = 8; float fYPos = (dependencyLine.tl.position.y + deltaDirection.y * 0.15f - fHardCodeOffset); TCHAR szIndex[8]; _stprintf(szIndex, _T("%d"), pDependencyLine->GetIndex()); m_pFont->RenderText(szIndex, fXPos, fYPos, 0xffff00ff); } } }
int process_inputs() { // Get mouse position double xpos, ypos; glfwGetCursorPos(mainWindow, &xpos, &ypos); // Reset mouse position for next frame glfwSetCursorPos(mainWindow, SCREEN_WIDTH/2, SCREEN_HEIGHT/2); // Compute new orientation horizontalAngle += mouseSpeed * (float)( SCREEN_WIDTH/2 - xpos ); verticalAngle += mouseSpeed * (float)( SCREEN_HEIGHT/2 - ypos ); /* If F1, reload */ if (glfwGetKey(mainWindow, GLFW_KEY_F1)) { Engine_Reload(); } /* If F2, reset view */ if (glfwGetKey(mainWindow, GLFW_KEY_F2)) { printf("Camera reset.\n"); Camera_Reset(); } /* If tab, change lookat to next mesh */ if (glfwGetKey(mainWindow, GLFW_KEY_TAB)) { //Camera_LookAtNext(); } /* Move closer */ //if (glfwGetKey(mainWindow, GLFW_KEY_W)) { // ypos = 100; //} /* Move further */ //if (glfwGetKey(mainWindow, GLFW_KEY_S)) { // ypos = -100; //} /* Move left */ //if (glfwGetKey(mainWindow, GLFW_KEY_A)) { // xpos = 100; //} /* Move right */ //if (glfwGetKey(mainWindow, GLFW_KEY_D)) { // xpos = -100; //} // Compute new orientation //horizontalAngle += mouseSpeed * (float)(1024/2 - xpos ); //verticalAngle += mouseSpeed * (float)( 768/2 - ypos ); horizontalAngle += mouseSpeed * xpos; verticalAngle += mouseSpeed * ypos; //printf("horizontalAngle is %f, and verticalAngle is %f.\n", horizontalAngle, verticalAngle); // Direction : Spherical coordinates to Cartesian coordinates conversion float temp1 = cos(verticalAngle) * sin(horizontalAngle); float temp2 = sin(verticalAngle); float temp3 = cos(verticalAngle) * cos(horizontalAngle); kmVec3 direction = {temp1, temp2, temp3}; // Right vector kmVec3 right = { sin(horizontalAngle - 3.14f/2.0f), 0, cos(horizontalAngle - 3.14f/2.0f) }; // Up vector kmVec3 up = *kmVec3Cross(&up, &right, &direction ); // Move forward if (glfwGetKey( mainWindow, GLFW_KEY_UP ) == GLFW_PRESS){ kmVec3Add(&position, &position, kmVec3Scale(&position, &direction, deltaTime * speed)); } // Move backward if (glfwGetKey( mainWindow, GLFW_KEY_DOWN ) == GLFW_PRESS){ kmVec3Subtract(&position, &position, kmVec3Scale(&position, &direction, deltaTime * speed)); } // Strafe right if (glfwGetKey( mainWindow, GLFW_KEY_RIGHT ) == GLFW_PRESS){ kmVec3Add(&position, &position, kmVec3Scale(&position, &right, deltaTime * speed)); } // Strafe left if (glfwGetKey( mainWindow, GLFW_KEY_LEFT ) == GLFW_PRESS){ kmVec3Subtract(&position, &position, kmVec3Scale(&position, &right, deltaTime * speed)); } float FoV = initialFoV; kmMat4PerspectiveProjection(&ProjectionMatrix, FoV, (16.0f / 8.0f), 0.1f, 100.0f); // Camera matrix //ViewMatrix = glm::lookAt( // position, // Camera is here // position+direction, // and looks here : at the same position, plus "direction" // up // Head is up (set to 0,-1,0 to look upside-down) // ); kmVec3 p_eye; p_eye = position; kmVec3 p_ctr; p_ctr = *kmVec3Add(&p_ctr, &position, &direction); kmVec3 p_up; p_up = up; kmMat4LookAt(&ViewMatrix, &p_eye, &p_ctr, &p_up); kmMat4Identity(&ModelMatrix); kmMat4 temp_mat; kmMat4Multiply(&temp_mat, &ViewMatrix, &ModelMatrix); kmMat4Multiply(&MVP, &ProjectionMatrix, &temp_mat ); //printf("Matrix contains:\n"); //printf("%f, %f, %f, %f\n", MVP.mat[0], MVP.mat[1], MVP.mat[2], MVP.mat[3]); //printf("%f, %f, %f, %f\n", MVP.mat[4], MVP.mat[5], MVP.mat[6], MVP.mat[7]); //printf("%f, %f, %f, %f\n", MVP.mat[8], MVP.mat[9], MVP.mat[10], MVP.mat[11]); //printf("%f, %f, %f, %f\n", MVP.mat[12], MVP.mat[13], MVP.mat[14], MVP.mat[15]); return 0; }
int main() { lightDir.x=0.5; lightDir.y=.7; lightDir.z=-0.5; kmVec3Normalize(&lightDir,&lightDir); // creates a window and GLES context // create a window and GLES context if (!glfwInit()) exit(EXIT_FAILURE); window = glfwCreateWindow(width, height, "I N V A D E R S ! ! !", NULL, NULL); if (!window) { glfwTerminate(); exit(EXIT_FAILURE); } glfwSetWindowSizeCallback(window,window_size_callback); glfwMakeContextCurrent(window); // all the shaders have at least texture unit 0 active so // activate it now and leave it active glActiveTexture(GL_TEXTURE0); // The obj shapes and their textures are loaded cubeTex = loadPNG("resources/textures/dice.png"); loadObj(&cubeObj, "resources/models/cube.gbo", "resources/shaders/textured.vert", "resources/shaders/textured.frag"); shipTex = loadPNG("resources/textures/shipv2.png"); loadObjCopyShader(&shipObj,"resources/models/ship.gbo",&cubeObj); alienTex = loadPNG("resources/textures/alien.png"); loadObjCopyShader(&alienObj, "resources/models/alien.gbo", &cubeObj); shotTex = loadPNG("resources/textures/shot.png"); loadObjCopyShader(&shotObj, "resources/models/shot.gbo", &cubeObj); expTex = loadPNG("resources/textures/explosion.png"); playerPos.x = 0; playerPos.y = 0; playerPos.z = 0; kmMat4Identity(&view); pEye.x = 0; pEye.y = 2; pEye.z = 4; pCenter.x = 0; pCenter.y = 0; pCenter.z = -5; pUp.x = 0; pUp.y = 1; pUp.z = 0; kmMat4LookAt(&view, &pEye, &pCenter, &pUp); // projection matrix, as distance increases // the way the model is drawn is effected kmMat4Identity(&projection); kmMat4PerspectiveProjection(&projection, 45, (float)width/ height, 0.1, 1000); glViewport(0, 0, width,height); // these two matrices are pre combined for use with each model render kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); // initialises glprint's matrix shader and texture initGlPrint(width,height); font1=createFont("resources/textures/font.png",0,256,16,16,16); font2=createFont("resources/textures/bigfont.png",32,512,9.5,32,48); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); // only used by glprintf glEnable(GL_DEPTH_TEST); int num_frames = 0; bool quit = false; resetAliens(); for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { playerShots[n].alive = false; } initPointClouds("resources/shaders/particle.vert", "resources/shaders/particle.frag",(float)width/24.0); for (int n = 0; n < MAX_ALIENS; n++) { aliens[n].explosion=createPointCloud(40); resetExposion(aliens[n].explosion); // sets initials positions } glClearColor(0, .5, 1, 1); while (!quit) { // the main loop clock_gettime(0,&ts); // note the time BEFORE we start to render the current frame glfwPollEvents(); if (glfwGetKey(window,GLFW_KEY_ESCAPE)==GLFW_PRESS || glfwWindowShouldClose(window)) quit = true; float rad; // radians rotation based on frame counter glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); frame++; rad = frame * (0.0175f * 2); //kmMat4Identity(&model); kmMat4Translation(&model, playerPos.x, playerPos.y, playerPos.z); playerCroll += (PIDcal(playerRoll, playerCroll, &playerPre_error, &playerIntegral) / 2); // kmMat4RotationPitchYawRoll(&model, 0, 3.1416, playerCroll * 3); // kmMat4RotationYawPitchRoll(&rot,0,3.1416,-playerCroll*3); kmMat4Multiply(&model, &model, &rot); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shipTex); drawObj(&shipObj, &mvp, &mv, lightDir, viewDir); glPrintf(50 + sinf(rad) * 16, 240 + cosf(rad) * 16, font2,"frame=%i", frame); kmVec3 tmp; playerFireCount--; if (glfwGetKey(window,GLFW_KEY_LEFT_CONTROL)==GLFW_PRESS && playerFireCount < 0) { struct playerShot_t *freeShot; freeShot = getFreeShot(); if (freeShot != 0) { playerFireCount = 15; freeShot->alive = true; kmVec3Assign(&freeShot->pos, &playerPos); } } for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { if (playerShots[n].alive) { playerShots[n].pos.z -= .08; if (playerShots[n].pos.z < -10) playerShots[n].alive = false; //kmMat4Identity(&model); kmMat4Translation(&model, playerShots[n].pos.x, playerShots[n].pos.y, playerShots[n].pos.z); //kmMat4RotationPitchYawRoll(&model, rad * 4, 0, // -rad * 4); kmMat4RotationYawPitchRoll(&rot,rad*4,0,-rad*4); kmMat4Multiply(&model,&model,&rot); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shotTex); drawObj(&shotObj, &mvp, &mv, lightDir, viewDir); } } playerRoll = 0; if (glfwGetKey(window,GLFW_KEY_LEFT)==GLFW_PRESS && playerPos.x > -10) { playerPos.x -= 0.1; playerRoll = .2; } if (glfwGetKey(window,GLFW_KEY_RIGHT)==GLFW_PRESS && playerPos.x < 10) { playerPos.x += 0.1; playerRoll = -.2; } pEye.x = playerPos.x * 1.25; pCenter.x = playerPos.x; pCenter.y = playerPos.y + 1; pCenter.z = playerPos.z; int deadAliens; deadAliens = 0; for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].alive == true) { //kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); //kmMat4RotationPitchYawRoll(&model, -.4, 0, 0); kmMat4RotationYawPitchRoll(&rot,.2,0,0); kmMat4Multiply(&model,&model,&rot); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, alienTex); drawObj(&alienObj, &mvp, &mv, lightDir, viewDir); kmVec3 d; for (int i = 0; i < MAX_PLAYER_SHOTS; i++) { kmVec3Subtract(&d, &aliens[n].pos, &playerShots[i].pos); if (kmVec3Length(&d) < .7 && playerShots[i].alive) { aliens[n].alive = false; playerShots[i].alive = false; aliens[n].exploding = true; resetExposion(aliens[n].explosion); } } } if (aliens[n].alive != true && aliens[n].exploding != true) { deadAliens++; } } if (deadAliens == MAX_ALIENS) { resetAliens(); } // draw explosions after ALL aliens for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].exploding==true) { kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); glBindTexture(GL_TEXTURE_2D, expTex); drawPointCloud(aliens[n].explosion, &mvp); aliens[n].explosion->tick=aliens[n].explosion->tick+0.05; if (aliens[n].explosion->tick>1.25) { aliens[n].exploding=false; } else { // update the explosion for (int i=0; i<aliens[n].explosion->totalPoints; i++) { float t; t=aliens[n].explosion->tick; if (i>aliens[n].explosion->totalPoints/2) t=t/2.0; aliens[n].explosion->pos[i*3]=aliens[n].explosion->vel[i*3] * t; aliens[n].explosion->pos[i*3+1]=aliens[n].explosion->vel[i*3+1] * t; aliens[n].explosion->pos[i*3+2]=aliens[n].explosion->vel[i*3+2] * t; } } } } // move camera kmMat4LookAt(&view, &pEye, &pCenter, &pUp); kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); kmVec3Subtract(&viewDir,&pEye,&pCenter); kmVec3Normalize(&viewDir,&viewDir); // dump values glPrintf(100, 280, font1,"eye %3.2f %3.2f %3.2f ", pEye.x, pEye.y, pEye.z); glPrintf(100, 296, font1,"centre %3.2f %3.2f %3.2f ", pCenter.x, pCenter.y, pCenter.z); glPrintf(100, 340, font1,"frame %i %i ", frame, frame % 20); glfwSwapBuffers(window); ts.tv_nsec+=20000000; // 1000000000 / 50 = 50hz less time to render the frame //thrd_sleep(&ts,NULL); // tinycthread usleep(20000); // while I work out why tinycthread that was working isnt.... :/ } glfwDestroyWindow(window); glfwTerminate(); return 0; }
int main() { lightDir.x=0.5; lightDir.y=.7; lightDir.z=-0.5; kmVec3Normalize(&lightDir,&lightDir); // creates a window and GLES context if (makeContext() != 0) exit(-1); // all the shaders have at least texture unit 0 active so // activate it now and leave it active glActiveTexture(GL_TEXTURE0); // The obj shapes and their textures are loaded cubeTex = loadPNG("resources/textures/dice.png"); loadObj(&cubeObj, "resources/models/cube.gbo", "resources/shaders/textured.vert", "resources/shaders/textured.frag"); shipTex = loadPNG("resources/textures/shipv2.png"); loadObjCopyShader(&shipObj,"resources/models/ship.gbo",&cubeObj); alienTex = loadPNG("resources/textures/alien.png"); loadObjCopyShader(&alienObj, "resources/models/alien.gbo", &cubeObj); shotTex = loadPNG("resources/textures/shot.png"); loadObjCopyShader(&shotObj, "resources/models/shot.gbo", &cubeObj); expTex = loadPNG("resources/textures/explosion.png"); playerPos.x = 0; playerPos.y = 0; playerPos.z = 0; kmMat4Identity(&view); pEye.x = 0; pEye.y = 2; pEye.z = 4; pCenter.x = 0; pCenter.y = 0; pCenter.z = -5; pUp.x = 0; pUp.y = 1; pUp.z = 0; kmMat4LookAt(&view, &pEye, &pCenter, &pUp); // projection matrix, as distance increases // the way the model is drawn is effected kmMat4Identity(&projection); kmMat4PerspectiveProjection(&projection, 45, (float)getDisplayWidth() / getDisplayHeight(), 0.1, 100); glViewport(0, 0, getDisplayWidth(), getDisplayHeight()); // these two matrices are pre combined for use with each model render kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); // initialises glprint's matrix shader and texture initGlPrint(getDisplayWidth(), getDisplayHeight()); font1=createFont("resources/textures/font.png",0,256,16,16,16); font2=createFont("resources/textures/bigfont.png",32,512,9.5,32,48); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); // only used by glprintf glEnable(GL_DEPTH_TEST); struct timeval t, ta, t1, t2; // fps stuff gettimeofday(&t1, NULL); int num_frames = 0; bool quit = false; mouse = getMouse(); keys = getKeys(); resetAliens(); for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { playerShots[n].alive = false; } initPointClouds("resources/shaders/particle.vert", "resources/shaders/particle.frag",(float)getDisplayWidth()/24.0); for (int n = 0; n < MAX_ALIENS; n++) { aliens[n].explosion=createPointCloud(40); resetExposion(aliens[n].explosion); // sets initials positions } while (!quit) { // the main loop doEvents(); // update mouse and key arrays // mask of 4 is right mouse if (keys[KEY_ESC]) quit = true; glClearColor(0, .5, 1, 1); // render between two gettimeofday calls so // we can sleep long enough to roughly sync // to ~60fps but not on the pi! // TODO find something a tad more elegent long i; gettimeofday(&t, NULL); i = t.tv_sec * 1e6 + t.tv_usec; // render(); float rad; // radians rotation based on frame counter glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); frame++; rad = frame * (0.0175f * 2); kmMat4Identity(&model); kmMat4Translation(&model, playerPos.x, playerPos.y, playerPos.z); playerCroll += (PIDcal(playerRoll, playerCroll, &playerPre_error, &playerIntegral) / 2); kmMat4RotationPitchYawRoll(&model, 0, 3.1416, playerCroll * 3); // kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shipTex); drawObj(&shipObj, &mvp, &mv, lightDir, viewDir); glPrintf(50 + sinf(rad) * 16, 240 + cosf(rad) * 16, font2,"frame=%i fps=%3.2f", frame, lfps); kmVec3 tmp; playerFireCount--; if (keys[KEY_LCTRL] && playerFireCount < 0) { struct playerShot_t *freeShot; freeShot = getFreeShot(); if (freeShot != 0) { playerFireCount = 15; freeShot->alive = true; kmVec3Assign(&freeShot->pos, &playerPos); } } for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { if (playerShots[n].alive) { playerShots[n].pos.z -= .08; if (playerShots[n].pos.z < -10) playerShots[n].alive = false; kmMat4Identity(&model); kmMat4Translation(&model, playerShots[n].pos.x, playerShots[n].pos.y, playerShots[n].pos.z); kmMat4RotationPitchYawRoll(&model, rad * 4, 0, -rad * 4); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shotTex); drawObj(&shotObj, &mvp, &mv, lightDir, viewDir); } } playerRoll = 0; if (keys[KEY_CURSL] && playerPos.x > -10) { playerPos.x -= 0.1; playerRoll = .2; } if (keys[KEY_CURSR] && playerPos.x < 10) { playerPos.x += 0.1; playerRoll = -.2; } pEye.x = playerPos.x * 1.25; pCenter.x = playerPos.x; pCenter.y = playerPos.y + 1; pCenter.z = playerPos.z; int deadAliens; deadAliens = 0; for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].alive == true) { kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); kmMat4RotationPitchYawRoll(&model, -.4, 0, 0); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, alienTex); drawObj(&alienObj, &mvp, &mv, lightDir, viewDir); kmVec3 d; for (int i = 0; i < MAX_PLAYER_SHOTS; i++) { kmVec3Subtract(&d, &aliens[n].pos, &playerShots[i].pos); if (kmVec3Length(&d) < .7 && playerShots[i].alive) { aliens[n].alive = false; playerShots[i].alive = false; aliens[n].exploding = true; resetExposion(aliens[n].explosion); } } } if (aliens[n].alive != true && aliens[n].exploding != true) { deadAliens++; } } if (deadAliens == MAX_ALIENS) { resetAliens(); } // draw explosions after ALL aliens for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].exploding==true) { kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); glBindTexture(GL_TEXTURE_2D, expTex); drawPointCloud(aliens[n].explosion, &mvp); aliens[n].explosion->tick=aliens[n].explosion->tick+0.05; if (aliens[n].explosion->tick>1.25) { aliens[n].exploding=false; } else { // update the explosion for (int i=0; i<aliens[n].explosion->totalPoints; i++) { float t; t=aliens[n].explosion->tick; if (i>aliens[n].explosion->totalPoints/2) t=t/2.0; aliens[n].explosion->pos[i*3]=aliens[n].explosion->vel[i*3] * t; aliens[n].explosion->pos[i*3+1]=aliens[n].explosion->vel[i*3+1] * t; aliens[n].explosion->pos[i*3+2]=aliens[n].explosion->vel[i*3+2] * t; } } } } // move camera kmMat4LookAt(&view, &pEye, &pCenter, &pUp); kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); kmVec3Subtract(&viewDir,&pEye,&pCenter); kmVec3Normalize(&viewDir,&viewDir); // dump values glPrintf(100, 280, font1,"eye %3.2f %3.2f %3.2f ", pEye.x, pEye.y, pEye.z); glPrintf(100, 296, font1,"centre %3.2f %3.2f %3.2f ", pCenter.x, pCenter.y, pCenter.z); glPrintf(100, 320, font1,"mouse %i,%i %i ", mouse[0], mouse[1], mouse[2]); glPrintf(100, 340, font1,"frame %i %i ", frame, frame % 20); swapBuffers(); gettimeofday(&ta, NULL); long j = (ta.tv_sec * 1e6 + ta.tv_usec); i = j - i; if (i < 0) i = 1000000; // pass through - slower that 60fps if (i < 16000) usleep(16000 - i); // every 10 frames average the time taken and store // fps value for later printing with glprintf if (++num_frames % 10 == 0) { gettimeofday(&t2, NULL); float dtf = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) * 1e-6; lfps = num_frames / dtf; num_frames = 0; t1 = t2; } } closeContext(); return 0; }