- 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 */; };
E450273B16E0491D00FDEC5C /* KRReverbZone.h in Headers */ = {isa = PBXBuildFile; fileRef = E450273816E0491D00FDEC5C /* KRReverbZone.h */; settings = {ATTRIBUTES = (Public, ); }; };
E450273C16E0491D00FDEC5C /* KRReverbZone.h in Headers */ = {isa = PBXBuildFile; fileRef = E450273816E0491D00FDEC5C /* KRReverbZone.h */; settings = {ATTRIBUTES = (Public, ); }; };
E45134B61746A4A300443C21 /* KRBehavior.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45134B41746A4A300443C21 /* KRBehavior.cpp */; };
E45134B71746A4A300443C21 /* KRBehavior.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45134B41746A4A300443C21 /* KRBehavior.cpp */; };
E45134B81746A4A300443C21 /* KRBehavior.h in Headers */ = {isa = PBXBuildFile; fileRef = E45134B51746A4A300443C21 /* KRBehavior.h */; };
E45134B91746A4A300443C21 /* KRBehavior.h in Headers */ = {isa = PBXBuildFile; fileRef = E45134B51746A4A300443C21 /* KRBehavior.h */; settings = {ATTRIBUTES = (Public, ); }; };
E459040416C30CC5002B00A0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E459040316C30CC5002B00A0 /* AudioUnit.framework */; };
E459040616C30CD9002B00A0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E459040516C30CD9002B00A0 /* AudioUnit.framework */; };
E460292616681CFF00261BB9 /* KRTextureAnimated.h in Headers */ = {isa = PBXBuildFile; fileRef = E460292516681CFE00261BB9 /* KRTextureAnimated.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -151,7 +155,7 @@
E48CF942173453990005EBBB /* KRFloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48CF940173453990005EBBB /* KRFloat.cpp */; };
E48CF943173453990005EBBB /* KRFloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48CF940173453990005EBBB /* KRFloat.cpp */; };
E48CF944173453990005EBBB /* KRFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = E48CF941173453990005EBBB /* KRFloat.h */; };
E48CF945173453990005EBBB /* KRFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = E48CF941173453990005EBBB /* KRFloat.h */; };
E48CF945173453990005EBBB /* KRFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = E48CF941173453990005EBBB /* KRFloat.h */; settings = {ATTRIBUTES = (Public, ); }; };
E491018713C99BDC0098455B /* KREngine.mm in Sources */ = {isa = PBXBuildFile; fileRef = E491016F13C99BDC0098455B /* KREngine.mm */; };
E491018A13C99BDC0098455B /* KREngine.h in Headers */ = {isa = PBXBuildFile; fileRef = E491017213C99BDC0098455B /* KREngine.h */; settings = {ATTRIBUTES = (Public, ); }; };
E491018E13C99BDC0098455B /* KRMat4.h in Headers */ = {isa = PBXBuildFile; fileRef = E491017613C99BDC0098455B /* KRMat4.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -419,6 +423,8 @@
E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = "<group>"; };
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; };
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; };
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>"; };
@@ -1020,6 +1026,8 @@
E4C454BA167BD248003586CD /* KRHitInfo.cpp */,
E44F38231683B22C00399B5D /* KRRenderSettings.h */,
E44F38271683B24400399B5D /* KRRenderSettings.cpp */,
E45134B41746A4A300443C21 /* KRBehavior.cpp */,
E45134B51746A4A300443C21 /* KRBehavior.h */,
);
path = kraken;
sourceTree = "<group>";
@@ -1238,6 +1246,7 @@
E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */,
E4EC73C31720B1FF0065299F /* KRVector4.h in Headers */,
E48CF944173453990005EBBB /* KRFloat.h in Headers */,
E45134B81746A4A300443C21 /* KRBehavior.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1313,9 +1322,10 @@
E499BF1D16AE74FF007FCDBE /* KRTextureAnimated.h in Headers */,
E4EC73C41720B1FF0065299F /* KRVector4.h in Headers */,
E4AE63601704FB0A00B460CD /* KRLODGroup.h in Headers */,
E45134B91746A4A300443C21 /* KRBehavior.h in Headers */,
E48CF945173453990005EBBB /* KRFloat.h in Headers */,
E499BF1F16AE753E007FCDBE /* KRCollider.h in Headers */,
E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */,
E48CF945173453990005EBBB /* KRFloat.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1580,6 +1590,7 @@
E4AE635D1704FB0A00B460CD /* KRLODGroup.cpp in Sources */,
E4EC73C11720B1FF0065299F /* KRVector4.cpp in Sources */,
E48CF942173453990005EBBB /* KRFloat.cpp in Sources */,
E45134B61746A4A300443C21 /* KRBehavior.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1655,6 +1666,7 @@
E4AE635E1704FB0A00B460CD /* KRLODGroup.cpp in Sources */,
E4EC73C21720B1FF0065299F /* KRVector4.cpp in Sources */,
E48CF943173453990005EBBB /* KRFloat.cpp in Sources */,
E45134B71746A4A300443C21 /* KRBehavior.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -39,9 +39,9 @@
KRAnimation::KRAnimation(KRContext &context, std::string name) : KRResource(context, name)
{
m_auto_play = true;
m_loop = true;
m_playing = true;
m_auto_play = false;
m_loop = false;
m_playing = false;
m_local_time = 0.0f;
m_duration = 0.0f;
}
@@ -94,11 +94,11 @@ KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, KRDa
}
if(animation_node->QueryBoolAttribute("loop", &new_animation->m_loop) != tinyxml2::XML_SUCCESS) {
new_animation->m_loop = true; // Default value
new_animation->m_loop = false; // Default value
}
if(animation_node->QueryBoolAttribute("auto_play", &new_animation->m_auto_play) != tinyxml2::XML_SUCCESS) {
new_animation->m_auto_play = true; // Default value
new_animation->m_auto_play = false; // Default value
}
for(tinyxml2::XMLElement *child_element=animation_node->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) {
@@ -135,9 +135,15 @@ void KRAnimation::update(float deltaTime)
if(m_playing) {
m_local_time += deltaTime;
}
if(m_loop) {
while(m_local_time > m_duration) {
m_local_time -= m_duration;
}
} else if(m_local_time > m_duration) {
m_local_time = m_duration;
m_playing = false;
getContext().getAnimationManager()->updateActiveAnimations(this);
}
for(unordered_map<std::string, KRAnimationLayer *>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer *layer = (*layer_itr).second;
@@ -151,7 +157,14 @@ void KRAnimation::update(float deltaTime)
KRNode::node_attribute_type attribute_type = attribute->getTargetAttribute();
if(curve != NULL && target != NULL) {
target->SetAttribute(attribute_type, curve->getValue(m_local_time));
int frame_number = (int)(m_local_time * curve->getFrameRate());
if(frame_number < curve->getFrameStart()) {
target->SetAttribute(attribute_type, curve->getValue(0));
} else if(frame_number - curve->getFrameStart() >= curve->getFrameCount()) {
target->SetAttribute(attribute_type, curve->getValue(curve->getFrameCount() - 1));
} else {
target->SetAttribute(attribute_type, curve->getValue(frame_number - curve->getFrameStart()));
}
}
}
@@ -194,3 +207,23 @@ bool KRAnimation::isPlaying()
{
return m_playing;
}
bool KRAnimation::getAutoPlay() const
{
return m_auto_play;
}
void KRAnimation::setAutoPlay(bool auto_play)
{
m_auto_play = auto_play;
}
bool KRAnimation::getLooping() const
{
return m_loop;
}
void KRAnimation::setLooping(bool looping)
{
m_loop = looping;
}

View File

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

View File

@@ -86,6 +86,60 @@ tinyxml2::XMLElement *KRAnimationAttribute::saveXML( tinyxml2::XMLNode *parent)
case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Z:
szAttribute = "rotate_z";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X:
szAttribute = "pre_rotate_x";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y:
szAttribute = "pre_rotate_y";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z:
szAttribute = "pre_rotate_z";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X:
szAttribute = "post_rotate_x";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y:
szAttribute = "post_rotate_y";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z:
szAttribute = "post_rotate_z";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X:
szAttribute = "rotate_pivot_x";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y:
szAttribute = "rotate_pivot_y";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z:
szAttribute = "rotate_pivot_z";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X:
szAttribute = "scale_pivot_x";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y:
szAttribute = "scale_pivot_y";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z:
szAttribute = "scale_pivot_z";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X:
szAttribute = "rotate_offset_x";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y:
szAttribute = "rotate_offset_y";
break;
case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z:
szAttribute = "rotate_offset_z";
break;
case KRNode::KRENGINE_NODE_SCALE_OFFSET_X:
szAttribute = "scale_offset_x";
break;
case KRNode::KRENGINE_NODE_SCALE_OFFSET_Y:
szAttribute = "scale_offset_y";
break;
case KRNode::KRENGINE_NODE_SCALE_OFFSET_Z:
szAttribute = "scale_offset_z";
break;
}
e->SetAttribute("attribute", szAttribute);
@@ -121,6 +175,42 @@ void KRAnimationAttribute::loadXML(tinyxml2::XMLElement *e)
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Y;
} else if(strcmp(szAttribute, "scale_z") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z;
} else if(strcmp(szAttribute, "pre_rotate_x") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X;
} else if(strcmp(szAttribute, "pre_rotate_y") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y;
} else if(strcmp(szAttribute, "pre_rotate_z") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z;
} else if(strcmp(szAttribute, "post_rotate_x") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X;
} else if(strcmp(szAttribute, "post_rotate_y") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y;
} else if(strcmp(szAttribute, "post_rotate_z") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z;
} else if(strcmp(szAttribute, "rotate_pivot_x") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X;
} else if(strcmp(szAttribute, "rotate_pivot_y") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y;
} else if(strcmp(szAttribute, "rotate_pivot_z") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z;
} else if(strcmp(szAttribute, "scale_pivot_x") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X;
} else if(strcmp(szAttribute, "scale_pivot_y") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y;
} else if(strcmp(szAttribute, "scale_pivot_z") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z;
} else if(strcmp(szAttribute, "rotate_offset_x") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X;
} else if(strcmp(szAttribute, "rotate_offset_y") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y;
} else if(strcmp(szAttribute, "rotate_offset_z") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z;
} else if(strcmp(szAttribute, "scale_offset_x") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_SCALE_OFFSET_X;
} else if(strcmp(szAttribute, "scale_offset_y") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_SCALE_OFFSET_Y;
} else if(strcmp(szAttribute, "scale_offset_z") == 0) {
m_node_attribute = KRNode::KRENGINE_NODE_SCALE_OFFSET_Z;
} else {
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE;
}
@@ -163,6 +253,9 @@ KRNode *KRAnimationAttribute::getTarget()
if(m_target == NULL) {
m_target = getContext().getSceneManager()->getFirstScene()->getRootNode()->find<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;
}

View File

@@ -32,7 +32,7 @@
#include "KRAnimationCurve.h"
#include "KRDataBlock.h"
KRAnimationCurve::KRAnimationCurve(KRContext &context, std::string name) : KRResource(context, name)
KRAnimationCurve::KRAnimationCurve(KRContext &context, const std::string &name) : KRResource(context, name)
{
m_pData = new KRDataBlock();
m_pData->expand(sizeof(animation_curve_header));
@@ -129,7 +129,7 @@ float KRAnimationCurve::getValue(int frame_number)
//printf("frame_number: %i\n", frame_number);
int clamped_frame = frame_number;
if(frame_number < 0) {
clamped_frame = frame_number;
clamped_frame = 0;
} else if(frame_number >= getFrameCount()) {
clamped_frame = getFrameCount()-1;
}

View File

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

View File

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

View File

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

View File

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

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 setBindPose(const KRMat4 &pose);
const KRMat4 &getBindPose();
private:
KRMat4 m_bind_pose;
};

View File

@@ -65,6 +65,23 @@ KRCamera::~KRCamera() {
destroyBuffers();
}
std::string KRCamera::getElementName() {
return "camera";
}
tinyxml2::XMLElement *KRCamera::saveXML( tinyxml2::XMLNode *parent)
{
tinyxml2::XMLElement *e = KRNode::saveXML(parent);
return e;
}
void KRCamera::loadXML(tinyxml2::XMLElement *e)
{
KRNode::loadXML(e);
}
void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint renderBufferHeight)
{
// ----====---- Record timing information for measuring FPS ----====----
@@ -82,9 +99,10 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
KRScene &scene = getScene();
KRMat4 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));
KRMat4 projectionMatrix;

View File

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

View File

@@ -12,6 +12,7 @@
#include "KRShader.h"
#include "KRContext.h"
#include "KRMat4.h"
#include "KRQuaternion.h"
#include "assert.h"
#include "KRStockGeometry.h"
@@ -30,20 +31,11 @@ std::string KRDirectionalLight::getElementName() {
}
KRVector3 KRDirectionalLight::getWorldLightDirection() {
KRVector3 world_rotation = getWorldRotation();
KRVector3 light_rotation = KRVector3(0.0, 0.0, 1.0);
KRMat4 m;
m.rotate(world_rotation.x, X_AXIS);
m.rotate(world_rotation.y, Y_AXIS);
m.rotate(world_rotation.z, Z_AXIS);
KRVector3 light_direction = KRMat4::Dot(m, light_rotation);
return light_direction;
return KRMat4::Dot(getWorldRotation().rotationMatrix(), getLocalLightDirection());
}
KRVector3 KRDirectionalLight::getLocalLightDirection() {
return KRVector3(0.0, 0.0, 1.0);
return KRVector3::Forward();
}

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 "KRVector3.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
{
KRCamera *camera = pScene->find<KRCamera>();
KRCamera *camera = pScene->find<KRCamera>("default_camera");
if(camera) {
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_occlusionQuery) {
/*
GLuint hasBeenTested = 0;
while(!hasBeenTested) {
GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_AVAILABLE_EXT, &hasBeenTested)); // FINDME, HACK!! This needs to be replaced with asynchonous logic
}
*/
GLuint params = 0;
GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_EXT, &params));
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 */
void KRMat4::rotate(float angle, AXIS axis) {
const int cos1[3] = { 5, 0, 0 };
const int cos2[3] = { 10, 10, 5 };
const int sin1[3] = { 6, 2, 1 };
const int sin2[3] = { 9, 8, 4 };
const int cos1[3] = { 5, 0, 0 }; // cos(angle)
const int cos2[3] = { 10, 10, 5 }; // cos(angle)
const int sin1[3] = { 9, 2, 4 }; // -sin(angle)
const int sin2[3] = { 6, 8, 1 }; // sin(angle)
/*
X_AXIS:
1, 0, 0, 0
0, cos(angle), -sin(angle), 0
0, sin(angle), cos(angle), 0
0, 0, 0, 1
Y_AXIS:
cos(angle), 0, -sin(angle), 0
0, 1, 0, 0
sin(angle), 0, cos(angle), 0
0, 0, 0, 1
Z_AXIS:
cos(angle), -sin(angle), 0, 0
sin(angle), cos(angle), 0, 0
0, 0, 1, 0
0, 0, 0, 1
*/
KRMat4 newMatrix; // Create new identity matrix
@@ -398,3 +422,30 @@ void KRMat4::setUniform(GLint location) const
{
if(location != -1) GLDEBUG(glUniformMatrix4fv(location, 1, GL_FALSE, c));
}
KRMat4 KRMat4::Translation(const KRVector3 &v)
{
KRMat4 m;
m[12] = v.x;
m[13] = v.y;
m[14] = v.z;
// m.translate(v);
return m;
}
KRMat4 KRMat4::Rotation(const KRVector3 &v)
{
KRMat4 m;
m.rotate(v.x, X_AXIS);
m.rotate(v.y, Y_AXIS);
m.rotate(v.z, Z_AXIS);
return m;
}
KRMat4 KRMat4::Scaling(const KRVector3 &v)
{
KRMat4 m;
m.scale(v);
return m;
}

View File

@@ -120,6 +120,10 @@ class KRMat4 {
static KRMat4 LookAt(const KRVector3 &cameraPos, const KRVector3 &lookAtPos, const KRVector3 &upDirection);
static KRMat4 Translation(const KRVector3 &v);
static KRMat4 Rotation(const KRVector3 &v);
static KRMat4 Scaling(const KRVector3 &v);
void setUniform(GLint location) const;
};

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;
}
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 bSameMaterial = *prevBoundMaterial == this;
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 bLightMap = pLightMap && pCamera->settings.bEnableLightMap;
if(!m_pAmbientMap && m_ambientMap.size()) {
@@ -240,15 +239,10 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str());
}
if(bones.size() > 0) {
bSameMaterial = false; // FINDME, HACK! - This is test code
}
KRVector2 default_scale = KRVector2::One();
KRVector2 default_offset = KRVector2::Zero();
if(!bSameMaterial) {
KRVector2 default_scale = KRVector2(1.0f, 1.0f);
KRVector2 default_offset = KRVector2(0.0f, 0.0f);
bool bHasReflection = m_reflectionColor != KRVector3(0.0f, 0.0f, 0.0f);
bool 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;
@@ -260,15 +254,10 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
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];
@@ -287,9 +276,12 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
//printf("%s - delta translation: %.4f %.4f %.4f\n", bone->getName().c_str(), translation.x - initialTranslation.x, translation.y - initialTranslation.y, translation.z - initialTranslation.z);
// printf("%s - delta scale: %.4f %.4f %.4f\n", bone->getName().c_str(), scale.x - initialScale.x, scale.y - initialScale.y, scale.z - initialScale.z);
KRMat4 model_mat = bone->getActivePoseMatrix();
KRMat4 skin_bone_bind_pose = bind_poses[bone_index];
KRMat4 active_mat = bone->getActivePoseMatrix();
KRMat4 inv_bind_mat = bone->getInverseBindPoseMatrix();
KRMat4 t = /*KRMat4::Invert(matModel) * */(inv_bind_mat * model_mat);
KRMat4 inv_bind_mat2 = KRMat4::Invert(bind_poses[bone_index]);
KRMat4 t = (inv_bind_mat * active_mat);
KRMat4 t2 = inv_bind_mat2 * bone->getModelMatrix();
for(int i=0; i < 16; i++) {
*bone_mat_component++ = t[i];
}
@@ -299,101 +291,33 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
}
}
bool bSameAmbient = false;
bool bSameDiffuse = false;
bool bSameSpecular = false;
bool bSameReflection = false;
bool bSameAmbientScale = false;
bool bSameDiffuseScale = false;
bool bSameSpecularScale = false;
bool bSameReflectionScale = false;
bool bSameNormalScale = false;
bool bSameAmbientOffset = false;
bool bSameDiffuseOffset = false;
bool bSameSpecularOffset = false;
bool bSameReflectionOffset = false;
bool bSameNormalOffset = false;
bool bSameShininess = false;
if(*prevBoundMaterial && bSameShader) {
bSameAmbient = (*prevBoundMaterial)->m_ambientColor == m_ambientColor;
bSameDiffuse = (*prevBoundMaterial)->m_diffuseColor == m_diffuseColor;
bSameSpecular = (*prevBoundMaterial)->m_specularColor == m_specularColor;
bSameShininess = (*prevBoundMaterial)->m_ns == m_ns;
bSameReflection = (*prevBoundMaterial)->m_reflectionColor == m_reflectionColor;
bSameAmbientScale = (*prevBoundMaterial)->m_ambientMapScale == m_ambientMapScale;
bSameDiffuseScale = (*prevBoundMaterial)->m_diffuseMapScale == m_diffuseMapScale;
bSameSpecularScale = (*prevBoundMaterial)->m_specularMapScale == m_specularMapScale;
bSameReflectionScale = (*prevBoundMaterial)->m_reflectionMapScale == m_reflectionMapScale;
bSameNormalScale = (*prevBoundMaterial)->m_normalMapScale == m_normalMapScale;
bSameAmbientOffset = (*prevBoundMaterial)->m_ambientMapOffset == m_ambientMapOffset;
bSameDiffuseOffset = (*prevBoundMaterial)->m_diffuseMapOffset == m_diffuseMapOffset;
bSameSpecularOffset = (*prevBoundMaterial)->m_specularMapOffset == m_specularMapOffset;
bSameReflectionOffset = (*prevBoundMaterial)->m_reflectionMapOffset == m_reflectionMapOffset;
bSameNormalOffset = (*prevBoundMaterial)->m_normalMapOffset == m_normalMapOffset;
}
if(!bSameAmbient) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_AMBIENT, m_ambientColor + pCamera->settings.ambient_intensity);
}
if(!bSameDiffuse) {
if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) {
// We pre-multiply the light color with the material color in the forward renderer
pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE, KRVector3(m_diffuseColor.x * pCamera->settings.light_intensity.x, m_diffuseColor.y * pCamera->settings.light_intensity.y, m_diffuseColor.z * pCamera->settings.light_intensity.z));
} else {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE, m_diffuseColor);
}
}
if(!bSameSpecular) {
if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) {
// We pre-multiply the light color with the material color in the forward renderer
pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR, KRVector3(m_specularColor.x * pCamera->settings.light_intensity.x, m_specularColor.y * pCamera->settings.light_intensity.y, m_specularColor.z * pCamera->settings.light_intensity.z));
} else {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR, m_specularColor);
}
}
if(!bSameShininess) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SHININESS, m_ns);
}
if(!bSameReflection) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_REFLECTION, m_reflectionColor);
}
if(bDiffuseMap && !bSameDiffuseScale && m_diffuseMapScale != default_scale) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_DIFFUSETEXTURE_SCALE, m_diffuseMapScale);
}
if(bSpecMap && !bSameSpecularScale && m_specularMapScale != default_scale) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_SPECULARTEXTURE_SCALE, m_specularMapScale);
}
if(bReflectionMap && !bSameReflectionScale && m_reflectionMapScale != default_scale) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_REFLECTIONTEXTURE_SCALE, m_reflectionMapScale);
}
if(bNormalMap && !bSameNormalScale && m_normalMapScale != default_scale) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_NORMALTEXTURE_SCALE, m_normalMapScale);
}
if(bDiffuseMap && !bSameDiffuseOffset && m_diffuseMapOffset != default_offset) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_DIFFUSETEXTURE_OFFSET, m_diffuseMapOffset);
}
if(bSpecMap && !bSameSpecularOffset && m_specularMapOffset != default_offset) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_SPECULARTEXTURE_OFFSET, m_specularMapOffset);
}
if(bReflectionMap && !bSameReflectionOffset && m_reflectionMapOffset != default_offset) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_REFLECTIONTEXTURE_OFFSET, m_reflectionMapOffset);
}
if(bNormalMap && !bSameNormalOffset && m_normalMapOffset != default_offset) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_NORMALTEXTURE_OFFSET, m_normalMapOffset);
}
pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_tr);
@@ -418,8 +342,6 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap);
}
*prevBoundMaterial = this;
} // if(!bSameMaterial)
return true;
}

