- 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);
This commit is contained in:
2013-05-24 12:20:47 -07:00
parent 1c7aea8d50
commit e0aaafc327
42 changed files with 1160 additions and 628 deletions

View File

@@ -82,6 +82,10 @@
E450273A16E0491D00FDEC5C /* KRReverbZone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E450273716E0491D00FDEC5C /* KRReverbZone.cpp */; }; 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, ); }; }; 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, ); }; }; 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 */; }; E459040416C30CC5002B00A0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E459040316C30CC5002B00A0 /* AudioUnit.framework */; };
E459040616C30CD9002B00A0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E459040516C30CD9002B00A0 /* 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, ); }; }; 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 */; }; E48CF942173453990005EBBB /* KRFloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48CF940173453990005EBBB /* KRFloat.cpp */; };
E48CF943173453990005EBBB /* 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 */; }; 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 */; }; 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, ); }; }; 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, ); }; }; 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 = "<group>"; }; E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = "<group>"; };
E450273716E0491D00FDEC5C /* KRReverbZone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRReverbZone.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E450273716E0491D00FDEC5C /* KRReverbZone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRReverbZone.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
E450273816E0491D00FDEC5C /* KRReverbZone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRReverbZone.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E450273816E0491D00FDEC5C /* KRReverbZone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRReverbZone.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
E45134B41746A4A300443C21 /* KRBehavior.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRBehavior.cpp; sourceTree = "<group>"; };
E45134B51746A4A300443C21 /* KRBehavior.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRBehavior.h; sourceTree = "<group>"; };
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; }; 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; }; 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 = "<group>"; }; E460292516681CFE00261BB9 /* KRTextureAnimated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureAnimated.h; sourceTree = "<group>"; };
@@ -1020,6 +1026,8 @@
E4C454BA167BD248003586CD /* KRHitInfo.cpp */, E4C454BA167BD248003586CD /* KRHitInfo.cpp */,
E44F38231683B22C00399B5D /* KRRenderSettings.h */, E44F38231683B22C00399B5D /* KRRenderSettings.h */,
E44F38271683B24400399B5D /* KRRenderSettings.cpp */, E44F38271683B24400399B5D /* KRRenderSettings.cpp */,
E45134B41746A4A300443C21 /* KRBehavior.cpp */,
E45134B51746A4A300443C21 /* KRBehavior.h */,
); );
path = kraken; path = kraken;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1238,6 +1246,7 @@
E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */, E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */,
E4EC73C31720B1FF0065299F /* KRVector4.h in Headers */, E4EC73C31720B1FF0065299F /* KRVector4.h in Headers */,
E48CF944173453990005EBBB /* KRFloat.h in Headers */, E48CF944173453990005EBBB /* KRFloat.h in Headers */,
E45134B81746A4A300443C21 /* KRBehavior.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -1313,9 +1322,10 @@
E499BF1D16AE74FF007FCDBE /* KRTextureAnimated.h in Headers */, E499BF1D16AE74FF007FCDBE /* KRTextureAnimated.h in Headers */,
E4EC73C41720B1FF0065299F /* KRVector4.h in Headers */, E4EC73C41720B1FF0065299F /* KRVector4.h in Headers */,
E4AE63601704FB0A00B460CD /* KRLODGroup.h in Headers */, E4AE63601704FB0A00B460CD /* KRLODGroup.h in Headers */,
E45134B91746A4A300443C21 /* KRBehavior.h in Headers */,
E48CF945173453990005EBBB /* KRFloat.h in Headers */,
E499BF1F16AE753E007FCDBE /* KRCollider.h in Headers */, E499BF1F16AE753E007FCDBE /* KRCollider.h in Headers */,
E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */, E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */,
E48CF945173453990005EBBB /* KRFloat.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -1580,6 +1590,7 @@
E4AE635D1704FB0A00B460CD /* KRLODGroup.cpp in Sources */, E4AE635D1704FB0A00B460CD /* KRLODGroup.cpp in Sources */,
E4EC73C11720B1FF0065299F /* KRVector4.cpp in Sources */, E4EC73C11720B1FF0065299F /* KRVector4.cpp in Sources */,
E48CF942173453990005EBBB /* KRFloat.cpp in Sources */, E48CF942173453990005EBBB /* KRFloat.cpp in Sources */,
E45134B61746A4A300443C21 /* KRBehavior.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -1655,6 +1666,7 @@
E4AE635E1704FB0A00B460CD /* KRLODGroup.cpp in Sources */, E4AE635E1704FB0A00B460CD /* KRLODGroup.cpp in Sources */,
E4EC73C21720B1FF0065299F /* KRVector4.cpp in Sources */, E4EC73C21720B1FF0065299F /* KRVector4.cpp in Sources */,
E48CF943173453990005EBBB /* KRFloat.cpp in Sources */, E48CF943173453990005EBBB /* KRFloat.cpp in Sources */,
E45134B71746A4A300443C21 /* KRBehavior.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@@ -39,9 +39,9 @@
KRAnimation::KRAnimation(KRContext &context, std::string name) : KRResource(context, name) KRAnimation::KRAnimation(KRContext &context, std::string name) : KRResource(context, name)
{ {
m_auto_play = true; m_auto_play = false;
m_loop = true; m_loop = false;
m_playing = true; m_playing = false;
m_local_time = 0.0f; m_local_time = 0.0f;
m_duration = 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) { 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) { 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()) { 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) void KRAnimation::update(float deltaTime)
{ {
if(m_playing) { if(m_playing) {
m_local_time += deltaTime; m_local_time += deltaTime;
} }
while(m_local_time > m_duration) { if(m_loop) {
m_local_time -= m_duration; 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<std::string, KRAnimationLayer *>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { for(unordered_map<std::string, KRAnimationLayer *>::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(); KRNode::node_attribute_type attribute_type = attribute->getTargetAttribute();
if(curve != NULL && target != NULL) { 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; 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;
}

View File

@@ -53,6 +53,10 @@ public:
void addLayer(KRAnimationLayer *layer); void addLayer(KRAnimationLayer *layer);
unordered_map<std::string, KRAnimationLayer *> &getLayers(); unordered_map<std::string, KRAnimationLayer *> &getLayers();
KRAnimationLayer *getLayer(const char *szName); KRAnimationLayer *getLayer(const char *szName);
bool getAutoPlay() const;
void setAutoPlay(bool auto_play);
bool getLooping() const;
void setLooping(bool looping);
void Play(); void Play();
void Stop(); void Stop();
void update(float deltaTime); void update(float deltaTime);

View File

@@ -86,6 +86,60 @@ tinyxml2::XMLElement *KRAnimationAttribute::saveXML( tinyxml2::XMLNode *parent)
case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Z: case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Z:
szAttribute = "rotate_z"; szAttribute = "rotate_z";
break; 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); e->SetAttribute("attribute", szAttribute);
@@ -121,6 +175,42 @@ void KRAnimationAttribute::loadXML(tinyxml2::XMLElement *e)
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Y; m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Y;
} else if(strcmp(szAttribute, "scale_z") == 0) { } else if(strcmp(szAttribute, "scale_z") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z; 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 { } else {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE;
} }
@@ -163,6 +253,9 @@ KRNode *KRAnimationAttribute::getTarget()
if(m_target == NULL) { if(m_target == NULL) {
m_target = getContext().getSceneManager()->getFirstScene()->getRootNode()->find<KRNode>(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 m_target = getContext().getSceneManager()->getFirstScene()->getRootNode()->find<KRNode>(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; return m_target;
} }

View File

@@ -32,7 +32,7 @@
#include "KRAnimationCurve.h" #include "KRAnimationCurve.h"
#include "KRDataBlock.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 = new KRDataBlock();
m_pData->expand(sizeof(animation_curve_header)); m_pData->expand(sizeof(animation_curve_header));
@@ -129,7 +129,7 @@ float KRAnimationCurve::getValue(int frame_number)
//printf("frame_number: %i\n", frame_number); //printf("frame_number: %i\n", frame_number);
int clamped_frame = frame_number; int clamped_frame = frame_number;
if(frame_number < 0) { if(frame_number < 0) {
clamped_frame = frame_number; clamped_frame = 0;
} else if(frame_number >= getFrameCount()) { } else if(frame_number >= getFrameCount()) {
clamped_frame = getFrameCount()-1; clamped_frame = getFrameCount()-1;
} }

View File

@@ -40,7 +40,7 @@
class KRAnimationCurve : public KRResource { class KRAnimationCurve : public KRResource {
public: public:
KRAnimationCurve(KRContext &context, std::string name); KRAnimationCurve(KRContext &context, const std::string &name);
virtual ~KRAnimationCurve(); virtual ~KRAnimationCurve();
virtual std::string getExtension(); virtual std::string getExtension();

View File

@@ -43,14 +43,14 @@ KRAnimationCurveManager::~KRAnimationCurveManager() {
} }
} }
KRAnimationCurve *KRAnimationCurveManager::loadAnimationCurve(const char *szName, KRDataBlock *data) { KRAnimationCurve *KRAnimationCurveManager::loadAnimationCurve(const std::string &name, KRDataBlock *data) {
KRAnimationCurve *pAnimationCurve = KRAnimationCurve::Load(*m_pContext, szName, data); KRAnimationCurve *pAnimationCurve = KRAnimationCurve::Load(*m_pContext, name, data);
m_animationCurves[szName] = pAnimationCurve; m_animationCurves[name] = pAnimationCurve;
return pAnimationCurve; return pAnimationCurve;
} }
KRAnimationCurve *KRAnimationCurveManager::getAnimationCurve(const char *szName) { KRAnimationCurve *KRAnimationCurveManager::getAnimationCurve(const std::string &name) {
return m_animationCurves[szName]; return m_animationCurves[name];
} }
unordered_map<std::string, KRAnimationCurve *> &KRAnimationCurveManager::getAnimationCurves() { unordered_map<std::string, KRAnimationCurve *> &KRAnimationCurveManager::getAnimationCurves() {

View File

@@ -45,8 +45,8 @@ public:
KRAnimationCurveManager(KRContext &context); KRAnimationCurveManager(KRContext &context);
virtual ~KRAnimationCurveManager(); virtual ~KRAnimationCurveManager();
KRAnimationCurve *loadAnimationCurve(const char *szName, KRDataBlock *data); KRAnimationCurve *loadAnimationCurve(const std::string &name, KRDataBlock *data);
KRAnimationCurve *getAnimationCurve(const char *szName); KRAnimationCurve *getAnimationCurve(const std::string &name);
void addAnimationCurve(KRAnimationCurve *new_animation_curve); void addAnimationCurve(KRAnimationCurve *new_animation_curve);
unordered_map<std::string, KRAnimationCurve *> &getAnimationCurves(); unordered_map<std::string, KRAnimationCurve *> &getAnimationCurves();

View File

@@ -355,6 +355,9 @@ void KRAudioSource::setIs3D(bool is3D)
bool KRAudioSource::hasPhysics() bool KRAudioSource::hasPhysics()
{ {
if(KRNode::hasPhysics()) {
return true;
}
KRAudioManager *audioManager = getContext().getAudioManager(); KRAudioManager *audioManager = getContext().getAudioManager();
return audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL; return audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL;
} }
@@ -370,6 +373,8 @@ void KRAudioSource::advanceBuffer()
void KRAudioSource::physicsUpdate(float deltaTime) void KRAudioSource::physicsUpdate(float deltaTime)
{ {
KRNode::physicsUpdate(deltaTime);
KRAudioManager *audioManager = getContext().getAudioManager(); KRAudioManager *audioManager = getContext().getAudioManager();
audioManager->activateAudioSource(this); audioManager->activateAudioSource(this);
if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) { if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) {

View File

@@ -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;
}

View File

@@ -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) */

