void BoundingBox::set(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { //min.set(minX, minY, minZ); kmVec3Fill(&min, minX, minY, minZ); //max.set(maxX, maxY, maxZ); kmVec3Fill( &max, maxX, maxY, maxZ ); }
CCSprite3D::CCSprite3D() : m_pModel(NULL) , m_modelRotation(0.0f) { kmVec3Fill(&m_modelPosition, 0, 0, 0); kmVec3Fill(&m_modelScale, 1.0f, 1.0f, 1.0f); }
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; }
CCSprite3D::CCSprite3D() : m_pModel(NULL) , m_modelRotation(0.0f) { kmVec3Fill(&m_modelPosition, 0, 0, 0); kmVec3Fill(&m_modelScale, 1.0f, 1.0f, 1.0f); mCustSkin = CCTextureCache::sharedTextureCache()->addImage("images/main.png"); mCustSkin->retain(); }
NS_CC_BEGIN ViewTransform::ViewTransform() { kmVec3Fill(&_position,0,0,0); kmVec3Fill(&_focus,0,0,-1); kmVec3Fill(&_up,0,1,0); _dirty = true; kmMat4Identity(&_matrix); }
void EGLView::setProjection(ccDirectorProjection kProjection) { CCSize size = m_obDesignResolutionSize; setViewPortInPoints(0, 0, m_obDesignResolutionSize.width, m_obDesignResolutionSize.height); switch (kProjection) { case kCCDirectorProjection2D: { kmGLMatrixMode(KM_GL_PROJECTION); kmGLLoadIdentity(); kmMat4 orthoMatrix; kmMat4OrthographicProjection(&orthoMatrix, 0, size.width, size.height, 0, -1024, 1024 ); kmGLMultMatrix(&orthoMatrix); kmGLMatrixMode(KM_GL_MODELVIEW); kmGLLoadIdentity(); } break; case kCCDirectorProjection3D: { float zeye = m_obDesignResolutionSize.height / 1.1566f; kmMat4 matrixPerspective, matrixLookup; kmGLMatrixMode(KM_GL_PROJECTION); kmGLLoadIdentity(); // issue #1334 kmMat4PerspectiveProjection( &matrixPerspective, 60, (GLfloat)size.width/size.height, 0.1f, zeye*2); // kmMat4PerspectiveProjection( &matrixPerspective, 60, (GLfloat)size.width/size.height, 0.1f, 1500); kmGLMultMatrix(&matrixPerspective); kmGLMatrixMode(KM_GL_MODELVIEW); kmGLLoadIdentity(); kmVec3 eye, center, up; kmVec3Fill( &eye, size.width/2, size.height/2, zeye ); kmVec3Fill( ¢er, size.width/2, size.height/2, 0.0f ); kmVec3Fill( &up, 0.0f, 1.0f, 0.0f); kmMat4LookAt(&matrixLookup, &eye, ¢er, &up); kmGLMultMatrix(&matrixLookup); } break; default: CCLOG("cocos2d: Director: unrecognized projection"); break; } m_eProjection = kProjection; ccSetProjectionMatrixDirty(); }
int main(int argc, char** argv) { // Get width and height if (argc > 1) { width = atoi(argv[1]); if (argc > 2) height = atoi(argv[2]); } // Set up the rasteriser srInitParams params; params.width = width; params.height = height; params.outputContext = SR_CTX_SDL; srInit(¶ms); width = srGetWidth(); height = srGetHeight(); srSetMaxFPS(60); // srSetRenderState(SR_WIREFRAME, SR_TRUE); // Set projectino matrix float aspect = (float)width / height; kmMat4PerspectiveProjection(&proj, 60.0f, aspect, 0.1f, 100.0f); // Initialise the scene init(); // Enter rendering loop kmVec3 eye; kmVec3 centre; kmVec3 up; float angle = 0.0f; while (srContextActive()) { // Calculate view matrix kmMat4LookAt(&view, kmVec3Fill(&eye, 0.0f, 0.0f, 3.0f), kmVec3Fill(¢re, 0.0f, 0.0f, 0.0f), kmVec3Fill(&up, 0.0f, 1.0f, 0.0f)); // Draw scene srBegin(0); render(angle); srEnd(); // Update rotation angle += M_PI / 2.0f * 0.01f; } // Clean-up cleanup(); srShutdown(); return 0; }
static void cxEngineLookAt(cxMatrix4f *matrix,const cxVec2f point) { cxEngine engine = cxEngineInstance(); cxFloat zeye = engine->winsize.h / 1.1566f; cxVec3f eye; cxVec3f center; cxVec3f up; kmVec3Fill(&eye, point.x, point.y, zeye); kmVec3Fill(¢er, point.x, point.y, 0.0f); kmVec3Fill(&up, 0.0f, 1.0f, 0.0f); kmMat4Identity(matrix); kmMat4LookAt(matrix, &eye, ¢er, &up); }
void BoundingBox::getCorners(kmVec3* dst) const { GP_ASSERT(dst); // Near face, specified counter-clockwise looking towards the origin from the positive z-axis. // Left-top-front. //dst[0].set(min.x, max.y, max.z); kmVec3Fill( &dst[0], min.x, max.y, max.z); // Left-bottom-front. //dst[1].set(min.x, min.y, max.z); kmVec3Fill(&dst[1], min.x, min.y, max.z); // Right-bottom-front. //dst[2].set(max.x, min.y, max.z); kmVec3Fill(&dst[2], max.x, min.y, max.z); // Right-top-front. //dst[3].set(max.x, max.y, max.z); kmVec3Fill(&dst[3], max.x, max.y, max.z); // Far face, specified counter-clockwise looking towards the origin from the negative z-axis. // Right-top-back. //dst[4].set(max.x, max.y, min.z); kmVec3Fill(&dst[4], max.x, max.y, min.z); // Right-bottom-back. //dst[5].set(max.x, min.y, min.z); kmVec3Fill(&dst[5], max.x, min.y, min.z); // Left-bottom-back. //dst[6].set(min.x, min.y, min.z); kmVec3Fill(&dst[6], min.x, min.y, min.z); // Left-top-back. //dst[7].set(min.x, max.y, min.z); kmVec3Fill(&dst[7], min.x, max.y, min.z); return; }
kmEnum kmAABB3ContainsAABB(const kmAABB3* container, const kmAABB3* to_check) { kmUchar i; kmVec3 corners[8]; kmEnum result = KM_CONTAINS_ALL; kmBool found = KM_FALSE; kmVec3Fill(&corners[0], to_check->min.x, to_check->min.y, to_check->min.z); kmVec3Fill(&corners[1], to_check->max.x, to_check->min.y, to_check->min.z); kmVec3Fill(&corners[2], to_check->max.x, to_check->max.y, to_check->min.z); kmVec3Fill(&corners[3], to_check->min.x, to_check->max.y, to_check->min.z); kmVec3Fill(&corners[4], to_check->min.x, to_check->min.y, to_check->max.z); kmVec3Fill(&corners[5], to_check->max.x, to_check->min.y, to_check->max.z); kmVec3Fill(&corners[6], to_check->max.x, to_check->max.y, to_check->max.z); kmVec3Fill(&corners[7], to_check->min.x, to_check->max.y, to_check->max.z); for(i = 0; i < 8; ++i) { if(!kmAABB3ContainsPoint(container, &corners[i])) { result = KM_CONTAINS_PARTIAL; if(found) { /*If we previously found a corner that was within the container*/ /*We know that partial is the final result*/ return result; } } else { found = KM_TRUE; } } if(!found) { result = KM_CONTAINS_NONE; } return result; }
/* \brief reset camera to default state */ GLHCKAPI void glhckCameraReset(glhckCamera *object) { CALL(0, "%p", object); assert(object); object->view.update = 1; kmVec3Fill(&object->view.upVector, 0, 1, 0); kmVec3Fill(&object->object->view.rotation, 0, 0, 0); kmVec3Fill(&object->object->view.target, 0, 0, 0); kmVec3Fill(&object->object->view.translation, 0, 0, 1); memset(&object->view.viewport, 0, sizeof(glhckRect)); object->view.viewport.w = GLHCKR()->width; object->view.viewport.h = GLHCKR()->height; _glhckCameraProjectionMatrix(object); }
kmVec3 Camera::project_point(ViewportID vid, const kmVec3& point) { if(!scene_) { throw LogicError("Passes a nullptr as a camera's Scene"); } kglt::Viewport& viewport = scene_->window().viewport(vid); kmVec3 tmp; kmVec3Fill(&tmp, point.x, point.y, point.z); kmVec3 result; kmVec3MultiplyMat4(&tmp, &tmp, &view_matrix()); kmVec3MultiplyMat4(&tmp, &tmp, &projection_matrix()); tmp.x /= tmp.z; tmp.y /= tmp.z; float vp_width = viewport.width(); float vp_height = viewport.height(); result.x = (tmp.x + 1) * vp_width / 2.0; result.y = (tmp.y + 1) * vp_height / 2.0; return result; }
kmBool kmRay3IntersectAABB3(const kmRay3* ray, const kmAABB3* aabb, kmVec3* intersection, kmScalar* distance) { //http://gamedev.stackexchange.com/a/18459/15125 kmVec3 rdir, dirfrac, diff; kmVec3Normalize(&rdir, &ray->dir); kmVec3Fill(&dirfrac, 1.0 / rdir.x, 1.0 / rdir.y, 1.0 / rdir.z); kmScalar t1 = (aabb->min.x - ray->start.x) * dirfrac.x; kmScalar t2 = (aabb->max.x - ray->start.x) * dirfrac.x; kmScalar t3 = (aabb->min.y - ray->start.y) * dirfrac.y; kmScalar t4 = (aabb->max.y - ray->start.y) * dirfrac.y; kmScalar t5 = (aabb->min.z - ray->start.z) * dirfrac.z; kmScalar t6 = (aabb->max.z - ray->start.z) * dirfrac.z; kmScalar tmin = kmMax(kmMax(kmMin(t1, t2), kmMin(t3, t4)), kmMin(t5, t6)); kmScalar tmax = kmMin(kmMin(kmMax(t1, t2), kmMax(t3, t4)), kmMax(t5, t6)); // if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behind us if(tmax < 0) { return KM_FALSE; } // if tmin > tmax, ray doesn't intersect AABB if (tmin > tmax) { return KM_FALSE; } if(distance) *distance = tmin; if(intersection) { kmVec3Scale(&diff, &rdir, tmin); kmVec3Add(intersection, &ray->start, &diff); } return KM_TRUE; }
kmVec3* kmVec3CatmullRom(kmVec3* pOut, const kmVec3* v1, const kmVec3* v2, const kmVec3* v3, const kmVec3* v4, const kmScalar t) { kmVec3Fill(pOut, CubicInterpolate(v1->x, v2->x, v3->x, v4->x, t), CubicInterpolate(v1->y, v2->y, v3->y, v4->y, t), CubicInterpolate(v1->z, v2->z, v3->z, v4->z, t)); return pOut; }
void CFCEditorGLWindow::UpdateCamera() { kmVec3 vec3Speed; kmVec3Fill(&vec3Speed, 1.0f, 1.0f, 1.0f); if ( SafeGetKeyStage(VK_SHIFT) ) { kmVec3Scale(&vec3Speed, &vec3Speed, 5.0F * 0.016F); } else { kmVec3Scale(&vec3Speed, &vec3Speed, 1.0F * 0.016F); } int type = CCamera::eCMT_NOMOVE; bool bPressA = SafeGetKeyStage('A'); bool bPressD = SafeGetKeyStage('D'); if ( bPressA || bPressD ) { type |= (1 << CCamera::eCMT_TRANVERSE); if (bPressA) { vec3Speed.x *= -1; } } bool bPressW = SafeGetKeyStage('W'); bool bPressS = SafeGetKeyStage('S'); if ( bPressW || bPressS ) { type |= (1 << CCamera::eCMT_STRAIGHT); if (bPressW) { vec3Speed.z *= -1; } } bool bPressUp = SafeGetKeyStage('Q'); bool bPressDown = SafeGetKeyStage('Z'); if ( bPressUp || bPressDown ) { type |= (1 << CCamera::eCMT_UPDOWN); if (bPressDown) { vec3Speed.y *= -1; } } bool bPressR = SafeGetKeyStage('R'); if (bPressR) { m_pCamera->ResetCamera(); } if (type != CCamera::eCMT_NOMOVE) { m_pCamera->Update(vec3Speed, type); } }
kmVec3* kmVec3ProjectOnToPlane(kmVec3* pOut, const kmVec3* point, const struct kmPlane* plane) { kmVec3 N; kmVec3Fill(&N, plane->a, plane->b, plane->c); kmVec3Normalize(&N, &N); kmScalar distance = -kmVec3Dot(&N, point); kmVec3Scale(&N, &N, distance); kmVec3Add(pOut, point, &N); return pOut; }
kmVec3* kmVec3Reflect(kmVec3* pOut, const kmVec3* v1, const kmVec3* normal) { const kmScalar d = 2 * kmVec3Dot(v1, normal); kmVec3Fill(pOut, v1->x - d * normal->x, v1->y - d * normal->y, v1->z - d * normal->z); return pOut; }
void GLAnimationCanvas::UpDateCamera() { kmVec3 vec3Speed; kmVec3Fill(&vec3Speed, 1.0f, 1.0f, 1.0f); if ( GetKeyState(KEY_SHIFT) ) { kmVec3Scale(&vec3Speed, &vec3Speed, 5.0F * 0.016F); } else { kmVec3Scale(&vec3Speed, &vec3Speed, 1.0F * 0.016F); } int type = CCamera::eCMT_NOMOVE; bool bPressA = GetKeyState(KEY_A); bool bPressD = GetKeyState(KEY_D); if ( bPressA || bPressD ) { type |= (1 << CCamera::eCMT_TRANVERSE); if (bPressA) { vec3Speed.x *= -1; } } bool bPressW = GetKeyState(KEY_W); bool bPressS = GetKeyState(KEY_S); if ( bPressW || bPressS ) { type |= (1 << CCamera::eCMT_STRAIGHT); if (bPressW) { vec3Speed.z *= -1; } } bool bPressUp = GetKeyState(KEY_Q); bool bPressDown = GetKeyState(KEY_Z); if ( bPressUp || bPressDown ) { type |= (1 << CCamera::eCMT_UPDOWN); if (bPressDown) { vec3Speed.y *= -1; } } if (type != CCamera::eCMT_NOMOVE) { CRenderManager::GetInstance()->GetCamera()->Update(vec3Speed, type); } }
/** * @brief SubMesh::recalc_bounds * * Recalculate the bounds of the submesh. This involves interating over all of the * vertices that make up the submesh and so is potentially quite slow. This happens automatically * when vertex_data->done() or index_data->done() are called. */ void SubMesh::_recalc_bounds() { //Set the min bounds to the max kmVec3Fill(&bounds_.min, std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max()); //Set the max bounds to the min kmVec3Fill(&bounds_.max, -1000000, -1000000, -1000000); if(!index_data->count()) { kmAABB3Initialize(&bounds_, nullptr, 0, 0, 0); return; } for(uint16_t idx: index_data->all()) { Vec3 pos = vertex_data->position_at<Vec3>(idx); if(pos.x < bounds_.min.x) bounds_.min.x = pos.x; if(pos.y < bounds_.min.y) bounds_.min.y = pos.y; if(pos.z < bounds_.min.z) bounds_.min.z = pos.z; if(pos.x > bounds_.max.x) bounds_.max.x = pos.x; if(pos.y > bounds_.max.y) bounds_.max.y = pos.y; if(pos.z > bounds_.max.z) bounds_.max.z = pos.z; } }
cxVec2f cxViewPointToWindowPoint(cxAny pview,cxVec2f vPoint) { cxView this = pview; cxView pv = this; cxVec3f out; kmVec3Fill(&out, vPoint.x, vPoint.y, 0); while (pv != NULL && pv->parentView != NULL) { kmVec3Transform(&out, &out, &pv->anchorMatrix); kmVec3Transform(&out, &out, &pv->normalMatrix); pv = pv->parentView; } return cxVec2fv(out.x, out.y); }
void kmGLRotatef(float angle, float x, float y, float z) { kmVec3 axis; kmMat4 rotation; //Create an axis vector kmVec3Fill(&axis, x, y, z); //Create a rotation matrix using the axis and the angle kmMat4RotationAxisAngle(&rotation, &axis, kmDegreesToRadians(angle)); //Multiply the rotation matrix by the current matrix kmMat4Multiply(current_stack->top, current_stack->top, &rotation); }
lite3d_scene_node *lite3d_scene_node_init(lite3d_scene_node *node) { SDL_assert(node); memset(node, 0, sizeof (lite3d_scene_node)); lite3d_list_link_init(&node->nodeLink); kmMat4Identity(&node->localView); kmMat4Identity(&node->worldView); kmMat3Identity(&node->normalModel); kmQuaternionIdentity(&node->rotation); kmVec3Fill(&node->position, 0, 0, 0); kmVec3Fill(&node->scale, 1.0f, 1.0f, 1.0f); node->recalc = LITE3D_TRUE; node->invalidated = LITE3D_TRUE; node->rotationCentered = LITE3D_TRUE; node->isCamera = LITE3D_FALSE; node->renderable = LITE3D_TRUE; node->enabled = LITE3D_TRUE; node->visible = LITE3D_TRUE; node->frustumTest = LITE3D_TRUE; lite3d_list_init(&node->childNodes); return node; }
void CFCEditorGLWindow::OnMouseMidScroll( wxMouseEvent& event ) { kmVec3 vec3Speed; kmVec3Fill(&vec3Speed, SHIFTWHEELSPEED, SHIFTWHEELSPEED, SHIFTWHEELSPEED); if (event.GetWheelRotation() > 0) { m_pCamera->Update(vec3Speed, (1 << CCamera::eCMT_STRAIGHT)); } else if (event.GetWheelRotation() < 0) { kmVec3Scale(&vec3Speed, &vec3Speed, -1.0f); m_pCamera->Update(vec3Speed, (1 << CCamera::eCMT_STRAIGHT)); } }
void kmGLRotatef(float angle, float x, float y, float z) { km_mat4_stack_context *current_context = (km_mat4_stack_context *)pthread_getspecific(current_context_key); kmVec3 axis; kmMat4 rotation; /*Create an axis vector*/ kmVec3Fill(&axis, x, y, z); /*Create a rotation matrix using the axis and the angle*/ kmMat4RotationAxisAngle(&rotation, &axis, kmDegreesToRadians(angle)); /*Multiply the rotation matrix by the current matrix*/ kmMat4Multiply(current_context->current_stack->top, current_context->current_stack->top, &rotation); }
void frustum_from_vp( ne_frustum *f, kmMat4 *mat) { float len = 0.f; kmVec3 tmp; f->planes[0].normal.x = mat->mat[3] + mat->mat[0]; f->planes[0].normal.y = mat->mat[7] + mat->mat[4]; f->planes[0].normal.z = mat->mat[11] + mat->mat[8]; f->planes[0].distance = mat->mat[15] + mat->mat[12]; f->planes[1].normal.x = mat->mat[3] - mat->mat[0]; f->planes[1].normal.y = mat->mat[7] - mat->mat[4]; f->planes[1].normal.z = mat->mat[11] - mat->mat[8]; f->planes[1].distance = mat->mat[15] - mat->mat[12]; f->planes[2].normal.x = mat->mat[3] - mat->mat[1]; f->planes[2].normal.y = mat->mat[7] - mat->mat[5]; f->planes[2].normal.z = mat->mat[11] - mat->mat[9]; f->planes[2].distance = mat->mat[15] - mat->mat[13]; f->planes[3].normal.x = mat->mat[3] + mat->mat[1]; f->planes[3].normal.y = mat->mat[7] + mat->mat[5]; f->planes[3].normal.z = mat->mat[11] + mat->mat[9]; f->planes[3].distance = mat->mat[15] + mat->mat[13]; f->planes[4].normal.x = mat->mat[3] + mat->mat[2]; f->planes[4].normal.y = mat->mat[7] + mat->mat[6]; f->planes[4].normal.z = mat->mat[11] + mat->mat[10]; f->planes[4].distance = mat->mat[15] + mat->mat[14]; f->planes[5].normal.x = mat->mat[3] - mat->mat[2]; f->planes[5].normal.y = mat->mat[7] - mat->mat[6]; f->planes[5].normal.z = mat->mat[11] - mat->mat[10]; f->planes[5].distance = mat->mat[15] - mat->mat[14]; for (uint8_t i = 0; i < 6; ++i) { len = kmVec3Length(&f->planes[i].normal); kmVec3Fill(&tmp, len, len, len); kmVec3Div(&f->planes[i].normal, &f->planes[i].normal, &tmp); f->planes[i].distance /= len; } }
kmQuaternion* kmQuaternionExtractRotationAroundAxis(const kmQuaternion* pIn, const kmVec3* axis, kmQuaternion* pOut) { /** Given a quaternion, and an axis. This extracts the rotation around the axis into pOut as another quaternion. Uses the swing-twist decomposition. http://stackoverflow.com/questions/3684269/component-of-a-quaternion-rotation-around-an-axis/22401169?noredirect=1#comment34098058_22401169 */ kmVec3 ra; kmScalar d; kmVec3Fill(&ra, pIn->x, pIn->y, pIn->z); d = kmVec3Dot(&ra, axis); kmQuaternionFill(pOut, axis->x * d, axis->y * d, axis->z * d, pIn->w); kmQuaternionNormalize(pOut, pOut); return pOut; }
cxVec2f cxWindowPointToViewPoint(cxAny pview,cxVec2f wPoint) { cxView this = pview; cxView pv = this; cxVec3f out; cxMatrix4f matrix; kmVec3Fill(&out, wPoint.x, wPoint.y, 0); cxArray list = CX_ALLOC(cxArray); while (pv != NULL && pv->parentView != NULL) { cxArrayAppend(list, pv); pv = pv->parentView; } CX_ARRAY_REVERSE(list, ele){ pv = cxArrayObject(ele); kmMat4Inverse(&matrix, &pv->normalMatrix); kmVec3Transform(&out, &out, &matrix); kmMat4Inverse(&matrix, &pv->anchorMatrix); kmVec3Transform(&out, &out, &matrix); }
void resetExposion(struct pointCloud_t* pntC) { pntC->tick=0; for (int i=0; i<pntC->totalPoints; i++) { kmVec3 v; kmVec3Fill(&v,rand_range(-1,2),rand_range(-1,2),rand_range(-1,2)); kmVec3Normalize(&v,&v); pntC->vel[i*3]=v.x; pntC->vel[i*3+1]=v.y; pntC->vel[i*3+2]=v.z; pntC->pos[i*3]=0; pntC->pos[i*3+1]=0; pntC->pos[i*3+2]=0; } }
bool Transform::pointInside(float x,float y,float& ox,float& oy) { kmMat4 t_mat; kmMat4Inverse(&t_mat, &m_matrix); kmVec3 outpos; kmVec3 inpos; // float nx = x*2/Device::GetInstance()->getCurrentCanvas()->getLayerWidth()-1; // float ny = -y*2/Device::GetInstance()->getCurrentCanvas()->getLayerHeight()+1; kmVec3Fill(&inpos,x,y,0); kmVec3Transform(&outpos,&inpos,&t_mat); ox = outpos.x; oy = outpos.y; if (outpos.x >= 0 && outpos.y >= 0 && outpos.x < m_width&& outpos.y < m_height) { return true; } return false; }
kmVec3 Camera::project_point(const RenderTarget &target, const Viewport &viewport, const kmVec3& point) { if(!window_) { throw std::logic_error("Passed a nullptr as a camera's window"); } kmVec3 tmp; kmVec3Fill(&tmp, point.x, point.y, point.z); kmVec3 result; kmVec3MultiplyMat4(&tmp, &tmp, &view_matrix()); kmVec3MultiplyMat4(&tmp, &tmp, &projection_matrix()); tmp.x /= tmp.z; tmp.y /= tmp.z; float vp_width = viewport.width_in_pixels(target); float vp_height = viewport.height_in_pixels(target); result.x = (tmp.x + 1) * vp_width / 2.0; result.y = (tmp.y + 1) * vp_height / 2.0; return result; }