View File

@@ -83,7 +83,7 @@ public:
bool isTransparent();
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();

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();
if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) {
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->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()) {
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();
@@ -359,27 +360,15 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
bool use_short_uvb = true;
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) {
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) {
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) {
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) {
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) {
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;
if(vertices.size()) {
if(mi.vertices.size()) {
if(use_short_vertexes) {
vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX_SHORT);
} else {
vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX);
}
}
if(normals.size() || calculate_normals) {
if(mi.normals.size() || calculate_normals) {
if(use_short_normals) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL_SHORT);
} else {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL);
}
}
if(tangents.size() || calculate_tangents) {
if(mi.tangents.size() || calculate_tangents) {
if(use_short_tangents) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT_SHORT);
} else {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT);
}
}
if(uva.size()) {
if(mi.uva.size()) {
if(use_short_uva) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA_SHORT);
} else {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA);
}
}
if(uvb.size()) {
if(mi.uvb.size()) {
if(use_short_uvb) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB_SHORT);
} else {
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);
}
size_t vertex_size = VertexSizeForAttributes(vertex_attrib_flags);
size_t index_count = vertex_indexes.size();
size_t index_base_count = vertex_index_bases.size();
size_t submesh_count = submesh_lengths.size();
size_t vertex_count = vertices.size();
size_t bone_count = bone_names.size();
size_t index_count = mi.vertex_indexes.size();
size_t index_base_count = mi.vertex_index_bases.size();
size_t submesh_count = mi.submesh_lengths.size();
size_t vertex_count = mi.vertices.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;
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->index_count = (__int32_t)index_count;
pHeader->index_base_count = (__int32_t)index_base_count;
pHeader->model_format = model_format;
pHeader->model_format = mi.format;
strcpy(pHeader->szTag, "KROBJPACK1.2 ");
updateAttributeOffsets();
@@ -459,28 +448,29 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
for(int iMaterial=0; iMaterial < pHeader->submesh_count; iMaterial++) {
pack_material *pPackMaterial = pPackMaterials + iMaterial;
pPackMaterial->start_vertex = submesh_starts[iMaterial];
pPackMaterial->vertex_count = submesh_lengths[iMaterial];
pPackMaterial->start_vertex = mi.submesh_starts[iMaterial];
pPackMaterial->vertex_count = mi.submesh_lengths[iMaterial];
memset(pPackMaterial->szName, 0, KRENGINE_MAX_NAME_LENGTH);
strncpy(pPackMaterial->szName, material_names[iMaterial].c_str(), KRENGINE_MAX_NAME_LENGTH);
strncpy(pPackMaterial->szName, mi.material_names[iMaterial].c_str(), KRENGINE_MAX_NAME_LENGTH);
}
for(int bone_index=0; bone_index < bone_count; bone_index++) {
pack_bone *bone = getBone(bone_index);
memset(bone->szName, 0, KRENGINE_MAX_NAME_LENGTH);
strncpy(bone->szName, bone_names[bone_index].c_str(), KRENGINE_MAX_NAME_LENGTH);
strncpy(bone->szName, mi.bone_names[bone_index].c_str(), KRENGINE_MAX_NAME_LENGTH);
memcpy(bone->bind_pose, mi.bone_bind_poses[bone_index].c, sizeof(float) * 16);
}
bool bFirstVertex = true;
memset(getVertexData(), 0, m_vertex_size * vertices.size());
for(int iVertex=0; iVertex < vertices.size(); iVertex++) {
KRVector3 source_vertex = vertices[iVertex];
memset(getVertexData(), 0, m_vertex_size * mi.vertices.size());
for(int iVertex=0; iVertex < mi.vertices.size(); iVertex++) {
KRVector3 source_vertex = mi.vertices[iVertex];
setVertexPosition(iVertex, source_vertex);
if(bone_names.size()) {
if(mi.bone_names.size()) {
for(int bone_weight_index=0; bone_weight_index<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; bone_weight_index++) {
setBoneIndex(iVertex, bone_weight_index, bone_indexes[iVertex][bone_weight_index]);
setBoneWeight(iVertex, bone_weight_index, bone_weights[iVertex][bone_weight_index]);
setBoneIndex(iVertex, bone_weight_index, mi.bone_indexes[iVertex][bone_weight_index]);
setBoneWeight(iVertex, bone_weight_index, mi.bone_weights[iVertex][bone_weight_index]);
}
}
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.z > m_maxPoint.z) m_maxPoint.z = source_vertex.z;
}
if(uva.size() > iVertex) {
setVertexUVA(iVertex, uva[iVertex]);
if(mi.uva.size() > iVertex) {
setVertexUVA(iVertex, mi.uva[iVertex]);
}
if(uvb.size() > iVertex) {
setVertexUVB(iVertex, uvb[iVertex]);
if(mi.uvb.size() > iVertex) {
setVertexUVB(iVertex, mi.uvb[iVertex]);
}
if(normals.size() > iVertex) {
setVertexNormal(iVertex, normals[iVertex]);
if(mi.normals.size() > iVertex) {
setVertexNormal(iVertex, KRVector3::Normalize(mi.normals[iVertex]));
}
if(tangents.size() > iVertex) {
setVertexTangent(iVertex, tangents[iVertex]);
if(mi.tangents.size() > iVertex) {
setVertexTangent(iVertex, KRVector3::Normalize(mi.tangents[iVertex]));
}
}
@@ -518,12 +508,12 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
__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;
}
__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).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";
if(calculate_normals || calculate_tangents) {
// 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 p2 = getVertexPosition(iVertex+1);
KRVector3 p3 = getVertexPosition(iVertex+2);
@@ -911,6 +901,11 @@ char *KRMesh::getBoneName(int bone_index)
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
{
return (model_format_t)getHeader()->model_format;
@@ -1064,30 +1059,19 @@ void KRMesh::convertToIndexed()
char *szKey = new char[m_vertex_size * 2 + 1];
// Convert model to indexed vertices, identying vertexes with identical attributes and optimizing order of trianges for best usage post-vertex-transform cache on GPU
std::vector<__uint16_t> vertex_indexes;
std::vector<std::pair<int, int> > vertex_index_bases;
int vertex_index_offset = 0;
int vertex_index_base_start_vertex = 0;
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;
mesh_info mi;
int bone_count = getBoneCount();
for(int bone_index=0; bone_index < bone_count; bone_index++) {
bone_names.push_back(getBoneName(bone_index));
mi.bone_names.push_back(getBoneName(bone_index));
mi.bone_bind_poses.push_back(getBoneBindPose(bone_index));
}
for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) {
material_names.push_back(getSubmesh(submesh_index)->szName);
mi.material_names.push_back(getSubmesh(submesh_index)->szName);
int vertexes_remaining = getVertexCount(submesh_index);
@@ -1097,13 +1081,13 @@ void KRMesh::convertToIndexed()
}
if(submesh_index == 0 || vertex_index_offset + vertex_count > 0xffff) {
vertex_index_bases.push_back(std::pair<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_base_start_vertex = vertices.size();
vertex_index_base_start_vertex = mi.vertices.size();
}
submesh_starts.push_back(vertex_index_bases.size() - 1 + (vertex_index_offset << 16));
submesh_lengths.push_back(vertexes_remaining);
mi.submesh_starts.push_back(mi.vertex_index_bases.size() - 1 + (vertex_index_offset << 16));
mi.submesh_lengths.push_back(vertexes_remaining);
int source_index = getSubmesh(submesh_index)->start_vertex;
@@ -1189,35 +1173,35 @@ void KRMesh::convertToIndexed()
*/
int found_index = -1;
if(prev_indexes.count(vertex_key) == 0) {
found_index = vertices.size() - vertex_index_base_start_vertex;
found_index = mi.vertices.size() - vertex_index_base_start_vertex;
if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX) || has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) {
vertices.push_back(vertex_position);
mi.vertices.push_back(vertex_position);
}
if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL) || has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) {
normals.push_back(vertex_normal);
mi.normals.push_back(vertex_normal);
}
if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT) || has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) {
tangents.push_back(vertex_tangent);
mi.tangents.push_back(vertex_tangent);
}
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) {
uva.push_back(vertex_uva);
mi.uva.push_back(vertex_uva);
}
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) {
uvb.push_back(vertex_uvb);
mi.uvb.push_back(vertex_uvb);
}
if(has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) {
bone_indexes.push_back(vertex_bone_indexes);
mi.bone_indexes.push_back(vertex_bone_indexes);
}
if(has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS)) {
bone_weights.push_back(vertex_bone_weights);
mi.bone_weights.push_back(vertex_bone_weights);
}
prev_indexes[vertex_key] = found_index;
} else {
found_index = prev_indexes[vertex_key];
}
vertex_indexes.push_back(found_index);
mi.vertex_indexes.push_back(found_index);
//fprintf(stderr, "Submesh: %6i IndexBase: %3i Index: %6i\n", submesh_index, vertex_index_bases.size(), found_index);
source_index++;
@@ -1233,20 +1217,20 @@ void KRMesh::convertToIndexed()
}
if(vertex_index_offset + vertex_count > 0xffff) {
vertex_index_bases.push_back(std::pair<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_base_start_vertex = vertices.size();
vertex_index_base_start_vertex = mi.vertices.size();
}
}
}
delete szKey;
fprintf(stderr, "Convert to indexed, before: %i after: %i \(%.2f%% saving)\n", getHeader()->vertex_count, vertices.size(), ((float)getHeader()->vertex_count - (float)vertices.size()) / (float)getHeader()->vertex_count * 100.0f);
fprintf(stderr, "Convert to indexed, before: %i after: %i \(%.2f%% saving)\n", getHeader()->vertex_count, mi.vertices.size(), ((float)getHeader()->vertex_count - (float)mi.vertices.size()) / (float)getHeader()->vertex_count * 100.0f);
LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights, KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES, false, false);
mi.format = KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES;
LoadData(mi, false, false);
}
void KRMesh::optimize()