View File

@@ -84,3 +84,13 @@ void KRBone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights
} }
} }
void KRBone::setBindPose(const KRMat4 &pose)
{
m_bind_pose = pose;
}
const KRMat4 &KRBone::getBindPose()
{
return m_bind_pose;
}

View File

@@ -24,9 +24,10 @@ public:
void render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass); void render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
void setBindPose(const KRMat4 &pose);
const KRMat4 &getBindPose();
private: private:
KRMat4 m_bind_pose;
}; };

View File

@@ -65,6 +65,23 @@ KRCamera::~KRCamera() {
destroyBuffers(); 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) void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint renderBufferHeight)
{ {
// ----====---- Record timing information for measuring FPS ----====---- // ----====---- Record timing information for measuring FPS ----====----
@@ -82,9 +99,10 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
KRScene &scene = getScene(); KRScene &scene = getScene();
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());
//KRMat4 viewMatrix = KRMat4::Invert(getModelMatrix());
settings.setViewportSize(KRVector2(backingWidth, backingHeight)); settings.setViewportSize(KRVector2(backingWidth, backingHeight));
KRMat4 projectionMatrix; KRMat4 projectionMatrix;

View File

@@ -60,6 +60,11 @@ public:
KRRenderSettings settings; KRRenderSettings settings;
const KRViewport &getViewport(); const KRViewport &getViewport();
virtual std::string getElementName();
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
virtual void loadXML(tinyxml2::XMLElement *e);
private: private:
void createBuffers(GLint renderBufferWidth, GLint renderBufferHeight); void createBuffers(GLint renderBufferWidth, GLint renderBufferHeight);

View File

@@ -12,6 +12,7 @@
#include "KRShader.h" #include "KRShader.h"
#include "KRContext.h" #include "KRContext.h"
#include "KRMat4.h" #include "KRMat4.h"
#include "KRQuaternion.h"
#include "assert.h" #include "assert.h"
#include "KRStockGeometry.h" #include "KRStockGeometry.h"
@@ -30,20 +31,11 @@ std::string KRDirectionalLight::getElementName() {
} }
KRVector3 KRDirectionalLight::getWorldLightDirection() { KRVector3 KRDirectionalLight::getWorldLightDirection() {
KRVector3 world_rotation = getWorldRotation(); return KRMat4::Dot(getWorldRotation().rotationMatrix(), getLocalLightDirection());
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;
} }
KRVector3 KRDirectionalLight::getLocalLightDirection() { KRVector3 KRDirectionalLight::getLocalLightDirection() {
return KRVector3(0.0, 0.0, 1.0); return KRVector3::Forward();
} }

View File

@@ -196,3 +196,4 @@ fprintf(stderr, "Error at line number %d, in file %s. Returned %d for call %s\n"
#include "KRVector4.h" #include "KRVector4.h"
#include "KRVector3.h" #include "KRVector3.h"
#include "KRVector2.h" #include "KRVector2.h"
#include "KRBehavior.h"

View File

@@ -209,7 +209,7 @@ void kraken::set_parameter(const std::string &parameter_name, float parameter_va
- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime AndWidth: (int)width AndHeight: (int)height - (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime AndWidth: (int)width AndHeight: (int)height
{ {
KRCamera *camera = pScene->find<KRCamera>(); KRCamera *camera = pScene->find<KRCamera>("default_camera");
if(camera) { if(camera) {
camera->settings = _settings; camera->settings = _settings;
} }

View File

@@ -313,12 +313,6 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
if(m_flareTexture.size() && m_flareSize > 0.0f) { if(m_flareTexture.size() && m_flareSize > 0.0f) {
if(m_occlusionQuery) { 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; GLuint params = 0;
GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_EXT, &params)); GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_EXT, &params));
GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery)); GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery));

View File

@@ -163,10 +163,34 @@ void KRMat4::translate(const KRVector3 &v)
/* Rotate a matrix by an angle on a X, Y, or Z axis */ /* Rotate a matrix by an angle on a X, Y, or Z axis */
void KRMat4::rotate(float angle, AXIS axis) { void KRMat4::rotate(float angle, AXIS axis) {
const int cos1[3] = { 5, 0, 0 }; const int cos1[3] = { 5, 0, 0 }; // cos(angle)
const int cos2[3] = { 10, 10, 5 }; const int cos2[3] = { 10, 10, 5 }; // cos(angle)
const int sin1[3] = { 6, 2, 1 }; const int sin1[3] = { 9, 2, 4 }; // -sin(angle)
const int sin2[3] = { 9, 8, 4 }; 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 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)); 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;
}

View File

@@ -120,6 +120,10 @@ class KRMat4 {
static KRMat4 LookAt(const KRVector3 &cameraPos, const KRVector3 &lookAtPos, const KRVector3 &upDirection); 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; void setUniform(GLint location) const;
}; };

View File

@@ -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; 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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) { bool KRMaterial::bind(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const std::vector<KRMat4> &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
bool bSameMaterial = *prevBoundMaterial == this;
bool bLightMap = pLightMap && pCamera->settings.bEnableLightMap; bool bLightMap = pLightMap && pCamera->settings.bEnableLightMap;
if(!m_pAmbientMap && m_ambientMap.size()) { 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()); m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str());
} }
if(bones.size() > 0) { KRVector2 default_scale = KRVector2::One();
bSameMaterial = false; // FINDME, HACK! - This is test code 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) { // Bind bones
KRVector2 default_scale = KRVector2(1.0f, 1.0f); if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) {
KRVector2 default_offset = KRVector2(0.0f, 0.0f); GLfloat bone_mats[256 * 16];
GLfloat *bone_mat_component = bone_mats;
bool bHasReflection = m_reflectionColor != KRVector3(0.0f, 0.0f, 0.0f); for(int bone_index=0; bone_index < bones.size(); bone_index++) {
bool bDiffuseMap = m_pDiffuseMap != NULL && pCamera->settings.bEnableDiffuseMap; KRBone *bone = bones[bone_index];
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;
}
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 initialRotation = bone->getInitialLocalRotation();
// KRVector3 rotation = bone->getLocalRotation(); // KRVector3 rotation = bone->getLocalRotation();
// KRVector3 initialTranslation = bone->getInitialLocalTranslation(); // KRVector3 initialTranslation = bone->getInitialLocalTranslation();
@@ -283,143 +272,76 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
// KRVector3 initialScale = bone->getInitialLocalScale(); // KRVector3 initialScale = bone->getInitialLocalScale();
// KRVector3 scale = bone->getLocalScale(); // 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 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 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); // 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 skin_bone_bind_pose = bind_poses[bone_index];
KRMat4 inv_bind_mat = bone->getInverseBindPoseMatrix(); KRMat4 active_mat = bone->getActivePoseMatrix();
KRMat4 t = /*KRMat4::Invert(matModel) * */(inv_bind_mat * model_mat); KRMat4 inv_bind_mat = bone->getInverseBindPoseMatrix();
for(int i=0; i < 16; i++) { KRMat4 inv_bind_mat2 = KRMat4::Invert(bind_poses[bone_index]);
*bone_mat_component++ = t[i]; KRMat4 t = (inv_bind_mat * active_mat);
} KRMat4 t2 = inv_bind_mat2 * bone->getModelMatrix();
} for(int i=0; i < 16; i++) {
if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) { *bone_mat_component++ = t[i];
glUniformMatrix4fv(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS], bones.size(), GL_FALSE, bone_mats);
} }
} }
if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) {
bool bSameAmbient = false; glUniformMatrix4fv(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS], bones.size(), GL_FALSE, bone_mats);
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);
} }
}
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; return true;
} }

View File

