From e0aaafc3270c986e07e6ea09cdb10b929f2f2e73 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Fri, 24 May 2013 12:20:47 -0700 Subject: [PATCH] - Implemented KRBehavior class - Imported animations now have the auto_play and loop flags set to false by default - Implemented Pre-Rotation, Post-Rotation, Scale Offset, Rotate Offset, Scale Pivot, and Rotate Pivot transform attributes. - Reduced use of euler angles, replacing them with Quaternions where possible - Fixed bug with incorrect Y rotation in KRMat4::rotate - Material / GL Context changes have been optimized to reduce redundant glUniform calls - New KRMesh format implemented, with support for importing BindPose matrices - Fixed bug that caused a duplicate "default_camera" node to be added rather than picking up an existing "default_camera" node imported from FBX. This enables animations to drive the camera correctly. - Implemented KRVector3::Scale - Implemented KRVector3::KRVector3(double *v); --- KREngine/Kraken.xcodeproj/project.pbxproj | 16 +- KREngine/kraken/KRAnimation.cpp | 51 ++- KREngine/kraken/KRAnimation.h | 4 + KREngine/kraken/KRAnimationAttribute.cpp | 93 +++++ KREngine/kraken/KRAnimationCurve.cpp | 4 +- KREngine/kraken/KRAnimationCurve.h | 2 +- KREngine/kraken/KRAnimationCurveManager.cpp | 10 +- KREngine/kraken/KRAnimationCurveManager.h | 4 +- KREngine/kraken/KRAudioSource.cpp | 5 + KREngine/kraken/KRBehavior.cpp | 30 ++ KREngine/kraken/KRBehavior.h | 36 ++ KREngine/kraken/KRBone.cpp | 10 + KREngine/kraken/KRBone.h | 5 +- KREngine/kraken/KRCamera.cpp | 24 +- KREngine/kraken/KRCamera.h | 5 + KREngine/kraken/KRDirectionalLight.cpp | 14 +- KREngine/kraken/KREngine-common.h | 1 + KREngine/kraken/KREngine.mm | 2 +- KREngine/kraken/KRLight.cpp | 6 - KREngine/kraken/KRMat4.cpp | 59 ++- KREngine/kraken/KRMat4.h | 4 + KREngine/kraken/KRMaterial.cpp | 256 +++++-------- KREngine/kraken/KRMaterial.h | 2 +- KREngine/kraken/KRMesh.cpp | 156 ++++---- KREngine/kraken/KRMesh.h | 25 +- KREngine/kraken/KRMeshCube.cpp | 53 +-- KREngine/kraken/KRMeshSphere.cpp | 33 +- KREngine/kraken/KRNode.cpp | 362 +++++++++++------- KREngine/kraken/KRNode.h | 37 +- KREngine/kraken/KRQuaternion.cpp | 43 ++- KREngine/kraken/KRQuaternion.h | 2 +- KREngine/kraken/KRResource+fbx.cpp | 329 +++++++++++++--- KREngine/kraken/KRResource+obj.cpp | 50 ++- KREngine/kraken/KRScene.cpp | 2 +- KREngine/kraken/KRShader.cpp | 6 +- KREngine/kraken/KRShaderManager.cpp | 9 +- KREngine/kraken/KRShaderManager.h | 3 - KREngine/kraken/KRVector3.cpp | 19 + KREngine/kraken/KRVector3.h | 3 + .../Shaders/ObjectShader.vsh | 5 +- .../Shaders/debug_font.vsh | 4 +- .../Shaders/debug_font_osx.vsh | 4 +- 42 files changed, 1160 insertions(+), 628 deletions(-) create mode 100644 KREngine/kraken/KRBehavior.cpp create mode 100644 KREngine/kraken/KRBehavior.h diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index 355f8ad..db1a25a 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -82,6 +82,10 @@ E450273A16E0491D00FDEC5C /* KRReverbZone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E450273716E0491D00FDEC5C /* KRReverbZone.cpp */; }; E450273B16E0491D00FDEC5C /* KRReverbZone.h in Headers */ = {isa = PBXBuildFile; fileRef = E450273816E0491D00FDEC5C /* KRReverbZone.h */; settings = {ATTRIBUTES = (Public, ); }; }; E450273C16E0491D00FDEC5C /* KRReverbZone.h in Headers */ = {isa = PBXBuildFile; fileRef = E450273816E0491D00FDEC5C /* KRReverbZone.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45134B61746A4A300443C21 /* KRBehavior.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45134B41746A4A300443C21 /* KRBehavior.cpp */; }; + E45134B71746A4A300443C21 /* KRBehavior.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45134B41746A4A300443C21 /* KRBehavior.cpp */; }; + E45134B81746A4A300443C21 /* KRBehavior.h in Headers */ = {isa = PBXBuildFile; fileRef = E45134B51746A4A300443C21 /* KRBehavior.h */; }; + E45134B91746A4A300443C21 /* KRBehavior.h in Headers */ = {isa = PBXBuildFile; fileRef = E45134B51746A4A300443C21 /* KRBehavior.h */; settings = {ATTRIBUTES = (Public, ); }; }; E459040416C30CC5002B00A0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E459040316C30CC5002B00A0 /* AudioUnit.framework */; }; E459040616C30CD9002B00A0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E459040516C30CD9002B00A0 /* AudioUnit.framework */; }; E460292616681CFF00261BB9 /* KRTextureAnimated.h in Headers */ = {isa = PBXBuildFile; fileRef = E460292516681CFE00261BB9 /* KRTextureAnimated.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -151,7 +155,7 @@ E48CF942173453990005EBBB /* KRFloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48CF940173453990005EBBB /* KRFloat.cpp */; }; E48CF943173453990005EBBB /* KRFloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48CF940173453990005EBBB /* KRFloat.cpp */; }; E48CF944173453990005EBBB /* KRFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = E48CF941173453990005EBBB /* KRFloat.h */; }; - E48CF945173453990005EBBB /* KRFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = E48CF941173453990005EBBB /* KRFloat.h */; }; + E48CF945173453990005EBBB /* KRFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = E48CF941173453990005EBBB /* KRFloat.h */; settings = {ATTRIBUTES = (Public, ); }; }; E491018713C99BDC0098455B /* KREngine.mm in Sources */ = {isa = PBXBuildFile; fileRef = E491016F13C99BDC0098455B /* KREngine.mm */; }; E491018A13C99BDC0098455B /* KREngine.h in Headers */ = {isa = PBXBuildFile; fileRef = E491017213C99BDC0098455B /* KREngine.h */; settings = {ATTRIBUTES = (Public, ); }; }; E491018E13C99BDC0098455B /* KRMat4.h in Headers */ = {isa = PBXBuildFile; fileRef = E491017613C99BDC0098455B /* KRMat4.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -419,6 +423,8 @@ E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = ""; }; E450273716E0491D00FDEC5C /* KRReverbZone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRReverbZone.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E450273816E0491D00FDEC5C /* KRReverbZone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRReverbZone.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + E45134B41746A4A300443C21 /* KRBehavior.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRBehavior.cpp; sourceTree = ""; }; + E45134B51746A4A300443C21 /* KRBehavior.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRBehavior.h; sourceTree = ""; }; E459040316C30CC5002B00A0 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/AudioUnit.framework; sourceTree = DEVELOPER_DIR; }; E459040516C30CD9002B00A0 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; E460292516681CFE00261BB9 /* KRTextureAnimated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureAnimated.h; sourceTree = ""; }; @@ -1020,6 +1026,8 @@ E4C454BA167BD248003586CD /* KRHitInfo.cpp */, E44F38231683B22C00399B5D /* KRRenderSettings.h */, E44F38271683B24400399B5D /* KRRenderSettings.cpp */, + E45134B41746A4A300443C21 /* KRBehavior.cpp */, + E45134B51746A4A300443C21 /* KRBehavior.h */, ); path = kraken; sourceTree = ""; @@ -1238,6 +1246,7 @@ E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */, E4EC73C31720B1FF0065299F /* KRVector4.h in Headers */, E48CF944173453990005EBBB /* KRFloat.h in Headers */, + E45134B81746A4A300443C21 /* KRBehavior.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1313,9 +1322,10 @@ E499BF1D16AE74FF007FCDBE /* KRTextureAnimated.h in Headers */, E4EC73C41720B1FF0065299F /* KRVector4.h in Headers */, E4AE63601704FB0A00B460CD /* KRLODGroup.h in Headers */, + E45134B91746A4A300443C21 /* KRBehavior.h in Headers */, + E48CF945173453990005EBBB /* KRFloat.h in Headers */, E499BF1F16AE753E007FCDBE /* KRCollider.h in Headers */, E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */, - E48CF945173453990005EBBB /* KRFloat.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1580,6 +1590,7 @@ E4AE635D1704FB0A00B460CD /* KRLODGroup.cpp in Sources */, E4EC73C11720B1FF0065299F /* KRVector4.cpp in Sources */, E48CF942173453990005EBBB /* KRFloat.cpp in Sources */, + E45134B61746A4A300443C21 /* KRBehavior.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1655,6 +1666,7 @@ E4AE635E1704FB0A00B460CD /* KRLODGroup.cpp in Sources */, E4EC73C21720B1FF0065299F /* KRVector4.cpp in Sources */, E48CF943173453990005EBBB /* KRFloat.cpp in Sources */, + E45134B71746A4A300443C21 /* KRBehavior.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/KREngine/kraken/KRAnimation.cpp b/KREngine/kraken/KRAnimation.cpp index a45dde3..47ea76b 100644 --- a/KREngine/kraken/KRAnimation.cpp +++ b/KREngine/kraken/KRAnimation.cpp @@ -39,9 +39,9 @@ KRAnimation::KRAnimation(KRContext &context, std::string name) : KRResource(context, name) { - m_auto_play = true; - m_loop = true; - m_playing = true; + m_auto_play = false; + m_loop = false; + m_playing = false; m_local_time = 0.0f; m_duration = 0.0f; } @@ -94,11 +94,11 @@ KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, KRDa } if(animation_node->QueryBoolAttribute("loop", &new_animation->m_loop) != tinyxml2::XML_SUCCESS) { - new_animation->m_loop = true; // Default value + new_animation->m_loop = false; // Default value } if(animation_node->QueryBoolAttribute("auto_play", &new_animation->m_auto_play) != tinyxml2::XML_SUCCESS) { - new_animation->m_auto_play = true; // Default value + new_animation->m_auto_play = false; // Default value } for(tinyxml2::XMLElement *child_element=animation_node->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { @@ -131,12 +131,18 @@ KRAnimationLayer *KRAnimation::getLayer(const char *szName) } void KRAnimation::update(float deltaTime) -{ +{ if(m_playing) { m_local_time += deltaTime; } - while(m_local_time > m_duration) { - m_local_time -= m_duration; + if(m_loop) { + while(m_local_time > m_duration) { + m_local_time -= m_duration; + } + } else if(m_local_time > m_duration) { + m_local_time = m_duration; + m_playing = false; + getContext().getAnimationManager()->updateActiveAnimations(this); } for(unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { @@ -151,7 +157,14 @@ void KRAnimation::update(float deltaTime) KRNode::node_attribute_type attribute_type = attribute->getTargetAttribute(); if(curve != NULL && target != NULL) { - target->SetAttribute(attribute_type, curve->getValue(m_local_time)); + int frame_number = (int)(m_local_time * curve->getFrameRate()); + if(frame_number < curve->getFrameStart()) { + target->SetAttribute(attribute_type, curve->getValue(0)); + } else if(frame_number - curve->getFrameStart() >= curve->getFrameCount()) { + target->SetAttribute(attribute_type, curve->getValue(curve->getFrameCount() - 1)); + } else { + target->SetAttribute(attribute_type, curve->getValue(frame_number - curve->getFrameStart())); + } } } @@ -194,3 +207,23 @@ bool KRAnimation::isPlaying() { return m_playing; } + +bool KRAnimation::getAutoPlay() const +{ + return m_auto_play; +} + +void KRAnimation::setAutoPlay(bool auto_play) +{ + m_auto_play = auto_play; +} + +bool KRAnimation::getLooping() const +{ + return m_loop; +} + +void KRAnimation::setLooping(bool looping) +{ + m_loop = looping; +} diff --git a/KREngine/kraken/KRAnimation.h b/KREngine/kraken/KRAnimation.h index 5357cee..38166a6 100644 --- a/KREngine/kraken/KRAnimation.h +++ b/KREngine/kraken/KRAnimation.h @@ -53,6 +53,10 @@ public: void addLayer(KRAnimationLayer *layer); unordered_map &getLayers(); KRAnimationLayer *getLayer(const char *szName); + bool getAutoPlay() const; + void setAutoPlay(bool auto_play); + bool getLooping() const; + void setLooping(bool looping); void Play(); void Stop(); void update(float deltaTime); diff --git a/KREngine/kraken/KRAnimationAttribute.cpp b/KREngine/kraken/KRAnimationAttribute.cpp index cb0a465..48d3943 100644 --- a/KREngine/kraken/KRAnimationAttribute.cpp +++ b/KREngine/kraken/KRAnimationAttribute.cpp @@ -86,6 +86,60 @@ tinyxml2::XMLElement *KRAnimationAttribute::saveXML( tinyxml2::XMLNode *parent) case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Z: szAttribute = "rotate_z"; break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X: + szAttribute = "pre_rotate_x"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y: + szAttribute = "pre_rotate_y"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z: + szAttribute = "pre_rotate_z"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X: + szAttribute = "post_rotate_x"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y: + szAttribute = "post_rotate_y"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z: + szAttribute = "post_rotate_z"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X: + szAttribute = "rotate_pivot_x"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y: + szAttribute = "rotate_pivot_y"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z: + szAttribute = "rotate_pivot_z"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X: + szAttribute = "scale_pivot_x"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y: + szAttribute = "scale_pivot_y"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z: + szAttribute = "scale_pivot_z"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X: + szAttribute = "rotate_offset_x"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y: + szAttribute = "rotate_offset_y"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z: + szAttribute = "rotate_offset_z"; + break; + case KRNode::KRENGINE_NODE_SCALE_OFFSET_X: + szAttribute = "scale_offset_x"; + break; + case KRNode::KRENGINE_NODE_SCALE_OFFSET_Y: + szAttribute = "scale_offset_y"; + break; + case KRNode::KRENGINE_NODE_SCALE_OFFSET_Z: + szAttribute = "scale_offset_z"; + break; } e->SetAttribute("attribute", szAttribute); @@ -121,6 +175,42 @@ void KRAnimationAttribute::loadXML(tinyxml2::XMLElement *e) m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Y; } else if(strcmp(szAttribute, "scale_z") == 0) { m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z; + } else if(strcmp(szAttribute, "pre_rotate_x") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X; + } else if(strcmp(szAttribute, "pre_rotate_y") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y; + } else if(strcmp(szAttribute, "pre_rotate_z") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z; + } else if(strcmp(szAttribute, "post_rotate_x") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X; + } else if(strcmp(szAttribute, "post_rotate_y") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y; + } else if(strcmp(szAttribute, "post_rotate_z") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z; + } else if(strcmp(szAttribute, "rotate_pivot_x") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X; + } else if(strcmp(szAttribute, "rotate_pivot_y") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y; + } else if(strcmp(szAttribute, "rotate_pivot_z") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z; + } else if(strcmp(szAttribute, "scale_pivot_x") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X; + } else if(strcmp(szAttribute, "scale_pivot_y") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y; + } else if(strcmp(szAttribute, "scale_pivot_z") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z; + } else if(strcmp(szAttribute, "rotate_offset_x") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X; + } else if(strcmp(szAttribute, "rotate_offset_y") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y; + } else if(strcmp(szAttribute, "rotate_offset_z") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z; + } else if(strcmp(szAttribute, "scale_offset_x") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_SCALE_OFFSET_X; + } else if(strcmp(szAttribute, "scale_offset_y") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_SCALE_OFFSET_Y; + } else if(strcmp(szAttribute, "scale_offset_z") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_SCALE_OFFSET_Z; } else { m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; } @@ -163,6 +253,9 @@ KRNode *KRAnimationAttribute::getTarget() if(m_target == NULL) { m_target = getContext().getSceneManager()->getFirstScene()->getRootNode()->find(m_target_name); // FINDME, HACK! - This won't work with multiple scenes in a context; we should move the animations out of KRAnimationManager and attach them to the parent nodes of the animated KRNode's } + if(m_target == NULL) { + fprintf(stderr, "Kraken - Animation attribute could not find object: %s\n", m_target_name.c_str()); + } return m_target; } diff --git a/KREngine/kraken/KRAnimationCurve.cpp b/KREngine/kraken/KRAnimationCurve.cpp index 94f5eb9..a1abbd7 100644 --- a/KREngine/kraken/KRAnimationCurve.cpp +++ b/KREngine/kraken/KRAnimationCurve.cpp @@ -32,7 +32,7 @@ #include "KRAnimationCurve.h" #include "KRDataBlock.h" -KRAnimationCurve::KRAnimationCurve(KRContext &context, std::string name) : KRResource(context, name) +KRAnimationCurve::KRAnimationCurve(KRContext &context, const std::string &name) : KRResource(context, name) { m_pData = new KRDataBlock(); m_pData->expand(sizeof(animation_curve_header)); @@ -129,7 +129,7 @@ float KRAnimationCurve::getValue(int frame_number) //printf("frame_number: %i\n", frame_number); int clamped_frame = frame_number; if(frame_number < 0) { - clamped_frame = frame_number; + clamped_frame = 0; } else if(frame_number >= getFrameCount()) { clamped_frame = getFrameCount()-1; } diff --git a/KREngine/kraken/KRAnimationCurve.h b/KREngine/kraken/KRAnimationCurve.h index 5e4b823..3b4f334 100644 --- a/KREngine/kraken/KRAnimationCurve.h +++ b/KREngine/kraken/KRAnimationCurve.h @@ -40,7 +40,7 @@ class KRAnimationCurve : public KRResource { public: - KRAnimationCurve(KRContext &context, std::string name); + KRAnimationCurve(KRContext &context, const std::string &name); virtual ~KRAnimationCurve(); virtual std::string getExtension(); diff --git a/KREngine/kraken/KRAnimationCurveManager.cpp b/KREngine/kraken/KRAnimationCurveManager.cpp index 0c197e2..017b13a 100644 --- a/KREngine/kraken/KRAnimationCurveManager.cpp +++ b/KREngine/kraken/KRAnimationCurveManager.cpp @@ -43,14 +43,14 @@ KRAnimationCurveManager::~KRAnimationCurveManager() { } } -KRAnimationCurve *KRAnimationCurveManager::loadAnimationCurve(const char *szName, KRDataBlock *data) { - KRAnimationCurve *pAnimationCurve = KRAnimationCurve::Load(*m_pContext, szName, data); - m_animationCurves[szName] = pAnimationCurve; +KRAnimationCurve *KRAnimationCurveManager::loadAnimationCurve(const std::string &name, KRDataBlock *data) { + KRAnimationCurve *pAnimationCurve = KRAnimationCurve::Load(*m_pContext, name, data); + m_animationCurves[name] = pAnimationCurve; return pAnimationCurve; } -KRAnimationCurve *KRAnimationCurveManager::getAnimationCurve(const char *szName) { - return m_animationCurves[szName]; +KRAnimationCurve *KRAnimationCurveManager::getAnimationCurve(const std::string &name) { + return m_animationCurves[name]; } unordered_map &KRAnimationCurveManager::getAnimationCurves() { diff --git a/KREngine/kraken/KRAnimationCurveManager.h b/KREngine/kraken/KRAnimationCurveManager.h index 5293cdf..b2a007c 100644 --- a/KREngine/kraken/KRAnimationCurveManager.h +++ b/KREngine/kraken/KRAnimationCurveManager.h @@ -45,8 +45,8 @@ public: KRAnimationCurveManager(KRContext &context); virtual ~KRAnimationCurveManager(); - KRAnimationCurve *loadAnimationCurve(const char *szName, KRDataBlock *data); - KRAnimationCurve *getAnimationCurve(const char *szName); + KRAnimationCurve *loadAnimationCurve(const std::string &name, KRDataBlock *data); + KRAnimationCurve *getAnimationCurve(const std::string &name); void addAnimationCurve(KRAnimationCurve *new_animation_curve); unordered_map &getAnimationCurves(); diff --git a/KREngine/kraken/KRAudioSource.cpp b/KREngine/kraken/KRAudioSource.cpp index ee4df3c..afef53d 100644 --- a/KREngine/kraken/KRAudioSource.cpp +++ b/KREngine/kraken/KRAudioSource.cpp @@ -355,6 +355,9 @@ void KRAudioSource::setIs3D(bool is3D) bool KRAudioSource::hasPhysics() { + if(KRNode::hasPhysics()) { + return true; + } KRAudioManager *audioManager = getContext().getAudioManager(); return audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL; } @@ -370,6 +373,8 @@ void KRAudioSource::advanceBuffer() void KRAudioSource::physicsUpdate(float deltaTime) { + KRNode::physicsUpdate(deltaTime); + KRAudioManager *audioManager = getContext().getAudioManager(); audioManager->activateAudioSource(this); if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) { diff --git a/KREngine/kraken/KRBehavior.cpp b/KREngine/kraken/KRBehavior.cpp new file mode 100644 index 0000000..0d50bb9 --- /dev/null +++ b/KREngine/kraken/KRBehavior.cpp @@ -0,0 +1,30 @@ +// +// KRBehavior.cpp +// Kraken +// +// Created by Kearwood Gilbert on 2013-05-17. +// Copyright (c) 2013 Kearwood Software. All rights reserved. +// + +#include "KRBehavior.h" +#include "KRNode.h" + +KRBehavior::KRBehavior() +{ + __node = NULL; +} + +KRBehavior::~KRBehavior() +{ + +} + +KRNode *KRBehavior::getNode() const +{ + return __node; +} + +void KRBehavior::__setNode(KRNode *node) +{ + __node = node; +} diff --git a/KREngine/kraken/KRBehavior.h b/KREngine/kraken/KRBehavior.h new file mode 100644 index 0000000..003bc67 --- /dev/null +++ b/KREngine/kraken/KRBehavior.h @@ -0,0 +1,36 @@ +// +// KRBehavior.h +// Kraken +// +// Created by Kearwood Gilbert on 2013-05-17. +// Copyright (c) 2013 Kearwood Software. All rights reserved. +// + +#ifndef KRBEHAVIOR_H +#define KRBEHAVIOR_H + + + +/* + + This class is a pure-virtual base class intended to be subclassed to define behavior of KRNode's in the scene + +*/ + +class KRNode; + +class KRBehavior +{ +public: + KRBehavior(); + virtual ~KRBehavior(); + KRNode *getNode() const; + + virtual void update(float deltaTime) = 0; + virtual void visibleUpdate(float deltatime) = 0; + void __setNode(KRNode *node); +private: + KRNode *__node; +}; + +#endif /* defined(KRBEHAVIOR_H) */ diff --git a/KREngine/kraken/KRBone.cpp b/KREngine/kraken/KRBone.cpp index 8783502..1b32c27 100644 --- a/KREngine/kraken/KRBone.cpp +++ b/KREngine/kraken/KRBone.cpp @@ -84,3 +84,13 @@ void KRBone::render(KRCamera *pCamera, std::vector &point_lights } } + + +void KRBone::setBindPose(const KRMat4 &pose) +{ + m_bind_pose = pose; +} +const KRMat4 &KRBone::getBindPose() +{ + return m_bind_pose; +} diff --git a/KREngine/kraken/KRBone.h b/KREngine/kraken/KRBone.h index 187b019..71a6b31 100644 --- a/KREngine/kraken/KRBone.h +++ b/KREngine/kraken/KRBone.h @@ -24,9 +24,10 @@ public: void render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass); - + void setBindPose(const KRMat4 &pose); + const KRMat4 &getBindPose(); private: - + KRMat4 m_bind_pose; }; diff --git a/KREngine/kraken/KRCamera.cpp b/KREngine/kraken/KRCamera.cpp index 197fa9d..fb67f83 100644 --- a/KREngine/kraken/KRCamera.cpp +++ b/KREngine/kraken/KRCamera.cpp @@ -65,6 +65,23 @@ KRCamera::~KRCamera() { destroyBuffers(); } +std::string KRCamera::getElementName() { + return "camera"; +} + +tinyxml2::XMLElement *KRCamera::saveXML( tinyxml2::XMLNode *parent) +{ + tinyxml2::XMLElement *e = KRNode::saveXML(parent); + + return e; +} + + +void KRCamera::loadXML(tinyxml2::XMLElement *e) +{ + KRNode::loadXML(e); +} + void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint renderBufferHeight) { // ----====---- Record timing information for measuring FPS ----====---- @@ -82,9 +99,10 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende KRScene &scene = getScene(); - - - KRMat4 viewMatrix = KRMat4::Invert(getModelMatrix()); + KRMat4 modelMatrix = getModelMatrix(); + KRMat4 viewMatrix = KRMat4::LookAt(KRMat4::Dot(modelMatrix, KRVector3::Zero()), KRMat4::Dot(modelMatrix, KRVector3::Forward()), KRVector3::Normalize(KRMat4::DotNoTranslate(modelMatrix, KRVector3::Up()))); + + //KRMat4 viewMatrix = KRMat4::Invert(getModelMatrix()); settings.setViewportSize(KRVector2(backingWidth, backingHeight)); KRMat4 projectionMatrix; diff --git a/KREngine/kraken/KRCamera.h b/KREngine/kraken/KRCamera.h index 69cda2d..2128e72 100644 --- a/KREngine/kraken/KRCamera.h +++ b/KREngine/kraken/KRCamera.h @@ -60,6 +60,11 @@ public: KRRenderSettings settings; const KRViewport &getViewport(); + + + virtual std::string getElementName(); + virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); + virtual void loadXML(tinyxml2::XMLElement *e); private: void createBuffers(GLint renderBufferWidth, GLint renderBufferHeight); diff --git a/KREngine/kraken/KRDirectionalLight.cpp b/KREngine/kraken/KRDirectionalLight.cpp index d5073df..2335b95 100644 --- a/KREngine/kraken/KRDirectionalLight.cpp +++ b/KREngine/kraken/KRDirectionalLight.cpp @@ -12,6 +12,7 @@ #include "KRShader.h" #include "KRContext.h" #include "KRMat4.h" +#include "KRQuaternion.h" #include "assert.h" #include "KRStockGeometry.h" @@ -30,20 +31,11 @@ std::string KRDirectionalLight::getElementName() { } KRVector3 KRDirectionalLight::getWorldLightDirection() { - KRVector3 world_rotation = getWorldRotation(); - KRVector3 light_rotation = KRVector3(0.0, 0.0, 1.0); - - KRMat4 m; - m.rotate(world_rotation.x, X_AXIS); - m.rotate(world_rotation.y, Y_AXIS); - m.rotate(world_rotation.z, Z_AXIS); - - KRVector3 light_direction = KRMat4::Dot(m, light_rotation); - return light_direction; + return KRMat4::Dot(getWorldRotation().rotationMatrix(), getLocalLightDirection()); } KRVector3 KRDirectionalLight::getLocalLightDirection() { - return KRVector3(0.0, 0.0, 1.0); + return KRVector3::Forward(); } diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index a59bf8d..d80a414 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -196,3 +196,4 @@ fprintf(stderr, "Error at line number %d, in file %s. Returned %d for call %s\n" #include "KRVector4.h" #include "KRVector3.h" #include "KRVector2.h" +#include "KRBehavior.h" diff --git a/KREngine/kraken/KREngine.mm b/KREngine/kraken/KREngine.mm index 5bd8759..e4d34b8 100644 --- a/KREngine/kraken/KREngine.mm +++ b/KREngine/kraken/KREngine.mm @@ -209,7 +209,7 @@ void kraken::set_parameter(const std::string ¶meter_name, float parameter_va - (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime AndWidth: (int)width AndHeight: (int)height { - KRCamera *camera = pScene->find(); + KRCamera *camera = pScene->find("default_camera"); if(camera) { camera->settings = _settings; } diff --git a/KREngine/kraken/KRLight.cpp b/KREngine/kraken/KRLight.cpp index 7c96687..c5337a6 100644 --- a/KREngine/kraken/KRLight.cpp +++ b/KREngine/kraken/KRLight.cpp @@ -313,12 +313,6 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light if(m_flareTexture.size() && m_flareSize > 0.0f) { if(m_occlusionQuery) { - /* - GLuint hasBeenTested = 0; - while(!hasBeenTested) { - GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_AVAILABLE_EXT, &hasBeenTested)); // FINDME, HACK!! This needs to be replaced with asynchonous logic - } - */ GLuint params = 0; GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms)); GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery)); diff --git a/KREngine/kraken/KRMat4.cpp b/KREngine/kraken/KRMat4.cpp index 27b2108..1441e55 100644 --- a/KREngine/kraken/KRMat4.cpp +++ b/KREngine/kraken/KRMat4.cpp @@ -163,10 +163,34 @@ void KRMat4::translate(const KRVector3 &v) /* Rotate a matrix by an angle on a X, Y, or Z axis */ void KRMat4::rotate(float angle, AXIS axis) { - const int cos1[3] = { 5, 0, 0 }; - const int cos2[3] = { 10, 10, 5 }; - const int sin1[3] = { 6, 2, 1 }; - const int sin2[3] = { 9, 8, 4 }; + const int cos1[3] = { 5, 0, 0 }; // cos(angle) + const int cos2[3] = { 10, 10, 5 }; // cos(angle) + const int sin1[3] = { 9, 2, 4 }; // -sin(angle) + const int sin2[3] = { 6, 8, 1 }; // sin(angle) + + /* + X_AXIS: + + 1, 0, 0, 0 + 0, cos(angle), -sin(angle), 0 + 0, sin(angle), cos(angle), 0 + 0, 0, 0, 1 + + Y_AXIS: + + cos(angle), 0, -sin(angle), 0 + 0, 1, 0, 0 + sin(angle), 0, cos(angle), 0 + 0, 0, 0, 1 + + Z_AXIS: + + cos(angle), -sin(angle), 0, 0 + sin(angle), cos(angle), 0, 0 + 0, 0, 1, 0 + 0, 0, 0, 1 + + */ KRMat4 newMatrix; // Create new identity matrix @@ -398,3 +422,30 @@ void KRMat4::setUniform(GLint location) const { if(location != -1) GLDEBUG(glUniformMatrix4fv(location, 1, GL_FALSE, c)); } + +KRMat4 KRMat4::Translation(const KRVector3 &v) +{ + KRMat4 m; + m[12] = v.x; + m[13] = v.y; + m[14] = v.z; +// m.translate(v); + return m; +} + +KRMat4 KRMat4::Rotation(const KRVector3 &v) +{ + KRMat4 m; + m.rotate(v.x, X_AXIS); + m.rotate(v.y, Y_AXIS); + m.rotate(v.z, Z_AXIS); + return m; +} + +KRMat4 KRMat4::Scaling(const KRVector3 &v) +{ + KRMat4 m; + m.scale(v); + return m; +} + diff --git a/KREngine/kraken/KRMat4.h b/KREngine/kraken/KRMat4.h index e08a4e7..c8ac508 100644 --- a/KREngine/kraken/KRMat4.h +++ b/KREngine/kraken/KRMat4.h @@ -120,6 +120,10 @@ class KRMat4 { static KRMat4 LookAt(const KRVector3 &cameraPos, const KRVector3 &lookAtPos, const KRVector3 &upDirection); + static KRMat4 Translation(const KRVector3 &v); + static KRMat4 Rotation(const KRVector3 &v); + static KRMat4 Scaling(const KRVector3 &v); + void setUniform(GLint location) const; }; diff --git a/KREngine/kraken/KRMaterial.cpp b/KREngine/kraken/KRMaterial.cpp index 141e177..95e836e 100644 --- a/KREngine/kraken/KRMaterial.cpp +++ b/KREngine/kraken/KRMaterial.cpp @@ -217,8 +217,7 @@ bool KRMaterial::isTransparent() { return m_tr < 1.0 || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE; } -bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) { - bool bSameMaterial = *prevBoundMaterial == this; +bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) { bool bLightMap = pLightMap && pCamera->settings.bEnableLightMap; if(!m_pAmbientMap && m_ambientMap.size()) { @@ -240,42 +239,32 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str()); } - if(bones.size() > 0) { - bSameMaterial = false; // FINDME, HACK! - This is test code + KRVector2 default_scale = KRVector2::One(); + KRVector2 default_offset = KRVector2::Zero(); + + bool bHasReflection = m_reflectionColor != KRVector3::Zero(); + bool bDiffuseMap = m_pDiffuseMap != NULL && pCamera->settings.bEnableDiffuseMap; + bool bNormalMap = m_pNormalMap != NULL && pCamera->settings.bEnableNormalMap; + bool bSpecMap = m_pSpecularMap != NULL && pCamera->settings.bEnableSpecMap; + bool bReflectionMap = m_pReflectionMap != NULL && pCamera->settings.bEnableReflectionMap && pCamera->settings.bEnableReflection && bHasReflection; + bool bReflectionCubeMap = m_pReflectionCube != NULL && pCamera->settings.bEnableReflection && bHasReflection; + bool bAlphaTest = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_TEST) && bDiffuseMap; + bool bAlphaBlend = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE) || (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); + + + KRShader *pShader = getContext().getShaderManager()->getShader("ObjectShader", pCamera, point_lights, directional_lights, spot_lights, bones.size(), bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_reflectionMapScale != default_scale && bReflectionMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_reflectionMapOffset != default_offset && bReflectionMap, m_normalMapOffset != default_offset && bNormalMap, bAlphaTest, bAlphaBlend, renderPass); + + if(!getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, matModel, point_lights, directional_lights, spot_lights, 0, renderPass)) { + return false; } - if(!bSameMaterial) { - KRVector2 default_scale = KRVector2(1.0f, 1.0f); - KRVector2 default_offset = KRVector2(0.0f, 0.0f); - - bool bHasReflection = m_reflectionColor != KRVector3(0.0f, 0.0f, 0.0f); - bool bDiffuseMap = m_pDiffuseMap != NULL && pCamera->settings.bEnableDiffuseMap; - bool bNormalMap = m_pNormalMap != NULL && pCamera->settings.bEnableNormalMap; - bool bSpecMap = m_pSpecularMap != NULL && pCamera->settings.bEnableSpecMap; - bool bReflectionMap = m_pReflectionMap != NULL && pCamera->settings.bEnableReflectionMap && pCamera->settings.bEnableReflection && bHasReflection; - bool bReflectionCubeMap = m_pReflectionCube != NULL && pCamera->settings.bEnableReflection && bHasReflection; - bool bAlphaTest = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_TEST) && bDiffuseMap; - bool bAlphaBlend = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE) || (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); - - - KRShader *pShader = getContext().getShaderManager()->getShader("ObjectShader", pCamera, point_lights, directional_lights, spot_lights, bones.size(), bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_reflectionMapScale != default_scale && bReflectionMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_reflectionMapOffset != default_offset && bReflectionMap, m_normalMapOffset != default_offset && bNormalMap, bAlphaTest, bAlphaBlend, renderPass); - - bool bSameShader = strcmp(pShader->getKey(), szPrevShaderKey) == 0; - if(!bSameShader) { - if(!getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, matModel, point_lights, directional_lights, spot_lights, 0, renderPass)) { - return false; - } + // Bind bones + if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) { + GLfloat bone_mats[256 * 16]; + GLfloat *bone_mat_component = bone_mats; + for(int bone_index=0; bone_index < bones.size(); bone_index++) { + KRBone *bone = bones[bone_index]; - strcpy(szPrevShaderKey, pShader->getKey()); - } - - // Bind bones - if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) { - GLfloat bone_mats[256 * 16]; - GLfloat *bone_mat_component = bone_mats; - for(int bone_index=0; bone_index < bones.size(); bone_index++) { - KRBone *bone = bones[bone_index]; - // KRVector3 initialRotation = bone->getInitialLocalRotation(); // KRVector3 rotation = bone->getLocalRotation(); // KRVector3 initialTranslation = bone->getInitialLocalTranslation(); @@ -283,143 +272,76 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC // KRVector3 initialScale = bone->getInitialLocalScale(); // KRVector3 scale = bone->getLocalScale(); // - //printf("%s - delta rotation: %.4f %.4f %.4f\n", bone->getName().c_str(), (rotation.x - initialRotation.x) * 180.0 / M_PI, (rotation.y - initialRotation.y) * 180.0 / M_PI, (rotation.z - initialRotation.z) * 180.0 / M_PI); - //printf("%s - delta translation: %.4f %.4f %.4f\n", bone->getName().c_str(), translation.x - initialTranslation.x, translation.y - initialTranslation.y, translation.z - initialTranslation.z); + //printf("%s - delta rotation: %.4f %.4f %.4f\n", bone->getName().c_str(), (rotation.x - initialRotation.x) * 180.0 / M_PI, (rotation.y - initialRotation.y) * 180.0 / M_PI, (rotation.z - initialRotation.z) * 180.0 / M_PI); + //printf("%s - delta translation: %.4f %.4f %.4f\n", bone->getName().c_str(), translation.x - initialTranslation.x, translation.y - initialTranslation.y, translation.z - initialTranslation.z); // printf("%s - delta scale: %.4f %.4f %.4f\n", bone->getName().c_str(), scale.x - initialScale.x, scale.y - initialScale.y, scale.z - initialScale.z); - - KRMat4 model_mat = bone->getActivePoseMatrix(); - KRMat4 inv_bind_mat = bone->getInverseBindPoseMatrix(); - KRMat4 t = /*KRMat4::Invert(matModel) * */(inv_bind_mat * model_mat); - for(int i=0; i < 16; i++) { - *bone_mat_component++ = t[i]; - } - } - if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) { - glUniformMatrix4fv(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS], bones.size(), GL_FALSE, bone_mats); + + KRMat4 skin_bone_bind_pose = bind_poses[bone_index]; + KRMat4 active_mat = bone->getActivePoseMatrix(); + KRMat4 inv_bind_mat = bone->getInverseBindPoseMatrix(); + KRMat4 inv_bind_mat2 = KRMat4::Invert(bind_poses[bone_index]); + KRMat4 t = (inv_bind_mat * active_mat); + KRMat4 t2 = inv_bind_mat2 * bone->getModelMatrix(); + for(int i=0; i < 16; i++) { + *bone_mat_component++ = t[i]; } } - - bool bSameAmbient = false; - bool bSameDiffuse = false; - bool bSameSpecular = false; - bool bSameReflection = false; - bool bSameAmbientScale = false; - bool bSameDiffuseScale = false; - bool bSameSpecularScale = false; - bool bSameReflectionScale = false; - bool bSameNormalScale = false; - bool bSameAmbientOffset = false; - bool bSameDiffuseOffset = false; - bool bSameSpecularOffset = false; - bool bSameReflectionOffset = false; - bool bSameNormalOffset = false; - bool bSameShininess = false; - - if(*prevBoundMaterial && bSameShader) { - bSameAmbient = (*prevBoundMaterial)->m_ambientColor == m_ambientColor; - bSameDiffuse = (*prevBoundMaterial)->m_diffuseColor == m_diffuseColor; - bSameSpecular = (*prevBoundMaterial)->m_specularColor == m_specularColor; - bSameShininess = (*prevBoundMaterial)->m_ns == m_ns; - bSameReflection = (*prevBoundMaterial)->m_reflectionColor == m_reflectionColor; - bSameAmbientScale = (*prevBoundMaterial)->m_ambientMapScale == m_ambientMapScale; - bSameDiffuseScale = (*prevBoundMaterial)->m_diffuseMapScale == m_diffuseMapScale; - bSameSpecularScale = (*prevBoundMaterial)->m_specularMapScale == m_specularMapScale; - bSameReflectionScale = (*prevBoundMaterial)->m_reflectionMapScale == m_reflectionMapScale; - bSameNormalScale = (*prevBoundMaterial)->m_normalMapScale == m_normalMapScale; - bSameAmbientOffset = (*prevBoundMaterial)->m_ambientMapOffset == m_ambientMapOffset; - bSameDiffuseOffset = (*prevBoundMaterial)->m_diffuseMapOffset == m_diffuseMapOffset; - bSameSpecularOffset = (*prevBoundMaterial)->m_specularMapOffset == m_specularMapOffset; - bSameReflectionOffset = (*prevBoundMaterial)->m_reflectionMapOffset == m_reflectionMapOffset; - bSameNormalOffset = (*prevBoundMaterial)->m_normalMapOffset == m_normalMapOffset; - } - - if(!bSameAmbient) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_AMBIENT, m_ambientColor + pCamera->settings.ambient_intensity); - } - - if(!bSameDiffuse) { - if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { - // We pre-multiply the light color with the material color in the forward renderer - pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE, KRVector3(m_diffuseColor.x * pCamera->settings.light_intensity.x, m_diffuseColor.y * pCamera->settings.light_intensity.y, m_diffuseColor.z * pCamera->settings.light_intensity.z)); - } else { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE, m_diffuseColor); - } - } - - if(!bSameSpecular) { - if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { - // We pre-multiply the light color with the material color in the forward renderer - pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR, KRVector3(m_specularColor.x * pCamera->settings.light_intensity.x, m_specularColor.y * pCamera->settings.light_intensity.y, m_specularColor.z * pCamera->settings.light_intensity.z)); - } else { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR, m_specularColor); - } - } - - if(!bSameShininess) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SHININESS, m_ns); - } - - if(!bSameReflection) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_REFLECTION, m_reflectionColor); - } - - if(bDiffuseMap && !bSameDiffuseScale && m_diffuseMapScale != default_scale) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_DIFFUSETEXTURE_SCALE, m_diffuseMapScale); - } - - if(bSpecMap && !bSameSpecularScale && m_specularMapScale != default_scale) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_SPECULARTEXTURE_SCALE, m_specularMapScale); - } - - if(bReflectionMap && !bSameReflectionScale && m_reflectionMapScale != default_scale) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_REFLECTIONTEXTURE_SCALE, m_reflectionMapScale); - } - - if(bNormalMap && !bSameNormalScale && m_normalMapScale != default_scale) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_NORMALTEXTURE_SCALE, m_normalMapScale); - } - - if(bDiffuseMap && !bSameDiffuseOffset && m_diffuseMapOffset != default_offset) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_DIFFUSETEXTURE_OFFSET, m_diffuseMapOffset); - } - - if(bSpecMap && !bSameSpecularOffset && m_specularMapOffset != default_offset) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_SPECULARTEXTURE_OFFSET, m_specularMapOffset); - } - - if(bReflectionMap && !bSameReflectionOffset && m_reflectionMapOffset != default_offset) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_REFLECTIONTEXTURE_OFFSET, m_reflectionMapOffset); - } - - if(bNormalMap && !bSameNormalOffset && m_normalMapOffset != default_offset) { - pShader->setUniform(KRShader::KRENGINE_UNIFORM_NORMALTEXTURE_OFFSET, m_normalMapOffset); - } - - pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_tr); - - if(bDiffuseMap) { - m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap); - } - - if(bSpecMap) { - m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap); + if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) { + glUniformMatrix4fv(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS], bones.size(), GL_FALSE, bone_mats); } + } + + + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_AMBIENT, m_ambientColor + pCamera->settings.ambient_intensity); + + if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { + // We pre-multiply the light color with the material color in the forward renderer + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE, KRVector3(m_diffuseColor.x * pCamera->settings.light_intensity.x, m_diffuseColor.y * pCamera->settings.light_intensity.y, m_diffuseColor.z * pCamera->settings.light_intensity.z)); + } else { + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE, m_diffuseColor); + } + + if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { + // We pre-multiply the light color with the material color in the forward renderer + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR, KRVector3(m_specularColor.x * pCamera->settings.light_intensity.x, m_specularColor.y * pCamera->settings.light_intensity.y, m_specularColor.z * pCamera->settings.light_intensity.z)); + } else { + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR, m_specularColor); + } + + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SHININESS, m_ns); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_REFLECTION, m_reflectionColor); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_DIFFUSETEXTURE_SCALE, m_diffuseMapScale); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_SPECULARTEXTURE_SCALE, m_specularMapScale); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_REFLECTIONTEXTURE_SCALE, m_reflectionMapScale); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_NORMALTEXTURE_SCALE, m_normalMapScale); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_DIFFUSETEXTURE_OFFSET, m_diffuseMapOffset); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_SPECULARTEXTURE_OFFSET, m_specularMapOffset); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_REFLECTIONTEXTURE_OFFSET, m_reflectionMapOffset); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_NORMALTEXTURE_OFFSET, m_normalMapOffset); + + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_tr); + + if(bDiffuseMap) { + m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap); + } + + if(bSpecMap) { + m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap); + } + + if(bNormalMap) { + m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap); + } + + if(bReflectionCubeMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { + m_pContext->getTextureManager()->selectTexture(4, m_pReflectionCube); + } + + if(bReflectionMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { + // GL_TEXTURE7 is used for reading the depth buffer in gBuffer pass 2 and re-used for the reflection map in gBuffer Pass 3 and in forward rendering + m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap); + } - if(bNormalMap) { - m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap); - } - - if(bReflectionCubeMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { - m_pContext->getTextureManager()->selectTexture(4, m_pReflectionCube); - } - - if(bReflectionMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { - // GL_TEXTURE7 is used for reading the depth buffer in gBuffer pass 2 and re-used for the reflection map in gBuffer Pass 3 and in forward rendering - m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap); - } - - *prevBoundMaterial = this; - } // if(!bSameMaterial) return true; } diff --git a/KREngine/kraken/KRMaterial.h b/KREngine/kraken/KRMaterial.h index a87e957..7b88eb8 100644 --- a/KREngine/kraken/KRMaterial.h +++ b/KREngine/kraken/KRMaterial.h @@ -83,7 +83,7 @@ public: bool isTransparent(); const std::string &getName() const; - bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass); + bool bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass); bool needsVertexTangents(); diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index 875678e..1afe334 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -159,9 +159,6 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect } } - KRMaterial *pPrevBoundMaterial = NULL; - char szPrevShaderKey[256]; - szPrevShaderKey[0] = '\0'; int cSubmeshes = m_submeshes.size(); if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) { for(int iSubmesh=0; iSubmeshisTransparent() && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { - if(pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, point_lights, directional_lights, spot_lights, bones, viewport, matModel, pLightMap, renderPass)) { + std::vector bone_bind_poses; + for(int i=0; i < bones.size(); i++) { + bone_bind_poses.push_back(getBoneBindPose(i)); + } + if(pMaterial->bind(pCamera, point_lights, directional_lights, spot_lights, bones, bone_bind_poses, viewport, matModel, pLightMap, renderPass)) { switch(pMaterial->getAlphaMode()) { case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials @@ -347,7 +348,7 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st } -void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector > vertex_index_bases, std::vector vertices, std::vector uva, std::vector uvb, std::vector normals, std::vector tangents, std::vector submesh_starts, std::vector submesh_lengths, std::vector material_names, std::vector bone_names, std::vector > bone_indexes, std::vector > bone_weights, KRMesh::model_format_t model_format, bool calculate_normals, bool calculate_tangents) { +void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vector > vertex_index_bases, std::vector vertices, std::vector uva, std::vector uvb, std::vector normals, std::vector tangents, std::vector submesh_starts, std::vector submesh_lengths, std::vector material_names, std::vector bone_names, std::vector bone_bind_poses, std::vector > bone_indexes, std::vector > bone_weights, model_format_t model_format, */const KRMesh::mesh_info &mi, bool calculate_normals, bool calculate_tangents) { clearData(); @@ -359,27 +360,15 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector::iterator itr=vertices.begin(); itr != vertices.end(); itr++) { + for(std::vector::const_iterator itr=mi.vertices.begin(); itr != mi.vertices.end(); itr++) { if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f || fabsf((*itr).z) > 1.0f) { use_short_vertexes = false; } } } - if(use_short_normals) { - for(std::vector::iterator itr=normals.begin(); itr != normals.end(); itr++) { - (*itr).normalize(); - } - } - - if(use_short_tangents) { - for(std::vector::iterator itr=tangents.begin(); itr != tangents.end(); itr++) { - (*itr).normalize(); - } - } - if(use_short_uva) { - for(std::vector::iterator itr=uva.begin(); itr != uva.end(); itr++) { + for(std::vector::const_iterator itr=mi.uva.begin(); itr != mi.uva.end(); itr++) { if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) { use_short_uva = false; } @@ -387,7 +376,7 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector::iterator itr=uvb.begin(); itr != uvb.end(); itr++) { + for(std::vector::const_iterator itr=mi.uvb.begin(); itr != mi.uvb.end(); itr++) { if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) { use_short_uvb = false; } @@ -395,50 +384,50 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vectorexpand(new_file_size); @@ -451,7 +440,7 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vectorbone_count = (__int32_t)bone_count; pHeader->index_count = (__int32_t)index_count; pHeader->index_base_count = (__int32_t)index_base_count; - pHeader->model_format = model_format; + pHeader->model_format = mi.format; strcpy(pHeader->szTag, "KROBJPACK1.2 "); updateAttributeOffsets(); @@ -459,28 +448,29 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vectorsubmesh_count; iMaterial++) { pack_material *pPackMaterial = pPackMaterials + iMaterial; - pPackMaterial->start_vertex = submesh_starts[iMaterial]; - pPackMaterial->vertex_count = submesh_lengths[iMaterial]; + pPackMaterial->start_vertex = mi.submesh_starts[iMaterial]; + pPackMaterial->vertex_count = mi.submesh_lengths[iMaterial]; memset(pPackMaterial->szName, 0, KRENGINE_MAX_NAME_LENGTH); - strncpy(pPackMaterial->szName, material_names[iMaterial].c_str(), KRENGINE_MAX_NAME_LENGTH); + strncpy(pPackMaterial->szName, mi.material_names[iMaterial].c_str(), KRENGINE_MAX_NAME_LENGTH); } for(int bone_index=0; bone_index < bone_count; bone_index++) { pack_bone *bone = getBone(bone_index); memset(bone->szName, 0, KRENGINE_MAX_NAME_LENGTH); - strncpy(bone->szName, bone_names[bone_index].c_str(), KRENGINE_MAX_NAME_LENGTH); + strncpy(bone->szName, mi.bone_names[bone_index].c_str(), KRENGINE_MAX_NAME_LENGTH); + memcpy(bone->bind_pose, mi.bone_bind_poses[bone_index].c, sizeof(float) * 16); } bool bFirstVertex = true; - memset(getVertexData(), 0, m_vertex_size * vertices.size()); - for(int iVertex=0; iVertex < vertices.size(); iVertex++) { - KRVector3 source_vertex = vertices[iVertex]; + memset(getVertexData(), 0, m_vertex_size * mi.vertices.size()); + for(int iVertex=0; iVertex < mi.vertices.size(); iVertex++) { + KRVector3 source_vertex = mi.vertices[iVertex]; setVertexPosition(iVertex, source_vertex); - if(bone_names.size()) { + if(mi.bone_names.size()) { for(int bone_weight_index=0; bone_weight_index vertex_indexes, std::vector m_maxPoint.y) m_maxPoint.y = source_vertex.y; if(source_vertex.z > m_maxPoint.z) m_maxPoint.z = source_vertex.z; } - if(uva.size() > iVertex) { - setVertexUVA(iVertex, uva[iVertex]); + if(mi.uva.size() > iVertex) { + setVertexUVA(iVertex, mi.uva[iVertex]); } - if(uvb.size() > iVertex) { - setVertexUVB(iVertex, uvb[iVertex]); + if(mi.uvb.size() > iVertex) { + setVertexUVB(iVertex, mi.uvb[iVertex]); } - if(normals.size() > iVertex) { - setVertexNormal(iVertex, normals[iVertex]); + if(mi.normals.size() > iVertex) { + setVertexNormal(iVertex, KRVector3::Normalize(mi.normals[iVertex])); } - if(tangents.size() > iVertex) { - setVertexTangent(iVertex, tangents[iVertex]); + if(mi.tangents.size() > iVertex) { + setVertexTangent(iVertex, KRVector3::Normalize(mi.tangents[iVertex])); } } @@ -518,12 +508,12 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector::iterator itr=vertex_indexes.begin(); itr != vertex_indexes.end(); itr++) { + for(std::vector<__uint16_t>::const_iterator itr=mi.vertex_indexes.begin(); itr != mi.vertex_indexes.end(); itr++) { *index_data++ = *itr; } __uint32_t *index_base_data = getIndexBaseData(); - for(std::vector >::iterator itr=vertex_index_bases.begin(); itr != vertex_index_bases.end(); itr++) { + for(std::vector >::const_iterator itr=mi.vertex_index_bases.begin(); itr != mi.vertex_index_bases.end(); itr++) { *index_base_data++ = (*itr).first; *index_base_data++ = (*itr).second; } @@ -533,7 +523,7 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vectorszName; } +KRMat4 KRMesh::getBoneBindPose(int bone_index) +{ + return KRMat4(getBone(bone_index)->bind_pose); +} + KRMesh::model_format_t KRMesh::getModelFormat() const { return (model_format_t)getHeader()->model_format; @@ -1064,30 +1059,19 @@ void KRMesh::convertToIndexed() char *szKey = new char[m_vertex_size * 2 + 1]; // Convert model to indexed vertices, identying vertexes with identical attributes and optimizing order of trianges for best usage post-vertex-transform cache on GPU - std::vector<__uint16_t> vertex_indexes; - std::vector > vertex_index_bases; int vertex_index_offset = 0; int vertex_index_base_start_vertex = 0; - std::vector vertices; - std::vector uva; - std::vector uvb; - std::vector normals; - std::vector tangents; - std::vector submesh_starts; - std::vector submesh_lengths; - std::vector material_names; - std::vector bone_names; - std::vector > bone_indexes; - std::vector > bone_weights; + mesh_info mi; int bone_count = getBoneCount(); for(int bone_index=0; bone_index < bone_count; bone_index++) { - bone_names.push_back(getBoneName(bone_index)); + mi.bone_names.push_back(getBoneName(bone_index)); + mi.bone_bind_poses.push_back(getBoneBindPose(bone_index)); } for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) { - material_names.push_back(getSubmesh(submesh_index)->szName); + mi.material_names.push_back(getSubmesh(submesh_index)->szName); int vertexes_remaining = getVertexCount(submesh_index); @@ -1097,13 +1081,13 @@ void KRMesh::convertToIndexed() } if(submesh_index == 0 || vertex_index_offset + vertex_count > 0xffff) { - vertex_index_bases.push_back(std::pair(vertex_indexes.size(), vertices.size())); + mi.vertex_index_bases.push_back(std::pair(mi.vertex_indexes.size(), mi.vertices.size())); vertex_index_offset = 0; - vertex_index_base_start_vertex = vertices.size(); + vertex_index_base_start_vertex = mi.vertices.size(); } - submesh_starts.push_back(vertex_index_bases.size() - 1 + (vertex_index_offset << 16)); - submesh_lengths.push_back(vertexes_remaining); + mi.submesh_starts.push_back(mi.vertex_index_bases.size() - 1 + (vertex_index_offset << 16)); + mi.submesh_lengths.push_back(vertexes_remaining); int source_index = getSubmesh(submesh_index)->start_vertex; @@ -1189,35 +1173,35 @@ void KRMesh::convertToIndexed() */ int found_index = -1; if(prev_indexes.count(vertex_key) == 0) { - found_index = vertices.size() - vertex_index_base_start_vertex; + found_index = mi.vertices.size() - vertex_index_base_start_vertex; if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX) || has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { - vertices.push_back(vertex_position); + mi.vertices.push_back(vertex_position); } if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL) || has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { - normals.push_back(vertex_normal); + mi.normals.push_back(vertex_normal); } if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT) || has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { - tangents.push_back(vertex_tangent); + mi.tangents.push_back(vertex_tangent); } if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { - uva.push_back(vertex_uva); + mi.uva.push_back(vertex_uva); } if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { - uvb.push_back(vertex_uvb); + mi.uvb.push_back(vertex_uvb); } if(has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) { - bone_indexes.push_back(vertex_bone_indexes); + mi.bone_indexes.push_back(vertex_bone_indexes); } if(has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS)) { - bone_weights.push_back(vertex_bone_weights); + mi.bone_weights.push_back(vertex_bone_weights); } prev_indexes[vertex_key] = found_index; } else { found_index = prev_indexes[vertex_key]; } - vertex_indexes.push_back(found_index); + mi.vertex_indexes.push_back(found_index); //fprintf(stderr, "Submesh: %6i IndexBase: %3i Index: %6i\n", submesh_index, vertex_index_bases.size(), found_index); source_index++; @@ -1233,20 +1217,20 @@ void KRMesh::convertToIndexed() } if(vertex_index_offset + vertex_count > 0xffff) { - vertex_index_bases.push_back(std::pair(vertex_indexes.size(), vertices.size())); + mi.vertex_index_bases.push_back(std::pair(mi.vertex_indexes.size(), mi.vertices.size())); vertex_index_offset = 0; - vertex_index_base_start_vertex = vertices.size(); + vertex_index_base_start_vertex = mi.vertices.size(); } } } delete szKey; - fprintf(stderr, "Convert to indexed, before: %i after: %i \(%.2f%% saving)\n", getHeader()->vertex_count, vertices.size(), ((float)getHeader()->vertex_count - (float)vertices.size()) / (float)getHeader()->vertex_count * 100.0f); + fprintf(stderr, "Convert to indexed, before: %i after: %i \(%.2f%% saving)\n", getHeader()->vertex_count, mi.vertices.size(), ((float)getHeader()->vertex_count - (float)mi.vertices.size()) / (float)getHeader()->vertex_count * 100.0f); - - LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights, KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES, false, false); + mi.format = KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES; + LoadData(mi, false, false); } void KRMesh::optimize() diff --git a/KREngine/kraken/KRMesh.h b/KREngine/kraken/KRMesh.h index bf5b9a1..abc03d7 100644 --- a/KREngine/kraken/KRMesh.h +++ b/KREngine/kraken/KRMesh.h @@ -31,6 +31,7 @@ #include "KREngine-common.h" #include "KRVector2.h" +#include "KRMat4.h" #include "KRContext.h" #include "KRBone.h" @@ -58,6 +59,9 @@ class KRNode; class KRMesh : public KRResource { public: + + + KRMesh(KRContext &context, std::string name, KRDataBlock *data); KRMesh(KRContext &context, std::string name); virtual ~KRMesh(); @@ -87,6 +91,23 @@ public: KRENGINE_MODEL_FORMAT_INDEXED_STRIP } model_format_t; + typedef struct { + model_format_t format; + std::vector vertices; + std::vector<__uint16_t> vertex_indexes; + std::vector > vertex_index_bases; + std::vector uva; + std::vector uvb; + std::vector normals; + std::vector tangents; + std::vector submesh_starts; + std::vector submesh_lengths; + std::vector material_names; + std::vector bone_names; + std::vector > bone_indexes; + std::vector bone_bind_poses; + std::vector > bone_weights; + } mesh_info; void render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones); @@ -96,7 +117,7 @@ public: virtual bool save(const std::string& path); virtual bool save(KRDataBlock &data); - void LoadData(std::vector<__uint16_t> vertex_indexes, std::vector > vertex_index_bases, std::vector vertices, std::vector uva, std::vector uvb, std::vector normals, std::vector tangents, std::vector submesh_starts, std::vector submesh_lengths, std::vector material_names, std::vector bone_names, std::vector > bone_indexes, std::vector > bone_weights, model_format_t model_format, bool calculate_normals, bool calculate_tangents); + void LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vector > vertex_index_bases, std::vector vertices, std::vector uva, std::vector uvb, std::vector normals, std::vector tangents, std::vector submesh_starts, std::vector submesh_lengths, std::vector material_names, std::vector bone_names, std::vector bone_bind_poses, std::vector > bone_indexes, std::vector > bone_weights, model_format_t model_format, */const mesh_info &mi, bool calculate_normals, bool calculate_tangents); void loadPack(KRDataBlock *data); void convertToIndexed(); @@ -132,6 +153,7 @@ public: typedef struct { char szName[KRENGINE_MAX_NAME_LENGTH]; + float bind_pose[16]; } pack_bone; int getLODCoverage() const; @@ -166,6 +188,7 @@ public: int getBoneCount(); char *getBoneName(int bone_index); + KRMat4 getBoneBindPose(int bone_index); model_format_t getModelFormat() const; diff --git a/KREngine/kraken/KRMeshCube.cpp b/KREngine/kraken/KRMeshCube.cpp index 0ade016..1d48c44 100644 --- a/KREngine/kraken/KRMeshCube.cpp +++ b/KREngine/kraken/KRMeshCube.cpp @@ -34,43 +34,32 @@ KRMeshCube::KRMeshCube(KRContext &context) : KRMesh(context, "__cube") { - std::vector vertices; - std::vector uva; - std::vector uvb; - std::vector normals; - std::vector tangents; - std::vector submesh_starts; - std::vector submesh_lengths; - std::vector material_names; - std::vector bone_names; - std::vector > bone_indexes; - std::vector > bone_weights; + KRMesh::mesh_info mi; - vertices.push_back(KRVector3(1.0, 1.0, 1.0)); - vertices.push_back(KRVector3(-1.0, 1.0, 1.0)); - vertices.push_back(KRVector3(1.0,-1.0, 1.0)); - vertices.push_back(KRVector3(-1.0,-1.0, 1.0)); - vertices.push_back(KRVector3(-1.0,-1.0,-1.0)); - vertices.push_back(KRVector3(-1.0, 1.0, 1.0)); - vertices.push_back(KRVector3(-1.0, 1.0,-1.0)); - vertices.push_back(KRVector3(1.0, 1.0, 1.0)); - vertices.push_back(KRVector3(1.0, 1.0,-1.0)); - vertices.push_back(KRVector3(1.0,-1.0, 1.0)); - vertices.push_back(KRVector3(1.0,-1.0,-1.0)); - vertices.push_back(KRVector3(-1.0,-1.0,-1.0)); - vertices.push_back(KRVector3(1.0, 1.0,-1.0)); - vertices.push_back(KRVector3(-1.0, 1.0,-1.0)); + mi.vertices.push_back(KRVector3(1.0, 1.0, 1.0)); + mi.vertices.push_back(KRVector3(-1.0, 1.0, 1.0)); + mi.vertices.push_back(KRVector3(1.0,-1.0, 1.0)); + mi.vertices.push_back(KRVector3(-1.0,-1.0, 1.0)); + mi.vertices.push_back(KRVector3(-1.0,-1.0,-1.0)); + mi.vertices.push_back(KRVector3(-1.0, 1.0, 1.0)); + mi.vertices.push_back(KRVector3(-1.0, 1.0,-1.0)); + mi.vertices.push_back(KRVector3(1.0, 1.0, 1.0)); + mi.vertices.push_back(KRVector3(1.0, 1.0,-1.0)); + mi.vertices.push_back(KRVector3(1.0,-1.0, 1.0)); + mi.vertices.push_back(KRVector3(1.0,-1.0,-1.0)); + mi.vertices.push_back(KRVector3(-1.0,-1.0,-1.0)); + mi.vertices.push_back(KRVector3(1.0, 1.0,-1.0)); + mi.vertices.push_back(KRVector3(-1.0, 1.0,-1.0)); - submesh_starts.push_back(0); - submesh_lengths.push_back(vertices.size()); - material_names.push_back(""); + mi.submesh_starts.push_back(0); + mi.submesh_lengths.push_back(mi.vertices.size()); + mi.material_names.push_back(""); + mi.format = KRENGINE_MODEL_FORMAT_STRIP; + - std::vector<__uint16_t> vertex_indexes; - std::vector > vertex_index_bases; - - LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights, KRENGINE_MODEL_FORMAT_STRIP, true, true); + LoadData(mi, true, true); } KRMeshCube::~KRMeshCube() diff --git a/KREngine/kraken/KRMeshSphere.cpp b/KREngine/kraken/KRMeshSphere.cpp index 71cf29f..cb581a7 100644 --- a/KREngine/kraken/KRMeshSphere.cpp +++ b/KREngine/kraken/KRMeshSphere.cpp @@ -34,19 +34,7 @@ KRMeshSphere::KRMeshSphere(KRContext &context) : KRMesh(context, "__sphere") { - std::vector vertices; - std::vector uva; - std::vector uvb; - std::vector normals; - std::vector tangents; - std::vector submesh_starts; - std::vector submesh_lengths; - std::vector material_names; - std::vector bone_names; - std::vector > bone_indexes; - std::vector > bone_weights; - - + KRMesh::mesh_info mi; // Create a triangular facet approximation to a sphere // Based on algorithm from Paul Bourke: http://paulbourke.net/miscellaneous/sphere_cylinder/ @@ -125,19 +113,18 @@ KRMeshSphere::KRMeshSphere(KRContext &context) : KRMesh(context, "__sphere") } for(int facet_index=0; facet_index < facet_count; facet_index++) { - vertices.push_back(f[facet_index].p1); - vertices.push_back(f[facet_index].p2); - vertices.push_back(f[facet_index].p3); + mi.vertices.push_back(f[facet_index].p1); + mi.vertices.push_back(f[facet_index].p2); + mi.vertices.push_back(f[facet_index].p3); } - submesh_starts.push_back(0); - submesh_lengths.push_back(vertices.size()); - material_names.push_back(""); + mi.submesh_starts.push_back(0); + mi.submesh_lengths.push_back(mi.vertices.size()); + mi.material_names.push_back(""); - std::vector<__uint16_t> vertex_indexes; - std::vector > vertex_index_bases; - - LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights, KRENGINE_MODEL_FORMAT_TRIANGLES, true, true); + + mi.format = KRENGINE_MODEL_FORMAT_TRIANGLES; + LoadData(mi, true, true); } KRMeshSphere::~KRMeshSphere() diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index 32157c7..56d8093 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -34,6 +34,22 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont m_initialLocalScale = m_localScale; m_initialLocalRotation = m_localRotation; + + + m_rotationOffset = KRVector3::Zero(); + m_scalingOffset = KRVector3::Zero(); + m_rotationPivot = KRVector3::Zero(); + m_scalingPivot = KRVector3::Zero(); + m_preRotation = KRVector3::Zero(); + m_postRotation = KRVector3::Zero(); + + m_initialRotationOffset = KRVector3::Zero(); + m_initialScalingOffset = KRVector3::Zero(); + m_initialRotationPivot = KRVector3::Zero(); + m_initialScalingPivot = KRVector3::Zero(); + m_initialPreRotation = KRVector3::Zero(); + m_initialPostRotation = KRVector3::Zero(); + m_parentNode = NULL; m_pScene = &scene; m_modelMatrixValid = false; @@ -46,16 +62,29 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont m_activePoseMatrix = KRMat4(); m_lod_visible = false; m_scale_compensation = false; + + m_lastRenderFrame = -1000; + for(int i=0; i < KRENGINE_NODE_ATTRIBUTE_COUNT; i++) { + m_animation_mask[i] = false; + } } KRNode::~KRNode() { + + while(m_childNodes.size() > 0) { delete *m_childNodes.begin(); } + + for(std::set::iterator itr = m_behaviors.begin(); itr != m_behaviors.end(); itr++) { + delete *itr; + } + m_behaviors.clear(); if(m_parentNode) { m_parentNode->childDeleted(this); } + getScene().notify_sceneGraphDelete(this); } @@ -181,9 +210,13 @@ void KRNode::setWorldTranslation(const KRVector3 &v) void KRNode::setWorldRotation(const KRVector3 &v) { if(m_parentNode) { - setLocalRotation(KRMat4::DotNoTranslate(m_parentNode->getInverseModelMatrix(), v)); + setLocalRotation((KRQuaternion(v) * -m_parentNode->getWorldRotation()).eulerXYZ()); + setPreRotation(KRVector3::Zero()); + setPostRotation(KRVector3::Zero()); } else { setLocalRotation(v); + setPreRotation(KRVector3::Zero()); + setPostRotation(KRVector3::Zero()); } } @@ -349,32 +382,6 @@ const KRVector3 KRNode::getWorldTranslation() { const KRVector3 KRNode::getWorldScale() { return KRMat4::DotNoTranslate(getModelMatrix(), m_localScale); } -const KRVector3 KRNode::getWorldRotation() { - KRVector3 world_rotation = (-KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation)).eulerXYZ();; - if(m_parentNode) { - KRVector3 parent_rotation = m_parentNode->getWorldRotation(); - world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ(); - } - return world_rotation; -} - -const KRVector3 KRNode::getBindPoseWorldRotation() { - KRVector3 world_rotation = (-KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation)).eulerXYZ(); - if(dynamic_cast(m_parentNode)) { - KRVector3 parent_rotation = m_parentNode->getBindPoseWorldRotation(); - world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ(); - } - return world_rotation; -} - -const KRVector3 KRNode::getActivePoseWorldRotation() { - KRVector3 world_rotation = (KRQuaternion(m_preRotation) * KRQuaternion(m_localRotation) * -KRQuaternion(m_postRotation)).eulerXYZ(); - if(dynamic_cast(m_parentNode)) { - KRVector3 parent_rotation = m_parentNode->getActivePoseWorldRotation(); - world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ(); - } - return world_rotation; -} std::string KRNode::getElementName() { return "node"; @@ -420,8 +427,10 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) { new_node = new KRAmbientZone(scene, szName); } else if(strcmp(szElementName, "reverb_zone") == 0) { new_node = new KRReverbZone(scene, szName); + } else if(strcmp(szElementName, "camera") == 0) { + new_node = new KRCamera(scene, szName); } - + if(new_node) { new_node->loadXML(e); } @@ -431,6 +440,7 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) { void KRNode::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, RenderPass renderPass) { + m_lastRenderFrame = getContext().getCurrentFrame(); } const std::set &KRNode::getChildren() { @@ -500,23 +510,21 @@ const KRMat4 &KRNode::getModelMatrix() } if(getScaleCompensation() && parent_is_bone) { - m_modelMatrix.translate(-m_scalingPivot); - m_modelMatrix.scale(m_localScale); - m_modelMatrix.translate(m_scalingPivot); - m_modelMatrix.translate(m_scalingOffset); - m_modelMatrix.translate(-m_rotationPivot); - m_modelMatrix.rotate(-m_postRotation.z, Z_AXIS); - m_modelMatrix.rotate(-m_postRotation.y, Y_AXIS); - m_modelMatrix.rotate(-m_postRotation.x, X_AXIS); - m_modelMatrix.rotate(m_localRotation.x, X_AXIS); - m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); - m_modelMatrix.rotate(m_localRotation.z, Z_AXIS); - m_modelMatrix.rotate(m_preRotation.x, X_AXIS); - m_modelMatrix.rotate(m_preRotation.y, Y_AXIS); - m_modelMatrix.rotate(m_preRotation.z, Z_AXIS); - m_modelMatrix.translate(m_rotationPivot); - m_modelMatrix.translate(m_rotationOffset); - //m_modelMatrix.translate(m_localTranslation); + + + // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 + m_modelMatrix = KRMat4::Translation(-m_scalingPivot) + * KRMat4::Scaling(m_localScale) + * KRMat4::Translation(m_scalingPivot) + * KRMat4::Translation(m_scalingOffset) + * KRMat4::Translation(-m_rotationPivot) + //* (KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation)).rotationMatrix() + * KRMat4::Rotation(m_postRotation) + * KRMat4::Rotation(m_localRotation) + * KRMat4::Rotation(m_preRotation) + * KRMat4::Translation(m_rotationPivot) + * KRMat4::Translation(m_rotationOffset); + if(m_parentNode) { m_modelMatrix.rotate(m_parentNode->getWorldRotation()); @@ -527,25 +535,19 @@ const KRMat4 &KRNode::getModelMatrix() } else { // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 - m_modelMatrix.translate(-m_scalingPivot); - m_modelMatrix.scale(m_localScale); - m_modelMatrix.translate(m_scalingPivot); - m_modelMatrix.translate(m_scalingOffset); - m_modelMatrix.translate(-m_rotationPivot); - m_modelMatrix.rotate(-m_postRotation.z, Z_AXIS); - m_modelMatrix.rotate(-m_postRotation.y, Y_AXIS); - m_modelMatrix.rotate(-m_postRotation.x, X_AXIS); - m_modelMatrix.rotate(m_localRotation.x, X_AXIS); - m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); - m_modelMatrix.rotate(m_localRotation.z, Z_AXIS); - m_modelMatrix.rotate(m_preRotation.x, X_AXIS); - m_modelMatrix.rotate(m_preRotation.y, Y_AXIS); - m_modelMatrix.rotate(m_preRotation.z, Z_AXIS); - m_modelMatrix.translate(m_rotationPivot); - m_modelMatrix.translate(m_rotationOffset); - m_modelMatrix.translate(m_localTranslation); - - + m_modelMatrix = KRMat4::Translation(-m_scalingPivot) + * KRMat4::Scaling(m_localScale) + * KRMat4::Translation(m_scalingPivot) + * KRMat4::Translation(m_scalingOffset) + * KRMat4::Translation(-m_rotationPivot) + //* (KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation)).rotationMatrix() + * KRMat4::Rotation(m_postRotation) + * KRMat4::Rotation(m_localRotation) + * KRMat4::Rotation(m_preRotation) + * KRMat4::Translation(m_rotationPivot) + * KRMat4::Translation(m_rotationOffset) + * KRMat4::Translation(m_localTranslation); + if(m_parentNode) { m_modelMatrix *= m_parentNode->getModelMatrix(); } @@ -568,22 +570,17 @@ const KRMat4 &KRNode::getBindPoseMatrix() } if(getScaleCompensation() && parent_is_bone) { - m_bindPoseMatrix.translate(-m_initialScalingPivot); - m_bindPoseMatrix.scale(m_initialLocalScale); - m_bindPoseMatrix.translate(m_initialScalingPivot); - m_bindPoseMatrix.translate(m_initialScalingOffset); - m_bindPoseMatrix.translate(-m_initialRotationPivot); - m_bindPoseMatrix.rotate(-m_initialPostRotation.z, Z_AXIS); - m_bindPoseMatrix.rotate(-m_initialPostRotation.y, Y_AXIS); - m_bindPoseMatrix.rotate(-m_initialPostRotation.x, X_AXIS); - m_bindPoseMatrix.rotate(m_initialLocalRotation.x, X_AXIS); - m_bindPoseMatrix.rotate(m_initialLocalRotation.y, Y_AXIS); - m_bindPoseMatrix.rotate(m_initialLocalRotation.z, Z_AXIS); - m_bindPoseMatrix.rotate(m_initialPreRotation.x, X_AXIS); - m_bindPoseMatrix.rotate(m_initialPreRotation.y, Y_AXIS); - m_bindPoseMatrix.rotate(m_initialPreRotation.z, Z_AXIS); - m_bindPoseMatrix.translate(m_initialRotationPivot); - m_bindPoseMatrix.translate(m_initialRotationOffset); + m_bindPoseMatrix = KRMat4::Translation(-m_initialScalingPivot) + * KRMat4::Scaling(m_initialLocalScale) + * KRMat4::Translation(m_initialScalingPivot) + * KRMat4::Translation(m_initialScalingOffset) + * KRMat4::Translation(-m_initialRotationPivot) + //* (KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation)).rotationMatrix() + * KRMat4::Rotation(m_initialPostRotation) + * KRMat4::Rotation(m_initialLocalRotation) + * KRMat4::Rotation(m_initialPreRotation) + * KRMat4::Translation(m_initialRotationPivot) + * KRMat4::Translation(m_initialRotationOffset); //m_bindPoseMatrix.translate(m_localTranslation); if(m_parentNode) { @@ -595,26 +592,22 @@ const KRMat4 &KRNode::getBindPoseMatrix() } else { // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 - m_bindPoseMatrix.translate(-m_scalingPivot); - m_bindPoseMatrix.scale(m_localScale); - m_bindPoseMatrix.translate(m_scalingPivot); - m_bindPoseMatrix.translate(m_scalingOffset); - m_bindPoseMatrix.translate(-m_rotationPivot); - m_bindPoseMatrix.rotate(-m_postRotation.z, Z_AXIS); - m_bindPoseMatrix.rotate(-m_postRotation.y, Y_AXIS); - m_bindPoseMatrix.rotate(-m_postRotation.x, X_AXIS); - m_bindPoseMatrix.rotate(m_localRotation.x, X_AXIS); - m_bindPoseMatrix.rotate(m_localRotation.y, Y_AXIS); - m_bindPoseMatrix.rotate(m_localRotation.z, Z_AXIS); - m_bindPoseMatrix.rotate(m_preRotation.x, X_AXIS); - m_bindPoseMatrix.rotate(m_preRotation.y, Y_AXIS); - m_bindPoseMatrix.rotate(m_preRotation.z, Z_AXIS); - m_bindPoseMatrix.translate(m_rotationPivot); - m_bindPoseMatrix.translate(m_rotationOffset); - m_bindPoseMatrix.translate(m_localTranslation); + m_bindPoseMatrix = KRMat4::Translation(-m_initialScalingPivot) + * KRMat4::Scaling(m_initialLocalScale) + * KRMat4::Translation(m_initialScalingPivot) + * KRMat4::Translation(m_initialScalingOffset) + * KRMat4::Translation(-m_initialRotationPivot) + // * (KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation)).rotationMatrix() + * KRMat4::Rotation(m_initialPostRotation) + * KRMat4::Rotation(m_initialLocalRotation) + * KRMat4::Rotation(m_initialPreRotation) + * KRMat4::Translation(m_initialRotationPivot) + * KRMat4::Translation(m_initialRotationOffset) + * KRMat4::Translation(m_initialLocalTranslation); if(m_parentNode && parent_is_bone) { + m_bindPoseMatrix *= m_parentNode->getBindPoseMatrix(); } } @@ -637,25 +630,20 @@ const KRMat4 &KRNode::getActivePoseMatrix() } if(getScaleCompensation() && parent_is_bone) { - m_activePoseMatrix.translate(-m_scalingPivot); - m_activePoseMatrix.scale(m_localScale); - m_activePoseMatrix.translate(m_scalingPivot); - m_activePoseMatrix.translate(m_scalingOffset); - m_activePoseMatrix.translate(-m_rotationPivot); - m_activePoseMatrix.rotate(-m_postRotation.z, Z_AXIS); - m_activePoseMatrix.rotate(-m_postRotation.y, Y_AXIS); - m_activePoseMatrix.rotate(-m_postRotation.x, X_AXIS); - m_activePoseMatrix.rotate(m_localRotation.x, X_AXIS); - m_activePoseMatrix.rotate(m_localRotation.y, Y_AXIS); - m_activePoseMatrix.rotate(m_localRotation.z, Z_AXIS); - m_activePoseMatrix.rotate(m_preRotation.x, X_AXIS); - m_activePoseMatrix.rotate(m_preRotation.y, Y_AXIS); - m_activePoseMatrix.rotate(m_preRotation.z, Z_AXIS); - m_activePoseMatrix.translate(m_rotationPivot); - m_activePoseMatrix.translate(m_rotationOffset); + m_activePoseMatrix= KRMat4::Translation(-m_scalingPivot) + * KRMat4::Scaling(m_localScale) + * KRMat4::Translation(m_scalingPivot) + * KRMat4::Translation(m_scalingOffset) + * KRMat4::Translation(-m_rotationPivot) + * KRMat4::Rotation(m_postRotation) + * KRMat4::Rotation(m_localRotation) + * KRMat4::Rotation(m_preRotation) + * KRMat4::Translation(m_rotationPivot) + * KRMat4::Translation(m_rotationOffset); + if(m_parentNode) { - m_activePoseMatrix.rotate(m_parentNode->getWorldRotation()); + m_activePoseMatrix.rotate(m_parentNode->getActivePoseWorldRotation()); m_activePoseMatrix.translate(KRMat4::Dot(m_parentNode->getActivePoseMatrix(), m_localTranslation)); } else { m_activePoseMatrix.translate(m_localTranslation); @@ -663,23 +651,17 @@ const KRMat4 &KRNode::getActivePoseMatrix() } else { // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 - m_activePoseMatrix.translate(-m_scalingPivot); - m_activePoseMatrix.scale(m_localScale); - m_activePoseMatrix.translate(m_scalingPivot); - m_activePoseMatrix.translate(m_scalingOffset); - m_activePoseMatrix.translate(-m_rotationPivot); - m_activePoseMatrix.rotate(-m_postRotation.z, Z_AXIS); - m_activePoseMatrix.rotate(-m_postRotation.y, Y_AXIS); - m_activePoseMatrix.rotate(-m_postRotation.x, X_AXIS); - m_activePoseMatrix.rotate(m_localRotation.x, X_AXIS); - m_activePoseMatrix.rotate(m_localRotation.y, Y_AXIS); - m_activePoseMatrix.rotate(m_localRotation.z, Z_AXIS); - m_activePoseMatrix.rotate(m_preRotation.x, X_AXIS); - m_activePoseMatrix.rotate(m_preRotation.y, Y_AXIS); - m_activePoseMatrix.rotate(m_preRotation.z, Z_AXIS); - m_activePoseMatrix.translate(m_rotationPivot); - m_activePoseMatrix.translate(m_rotationOffset); - m_activePoseMatrix.translate(m_localTranslation); + m_activePoseMatrix = KRMat4::Translation(-m_scalingPivot) + * KRMat4::Scaling(m_localScale) + * KRMat4::Translation(m_scalingPivot) + * KRMat4::Translation(m_scalingOffset) + * KRMat4::Translation(-m_rotationPivot) + * KRMat4::Rotation(m_postRotation) + * KRMat4::Rotation(m_localRotation) + * KRMat4::Rotation(m_preRotation) + * KRMat4::Translation(m_rotationPivot) + * KRMat4::Translation(m_rotationOffset) + * KRMat4::Translation(m_localTranslation); if(m_parentNode && parent_is_bone) { @@ -694,6 +676,30 @@ const KRMat4 &KRNode::getActivePoseMatrix() } +const KRQuaternion KRNode::getWorldRotation() { + KRQuaternion world_rotation = KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation); + if(m_parentNode) { + world_rotation = world_rotation * m_parentNode->getWorldRotation(); + } + return world_rotation; +} + +const KRQuaternion KRNode::getBindPoseWorldRotation() { + KRQuaternion world_rotation = KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation); + if(dynamic_cast(m_parentNode)) { + world_rotation = world_rotation * m_parentNode->getBindPoseWorldRotation(); + } + return world_rotation; +} + +const KRQuaternion KRNode::getActivePoseWorldRotation() { + KRQuaternion world_rotation = KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation); + if(dynamic_cast(m_parentNode)) { + world_rotation = world_rotation * m_parentNode->getActivePoseWorldRotation(); + } + return world_rotation; +} + const KRMat4 &KRNode::getInverseModelMatrix() { if(!m_inverseModelMatrixValid) { @@ -713,59 +719,124 @@ const KRMat4 &KRNode::getInverseBindPoseMatrix() void KRNode::physicsUpdate(float deltaTime) { - + const long MIN_DISPLAY_FRAMES = 10; + bool visible = m_lastRenderFrame + MIN_DISPLAY_FRAMES >= getContext().getCurrentFrame(); + for(std::set::iterator itr=m_behaviors.begin(); itr != m_behaviors.end(); itr++) { + (*itr)->update(deltaTime); + if(visible) { + (*itr)->visibleUpdate(deltaTime); + } + } } bool KRNode::hasPhysics() { - return false; + return m_behaviors.size() > 0; } void KRNode::SetAttribute(node_attribute_type attrib, float v) { + if(m_animation_mask[attrib]) return; + const float DEGREES_TO_RAD = M_PI / 180.0f; //printf("%s - ", m_name.c_str()); switch(attrib) { case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X: - //printf("translate_x: %f\n", v); setLocalTranslation(KRVector3(v, m_localTranslation.y, m_localTranslation.z)); break; case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y: - //printf("translate_y: %f\n", v); setLocalTranslation(KRVector3(m_localTranslation.x, v, m_localTranslation.z)); break; case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z: - //printf("translate_z: %f\n", v); setLocalTranslation(KRVector3(m_localTranslation.x, m_localTranslation.y, v)); break; case KRENGINE_NODE_ATTRIBUTE_SCALE_X: - //printf("scale_x: %f\n", v); setLocalScale(KRVector3(v, m_localScale.y, m_localScale.z)); break; case KRENGINE_NODE_ATTRIBUTE_SCALE_Y: - //printf("scale_y: %f\n", v); setLocalScale(KRVector3(m_localScale.x, v, m_localScale.z)); break; case KRENGINE_NODE_ATTRIBUTE_SCALE_Z: - //printf("scale_z: %f\n", v); setLocalScale(KRVector3(m_localScale.x, m_localScale.y, v)); break; case KRENGINE_NODE_ATTRIBUTE_ROTATE_X: - //printf("rotate_x: %f\n", v); setLocalRotation(KRVector3(v * DEGREES_TO_RAD, m_localRotation.y, m_localRotation.z)); break; case KRENGINE_NODE_ATTRIBUTE_ROTATE_Y: - //printf("rotate_y: %f\n", v); setLocalRotation(KRVector3(m_localRotation.x, v * DEGREES_TO_RAD, m_localRotation.z)); break; case KRENGINE_NODE_ATTRIBUTE_ROTATE_Z: - //printf("rotate_z: %f\n", v); setLocalRotation(KRVector3(m_localRotation.x, m_localRotation.y, v * DEGREES_TO_RAD)); break; + + + case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X: + setPreRotation(KRVector3(v * DEGREES_TO_RAD, m_preRotation.y, m_preRotation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y: + setPreRotation(KRVector3(m_preRotation.x, v * DEGREES_TO_RAD, m_preRotation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z: + setPreRotation(KRVector3(m_preRotation.x, m_preRotation.y, v * DEGREES_TO_RAD)); + break; + case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X: + setPostRotation(KRVector3(v * DEGREES_TO_RAD, m_postRotation.y, m_postRotation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y: + setPostRotation(KRVector3(m_postRotation.x, v * DEGREES_TO_RAD, m_postRotation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z: + setPostRotation(KRVector3(m_postRotation.x, m_postRotation.y, v * DEGREES_TO_RAD)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X: + setRotationPivot(KRVector3(v, m_rotationPivot.y, m_rotationPivot.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y: + setRotationPivot(KRVector3(m_rotationPivot.x, v, m_rotationPivot.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z: + setRotationPivot(KRVector3(m_rotationPivot.x, m_rotationPivot.y, v)); + break; + case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X: + setScalingPivot(KRVector3(v, m_scalingPivot.y, m_scalingPivot.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y: + setScalingPivot(KRVector3(m_scalingPivot.x, v, m_scalingPivot.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z: + setScalingPivot(KRVector3(m_scalingPivot.x, m_scalingPivot.y, v)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X: + setRotationOffset(KRVector3(v, m_rotationOffset.y, m_rotationOffset.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y: + setRotationOffset(KRVector3(m_rotationOffset.x, v, m_rotationOffset.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z: + setRotationOffset(KRVector3(m_rotationOffset.x, m_rotationOffset.y, v)); + break; + case KRENGINE_NODE_SCALE_OFFSET_X: + setScalingOffset(KRVector3(v, m_scalingOffset.y, m_scalingOffset.z)); + break; + case KRENGINE_NODE_SCALE_OFFSET_Y: + setScalingOffset(KRVector3(m_scalingOffset.x, v, m_scalingOffset.z)); + break; + case KRENGINE_NODE_SCALE_OFFSET_Z: + setScalingOffset(KRVector3(m_scalingOffset.x, m_scalingOffset.y, v)); + break; } } +void KRNode::setAnimationEnabled(node_attribute_type attrib, bool enable) +{ + m_animation_mask[attrib] = !enable; +} +bool KRNode::getAnimationEnabled(node_attribute_type attrib) const +{ + return !m_animation_mask[attrib]; +} + void KRNode::removeFromOctreeNodes() { for(std::set::iterator itr=m_octree_nodes.begin(); itr != m_octree_nodes.end(); itr++) { @@ -833,3 +904,10 @@ const KRVector3 KRNode::worldToLocal(const KRVector3 &world_point) { return KRMat4::Dot(getInverseModelMatrix(), world_point); } + +void KRNode::addBehavior(KRBehavior *behavior) +{ + m_behaviors.insert(behavior); + behavior->__setNode(this); + getScene().notify_sceneGraphModify(this); +} \ No newline at end of file diff --git a/KREngine/kraken/KRNode.h b/KREngine/kraken/KRNode.h index e03f8f9..61cea10 100644 --- a/KREngine/kraken/KRNode.h +++ b/KREngine/kraken/KRNode.h @@ -14,6 +14,7 @@ #include "KRViewport.h" #include "tinyxml2.h" #include "KROctreeNode.h" +#include "KRBehavior.h" class KRCamera; class KRShaderManager; @@ -95,10 +96,10 @@ public: const KRVector3 getWorldTranslation(); const KRVector3 getWorldScale(); - const KRVector3 getWorldRotation(); + const KRQuaternion getWorldRotation(); - const KRVector3 getBindPoseWorldRotation(); - const KRVector3 getActivePoseWorldRotation(); + const KRQuaternion getBindPoseWorldRotation(); + const KRQuaternion getActivePoseWorldRotation(); const KRVector3 localToWorld(const KRVector3 &local_point); const KRVector3 worldToLocal(const KRVector3 &world_point); @@ -124,7 +125,26 @@ public: KRENGINE_NODE_ATTRIBUTE_SCALE_Z, KRENGINE_NODE_ATTRIBUTE_ROTATE_X, KRENGINE_NODE_ATTRIBUTE_ROTATE_Y, - KRENGINE_NODE_ATTRIBUTE_ROTATE_Z + KRENGINE_NODE_ATTRIBUTE_ROTATE_Z, + KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X, + KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y, + KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z, + KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X, + KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y, + KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z, + KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X, + KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y, + KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z, + KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X, + KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y, + KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z, + KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X, + KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y, + KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z, + KRENGINE_NODE_SCALE_OFFSET_X, + KRENGINE_NODE_SCALE_OFFSET_Y, + KRENGINE_NODE_SCALE_OFFSET_Z, + KRENGINE_NODE_ATTRIBUTE_COUNT }; void SetAttribute(node_attribute_type attrib, float v); @@ -141,6 +161,8 @@ public: void setScaleCompensation(bool scale_compensation); bool getScaleCompensation(); + void setAnimationEnabled(node_attribute_type attrib, bool enable); + bool getAnimationEnabled(node_attribute_type attrib) const; protected: KRVector3 m_localTranslation; @@ -174,7 +196,10 @@ protected: KRNode *m_parentNode; std::set m_childNodes; + bool m_animation_mask[KRENGINE_NODE_ATTRIBUTE_COUNT]; + private: + long m_lastRenderFrame; void invalidateModelMatrix(); void invalidateBindPoseMatrix(); KRMat4 m_modelMatrix; @@ -197,8 +222,10 @@ private: std::set m_octree_nodes; bool m_scale_compensation; -public: + std::set m_behaviors; +public: + void addBehavior(KRBehavior *behavior); void removeFromOctreeNodes(); void addToOctreeNode(KROctreeNode *octree_node); void childDeleted(KRNode *child_node); diff --git a/KREngine/kraken/KRQuaternion.cpp b/KREngine/kraken/KRQuaternion.cpp index 0d5a3cb..c6eabf8 100644 --- a/KREngine/kraken/KRQuaternion.cpp +++ b/KREngine/kraken/KRQuaternion.cpp @@ -79,6 +79,13 @@ KRQuaternion::~KRQuaternion() { } +void KRQuaternion::setEulerXYZ(const KRVector3 &euler) +{ + *this = KRQuaternion::FromAngleAxis(KRVector3(1.0f, 0.0f, 0.0f), euler.x) + * KRQuaternion::FromAngleAxis(KRVector3(0.0f, 1.0f, 0.0f), euler.y) + * KRQuaternion::FromAngleAxis(KRVector3(0.0f, 0.0f, 1.0f), euler.z); +} + void KRQuaternion::setEulerZYX(const KRVector3 &euler) { // ZYX Order! float c1 = cos(euler[0] * 0.5f); @@ -189,10 +196,10 @@ KRQuaternion& KRQuaternion::operator +=(const KRQuaternion& v) { } KRQuaternion& KRQuaternion::operator -=(const KRQuaternion& v) { - m_val[0] += v[0]; - m_val[1] += v[1]; - m_val[2] += v[2]; - m_val[3] += v[3]; + m_val[0] -= v[0]; + m_val[1] -= v[1]; + m_val[2] -= v[2]; + m_val[3] -= v[3]; return *this; } @@ -270,28 +277,30 @@ void KRQuaternion::conjugate() { } KRMat4 KRQuaternion::rotationMatrix() const { - - KRVector3 euler = eulerXYZ(); KRMat4 matRotate; + + /* + KRVector3 euler = eulerXYZ(); + matRotate.rotate(euler.x, X_AXIS); matRotate.rotate(euler.y, Y_AXIS); matRotate.rotate(euler.z, Z_AXIS); + */ // FINDME - Determine why the more optimal routine commented below wasn't working - /* - matRotate.getPointer()[0] = 1.0 - 2.0 * (m_val[2] * m_val[2] + m_val[3] * m_val[3]); - matRotate.getPointer()[1] = 2.0 * (m_val[1] * m_val[2] - m_val[0] * m_val[3]); - matRotate.getPointer()[2] = 2.0 * (m_val[0] * m_val[2] + m_val[1] * m_val[3]); - matRotate.getPointer()[4] = 2.0 * (m_val[1] * m_val[2] + m_val[0] * m_val[3]); - matRotate.getPointer()[5] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[3] * m_val[3]); - matRotate.getPointer()[6] = 2.0 * (m_val[2] * m_val[3] - m_val[0] * m_val[1]); + matRotate.c[0] = 1.0 - 2.0 * (m_val[2] * m_val[2] + m_val[3] * m_val[3]); + matRotate.c[1] = 2.0 * (m_val[1] * m_val[2] - m_val[0] * m_val[3]); + matRotate.c[2] = 2.0 * (m_val[0] * m_val[2] + m_val[1] * m_val[3]); - matRotate.getPointer()[8] = 2.0 * (m_val[1] * m_val[3] - m_val[0] * m_val[2]); - matRotate.getPointer()[9] = 2.0 * (m_val[0] * m_val[1] + m_val[2] * m_val[3]); - matRotate.getPointer()[10] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[2] * m_val[2]); - */ + matRotate.c[4] = 2.0 * (m_val[1] * m_val[2] + m_val[0] * m_val[3]); + matRotate.c[5] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[3] * m_val[3]); + matRotate.c[6] = 2.0 * (m_val[2] * m_val[3] - m_val[0] * m_val[1]); + + matRotate.c[8] = 2.0 * (m_val[1] * m_val[3] - m_val[0] * m_val[2]); + matRotate.c[9] = 2.0 * (m_val[0] * m_val[1] + m_val[2] * m_val[3]); + matRotate.c[10] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[2] * m_val[2]); return matRotate; } diff --git a/KREngine/kraken/KRQuaternion.h b/KREngine/kraken/KRQuaternion.h index 8749d18..5b0c65c 100644 --- a/KREngine/kraken/KRQuaternion.h +++ b/KREngine/kraken/KRQuaternion.h @@ -67,7 +67,7 @@ public: float& operator [](unsigned i); float operator [](unsigned i) const; - + void setEulerXYZ(const KRVector3 &euler); void setEulerZYX(const KRVector3 &euler); KRVector3 eulerXYZ() const; KRMat4 rotationMatrix() const; diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index 9951d49..37c7dda 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -42,10 +42,10 @@ KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLaye void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); //void BakeNode(KFbxNode* pNode); void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial); -void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh); -KRNode *LoadMesh(KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); +void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh); +KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode); -KRNode *LoadSkeleton(KRNode *parent_node, KFbxNode* pNode); +KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode); KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode); std::string GetFbxObjectName(FbxObject *obj); @@ -56,14 +56,19 @@ std::string GetFbxObjectName(FbxObject *obj) { // Object names from FBX files are now concatenated with the FBX numerical ID to ensure that they are unique // TODO - This should be updated to only add a prefix or suffix if needed to make the name unique - std::stringstream st; - st << "fbx_"; - st << obj->GetUniqueID(); - if(strlen(obj->GetName()) != 0) { - st << "_"; - st << obj->GetName(); + if(strcmp(obj->GetName(), "default_camera") == 0) { + // There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera + return "default_camera"; + } else { + std::stringstream st; + st << "fbx_"; + st << obj->GetUniqueID(); + if(strlen(obj->GetName()) != 0) { + st << "_"; + st << obj->GetName(); + } + return st.str(); } - return st.str(); } void KRResource::LoadFbx(KRContext &context, const std::string& path) @@ -136,7 +141,7 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path) FbxMesh *mesh = pFbxScene->GetSrcObject(i); printf(" Mesh %i of %i: %s\n", i+1, mesh_count, mesh->GetNode()->GetName()); - LoadMesh(context, pGeometryConverter, mesh); + LoadMesh(context, pFbxScene, pGeometryConverter, mesh); } // ----====---- Import Textures ----====---- @@ -640,6 +645,171 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z); pAnimationLayer->addAttribute(new_attribute); } + + pAnimCurve = pNode->PreRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->PreRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->PreRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->PostRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->PostRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->PostRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z); + pAnimationLayer->addAttribute(new_attribute); + } + + + pAnimCurve = pNode->RotationPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->RotationPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->RotationPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->ScalingPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->ScalingPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->ScalingPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z); + pAnimationLayer->addAttribute(new_attribute); + } + + + pAnimCurve = pNode->RotationOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->RotationOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->RotationOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z); + pAnimationLayer->addAttribute(new_attribute); + } + + + pAnimCurve = pNode->ScalingOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_SCALE_OFFSET_X); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->ScalingOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_SCALE_OFFSET_Y); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->ScalingOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z); + if(pAnimCurve) { + KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext()); + new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); + new_attribute->setTargetName(GetFbxObjectName(pNode)); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_SCALE_OFFSET_Z); + pAnimationLayer->addAttribute(new_attribute); + } } } } @@ -648,6 +818,8 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p fbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot); fbxDouble3 local_scale = pNode->LclScaling.Get(); // pNode->GetGeometricScaling(KFbxNode::eSourcePivot); + bool rotation_active = pNode->RotationActive.Get(); + fbxDouble3 post_rotation = pNode->PostRotation.Get(); fbxDouble3 pre_rotation = pNode->PreRotation.Get(); fbxDouble3 rotation_offset = pNode->RotationOffset.Get(); @@ -676,8 +848,14 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p KRVector3 node_scaling_offset = KRVector3(scaling_offset[0], scaling_offset[1], scaling_offset[2]); KRVector3 node_rotation_pivot = KRVector3(rotation_pivot[0], rotation_pivot[1], rotation_pivot[2]); KRVector3 node_scaling_pivot = KRVector3(scaling_pivot[0], scaling_pivot[1], scaling_pivot[2]); - KRVector3 node_pre_rotation = KRVector3(pre_rotation[0], pre_rotation[1], pre_rotation[2]) / 180.0 * M_PI; - KRVector3 node_post_rotation = KRVector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI; + KRVector3 node_pre_rotation, node_post_rotation; + if(rotation_active) { + node_pre_rotation = KRVector3(pre_rotation[0], pre_rotation[1], pre_rotation[2]) / 180.0 * M_PI; + node_post_rotation = KRVector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI; + } else { + node_pre_rotation = KRVector3::Zero(); + node_post_rotation = KRVector3::Zero(); + } // printf(" Local Translation: %f %f %f\n", local_translation[0], local_translation[1], local_translation[2]); // printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]); @@ -769,13 +947,13 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p KRNode *new_node = NULL; switch(attribute_type) { case KFbxNodeAttribute::eMesh: - new_node = LoadMesh(parent_node, pGeometryConverter, pNode); + new_node = LoadMesh(parent_node, pFbxScene, pGeometryConverter, pNode); break; case KFbxNodeAttribute::eLight: new_node = LoadLight(parent_node, pNode); break; case KFbxNodeAttribute::eSkeleton: - new_node = LoadSkeleton(parent_node, pNode); + new_node = LoadSkeleton(parent_node, pFbxScene, pNode); break; case KFbxNodeAttribute::eCamera: new_node = LoadCamera(parent_node, pNode); @@ -1027,18 +1205,23 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { } } -void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh) { + + +void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh) { KFbxMesh* pMesh = pGeometryConverter->TriangulateMesh(pSourceMesh); + KRMesh::mesh_info mi; + mi.format = KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES; + + typedef struct { + float weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX]; + int bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX]; + } control_point_weight_info_t; + int control_point_count = pMesh->GetControlPointsCount(); KFbxVector4* control_points = pMesh->GetControlPoints(); - struct control_point_weight_info { - float weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX]; - int bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX]; - }; - - control_point_weight_info *control_point_weights = new control_point_weight_info[control_point_count]; + control_point_weight_info_t *control_point_weights = new control_point_weight_info_t[control_point_count]; for(int control_point=0; control_point < control_point_count; control_point++) { for(int i=0; i bone_names; bool too_many_bone_weights = false; // Collect the top 4 bone weights per vertex ... @@ -1063,12 +1245,39 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx printf(" Warning! link mode not supported.\n"); } std::string bone_name = GetFbxObjectName(cluster->GetLink()); - bone_names.push_back(bone_name); + mi.bone_names.push_back(bone_name); + + /* + FbxMatrix fbx_bind_pose_matrix; + KRMat4 bind_pose; + PoseList pose_list; + FbxArray pose_indices; + if(FbxPose::GetBindPoseContaining(pFbxScene, cluster->GetLink(), pose_list, pose_indices)) { + fbx_bind_pose_matrix = (*pose_list)[0].GetMatrix(pose_indices[0]); + bind_pose = KRMat4( + KRVector3(fbx_bind_pose_matrix.GetColumn(0).mData), + KRVector3(fbx_bind_pose_matrix.GetColumn(1).mData), + KRVector3(fbx_bind_pose_matrix.GetColumn(2).mData), + KRVector3(fbx_bind_pose_matrix.GetColumn(3).mData) + ); + fprintf(stderr, "Found bind pose(s)!\n"); + } + */ + + FbxAMatrix link_matrix; + cluster->GetTransformLinkMatrix(link_matrix); + mi.bone_bind_poses.push_back(KRMat4( + KRVector3(link_matrix.GetColumn(0).mData), + KRVector3(link_matrix.GetColumn(1).mData), + KRVector3(link_matrix.GetColumn(2).mData), + KRVector3(link_matrix.GetColumn(3).mData) + )); int cluster_control_point_count = cluster->GetControlPointIndicesCount(); - for(int control_point=0; control_pointGetControlPointIndices()[control_point]]; - float bone_weight = cluster->GetControlPointWeights()[control_point]; + for(int cluster_control_point=0; cluster_control_pointGetControlPointIndices()[cluster_control_point]; + control_point_weight_info_t &weight_info = control_point_weights[control_point]; + float bone_weight = cluster->GetControlPointWeights()[cluster_control_point]; if(bone_weight > weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1]) { if(weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] != 0.0f) { too_many_bone_weights = true; @@ -1095,9 +1304,9 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx printf(" WARNING! - Clipped bone weights to limit of %i per vertex (selecting largest weights and re-normalizing).\n", KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX); } // Normalize bone weights - if(bone_names.size() > 0) { + if(mi.bone_names.size() > 0) { for(int control_point_index=0; control_point_index < control_point_count; control_point_index++) { - control_point_weight_info &weight_info = control_point_weights[control_point_index]; + control_point_weight_info_t &weight_info = control_point_weights[control_point_index]; float total_weights = 0.0f; for(int i=0; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) { total_weights += weight_info.weights[i]; @@ -1116,17 +1325,17 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx int elementmaterial_count = pMesh->GetElementMaterialCount(); int material_count = pSourceMesh->GetNode()->GetMaterialCount(); // FINDME, TODO - To support instancing, material names should be stored in the instance rather than the mesh - std::vector > bone_weights; - std::vector > bone_indexes; - - std::vector vertices; - std::vector uva; - std::vector uvb; - std::vector normals; - std::vector tangents; - std::vector submesh_lengths; - std::vector submesh_starts; - std::vector material_names; +// std::vector > bone_weights; +// std::vector > bone_indexes; +// +// std::vector vertices; +// std::vector uva; +// std::vector uvb; +// std::vector normals; +// std::vector tangents; +// std::vector submesh_lengths; +// std::vector submesh_starts; +// std::vector material_names; int dest_vertex_id = 0; @@ -1172,18 +1381,18 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx // ----====---- Read Vertex Position ----====---- int lControlPointIndex = pMesh->GetPolygonVertex(iPolygon, iVertex); KFbxVector4 v = control_points[lControlPointIndex]; - vertices.push_back(KRVector3(v[0], v[1], v[2])); + mi.vertices.push_back(KRVector3(v[0], v[1], v[2])); - if(bone_names.size() > 0) { - control_point_weight_info &weight_info = control_point_weights[lControlPointIndex]; + if(mi.bone_names.size() > 0) { + control_point_weight_info_t &weight_info = control_point_weights[lControlPointIndex]; std::vector vertex_bone_indexes; std::vector vertex_bone_weights; for(int i=0; iGetPolygonVertexUV(iPolygon, iVertex, setName, uv)) { new_uva = KRVector2(uv[0], uv[1]); } - uva.push_back(new_uva); + mi.uva.push_back(new_uva); } if(uv_count >= 2) { @@ -1209,14 +1418,14 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv)) { new_uvb = KRVector2(uv[0], uv[1]); } - uvb.push_back(new_uvb); + mi.uvb.push_back(new_uvb); } // ----====---- Read Normals ----====---- KFbxVector4 new_normal; if(pMesh->GetPolygonVertexNormal(iPolygon, iVertex, new_normal)) { - normals.push_back(KRVector3(new_normal[0], new_normal[1], new_normal[2])); + mi.normals.push_back(KRVector3(new_normal[0], new_normal[1], new_normal[2])); } @@ -1242,7 +1451,7 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx } } if(l == 0) { - tangents.push_back(KRVector3(new_tangent[0], new_tangent[1], new_tangent[2])); + mi.tangents.push_back(KRVector3(new_tangent[0], new_tangent[1], new_tangent[2])); } } @@ -1261,23 +1470,21 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx if(mat_vertex_count) { // ----====---- Output last material / submesh details ----====---- - submesh_starts.push_back(mat_vertex_start); - submesh_lengths.push_back(mat_vertex_count); - material_names.push_back(pMaterial->GetName()); + mi.submesh_starts.push_back(mat_vertex_start); + mi.submesh_lengths.push_back(mat_vertex_count); + mi.material_names.push_back(pMaterial->GetName()); } } delete control_point_weights; KRMesh *new_mesh = new KRMesh(context, pSourceMesh->GetNode()->GetName()); - std::vector<__uint16_t> vertex_indexes; - std::vector > vertex_index_bases; - new_mesh->LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights,KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES, true, need_tangents); + new_mesh->LoadData(mi, true, need_tangents); context.getModelManager()->addModel(new_mesh); } -KRNode *LoadMesh(KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) { +KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) { std::string name = GetFbxObjectName(pNode); KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute(); @@ -1305,9 +1512,17 @@ KRNode *LoadMesh(KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, } -KRNode *LoadSkeleton(KRNode *parent_node, KFbxNode* pNode) { +KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) { std::string name = GetFbxObjectName(pNode); KRBone *new_bone = new KRBone(parent_node->getScene(), name.c_str()); + + //static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray& pIndex); +// PoseList pose_list; +// FbxArray pose_indices; +// if(FbxPose::GetBindPoseContaining(pFbxScene, pNode, pose_list, pose_indices)) { +// fprintf(stderr, "Found bind pose(s)!\n"); +// } + return new_bone; } diff --git a/KREngine/kraken/KRResource+obj.cpp b/KREngine/kraken/KRResource+obj.cpp index 991e766..90406b1 100644 --- a/KREngine/kraken/KRResource+obj.cpp +++ b/KREngine/kraken/KRResource+obj.cpp @@ -17,14 +17,8 @@ std::vector KRResource::LoadObj(KRContext &context, const std::str KRMesh *new_mesh = new KRMesh(context, KRResource::GetFileBase(path)); resources.push_back(new_mesh); - std::vector vertices; - std::vector uva; - std::vector uvb; - std::vector normals; - std::vector tangents; - std::vector submesh_lengths; - std::vector submesh_starts; - std::vector material_names; + + KRMesh::mesh_info mi; std::vector material_names_t; @@ -266,13 +260,13 @@ std::vector KRResource::LoadObj(KRContext &context, const std::str // There have already been 3 vertices. Now we need to split the quad into a second triangle composed of the 1st, 3rd, and 4th vertices iVertex+=2; - vertices.push_back(firstFaceVertex); - uva.push_back(firstFaceUva); - normals.push_back(firstFaceNormal); + mi.vertices.push_back(firstFaceVertex); + mi.uva.push_back(firstFaceUva); + mi.normals.push_back(firstFaceNormal); - vertices.push_back(prevFaceVertex); - uva.push_back(prevFaceUva); - normals.push_back(prevFaceNormal); + mi.vertices.push_back(prevFaceVertex); + mi.uva.push_back(prevFaceUva); + mi.normals.push_back(prevFaceNormal); } KRVector3 vertex = indexed_vertices[pFace[iFaceVertex*3+1]]; KRVector2 new_uva; @@ -284,9 +278,9 @@ std::vector KRResource::LoadObj(KRContext &context, const std::str KRVector3 normal = indexed_normals[pFace[iFaceVertex*3+3]]; } - vertices.push_back(vertex); - uva.push_back(new_uva); - normals.push_back(normal); + mi.vertices.push_back(vertex); + mi.uva.push_back(new_uva); + mi.normals.push_back(normal); if(iFaceVertex==0) { firstFaceVertex = vertex; @@ -318,22 +312,24 @@ std::vector KRResource::LoadObj(KRContext &context, const std::str for(int iMaterial=0; iMaterial < m_materials.size(); iMaterial++) { KRMesh::pack_material *pNewMaterial = m_materials[iMaterial]; if(pNewMaterial->vertex_count > 0) { - material_names.push_back(std::string(pNewMaterial->szName)); - submesh_starts.push_back(pNewMaterial->start_vertex); - submesh_lengths.push_back(pNewMaterial->vertex_count); + mi.material_names.push_back(std::string(pNewMaterial->szName)); + mi.submesh_starts.push_back(pNewMaterial->start_vertex); + mi.submesh_lengths.push_back(pNewMaterial->vertex_count); } delete pNewMaterial; } // TODO: Bones not yet supported for OBJ - std::vector bone_names; - std::vector > bone_indexes; - std::vector > bone_weights; +// std::vector bone_names; +// std::vector bone_bind_poses; +// std::vector > bone_indexes; +// std::vector > bone_weights; +// +// std::vector<__uint16_t> vertex_indexes; +// std::vector > vertex_index_bases; - std::vector<__uint16_t> vertex_indexes; - std::vector > vertex_index_bases; - - new_mesh->LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights, KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES, true, false); + mi.format = KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES; + new_mesh->LoadData(mi, true, false); } if(pFaces) { diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 90ee2d7..2a1f2f5 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -62,7 +62,7 @@ KRScene::~KRScene() { void KRScene::renderFrame(float deltaTime, int width, int height) { getContext().startFrame(deltaTime); - KRCamera *camera = find(); + KRCamera *camera = find("default_camera"); if(camera == NULL) { // Add a default camera if none are present camera = new KRCamera(*this, "default_camera"); diff --git a/KREngine/kraken/KRShader.cpp b/KREngine/kraken/KRShader.cpp index 3c26261..210aae4 100644 --- a/KREngine/kraken/KRShader.cpp +++ b/KREngine/kraken/KRShader.cpp @@ -345,11 +345,11 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & return false; } - bool need_to_validate = false; + bool shander_changed = false; if(getContext().getShaderManager()->m_active_shader != this) { getContext().getShaderManager()->m_active_shader = this; GLDEBUG(glUseProgram(m_iProgram)); - need_to_validate = true; + shander_changed = true; } @@ -544,7 +544,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & setUniform(KRENGINE_UNIFORM_VOLUMETRIC_ENVIRONMENT_FRAME, 2); #if DEBUG - if(need_to_validate) { + if(shander_changed) { GLint logLength; GLint validate_status = GL_FALSE; diff --git a/KREngine/kraken/KRShaderManager.cpp b/KREngine/kraken/KRShaderManager.cpp index e691328..a591ea8 100644 --- a/KREngine/kraken/KRShaderManager.cpp +++ b/KREngine/kraken/KRShaderManager.cpp @@ -40,7 +40,6 @@ using namespace std; KRShaderManager::KRShaderManager(KRContext &context) : KRContextObject(context) { - m_szCurrentShaderKey[0] = '\0'; m_active_shader = NULL; } @@ -248,13 +247,7 @@ bool KRShaderManager::selectShader(const std::string &shader_name, KRCamera &cam bool KRShaderManager::selectShader(KRCamera &camera, KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRNode::RenderPass &renderPass) { if(pShader) { - bool bSameShader = strcmp(pShader->getKey(), m_szCurrentShaderKey) == 0; - if(!bSameShader || true) { // FINDME, HACK. Need to update logic to detect appropriate times to bind a new shader - strcpy(m_szCurrentShaderKey, pShader->getKey()); - return pShader->bind(camera, viewport, matModel, point_lights, directional_lights, spot_lights, renderPass); - } else { - return true; - } + return pShader->bind(camera, viewport, matModel, point_lights, directional_lights, spot_lights, renderPass); } else { return false; } diff --git a/KREngine/kraken/KRShaderManager.h b/KREngine/kraken/KRShaderManager.h index 59b762d..1de85da 100644 --- a/KREngine/kraken/KRShaderManager.h +++ b/KREngine/kraken/KRShaderManager.h @@ -74,9 +74,6 @@ private: unordered_map m_fragShaderSource; unordered_map m_vertShaderSource; - - - char m_szCurrentShaderKey[256]; }; #endif diff --git a/KREngine/kraken/KRVector3.cpp b/KREngine/kraken/KRVector3.cpp index bdad05c..6505716 100644 --- a/KREngine/kraken/KRVector3.cpp +++ b/KREngine/kraken/KRVector3.cpp @@ -59,6 +59,12 @@ KRVector3::KRVector3(float *v) { z = v[2]; } +KRVector3::KRVector3(double *v) { + x = (float)v[0]; + y = (float)v[1]; + z = (float)v[2]; +} + KRVector3 KRVector3::Min() { return KRVector3(-std::numeric_limits::max()); } @@ -99,6 +105,19 @@ KRVector3 KRVector3::Right() { return KRVector3(1.0f, 0.0f, 0.0f); } + +void KRVector3::scale(const KRVector3 &v) +{ + x *= v.x; + y *= v.y; + z *= v.z; +} + +KRVector3 KRVector3::Scale(const KRVector3 &v1, const KRVector3 &v2) +{ + return KRVector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); +} + KRVector3 KRVector3::Lerp(const KRVector3 &v1, const KRVector3 &v2, float d) { return v1 + (v2 - v1) * d; } diff --git a/KREngine/kraken/KRVector3.h b/KREngine/kraken/KRVector3.h index 81ea190..dc14294 100644 --- a/KREngine/kraken/KRVector3.h +++ b/KREngine/kraken/KRVector3.h @@ -51,6 +51,7 @@ public: KRVector3(float X, float Y, float Z); KRVector3(float v); KRVector3(float *v); + KRVector3(double *v); KRVector3(const KRVector3 &v); KRVector3(const KRVector4 &v); ~KRVector3(); @@ -83,6 +84,7 @@ public: float sqrMagnitude() const; // calculate the square of the magnitude (useful for comparison of magnitudes without the cost of a sqrt() function) float magnitude() const; + void scale(const KRVector3 &v); void normalize(); static KRVector3 Normalize(const KRVector3 &v); @@ -99,6 +101,7 @@ public: static KRVector3 Down(); static KRVector3 Left(); static KRVector3 Right(); + static KRVector3 Scale(const KRVector3 &v1, const KRVector3 &v2); static KRVector3 Lerp(const KRVector3 &v1, const KRVector3 &v2, float d); static KRVector3 Slerp(const KRVector3 &v1, const KRVector3 &v2, float d); static void OrthoNormalize(KRVector3 &normal, KRVector3 &tangent); // Gram-Schmidt Orthonormalization diff --git a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh index 4e379d3..353f5b2 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh @@ -29,6 +29,7 @@ // or implied, of Kearwood Gilbert. // + attribute highp vec3 vertex_position, vertex_normal; #if HAS_NORMAL_MAP == 1 attribute highp vec3 vertex_tangent; @@ -171,8 +172,8 @@ void main() mediump vec4 scaled_bone_indexes = bone_indexes; mediump vec4 scaled_bone_weights = bone_weights; - //scaled_bone_indexes = vec4(1.0, 0.0, 0.0, 0.0); - scaled_bone_weights = vec4(1.0, 0.0, 0.0, 0.0); + //scaled_bone_indexes = vec4(0.0, 0.0, 0.0, 0.0); + //scaled_bone_weights = vec4(1.0, 0.0, 0.0, 0.0); highp mat4 skin_matrix = bone_transforms[ int(scaled_bone_indexes.x) ] * scaled_bone_weights.x + diff --git a/KREngine/kraken_standard_assets_ios/Shaders/debug_font.vsh b/KREngine/kraken_standard_assets_ios/Shaders/debug_font.vsh index 31a8ba7..5d7bdea 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/debug_font.vsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/debug_font.vsh @@ -28,11 +28,11 @@ varying mediump vec2 textureCoordinate; attribute vec4 vertex_position; -attribute lowp vec4 vertex_uv; +attribute lowp vec2 vertex_uv; uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices void main() { gl_Position = /*mvp_matrix * */vertex_position; - textureCoordinate = vertex_uv.xy; + textureCoordinate = vertex_uv; } diff --git a/KREngine/kraken_standard_assets_osx/Shaders/debug_font_osx.vsh b/KREngine/kraken_standard_assets_osx/Shaders/debug_font_osx.vsh index 31a8ba7..5d7bdea 100644 --- a/KREngine/kraken_standard_assets_osx/Shaders/debug_font_osx.vsh +++ b/KREngine/kraken_standard_assets_osx/Shaders/debug_font_osx.vsh @@ -28,11 +28,11 @@ varying mediump vec2 textureCoordinate; attribute vec4 vertex_position; -attribute lowp vec4 vertex_uv; +attribute lowp vec2 vertex_uv; uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices void main() { gl_Position = /*mvp_matrix * */vertex_position; - textureCoordinate = vertex_uv.xy; + textureCoordinate = vertex_uv; }