View File

@@ -31,6 +31,7 @@
#include "KREngine-common.h"
#include "KRVector2.h"
#include "KRMat4.h"
#include "KRContext.h"
#include "KRBone.h"
@@ -58,6 +59,9 @@ class KRNode;
class KRMesh : public KRResource {
public:
KRMesh(KRContext &context, std::string name, KRDataBlock *data);
KRMesh(KRContext &context, std::string name);
virtual ~KRMesh();
@@ -87,6 +91,23 @@ public:
KRENGINE_MODEL_FORMAT_INDEXED_STRIP
} model_format_t;
typedef struct {
model_format_t format;
std::vector<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);
@@ -96,7 +117,7 @@ public:
virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data);
void LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<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 convertToIndexed();
@@ -132,6 +153,7 @@ public:
typedef struct {
char szName[KRENGINE_MAX_NAME_LENGTH];
float bind_pose[16];
} pack_bone;
int getLODCoverage() const;
@@ -166,6 +188,7 @@ public:
int getBoneCount();
char *getBoneName(int bone_index);
KRMat4 getBoneBindPose(int bone_index);
model_format_t getModelFormat() const;

View File

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

View File

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

View File

@@ -34,6 +34,22 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont
m_initialLocalScale = m_localScale;
m_initialLocalRotation = m_localRotation;
m_rotationOffset = KRVector3::Zero();
m_scalingOffset = KRVector3::Zero();
m_rotationPivot = KRVector3::Zero();
m_scalingPivot = KRVector3::Zero();
m_preRotation = KRVector3::Zero();
m_postRotation = KRVector3::Zero();
m_initialRotationOffset = KRVector3::Zero();
m_initialScalingOffset = KRVector3::Zero();
m_initialRotationPivot = KRVector3::Zero();
m_initialScalingPivot = KRVector3::Zero();
m_initialPreRotation = KRVector3::Zero();
m_initialPostRotation = KRVector3::Zero();
m_parentNode = NULL;
m_pScene = &scene;
m_modelMatrixValid = false;
@@ -46,16 +62,29 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont
m_activePoseMatrix = KRMat4();
m_lod_visible = false;
m_scale_compensation = false;
m_lastRenderFrame = -1000;
for(int i=0; i < KRENGINE_NODE_ATTRIBUTE_COUNT; i++) {
m_animation_mask[i] = false;
}
}
KRNode::~KRNode() {
while(m_childNodes.size() > 0) {
delete *m_childNodes.begin();
}
for(std::set<KRBehavior *>::iterator itr = m_behaviors.begin(); itr != m_behaviors.end(); itr++) {
delete *itr;
}
m_behaviors.clear();
if(m_parentNode) {
m_parentNode->childDeleted(this);
}
getScene().notify_sceneGraphDelete(this);
}
@@ -181,9 +210,13 @@ void KRNode::setWorldTranslation(const KRVector3 &v)
void KRNode::setWorldRotation(const KRVector3 &v)
{
if(m_parentNode) {
setLocalRotation(KRMat4::DotNoTranslate(m_parentNode->getInverseModelMatrix(), v));
setLocalRotation((KRQuaternion(v) * -m_parentNode->getWorldRotation()).eulerXYZ());
setPreRotation(KRVector3::Zero());
setPostRotation(KRVector3::Zero());
} else {
setLocalRotation(v);
setPreRotation(KRVector3::Zero());
setPostRotation(KRVector3::Zero());
}
}
@@ -349,32 +382,6 @@ const KRVector3 KRNode::getWorldTranslation() {
const KRVector3 KRNode::getWorldScale() {
return KRMat4::DotNoTranslate(getModelMatrix(), m_localScale);
}
const KRVector3 KRNode::getWorldRotation() {
KRVector3 world_rotation = (-KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation)).eulerXYZ();;
if(m_parentNode) {
KRVector3 parent_rotation = m_parentNode->getWorldRotation();
world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ();
}
return world_rotation;
}
const KRVector3 KRNode::getBindPoseWorldRotation() {
KRVector3 world_rotation = (-KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation)).eulerXYZ();
if(dynamic_cast<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() {
return "node";
@@ -420,6 +427,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
new_node = new KRAmbientZone(scene, szName);
} else if(strcmp(szElementName, "reverb_zone") == 0) {
new_node = new KRReverbZone(scene, szName);
} else if(strcmp(szElementName, "camera") == 0) {
new_node = new KRCamera(scene, szName);
}
if(new_node) {
@@ -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)
{
m_lastRenderFrame = getContext().getCurrentFrame();
}
const std::set<KRNode *> &KRNode::getChildren() {
@@ -500,23 +510,21 @@ const KRMat4 &KRNode::getModelMatrix()
}
if(getScaleCompensation() && parent_is_bone) {
m_modelMatrix.translate(-m_scalingPivot);
m_modelMatrix.scale(m_localScale);
m_modelMatrix.translate(m_scalingPivot);
m_modelMatrix.translate(m_scalingOffset);
m_modelMatrix.translate(-m_rotationPivot);
m_modelMatrix.rotate(-m_postRotation.z, Z_AXIS);
m_modelMatrix.rotate(-m_postRotation.y, Y_AXIS);
m_modelMatrix.rotate(-m_postRotation.x, X_AXIS);
m_modelMatrix.rotate(m_localRotation.x, X_AXIS);
m_modelMatrix.rotate(m_localRotation.y, Y_AXIS);
m_modelMatrix.rotate(m_localRotation.z, Z_AXIS);
m_modelMatrix.rotate(m_preRotation.x, X_AXIS);
m_modelMatrix.rotate(m_preRotation.y, Y_AXIS);
m_modelMatrix.rotate(m_preRotation.z, Z_AXIS);
m_modelMatrix.translate(m_rotationPivot);
m_modelMatrix.translate(m_rotationOffset);
//m_modelMatrix.translate(m_localTranslation);
// WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
m_modelMatrix = KRMat4::Translation(-m_scalingPivot)
* KRMat4::Scaling(m_localScale)
* KRMat4::Translation(m_scalingPivot)
* KRMat4::Translation(m_scalingOffset)
* KRMat4::Translation(-m_rotationPivot)
//* (KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation)).rotationMatrix()
* KRMat4::Rotation(m_postRotation)
* KRMat4::Rotation(m_localRotation)
* KRMat4::Rotation(m_preRotation)
* KRMat4::Translation(m_rotationPivot)
* KRMat4::Translation(m_rotationOffset);
if(m_parentNode) {
m_modelMatrix.rotate(m_parentNode->getWorldRotation());
@@ -527,24 +535,18 @@ const KRMat4 &KRNode::getModelMatrix()
} else {
// WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
m_modelMatrix.translate(-m_scalingPivot);
m_modelMatrix.scale(m_localScale);
m_modelMatrix.translate(m_scalingPivot);
m_modelMatrix.translate(m_scalingOffset);
m_modelMatrix.translate(-m_rotationPivot);
m_modelMatrix.rotate(-m_postRotation.z, Z_AXIS);
m_modelMatrix.rotate(-m_postRotation.y, Y_AXIS);
m_modelMatrix.rotate(-m_postRotation.x, X_AXIS);
m_modelMatrix.rotate(m_localRotation.x, X_AXIS);
m_modelMatrix.rotate(m_localRotation.y, Y_AXIS);
m_modelMatrix.rotate(m_localRotation.z, Z_AXIS);
m_modelMatrix.rotate(m_preRotation.x, X_AXIS);
m_modelMatrix.rotate(m_preRotation.y, Y_AXIS);
m_modelMatrix.rotate(m_preRotation.z, Z_AXIS);
m_modelMatrix.translate(m_rotationPivot);
m_modelMatrix.translate(m_rotationOffset);
m_modelMatrix.translate(m_localTranslation);
m_modelMatrix = KRMat4::Translation(-m_scalingPivot)
* KRMat4::Scaling(m_localScale)
* KRMat4::Translation(m_scalingPivot)
* KRMat4::Translation(m_scalingOffset)
* KRMat4::Translation(-m_rotationPivot)
//* (KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation)).rotationMatrix()
* KRMat4::Rotation(m_postRotation)
* KRMat4::Rotation(m_localRotation)
* KRMat4::Rotation(m_preRotation)
* KRMat4::Translation(m_rotationPivot)
* KRMat4::Translation(m_rotationOffset)
* KRMat4::Translation(m_localTranslation);
if(m_parentNode) {
m_modelMatrix *= m_parentNode->getModelMatrix();
@@ -568,22 +570,17 @@ const KRMat4 &KRNode::getBindPoseMatrix()
}
if(getScaleCompensation() && parent_is_bone) {
m_bindPoseMatrix.translate(-m_initialScalingPivot);
m_bindPoseMatrix.scale(m_initialLocalScale);
m_bindPoseMatrix.translate(m_initialScalingPivot);
m_bindPoseMatrix.translate(m_initialScalingOffset);
m_bindPoseMatrix.translate(-m_initialRotationPivot);
m_bindPoseMatrix.rotate(-m_initialPostRotation.z, Z_AXIS);
m_bindPoseMatrix.rotate(-m_initialPostRotation.y, Y_AXIS);
m_bindPoseMatrix.rotate(-m_initialPostRotation.x, X_AXIS);
m_bindPoseMatrix.rotate(m_initialLocalRotation.x, X_AXIS);
m_bindPoseMatrix.rotate(m_initialLocalRotation.y, Y_AXIS);
m_bindPoseMatrix.rotate(m_initialLocalRotation.z, Z_AXIS);
m_bindPoseMatrix.rotate(m_initialPreRotation.x, X_AXIS);
m_bindPoseMatrix.rotate(m_initialPreRotation.y, Y_AXIS);
m_bindPoseMatrix.rotate(m_initialPreRotation.z, Z_AXIS);
m_bindPoseMatrix.translate(m_initialRotationPivot);
m_bindPoseMatrix.translate(m_initialRotationOffset);
m_bindPoseMatrix = KRMat4::Translation(-m_initialScalingPivot)
* KRMat4::Scaling(m_initialLocalScale)
* KRMat4::Translation(m_initialScalingPivot)
* KRMat4::Translation(m_initialScalingOffset)
* KRMat4::Translation(-m_initialRotationPivot)
//* (KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation)).rotationMatrix()
* KRMat4::Rotation(m_initialPostRotation)
* KRMat4::Rotation(m_initialLocalRotation)
* KRMat4::Rotation(m_initialPreRotation)
* KRMat4::Translation(m_initialRotationPivot)
* KRMat4::Translation(m_initialRotationOffset);
//m_bindPoseMatrix.translate(m_localTranslation);
if(m_parentNode) {
@@ -595,26 +592,22 @@ const KRMat4 &KRNode::getBindPoseMatrix()
} else {
// WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
m_bindPoseMatrix.translate(-m_scalingPivot);
m_bindPoseMatrix.scale(m_localScale);
m_bindPoseMatrix.translate(m_scalingPivot);
m_bindPoseMatrix.translate(m_scalingOffset);
m_bindPoseMatrix.translate(-m_rotationPivot);
m_bindPoseMatrix.rotate(-m_postRotation.z, Z_AXIS);
m_bindPoseMatrix.rotate(-m_postRotation.y, Y_AXIS);
m_bindPoseMatrix.rotate(-m_postRotation.x, X_AXIS);
m_bindPoseMatrix.rotate(m_localRotation.x, X_AXIS);
m_bindPoseMatrix.rotate(m_localRotation.y, Y_AXIS);
m_bindPoseMatrix.rotate(m_localRotation.z, Z_AXIS);
m_bindPoseMatrix.rotate(m_preRotation.x, X_AXIS);
m_bindPoseMatrix.rotate(m_preRotation.y, Y_AXIS);
m_bindPoseMatrix.rotate(m_preRotation.z, Z_AXIS);
m_bindPoseMatrix.translate(m_rotationPivot);
m_bindPoseMatrix.translate(m_rotationOffset);
m_bindPoseMatrix.translate(m_localTranslation);
m_bindPoseMatrix = KRMat4::Translation(-m_initialScalingPivot)
* KRMat4::Scaling(m_initialLocalScale)
* KRMat4::Translation(m_initialScalingPivot)
* KRMat4::Translation(m_initialScalingOffset)
* KRMat4::Translation(-m_initialRotationPivot)
// * (KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation)).rotationMatrix()
* KRMat4::Rotation(m_initialPostRotation)
* KRMat4::Rotation(m_initialLocalRotation)
* KRMat4::Rotation(m_initialPreRotation)
* KRMat4::Translation(m_initialRotationPivot)
* KRMat4::Translation(m_initialRotationOffset)
* KRMat4::Translation(m_initialLocalTranslation);
if(m_parentNode && parent_is_bone) {
m_bindPoseMatrix *= m_parentNode->getBindPoseMatrix();
}
}
@@ -637,25 +630,20 @@ const KRMat4 &KRNode::getActivePoseMatrix()
}
if(getScaleCompensation() && parent_is_bone) {
m_activePoseMatrix.translate(-m_scalingPivot);
m_activePoseMatrix.scale(m_localScale);
m_activePoseMatrix.translate(m_scalingPivot);
m_activePoseMatrix.translate(m_scalingOffset);
m_activePoseMatrix.translate(-m_rotationPivot);
m_activePoseMatrix.rotate(-m_postRotation.z, Z_AXIS);
m_activePoseMatrix.rotate(-m_postRotation.y, Y_AXIS);
m_activePoseMatrix.rotate(-m_postRotation.x, X_AXIS);
m_activePoseMatrix.rotate(m_localRotation.x, X_AXIS);
m_activePoseMatrix.rotate(m_localRotation.y, Y_AXIS);
m_activePoseMatrix.rotate(m_localRotation.z, Z_AXIS);
m_activePoseMatrix.rotate(m_preRotation.x, X_AXIS);
m_activePoseMatrix.rotate(m_preRotation.y, Y_AXIS);
m_activePoseMatrix.rotate(m_preRotation.z, Z_AXIS);
m_activePoseMatrix.translate(m_rotationPivot);
m_activePoseMatrix.translate(m_rotationOffset);
m_activePoseMatrix= KRMat4::Translation(-m_scalingPivot)
* KRMat4::Scaling(m_localScale)
* KRMat4::Translation(m_scalingPivot)
* KRMat4::Translation(m_scalingOffset)
* KRMat4::Translation(-m_rotationPivot)
* KRMat4::Rotation(m_postRotation)
* KRMat4::Rotation(m_localRotation)
* KRMat4::Rotation(m_preRotation)
* KRMat4::Translation(m_rotationPivot)
* KRMat4::Translation(m_rotationOffset);
if(m_parentNode) {
m_activePoseMatrix.rotate(m_parentNode->getWorldRotation());
m_activePoseMatrix.rotate(m_parentNode->getActivePoseWorldRotation());
m_activePoseMatrix.translate(KRMat4::Dot(m_parentNode->getActivePoseMatrix(), m_localTranslation));
} else {
m_activePoseMatrix.translate(m_localTranslation);
@@ -663,23 +651,17 @@ const KRMat4 &KRNode::getActivePoseMatrix()
} else {
// WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
m_activePoseMatrix.translate(-m_scalingPivot);
m_activePoseMatrix.scale(m_localScale);
m_activePoseMatrix.translate(m_scalingPivot);
m_activePoseMatrix.translate(m_scalingOffset);
m_activePoseMatrix.translate(-m_rotationPivot);
m_activePoseMatrix.rotate(-m_postRotation.z, Z_AXIS);
m_activePoseMatrix.rotate(-m_postRotation.y, Y_AXIS);
m_activePoseMatrix.rotate(-m_postRotation.x, X_AXIS);
m_activePoseMatrix.rotate(m_localRotation.x, X_AXIS);
m_activePoseMatrix.rotate(m_localRotation.y, Y_AXIS);
m_activePoseMatrix.rotate(m_localRotation.z, Z_AXIS);
m_activePoseMatrix.rotate(m_preRotation.x, X_AXIS);
m_activePoseMatrix.rotate(m_preRotation.y, Y_AXIS);
m_activePoseMatrix.rotate(m_preRotation.z, Z_AXIS);
m_activePoseMatrix.translate(m_rotationPivot);
m_activePoseMatrix.translate(m_rotationOffset);
m_activePoseMatrix.translate(m_localTranslation);
m_activePoseMatrix = KRMat4::Translation(-m_scalingPivot)
* KRMat4::Scaling(m_localScale)
* KRMat4::Translation(m_scalingPivot)
* KRMat4::Translation(m_scalingOffset)
* KRMat4::Translation(-m_rotationPivot)
* KRMat4::Rotation(m_postRotation)
* KRMat4::Rotation(m_localRotation)
* KRMat4::Rotation(m_preRotation)
* KRMat4::Translation(m_rotationPivot)
* KRMat4::Translation(m_rotationOffset)
* KRMat4::Translation(m_localTranslation);
if(m_parentNode && parent_is_bone) {
@@ -694,6 +676,30 @@ const KRMat4 &KRNode::getActivePoseMatrix()
}
const KRQuaternion KRNode::getWorldRotation() {
KRQuaternion world_rotation = KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation);
if(m_parentNode) {
world_rotation = world_rotation * m_parentNode->getWorldRotation();
}
return world_rotation;
}
const KRQuaternion KRNode::getBindPoseWorldRotation() {
KRQuaternion world_rotation = KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation);
if(dynamic_cast<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()
{
if(!m_inverseModelMatrixValid) {
@@ -713,59 +719,124 @@ const KRMat4 &KRNode::getInverseBindPoseMatrix()
void KRNode::physicsUpdate(float deltaTime)
{
const long MIN_DISPLAY_FRAMES = 10;
bool visible = m_lastRenderFrame + MIN_DISPLAY_FRAMES >= getContext().getCurrentFrame();
for(std::set<KRBehavior *>::iterator itr=m_behaviors.begin(); itr != m_behaviors.end(); itr++) {
(*itr)->update(deltaTime);
if(visible) {
(*itr)->visibleUpdate(deltaTime);
}
}
}
bool KRNode::hasPhysics()
{
return false;
return m_behaviors.size() > 0;
}
void KRNode::SetAttribute(node_attribute_type attrib, float v)
{
if(m_animation_mask[attrib]) return;
const float DEGREES_TO_RAD = M_PI / 180.0f;
//printf("%s - ", m_name.c_str());
switch(attrib) {
case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X:
//printf("translate_x: %f\n", v);
setLocalTranslation(KRVector3(v, m_localTranslation.y, m_localTranslation.z));
break;
case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y:
//printf("translate_y: %f\n", v);
setLocalTranslation(KRVector3(m_localTranslation.x, v, m_localTranslation.z));
break;
case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z:
//printf("translate_z: %f\n", v);
setLocalTranslation(KRVector3(m_localTranslation.x, m_localTranslation.y, v));
break;
case KRENGINE_NODE_ATTRIBUTE_SCALE_X:
//printf("scale_x: %f\n", v);
setLocalScale(KRVector3(v, m_localScale.y, m_localScale.z));
break;
case KRENGINE_NODE_ATTRIBUTE_SCALE_Y:
//printf("scale_y: %f\n", v);
setLocalScale(KRVector3(m_localScale.x, v, m_localScale.z));
break;
case KRENGINE_NODE_ATTRIBUTE_SCALE_Z:
//printf("scale_z: %f\n", v);
setLocalScale(KRVector3(m_localScale.x, m_localScale.y, v));
break;
case KRENGINE_NODE_ATTRIBUTE_ROTATE_X:
//printf("rotate_x: %f\n", v);
setLocalRotation(KRVector3(v * DEGREES_TO_RAD, m_localRotation.y, m_localRotation.z));
break;
case KRENGINE_NODE_ATTRIBUTE_ROTATE_Y:
//printf("rotate_y: %f\n", v);
setLocalRotation(KRVector3(m_localRotation.x, v * DEGREES_TO_RAD, m_localRotation.z));
break;
case KRENGINE_NODE_ATTRIBUTE_ROTATE_Z:
//printf("rotate_z: %f\n", v);
setLocalRotation(KRVector3(m_localRotation.x, m_localRotation.y, v * DEGREES_TO_RAD));
break;
case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X:
setPreRotation(KRVector3(v * DEGREES_TO_RAD, m_preRotation.y, m_preRotation.z));
break;
case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y:
setPreRotation(KRVector3(m_preRotation.x, v * DEGREES_TO_RAD, m_preRotation.z));
break;
case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z:
setPreRotation(KRVector3(m_preRotation.x, m_preRotation.y, v * DEGREES_TO_RAD));
break;
case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X:
setPostRotation(KRVector3(v * DEGREES_TO_RAD, m_postRotation.y, m_postRotation.z));
break;
case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y:
setPostRotation(KRVector3(m_postRotation.x, v * DEGREES_TO_RAD, m_postRotation.z));
break;
case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z:
setPostRotation(KRVector3(m_postRotation.x, m_postRotation.y, v * DEGREES_TO_RAD));
break;
case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X:
setRotationPivot(KRVector3(v, m_rotationPivot.y, m_rotationPivot.z));
break;
case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y:
setRotationPivot(KRVector3(m_rotationPivot.x, v, m_rotationPivot.z));
break;
case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z:
setRotationPivot(KRVector3(m_rotationPivot.x, m_rotationPivot.y, v));
break;
case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X:
setScalingPivot(KRVector3(v, m_scalingPivot.y, m_scalingPivot.z));
break;
case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y:
setScalingPivot(KRVector3(m_scalingPivot.x, v, m_scalingPivot.z));
break;
case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z:
setScalingPivot(KRVector3(m_scalingPivot.x, m_scalingPivot.y, v));
break;
case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X:
setRotationOffset(KRVector3(v, m_rotationOffset.y, m_rotationOffset.z));
break;
case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y:
setRotationOffset(KRVector3(m_rotationOffset.x, v, m_rotationOffset.z));
break;
case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z:
setRotationOffset(KRVector3(m_rotationOffset.x, m_rotationOffset.y, v));
break;
case KRENGINE_NODE_SCALE_OFFSET_X:
setScalingOffset(KRVector3(v, m_scalingOffset.y, m_scalingOffset.z));
break;
case KRENGINE_NODE_SCALE_OFFSET_Y:
setScalingOffset(KRVector3(m_scalingOffset.x, v, m_scalingOffset.z));
break;
case KRENGINE_NODE_SCALE_OFFSET_Z:
setScalingOffset(KRVector3(m_scalingOffset.x, m_scalingOffset.y, v));
break;
}
}
void KRNode::setAnimationEnabled(node_attribute_type attrib, bool enable)
{
m_animation_mask[attrib] = !enable;
}
bool KRNode::getAnimationEnabled(node_attribute_type attrib) const
{
return !m_animation_mask[attrib];
}
void KRNode::removeFromOctreeNodes()
{
for(std::set<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);
}
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 "tinyxml2.h"
#include "KROctreeNode.h"
#include "KRBehavior.h"
class KRCamera;
class KRShaderManager;
@@ -95,10 +96,10 @@ public:
const KRVector3 getWorldTranslation();
const KRVector3 getWorldScale();
const KRVector3 getWorldRotation();
const KRQuaternion getWorldRotation();
const KRVector3 getBindPoseWorldRotation();
const KRVector3 getActivePoseWorldRotation();
const KRQuaternion getBindPoseWorldRotation();
const KRQuaternion getActivePoseWorldRotation();
const KRVector3 localToWorld(const KRVector3 &local_point);
const KRVector3 worldToLocal(const KRVector3 &world_point);
@@ -124,7 +125,26 @@ public:
KRENGINE_NODE_ATTRIBUTE_SCALE_Z,
KRENGINE_NODE_ATTRIBUTE_ROTATE_X,
KRENGINE_NODE_ATTRIBUTE_ROTATE_Y,
KRENGINE_NODE_ATTRIBUTE_ROTATE_Z
KRENGINE_NODE_ATTRIBUTE_ROTATE_Z,
KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X,
KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y,
KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z,
KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X,
KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y,
KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z,
KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X,
KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y,
KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z,
KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X,
KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y,
KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z,
KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X,
KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y,
KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z,
KRENGINE_NODE_SCALE_OFFSET_X,
KRENGINE_NODE_SCALE_OFFSET_Y,
KRENGINE_NODE_SCALE_OFFSET_Z,
KRENGINE_NODE_ATTRIBUTE_COUNT
};
void SetAttribute(node_attribute_type attrib, float v);
@@ -141,6 +161,8 @@ public:
void setScaleCompensation(bool scale_compensation);
bool getScaleCompensation();
void setAnimationEnabled(node_attribute_type attrib, bool enable);
bool getAnimationEnabled(node_attribute_type attrib) const;
protected:
KRVector3 m_localTranslation;
@@ -174,7 +196,10 @@ protected:
KRNode *m_parentNode;
std::set<KRNode *> m_childNodes;
bool m_animation_mask[KRENGINE_NODE_ATTRIBUTE_COUNT];
private:
long m_lastRenderFrame;
void invalidateModelMatrix();
void invalidateBindPoseMatrix();
KRMat4 m_modelMatrix;
@@ -197,8 +222,10 @@ private:
std::set<KROctreeNode *> m_octree_nodes;
bool m_scale_compensation;
public:
std::set<KRBehavior *> m_behaviors;
public:
void addBehavior(KRBehavior *behavior);
void removeFromOctreeNodes();
void addToOctreeNode(KROctreeNode *octree_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) {
// ZYX Order!
float c1 = cos(euler[0] * 0.5f);
@@ -189,10 +196,10 @@ KRQuaternion& KRQuaternion::operator +=(const KRQuaternion& v) {
}
KRQuaternion& KRQuaternion::operator -=(const KRQuaternion& v) {
m_val[0] += v[0];
m_val[1] += v[1];
m_val[2] += v[2];
m_val[3] += v[3];
m_val[0] -= v[0];
m_val[1] -= v[1];
m_val[2] -= v[2];
m_val[3] -= v[3];
return *this;
}
@@ -270,28 +277,30 @@ void KRQuaternion::conjugate() {
}
KRMat4 KRQuaternion::rotationMatrix() const {
KRVector3 euler = eulerXYZ();
KRMat4 matRotate;
/*
KRVector3 euler = eulerXYZ();
matRotate.rotate(euler.x, X_AXIS);
matRotate.rotate(euler.y, Y_AXIS);
matRotate.rotate(euler.z, Z_AXIS);
*/
// FINDME - Determine why the more optimal routine commented below wasn't working
/*
matRotate.getPointer()[0] = 1.0 - 2.0 * (m_val[2] * m_val[2] + m_val[3] * m_val[3]);
matRotate.getPointer()[1] = 2.0 * (m_val[1] * m_val[2] - m_val[0] * m_val[3]);
matRotate.getPointer()[2] = 2.0 * (m_val[0] * m_val[2] + m_val[1] * m_val[3]);
matRotate.getPointer()[4] = 2.0 * (m_val[1] * m_val[2] + m_val[0] * m_val[3]);
matRotate.getPointer()[5] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[3] * m_val[3]);
matRotate.getPointer()[6] = 2.0 * (m_val[2] * m_val[3] - m_val[0] * m_val[1]);
matRotate.c[0] = 1.0 - 2.0 * (m_val[2] * m_val[2] + m_val[3] * m_val[3]);
matRotate.c[1] = 2.0 * (m_val[1] * m_val[2] - m_val[0] * m_val[3]);
matRotate.c[2] = 2.0 * (m_val[0] * m_val[2] + m_val[1] * m_val[3]);
matRotate.getPointer()[8] = 2.0 * (m_val[1] * m_val[3] - m_val[0] * m_val[2]);
matRotate.getPointer()[9] = 2.0 * (m_val[0] * m_val[1] + m_val[2] * m_val[3]);
matRotate.getPointer()[10] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[2] * m_val[2]);
*/
matRotate.c[4] = 2.0 * (m_val[1] * m_val[2] + m_val[0] * m_val[3]);
matRotate.c[5] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[3] * m_val[3]);
matRotate.c[6] = 2.0 * (m_val[2] * m_val[3] - m_val[0] * m_val[1]);
matRotate.c[8] = 2.0 * (m_val[1] * m_val[3] - m_val[0] * m_val[2]);
matRotate.c[9] = 2.0 * (m_val[0] * m_val[1] + m_val[2] * m_val[3]);
matRotate.c[10] = 1.0 - 2.0 * (m_val[1] * m_val[1] + m_val[2] * m_val[2]);
return matRotate;
}

View File

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

View File

@@ -42,10 +42,10 @@ KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLaye
void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
//void BakeNode(KFbxNode* pNode);
void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial);
void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh);
KRNode *LoadMesh(KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh);
KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode);
KRNode *LoadSkeleton(KRNode *parent_node, KFbxNode* pNode);
KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode);
KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode);
std::string GetFbxObjectName(FbxObject *obj);
@@ -56,6 +56,10 @@ std::string GetFbxObjectName(FbxObject *obj)
{
// Object names from FBX files are now concatenated with the FBX numerical ID to ensure that they are unique
// TODO - This should be updated to only add a prefix or suffix if needed to make the name unique
if(strcmp(obj->GetName(), "default_camera") == 0) {
// There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera
return "default_camera";
} else {
std::stringstream st;
st << "fbx_";
st << obj->GetUniqueID();
@@ -65,6 +69,7 @@ std::string GetFbxObjectName(FbxObject *obj)
}
return st.str();
}
}
void KRResource::LoadFbx(KRContext &context, const std::string& path)
{
@@ -136,7 +141,7 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path)
FbxMesh *mesh = pFbxScene->GetSrcObject<FbxMesh>(i);
printf(" Mesh %i of %i: %s\n", i+1, mesh_count, mesh->GetNode()->GetName());
LoadMesh(context, pGeometryConverter, mesh);
LoadMesh(context, pFbxScene, pGeometryConverter, mesh);
}
// ----====---- Import Textures ----====----
@@ -640,6 +645,171 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->PreRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->PreRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->PreRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->PostRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->PostRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->PostRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->RotationPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->RotationPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->RotationPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->ScalingPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->ScalingPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->ScalingPivot.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->RotationOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->RotationOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->RotationOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->ScalingOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_SCALE_OFFSET_X);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->ScalingOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_SCALE_OFFSET_Y);
pAnimationLayer->addAttribute(new_attribute);
}
pAnimCurve = pNode->ScalingOffset.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z);
if(pAnimCurve) {
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(parent_node->getContext());
new_attribute->setCurveName(GetFbxObjectName(pAnimCurve));
new_attribute->setTargetName(GetFbxObjectName(pNode));
new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_SCALE_OFFSET_Z);
pAnimationLayer->addAttribute(new_attribute);
}
}
}
}
@@ -648,6 +818,8 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
fbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot);
fbxDouble3 local_scale = pNode->LclScaling.Get(); // pNode->GetGeometricScaling(KFbxNode::eSourcePivot);
bool rotation_active = pNode->RotationActive.Get();
fbxDouble3 post_rotation = pNode->PostRotation.Get();
fbxDouble3 pre_rotation = pNode->PreRotation.Get();
fbxDouble3 rotation_offset = pNode->RotationOffset.Get();
@@ -676,8 +848,14 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
KRVector3 node_scaling_offset = KRVector3(scaling_offset[0], scaling_offset[1], scaling_offset[2]);
KRVector3 node_rotation_pivot = KRVector3(rotation_pivot[0], rotation_pivot[1], rotation_pivot[2]);
KRVector3 node_scaling_pivot = KRVector3(scaling_pivot[0], scaling_pivot[1], scaling_pivot[2]);
KRVector3 node_pre_rotation = KRVector3(pre_rotation[0], pre_rotation[1], pre_rotation[2]) / 180.0 * M_PI;
KRVector3 node_post_rotation = KRVector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI;
KRVector3 node_pre_rotation, node_post_rotation;
if(rotation_active) {
node_pre_rotation = KRVector3(pre_rotation[0], pre_rotation[1], pre_rotation[2]) / 180.0 * M_PI;
node_post_rotation = KRVector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI;
} else {
node_pre_rotation = KRVector3::Zero();
node_post_rotation = KRVector3::Zero();
}
// printf(" Local Translation: %f %f %f\n", local_translation[0], local_translation[1], local_translation[2]);
// printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]);
@@ -769,13 +947,13 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
KRNode *new_node = NULL;
switch(attribute_type) {
case KFbxNodeAttribute::eMesh:
new_node = LoadMesh(parent_node, pGeometryConverter, pNode);
new_node = LoadMesh(parent_node, pFbxScene, pGeometryConverter, pNode);
break;
case KFbxNodeAttribute::eLight:
new_node = LoadLight(parent_node, pNode);
break;
case KFbxNodeAttribute::eSkeleton:
new_node = LoadSkeleton(parent_node, pNode);
new_node = LoadSkeleton(parent_node, pFbxScene, pNode);
break;
case KFbxNodeAttribute::eCamera:
new_node = LoadCamera(parent_node, pNode);
@@ -1027,18 +1205,23 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) {
}
}
void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh) {
void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh) {
KFbxMesh* pMesh = pGeometryConverter->TriangulateMesh(pSourceMesh);
KRMesh::mesh_info mi;
mi.format = KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES;
typedef struct {
float weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX];
int bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX];
} control_point_weight_info_t;
int control_point_count = pMesh->GetControlPointsCount();
KFbxVector4* control_points = pMesh->GetControlPoints();
struct control_point_weight_info {
float weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX];
int bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX];
};
control_point_weight_info *control_point_weights = new control_point_weight_info[control_point_count];
control_point_weight_info_t *control_point_weights = new control_point_weight_info_t[control_point_count];
for(int control_point=0; control_point < control_point_count; control_point++) {
for(int i=0; i<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) {
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;
// Collect the top 4 bone weights per vertex ...
@@ -1063,12 +1245,39 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
printf(" Warning! link mode not supported.\n");
}
std::string bone_name = GetFbxObjectName(cluster->GetLink());
bone_names.push_back(bone_name);
mi.bone_names.push_back(bone_name);
/*
FbxMatrix fbx_bind_pose_matrix;
KRMat4 bind_pose;
PoseList pose_list;
FbxArray<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();
for(int control_point=0; control_point<cluster_control_point_count; control_point++) {
control_point_weight_info &weight_info = control_point_weights[cluster->GetControlPointIndices()[control_point]];
float bone_weight = cluster->GetControlPointWeights()[control_point];
for(int cluster_control_point=0; cluster_control_point<cluster_control_point_count; cluster_control_point++) {
int control_point = cluster->GetControlPointIndices()[cluster_control_point];
control_point_weight_info_t &weight_info = control_point_weights[control_point];
float bone_weight = cluster->GetControlPointWeights()[cluster_control_point];
if(bone_weight > weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1]) {
if(weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] != 0.0f) {
too_many_bone_weights = true;
@@ -1095,9 +1304,9 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
printf(" WARNING! - Clipped bone weights to limit of %i per vertex (selecting largest weights and re-normalizing).\n", KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX);
}
// Normalize bone weights
if(bone_names.size() > 0) {
if(mi.bone_names.size() > 0) {
for(int control_point_index=0; control_point_index < control_point_count; control_point_index++) {
control_point_weight_info &weight_info = control_point_weights[control_point_index];
control_point_weight_info_t &weight_info = control_point_weights[control_point_index];
float total_weights = 0.0f;
for(int i=0; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) {
total_weights += weight_info.weights[i];
@@ -1116,17 +1325,17 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
int elementmaterial_count = pMesh->GetElementMaterialCount();
int material_count = pSourceMesh->GetNode()->GetMaterialCount(); // FINDME, TODO - To support instancing, material names should be stored in the instance rather than the mesh
std::vector<std::vector<float> > bone_weights;
std::vector<std::vector<int> > bone_indexes;
std::vector<KRVector3> vertices;
std::vector<KRVector2> uva;
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::vector<float> > bone_weights;
// std::vector<std::vector<int> > bone_indexes;
//
// std::vector<KRVector3> vertices;
// std::vector<KRVector2> uva;
// 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;
int dest_vertex_id = 0;
@@ -1172,18 +1381,18 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
// ----====---- Read Vertex Position ----====----
int lControlPointIndex = pMesh->GetPolygonVertex(iPolygon, iVertex);
KFbxVector4 v = control_points[lControlPointIndex];
vertices.push_back(KRVector3(v[0], v[1], v[2]));
mi.vertices.push_back(KRVector3(v[0], v[1], v[2]));
if(bone_names.size() > 0) {
control_point_weight_info &weight_info = control_point_weights[lControlPointIndex];
if(mi.bone_names.size() > 0) {
control_point_weight_info_t &weight_info = control_point_weights[lControlPointIndex];
std::vector<int> vertex_bone_indexes;
std::vector<float> vertex_bone_weights;
for(int i=0; i<KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) {
vertex_bone_indexes.push_back(weight_info.bone_indexes[i]);
vertex_bone_weights.push_back(weight_info.weights[i]);
}
bone_indexes.push_back(vertex_bone_indexes);
bone_weights.push_back(vertex_bone_weights);
mi.bone_indexes.push_back(vertex_bone_indexes);
mi.bone_weights.push_back(vertex_bone_weights);
}
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)) {
new_uva = KRVector2(uv[0], uv[1]);
}
uva.push_back(new_uva);
mi.uva.push_back(new_uva);
}
if(uv_count >= 2) {
@@ -1209,14 +1418,14 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv)) {
new_uvb = KRVector2(uv[0], uv[1]);
}
uvb.push_back(new_uvb);
mi.uvb.push_back(new_uvb);
}
// ----====---- Read Normals ----====----
KFbxVector4 new_normal;
if(pMesh->GetPolygonVertexNormal(iPolygon, iVertex, new_normal)) {
normals.push_back(KRVector3(new_normal[0], new_normal[1], new_normal[2]));
mi.normals.push_back(KRVector3(new_normal[0], new_normal[1], new_normal[2]));
}
@@ -1242,7 +1451,7 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
}
}
if(l == 0) {
tangents.push_back(KRVector3(new_tangent[0], new_tangent[1], new_tangent[2]));
mi.tangents.push_back(KRVector3(new_tangent[0], new_tangent[1], new_tangent[2]));
}
}
@@ -1261,23 +1470,21 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
if(mat_vertex_count) {
// ----====---- Output last material / submesh details ----====----
submesh_starts.push_back(mat_vertex_start);
submesh_lengths.push_back(mat_vertex_count);
material_names.push_back(pMaterial->GetName());
mi.submesh_starts.push_back(mat_vertex_start);
mi.submesh_lengths.push_back(mat_vertex_count);
mi.material_names.push_back(pMaterial->GetName());
}
}
delete control_point_weights;
KRMesh *new_mesh = new KRMesh(context, pSourceMesh->GetNode()->GetName());
std::vector<__uint16_t> vertex_indexes;
std::vector<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);
new_mesh->LoadData(mi, true, need_tangents);
context.getModelManager()->addModel(new_mesh);
}
KRNode *LoadMesh(KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) {
KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) {
std::string name = GetFbxObjectName(pNode);
KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute();
@@ -1305,9 +1512,17 @@ KRNode *LoadMesh(KRNode *parent_node, FbxGeometryConverter *pGeometryConverter,
}
KRNode *LoadSkeleton(KRNode *parent_node, KFbxNode* pNode) {
KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) {
std::string name = GetFbxObjectName(pNode);
KRBone *new_bone = new KRBone(parent_node->getScene(), name.c_str());
//static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray<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;
}

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

View File

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

View File

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

View File

@@ -40,7 +40,6 @@
using namespace std;
KRShaderManager::KRShaderManager(KRContext &context) : KRContextObject(context) {
m_szCurrentShaderKey[0] = '\0';
m_active_shader = NULL;
}
@@ -248,13 +247,7 @@ bool KRShaderManager::selectShader(const std::string &shader_name, KRCamera &cam
bool KRShaderManager::selectShader(KRCamera &camera, KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, int bone_count, const KRNode::RenderPass &renderPass)
{
if(pShader) {
bool bSameShader = strcmp(pShader->getKey(), m_szCurrentShaderKey) == 0;
if(!bSameShader || true) { // FINDME, HACK. Need to update logic to detect appropriate times to bind a new shader
strcpy(m_szCurrentShaderKey, pShader->getKey());
return pShader->bind(camera, viewport, matModel, point_lights, directional_lights, spot_lights, renderPass);
} else {
return true;
}
} else {
return false;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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