@@ -83,7 +83,7 @@ public:
bool isTransparent(); bool isTransparent();
const std::string &getName() const; const std::string &getName() const;
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass); bool bind(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const std::vector<KRMat4> &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
bool needsVertexTangents(); bool needsVertexTangents();

View File

@@ -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(); int cSubmeshes = m_submeshes.size();
if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) { if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) {
for(int iSubmesh=0; iSubmesh<cSubmeshes; iSubmesh++) { for(int iSubmesh=0; iSubmesh<cSubmeshes; iSubmesh++) {
@@ -184,7 +181,11 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect
if(pMaterial != NULL && pMaterial == (*mat_itr)) { if(pMaterial != NULL && pMaterial == (*mat_itr)) {
if((!pMaterial->isTransparent() && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { if((!pMaterial->isTransparent() && 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<KRMat4> 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()) { switch(pMaterial->getAlphaMode()) {
case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials 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<std::pair<int, int> > vertex_index_bases, std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::vector<std::string> bone_names, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > 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<std::pair<int, int> > vertex_index_bases, std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::vector<std::string> bone_names, std::vector<KRMat4> bone_bind_poses, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > bone_weights, model_format_t model_format, */const KRMesh::mesh_info &mi, bool calculate_normals, bool calculate_tangents) {
clearData(); clearData();
@@ -359,27 +360,15 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
bool use_short_uvb = true; bool use_short_uvb = true;
if(use_short_vertexes) { if(use_short_vertexes) {
for(std::vector<KRVector3>::iterator itr=vertices.begin(); itr != vertices.end(); itr++) { for(std::vector<KRVector3>::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) { if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f || fabsf((*itr).z) > 1.0f) {
use_short_vertexes = false; use_short_vertexes = false;
} }
} }
} }
if(use_short_normals) {
for(std::vector<KRVector3>::iterator itr=normals.begin(); itr != normals.end(); itr++) {
(*itr).normalize();
}
}
if(use_short_tangents) {
for(std::vector<KRVector3>::iterator itr=tangents.begin(); itr != tangents.end(); itr++) {
(*itr).normalize();
}
}
if(use_short_uva) { if(use_short_uva) {
for(std::vector<KRVector2>::iterator itr=uva.begin(); itr != uva.end(); itr++) { for(std::vector<KRVector2>::const_iterator itr=mi.uva.begin(); itr != mi.uva.end(); itr++) {
if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) { if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) {
use_short_uva = false; use_short_uva = false;
} }
@@ -387,7 +376,7 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
} }
if(use_short_uvb) { if(use_short_uvb) {
for(std::vector<KRVector2>::iterator itr=uvb.begin(); itr != uvb.end(); itr++) { for(std::vector<KRVector2>::const_iterator itr=mi.uvb.begin(); itr != mi.uvb.end(); itr++) {
if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) { if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) {
use_short_uvb = false; use_short_uvb = false;
} }
@@ -395,50 +384,50 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
} }
__int32_t vertex_attrib_flags = 0; __int32_t vertex_attrib_flags = 0;
if(vertices.size()) { if(mi.vertices.size()) {
if(use_short_vertexes) { if(use_short_vertexes) {
vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX_SHORT); vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX_SHORT);
} else { } else {
vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX); vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX);
} }
} }
if(normals.size() || calculate_normals) { if(mi.normals.size() || calculate_normals) {
if(use_short_normals) { if(use_short_normals) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL_SHORT); vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL_SHORT);
} else { } else {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL); vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL);
} }
} }
if(tangents.size() || calculate_tangents) { if(mi.tangents.size() || calculate_tangents) {
if(use_short_tangents) { if(use_short_tangents) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT_SHORT); vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT_SHORT);
} else { } else {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT); vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT);
} }
} }
if(uva.size()) { if(mi.uva.size()) {
if(use_short_uva) { if(use_short_uva) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA_SHORT); vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA_SHORT);
} else { } else {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA); vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA);
} }
} }
if(uvb.size()) { if(mi.uvb.size()) {
if(use_short_uvb) { if(use_short_uvb) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB_SHORT); vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB_SHORT);
} else { } else {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB); vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB);
} }
} }
if(bone_names.size()) { if(mi.bone_names.size()) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_BONEINDEXES) + (1 << KRENGINE_ATTRIB_BONEWEIGHTS); vertex_attrib_flags += (1 << KRENGINE_ATTRIB_BONEINDEXES) + (1 << KRENGINE_ATTRIB_BONEWEIGHTS);
} }
size_t vertex_size = VertexSizeForAttributes(vertex_attrib_flags); size_t vertex_size = VertexSizeForAttributes(vertex_attrib_flags);
size_t index_count = vertex_indexes.size(); size_t index_count = mi.vertex_indexes.size();
size_t index_base_count = vertex_index_bases.size(); size_t index_base_count = mi.vertex_index_bases.size();
size_t submesh_count = submesh_lengths.size(); size_t submesh_count = mi.submesh_lengths.size();
size_t vertex_count = vertices.size(); size_t vertex_count = mi.vertices.size();
size_t bone_count = bone_names.size(); size_t bone_count = mi.bone_names.size();
size_t new_file_size = sizeof(pack_header) + sizeof(pack_material) * submesh_count + sizeof(pack_bone) * bone_count + KRALIGN(2 * index_count) + KRALIGN(8 * index_base_count) + vertex_size * vertex_count; size_t new_file_size = sizeof(pack_header) + sizeof(pack_material) * submesh_count + sizeof(pack_bone) * bone_count + KRALIGN(2 * index_count) + KRALIGN(8 * index_base_count) + vertex_size * vertex_count;
m_pData->expand(new_file_size); m_pData->expand(new_file_size);
@@ -451,7 +440,7 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
pHeader->bone_count = (__int32_t)bone_count; pHeader->bone_count = (__int32_t)bone_count;
pHeader->index_count = (__int32_t)index_count; pHeader->index_count = (__int32_t)index_count;
pHeader->index_base_count = (__int32_t)index_base_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 "); strcpy(pHeader->szTag, "KROBJPACK1.2 ");
updateAttributeOffsets(); updateAttributeOffsets();
@@ -459,28 +448,29 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
for(int iMaterial=0; iMaterial < pHeader->submesh_count; iMaterial++) { for(int iMaterial=0; iMaterial < pHeader->submesh_count; iMaterial++) {
pack_material *pPackMaterial = pPackMaterials + iMaterial; pack_material *pPackMaterial = pPackMaterials + iMaterial;
pPackMaterial->start_vertex = submesh_starts[iMaterial]; pPackMaterial->start_vertex = mi.submesh_starts[iMaterial];
pPackMaterial->vertex_count = submesh_lengths[iMaterial]; pPackMaterial->vertex_count = mi.submesh_lengths[iMaterial];
memset(pPackMaterial->szName, 0, KRENGINE_MAX_NAME_LENGTH); 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++) { for(int bone_index=0; bone_index < bone_count; bone_index++) {
pack_bone *bone = getBone(bone_index); pack_bone *bone = getBone(bone_index);
memset(bone->szName, 0, KRENGINE_MAX_NAME_LENGTH); 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; bool bFirstVertex = true;
memset(getVertexData(), 0, m_vertex_size * vertices.size()); memset(getVertexData(), 0, m_vertex_size * mi.vertices.size());
for(int iVertex=0; iVertex < vertices.size(); iVertex++) { for(int iVertex=0; iVertex < mi.vertices.size(); iVertex++) {
KRVector3 source_vertex = vertices[iVertex]; KRVector3 source_vertex = mi.vertices[iVertex];
setVertexPosition(iVertex, source_vertex); setVertexPosition(iVertex, source_vertex);
if(bone_names.size()) { if(mi.bone_names.size()) {
for(int bone_weight_index=0; bone_weight_index<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; bone_weight_index++) { for(int bone_weight_index=0; bone_weight_index<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; bone_weight_index++) {
setBoneIndex(iVertex, bone_weight_index, bone_indexes[iVertex][bone_weight_index]); setBoneIndex(iVertex, bone_weight_index, mi.bone_indexes[iVertex][bone_weight_index]);
setBoneWeight(iVertex, bone_weight_index, bone_weights[iVertex][bone_weight_index]); setBoneWeight(iVertex, bone_weight_index, mi.bone_weights[iVertex][bone_weight_index]);
} }
} }
if(bFirstVertex) { if(bFirstVertex) {
@@ -495,17 +485,17 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
if(source_vertex.y > m_maxPoint.y) m_maxPoint.y = source_vertex.y; if(source_vertex.y > m_maxPoint.y) m_maxPoint.y = source_vertex.y;
if(source_vertex.z > m_maxPoint.z) m_maxPoint.z = source_vertex.z; if(source_vertex.z > m_maxPoint.z) m_maxPoint.z = source_vertex.z;
} }
if(uva.size() > iVertex) { if(mi.uva.size() > iVertex) {
setVertexUVA(iVertex, uva[iVertex]); setVertexUVA(iVertex, mi.uva[iVertex]);
} }
if(uvb.size() > iVertex) { if(mi.uvb.size() > iVertex) {
setVertexUVB(iVertex, uvb[iVertex]); setVertexUVB(iVertex, mi.uvb[iVertex]);
} }
if(normals.size() > iVertex) { if(mi.normals.size() > iVertex) {
setVertexNormal(iVertex, normals[iVertex]); setVertexNormal(iVertex, KRVector3::Normalize(mi.normals[iVertex]));
} }
if(tangents.size() > iVertex) { if(mi.tangents.size() > iVertex) {
setVertexTangent(iVertex, tangents[iVertex]); setVertexTangent(iVertex, KRVector3::Normalize(mi.tangents[iVertex]));
} }
} }
@@ -518,12 +508,12 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
__uint16_t *index_data = getIndexData(); __uint16_t *index_data = getIndexData();
for(std::vector<__uint16_t>::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; *index_data++ = *itr;
} }
__uint32_t *index_base_data = getIndexBaseData(); __uint32_t *index_base_data = getIndexBaseData();
for(std::vector<std::pair<int, int> >::iterator itr=vertex_index_bases.begin(); itr != vertex_index_bases.end(); itr++) { for(std::vector<std::pair<int, int> >::const_iterator itr=mi.vertex_index_bases.begin(); itr != mi.vertex_index_bases.end(); itr++) {
*index_base_data++ = (*itr).first; *index_base_data++ = (*itr).first;
*index_base_data++ = (*itr).second; *index_base_data++ = (*itr).second;
} }
@@ -533,7 +523,7 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
//cout << " Calculate surface normals and tangents\n"; //cout << " Calculate surface normals and tangents\n";
if(calculate_normals || calculate_tangents) { if(calculate_normals || calculate_tangents) {
// NOTE: This will not work properly if the vertices are already indexed // NOTE: This will not work properly if the vertices are already indexed
for(int iVertex=0; iVertex < vertices.size(); iVertex+= 3) { for(int iVertex=0; iVertex < mi.vertices.size(); iVertex+= 3) {
KRVector3 p1 = getVertexPosition(iVertex); KRVector3 p1 = getVertexPosition(iVertex);
KRVector3 p2 = getVertexPosition(iVertex+1); KRVector3 p2 = getVertexPosition(iVertex+1);
KRVector3 p3 = getVertexPosition(iVertex+2); KRVector3 p3 = getVertexPosition(iVertex+2);
@@ -911,6 +901,11 @@ char *KRMesh::getBoneName(int bone_index)
return getBone(bone_index)->szName; return getBone(bone_index)->szName;
} }
KRMat4 KRMesh::getBoneBindPose(int bone_index)
{
return KRMat4(getBone(bone_index)->bind_pose);
}
KRMesh::model_format_t KRMesh::getModelFormat() const KRMesh::model_format_t KRMesh::getModelFormat() const
{ {
return (model_format_t)getHeader()->model_format; return (model_format_t)getHeader()->model_format;
@@ -1064,30 +1059,19 @@ void KRMesh::convertToIndexed()
char *szKey = new char[m_vertex_size * 2 + 1]; 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 // 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<std::pair<int, int> > vertex_index_bases;
int vertex_index_offset = 0; int vertex_index_offset = 0;
int vertex_index_base_start_vertex = 0; int vertex_index_base_start_vertex = 0;
std::vector<KRVector3> vertices; mesh_info mi;
std::vector<KRVector2> uva;
std::vector<KRVector2> uvb;
std::vector<KRVector3> normals;
std::vector<KRVector3> tangents;
std::vector<int> submesh_starts;
std::vector<int> submesh_lengths;
std::vector<std::string> material_names;
std::vector<std::string> bone_names;
std::vector<std::vector<int> > bone_indexes;
std::vector<std::vector<float> > bone_weights;
int bone_count = getBoneCount(); int bone_count = getBoneCount();
for(int bone_index=0; bone_index < bone_count; bone_index++) { 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++) { 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); int vertexes_remaining = getVertexCount(submesh_index);
@@ -1097,13 +1081,13 @@ void KRMesh::convertToIndexed()
} }
if(submesh_index == 0 || vertex_index_offset + vertex_count > 0xffff) { if(submesh_index == 0 || vertex_index_offset + vertex_count > 0xffff) {
vertex_index_bases.push_back(std::pair<int, int>(vertex_indexes.size(), vertices.size())); mi.vertex_index_bases.push_back(std::pair<int, int>(mi.vertex_indexes.size(), mi.vertices.size()));
vertex_index_offset = 0; 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)); mi.submesh_starts.push_back(mi.vertex_index_bases.size() - 1 + (vertex_index_offset << 16));
submesh_lengths.push_back(vertexes_remaining); mi.submesh_lengths.push_back(vertexes_remaining);
int source_index = getSubmesh(submesh_index)->start_vertex; int source_index = getSubmesh(submesh_index)->start_vertex;
@@ -1189,35 +1173,35 @@ void KRMesh::convertToIndexed()
*/ */
int found_index = -1; int found_index = -1;
if(prev_indexes.count(vertex_key) == 0) { 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)) { 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)) { 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)) { 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)) { 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)) { 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)) { 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)) { 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; prev_indexes[vertex_key] = found_index;
} else { } else {
found_index = prev_indexes[vertex_key]; 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); //fprintf(stderr, "Submesh: %6i IndexBase: %3i Index: %6i\n", submesh_index, vertex_index_bases.size(), found_index);
source_index++; source_index++;
@@ -1233,20 +1217,20 @@ void KRMesh::convertToIndexed()
} }
if(vertex_index_offset + vertex_count > 0xffff) { if(vertex_index_offset + vertex_count > 0xffff) {
vertex_index_bases.push_back(std::pair<int, int>(vertex_indexes.size(), vertices.size())); mi.vertex_index_bases.push_back(std::pair<int, int>(mi.vertex_indexes.size(), mi.vertices.size()));
vertex_index_offset = 0; vertex_index_offset = 0;
vertex_index_base_start_vertex = vertices.size(); vertex_index_base_start_vertex = mi.vertices.size();
} }
} }
} }
delete szKey; 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);
mi.format = KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES;
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); LoadData(mi, false, false);
} }
void KRMesh::optimize() void KRMesh::optimize()

