From cb6facedd522734d18890784f64e9dc1ff09c41e Mon Sep 17 00:00:00 2001 From: kearwood Date: Fri, 28 Dec 2012 03:20:06 +0000 Subject: [PATCH] Completed ray/line casting system and refactoring --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40200 --- KREngine/KREngine/Classes/KRCamera.cpp | 27 ++++++------------ KREngine/KREngine/Classes/KRCamera.h | 2 -- KREngine/KREngine/Classes/KRCollider.cpp | 16 ++++++----- KREngine/KREngine/Classes/KREngine.h | 3 +- KREngine/KREngine/Classes/KREngine.mm | 16 +---------- KREngine/KREngine/Classes/KRHitInfo.cpp | 2 +- KREngine/KREngine/Classes/KRModel.cpp | 4 +-- KREngine/KREngine/Classes/KROctree.cpp | 8 +++++- KREngine/KREngine/Classes/KRQuaternion.cpp | 32 ++++++++++++++++------ KREngine/KREngine/Classes/KRQuaternion.h | 4 +-- KREngine/KREngine/Classes/KRScene.cpp | 7 +++-- 11 files changed, 61 insertions(+), 60 deletions(-) diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index a7f1cc0..64af862 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -67,39 +67,27 @@ KRCamera::~KRCamera() { void KRCamera::renderFrame(float deltaTime) { + + createBuffers(); + + KRScene &scene = getScene(); + #if TARGET_OS_IPHONE + KRMat4 viewMatrix = KRMat4::Invert(getModelMatrix()); GLint defaultFBO; GLDEBUG(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO)); - createBuffers(); - settings.setViewportSize(KRVector2(backingWidth, backingHeight)); KRMat4 projectionMatrix; projectionMatrix.perspective(settings.perspective_fov, settings.m_viewportSize.x / settings.m_viewportSize.y, settings.perspective_nearz, settings.perspective_farz); m_viewport = KRViewport(settings.getViewportSize(), viewMatrix, projectionMatrix); - - renderFrame(getScene(), deltaTime); - - GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO)); - renderPost(); -#endif - -} - -void KRCamera::renderFrame(KRScene &scene, float deltaTime) { - -#if TARGET_OS_IPHONE KRVector3 vecCameraDirection = m_viewport.getCameraDirection(); -// GLuint shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS]; -// KRViewport shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS]; -// int cShadows = 0; - if(settings.bEnableDeferredLighting) { // ----====---- Opaque Geometry, Deferred rendering Pass 1 ----====---- @@ -387,6 +375,9 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) { // fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i/%i Kbyte (active/total) Shader Handles: %i Visible Bounds: %i Max Texture LOD: %i\n", (int)m_pContext->getModelManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getActiveMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024, (int)m_pContext->getShaderManager()->getShaderHandlesUsed(), (int)m_visibleBounds.size(), m_pContext->getTextureManager()->getLODDimCap()); + + GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO)); + renderPost(); #endif } diff --git a/KREngine/KREngine/Classes/KRCamera.h b/KREngine/KREngine/Classes/KRCamera.h index febcfbd..e63768c 100644 --- a/KREngine/KREngine/Classes/KRCamera.h +++ b/KREngine/KREngine/Classes/KRCamera.h @@ -73,8 +73,6 @@ private: void destroyBuffers(); - void renderFrame(KRScene &scene, float deltaTime); - KRTexture *m_pSkyBoxTexture; KRViewport m_viewport; diff --git a/KREngine/KREngine/Classes/KRCollider.cpp b/KREngine/KREngine/Classes/KRCollider.cpp index a9d245b..7746116 100644 --- a/KREngine/KREngine/Classes/KRCollider.cpp +++ b/KREngine/KREngine/Classes/KRCollider.cpp @@ -75,13 +75,14 @@ KRAABB KRCollider::getBounds() { bool KRCollider::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) { + loadModel(); if(m_models.size()) { if(getBounds().intersectsLine(v0, v1)) { KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode()); - KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0); - KRVector3 v1_model_space = KRMat4::Dot(getModelMatrix(), v1); + KRVector3 v0_model_space = KRMat4::Dot(getInverseModelMatrix(), v0); + KRVector3 v1_model_space = KRMat4::Dot(getInverseModelMatrix(), v1); if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) { - hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), this); + hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRVector3::Normalize(KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal())), this); return true; } } @@ -91,13 +92,14 @@ bool KRCollider::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &h bool KRCollider::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo) { + loadModel(); if(m_models.size()) { if(getBounds().intersectsRay(v0, dir)) { - KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode()); - KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0); - KRVector3 dir_model_space = KRMat4::DotNoTranslate(getModelMatrix(), dir); + KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRVector3::Normalize(KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal())), hitinfo.getNode()); + KRVector3 v0_model_space = KRMat4::Dot(getInverseModelMatrix(), v0); + KRVector3 dir_model_space = KRMat4::DotNoTranslate(getInverseModelMatrix(), dir); if(m_models[0]->rayCast(v0_model_space, dir, hitinfo_model_space)) { - hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), this); + hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRVector3::Normalize(KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal())), this); return true; } } diff --git a/KREngine/KREngine/Classes/KREngine.h b/KREngine/KREngine/Classes/KREngine.h index 82b2f60..3ccdb68 100644 --- a/KREngine/KREngine/Classes/KREngine.h +++ b/KREngine/KREngine/Classes/KREngine.h @@ -66,8 +66,7 @@ typedef enum KREngineParameterType {KRENGINE_PARAMETER_INT, KRENGINE_PARAMETER_F -(void)setParameterValueWithName: (NSString *)name Value: (float)v; -(int)getParameterIndexWithName: (NSString *)name; -- (void)renderScene: (KRScene *)pScene WithViewMatrix: (KRMat4)viewMatrix AndDeltaTime: (float)deltaTime; -- (void)renderScene: (KRScene *)pScene WithPosition: (KRVector3)position Yaw: (GLfloat)yaw Pitch: (GLfloat)pitch Roll: (GLfloat)roll AndDeltaTime: (float)deltaTime; +- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime; - (void)setNearZ: (float)dNearZ; - (void)setFarZ: (float)dFarZ; diff --git a/KREngine/KREngine/Classes/KREngine.mm b/KREngine/KREngine/Classes/KREngine.mm index cba9481..500dfc0 100644 --- a/KREngine/KREngine/Classes/KREngine.mm +++ b/KREngine/KREngine/Classes/KREngine.mm @@ -154,25 +154,11 @@ using namespace std; return self; } -- (void)renderScene: (KRScene *)pScene WithPosition: (KRVector3)position Yaw: (GLfloat)yaw Pitch: (GLfloat)pitch Roll: (GLfloat)roll AndDeltaTime: (float)deltaTime -{ - KRMat4 viewMatrix; - viewMatrix.translate(-position.x, -position.y, -position.z); - viewMatrix.rotate(yaw, Y_AXIS); - viewMatrix.rotate(pitch, X_AXIS); - viewMatrix.rotate(roll, Z_AXIS); - - [self renderScene: pScene WithViewMatrix: viewMatrix AndDeltaTime: deltaTime]; -} - -- (void)renderScene: (KRScene *)pScene WithViewMatrix: (KRMat4)viewMatrix AndDeltaTime: (float)deltaTime +- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime { KRCamera *camera = pScene->find(); if(camera) { camera->settings = _settings; - KRMat4 invView = KRMat4::Invert(viewMatrix); - camera->setLocalRotation(KRMat4::DotNoTranslate(invView, KRVector3::Forward())); - camera->setLocalTranslation(KRMat4::Dot(invView, KRVector3::Zero())); } pScene->renderFrame(deltaTime); } diff --git a/KREngine/KREngine/Classes/KRHitInfo.cpp b/KREngine/KREngine/Classes/KRHitInfo.cpp index d383c3d..b0bde92 100644 --- a/KREngine/KREngine/Classes/KRHitInfo.cpp +++ b/KREngine/KREngine/Classes/KRHitInfo.cpp @@ -59,7 +59,7 @@ KRHitInfo::~KRHitInfo() bool KRHitInfo::didHit() const { - return m_normal == KRVector3::Zero(); + return m_normal != KRVector3::Zero(); } KRVector3 KRHitInfo::getPosition() const diff --git a/KREngine/KREngine/Classes/KRModel.cpp b/KREngine/KREngine/Classes/KRModel.cpp index fc90e91..42d7b41 100644 --- a/KREngine/KREngine/Classes/KRModel.cpp +++ b/KREngine/KREngine/Classes/KRModel.cpp @@ -808,9 +808,9 @@ bool KRModel::rayCast(const KRVector3 &line_v0, const KRVector3 &dir, const KRVe distance_v0 /= distance_total; distance_v1 /= distance_total; distance_v2 /= distance_total; - KRVector3 normal = tri_n0 * (1.0 - distance_v0) + tri_n1 * (1.0 - distance_v1) + tri_n2 * (1.0 - distance_v2); + KRVector3 normal = KRVector3::Normalize(tri_n0 * (1.0 - distance_v0) + tri_n1 * (1.0 - distance_v1) + tri_n2 * (1.0 - distance_v2)); - hitinfo = KRHitInfo(hit_point, KRVector3()); + hitinfo = KRHitInfo(hit_point, normal); } return true; // hit_point is in triangle diff --git a/KREngine/KREngine/Classes/KROctree.cpp b/KREngine/KREngine/Classes/KROctree.cpp index 51ad29f..1153cc8 100644 --- a/KREngine/KREngine/Classes/KROctree.cpp +++ b/KREngine/KREngine/Classes/KROctree.cpp @@ -98,12 +98,18 @@ std::set &KROctree::getOuterSceneNodes() bool KROctree::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) { bool hit_found = false; + std::vector outer_colliders; + for(std::set::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) { KRCollider *collider = dynamic_cast(*outer_nodes_itr); if(collider) { - if(collider->lineCast(v0, v1, hitinfo)) hit_found = true; + outer_colliders.push_back(collider); } } + for(std::vector::iterator itr=outer_colliders.begin(); itr != outer_colliders.end(); itr++) { + if((*itr)->lineCast(v0, v1, hitinfo)) hit_found = true; + } + if(m_pRootNode) { if(m_pRootNode->lineCast(v0, v1, hitinfo)) hit_found = true; } diff --git a/KREngine/KREngine/Classes/KRQuaternion.cpp b/KREngine/KREngine/Classes/KRQuaternion.cpp index 47a3c7b..d98dcab 100644 --- a/KREngine/KREngine/Classes/KRQuaternion.cpp +++ b/KREngine/KREngine/Classes/KRQuaternion.cpp @@ -62,7 +62,7 @@ KRQuaternion& KRQuaternion::operator =( const KRQuaternion& p ) { } KRQuaternion::KRQuaternion(const KRVector3 &euler) { - setEuler(euler); + setEulerZYX(euler); } KRQuaternion::KRQuaternion(const KRVector3 &from_vector, const KRVector3 &to_vector) { @@ -79,7 +79,7 @@ KRQuaternion::~KRQuaternion() { } -void KRQuaternion::setEuler(const KRVector3 &euler) { +void KRQuaternion::setEulerZYX(const KRVector3 &euler) { // ZYX Order! m_val[0] = cos(euler[0] / 2.0) * cos(euler[1] / 2.0) * cos(euler[2] / 2.0) + sin(euler[0] / 2.0) * sin(euler[1] / 2.0) * sin(euler[2] / 2.0); m_val[1] = sin(euler[0] / 2.0) * cos(euler[1] / 2.0) * cos(euler[2] / 2.0) - cos(euler[0] / 2.0) * sin(euler[1] / 2.0) * sin(euler[2] / 2.0); @@ -95,13 +95,29 @@ float &KRQuaternion::operator [](unsigned i) { return m_val[i]; } -KRVector3 KRQuaternion::euler() const { - KRVector3 euler; - euler[0] = atan2(2.0 * (m_val[0] * m_val[1] + m_val[2] * m_val[3]), 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[2] * m_val[2])); - euler[1] = asin(2.0 * (m_val[0] * m_val[2] - m_val[3] * m_val[1])); - euler[2] = atan2(2.0 * (m_val[0] * m_val[3] + m_val[1] * m_val[2]), 1.0 - 2.0 * (m_val[2] * m_val[2] + m_val[3] * m_val[3])); +KRVector3 KRQuaternion::eulerXYZ() const { + double a2 = 2 * (m_val[0] * m_val[2] - m_val[1] * m_val[3]); + if(a2 <= -0.99999) { + return KRVector3( + 2.0 * atan2(m_val[1], m_val[0]), + -PI / 2.0, + 0 + ); + } else if(a2 >= 0.99999) { + return KRVector3( + 2.0 * atan2(m_val[1], m_val[0]), + PI / 2.0, + 0 + ); + } else { + return KRVector3( + atan2(2 * (m_val[0] * m_val[1] + m_val[2] * m_val[3]), (1 - 2 * (m_val[1] * m_val[1] + m_val[2] * m_val[2]))), + asin(a2), + atan2(2 * (m_val[0] * m_val[3] + m_val[1] * m_val[2]), (1 - 2 * (m_val[2] * m_val[2] + m_val[3] * m_val[3]))) + ); + } - return euler; + } bool operator ==(KRQuaternion &v1, KRQuaternion &v2) { diff --git a/KREngine/KREngine/Classes/KRQuaternion.h b/KREngine/KREngine/Classes/KRQuaternion.h index 3e3670e..b9c4b27 100644 --- a/KREngine/KREngine/Classes/KRQuaternion.h +++ b/KREngine/KREngine/Classes/KRQuaternion.h @@ -69,8 +69,8 @@ public: float operator [](unsigned i) const; - void setEuler(const KRVector3 &euler); - KRVector3 euler() const; + void setEulerZYX(const KRVector3 &euler); + KRVector3 eulerXYZ() const; KRMat4 rotationMatrix() const; void normalize(); diff --git a/KREngine/KREngine/Classes/KRScene.cpp b/KREngine/KREngine/Classes/KRScene.cpp index e405283..cc4efce 100644 --- a/KREngine/KREngine/Classes/KRScene.cpp +++ b/KREngine/KREngine/Classes/KRScene.cpp @@ -53,6 +53,7 @@ KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, nam m_skyBoxName = ""; } + KRScene::~KRScene() { delete m_pRootNode; m_pRootNode = NULL; @@ -66,7 +67,9 @@ void KRScene::renderFrame(float deltaTime) { getContext().startFrame(deltaTime); KRCamera *camera = find(); if(camera == NULL) { - + // Add a default camera if none are present + camera = new KRCamera(*this, "default_camera"); + m_pRootNode->addChild(camera); } camera->renderFrame(deltaTime); getContext().endFrame(deltaTime); @@ -431,7 +434,7 @@ void KRScene::addDefaultLights() { KRDirectionalLight *light1 = new KRDirectionalLight(*this, "default_light1"); - light1->setLocalRotation((KRQuaternion(KRVector3(0.0, M_PI * 0.10, 0.0)) * KRQuaternion(KRVector3(0.0, 0.0, -M_PI * 0.15))).euler()); + light1->setLocalRotation((KRQuaternion(KRVector3(0.0, M_PI * 0.10, 0.0)) * KRQuaternion(KRVector3(0.0, 0.0, -M_PI * 0.15))).eulerXYZ()); m_pRootNode->addChild(light1); }