View File

@@ -31,6 +31,7 @@
#include "KREngine-common.h" #include "KREngine-common.h"
#include "KRVector2.h" #include "KRVector2.h"
#include "KRMat4.h"
#include "KRContext.h" #include "KRContext.h"
#include "KRBone.h" #include "KRBone.h"
@@ -58,6 +59,9 @@ class KRNode;
class KRMesh : public KRResource { class KRMesh : public KRResource {
public: public:
KRMesh(KRContext &context, std::string name, KRDataBlock *data); KRMesh(KRContext &context, std::string name, KRDataBlock *data);
KRMesh(KRContext &context, std::string name); KRMesh(KRContext &context, std::string name);
virtual ~KRMesh(); virtual ~KRMesh();
@@ -87,6 +91,23 @@ public:
KRENGINE_MODEL_FORMAT_INDEXED_STRIP KRENGINE_MODEL_FORMAT_INDEXED_STRIP
} model_format_t; } model_format_t;
typedef struct {
model_format_t format;
std::vector<KRVector3> vertices;
std::vector<__uint16_t> vertex_indexes;
std::vector<std::pair<int, int> > vertex_index_bases;
std::vector<KRVector2> uva;
std::vector<KRVector2> uvb;
std::vector<KRVector3> normals;
std::vector<KRVector3> tangents;
std::vector<int> submesh_starts;
std::vector<int> submesh_lengths;
std::vector<std::string> material_names;
std::vector<std::string> bone_names;
std::vector<std::vector<int> > bone_indexes;
std::vector<KRMat4> bone_bind_poses;
std::vector<std::vector<float> > bone_weights;
} mesh_info;
void render(const std::string &object_name, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones); void render(const std::string &object_name, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones);
@@ -96,7 +117,7 @@ public:
virtual bool save(const std::string& path); virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data); virtual bool save(KRDataBlock &data);
void LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::pair<int, int> > vertex_index_bases, std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::vector<std::string> bone_names, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > bone_weights, model_format_t model_format, bool calculate_normals, bool calculate_tangents); void LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vector<std::pair<int, int> > vertex_index_bases, std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::vector<std::string> bone_names, std::vector<KRMat4> bone_bind_poses, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > bone_weights, model_format_t model_format, */const mesh_info &mi, bool calculate_normals, bool calculate_tangents);
void loadPack(KRDataBlock *data); void loadPack(KRDataBlock *data);
void convertToIndexed(); void convertToIndexed();
@@ -132,6 +153,7 @@ public:
typedef struct { typedef struct {
char szName[KRENGINE_MAX_NAME_LENGTH]; char szName[KRENGINE_MAX_NAME_LENGTH];
float bind_pose[16];
} pack_bone; } pack_bone;
int getLODCoverage() const; int getLODCoverage() const;
@@ -166,6 +188,7 @@ public:
int getBoneCount(); int getBoneCount();
char *getBoneName(int bone_index); char *getBoneName(int bone_index);
KRMat4 getBoneBindPose(int bone_index);
model_format_t getModelFormat() const; model_format_t getModelFormat() const;

View File

@@ -34,43 +34,32 @@
KRMeshCube::KRMeshCube(KRContext &context) : KRMesh(context, "__cube") KRMeshCube::KRMeshCube(KRContext &context) : KRMesh(context, "__cube")
{ {
std::vector<KRVector3> vertices; KRMesh::mesh_info mi;
std::vector<KRVector2> uva;
std::vector<KRVector2> uvb;
std::vector<KRVector3> normals;
std::vector<KRVector3> tangents;
std::vector<int> submesh_starts;
std::vector<int> submesh_lengths;
std::vector<std::string> material_names;
std::vector<std::string> bone_names;
std::vector<std::vector<int> > bone_indexes;
std::vector<std::vector<float> > bone_weights;
vertices.push_back(KRVector3(1.0, 1.0, 1.0)); mi.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));
vertices.push_back(KRVector3(1.0,-1.0, 1.0)); mi.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));
vertices.push_back(KRVector3(-1.0,-1.0,-1.0)); mi.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));
vertices.push_back(KRVector3(-1.0, 1.0,-1.0)); mi.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));
vertices.push_back(KRVector3(1.0, 1.0,-1.0)); mi.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));
vertices.push_back(KRVector3(1.0,-1.0,-1.0)); mi.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));
vertices.push_back(KRVector3(1.0, 1.0,-1.0)); mi.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));
submesh_starts.push_back(0); mi.submesh_starts.push_back(0);
submesh_lengths.push_back(vertices.size()); mi.submesh_lengths.push_back(mi.vertices.size());
material_names.push_back(""); mi.material_names.push_back("");
mi.format = KRENGINE_MODEL_FORMAT_STRIP;
std::vector<__uint16_t> vertex_indexes; LoadData(mi, true, true);
std::vector<std::pair<int, int> > 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);
} }
KRMeshCube::~KRMeshCube() KRMeshCube::~KRMeshCube()

View File

@@ -34,19 +34,7 @@
KRMeshSphere::KRMeshSphere(KRContext &context) : KRMesh(context, "__sphere") KRMeshSphere::KRMeshSphere(KRContext &context) : KRMesh(context, "__sphere")
{ {
std::vector<KRVector3> vertices; KRMesh::mesh_info mi;
std::vector<KRVector2> uva;
std::vector<KRVector2> uvb;
std::vector<KRVector3> normals;
std::vector<KRVector3> tangents;
std::vector<int> submesh_starts;
std::vector<int> submesh_lengths;
std::vector<std::string> material_names;
std::vector<std::string> bone_names;
std::vector<std::vector<int> > bone_indexes;
std::vector<std::vector<float> > bone_weights;
// Create a triangular facet approximation to a sphere // Create a triangular facet approximation to a sphere
// Based on algorithm from Paul Bourke: http://paulbourke.net/miscellaneous/sphere_cylinder/ // 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++) { for(int facet_index=0; facet_index < facet_count; facet_index++) {
vertices.push_back(f[facet_index].p1); mi.vertices.push_back(f[facet_index].p1);
vertices.push_back(f[facet_index].p2); mi.vertices.push_back(f[facet_index].p2);
vertices.push_back(f[facet_index].p3); mi.vertices.push_back(f[facet_index].p3);
} }
submesh_starts.push_back(0); mi.submesh_starts.push_back(0);
submesh_lengths.push_back(vertices.size()); mi.submesh_lengths.push_back(mi.vertices.size());
material_names.push_back(""); mi.material_names.push_back("");
std::vector<__uint16_t> vertex_indexes;
std::vector<std::pair<int, int> > vertex_index_bases; mi.format = KRENGINE_MODEL_FORMAT_TRIANGLES;
LoadData(mi, true, true);
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);
} }
KRMeshSphere::~KRMeshSphere() KRMeshSphere::~KRMeshSphere()

View File

@@ -34,6 +34,22 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont
m_initialLocalScale = m_localScale; m_initialLocalScale = m_localScale;
m_initialLocalRotation = m_localRotation; 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_parentNode = NULL;
m_pScene = &scene; m_pScene = &scene;
m_modelMatrixValid = false; m_modelMatrixValid = false;
@@ -46,16 +62,29 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont
m_activePoseMatrix = KRMat4(); m_activePoseMatrix = KRMat4();
m_lod_visible = false; m_lod_visible = false;
m_scale_compensation = 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() { KRNode::~KRNode() {
while(m_childNodes.size() > 0) { while(m_childNodes.size() > 0) {
delete *m_childNodes.begin(); delete *m_childNodes.begin();
} }
for(std::set<KRBehavior *>::iterator itr = m_behaviors.begin(); itr != m_behaviors.end(); itr++) {
delete *itr;
}
m_behaviors.clear();
if(m_parentNode) { if(m_parentNode) {
m_parentNode->childDeleted(this); m_parentNode->childDeleted(this);
} }
getScene().notify_sceneGraphDelete(this); getScene().notify_sceneGraphDelete(this);
} }
@@ -181,9 +210,13 @@ void KRNode::setWorldTranslation(const KRVector3 &v)
void KRNode::setWorldRotation(const KRVector3 &v) void KRNode::setWorldRotation(const KRVector3 &v)
{ {
if(m_parentNode) { if(m_parentNode) {
setLocalRotation(KRMat4::DotNoTranslate(m_parentNode->getInverseModelMatrix(), v)); setLocalRotation((KRQuaternion(v) * -m_parentNode->getWorldRotation()).eulerXYZ());
setPreRotation(KRVector3::Zero());
setPostRotation(KRVector3::Zero());
} else { } else {
setLocalRotation(v); setLocalRotation(v);
setPreRotation(KRVector3::Zero());
setPostRotation(KRVector3::Zero());
} }
} }
@@ -349,32 +382,6 @@ const KRVector3 KRNode::getWorldTranslation() {
const KRVector3 KRNode::getWorldScale() { const KRVector3 KRNode::getWorldScale() {
return KRMat4::DotNoTranslate(getModelMatrix(), m_localScale); 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<KRBone *>(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<KRBone *>(m_parentNode)) {
KRVector3 parent_rotation = m_parentNode->getActivePoseWorldRotation();
world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ();
}
return world_rotation;
}
std::string KRNode::getElementName() { std::string KRNode::getElementName() {
return "node"; return "node";
@@ -420,8 +427,10 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
new_node = new KRAmbientZone(scene, szName); new_node = new KRAmbientZone(scene, szName);
} else if(strcmp(szElementName, "reverb_zone") == 0) { } else if(strcmp(szElementName, "reverb_zone") == 0) {
new_node = new KRReverbZone(scene, szName); new_node = new KRReverbZone(scene, szName);
} else if(strcmp(szElementName, "camera") == 0) {
new_node = new KRCamera(scene, szName);
} }
if(new_node) { if(new_node) {
new_node->loadXML(e); new_node->loadXML(e);
} }
@@ -431,6 +440,7 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
void KRNode::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, RenderPass renderPass) void KRNode::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, RenderPass renderPass)
{ {
m_lastRenderFrame = getContext().getCurrentFrame();
} }
const std::set<KRNode *> &KRNode::getChildren() { const std::set<KRNode *> &KRNode::getChildren() {
@@ -500,23 +510,21 @@ const KRMat4 &KRNode::getModelMatrix()
} }
if(getScaleCompensation() && parent_is_bone) { if(getScaleCompensation() && parent_is_bone) {
m_modelMatrix.translate(-m_scalingPivot);
m_modelMatrix.scale(m_localScale);
m_modelMatrix.translate(m_scalingPivot); // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
m_modelMatrix.translate(m_scalingOffset); m_modelMatrix = KRMat4::Translation(-m_scalingPivot)
m_modelMatrix.translate(-m_rotationPivot); * KRMat4::Scaling(m_localScale)
m_modelMatrix.rotate(-m_postRotation.z, Z_AXIS); * KRMat4::Translation(m_scalingPivot)
m_modelMatrix.rotate(-m_postRotation.y, Y_AXIS); * KRMat4::Translation(m_scalingOffset)
m_modelMatrix.rotate(-m_postRotation.x, X_AXIS); * KRMat4::Translation(-m_rotationPivot)
m_modelMatrix.rotate(m_localRotation.x, X_AXIS); //* (KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation)).rotationMatrix()
m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); * KRMat4::Rotation(m_postRotation)
m_modelMatrix.rotate(m_localRotation.z, Z_AXIS); * KRMat4::Rotation(m_localRotation)
m_modelMatrix.rotate(m_preRotation.x, X_AXIS); * KRMat4::Rotation(m_preRotation)
m_modelMatrix.rotate(m_preRotation.y, Y_AXIS); * KRMat4::Translation(m_rotationPivot)
m_modelMatrix.rotate(m_preRotation.z, Z_AXIS); * KRMat4::Translation(m_rotationOffset);
m_modelMatrix.translate(m_rotationPivot);
m_modelMatrix.translate(m_rotationOffset);
//m_modelMatrix.translate(m_localTranslation);
if(m_parentNode) { if(m_parentNode) {
m_modelMatrix.rotate(m_parentNode->getWorldRotation()); m_modelMatrix.rotate(m_parentNode->getWorldRotation());
@@ -527,25 +535,19 @@ const KRMat4 &KRNode::getModelMatrix()
} else { } else {
// WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
m_modelMatrix.translate(-m_scalingPivot); m_modelMatrix = KRMat4::Translation(-m_scalingPivot)
m_modelMatrix.scale(m_localScale); * KRMat4::Scaling(m_localScale)
m_modelMatrix.translate(m_scalingPivot); * KRMat4::Translation(m_scalingPivot)
m_modelMatrix.translate(m_scalingOffset); * KRMat4::Translation(m_scalingOffset)
m_modelMatrix.translate(-m_rotationPivot); * KRMat4::Translation(-m_rotationPivot)
m_modelMatrix.rotate(-m_postRotation.z, Z_AXIS); //* (KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation)).rotationMatrix()
m_modelMatrix.rotate(-m_postRotation.y, Y_AXIS); * KRMat4::Rotation(m_postRotation)
m_modelMatrix.rotate(-m_postRotation.x, X_AXIS); * KRMat4::Rotation(m_localRotation)
m_modelMatrix.rotate(m_localRotation.x, X_AXIS); * KRMat4::Rotation(m_preRotation)
m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); * KRMat4::Translation(m_rotationPivot)
m_modelMatrix.rotate(m_localRotation.z, Z_AXIS); * KRMat4::Translation(m_rotationOffset)
m_modelMatrix.rotate(m_preRotation.x, X_AXIS); * KRMat4::Translation(m_localTranslation);
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);
if(m_parentNode) { if(m_parentNode) {
m_modelMatrix *= m_parentNode->getModelMatrix(); m_modelMatrix *= m_parentNode->getModelMatrix();
} }
@@ -568,22 +570,17 @@ const KRMat4 &KRNode::getBindPoseMatrix()
} }
if(getScaleCompensation() && parent_is_bone) { if(getScaleCompensation() && parent_is_bone) {
m_bindPoseMatrix.translate(-m_initialScalingPivot); m_bindPoseMatrix = KRMat4::Translation(-m_initialScalingPivot)
m_bindPoseMatrix.scale(m_initialLocalScale); * KRMat4::Scaling(m_initialLocalScale)
m_bindPoseMatrix.translate(m_initialScalingPivot); * KRMat4::Translation(m_initialScalingPivot)
m_bindPoseMatrix.translate(m_initialScalingOffset); * KRMat4::Translation(m_initialScalingOffset)
m_bindPoseMatrix.translate(-m_initialRotationPivot); * KRMat4::Translation(-m_initialRotationPivot)
m_bindPoseMatrix.rotate(-m_initialPostRotation.z, Z_AXIS); //* (KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation)).rotationMatrix()
m_bindPoseMatrix.rotate(-m_initialPostRotation.y, Y_AXIS); * KRMat4::Rotation(m_initialPostRotation)
m_bindPoseMatrix.rotate(-m_initialPostRotation.x, X_AXIS); * KRMat4::Rotation(m_initialLocalRotation)
m_bindPoseMatrix.rotate(m_initialLocalRotation.x, X_AXIS); * KRMat4::Rotation(m_initialPreRotation)
m_bindPoseMatrix.rotate(m_initialLocalRotation.y, Y_AXIS); * KRMat4::Translation(m_initialRotationPivot)
m_bindPoseMatrix.rotate(m_initialLocalRotation.z, Z_AXIS); * KRMat4::Translation(m_initialRotationOffset);
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.translate(m_localTranslation); //m_bindPoseMatrix.translate(m_localTranslation);
if(m_parentNode) { if(m_parentNode) {
@@ -595,26 +592,22 @@ const KRMat4 &KRNode::getBindPoseMatrix()
} else { } else {
// WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 // 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) { if(m_parentNode && parent_is_bone) {
m_bindPoseMatrix *= m_parentNode->getBindPoseMatrix(); m_bindPoseMatrix *= m_parentNode->getBindPoseMatrix();
} }
} }
@@ -637,25 +630,20 @@ const KRMat4 &KRNode::getActivePoseMatrix()
} }
if(getScaleCompensation() && parent_is_bone) { if(getScaleCompensation() && parent_is_bone) {
m_activePoseMatrix.translate(-m_scalingPivot); m_activePoseMatrix= KRMat4::Translation(-m_scalingPivot)
m_activePoseMatrix.scale(m_localScale); * KRMat4::Scaling(m_localScale)
m_activePoseMatrix.translate(m_scalingPivot); * KRMat4::Translation(m_scalingPivot)
m_activePoseMatrix.translate(m_scalingOffset); * KRMat4::Translation(m_scalingOffset)
m_activePoseMatrix.translate(-m_rotationPivot); * KRMat4::Translation(-m_rotationPivot)
m_activePoseMatrix.rotate(-m_postRotation.z, Z_AXIS); * KRMat4::Rotation(m_postRotation)
m_activePoseMatrix.rotate(-m_postRotation.y, Y_AXIS); * KRMat4::Rotation(m_localRotation)
m_activePoseMatrix.rotate(-m_postRotation.x, X_AXIS); * KRMat4::Rotation(m_preRotation)
m_activePoseMatrix.rotate(m_localRotation.x, X_AXIS); * KRMat4::Translation(m_rotationPivot)
m_activePoseMatrix.rotate(m_localRotation.y, Y_AXIS); * KRMat4::Translation(m_rotationOffset);
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);
if(m_parentNode) { 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)); m_activePoseMatrix.translate(KRMat4::Dot(m_parentNode->getActivePoseMatrix(), m_localTranslation));
} else { } else {
m_activePoseMatrix.translate(m_localTranslation); m_activePoseMatrix.translate(m_localTranslation);
@@ -663,23 +651,17 @@ const KRMat4 &KRNode::getActivePoseMatrix()
} else { } else {
// WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
m_activePoseMatrix.translate(-m_scalingPivot); m_activePoseMatrix = KRMat4::Translation(-m_scalingPivot)
m_activePoseMatrix.scale(m_localScale); * KRMat4::Scaling(m_localScale)
m_activePoseMatrix.translate(m_scalingPivot); * KRMat4::Translation(m_scalingPivot)
m_activePoseMatrix.translate(m_scalingOffset); * KRMat4::Translation(m_scalingOffset)
m_activePoseMatrix.translate(-m_rotationPivot); * KRMat4::Translation(-m_rotationPivot)
m_activePoseMatrix.rotate(-m_postRotation.z, Z_AXIS); * KRMat4::Rotation(m_postRotation)
m_activePoseMatrix.rotate(-m_postRotation.y, Y_AXIS); * KRMat4::Rotation(m_localRotation)
m_activePoseMatrix.rotate(-m_postRotation.x, X_AXIS); * KRMat4::Rotation(m_preRotation)
m_activePoseMatrix.rotate(m_localRotation.x, X_AXIS); * KRMat4::Translation(m_rotationPivot)
m_activePoseMatrix.rotate(m_localRotation.y, Y_AXIS); * KRMat4::Translation(m_rotationOffset)
m_activePoseMatrix.rotate(m_localRotation.z, Z_AXIS); * KRMat4::Translation(m_localTranslation);
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);
if(m_parentNode && parent_is_bone) { 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<KRBone *>(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<KRBone *>(m_parentNode)) {
world_rotation = world_rotation * m_parentNode->getActivePoseWorldRotation();
}
return world_rotation;
}
const KRMat4 &KRNode::getInverseModelMatrix() const KRMat4 &KRNode::getInverseModelMatrix()
{ {
if(!m_inverseModelMatrixValid) { if(!m_inverseModelMatrixValid) {
@@ -713,59 +719,124 @@ const KRMat4 &KRNode::getInverseBindPoseMatrix()
void KRNode::physicsUpdate(float deltaTime) void KRNode::physicsUpdate(float deltaTime)
{ {
const long MIN_DISPLAY_FRAMES = 10;
bool visible = m_lastRenderFrame + MIN_DISPLAY_FRAMES >= getContext().getCurrentFrame();
for(std::set<KRBehavior *>::iterator itr=m_behaviors.begin(); itr != m_behaviors.end(); itr++) {
(*itr)->update(deltaTime);
if(visible) {
(*itr)->visibleUpdate(deltaTime);
}
}
} }
bool KRNode::hasPhysics() bool KRNode::hasPhysics()
{ {
return false; return m_behaviors.size() > 0;
} }
void KRNode::SetAttribute(node_attribute_type attrib, float v) void KRNode::SetAttribute(node_attribute_type attrib, float v)
{ {
if(m_animation_mask[attrib]) return;
const float DEGREES_TO_RAD = M_PI / 180.0f; const float DEGREES_TO_RAD = M_PI / 180.0f;
//printf("%s - ", m_name.c_str()); //printf("%s - ", m_name.c_str());
switch(attrib) { switch(attrib) {
case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X: case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X:
//printf("translate_x: %f\n", v);
setLocalTranslation(KRVector3(v, m_localTranslation.y, m_localTranslation.z)); setLocalTranslation(KRVector3(v, m_localTranslation.y, m_localTranslation.z));
break; break;
case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y: case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y:
//printf("translate_y: %f\n", v);
setLocalTranslation(KRVector3(m_localTranslation.x, v, m_localTranslation.z)); setLocalTranslation(KRVector3(m_localTranslation.x, v, m_localTranslation.z));
break; break;
case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z: case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z:
//printf("translate_z: %f\n", v);
setLocalTranslation(KRVector3(m_localTranslation.x, m_localTranslation.y, v)); setLocalTranslation(KRVector3(m_localTranslation.x, m_localTranslation.y, v));
break; break;
case KRENGINE_NODE_ATTRIBUTE_SCALE_X: case KRENGINE_NODE_ATTRIBUTE_SCALE_X:
//printf("scale_x: %f\n", v);
setLocalScale(KRVector3(v, m_localScale.y, m_localScale.z)); setLocalScale(KRVector3(v, m_localScale.y, m_localScale.z));
break; break;
case KRENGINE_NODE_ATTRIBUTE_SCALE_Y: case KRENGINE_NODE_ATTRIBUTE_SCALE_Y:
//printf("scale_y: %f\n", v);
setLocalScale(KRVector3(m_localScale.x, v, m_localScale.z)); setLocalScale(KRVector3(m_localScale.x, v, m_localScale.z));
break; break;
case KRENGINE_NODE_ATTRIBUTE_SCALE_Z: case KRENGINE_NODE_ATTRIBUTE_SCALE_Z:
//printf("scale_z: %f\n", v);
setLocalScale(KRVector3(m_localScale.x, m_localScale.y, v)); setLocalScale(KRVector3(m_localScale.x, m_localScale.y, v));
break; break;
case KRENGINE_NODE_ATTRIBUTE_ROTATE_X: case KRENGINE_NODE_ATTRIBUTE_ROTATE_X:
//printf("rotate_x: %f\n", v);
setLocalRotation(KRVector3(v * DEGREES_TO_RAD, m_localRotation.y, m_localRotation.z)); setLocalRotation(KRVector3(v * DEGREES_TO_RAD, m_localRotation.y, m_localRotation.z));
break; break;
case KRENGINE_NODE_ATTRIBUTE_ROTATE_Y: case KRENGINE_NODE_ATTRIBUTE_ROTATE_Y:
//printf("rotate_y: %f\n", v);
setLocalRotation(KRVector3(m_localRotation.x, v * DEGREES_TO_RAD, m_localRotation.z)); setLocalRotation(KRVector3(m_localRotation.x, v * DEGREES_TO_RAD, m_localRotation.z));
break; break;
case KRENGINE_NODE_ATTRIBUTE_ROTATE_Z: case KRENGINE_NODE_ATTRIBUTE_ROTATE_Z:
//printf("rotate_z: %f\n", v);
setLocalRotation(KRVector3(m_localRotation.x, m_localRotation.y, v * DEGREES_TO_RAD)); setLocalRotation(KRVector3(m_localRotation.x, m_localRotation.y, v * DEGREES_TO_RAD));
break; 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() void KRNode::removeFromOctreeNodes()
{ {
for(std::set<KROctreeNode *>::iterator itr=m_octree_nodes.begin(); itr != m_octree_nodes.end(); itr++) { for(std::set<KROctreeNode *>::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); return KRMat4::Dot(getInverseModelMatrix(), world_point);
} }
void KRNode::addBehavior(KRBehavior *behavior)
{
m_behaviors.insert(behavior);
behavior->__setNode(this);
getScene().notify_sceneGraphModify(this);
}

View File

@@ -14,6 +14,7 @@
#include "KRViewport.h" #include "KRViewport.h"
#include "tinyxml2.h" #include "tinyxml2.h"
#include "KROctreeNode.h" #include "KROctreeNode.h"
#include "KRBehavior.h"
class KRCamera; class KRCamera;
class KRShaderManager; class KRShaderManager;
@@ -95,10 +96,10 @@ public:
const KRVector3 getWorldTranslation(); const KRVector3 getWorldTranslation();
const KRVector3 getWorldScale(); const KRVector3 getWorldScale();
const KRVector3 getWorldRotation(); const KRQuaternion getWorldRotation();
const KRVector3 getBindPoseWorldRotation(); const KRQuaternion getBindPoseWorldRotation();
const KRVector3 getActivePoseWorldRotation(); const KRQuaternion getActivePoseWorldRotation();
const KRVector3 localToWorld(const KRVector3 &local_point); const KRVector3 localToWorld(const KRVector3 &local_point);
const KRVector3 worldToLocal(const KRVector3 &world_point); const KRVector3 worldToLocal(const KRVector3 &world_point);
@@ -124,7 +125,26 @@ public:
KRENGINE_NODE_ATTRIBUTE_SCALE_Z, KRENGINE_NODE_ATTRIBUTE_SCALE_Z,
KRENGINE_NODE_ATTRIBUTE_ROTATE_X, KRENGINE_NODE_ATTRIBUTE_ROTATE_X,
KRENGINE_NODE_ATTRIBUTE_ROTATE_Y, 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); void SetAttribute(node_attribute_type attrib, float v);
@@ -141,6 +161,8 @@ public:
void setScaleCompensation(bool scale_compensation); void setScaleCompensation(bool scale_compensation);
bool getScaleCompensation(); bool getScaleCompensation();
void setAnimationEnabled(node_attribute_type attrib, bool enable);
bool getAnimationEnabled(node_attribute_type attrib) const;
protected: protected:
KRVector3 m_localTranslation; KRVector3 m_localTranslation;
@@ -174,7 +196,10 @@ protected:
KRNode *m_parentNode; KRNode *m_parentNode;
std::set<KRNode *> m_childNodes; std::set<KRNode *> m_childNodes;
bool m_animation_mask[KRENGINE_NODE_ATTRIBUTE_COUNT];
private: private:
long m_lastRenderFrame;
void invalidateModelMatrix(); void invalidateModelMatrix();
void invalidateBindPoseMatrix(); void invalidateBindPoseMatrix();
KRMat4 m_modelMatrix; KRMat4 m_modelMatrix;
@@ -197,8 +222,10 @@ private:
std::set<KROctreeNode *> m_octree_nodes; std::set<KROctreeNode *> m_octree_nodes;
bool m_scale_compensation; bool m_scale_compensation;
public: std::set<KRBehavior *> m_behaviors;
public:
void addBehavior(KRBehavior *behavior);
void removeFromOctreeNodes(); void removeFromOctreeNodes();
void addToOctreeNode(KROctreeNode *octree_node); void addToOctreeNode(KROctreeNode *octree_node);
void childDeleted(KRNode *child_node); void childDeleted(KRNode *child_node);

View File

@@ -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) { void KRQuaternion::setEulerZYX(const KRVector3 &euler) {
// ZYX Order! // ZYX Order!
float c1 = cos(euler[0] * 0.5f); float c1 = cos(euler[0] * 0.5f);
@@ -189,10 +196,10 @@ KRQuaternion& KRQuaternion::operator +=(const KRQuaternion& v) {
} }
KRQuaternion& KRQuaternion::operator -=(const KRQuaternion& v) { KRQuaternion& KRQuaternion::operator -=(const KRQuaternion& v) {
m_val[0] += v[0]; m_val[0] -= v[0];
m_val[1] += v[1]; m_val[1] -= v[1];
m_val[2] += v[2]; m_val[2] -= v[2];
m_val[3] += v[3]; m_val[3] -= v[3];
return *this; return *this;
} }
@@ -270,28 +277,30 @@ void KRQuaternion::conjugate() {
} }
KRMat4 KRQuaternion::rotationMatrix() const { KRMat4 KRQuaternion::rotationMatrix() const {
KRVector3 euler = eulerXYZ();
KRMat4 matRotate; KRMat4 matRotate;
/*
KRVector3 euler = eulerXYZ();
matRotate.rotate(euler.x, X_AXIS); matRotate.rotate(euler.x, X_AXIS);
matRotate.rotate(euler.y, Y_AXIS); matRotate.rotate(euler.y, Y_AXIS);
matRotate.rotate(euler.z, Z_AXIS); matRotate.rotate(euler.z, Z_AXIS);
*/
// FINDME - Determine why the more optimal routine commented below wasn't working // 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.c[0] = 1.0 - 2.0 * (m_val[2] * m_val[2] + m_val[3] * m_val[3]);
matRotate.getPointer()[5] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[3] * m_val[3]); matRotate.c[1] = 2.0 * (m_val[1] * m_val[2] - m_val[0] * m_val[3]);
matRotate.getPointer()[6] = 2.0 * (m_val[2] * m_val[3] - m_val[0] * m_val[1]); 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.c[4] = 2.0 * (m_val[1] * m_val[2] + m_val[0] * m_val[3]);
matRotate.getPointer()[9] = 2.0 * (m_val[0] * m_val[1] + m_val[2] * m_val[3]); matRotate.c[5] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[3] * m_val[3]);
matRotate.getPointer()[10] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[2] * m_val[2]); 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; return matRotate;
} }

View File

@@ -67,7 +67,7 @@ public:
float& operator [](unsigned i); float& operator [](unsigned i);
float operator [](unsigned i) const; float operator [](unsigned i) const;
void setEulerXYZ(const KRVector3 &euler);
void setEulerZYX(const KRVector3 &euler); void setEulerZYX(const KRVector3 &euler);
KRVector3 eulerXYZ() const; KRVector3 eulerXYZ() const;
KRMat4 rotationMatrix() const; KRMat4 rotationMatrix() const;

View File

@@ -42,10 +42,10 @@ KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLaye
void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
//void BakeNode(KFbxNode* pNode); //void BakeNode(KFbxNode* pNode);
void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial); void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial);
void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh); void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh);
KRNode *LoadMesh(KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
KRNode *LoadLight(KRNode *parent_node, 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); KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode);
std::string GetFbxObjectName(FbxObject *obj); 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 // 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 // TODO - This should be updated to only add a prefix or suffix if needed to make the name unique
std::stringstream st; if(strcmp(obj->GetName(), "default_camera") == 0) {
st << "fbx_"; // 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
st << obj->GetUniqueID(); return "default_camera";
if(strlen(obj->GetName()) != 0) { } else {
st << "_"; std::stringstream st;
st << obj->GetName(); 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) 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<FbxMesh>(i); FbxMesh *mesh = pFbxScene->GetSrcObject<FbxMesh>(i);
printf(" Mesh %i of %i: %s\n", i+1, mesh_count, mesh->GetNode()->GetName()); 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 ----====---- // ----====---- Import Textures ----====----
@@ -640,6 +645,171 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z); new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z);
pAnimationLayer->addAttribute(new_attribute); 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_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot);
fbxDouble3 local_scale = pNode->LclScaling.Get(); // pNode->GetGeometricScaling(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 post_rotation = pNode->PostRotation.Get();
fbxDouble3 pre_rotation = pNode->PreRotation.Get(); fbxDouble3 pre_rotation = pNode->PreRotation.Get();
fbxDouble3 rotation_offset = pNode->RotationOffset.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_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_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_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_pre_rotation, node_post_rotation;
KRVector3 node_post_rotation = KRVector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI; 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 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]); // 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; KRNode *new_node = NULL;
switch(attribute_type) { switch(attribute_type) {
case KFbxNodeAttribute::eMesh: case KFbxNodeAttribute::eMesh:
new_node = LoadMesh(parent_node, pGeometryConverter, pNode); new_node = LoadMesh(parent_node, pFbxScene, pGeometryConverter, pNode);
break; break;
case KFbxNodeAttribute::eLight: case KFbxNodeAttribute::eLight:
new_node = LoadLight(parent_node, pNode); new_node = LoadLight(parent_node, pNode);
break; break;
case KFbxNodeAttribute::eSkeleton: case KFbxNodeAttribute::eSkeleton:
new_node = LoadSkeleton(parent_node, pNode); new_node = LoadSkeleton(parent_node, pFbxScene, pNode);
break; break;
case KFbxNodeAttribute::eCamera: case KFbxNodeAttribute::eCamera:
new_node = LoadCamera(parent_node, pNode); 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); 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(); int control_point_count = pMesh->GetControlPointsCount();
KFbxVector4* control_points = pMesh->GetControlPoints(); KFbxVector4* control_points = pMesh->GetControlPoints();
struct control_point_weight_info { control_point_weight_info_t *control_point_weights = new control_point_weight_info_t[control_point_count];
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];
for(int control_point=0; control_point < control_point_count; control_point++) { for(int control_point=0; control_point < control_point_count; control_point++) {
for(int i=0; i<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) { for(int i=0; i<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) {
control_point_weights[control_point].weights[i] = 0.0f; control_point_weights[control_point].weights[i] = 0.0f;
@@ -1047,7 +1230,6 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
} }
std::vector<std::string> bone_names;
bool too_many_bone_weights = false; bool too_many_bone_weights = false;
// Collect the top 4 bone weights per vertex ... // 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"); printf(" Warning! link mode not supported.\n");
} }
std::string bone_name = GetFbxObjectName(cluster->GetLink()); 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<int> 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(); int cluster_control_point_count = cluster->GetControlPointIndicesCount();
for(int control_point=0; control_point<cluster_control_point_count; control_point++) { for(int cluster_control_point=0; cluster_control_point<cluster_control_point_count; cluster_control_point++) {
control_point_weight_info &weight_info = control_point_weights[cluster->GetControlPointIndices()[control_point]]; int control_point = cluster->GetControlPointIndices()[cluster_control_point];
float bone_weight = cluster->GetControlPointWeights()[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(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) { if(weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] != 0.0f) {
too_many_bone_weights = true; 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); 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 // 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++) { 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; float total_weights = 0.0f;
for(int i=0; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) { for(int i=0; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) {
total_weights += weight_info.weights[i]; total_weights += weight_info.weights[i];
@@ -1116,17 +1325,17 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
int elementmaterial_count = pMesh->GetElementMaterialCount(); 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 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<std::vector<float> > bone_weights; // std::vector<std::vector<float> > bone_weights;
std::vector<std::vector<int> > bone_indexes; // std::vector<std::vector<int> > bone_indexes;
//
std::vector<KRVector3> vertices; // std::vector<KRVector3> vertices;
std::vector<KRVector2> uva; // std::vector<KRVector2> uva;
std::vector<KRVector2> uvb; // std::vector<KRVector2> uvb;
std::vector<KRVector3> normals; // std::vector<KRVector3> normals;
std::vector<KRVector3> tangents; // std::vector<KRVector3> tangents;
std::vector<int> submesh_lengths; // std::vector<int> submesh_lengths;
std::vector<int> submesh_starts; // std::vector<int> submesh_starts;
std::vector<std::string> material_names; // std::vector<std::string> material_names;
int dest_vertex_id = 0; int dest_vertex_id = 0;
@@ -1172,18 +1381,18 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
// ----====---- Read Vertex Position ----====---- // ----====---- Read Vertex Position ----====----
int lControlPointIndex = pMesh->GetPolygonVertex(iPolygon, iVertex); int lControlPointIndex = pMesh->GetPolygonVertex(iPolygon, iVertex);
KFbxVector4 v = control_points[lControlPointIndex]; 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) { if(mi.bone_names.size() > 0) {
control_point_weight_info &weight_info = control_point_weights[lControlPointIndex]; control_point_weight_info_t &weight_info = control_point_weights[lControlPointIndex];
std::vector<int> vertex_bone_indexes; std::vector<int> vertex_bone_indexes;
std::vector<float> vertex_bone_weights; std::vector<float> vertex_bone_weights;
for(int i=0; i<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) { for(int i=0; i<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) {
vertex_bone_indexes.push_back(weight_info.bone_indexes[i]); vertex_bone_indexes.push_back(weight_info.bone_indexes[i]);
vertex_bone_weights.push_back(weight_info.weights[i]); vertex_bone_weights.push_back(weight_info.weights[i]);
} }
bone_indexes.push_back(vertex_bone_indexes); mi.bone_indexes.push_back(vertex_bone_indexes);
bone_weights.push_back(vertex_bone_weights); mi.bone_weights.push_back(vertex_bone_weights);
} }
KRVector2 new_uva = KRVector2(0.0, 0.0); KRVector2 new_uva = KRVector2(0.0, 0.0);
@@ -1200,7 +1409,7 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv)) { if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv)) {
new_uva = KRVector2(uv[0], uv[1]); new_uva = KRVector2(uv[0], uv[1]);
} }
uva.push_back(new_uva); mi.uva.push_back(new_uva);
} }
if(uv_count >= 2) { if(uv_count >= 2) {
@@ -1209,14 +1418,14 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv)) { if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv)) {
new_uvb = KRVector2(uv[0], uv[1]); new_uvb = KRVector2(uv[0], uv[1]);
} }
uvb.push_back(new_uvb); mi.uvb.push_back(new_uvb);
} }
// ----====---- Read Normals ----====---- // ----====---- Read Normals ----====----
KFbxVector4 new_normal; KFbxVector4 new_normal;
if(pMesh->GetPolygonVertexNormal(iPolygon, iVertex, 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) { 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) { if(mat_vertex_count) {
// ----====---- Output last material / submesh details ----====---- // ----====---- Output last material / submesh details ----====----
submesh_starts.push_back(mat_vertex_start); mi.submesh_starts.push_back(mat_vertex_start);
submesh_lengths.push_back(mat_vertex_count); mi.submesh_lengths.push_back(mat_vertex_count);
material_names.push_back(pMaterial->GetName()); mi.material_names.push_back(pMaterial->GetName());
} }
} }
delete control_point_weights; delete control_point_weights;
KRMesh *new_mesh = new KRMesh(context, pSourceMesh->GetNode()->GetName()); KRMesh *new_mesh = new KRMesh(context, pSourceMesh->GetNode()->GetName());
std::vector<__uint16_t> vertex_indexes; new_mesh->LoadData(mi, true, need_tangents);
std::vector<std::pair<int, int> > 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);
context.getModelManager()->addModel(new_mesh); 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); std::string name = GetFbxObjectName(pNode);
KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute(); 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); std::string name = GetFbxObjectName(pNode);
KRBone *new_bone = new KRBone(parent_node->getScene(), name.c_str()); KRBone *new_bone = new KRBone(parent_node->getScene(), name.c_str());
//static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray<int>& pIndex);
// PoseList pose_list;
// FbxArray<int> pose_indices;
// if(FbxPose::GetBindPoseContaining(pFbxScene, pNode, pose_list, pose_indices)) {
// fprintf(stderr, "Found bind pose(s)!\n");
// }
return new_bone; return new_bone;
} }

View File

@@ -17,14 +17,8 @@ std::vector<KRResource *> KRResource::LoadObj(KRContext &context, const std::str
KRMesh *new_mesh = new KRMesh(context, KRResource::GetFileBase(path)); KRMesh *new_mesh = new KRMesh(context, KRResource::GetFileBase(path));
resources.push_back(new_mesh); resources.push_back(new_mesh);
std::vector<KRVector3> vertices;
std::vector<KRVector2> uva; KRMesh::mesh_info mi;
std::vector<KRVector2> uvb;
std::vector<KRVector3> normals;
std::vector<KRVector3> tangents;
std::vector<int> submesh_lengths;
std::vector<int> submesh_starts;
std::vector<std::string> material_names;
std::vector<std::string> material_names_t; std::vector<std::string> material_names_t;
@@ -266,13 +260,13 @@ std::vector<KRResource *> 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 // 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; iVertex+=2;
vertices.push_back(firstFaceVertex); mi.vertices.push_back(firstFaceVertex);
uva.push_back(firstFaceUva); mi.uva.push_back(firstFaceUva);
normals.push_back(firstFaceNormal); mi.normals.push_back(firstFaceNormal);
vertices.push_back(prevFaceVertex); mi.vertices.push_back(prevFaceVertex);
uva.push_back(prevFaceUva); mi.uva.push_back(prevFaceUva);
normals.push_back(prevFaceNormal); mi.normals.push_back(prevFaceNormal);
} }
KRVector3 vertex = indexed_vertices[pFace[iFaceVertex*3+1]]; KRVector3 vertex = indexed_vertices[pFace[iFaceVertex*3+1]];
KRVector2 new_uva; KRVector2 new_uva;
@@ -284,9 +278,9 @@ std::vector<KRResource *> KRResource::LoadObj(KRContext &context, const std::str
KRVector3 normal = indexed_normals[pFace[iFaceVertex*3+3]]; KRVector3 normal = indexed_normals[pFace[iFaceVertex*3+3]];
} }
vertices.push_back(vertex); mi.vertices.push_back(vertex);
uva.push_back(new_uva); mi.uva.push_back(new_uva);
normals.push_back(normal); mi.normals.push_back(normal);
if(iFaceVertex==0) { if(iFaceVertex==0) {
firstFaceVertex = vertex; firstFaceVertex = vertex;
@@ -318,22 +312,24 @@ std::vector<KRResource *> KRResource::LoadObj(KRContext &context, const std::str
for(int iMaterial=0; iMaterial < m_materials.size(); iMaterial++) { for(int iMaterial=0; iMaterial < m_materials.size(); iMaterial++) {
KRMesh::pack_material *pNewMaterial = m_materials[iMaterial]; KRMesh::pack_material *pNewMaterial = m_materials[iMaterial];
if(pNewMaterial->vertex_count > 0) { if(pNewMaterial->vertex_count > 0) {
material_names.push_back(std::string(pNewMaterial->szName)); mi.material_names.push_back(std::string(pNewMaterial->szName));
submesh_starts.push_back(pNewMaterial->start_vertex); mi.submesh_starts.push_back(pNewMaterial->start_vertex);
submesh_lengths.push_back(pNewMaterial->vertex_count); mi.submesh_lengths.push_back(pNewMaterial->vertex_count);
} }
delete pNewMaterial; delete pNewMaterial;
} }
// TODO: Bones not yet supported for OBJ // TODO: Bones not yet supported for OBJ
std::vector<std::string> bone_names; // std::vector<std::string> bone_names;
std::vector<std::vector<int> > bone_indexes; // std::vector<KRMat4> bone_bind_poses;
std::vector<std::vector<float> > bone_weights; // std::vector<std::vector<int> > bone_indexes;
// std::vector<std::vector<float> > bone_weights;
//
// std::vector<__uint16_t> vertex_indexes;
// std::vector<std::pair<int, int> > vertex_index_bases;
std::vector<__uint16_t> vertex_indexes; mi.format = KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES;
std::vector<std::pair<int, int> > vertex_index_bases; new_mesh->LoadData(mi, true, false);
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);
} }
if(pFaces) { if(pFaces) {

View File

@@ -62,7 +62,7 @@ KRScene::~KRScene() {
void KRScene::renderFrame(float deltaTime, int width, int height) { void KRScene::renderFrame(float deltaTime, int width, int height) {
getContext().startFrame(deltaTime); getContext().startFrame(deltaTime);
KRCamera *camera = find<KRCamera>(); KRCamera *camera = find<KRCamera>("default_camera");
if(camera == NULL) { if(camera == NULL) {
// Add a default camera if none are present // Add a default camera if none are present
camera = new KRCamera(*this, "default_camera"); camera = new KRCamera(*this, "default_camera");

View File

@@ -345,11 +345,11 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &
return false; return false;
} }
bool need_to_validate = false; bool shander_changed = false;
if(getContext().getShaderManager()->m_active_shader != this) { if(getContext().getShaderManager()->m_active_shader != this) {
getContext().getShaderManager()->m_active_shader = this; getContext().getShaderManager()->m_active_shader = this;
GLDEBUG(glUseProgram(m_iProgram)); 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); setUniform(KRENGINE_UNIFORM_VOLUMETRIC_ENVIRONMENT_FRAME, 2);
#if DEBUG #if DEBUG
if(need_to_validate) { if(shander_changed) {
GLint logLength; GLint logLength;
GLint validate_status = GL_FALSE; GLint validate_status = GL_FALSE;

View File

@@ -40,7 +40,6 @@
using namespace std; using namespace std;
KRShaderManager::KRShaderManager(KRContext &context) : KRContextObject(context) { KRShaderManager::KRShaderManager(KRContext &context) : KRContextObject(context) {
m_szCurrentShaderKey[0] = '\0';
m_active_shader = NULL; 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<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, int bone_count, const KRNode::RenderPass &renderPass) bool KRShaderManager::selectShader(KRCamera &camera, KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, int bone_count, const KRNode::RenderPass &renderPass)
{ {
if(pShader) { if(pShader) {
bool bSameShader = strcmp(pShader->getKey(), m_szCurrentShaderKey) == 0; return pShader->bind(camera, viewport, matModel, point_lights, directional_lights, spot_lights, renderPass);
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;
}
} else { } else {
return false; return false;
} }

View File

@@ -74,9 +74,6 @@ private:
unordered_map<std::string, std::string> m_fragShaderSource; unordered_map<std::string, std::string> m_fragShaderSource;
unordered_map<std::string, std::string> m_vertShaderSource; unordered_map<std::string, std::string> m_vertShaderSource;
char m_szCurrentShaderKey[256];
}; };
#endif #endif

View File

@@ -59,6 +59,12 @@ KRVector3::KRVector3(float *v) {
z = v[2]; z = v[2];
} }
KRVector3::KRVector3(double *v) {
x = (float)v[0];
y = (float)v[1];
z = (float)v[2];
}
KRVector3 KRVector3::Min() { KRVector3 KRVector3::Min() {
return KRVector3(-std::numeric_limits<float>::max()); return KRVector3(-std::numeric_limits<float>::max());
} }
@@ -99,6 +105,19 @@ KRVector3 KRVector3::Right() {
return KRVector3(1.0f, 0.0f, 0.0f); 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) { KRVector3 KRVector3::Lerp(const KRVector3 &v1, const KRVector3 &v2, float d) {
return v1 + (v2 - v1) * d; return v1 + (v2 - v1) * d;
} }

View File

@@ -51,6 +51,7 @@ public:
KRVector3(float X, float Y, float Z); KRVector3(float X, float Y, float Z);
KRVector3(float v); KRVector3(float v);
KRVector3(float *v); KRVector3(float *v);
KRVector3(double *v);
KRVector3(const KRVector3 &v); KRVector3(const KRVector3 &v);
KRVector3(const KRVector4 &v); KRVector3(const KRVector4 &v);
~KRVector3(); ~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 sqrMagnitude() const; // calculate the square of the magnitude (useful for comparison of magnitudes without the cost of a sqrt() function)
float magnitude() const; float magnitude() const;
void scale(const KRVector3 &v);
void normalize(); void normalize();
static KRVector3 Normalize(const KRVector3 &v); static KRVector3 Normalize(const KRVector3 &v);
@@ -99,6 +101,7 @@ public:
static KRVector3 Down(); static KRVector3 Down();
static KRVector3 Left(); static KRVector3 Left();
static KRVector3 Right(); 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 Lerp(const KRVector3 &v1, const KRVector3 &v2, float d);
static KRVector3 Slerp(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 static void OrthoNormalize(KRVector3 &normal, KRVector3 &tangent); // Gram-Schmidt Orthonormalization

View File

@@ -29,6 +29,7 @@
// or implied, of Kearwood Gilbert. // or implied, of Kearwood Gilbert.
// //
attribute highp vec3 vertex_position, vertex_normal; attribute highp vec3 vertex_position, vertex_normal;
#if HAS_NORMAL_MAP == 1 #if HAS_NORMAL_MAP == 1
attribute highp vec3 vertex_tangent; attribute highp vec3 vertex_tangent;
@@ -171,8 +172,8 @@ void main()
mediump vec4 scaled_bone_indexes = bone_indexes; mediump vec4 scaled_bone_indexes = bone_indexes;
mediump vec4 scaled_bone_weights = bone_weights; mediump vec4 scaled_bone_weights = bone_weights;
//scaled_bone_indexes = 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); //scaled_bone_weights = vec4(1.0, 0.0, 0.0, 0.0);
highp mat4 skin_matrix = highp mat4 skin_matrix =
bone_transforms[ int(scaled_bone_indexes.x) ] * scaled_bone_weights.x + bone_transforms[ int(scaled_bone_indexes.x) ] * scaled_bone_weights.x +

View File

@@ -28,11 +28,11 @@
varying mediump vec2 textureCoordinate; varying mediump vec2 textureCoordinate;
attribute vec4 vertex_position; 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 uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices
void main() void main()
{ {
gl_Position = /*mvp_matrix * */vertex_position; gl_Position = /*mvp_matrix * */vertex_position;
textureCoordinate = vertex_uv.xy; textureCoordinate = vertex_uv;
} }

View File

@@ -28,11 +28,11 @@
varying mediump vec2 textureCoordinate; varying mediump vec2 textureCoordinate;
attribute vec4 vertex_position; 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 uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices
void main() void main()
{ {
gl_Position = /*mvp_matrix * */vertex_position; gl_Position = /*mvp_matrix * */vertex_position;
textureCoordinate = vertex_uv.xy; textureCoordinate = vertex_uv;
} }