diff --git a/kraken/KRAmbientZone.cpp b/kraken/KRAmbientZone.cpp index b7fbb60..63e9933 100755 --- a/kraken/KRAmbientZone.cpp +++ b/kraken/KRAmbientZone.cpp @@ -42,152 +42,153 @@ void KRAmbientZone::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->ambient_zone.sample = -1; } -KRAmbientZone::KRAmbientZone(KRScene &scene, std::string name) : KRNode(scene, name) +KRAmbientZone::KRAmbientZone(KRScene& scene, std::string name) : KRNode(scene, name) { - m_ambient = ""; - m_ambient_gain = 1.0f; + m_ambient = ""; + m_ambient_gain = 1.0f; + + m_gradient_distance = 0.25f; - m_gradient_distance = 0.25f; - } KRAmbientZone::~KRAmbientZone() +{} + +std::string KRAmbientZone::getElementName() { + return "ambient_zone"; } -std::string KRAmbientZone::getElementName() { - return "ambient_zone"; +tinyxml2::XMLElement* KRAmbientZone::saveXML(tinyxml2::XMLNode* parent) +{ + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + e->SetAttribute("zone", m_zone.c_str()); + e->SetAttribute("sample", m_ambient.c_str()); + e->SetAttribute("gain", m_ambient_gain); + e->SetAttribute("gradient", m_gradient_distance); + return e; } -tinyxml2::XMLElement *KRAmbientZone::saveXML( tinyxml2::XMLNode *parent) +void KRAmbientZone::loadXML(tinyxml2::XMLElement* e) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - e->SetAttribute("zone", m_zone.c_str()); - e->SetAttribute("sample", m_ambient.c_str()); - e->SetAttribute("gain", m_ambient_gain); - e->SetAttribute("gradient", m_gradient_distance); - return e; -} + KRNode::loadXML(e); -void KRAmbientZone::loadXML(tinyxml2::XMLElement *e) -{ - KRNode::loadXML(e); - - m_zone = e->Attribute("zone"); - + m_zone = e->Attribute("zone"); + + m_gradient_distance = 0.25f; + if (e->QueryFloatAttribute("gradient", &m_gradient_distance) != tinyxml2::XML_SUCCESS) { m_gradient_distance = 0.25f; - if(e->QueryFloatAttribute("gradient", &m_gradient_distance) != tinyxml2::XML_SUCCESS) { - m_gradient_distance = 0.25f; - } - - m_ambient = e->Attribute("sample"); - + } + + m_ambient = e->Attribute("sample"); + + m_ambient_gain = 1.0f; + if (e->QueryFloatAttribute("gain", &m_ambient_gain) != tinyxml2::XML_SUCCESS) { m_ambient_gain = 1.0f; - if(e->QueryFloatAttribute("gain", &m_ambient_gain) != tinyxml2::XML_SUCCESS) { - m_ambient_gain = 1.0f; - } + } } std::string KRAmbientZone::getAmbient() { - return m_ambient; + return m_ambient; } -void KRAmbientZone::setAmbient(const std::string &ambient) +void KRAmbientZone::setAmbient(const std::string& ambient) { - m_ambient = ambient; + m_ambient = ambient; } float KRAmbientZone::getAmbientGain() { - return m_ambient_gain; + return m_ambient_gain; } void KRAmbientZone::setAmbientGain(float ambient_gain) { - m_ambient_gain = ambient_gain; + m_ambient_gain = ambient_gain; } std::string KRAmbientZone::getZone() { - return m_zone; + return m_zone; } -void KRAmbientZone::setZone(const std::string &zone) +void KRAmbientZone::setZone(const std::string& zone) { - m_zone = zone; + m_zone = zone; } void KRAmbientZone::render(RenderInfo& ri) { - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRNode::render(ri); - - bool bVisualize = ri.camera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_SIREN_AMBIENT_ZONES; - - if(ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) { - KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere"); - if (sphereModel) { + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - Matrix4 sphereModelMatrix = getModelMatrix(); + KRNode::render(ri); - PipelineInfo info{}; - std::string shader_name("visualize_overlay"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAdditive; - info.modelFormat = sphereModel->getModelFormat(); - info.vertexAttributes = sphereModel->getVertexAttributes(); - - KRPipeline *pPipeline = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pPipeline->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + bool bVisualize = ri.camera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_SIREN_AMBIENT_ZONES; - sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); - } // sphereModel - } + if (ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) { + KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere"); + if (sphereModel) { + + Matrix4 sphereModelMatrix = getModelMatrix(); + + PipelineInfo info{}; + std::string shader_name("visualize_overlay"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.renderPass = ri.renderPass; + info.rasterMode = RasterMode::kAdditive; + info.modelFormat = sphereModel->getModelFormat(); + info.vertexAttributes = sphereModel->getVertexAttributes(); + + KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + pPipeline->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + + sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); + } // sphereModel + } } float KRAmbientZone::getGradientDistance() { - return m_gradient_distance; + return m_gradient_distance; } void KRAmbientZone::setGradientDistance(float gradient_distance) { - m_gradient_distance = gradient_distance; + m_gradient_distance = gradient_distance; } -AABB KRAmbientZone::getBounds() { - // Ambient zones always have a -1, -1, -1 to 1, 1, 1 bounding box - return AABB::Create(-Vector3::One(), Vector3::One(), getModelMatrix()); -} - -float KRAmbientZone::getContainment(const Vector3 &pos) +AABB KRAmbientZone::getBounds() { - AABB bounds = getBounds(); - if(bounds.contains(pos)) { - Vector3 size = bounds.size(); - Vector3 diff = pos - bounds.center(); - diff = diff * 2.0f; - diff = Vector3::Create(diff.x / size.x, diff.y / size.y, diff.z / size.z); - float d = diff.magnitude(); - - if(m_gradient_distance <= 0.0f) { - // Avoid division by zero - d = d > 1.0f ? 0.0f : 1.0f; - } else { - d = (1.0f - d) / m_gradient_distance; - d = KRCLAMP(d, 0.0f, 1.0f); - } - return d; - + // Ambient zones always have a -1, -1, -1 to 1, 1, 1 bounding box + return AABB::Create(-Vector3::One(), Vector3::One(), getModelMatrix()); +} + +float KRAmbientZone::getContainment(const Vector3& pos) +{ + AABB bounds = getBounds(); + if (bounds.contains(pos)) { + Vector3 size = bounds.size(); + Vector3 diff = pos - bounds.center(); + diff = diff * 2.0f; + diff = Vector3::Create(diff.x / size.x, diff.y / size.y, diff.z / size.z); + float d = diff.magnitude(); + + if (m_gradient_distance <= 0.0f) { + // Avoid division by zero + d = d > 1.0f ? 0.0f : 1.0f; } else { - return 0.0f; + d = (1.0f - d) / m_gradient_distance; + d = KRCLAMP(d, 0.0f, 1.0f); } + return d; + + } else { + return 0.0f; + } } \ No newline at end of file diff --git a/kraken/KRAmbientZone.h b/kraken/KRAmbientZone.h index 16efdab..79cef96 100755 --- a/kraken/KRAmbientZone.h +++ b/kraken/KRAmbientZone.h @@ -35,39 +35,40 @@ #include "KRNode.h" #include "KRTexture.h" -class KRAmbientZone : public KRNode { +class KRAmbientZone : public KRNode +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); + static void InitNodeInfo(KrNodeInfo* nodeInfo); + + KRAmbientZone(KRScene& scene, std::string name); + virtual ~KRAmbientZone(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + + void render(RenderInfo& ri); + + std::string getZone(); + void setZone(const std::string& zone); + + float getGradientDistance(); + void setGradientDistance(float gradient_distance); + + std::string getAmbient(); + void setAmbient(const std::string& ambient); + + float getAmbientGain(); + void setAmbientGain(float ambient_gain); + + virtual AABB getBounds(); + + float getContainment(const Vector3& pos); - KRAmbientZone(KRScene &scene, std::string name); - virtual ~KRAmbientZone(); - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - - void render(RenderInfo& ri); - - std::string getZone(); - void setZone(const std::string &zone); - - float getGradientDistance(); - void setGradientDistance(float gradient_distance); - - std::string getAmbient(); - void setAmbient(const std::string &ambient); - - float getAmbientGain(); - void setAmbientGain(float ambient_gain); - - virtual AABB getBounds(); - - float getContainment(const Vector3 &pos); - private: - std::string m_zone; - - float m_gradient_distance; - - std::string m_ambient; - float m_ambient_gain; + std::string m_zone; + + float m_gradient_distance; + + std::string m_ambient; + float m_ambient_gain; }; diff --git a/kraken/KRAnimation.cpp b/kraken/KRAnimation.cpp index 676a08f..cab76ad 100755 --- a/kraken/KRAnimation.cpp +++ b/kraken/KRAnimation.cpp @@ -35,313 +35,315 @@ #include "KRAnimationCurve.h" #include "KREngine-common.h" -KRAnimation::KRAnimation(KRContext &context, std::string name) : KRResource(context, name) +KRAnimation::KRAnimation(KRContext& context, std::string name) : KRResource(context, name) { - m_auto_play = false; - m_loop = false; - m_playing = false; - m_local_time = 0.0f; - m_duration = 0.0f; - m_start_time = 0.0f; + m_auto_play = false; + m_loop = false; + m_playing = false; + m_local_time = 0.0f; + m_duration = 0.0f; + m_start_time = 0.0f; } KRAnimation::~KRAnimation() { - for(unordered_map::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr){ - delete (*itr).second; - } + for (unordered_map::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr) { + delete (*itr).second; + } } -std::string KRAnimation::getExtension() { - return "kranimation"; -} - -void KRAnimation::addLayer(KRAnimationLayer *layer) +std::string KRAnimation::getExtension() { - m_layers[layer->getName()] = layer; + return "kranimation"; } -bool KRAnimation::save(KRDataBlock &data) { - tinyxml2::XMLDocument doc; - tinyxml2::XMLElement *animation_node = doc.NewElement( "animation" ); - doc.InsertEndChild(animation_node); - animation_node->SetAttribute("loop", m_loop ? "true" : "false"); - animation_node->SetAttribute("auto_play", m_auto_play ? "true" : "false"); - animation_node->SetAttribute("duration", m_duration); - animation_node->SetAttribute("start_time", m_start_time); - - for(unordered_map::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr){ - (*itr).second->saveXML(animation_node); - } - - tinyxml2::XMLPrinter p; - doc.Print(&p); - data.append((void *)p.CStr(), strlen(p.CStr())+1); - - return true; -} - -KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, KRDataBlock *data) +void KRAnimation::addLayer(KRAnimationLayer* layer) { - std::string xml_string = data->getString(); - - tinyxml2::XMLDocument doc; - doc.Parse(xml_string.c_str()); - KRAnimation *new_animation = new KRAnimation(context, name); - - tinyxml2::XMLElement *animation_node = doc.RootElement(); - - if(animation_node->QueryFloatAttribute("duration", &new_animation->m_duration) != tinyxml2::XML_SUCCESS) { - new_animation->m_duration = 0.0f; // Default value - } - - if(animation_node->QueryFloatAttribute("start_time", &new_animation->m_start_time) != tinyxml2::XML_SUCCESS) { - new_animation->m_start_time = 0.0f; // Default value - } - - if(animation_node->QueryBoolAttribute("loop", &new_animation->m_loop) != tinyxml2::XML_SUCCESS) { - 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 = false; // Default value - } + m_layers[layer->getName()] = layer; +} - for(tinyxml2::XMLElement *child_element=animation_node->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { - if(strcmp(child_element->Name(), "layer") == 0) { - KRAnimationLayer *new_layer = new KRAnimationLayer(context); - new_layer->loadXML(child_element); - new_animation->m_layers[new_layer->getName()] = new_layer; - } +bool KRAnimation::save(KRDataBlock& data) +{ + tinyxml2::XMLDocument doc; + tinyxml2::XMLElement* animation_node = doc.NewElement("animation"); + doc.InsertEndChild(animation_node); + animation_node->SetAttribute("loop", m_loop ? "true" : "false"); + animation_node->SetAttribute("auto_play", m_auto_play ? "true" : "false"); + animation_node->SetAttribute("duration", m_duration); + animation_node->SetAttribute("start_time", m_start_time); + + for (unordered_map::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr) { + (*itr).second->saveXML(animation_node); + } + + tinyxml2::XMLPrinter p; + doc.Print(&p); + data.append((void*)p.CStr(), strlen(p.CStr()) + 1); + + return true; +} + +KRAnimation* KRAnimation::Load(KRContext& context, const std::string& name, KRDataBlock* data) +{ + std::string xml_string = data->getString(); + + tinyxml2::XMLDocument doc; + doc.Parse(xml_string.c_str()); + KRAnimation* new_animation = new KRAnimation(context, name); + + tinyxml2::XMLElement* animation_node = doc.RootElement(); + + if (animation_node->QueryFloatAttribute("duration", &new_animation->m_duration) != tinyxml2::XML_SUCCESS) { + new_animation->m_duration = 0.0f; // Default value + } + + if (animation_node->QueryFloatAttribute("start_time", &new_animation->m_start_time) != tinyxml2::XML_SUCCESS) { + new_animation->m_start_time = 0.0f; // Default value + } + + if (animation_node->QueryBoolAttribute("loop", &new_animation->m_loop) != tinyxml2::XML_SUCCESS) { + 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 = false; // Default value + } + + for (tinyxml2::XMLElement* child_element = animation_node->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { + if (strcmp(child_element->Name(), "layer") == 0) { + KRAnimationLayer* new_layer = new KRAnimationLayer(context); + new_layer->loadXML(child_element); + new_animation->m_layers[new_layer->getName()] = new_layer; } - - if(new_animation->m_auto_play) { - new_animation->m_playing = true; - } - -// KRNode *n = KRNode::LoadXML(*new_scene, scene_element->FirstChildElement()); - - delete data; - return new_animation; + } + + if (new_animation->m_auto_play) { + new_animation->m_playing = true; + } + + // KRNode *n = KRNode::LoadXML(*new_scene, scene_element->FirstChildElement()); + + delete data; + return new_animation; } -unordered_map &KRAnimation::getLayers() +unordered_map& KRAnimation::getLayers() { - return m_layers; + return m_layers; } -KRAnimationLayer *KRAnimation::getLayer(const char *szName) +KRAnimationLayer* KRAnimation::getLayer(const char* szName) { - return m_layers[szName]; + return m_layers[szName]; } void KRAnimation::update(float deltaTime) -{ - if(m_playing) { - m_local_time += deltaTime; +{ + if (m_playing) { + m_local_time += deltaTime; + } + if (m_loop) { + while (m_local_time > m_duration) { + m_local_time -= m_duration; } - if(m_loop) { - while(m_local_time > m_duration) { - m_local_time -= m_duration; - } - } else if(m_local_time > m_duration) { - m_local_time = m_duration; - m_playing = false; - getContext().getAnimationManager()->updateActiveAnimations(this); - } - - for(unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { - KRAnimationLayer *layer = (*layer_itr).second; - for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { - KRAnimationAttribute *attribute = *attribute_itr; - - - // TODO - Currently only a single layer supported per animation -- need to either implement combining of multiple layers or ask the FBX sdk to bake all layers into one - KRAnimationCurve *curve = attribute->getCurve(); - KRNode *target = attribute->getTarget(); - KRNode::node_attribute_type attribute_type = attribute->getTargetAttribute(); - - if(curve != NULL && target != NULL) { - target->SetAttribute(attribute_type, curve->getValue(m_local_time + m_start_time)); - } - } + } else if (m_local_time > m_duration) { + m_local_time = m_duration; + m_playing = false; + getContext().getAnimationManager()->updateActiveAnimations(this); + } + + for (unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { + KRAnimationLayer* layer = (*layer_itr).second; + for (std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { + KRAnimationAttribute* attribute = *attribute_itr; + + + // TODO - Currently only a single layer supported per animation -- need to either implement combining of multiple layers or ask the FBX sdk to bake all layers into one + KRAnimationCurve* curve = attribute->getCurve(); + KRNode* target = attribute->getTarget(); + KRNode::node_attribute_type attribute_type = attribute->getTargetAttribute(); + + if (curve != NULL && target != NULL) { + target->SetAttribute(attribute_type, curve->getValue(m_local_time + m_start_time)); + } } + } } void KRAnimation::Play() { - m_playing = true; - getContext().getAnimationManager()->updateActiveAnimations(this); + m_playing = true; + getContext().getAnimationManager()->updateActiveAnimations(this); } void KRAnimation::Stop() { - m_playing = false; - getContext().getAnimationManager()->updateActiveAnimations(this); + m_playing = false; + getContext().getAnimationManager()->updateActiveAnimations(this); } float KRAnimation::getTime() { - return m_local_time; + return m_local_time; } void KRAnimation::setTime(float time) { - m_local_time = time; + m_local_time = time; } float KRAnimation::getDuration() { - return m_duration; + return m_duration; } void KRAnimation::setDuration(float duration) { - m_duration = duration; + m_duration = duration; } float KRAnimation::getStartTime() { - return m_start_time; + return m_start_time; } void KRAnimation::setStartTime(float start_time) { - m_start_time = start_time; + m_start_time = start_time; } bool KRAnimation::isPlaying() { - return m_playing; + return m_playing; } bool KRAnimation::getAutoPlay() const { - return m_auto_play; + return m_auto_play; } void KRAnimation::setAutoPlay(bool auto_play) { - m_auto_play = auto_play; + m_auto_play = auto_play; } bool KRAnimation::getLooping() const { - return m_loop; + return m_loop; } void KRAnimation::setLooping(bool looping) { - m_loop = looping; + m_loop = looping; } -KRAnimation *KRAnimation::split(const std::string &name, float start_time, float duration, bool strip_unchanging_attributes, bool clone_curves) +KRAnimation* KRAnimation::split(const std::string& name, float start_time, float duration, bool strip_unchanging_attributes, bool clone_curves) { - KRAnimation *new_animation = new KRAnimation(getContext(), name); - new_animation->setStartTime(start_time); - new_animation->setDuration(duration); - new_animation->m_loop = m_loop; - new_animation->m_auto_play = m_auto_play; - int new_curve_count = 0; - for(unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { - KRAnimationLayer *layer = (*layer_itr).second; - KRAnimationLayer *new_layer = new KRAnimationLayer(getContext()); - new_layer->setName(layer->getName()); - new_layer->setRotationAccumulationMode(layer->getRotationAccumulationMode()); - new_layer->setScaleAccumulationMode(layer->getScaleAccumulationMode()); - new_layer->setWeight(layer->getWeight()); - new_animation->m_layers[new_layer->getName()] = new_layer; - for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { - KRAnimationAttribute *attribute = *attribute_itr; - - // Updated Dec 9, 2013 by Peter to change the way that attributes are stripped. - // - // If we have been asked to strip_unchanging_attributes then we only want to strip those attributes that don't havechanges - // in any of their components (x, y, z). This means that we have to group the attributes before we check for valueChanges(). - // The attributes won't come through in order, but they do come through in group order (each group of 3 arrives as x, y, z) - // - // Since this method isn't designed to handle groups, this is a bit of a hack. We simply take whatever channel is coming - // through and then check the other associated curves. - // - int targetAttribute = attribute->getTargetAttribute(); - if (targetAttribute > 0) { // we have a valid target that fits within a group of 3 - targetAttribute--; // this is now group relative 0,1,2 is the first group .. 3,4,5 is the second group, etc. - - KRAnimationCurve *curve = attribute->getCurve(); // this is the curve we are currently handling - - int placeInGroup = targetAttribute % 3; // this will be 0, 1 or 2 - static long placeLookup[] = { 1, 2, -1, 1, -2, -1 }; - - KRAnimationAttribute *attribute2 = *(attribute_itr + placeLookup[placeInGroup*2]); - KRAnimationAttribute *attribute3 = *(attribute_itr + placeLookup[placeInGroup*2+1]); - KRAnimationCurve *curve2 = attribute2->getCurve(); - KRAnimationCurve *curve3 = attribute3->getCurve(); + KRAnimation* new_animation = new KRAnimation(getContext(), name); + new_animation->setStartTime(start_time); + new_animation->setDuration(duration); + new_animation->m_loop = m_loop; + new_animation->m_auto_play = m_auto_play; + int new_curve_count = 0; + for (unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { + KRAnimationLayer* layer = (*layer_itr).second; + KRAnimationLayer* new_layer = new KRAnimationLayer(getContext()); + new_layer->setName(layer->getName()); + new_layer->setRotationAccumulationMode(layer->getRotationAccumulationMode()); + new_layer->setScaleAccumulationMode(layer->getScaleAccumulationMode()); + new_layer->setWeight(layer->getWeight()); + new_animation->m_layers[new_layer->getName()] = new_layer; + for (std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { + KRAnimationAttribute* attribute = *attribute_itr; - bool include_attribute = true; - if(strip_unchanging_attributes) { - include_attribute = curve->valueChanges(start_time, duration) | - curve2->valueChanges(start_time, duration) | - curve3->valueChanges(start_time, duration); - } - - if(include_attribute) { - KRAnimationAttribute *new_attribute = new KRAnimationAttribute(getContext()); - KRAnimationCurve *new_curve = curve; - if(clone_curves) { - std::string new_curve_name = name + "_curve" + std::to_string(++new_curve_count); - new_curve = curve->split(new_curve_name, start_time, duration); - } - - new_attribute->setCurveName(new_curve->getName()); - new_attribute->setTargetAttribute(attribute->getTargetAttribute()); - new_attribute->setTargetName(attribute->getTargetName()); - new_layer->addAttribute(new_attribute); - } - } + // Updated Dec 9, 2013 by Peter to change the way that attributes are stripped. + // + // If we have been asked to strip_unchanging_attributes then we only want to strip those attributes that don't havechanges + // in any of their components (x, y, z). This means that we have to group the attributes before we check for valueChanges(). + // The attributes won't come through in order, but they do come through in group order (each group of 3 arrives as x, y, z) + // + // Since this method isn't designed to handle groups, this is a bit of a hack. We simply take whatever channel is coming + // through and then check the other associated curves. + // + int targetAttribute = attribute->getTargetAttribute(); + if (targetAttribute > 0) { // we have a valid target that fits within a group of 3 + targetAttribute--; // this is now group relative 0,1,2 is the first group .. 3,4,5 is the second group, etc. + + KRAnimationCurve* curve = attribute->getCurve(); // this is the curve we are currently handling + + int placeInGroup = targetAttribute % 3; // this will be 0, 1 or 2 + static long placeLookup[] = { 1, 2, -1, 1, -2, -1 }; + + KRAnimationAttribute* attribute2 = *(attribute_itr + placeLookup[placeInGroup * 2]); + KRAnimationAttribute* attribute3 = *(attribute_itr + placeLookup[placeInGroup * 2 + 1]); + KRAnimationCurve* curve2 = attribute2->getCurve(); + KRAnimationCurve* curve3 = attribute3->getCurve(); + + bool include_attribute = true; + if (strip_unchanging_attributes) { + include_attribute = curve->valueChanges(start_time, duration) | + curve2->valueChanges(start_time, duration) | + curve3->valueChanges(start_time, duration); } + + if (include_attribute) { + KRAnimationAttribute* new_attribute = new KRAnimationAttribute(getContext()); + KRAnimationCurve* new_curve = curve; + if (clone_curves) { + std::string new_curve_name = name + "_curve" + std::to_string(++new_curve_count); + new_curve = curve->split(new_curve_name, start_time, duration); + } + + new_attribute->setCurveName(new_curve->getName()); + new_attribute->setTargetAttribute(attribute->getTargetAttribute()); + new_attribute->setTargetName(attribute->getTargetName()); + new_layer->addAttribute(new_attribute); + } + } } - - getContext().getAnimationManager()->addAnimation(new_animation); - return new_animation; + } + + getContext().getAnimationManager()->addAnimation(new_animation); + return new_animation; } void KRAnimation::deleteCurves() { - for(unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { - KRAnimationLayer *layer = (*layer_itr).second; - for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { - KRAnimationAttribute *attribute = *attribute_itr; - attribute->deleteCurve(); - } + for (unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { + KRAnimationLayer* layer = (*layer_itr).second; + for (std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { + KRAnimationAttribute* attribute = *attribute_itr; + attribute->deleteCurve(); } + } } void KRAnimation::_lockData() { - for(unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { - KRAnimationLayer *layer = (*layer_itr).second; - for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { - KRAnimationAttribute *attribute = *attribute_itr; - KRAnimationCurve *curve = attribute->getCurve(); - if(curve) { - curve->_lockData(); - } - } + for (unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { + KRAnimationLayer* layer = (*layer_itr).second; + for (std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { + KRAnimationAttribute* attribute = *attribute_itr; + KRAnimationCurve* curve = attribute->getCurve(); + if (curve) { + curve->_lockData(); + } } + } } void KRAnimation::_unlockData() { - for(unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { - KRAnimationLayer *layer = (*layer_itr).second; - for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { - KRAnimationAttribute *attribute = *attribute_itr; - KRAnimationCurve *curve = attribute->getCurve(); - if(curve) { - curve->_unlockData(); - } - } + for (unordered_map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { + KRAnimationLayer* layer = (*layer_itr).second; + for (std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { + KRAnimationAttribute* attribute = *attribute_itr; + KRAnimationCurve* curve = attribute->getCurve(); + if (curve) { + curve->_unlockData(); + } } + } } diff --git a/kraken/KRAnimation.h b/kraken/KRAnimation.h index 7fcb48e..448a63b 100755 --- a/kraken/KRAnimation.h +++ b/kraken/KRAnimation.h @@ -38,47 +38,48 @@ #include "KRAnimationLayer.h" -class KRAnimation : public KRResource { - +class KRAnimation : public KRResource +{ + public: - KRAnimation(KRContext &context, std::string name); - virtual ~KRAnimation(); - - virtual std::string getExtension(); - virtual bool save(KRDataBlock &data); - - static KRAnimation *Load(KRContext &context, const std::string &name, KRDataBlock *data); - - void addLayer(KRAnimationLayer *layer); - unordered_map &getLayers(); - KRAnimationLayer *getLayer(const char *szName); - bool getAutoPlay() const; - void setAutoPlay(bool auto_play); - bool getLooping() const; - void setLooping(bool looping); - void Play(); - void Stop(); - void update(float deltaTime); - float getTime(); - void setTime(float time); - float getDuration(); - void setDuration(float duration); - float getStartTime(); - void setStartTime(float start_time); - bool isPlaying(); - - KRAnimation *split(const std::string &name, float start_time, float duration, bool strip_unchanging_attributes = true, bool clone_curves = true); - void deleteCurves(); - - void _lockData(); - void _unlockData(); - + KRAnimation(KRContext& context, std::string name); + virtual ~KRAnimation(); + + virtual std::string getExtension(); + virtual bool save(KRDataBlock& data); + + static KRAnimation* Load(KRContext& context, const std::string& name, KRDataBlock* data); + + void addLayer(KRAnimationLayer* layer); + unordered_map& getLayers(); + KRAnimationLayer* getLayer(const char* szName); + bool getAutoPlay() const; + void setAutoPlay(bool auto_play); + bool getLooping() const; + void setLooping(bool looping); + void Play(); + void Stop(); + void update(float deltaTime); + float getTime(); + void setTime(float time); + float getDuration(); + void setDuration(float duration); + float getStartTime(); + void setStartTime(float start_time); + bool isPlaying(); + + KRAnimation* split(const std::string& name, float start_time, float duration, bool strip_unchanging_attributes = true, bool clone_curves = true); + void deleteCurves(); + + void _lockData(); + void _unlockData(); + private: - unordered_map m_layers; - bool m_auto_play; - bool m_loop; - bool m_playing; - float m_local_time; - float m_duration; - float m_start_time; + unordered_map m_layers; + bool m_auto_play; + bool m_loop; + bool m_playing; + float m_local_time; + float m_duration; + float m_start_time; }; diff --git a/kraken/KRAnimationAttribute.cpp b/kraken/KRAnimationAttribute.cpp index 13e038f..1bfef24 100755 --- a/kraken/KRAnimationAttribute.cpp +++ b/kraken/KRAnimationAttribute.cpp @@ -35,249 +35,249 @@ #include "KRAnimationCurveManager.h" -KRAnimationAttribute::KRAnimationAttribute(KRContext &context) : KRContextObject(context) +KRAnimationAttribute::KRAnimationAttribute(KRContext& context) : KRContextObject(context) { - m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; - m_target = NULL; - m_curve = NULL; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; + m_target = NULL; + m_curve = NULL; } KRAnimationAttribute::~KRAnimationAttribute() { - + } -tinyxml2::XMLElement *KRAnimationAttribute::saveXML( tinyxml2::XMLNode *parent) +tinyxml2::XMLElement* KRAnimationAttribute::saveXML(tinyxml2::XMLNode* parent) { - tinyxml2::XMLDocument *doc = parent->GetDocument(); - tinyxml2::XMLElement *e = doc->NewElement("attribute"); - parent->InsertEndChild(e); - e->SetAttribute("curve", m_curve_name.c_str()); - e->SetAttribute("target", m_target_name.c_str()); - const char *szAttribute = "none"; - switch(m_node_attribute) { - case KRNode::KRENGINE_NODE_ATTRIBUTE_NONE: - szAttribute = "none"; - break; - case KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X: - szAttribute = "translate_x"; - break; - case KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y: - szAttribute = "translate_y"; - break; - case KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z: - szAttribute = "translate_z"; - break; - case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_X: - szAttribute = "scale_x"; - break; - case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Y: - szAttribute = "scale_y"; - break; - case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z: - szAttribute = "scale_z"; - break; - case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_X: - szAttribute = "rotate_x"; - break; - case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Y: - szAttribute = "rotate_y"; - break; - 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; - case KRNode::KRENGINE_NODE_ATTRIBUTE_COUNT: - // Suppress warning - break; - } - - e->SetAttribute("attribute", szAttribute); - return e; + tinyxml2::XMLDocument* doc = parent->GetDocument(); + tinyxml2::XMLElement* e = doc->NewElement("attribute"); + parent->InsertEndChild(e); + e->SetAttribute("curve", m_curve_name.c_str()); + e->SetAttribute("target", m_target_name.c_str()); + const char* szAttribute = "none"; + switch (m_node_attribute) { + case KRNode::KRENGINE_NODE_ATTRIBUTE_NONE: + szAttribute = "none"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X: + szAttribute = "translate_x"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y: + szAttribute = "translate_y"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z: + szAttribute = "translate_z"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_X: + szAttribute = "scale_x"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Y: + szAttribute = "scale_y"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z: + szAttribute = "scale_z"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_X: + szAttribute = "rotate_x"; + break; + case KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Y: + szAttribute = "rotate_y"; + break; + 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; + case KRNode::KRENGINE_NODE_ATTRIBUTE_COUNT: + // Suppress warning + break; + } + + e->SetAttribute("attribute", szAttribute); + return e; } -void KRAnimationAttribute::loadXML(tinyxml2::XMLElement *e) +void KRAnimationAttribute::loadXML(tinyxml2::XMLElement* e) { - m_target = NULL; - m_curve = NULL; - m_curve_name = e->Attribute("curve"); - m_target_name = e->Attribute("target"); - + m_target = NULL; + m_curve = NULL; + m_curve_name = e->Attribute("curve"); + m_target_name = e->Attribute("target"); + + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; + + const char* szAttribute = e->Attribute("attribute"); + if (strcmp(szAttribute, "none") == 0) { m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; - - const char *szAttribute = e->Attribute("attribute"); - if(strcmp(szAttribute, "none") == 0) { - m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; - } else if(strcmp(szAttribute, "translate_x") == 0) { - m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X; - } else if(strcmp(szAttribute, "translate_y") == 0) { - m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y; - } else if(strcmp(szAttribute, "translate_z") == 0) { - m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z; - } else if(strcmp(szAttribute, "rotate_x") == 0) { - m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_X; - } else if(strcmp(szAttribute, "rotate_y") == 0) { - m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Y; - } else if(strcmp(szAttribute, "rotate_z") == 0) { - m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Z; - } else if(strcmp(szAttribute, "scale_x") == 0) { - m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_X; - } else if(strcmp(szAttribute, "scale_y") == 0) { - 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; - } + } else if (strcmp(szAttribute, "translate_x") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X; + } else if (strcmp(szAttribute, "translate_y") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y; + } else if (strcmp(szAttribute, "translate_z") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z; + } else if (strcmp(szAttribute, "rotate_x") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_X; + } else if (strcmp(szAttribute, "rotate_y") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Y; + } else if (strcmp(szAttribute, "rotate_z") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Z; + } else if (strcmp(szAttribute, "scale_x") == 0) { + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_X; + } else if (strcmp(szAttribute, "scale_y") == 0) { + 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; + } } KRNode::node_attribute_type KRAnimationAttribute::getTargetAttribute() const { - return m_node_attribute; + return m_node_attribute; } void KRAnimationAttribute::setTargetAttribute(KRNode::node_attribute_type target_attribute) { - m_node_attribute = target_attribute; + m_node_attribute = target_attribute; } std::string KRAnimationAttribute::getTargetName() const { - return m_target_name; + return m_target_name; } -void KRAnimationAttribute::setTargetName(const std::string &target_name) +void KRAnimationAttribute::setTargetName(const std::string& target_name) { - m_target_name = target_name; - m_target = NULL; + m_target_name = target_name; + m_target = NULL; } std::string KRAnimationAttribute::getCurveName() const { - return m_curve_name; + return m_curve_name; } -void KRAnimationAttribute::setCurveName(const std::string &curve_name) +void KRAnimationAttribute::setCurveName(const std::string& curve_name) { - m_curve_name = curve_name; - m_curve = NULL; + m_curve_name = curve_name; + m_curve = NULL; } -KRNode *KRAnimationAttribute::getTarget() +KRNode* KRAnimationAttribute::getTarget() { - if(m_target == NULL) { - m_target = getContext().getSceneManager()->getFirstScene()->getRootNode()->find(m_target_name); // FINDME, HACK! - This won't work with multiple scenes in a context; we should move the animations out of KRAnimationManager and attach them to the parent nodes of the animated KRNode's - } - if(m_target == NULL) { - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - Animation attribute could not find object: %s", m_target_name.c_str()); - } - return m_target; + if (m_target == NULL) { + m_target = getContext().getSceneManager()->getFirstScene()->getRootNode()->find(m_target_name); // FINDME, HACK! - This won't work with multiple scenes in a context; we should move the animations out of KRAnimationManager and attach them to the parent nodes of the animated KRNode's + } + if (m_target == NULL) { + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - Animation attribute could not find object: %s", m_target_name.c_str()); + } + return m_target; } -KRAnimationCurve *KRAnimationAttribute::getCurve() +KRAnimationCurve* KRAnimationAttribute::getCurve() { - if(m_curve == NULL) { - m_curve = getContext().getAnimationCurveManager()->getAnimationCurve(m_curve_name.c_str()); - } - return m_curve; + if (m_curve == NULL) { + m_curve = getContext().getAnimationCurveManager()->getAnimationCurve(m_curve_name.c_str()); + } + return m_curve; } void KRAnimationAttribute::deleteCurve() { - KRAnimationCurve *curve = getCurve(); - if(curve) { - getContext().getAnimationCurveManager()->deleteAnimationCurve(curve); - m_curve = NULL; - } + KRAnimationCurve* curve = getCurve(); + if (curve) { + getContext().getAnimationCurveManager()->deleteAnimationCurve(curve); + m_curve = NULL; + } } diff --git a/kraken/KRAnimationAttribute.h b/kraken/KRAnimationAttribute.h index eaa01e6..a8518c2 100755 --- a/kraken/KRAnimationAttribute.h +++ b/kraken/KRAnimationAttribute.h @@ -36,33 +36,34 @@ #include "KRNode.h" #include "KRAnimationCurve.h" -class KRAnimationAttribute : public KRContextObject { +class KRAnimationAttribute : public KRContextObject +{ public: - KRAnimationAttribute(KRContext &context); - ~KRAnimationAttribute(); - - tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - void loadXML(tinyxml2::XMLElement *e); - - std::string getCurveName() const; - void setCurveName(const std::string &curve_name); - - std::string getTargetName() const; - void setTargetName(const std::string &target_name); - - KRNode::node_attribute_type getTargetAttribute() const; - void setTargetAttribute(KRNode::node_attribute_type target_attribute); - - KRNode *getTarget(); - KRAnimationCurve *getCurve(); - - void deleteCurve(); - + KRAnimationAttribute(KRContext& context); + ~KRAnimationAttribute(); + + tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + void loadXML(tinyxml2::XMLElement* e); + + std::string getCurveName() const; + void setCurveName(const std::string& curve_name); + + std::string getTargetName() const; + void setTargetName(const std::string& target_name); + + KRNode::node_attribute_type getTargetAttribute() const; + void setTargetAttribute(KRNode::node_attribute_type target_attribute); + + KRNode* getTarget(); + KRAnimationCurve* getCurve(); + + void deleteCurve(); + private: - std::string m_target_name; - std::string m_curve_name; - KRNode::node_attribute_type m_node_attribute; - - KRNode *m_target; - KRAnimationCurve *m_curve; + std::string m_target_name; + std::string m_curve_name; + KRNode::node_attribute_type m_node_attribute; + + KRNode* m_target; + KRAnimationCurve* m_curve; }; diff --git a/kraken/KRAnimationCurve.cpp b/kraken/KRAnimationCurve.cpp index 4f8f28b..8c02522 100755 --- a/kraken/KRAnimationCurve.cpp +++ b/kraken/KRAnimationCurve.cpp @@ -33,208 +33,211 @@ #include "KRAnimationCurve.h" #include "KRDataBlock.h" -KRAnimationCurve::KRAnimationCurve(KRContext &context, const 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)); - m_pData->lock(); - animation_curve_header *header = (animation_curve_header *)m_pData->getStart(); - strcpy(header->szTag, "KRCURVE1.0 "); - header->frame_rate = 30.0f; - header->frame_start = 0; - header->frame_count = 0; - m_pData->unlock(); + m_pData = new KRDataBlock(); + m_pData->expand(sizeof(animation_curve_header)); + m_pData->lock(); + animation_curve_header* header = (animation_curve_header*)m_pData->getStart(); + strcpy(header->szTag, "KRCURVE1.0 "); + header->frame_rate = 30.0f; + header->frame_start = 0; + header->frame_count = 0; + m_pData->unlock(); } KRAnimationCurve::~KRAnimationCurve() { - m_pData->unload(); - delete m_pData; + m_pData->unload(); + delete m_pData; } -bool KRAnimationCurve::load(KRDataBlock *data) +bool KRAnimationCurve::load(KRDataBlock* data) { - m_pData->unload(); - delete m_pData; - m_pData = data; - return true; + m_pData->unload(); + delete m_pData; + m_pData = data; + return true; } -std::string KRAnimationCurve::getExtension() { - return "kranimationcurve"; -} - -bool KRAnimationCurve::save(const std::string& path) { - return m_pData->save(path); -} - -bool KRAnimationCurve::save(KRDataBlock &data) { - data.append(*m_pData); - return true; -} - -KRAnimationCurve *KRAnimationCurve::Load(KRContext &context, const std::string &name, KRDataBlock *data) +std::string KRAnimationCurve::getExtension() { - KRAnimationCurve *new_animation_curve = new KRAnimationCurve(context, name); - if(new_animation_curve->load(data)) { - return new_animation_curve; - } else { - delete new_animation_curve; - delete data; - return NULL; - } + return "kranimationcurve"; +} + +bool KRAnimationCurve::save(const std::string& path) +{ + return m_pData->save(path); +} + +bool KRAnimationCurve::save(KRDataBlock& data) +{ + data.append(*m_pData); + return true; +} + +KRAnimationCurve* KRAnimationCurve::Load(KRContext& context, const std::string& name, KRDataBlock* data) +{ + KRAnimationCurve* new_animation_curve = new KRAnimationCurve(context, name); + if (new_animation_curve->load(data)) { + return new_animation_curve; + } else { + delete new_animation_curve; + delete data; + return NULL; + } } int KRAnimationCurve::getFrameCount() { - m_pData->lock(); - int frame_count = ((animation_curve_header *)m_pData->getStart())->frame_count; - m_pData->unlock(); - - return frame_count; + m_pData->lock(); + int frame_count = ((animation_curve_header*)m_pData->getStart())->frame_count; + m_pData->unlock(); + + return frame_count; } void KRAnimationCurve::setFrameCount(int frame_count) { - m_pData->lock(); - int prev_frame_count = getFrameCount(); - if(frame_count != prev_frame_count) { - float fill_value = 0.0f; - if(prev_frame_count > 0) { - fill_value = getValue(prev_frame_count - 1); - } - m_pData->expand(sizeof(animation_curve_header) + sizeof(float) * frame_count - m_pData->getSize()); - float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header)); - for(int frame_number=prev_frame_count; frame_number < frame_count; frame_number++) { - frame_data[frame_number] = fill_value; - } - ((animation_curve_header *)m_pData->getStart())->frame_count = frame_count; + m_pData->lock(); + int prev_frame_count = getFrameCount(); + if (frame_count != prev_frame_count) { + float fill_value = 0.0f; + if (prev_frame_count > 0) { + fill_value = getValue(prev_frame_count - 1); } - m_pData->unlock(); + m_pData->expand(sizeof(animation_curve_header) + sizeof(float) * frame_count - m_pData->getSize()); + float* frame_data = (float*)((char*)m_pData->getStart() + sizeof(animation_curve_header)); + for (int frame_number = prev_frame_count; frame_number < frame_count; frame_number++) { + frame_data[frame_number] = fill_value; + } + ((animation_curve_header*)m_pData->getStart())->frame_count = frame_count; + } + m_pData->unlock(); } float KRAnimationCurve::getFrameRate() { - m_pData->lock(); - float frame_rate =((animation_curve_header *)m_pData->getStart())->frame_rate; - m_pData->unlock(); - return frame_rate; + m_pData->lock(); + float frame_rate = ((animation_curve_header*)m_pData->getStart())->frame_rate; + m_pData->unlock(); + return frame_rate; } void KRAnimationCurve::setFrameRate(float frame_rate) { - m_pData->lock(); - ((animation_curve_header *)m_pData->getStart())->frame_rate = frame_rate; - m_pData->unlock(); + m_pData->lock(); + ((animation_curve_header*)m_pData->getStart())->frame_rate = frame_rate; + m_pData->unlock(); } int KRAnimationCurve::getFrameStart() { - m_pData->lock(); - int frame_start = ((animation_curve_header *)m_pData->getStart())->frame_start; - m_pData->unlock(); - return frame_start; + m_pData->lock(); + int frame_start = ((animation_curve_header*)m_pData->getStart())->frame_start; + m_pData->unlock(); + return frame_start; } void KRAnimationCurve::setFrameStart(int frame_number) { - m_pData->lock(); - ((animation_curve_header *)m_pData->getStart())->frame_start = frame_number; - m_pData->unlock(); + m_pData->lock(); + ((animation_curve_header*)m_pData->getStart())->frame_start = frame_number; + m_pData->unlock(); } float KRAnimationCurve::getValue(int frame_number) { - m_pData->lock(); - //printf("frame_number: %i\n", frame_number); - int clamped_frame = frame_number - getFrameStart(); - if(clamped_frame < 0) { - clamped_frame = 0; - } else if(clamped_frame >= getFrameCount()) { - clamped_frame = getFrameCount()-1; - } - float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header)); - float v = frame_data[clamped_frame]; - m_pData->unlock(); - return v; + m_pData->lock(); + //printf("frame_number: %i\n", frame_number); + int clamped_frame = frame_number - getFrameStart(); + if (clamped_frame < 0) { + clamped_frame = 0; + } else if (clamped_frame >= getFrameCount()) { + clamped_frame = getFrameCount() - 1; + } + float* frame_data = (float*)((char*)m_pData->getStart() + sizeof(animation_curve_header)); + float v = frame_data[clamped_frame]; + m_pData->unlock(); + return v; } void KRAnimationCurve::setValue(int frame_number, float value) { - m_pData->lock(); - int clamped_frame = frame_number - getFrameStart(); - if(clamped_frame >= 0 && clamped_frame < getFrameCount()) { - float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header)); - frame_data[clamped_frame] = value; - } - m_pData->unlock(); + m_pData->lock(); + int clamped_frame = frame_number - getFrameStart(); + if (clamped_frame >= 0 && clamped_frame < getFrameCount()) { + float* frame_data = (float*)((char*)m_pData->getStart() + sizeof(animation_curve_header)); + frame_data[clamped_frame] = value; + } + m_pData->unlock(); } float KRAnimationCurve::getValue(float local_time) { - // TODO - Need to add interpolation for time values between frames. - // Must consider looping animations when determining which two frames to interpolate between. - m_pData->lock(); - float v = getValue((int)(local_time * getFrameRate())); - m_pData->unlock(); - return v; + // TODO - Need to add interpolation for time values between frames. + // Must consider looping animations when determining which two frames to interpolate between. + m_pData->lock(); + float v = getValue((int)(local_time * getFrameRate())); + m_pData->unlock(); + return v; } bool KRAnimationCurve::valueChanges(float start_time, float duration) { - m_pData->lock(); - bool c = valueChanges((int)(start_time * getFrameRate()), (int)(duration * getFrameRate())); - m_pData->unlock(); - return c; + m_pData->lock(); + bool c = valueChanges((int)(start_time * getFrameRate()), (int)(duration * getFrameRate())); + m_pData->unlock(); + return c; } bool KRAnimationCurve::valueChanges(int start_frame, int frame_count) { - m_pData->lock(); - float first_value = getValue(start_frame); - - bool change_found = false; - - // Range of frames is not inclusive of last frame - for(int frame_number = start_frame + 1; frame_number < start_frame + frame_count && !change_found; frame_number++) { - if(getValue(frame_number) != first_value) { - change_found = true; - } + m_pData->lock(); + float first_value = getValue(start_frame); + + bool change_found = false; + + // Range of frames is not inclusive of last frame + for (int frame_number = start_frame + 1; frame_number < start_frame + frame_count && !change_found; frame_number++) { + if (getValue(frame_number) != first_value) { + change_found = true; } - - m_pData->unlock(); - return change_found; + } + + m_pData->unlock(); + return change_found; } -KRAnimationCurve *KRAnimationCurve::split(const std::string &name, float start_time, float duration) +KRAnimationCurve* KRAnimationCurve::split(const std::string& name, float start_time, float duration) { - return split(name, (int)(start_time * getFrameRate()), (int)(duration * getFrameRate())); + return split(name, (int)(start_time * getFrameRate()), (int)(duration * getFrameRate())); } -KRAnimationCurve *KRAnimationCurve::split(const std::string &name, int start_frame, int frame_count) +KRAnimationCurve* KRAnimationCurve::split(const std::string& name, int start_frame, int frame_count) { - KRAnimationCurve *new_curve = new KRAnimationCurve(getContext(), name); - - new_curve->setFrameRate(getFrameRate()); - new_curve->setFrameStart(start_frame); - new_curve->setFrameCount(frame_count); - new_curve->m_pData->lock(); - - // Range of frames is not inclusive of last frame - for(int frame_number = start_frame; frame_number < start_frame + frame_count; frame_number++) { - new_curve->setValue(frame_number, getValue(frame_number)); // TODO - MEMCPY here? - } - new_curve->m_pData->unlock(); - - getContext().getAnimationCurveManager()->addAnimationCurve(new_curve); - return new_curve; + KRAnimationCurve* new_curve = new KRAnimationCurve(getContext(), name); + + new_curve->setFrameRate(getFrameRate()); + new_curve->setFrameStart(start_frame); + new_curve->setFrameCount(frame_count); + new_curve->m_pData->lock(); + + // Range of frames is not inclusive of last frame + for (int frame_number = start_frame; frame_number < start_frame + frame_count; frame_number++) { + new_curve->setValue(frame_number, getValue(frame_number)); // TODO - MEMCPY here? + } + new_curve->m_pData->unlock(); + + getContext().getAnimationCurveManager()->addAnimationCurve(new_curve); + return new_curve; } void KRAnimationCurve::_lockData() { - m_pData->lock(); + m_pData->lock(); } void KRAnimationCurve::_unlockData() { - m_pData->unlock(); + m_pData->unlock(); } diff --git a/kraken/KRAnimationCurve.h b/kraken/KRAnimationCurve.h index 90f771e..df5740d 100755 --- a/kraken/KRAnimationCurve.h +++ b/kraken/KRAnimationCurve.h @@ -36,48 +36,50 @@ #include "KRDataBlock.h" #include "KRResource.h" -class KRAnimationCurve : public KRResource { - +class KRAnimationCurve : public KRResource +{ + public: - KRAnimationCurve(KRContext &context, const std::string &name); - virtual ~KRAnimationCurve(); - - virtual std::string getExtension(); - virtual bool save(const std::string& path); - virtual bool save(KRDataBlock &data); - virtual bool load(KRDataBlock *data); - - float getFrameRate(); - void setFrameRate(float frame_rate); - int getFrameStart(); - void setFrameStart(int frame_number); - int getFrameCount(); - void setFrameCount(int frame_count); - float getValue(float local_time); - float getValue(int frame_number); - void setValue(int frame_number, float value); - - - static KRAnimationCurve *Load(KRContext &context, const std::string &name, KRDataBlock *data); - - bool valueChanges(float start_time, float duration); - bool valueChanges(int start_frame, int frame_count); - - KRAnimationCurve *split(const std::string &name, float start_time, float duration); - KRAnimationCurve *split(const std::string &name, int start_frame, int frame_count); - - void _lockData(); - void _unlockData(); - + KRAnimationCurve(KRContext& context, const std::string& name); + virtual ~KRAnimationCurve(); + + virtual std::string getExtension(); + virtual bool save(const std::string& path); + virtual bool save(KRDataBlock& data); + virtual bool load(KRDataBlock* data); + + float getFrameRate(); + void setFrameRate(float frame_rate); + int getFrameStart(); + void setFrameStart(int frame_number); + int getFrameCount(); + void setFrameCount(int frame_count); + float getValue(float local_time); + float getValue(int frame_number); + void setValue(int frame_number, float value); + + + static KRAnimationCurve* Load(KRContext& context, const std::string& name, KRDataBlock* data); + + bool valueChanges(float start_time, float duration); + bool valueChanges(int start_frame, int frame_count); + + KRAnimationCurve* split(const std::string& name, float start_time, float duration); + KRAnimationCurve* split(const std::string& name, int start_frame, int frame_count); + + void _lockData(); + void _unlockData(); + private: - KRDataBlock *m_pData; - - typedef struct { - char szTag[16]; - float frame_rate; - int32_t frame_start; - int32_t frame_count; - } animation_curve_header; + KRDataBlock* m_pData; + + typedef struct + { + char szTag[16]; + float frame_rate; + int32_t frame_start; + int32_t frame_count; + } animation_curve_header; }; diff --git a/kraken/KRAnimationCurveManager.cpp b/kraken/KRAnimationCurveManager.cpp index 6bc9c64..8434b7c 100755 --- a/kraken/KRAnimationCurveManager.cpp +++ b/kraken/KRAnimationCurveManager.cpp @@ -32,61 +32,66 @@ #include "KRAnimationCurveManager.h" #include "KRAnimationCurve.h" -KRAnimationCurveManager::KRAnimationCurveManager(KRContext &context) : KRResourceManager(context) +KRAnimationCurveManager::KRAnimationCurveManager(KRContext& context) : KRResourceManager(context) { - + } -KRAnimationCurveManager::~KRAnimationCurveManager() { - for(unordered_map::iterator itr = m_animationCurves.begin(); itr != m_animationCurves.end(); ++itr){ - delete (*itr).second; - } +KRAnimationCurveManager::~KRAnimationCurveManager() +{ + for (unordered_map::iterator itr = m_animationCurves.begin(); itr != m_animationCurves.end(); ++itr) { + delete (*itr).second; + } } -void KRAnimationCurveManager::deleteAnimationCurve(KRAnimationCurve *curve) { - m_animationCurves.erase(curve->getName()); - delete curve; +void KRAnimationCurveManager::deleteAnimationCurve(KRAnimationCurve* curve) +{ + m_animationCurves.erase(curve->getName()); + delete curve; } KRResource* KRAnimationCurveManager::loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) { - if (extension.compare("kranimationcurve") == 0) { - return loadAnimationCurve(name, data); - } - return nullptr; + if (extension.compare("kranimationcurve") == 0) { + return loadAnimationCurve(name, data); + } + return nullptr; } KRResource* KRAnimationCurveManager::getResource(const std::string& name, const std::string& extension) { - if (extension.compare("kranimationcurve") == 0) { - return getAnimationCurve(name); - } - return nullptr; + if (extension.compare("kranimationcurve") == 0) { + return getAnimationCurve(name); + } + return nullptr; } -KRAnimationCurve *KRAnimationCurveManager::loadAnimationCurve(const std::string &name, KRDataBlock *data) { - KRAnimationCurve *pAnimationCurve = KRAnimationCurve::Load(*m_pContext, name, data); - if(pAnimationCurve) { - m_animationCurves[name] = pAnimationCurve; - } - return pAnimationCurve; -} - -KRAnimationCurve *KRAnimationCurveManager::getAnimationCurve(const std::string &name) { - unordered_map::iterator itr = m_animationCurves.find(name); - if(itr == m_animationCurves.end()) { - return NULL; // Not found - } else { - return (*itr).second; - } -} - -unordered_map &KRAnimationCurveManager::getAnimationCurves() { - return m_animationCurves; -} - -void KRAnimationCurveManager::addAnimationCurve(KRAnimationCurve *new_animation_curve) +KRAnimationCurve* KRAnimationCurveManager::loadAnimationCurve(const std::string& name, KRDataBlock* data) { - assert(new_animation_curve != NULL); - m_animationCurves[new_animation_curve->getName()] = new_animation_curve; + KRAnimationCurve* pAnimationCurve = KRAnimationCurve::Load(*m_pContext, name, data); + if (pAnimationCurve) { + m_animationCurves[name] = pAnimationCurve; + } + return pAnimationCurve; +} + +KRAnimationCurve* KRAnimationCurveManager::getAnimationCurve(const std::string& name) +{ + unordered_map::iterator itr = m_animationCurves.find(name); + if (itr == m_animationCurves.end()) { + return NULL; // Not found + } else { + return (*itr).second; + } +} + +unordered_map& KRAnimationCurveManager::getAnimationCurves() +{ + return m_animationCurves; +} + +void KRAnimationCurveManager::addAnimationCurve(KRAnimationCurve* new_animation_curve) +{ + assert(new_animation_curve != NULL); + m_animationCurves[new_animation_curve->getName()] = new_animation_curve; } diff --git a/kraken/KRAnimationCurveManager.h b/kraken/KRAnimationCurveManager.h index 78cfb59..06b1214 100755 --- a/kraken/KRAnimationCurveManager.h +++ b/kraken/KRAnimationCurveManager.h @@ -41,22 +41,23 @@ using std::map; -class KRAnimationCurveManager : public KRResourceManager { +class KRAnimationCurveManager : public KRResourceManager +{ public: - KRAnimationCurveManager(KRContext &context); - virtual ~KRAnimationCurveManager(); + KRAnimationCurveManager(KRContext& context); + virtual ~KRAnimationCurveManager(); - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; + + KRAnimationCurve* loadAnimationCurve(const std::string& name, KRDataBlock* data); + KRAnimationCurve* getAnimationCurve(const std::string& name); + void addAnimationCurve(KRAnimationCurve* new_animation_curve); + unordered_map& getAnimationCurves(); + + void deleteAnimationCurve(KRAnimationCurve* curve); - KRAnimationCurve *loadAnimationCurve(const std::string &name, KRDataBlock *data); - KRAnimationCurve *getAnimationCurve(const std::string &name); - void addAnimationCurve(KRAnimationCurve *new_animation_curve); - unordered_map &getAnimationCurves(); - - void deleteAnimationCurve(KRAnimationCurve *curve); - private: - unordered_map m_animationCurves; + unordered_map m_animationCurves; }; diff --git a/kraken/KRAnimationLayer.cpp b/kraken/KRAnimationLayer.cpp index 1c77edb..77c514b 100755 --- a/kraken/KRAnimationLayer.cpp +++ b/kraken/KRAnimationLayer.cpp @@ -31,168 +31,168 @@ #include "KRAnimationLayer.h" -KRAnimationLayer::KRAnimationLayer(KRContext &context) : KRContextObject(context) +KRAnimationLayer::KRAnimationLayer(KRContext& context) : KRContextObject(context) { - m_name = ""; - m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE; - m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER; - m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY; + m_name = ""; + m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE; + m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER; + m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY; } KRAnimationLayer::~KRAnimationLayer() { - for(std::vector::iterator itr = m_attributes.begin(); itr != m_attributes.end(); ++itr){ - delete (*itr); - } + for (std::vector::iterator itr = m_attributes.begin(); itr != m_attributes.end(); ++itr) { + delete (*itr); + } } std::string KRAnimationLayer::getName() const { - return m_name; + return m_name; } -void KRAnimationLayer::setName(const std::string &name) +void KRAnimationLayer::setName(const std::string& name) { - m_name = name; + m_name = name; } -tinyxml2::XMLElement *KRAnimationLayer::saveXML( tinyxml2::XMLNode *parent) +tinyxml2::XMLElement* KRAnimationLayer::saveXML(tinyxml2::XMLNode* parent) { - tinyxml2::XMLDocument *doc = parent->GetDocument(); - tinyxml2::XMLElement *e = doc->NewElement("layer"); - tinyxml2::XMLNode *n = parent->InsertEndChild(e); - e->SetAttribute("name", m_name.c_str()); - e->SetAttribute("weight", m_weight); - - switch(m_blend_mode) { - case KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE: - e->SetAttribute("blend_mode", "additive"); - break; - case KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE: - e->SetAttribute("blend_mode", "override"); - break; - case KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH: - e->SetAttribute("blend_mode", "override_passthrough"); - break; - } - - switch(m_rotation_accumulation_mode) { - case KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL: - e->SetAttribute("rotation_accumulation_mode", "by_channel"); - break; - case KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER: - e->SetAttribute("rotation_accumulation_mode", "by_layer"); - break; - } - - switch(m_scale_accumulation_mode) { - case KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE: - e->SetAttribute("scale_accumulation_mode", "additive"); - break; - case KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY: - e->SetAttribute("scale_accumulation_mode", "multiply"); - break; - } - - for(std::vector::iterator itr = m_attributes.begin(); itr != m_attributes.end(); ++itr){ - (*itr)->saveXML(n); - } - - return e; + tinyxml2::XMLDocument* doc = parent->GetDocument(); + tinyxml2::XMLElement* e = doc->NewElement("layer"); + tinyxml2::XMLNode* n = parent->InsertEndChild(e); + e->SetAttribute("name", m_name.c_str()); + e->SetAttribute("weight", m_weight); + + switch (m_blend_mode) { + case KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE: + e->SetAttribute("blend_mode", "additive"); + break; + case KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE: + e->SetAttribute("blend_mode", "override"); + break; + case KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH: + e->SetAttribute("blend_mode", "override_passthrough"); + break; + } + + switch (m_rotation_accumulation_mode) { + case KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL: + e->SetAttribute("rotation_accumulation_mode", "by_channel"); + break; + case KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER: + e->SetAttribute("rotation_accumulation_mode", "by_layer"); + break; + } + + switch (m_scale_accumulation_mode) { + case KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE: + e->SetAttribute("scale_accumulation_mode", "additive"); + break; + case KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY: + e->SetAttribute("scale_accumulation_mode", "multiply"); + break; + } + + for (std::vector::iterator itr = m_attributes.begin(); itr != m_attributes.end(); ++itr) { + (*itr)->saveXML(n); + } + + return e; } -void KRAnimationLayer::loadXML(tinyxml2::XMLElement *e) +void KRAnimationLayer::loadXML(tinyxml2::XMLElement* e) { - m_name = e->Attribute("name"); - if(e->QueryFloatAttribute("weight", &m_weight) != tinyxml2::XML_SUCCESS) { - m_weight = 1.0f; // default - } - - const char *szBlendMode = e->Attribute("blend_mode"); - if(strcmp(szBlendMode, "additive") == 0) { - m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE; - } else if(strcmp(szBlendMode, "override") == 0) { - m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE; - } else if(strcmp(szBlendMode, "override_passthrough") == 0) { - m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH; - } else { - m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE; // default - } - - const char *szRotationAccumulationMode = e->Attribute("rotation_accumulation_mode"); - if(strcmp(szRotationAccumulationMode, "by_channel") == 0) { - m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL; - } else if(strcmp(szRotationAccumulationMode, "by_layer") == 0) { - m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER; - } else { - m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER; // default - } - - const char *szScaleAccumulationMode = e->Attribute("scale_accumulation_mode"); - if(strcmp(szScaleAccumulationMode, "additive") == 0) { - m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE; - } else if(strcmp(szScaleAccumulationMode, "multiply") == 0) { - m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY; - } else { - m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY; // default - } - - for(tinyxml2::XMLElement *child_element=e->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { - if(strcmp(child_element->Name(), "attribute") == 0) { - KRAnimationAttribute *new_attribute = new KRAnimationAttribute(getContext()); - new_attribute->loadXML(child_element); - m_attributes.push_back(new_attribute); - } + m_name = e->Attribute("name"); + if (e->QueryFloatAttribute("weight", &m_weight) != tinyxml2::XML_SUCCESS) { + m_weight = 1.0f; // default + } + + const char* szBlendMode = e->Attribute("blend_mode"); + if (strcmp(szBlendMode, "additive") == 0) { + m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE; + } else if (strcmp(szBlendMode, "override") == 0) { + m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE; + } else if (strcmp(szBlendMode, "override_passthrough") == 0) { + m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH; + } else { + m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE; // default + } + + const char* szRotationAccumulationMode = e->Attribute("rotation_accumulation_mode"); + if (strcmp(szRotationAccumulationMode, "by_channel") == 0) { + m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL; + } else if (strcmp(szRotationAccumulationMode, "by_layer") == 0) { + m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER; + } else { + m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER; // default + } + + const char* szScaleAccumulationMode = e->Attribute("scale_accumulation_mode"); + if (strcmp(szScaleAccumulationMode, "additive") == 0) { + m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE; + } else if (strcmp(szScaleAccumulationMode, "multiply") == 0) { + m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY; + } else { + m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY; // default + } + + for (tinyxml2::XMLElement* child_element = e->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { + if (strcmp(child_element->Name(), "attribute") == 0) { + KRAnimationAttribute* new_attribute = new KRAnimationAttribute(getContext()); + new_attribute->loadXML(child_element); + m_attributes.push_back(new_attribute); } + } } float KRAnimationLayer::getWeight() const { - return m_weight; + return m_weight; } void KRAnimationLayer::setWeight(float weight) { - m_weight = weight; + m_weight = weight; } KRAnimationLayer::blend_mode_t KRAnimationLayer::getBlendMode() const { - return m_blend_mode; + return m_blend_mode; } -void KRAnimationLayer::setBlendMode(const KRAnimationLayer::blend_mode_t &blend_mode) +void KRAnimationLayer::setBlendMode(const KRAnimationLayer::blend_mode_t& blend_mode) { - m_blend_mode = blend_mode; + m_blend_mode = blend_mode; } KRAnimationLayer::rotation_accumulation_mode_t KRAnimationLayer::getRotationAccumulationMode() const { - return m_rotation_accumulation_mode; + return m_rotation_accumulation_mode; } -void KRAnimationLayer::setRotationAccumulationMode(const KRAnimationLayer::rotation_accumulation_mode_t &rotation_accumulation_mode) +void KRAnimationLayer::setRotationAccumulationMode(const KRAnimationLayer::rotation_accumulation_mode_t& rotation_accumulation_mode) { - m_rotation_accumulation_mode = rotation_accumulation_mode; + m_rotation_accumulation_mode = rotation_accumulation_mode; } KRAnimationLayer::scale_accumulation_mode_t KRAnimationLayer::getScaleAccumulationMode() const { - return m_scale_accumulation_mode; + return m_scale_accumulation_mode; } -void KRAnimationLayer::setScaleAccumulationMode(const KRAnimationLayer::scale_accumulation_mode_t &scale_accumulation_mode) +void KRAnimationLayer::setScaleAccumulationMode(const KRAnimationLayer::scale_accumulation_mode_t& scale_accumulation_mode) { - m_scale_accumulation_mode = scale_accumulation_mode; + m_scale_accumulation_mode = scale_accumulation_mode; } -void KRAnimationLayer::addAttribute(KRAnimationAttribute *attribute) +void KRAnimationLayer::addAttribute(KRAnimationAttribute* attribute) { - m_attributes.push_back(attribute); + m_attributes.push_back(attribute); } -std::vector &KRAnimationLayer::getAttributes() +std::vector& KRAnimationLayer::getAttributes() { - return m_attributes; + return m_attributes; } diff --git a/kraken/KRAnimationLayer.h b/kraken/KRAnimationLayer.h index 9ae83e8..58b39bd 100755 --- a/kraken/KRAnimationLayer.h +++ b/kraken/KRAnimationLayer.h @@ -36,58 +36,62 @@ #include "KRAnimationAttribute.h" namespace tinyxml2 { - class XMLNode; - class XMLAttribute; +class XMLNode; +class XMLAttribute; } -class KRAnimationLayer : public KRContextObject { +class KRAnimationLayer : public KRContextObject +{ public: - KRAnimationLayer(KRContext &context); - ~KRAnimationLayer(); - - tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - void loadXML(tinyxml2::XMLElement *e); - - std::string getName() const; - void setName(const std::string &name); - - float getWeight() const; - void setWeight(float weight); - - typedef enum { - KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE, - KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE, - KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH - } blend_mode_t; - - blend_mode_t getBlendMode() const; - void setBlendMode(const blend_mode_t &blend_mode); - - typedef enum { - KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER, - KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL - } rotation_accumulation_mode_t; - - rotation_accumulation_mode_t getRotationAccumulationMode() const; - void setRotationAccumulationMode(const rotation_accumulation_mode_t &rotation_accumulation_mode); - - typedef enum { - KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY, - KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE - } scale_accumulation_mode_t; - - scale_accumulation_mode_t getScaleAccumulationMode() const; - void setScaleAccumulationMode(const scale_accumulation_mode_t &scale_accumulation_mode); + KRAnimationLayer(KRContext& context); + ~KRAnimationLayer(); + + tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + void loadXML(tinyxml2::XMLElement* e); + + std::string getName() const; + void setName(const std::string& name); + + float getWeight() const; + void setWeight(float weight); + + typedef enum + { + KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE, + KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE, + KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH + } blend_mode_t; + + blend_mode_t getBlendMode() const; + void setBlendMode(const blend_mode_t& blend_mode); + + typedef enum + { + KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER, + KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL + } rotation_accumulation_mode_t; + + rotation_accumulation_mode_t getRotationAccumulationMode() const; + void setRotationAccumulationMode(const rotation_accumulation_mode_t& rotation_accumulation_mode); + + typedef enum + { + KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY, + KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE + } scale_accumulation_mode_t; + + scale_accumulation_mode_t getScaleAccumulationMode() const; + void setScaleAccumulationMode(const scale_accumulation_mode_t& scale_accumulation_mode); + + void addAttribute(KRAnimationAttribute* attribute); + std::vector& getAttributes(); - void addAttribute(KRAnimationAttribute *attribute); - std::vector &getAttributes(); - private: - std::string m_name; - float m_weight; - blend_mode_t m_blend_mode; - rotation_accumulation_mode_t m_rotation_accumulation_mode; - scale_accumulation_mode_t m_scale_accumulation_mode; - - std::vector m_attributes; + std::string m_name; + float m_weight; + blend_mode_t m_blend_mode; + rotation_accumulation_mode_t m_rotation_accumulation_mode; + scale_accumulation_mode_t m_scale_accumulation_mode; + + std::vector m_attributes; }; diff --git a/kraken/KRAnimationManager.cpp b/kraken/KRAnimationManager.cpp index a7c2b7b..ca321e8 100755 --- a/kraken/KRAnimationManager.cpp +++ b/kraken/KRAnimationManager.cpp @@ -32,53 +32,54 @@ #include "KRAnimationManager.h" #include "KRAnimation.h" -KRAnimationManager::KRAnimationManager(KRContext &context) : KRResourceManager(context) +KRAnimationManager::KRAnimationManager(KRContext& context) : KRResourceManager(context) { } -KRAnimationManager::~KRAnimationManager() { - for(std::set::iterator itr = m_activeAnimations.begin(); itr != m_activeAnimations.end(); itr++) { - KRAnimation *animation = *itr; - animation->_unlockData(); - } - - for(unordered_map::iterator itr = m_animations.begin(); itr != m_animations.end(); ++itr){ - delete (*itr).second; - } +KRAnimationManager::~KRAnimationManager() +{ + for (std::set::iterator itr = m_activeAnimations.begin(); itr != m_activeAnimations.end(); itr++) { + KRAnimation* animation = *itr; + animation->_unlockData(); + } + + for (unordered_map::iterator itr = m_animations.begin(); itr != m_animations.end(); ++itr) { + delete (*itr).second; + } } void KRAnimationManager::startFrame(float deltaTime) { - for(std::set::iterator itr = m_animationsToUpdate.begin(); itr != m_animationsToUpdate.end(); itr++) { - KRAnimation *animation = *itr; - std::set::iterator active_animations_itr = m_activeAnimations.find(animation); - if(animation->isPlaying()) { - // Add playing animations to the active animations list - if(active_animations_itr == m_activeAnimations.end()) { - m_activeAnimations.insert(animation); - animation->_lockData(); - } - } else { - // Remove stopped animations from the active animations list - if(active_animations_itr != m_activeAnimations.end()) { - m_activeAnimations.erase(active_animations_itr); - animation->_unlockData(); - } - } - } - - m_animationsToUpdate.clear(); - - for(std::set::iterator active_animations_itr = m_activeAnimations.begin(); active_animations_itr != m_activeAnimations.end(); active_animations_itr++) { - KRAnimation *animation = *active_animations_itr; - animation->update(deltaTime); + for (std::set::iterator itr = m_animationsToUpdate.begin(); itr != m_animationsToUpdate.end(); itr++) { + KRAnimation* animation = *itr; + std::set::iterator active_animations_itr = m_activeAnimations.find(animation); + if (animation->isPlaying()) { + // Add playing animations to the active animations list + if (active_animations_itr == m_activeAnimations.end()) { + m_activeAnimations.insert(animation); + animation->_lockData(); + } + } else { + // Remove stopped animations from the active animations list + if (active_animations_itr != m_activeAnimations.end()) { + m_activeAnimations.erase(active_animations_itr); + animation->_unlockData(); + } } + } + + m_animationsToUpdate.clear(); + + for (std::set::iterator active_animations_itr = m_activeAnimations.begin(); active_animations_itr != m_activeAnimations.end(); active_animations_itr++) { + KRAnimation* animation = *active_animations_itr; + animation->update(deltaTime); + } } void KRAnimationManager::endFrame(float deltaTime) { - + } KRResource* KRAnimationManager::loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) @@ -96,37 +97,39 @@ KRResource* KRAnimationManager::getResource(const std::string& name, const std:: return nullptr; } -KRAnimation *KRAnimationManager::loadAnimation(const char *szName, KRDataBlock *data) { - KRAnimation *pAnimation = KRAnimation::Load(*m_pContext, szName, data); - addAnimation(pAnimation); - return pAnimation; -} - -KRAnimation *KRAnimationManager::getAnimation(const char *szName) { - return m_animations[szName]; -} - -unordered_map &KRAnimationManager::getAnimations() { - return m_animations; -} - -void KRAnimationManager::addAnimation(KRAnimation *new_animation) +KRAnimation* KRAnimationManager::loadAnimation(const char* szName, KRDataBlock* data) { - m_animations[new_animation->getName()] = new_animation; - updateActiveAnimations(new_animation); + KRAnimation* pAnimation = KRAnimation::Load(*m_pContext, szName, data); + addAnimation(pAnimation); + return pAnimation; } -void KRAnimationManager::updateActiveAnimations(KRAnimation *animation) +KRAnimation* KRAnimationManager::getAnimation(const char* szName) { - m_animationsToUpdate.insert(animation); + return m_animations[szName]; } -void KRAnimationManager::deleteAnimation(KRAnimation *animation, bool delete_curves) +unordered_map& KRAnimationManager::getAnimations() { - if(delete_curves) - { - animation->deleteCurves(); - } - m_animations.erase(animation->getName()); - delete animation; + return m_animations; +} + +void KRAnimationManager::addAnimation(KRAnimation* new_animation) +{ + m_animations[new_animation->getName()] = new_animation; + updateActiveAnimations(new_animation); +} + +void KRAnimationManager::updateActiveAnimations(KRAnimation* animation) +{ + m_animationsToUpdate.insert(animation); +} + +void KRAnimationManager::deleteAnimation(KRAnimation* animation, bool delete_curves) +{ + if (delete_curves) { + animation->deleteCurves(); + } + m_animations.erase(animation->getName()); + delete animation; } diff --git a/kraken/KRAnimationManager.h b/kraken/KRAnimationManager.h index 67f500b..e79b303 100755 --- a/kraken/KRAnimationManager.h +++ b/kraken/KRAnimationManager.h @@ -41,28 +41,29 @@ -class KRAnimationManager : public KRResourceManager { +class KRAnimationManager : public KRResourceManager +{ public: - KRAnimationManager(KRContext &context); - virtual ~KRAnimationManager(); + KRAnimationManager(KRContext& context); + virtual ~KRAnimationManager(); + + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; + + KRAnimation* loadAnimation(const char* szName, KRDataBlock* data); + KRAnimation* getAnimation(const char* szName); + void addAnimation(KRAnimation* new_animation); + unordered_map& getAnimations(); + void deleteAnimation(KRAnimation* animation, bool delete_curves); + + void startFrame(float deltaTime); + void endFrame(float deltaTime); + + void updateActiveAnimations(KRAnimation* animation); - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - - KRAnimation *loadAnimation(const char *szName, KRDataBlock *data); - KRAnimation *getAnimation(const char *szName); - void addAnimation(KRAnimation *new_animation); - unordered_map &getAnimations(); - void deleteAnimation(KRAnimation *animation, bool delete_curves); - - void startFrame(float deltaTime); - void endFrame(float deltaTime); - - void updateActiveAnimations(KRAnimation *animation); - private: - unordered_map m_animations; - set m_activeAnimations; - set m_animationsToUpdate; + unordered_map m_animations; + set m_activeAnimations; + set m_animationsToUpdate; }; diff --git a/kraken/KRAudioBuffer.cpp b/kraken/KRAudioBuffer.cpp index fbe21b0..46fa596 100755 --- a/kraken/KRAudioBuffer.cpp +++ b/kraken/KRAudioBuffer.cpp @@ -33,47 +33,47 @@ #include "KRAudioManager.h" -KRAudioBuffer::KRAudioBuffer(KRAudioManager *manager, KRAudioSample *sound, int index, int frameCount, int frameRate, int bytesPerFrame, void (*fn_populate)(KRAudioSample *, int, void *)) +KRAudioBuffer::KRAudioBuffer(KRAudioManager* manager, KRAudioSample* sound, int index, int frameCount, int frameRate, int bytesPerFrame, void (*fn_populate)(KRAudioSample*, int, void*)) { - m_pSoundManager = manager; - m_frameCount = frameCount; - m_frameRate = frameRate; - m_bytesPerFrame = bytesPerFrame; - m_pData = NULL; - m_audioSample = sound; - m_index = index; - - m_pSoundManager->makeCurrentContext(); - m_pData = m_pSoundManager->getBufferData(m_frameCount * m_bytesPerFrame); - fn_populate(sound, index, m_pData->getStart()); + m_pSoundManager = manager; + m_frameCount = frameCount; + m_frameRate = frameRate; + m_bytesPerFrame = bytesPerFrame; + m_pData = NULL; + m_audioSample = sound; + m_index = index; + + m_pSoundManager->makeCurrentContext(); + m_pData = m_pSoundManager->getBufferData(m_frameCount * m_bytesPerFrame); + fn_populate(sound, index, m_pData->getStart()); } KRAudioBuffer::~KRAudioBuffer() -{ - m_pSoundManager->recycleBufferData(m_pData); +{ + m_pSoundManager->recycleBufferData(m_pData); } -KRAudioSample *KRAudioBuffer::getAudioSample() +KRAudioSample* KRAudioBuffer::getAudioSample() { - return m_audioSample; + return m_audioSample; } int KRAudioBuffer::getFrameCount() { - return m_frameCount; + return m_frameCount; } int KRAudioBuffer::getFrameRate() { - return m_frameRate; + return m_frameRate; } -signed short *KRAudioBuffer::getFrameData() +signed short* KRAudioBuffer::getFrameData() { - return (signed short *)m_pData->getStart(); + return (signed short*)m_pData->getStart(); } int KRAudioBuffer::getIndex() { - return m_index; + return m_index; } \ No newline at end of file diff --git a/kraken/KRAudioBuffer.h b/kraken/KRAudioBuffer.h index 1f7afea..af7254b 100755 --- a/kraken/KRAudioBuffer.h +++ b/kraken/KRAudioBuffer.h @@ -40,23 +40,23 @@ class KRAudioSample; class KRAudioBuffer { public: - KRAudioBuffer(KRAudioManager *manager, KRAudioSample *sound, int index, int frameCount, int frameRate, int bytesPerFrame, void (*fn_populate)(KRAudioSample *, int, void *)); - ~KRAudioBuffer(); + KRAudioBuffer(KRAudioManager* manager, KRAudioSample* sound, int index, int frameCount, int frameRate, int bytesPerFrame, void (*fn_populate)(KRAudioSample*, int, void*)); + ~KRAudioBuffer(); - int getFrameCount(); - int getFrameRate(); - signed short *getFrameData(); + int getFrameCount(); + int getFrameRate(); + signed short* getFrameData(); - KRAudioSample *getAudioSample(); - int getIndex(); + KRAudioSample* getAudioSample(); + int getIndex(); private: - KRAudioManager *m_pSoundManager; + KRAudioManager* m_pSoundManager; - int m_index; - int m_frameCount; - int m_frameRate; - int m_bytesPerFrame; - KRDataBlock *m_pData; + int m_index; + int m_frameCount; + int m_frameRate; + int m_bytesPerFrame; + KRDataBlock* m_pData; - KRAudioSample *m_audioSample; + KRAudioSample* m_audioSample; }; diff --git a/kraken/KRAudioManager.cpp b/kraken/KRAudioManager.cpp index 55057fd..f138966 100755 --- a/kraken/KRAudioManager.cpp +++ b/kraken/KRAudioManager.cpp @@ -38,1106 +38,1106 @@ #include "KRCollider.h" #include "KRDSP.h" -KRAudioManager::KRAudioManager(KRContext &context) - : KRResourceManager(context) - , m_initialized(false) +KRAudioManager::KRAudioManager(KRContext& context) + : KRResourceManager(context) + , m_initialized(false) { - m_enable_audio = true; - m_enable_hrtf = true; - m_enable_reverb = true; - m_reverb_max_length = 8.0f; - - m_anticlick_block = true; -#ifdef __APPLE__ - mach_timebase_info(&m_timebase_info); -#endif - - m_high_quality_hrtf = false; - - m_listener_scene = NULL; - - m_global_gain = 0.20f; - m_global_reverb_send_level = 1.0f; - m_global_ambient_gain = 1.0f; - -#ifdef __APPLE__ - // Apple Core Audio - m_auGraph = NULL; - m_auMixer = NULL; -#endif - - m_audio_frame = 0; - - m_output_sample = 0; + m_enable_audio = true; + m_enable_hrtf = true; + m_enable_reverb = true; + m_reverb_max_length = 8.0f; - - m_reverb_input_samples = NULL; - m_reverb_input_next_sample = 0; - - m_workspace_data = NULL; - m_reverb_sequence = 0; - - m_hrtf_data = NULL; + m_anticlick_block = true; +#ifdef __APPLE__ + mach_timebase_info(&m_timebase_info); +#endif - for(int i=0; i < KRENGINE_MAX_REVERB_IMPULSE_MIX; i++) { - m_reverb_impulse_responses[i] = NULL; - m_reverb_impulse_responses_weight[i] = 0.0f; - } - m_output_accumulation = NULL; + m_high_quality_hrtf = false; + + m_listener_scene = NULL; + + m_global_gain = 0.20f; + m_global_reverb_send_level = 1.0f; + m_global_ambient_gain = 1.0f; + +#ifdef __APPLE__ + // Apple Core Audio + m_auGraph = NULL; + m_auMixer = NULL; +#endif + + m_audio_frame = 0; + + m_output_sample = 0; + + + m_reverb_input_samples = NULL; + m_reverb_input_next_sample = 0; + + m_workspace_data = NULL; + m_reverb_sequence = 0; + + m_hrtf_data = NULL; + + for (int i = 0; i < KRENGINE_MAX_REVERB_IMPULSE_MIX; i++) { + m_reverb_impulse_responses[i] = NULL; + m_reverb_impulse_responses_weight[i] = 0.0f; + } + m_output_accumulation = NULL; } -unordered_map &KRAudioManager::getSounds() +unordered_map& KRAudioManager::getSounds() { - return m_sounds; + return m_sounds; } bool KRAudioManager::getEnableAudio() { - return m_enable_audio; + return m_enable_audio; } void KRAudioManager::setEnableAudio(bool enable) { - m_enable_audio = enable; + m_enable_audio = enable; } bool KRAudioManager::getEnableHRTF() { - return m_enable_hrtf; + return m_enable_hrtf; } void KRAudioManager::setEnableHRTF(bool enable) { - m_enable_hrtf = enable; + m_enable_hrtf = enable; } bool KRAudioManager::getEnableReverb() { - return m_enable_reverb; + return m_enable_reverb; } float KRAudioManager::getReverbMaxLength() { - return m_reverb_max_length; + return m_reverb_max_length; } void KRAudioManager::setEnableReverb(bool enable) { - m_enable_reverb = enable; + m_enable_reverb = enable; } void KRAudioManager::setReverbMaxLength(float max_length) { - m_reverb_max_length = max_length; + m_reverb_max_length = max_length; } -KRScene *KRAudioManager::getListenerScene() +KRScene* KRAudioManager::getListenerScene() { - return m_listener_scene; + return m_listener_scene; } -void KRAudioManager::setListenerScene(KRScene *scene) +void KRAudioManager::setListenerScene(KRScene* scene) { - m_listener_scene = scene; + m_listener_scene = scene; } #ifdef __APPLE__ // Apple Core Audio -void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData) +void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList* ioData) { - // uint64_t start_time = mach_absolute_time(); - Float32 *outA = (Float32 *)ioData->mBuffers[0].mData; - Float32 *outB = (Float32 *)ioData->mBuffers[1].mData; // Non-Interleaved only - - int output_frame = 0; - - while(output_frame < inNumberFrames) { - int frames_ready = KRENGINE_AUDIO_BLOCK_LENGTH - m_output_sample; - if(frames_ready == 0) { - renderBlock(); - m_output_sample = 0; - frames_ready = KRENGINE_AUDIO_BLOCK_LENGTH; - } - - int frames_processed = inNumberFrames - output_frame; - if(frames_processed > frames_ready) frames_processed = frames_ready; - - float *block_data = getBlockAddress(0); - - for(int i=0; i < frames_processed; i++) { - - float left_channel = block_data[m_output_sample * KRENGINE_MAX_OUTPUT_CHANNELS]; - float right_channel = block_data[m_output_sample * KRENGINE_MAX_OUTPUT_CHANNELS + 1]; - m_output_sample++; - - // Interleaved - // outA[i*2] = (Float32)left_channel; - // outA[i*2 + 1] = (Float32)right_channel; - - // Non-Interleaved - outA[output_frame] = (Float32)left_channel; - outB[output_frame] = (Float32)right_channel; - output_frame++; - } + // uint64_t start_time = mach_absolute_time(); + Float32* outA = (Float32*)ioData->mBuffers[0].mData; + Float32* outB = (Float32*)ioData->mBuffers[1].mData; // Non-Interleaved only + + int output_frame = 0; + + while (output_frame < inNumberFrames) { + int frames_ready = KRENGINE_AUDIO_BLOCK_LENGTH - m_output_sample; + if (frames_ready == 0) { + renderBlock(); + m_output_sample = 0; + frames_ready = KRENGINE_AUDIO_BLOCK_LENGTH; } - -// uint64_t end_time = mach_absolute_time(); -// uint64_t duration = (end_time - start_time) * m_timebase_info.numer / m_timebase_info.denom; // Nanoseconds -// double ms = duration; -// ms = ms / 1000000.0; -// uint64_t max_duration = (uint64_t)inNumberFrames * 1000000000 / 44100; -// fprintf(stderr, "audio load: %5.1f%% hrtf channels: %li\n", (float)(duration * 1000 / max_duration) / 10.0f, m_mapped_sources.size()); -// printf("ms %2.3f frames %ld audio load: %5.1f%% hrtf channels: %li\n", ms, (unsigned long) inNumberFrames, (float)(duration * 1000 / max_duration) / 10.0f, m_mapped_sources.size()); + + int frames_processed = inNumberFrames - output_frame; + if (frames_processed > frames_ready) frames_processed = frames_ready; + + float* block_data = getBlockAddress(0); + + for (int i = 0; i < frames_processed; i++) { + + float left_channel = block_data[m_output_sample * KRENGINE_MAX_OUTPUT_CHANNELS]; + float right_channel = block_data[m_output_sample * KRENGINE_MAX_OUTPUT_CHANNELS + 1]; + m_output_sample++; + + // Interleaved + // outA[i*2] = (Float32)left_channel; + // outA[i*2 + 1] = (Float32)right_channel; + + // Non-Interleaved + outA[output_frame] = (Float32)left_channel; + outB[output_frame] = (Float32)right_channel; + output_frame++; + } + } + + // uint64_t end_time = mach_absolute_time(); + // uint64_t duration = (end_time - start_time) * m_timebase_info.numer / m_timebase_info.denom; // Nanoseconds + // double ms = duration; + // ms = ms / 1000000.0; + // uint64_t max_duration = (uint64_t)inNumberFrames * 1000000000 / 44100; + // fprintf(stderr, "audio load: %5.1f%% hrtf channels: %li\n", (float)(duration * 1000 / max_duration) / 10.0f, m_mapped_sources.size()); + // printf("ms %2.3f frames %ld audio load: %5.1f%% hrtf channels: %li\n", ms, (unsigned long) inNumberFrames, (float)(duration * 1000 / max_duration) / 10.0f, m_mapped_sources.size()); } #endif -float *KRAudioManager::getBlockAddress(int block_offset) +float* KRAudioManager::getBlockAddress(int block_offset) { - return m_output_accumulation + (m_output_accumulation_block_start + block_offset * KRENGINE_AUDIO_BLOCK_LENGTH * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + return m_output_accumulation + (m_output_accumulation_block_start + block_offset * KRENGINE_AUDIO_BLOCK_LENGTH * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); } void KRAudioManager::renderReverbImpulseResponse(int impulse_response_offset, int frame_count_log2) { - int frame_count = 1 << frame_count_log2; - int fft_size = frame_count * 2; - int fft_size_log2 = frame_count_log2 + 1; - - KRDSP::SplitComplex reverb_sample_data_complex = m_workspace[0]; - KRDSP::SplitComplex impulse_block_data_complex = m_workspace[1]; - KRDSP::SplitComplex conv_data_complex = m_workspace[2]; - - int reverb_offset = (m_reverb_input_next_sample + KRENGINE_AUDIO_BLOCK_LENGTH - frame_count); - if(reverb_offset < 0) { - reverb_offset += KRENGINE_REVERB_MAX_SAMPLES; - } else { - reverb_offset = reverb_offset % KRENGINE_REVERB_MAX_SAMPLES; - } - - int frames_left = frame_count; - while(frames_left) { - int frames_to_process = KRENGINE_REVERB_MAX_SAMPLES - reverb_offset; - if(frames_to_process > frames_left) frames_to_process = frames_left; - memcpy(reverb_sample_data_complex.realp + frame_count - frames_left, m_reverb_input_samples + reverb_offset, frames_to_process * sizeof(float)); - - frames_left -= frames_to_process; - reverb_offset = (reverb_offset + frames_to_process) % KRENGINE_REVERB_MAX_SAMPLES; - } - - memset(reverb_sample_data_complex.realp + frame_count, 0, frame_count * sizeof(float)); - memset(reverb_sample_data_complex.imagp, 0, fft_size * sizeof(float)); + int frame_count = 1 << frame_count_log2; + int fft_size = frame_count * 2; + int fft_size_log2 = frame_count_log2 + 1; - KRDSP::FFTForward(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], &reverb_sample_data_complex, fft_size_log2); - - float scale = 0.5f / fft_size; - - int impulse_response_channels = 2; - for(int channel=0; channel < impulse_response_channels; channel++) { - bool first_sample = true; - for(unordered_map::iterator zone_itr=m_reverb_zone_weights.begin(); zone_itr != m_reverb_zone_weights.end(); zone_itr++) { - siren_reverb_zone_weight_info zi = (*zone_itr).second; - if(zi.reverb_sample) { - if(impulse_response_offset < KRMIN(zi.reverb_sample->getFrameCount(), m_reverb_max_length * 44100)) { // Optimization - when mixing multiple impulse responses (i.e. fading between reverb zones), do not process blocks past the end of a shorter impulse response sample when they differ in length - if(first_sample) { - // If this is the first or only sample, write directly to the first half of the FFT input buffer - first_sample = false; - zi.reverb_sample->sample(impulse_response_offset, frame_count, channel, impulse_block_data_complex.realp, zi.weight, false); - } else { - // Subsequent samples write to the second half of the FFT input buffer, which is then added to the first half (the second half will be zero'ed out anyways and works as a convenient temporary buffer) - zi.reverb_sample->sample(impulse_response_offset, frame_count, channel, impulse_block_data_complex.realp + frame_count, zi.weight, false); - KRDSP::Accumulate(impulse_block_data_complex.realp, 1, impulse_block_data_complex.realp + frame_count, 1, frame_count); - } - } - - } - } - memset(impulse_block_data_complex.realp + frame_count, 0, frame_count * sizeof(float)); - memset(impulse_block_data_complex.imagp, 0, fft_size * sizeof(float)); - + KRDSP::SplitComplex reverb_sample_data_complex = m_workspace[0]; + KRDSP::SplitComplex impulse_block_data_complex = m_workspace[1]; + KRDSP::SplitComplex conv_data_complex = m_workspace[2]; - - KRDSP::FFTForward(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], &impulse_block_data_complex, fft_size_log2); - KRDSP::Multiply(&reverb_sample_data_complex, &impulse_block_data_complex, &conv_data_complex, fft_size); - KRDSP::FFTInverse(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], &conv_data_complex, fft_size_log2); - KRDSP::Scale(conv_data_complex.realp, scale, fft_size); - - - int output_offset = (m_output_accumulation_block_start + impulse_response_offset * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); - frames_left = fft_size; - while(frames_left) { - int frames_to_process = (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS - output_offset) / KRENGINE_MAX_OUTPUT_CHANNELS; - if(frames_to_process > frames_left) frames_to_process = frames_left; - KRDSP::Accumulate(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, - conv_data_complex.realp + fft_size - frames_left, 1, - frames_to_process); - frames_left -= frames_to_process; - output_offset = (output_offset + frames_to_process * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + int reverb_offset = (m_reverb_input_next_sample + KRENGINE_AUDIO_BLOCK_LENGTH - frame_count); + if (reverb_offset < 0) { + reverb_offset += KRENGINE_REVERB_MAX_SAMPLES; + } else { + reverb_offset = reverb_offset % KRENGINE_REVERB_MAX_SAMPLES; + } + + int frames_left = frame_count; + while (frames_left) { + int frames_to_process = KRENGINE_REVERB_MAX_SAMPLES - reverb_offset; + if (frames_to_process > frames_left) frames_to_process = frames_left; + memcpy(reverb_sample_data_complex.realp + frame_count - frames_left, m_reverb_input_samples + reverb_offset, frames_to_process * sizeof(float)); + + frames_left -= frames_to_process; + reverb_offset = (reverb_offset + frames_to_process) % KRENGINE_REVERB_MAX_SAMPLES; + } + + memset(reverb_sample_data_complex.realp + frame_count, 0, frame_count * sizeof(float)); + memset(reverb_sample_data_complex.imagp, 0, fft_size * sizeof(float)); + + KRDSP::FFTForward(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], &reverb_sample_data_complex, fft_size_log2); + + float scale = 0.5f / fft_size; + + int impulse_response_channels = 2; + for (int channel = 0; channel < impulse_response_channels; channel++) { + bool first_sample = true; + for (unordered_map::iterator zone_itr = m_reverb_zone_weights.begin(); zone_itr != m_reverb_zone_weights.end(); zone_itr++) { + siren_reverb_zone_weight_info zi = (*zone_itr).second; + if (zi.reverb_sample) { + if (impulse_response_offset < KRMIN(zi.reverb_sample->getFrameCount(), m_reverb_max_length * 44100)) { // Optimization - when mixing multiple impulse responses (i.e. fading between reverb zones), do not process blocks past the end of a shorter impulse response sample when they differ in length + if (first_sample) { + // If this is the first or only sample, write directly to the first half of the FFT input buffer + first_sample = false; + zi.reverb_sample->sample(impulse_response_offset, frame_count, channel, impulse_block_data_complex.realp, zi.weight, false); + } else { + // Subsequent samples write to the second half of the FFT input buffer, which is then added to the first half (the second half will be zero'ed out anyways and works as a convenient temporary buffer) + zi.reverb_sample->sample(impulse_response_offset, frame_count, channel, impulse_block_data_complex.realp + frame_count, zi.weight, false); + KRDSP::Accumulate(impulse_block_data_complex.realp, 1, impulse_block_data_complex.realp + frame_count, 1, frame_count); + } } + + } } + memset(impulse_block_data_complex.realp + frame_count, 0, frame_count * sizeof(float)); + memset(impulse_block_data_complex.imagp, 0, fft_size * sizeof(float)); + + + + KRDSP::FFTForward(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], &impulse_block_data_complex, fft_size_log2); + KRDSP::Multiply(&reverb_sample_data_complex, &impulse_block_data_complex, &conv_data_complex, fft_size); + KRDSP::FFTInverse(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], &conv_data_complex, fft_size_log2); + KRDSP::Scale(conv_data_complex.realp, scale, fft_size); + + + int output_offset = (m_output_accumulation_block_start + impulse_response_offset * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + frames_left = fft_size; + while (frames_left) { + int frames_to_process = (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS - output_offset) / KRENGINE_MAX_OUTPUT_CHANNELS; + if (frames_to_process > frames_left) frames_to_process = frames_left; + KRDSP::Accumulate(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, + conv_data_complex.realp + fft_size - frames_left, 1, + frames_to_process); + frames_left -= frames_to_process; + output_offset = (output_offset + frames_to_process * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + } + } } void KRAudioManager::renderReverb() { - float reverb_data[KRENGINE_AUDIO_BLOCK_LENGTH]; - - float *reverb_accum = m_reverb_input_samples + m_reverb_input_next_sample; - memset(reverb_accum, 0, sizeof(float) * KRENGINE_AUDIO_BLOCK_LENGTH); - - std::set active_sources = m_activeAudioSources; - - for(std::set::iterator itr=active_sources.begin(); itr != active_sources.end(); itr++) { - KRAudioSource *source = *itr; - if(&source->getScene() == m_listener_scene) { - float containment_factor = 0.0f; - - for(unordered_map::iterator zone_itr=m_reverb_zone_weights.begin(); zone_itr != m_reverb_zone_weights.end(); zone_itr++) { - siren_reverb_zone_weight_info zi = (*zone_itr).second; - float gain = zi.weight * zi.reverb_zone->getReverbGain() * zi.reverb_zone->getContainment(source->getWorldTranslation()); - if(gain > containment_factor) containment_factor = gain; - } - - - float reverb_send_level = m_global_reverb_send_level * m_global_gain * source->getReverb() * containment_factor; - if(reverb_send_level > 0.0f) { - source->sample(KRENGINE_AUDIO_BLOCK_LENGTH, 0, reverb_data, reverb_send_level); - KRDSP::Accumulate(reverb_accum, 1, reverb_data, 1, KRENGINE_AUDIO_BLOCK_LENGTH); - } - } - } - - // Apply impulse response reverb - // KRAudioSample *impulse_response = getContext().getAudioManager()->get("hrtf_kemar_H10e040a"); - - int impulse_response_blocks = 0; - for(unordered_map::iterator zone_itr=m_reverb_zone_weights.begin(); zone_itr != m_reverb_zone_weights.end(); zone_itr++) { + float reverb_data[KRENGINE_AUDIO_BLOCK_LENGTH]; + + float* reverb_accum = m_reverb_input_samples + m_reverb_input_next_sample; + memset(reverb_accum, 0, sizeof(float) * KRENGINE_AUDIO_BLOCK_LENGTH); + + std::set active_sources = m_activeAudioSources; + + for (std::set::iterator itr = active_sources.begin(); itr != active_sources.end(); itr++) { + KRAudioSource* source = *itr; + if (&source->getScene() == m_listener_scene) { + float containment_factor = 0.0f; + + for (unordered_map::iterator zone_itr = m_reverb_zone_weights.begin(); zone_itr != m_reverb_zone_weights.end(); zone_itr++) { siren_reverb_zone_weight_info zi = (*zone_itr).second; - if(zi.reverb_sample) { - int zone_sample_blocks = KRMIN((int)zi.reverb_sample->getFrameCount(), (int)(m_reverb_max_length * 44100.0f)) / KRENGINE_AUDIO_BLOCK_LENGTH + 1; - impulse_response_blocks = KRMAX(impulse_response_blocks, zone_sample_blocks); - } + float gain = zi.weight * zi.reverb_zone->getReverbGain() * zi.reverb_zone->getContainment(source->getWorldTranslation()); + if (gain > containment_factor) containment_factor = gain; + } + + + float reverb_send_level = m_global_reverb_send_level * m_global_gain * source->getReverb() * containment_factor; + if (reverb_send_level > 0.0f) { + source->sample(KRENGINE_AUDIO_BLOCK_LENGTH, 0, reverb_data, reverb_send_level); + KRDSP::Accumulate(reverb_accum, 1, reverb_data, 1, KRENGINE_AUDIO_BLOCK_LENGTH); + } } - -// KRAudioSample *impulse_response_sample = getContext().getAudioManager()->get("test_reverb"); - if(impulse_response_blocks) { -// int impulse_response_blocks = impulse_response_sample->getFrameCount() / KRENGINE_AUDIO_BLOCK_LENGTH + 1; - int period_log2 = 0; - int impulse_response_block=0; - int period_count = 0; - - while(impulse_response_block < impulse_response_blocks) { - int period = 1 << period_log2; - - if((m_reverb_sequence + period - period_count) % period == 0) { - renderReverbImpulseResponse(impulse_response_block * KRENGINE_AUDIO_BLOCK_LENGTH, KRENGINE_AUDIO_BLOCK_LOG2N + period_log2); - } - - impulse_response_block += period; - - period_count++; - if(period_count >= period) { - period_count = 0; - if(KRENGINE_AUDIO_BLOCK_LOG2N + period_log2 + 1 < KRENGINE_REVERB_MAX_FFT_LOG2) { // FFT Size is double the number of frames in the period - period_log2++; - } - } - } + } + + // Apply impulse response reverb + // KRAudioSample *impulse_response = getContext().getAudioManager()->get("hrtf_kemar_H10e040a"); + + int impulse_response_blocks = 0; + for (unordered_map::iterator zone_itr = m_reverb_zone_weights.begin(); zone_itr != m_reverb_zone_weights.end(); zone_itr++) { + siren_reverb_zone_weight_info zi = (*zone_itr).second; + if (zi.reverb_sample) { + int zone_sample_blocks = KRMIN((int)zi.reverb_sample->getFrameCount(), (int)(m_reverb_max_length * 44100.0f)) / KRENGINE_AUDIO_BLOCK_LENGTH + 1; + impulse_response_blocks = KRMAX(impulse_response_blocks, zone_sample_blocks); } - - m_reverb_sequence = (m_reverb_sequence + 1) % 0x1000000; - - // Rotate reverb buffer - m_reverb_input_next_sample = (m_reverb_input_next_sample + KRENGINE_AUDIO_BLOCK_LENGTH) % KRENGINE_REVERB_MAX_SAMPLES; + } + + // KRAudioSample *impulse_response_sample = getContext().getAudioManager()->get("test_reverb"); + if (impulse_response_blocks) { + // int impulse_response_blocks = impulse_response_sample->getFrameCount() / KRENGINE_AUDIO_BLOCK_LENGTH + 1; + int period_log2 = 0; + int impulse_response_block = 0; + int period_count = 0; + + while (impulse_response_block < impulse_response_blocks) { + int period = 1 << period_log2; + + if ((m_reverb_sequence + period - period_count) % period == 0) { + renderReverbImpulseResponse(impulse_response_block * KRENGINE_AUDIO_BLOCK_LENGTH, KRENGINE_AUDIO_BLOCK_LOG2N + period_log2); + } + + impulse_response_block += period; + + period_count++; + if (period_count >= period) { + period_count = 0; + if (KRENGINE_AUDIO_BLOCK_LOG2N + period_log2 + 1 < KRENGINE_REVERB_MAX_FFT_LOG2) { // FFT Size is double the number of frames in the period + period_log2++; + } + } + } + } + + m_reverb_sequence = (m_reverb_sequence + 1) % 0x1000000; + + // Rotate reverb buffer + m_reverb_input_next_sample = (m_reverb_input_next_sample + KRENGINE_AUDIO_BLOCK_LENGTH) % KRENGINE_REVERB_MAX_SAMPLES; } void KRAudioManager::renderBlock() { - m_mutex.lock(); - - // ----====---- Advance to next block in accumulation buffer ----====---- - - // Zero out block that was last used, so it will be ready for the next pass through the circular buffer - float *block_data = getBlockAddress(0); - memset(block_data, 0, KRENGINE_AUDIO_BLOCK_LENGTH * KRENGINE_MAX_OUTPUT_CHANNELS * sizeof(float)); - - // Advance to the next block, and wrap around - m_output_accumulation_block_start = (m_output_accumulation_block_start + KRENGINE_AUDIO_BLOCK_LENGTH * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); - - if(m_enable_audio) { - // ----====---- Render Direct / HRTF audio ----====---- - if(m_enable_hrtf) { - renderHRTF(); - } else { - renderITD(); - } - - // ----====---- Render Indirect / Reverb channel ----====---- - if(m_enable_reverb && m_reverb_max_length > 0.0f) { - renderReverb(); - } - - // ----====---- Render Ambient Sound ----====---- - renderAmbient(); - - // ----====---- Render Ambient Sound ----====---- - renderLimiter(); + m_mutex.lock(); + + // ----====---- Advance to next block in accumulation buffer ----====---- + + // Zero out block that was last used, so it will be ready for the next pass through the circular buffer + float* block_data = getBlockAddress(0); + memset(block_data, 0, KRENGINE_AUDIO_BLOCK_LENGTH * KRENGINE_MAX_OUTPUT_CHANNELS * sizeof(float)); + + // Advance to the next block, and wrap around + m_output_accumulation_block_start = (m_output_accumulation_block_start + KRENGINE_AUDIO_BLOCK_LENGTH * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + + if (m_enable_audio) { + // ----====---- Render Direct / HRTF audio ----====---- + if (m_enable_hrtf) { + renderHRTF(); + } else { + renderITD(); } - - // ----====---- Advance audio sources ----====---- - m_audio_frame += KRENGINE_AUDIO_BLOCK_LENGTH; - - std::set open_samples = m_openAudioSamples; - - for(auto itr=open_samples.begin(); itr != open_samples.end(); itr++) { - KRAudioSample *sample = *itr; - sample->_endFrame(); + + // ----====---- Render Indirect / Reverb channel ----====---- + if (m_enable_reverb && m_reverb_max_length > 0.0f) { + renderReverb(); } - - m_anticlick_block = false; - m_mutex.unlock(); + + // ----====---- Render Ambient Sound ----====---- + renderAmbient(); + + // ----====---- Render Ambient Sound ----====---- + renderLimiter(); + } + + // ----====---- Advance audio sources ----====---- + m_audio_frame += KRENGINE_AUDIO_BLOCK_LENGTH; + + std::set open_samples = m_openAudioSamples; + + for (auto itr = open_samples.begin(); itr != open_samples.end(); itr++) { + KRAudioSample* sample = *itr; + sample->_endFrame(); + } + + m_anticlick_block = false; + m_mutex.unlock(); } #ifdef __APPLE__ // Apple Core Audio // audio render procedure, don't allocate memory, don't take any locks, don't waste time -OSStatus KRAudioManager::renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) +OSStatus KRAudioManager::renderInput(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData) { - ((KRAudioManager*)inRefCon)->renderAudio(inNumberFrames, ioData); - return noErr; + ((KRAudioManager*)inRefCon)->renderAudio(inNumberFrames, ioData); + return noErr; } -void KRSetAUCanonical(AudioStreamBasicDescription &desc, UInt32 nChannels, bool interleaved) +void KRSetAUCanonical(AudioStreamBasicDescription& desc, UInt32 nChannels, bool interleaved) { - desc.mFormatID = kAudioFormatLinearPCM; - desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; - desc.mChannelsPerFrame = nChannels; - desc.mFramesPerPacket = 1; - desc.mBitsPerChannel = 8 * sizeof(Float32); - if (interleaved) - desc.mBytesPerPacket = desc.mBytesPerFrame = nChannels * sizeof(Float32); - else { - desc.mBytesPerPacket = desc.mBytesPerFrame = sizeof(Float32); - desc.mFormatFlags |= kAudioFormatFlagIsNonInterleaved; - } + desc.mFormatID = kAudioFormatLinearPCM; + desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; + desc.mChannelsPerFrame = nChannels; + desc.mFramesPerPacket = 1; + desc.mBitsPerChannel = 8 * sizeof(Float32); + if (interleaved) + desc.mBytesPerPacket = desc.mBytesPerFrame = nChannels * sizeof(Float32); + else { + desc.mBytesPerPacket = desc.mBytesPerFrame = sizeof(Float32); + desc.mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } } #endif // Apple Core Audio void KRAudioManager::initHRTF() { - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,005.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,010.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,015.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,020.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,025.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,030.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,035.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,040.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,045.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,050.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,055.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,060.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,065.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,070.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,075.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,080.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,085.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,095.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,100.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,105.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,110.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,115.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,125.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,130.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,135.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,140.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,145.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,150.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,155.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,160.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,165.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,170.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,175.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,005.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,010.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,015.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,020.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,025.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,030.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,035.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,040.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,045.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,050.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,055.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,060.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,065.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,070.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,075.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,080.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,085.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,095.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,100.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,105.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,110.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,115.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,125.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,130.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,135.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,140.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,145.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,150.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,155.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,160.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,165.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,170.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,175.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,006.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,012.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,018.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,024.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,030.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,036.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,042.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,048.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,054.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,060.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,066.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,072.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,078.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,084.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,096.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,102.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,108.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,114.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,126.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,132.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,138.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,144.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,150.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,156.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,162.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,168.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,174.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,006.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,013.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,019.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,026.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,032.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,039.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,045.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,051.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,058.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,064.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,071.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,077.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,084.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,096.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,103.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,109.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,116.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,122.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,129.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,135.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,141.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,148.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,154.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,161.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,167.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,174.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,005.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,010.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,015.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,020.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,025.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,030.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,035.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,040.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,045.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,050.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,055.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,060.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,065.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,070.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,075.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,080.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,085.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,095.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,100.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,105.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,110.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,115.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,125.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,130.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,135.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,140.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,145.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,150.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,155.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,160.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,165.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,170.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,175.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(0.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,005.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,010.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,015.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,020.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,025.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,030.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,035.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,040.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,045.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,050.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,055.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,060.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,065.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,070.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,075.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,080.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,085.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,095.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,100.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,105.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,110.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,115.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,125.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,130.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,135.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,140.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,145.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,150.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,155.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,160.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,165.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,170.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,175.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(10.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,005.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,010.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,015.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,020.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,025.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,030.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,035.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,040.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,045.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,050.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,055.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,060.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,065.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,070.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,075.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,080.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,085.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,095.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,100.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,105.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,110.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,115.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,125.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,130.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,135.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,140.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,145.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,150.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,155.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,160.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,165.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,170.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,175.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(20.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,006.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,012.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,018.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,024.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,030.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,036.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,042.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,048.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,054.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,060.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,066.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,072.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,078.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,084.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,096.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,102.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,108.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,114.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,126.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,132.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,138.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,144.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,150.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,156.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,162.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,168.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,174.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(30.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,006.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,013.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,019.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,026.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,032.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,039.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,045.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,051.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,058.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,064.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,071.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,077.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,084.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,096.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,103.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,109.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,116.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,122.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,129.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,135.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,141.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,148.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,154.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,161.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,167.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,174.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(40.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,008.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,016.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,024.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,032.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,040.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,048.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,056.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,064.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,072.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,080.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,088.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,096.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,104.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,112.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,128.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,136.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,144.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,152.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,160.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,168.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(50.0f,176.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,010.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,020.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,030.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,040.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,050.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,060.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,070.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,080.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,100.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,110.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,130.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,140.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,150.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,160.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,170.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(60.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,015.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,030.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,045.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,060.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,075.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,105.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,135.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,150.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,165.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(70.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(80.0f,000.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(80.0f,030.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(80.0f,060.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(80.0f,090.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(80.0f,120.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(80.0f,150.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(80.0f,180.0f)); - m_hrtf_sample_locations.push_back(Vector2::Create(90.0f,000.0f)); - - if(m_hrtf_data) { - delete m_hrtf_data; + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 005.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 010.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 015.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 020.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 025.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 030.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 035.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 040.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 045.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 050.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 055.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 060.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 065.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 070.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 075.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 080.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 085.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 095.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 100.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 105.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 110.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 115.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 125.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 130.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 135.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 140.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 145.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 150.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 155.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 160.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 165.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 170.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 175.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-10.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 005.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 010.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 015.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 020.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 025.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 030.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 035.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 040.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 045.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 050.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 055.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 060.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 065.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 070.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 075.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 080.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 085.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 095.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 100.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 105.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 110.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 115.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 125.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 130.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 135.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 140.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 145.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 150.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 155.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 160.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 165.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 170.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 175.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-20.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 006.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 012.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 018.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 024.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 030.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 036.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 042.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 048.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 054.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 060.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 066.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 072.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 078.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 084.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 096.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 102.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 108.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 114.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 126.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 132.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 138.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 144.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 150.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 156.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 162.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 168.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 174.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-30.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 006.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 013.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 019.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 026.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 032.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 039.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 045.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 051.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 058.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 064.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 071.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 077.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 084.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 096.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 103.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 109.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 116.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 122.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 129.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 135.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 141.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 148.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 154.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 161.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 167.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 174.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(-40.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 005.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 010.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 015.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 020.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 025.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 030.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 035.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 040.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 045.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 050.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 055.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 060.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 065.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 070.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 075.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 080.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 085.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 095.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 100.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 105.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 110.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 115.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 125.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 130.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 135.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 140.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 145.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 150.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 155.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 160.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 165.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 170.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 175.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(0.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 005.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 010.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 015.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 020.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 025.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 030.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 035.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 040.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 045.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 050.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 055.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 060.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 065.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 070.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 075.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 080.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 085.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 095.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 100.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 105.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 110.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 115.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 125.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 130.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 135.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 140.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 145.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 150.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 155.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 160.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 165.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 170.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 175.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(10.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 005.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 010.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 015.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 020.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 025.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 030.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 035.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 040.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 045.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 050.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 055.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 060.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 065.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 070.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 075.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 080.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 085.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 095.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 100.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 105.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 110.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 115.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 125.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 130.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 135.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 140.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 145.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 150.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 155.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 160.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 165.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 170.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 175.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(20.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 006.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 012.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 018.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 024.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 030.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 036.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 042.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 048.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 054.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 060.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 066.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 072.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 078.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 084.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 096.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 102.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 108.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 114.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 126.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 132.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 138.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 144.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 150.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 156.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 162.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 168.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 174.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(30.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 006.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 013.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 019.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 026.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 032.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 039.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 045.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 051.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 058.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 064.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 071.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 077.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 084.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 096.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 103.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 109.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 116.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 122.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 129.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 135.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 141.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 148.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 154.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 161.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 167.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 174.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(40.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 008.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 016.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 024.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 032.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 040.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 048.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 056.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 064.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 072.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 080.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 088.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 096.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 104.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 112.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 128.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 136.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 144.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 152.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 160.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 168.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(50.0f, 176.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 010.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 020.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 030.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 040.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 050.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 060.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 070.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 080.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 100.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 110.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 130.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 140.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 150.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 160.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 170.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(60.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 015.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 030.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 045.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 060.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 075.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 105.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 135.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 150.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 165.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(70.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(80.0f, 000.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(80.0f, 030.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(80.0f, 060.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(80.0f, 090.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(80.0f, 120.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(80.0f, 150.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(80.0f, 180.0f)); + m_hrtf_sample_locations.push_back(Vector2::Create(90.0f, 000.0f)); + + if (m_hrtf_data) { + delete m_hrtf_data; + } + m_hrtf_data = (float*)malloc(m_hrtf_sample_locations.size() * sizeof(float) * 128 * 4 * 2); + + for (int channel = 0; channel < 2; channel++) { + m_hrtf_spectral[channel].clear(); + } + + int sample_index = 0; + for (std::vector::iterator itr = m_hrtf_sample_locations.begin(); itr != m_hrtf_sample_locations.end(); itr++) { + Vector2 pos = *itr; + KRAudioSample* sample = getHRTFSample(pos); + for (int channel = 0; channel < 2; channel++) { + KRDSP::SplitComplex spectral; + spectral.realp = m_hrtf_data + sample_index * 1024 + channel * 512; + spectral.imagp = m_hrtf_data + sample_index * 1024 + channel * 512 + 256; + sample->sample(0, 128, channel, spectral.realp, 1.0f, false); + memset(spectral.realp + 128, 0, sizeof(float) * 128); + memset(spectral.imagp, 0, sizeof(float) * 256); + KRDSP::FFTForward(m_fft_setup[8 - KRENGINE_AUDIO_BLOCK_LOG2N], &spectral, 8); + m_hrtf_spectral[channel][pos] = spectral; } - m_hrtf_data = (float *)malloc(m_hrtf_sample_locations.size() * sizeof(float) * 128 * 4 * 2); - - for(int channel=0; channel < 2; channel++) { - m_hrtf_spectral[channel].clear(); - } - - int sample_index=0; - for(std::vector::iterator itr=m_hrtf_sample_locations.begin(); itr != m_hrtf_sample_locations.end(); itr++) { - Vector2 pos = *itr; - KRAudioSample *sample = getHRTFSample(pos); - for(int channel=0; channel < 2; channel++) { - KRDSP::SplitComplex spectral; - spectral.realp = m_hrtf_data + sample_index * 1024 + channel * 512; - spectral.imagp = m_hrtf_data + sample_index * 1024 + channel * 512 + 256; - sample->sample(0, 128, channel, spectral.realp, 1.0f, false); - memset(spectral.realp + 128, 0, sizeof(float) * 128); - memset(spectral.imagp, 0, sizeof(float) * 256); - KRDSP::FFTForward(m_fft_setup[8 - KRENGINE_AUDIO_BLOCK_LOG2N], &spectral, 8); - m_hrtf_spectral[channel][pos] = spectral; - } - sample_index++; - } - + sample_index++; + } + } -KRAudioSample *KRAudioManager::getHRTFSample(const Vector2 &hrtf_dir) +KRAudioSample* KRAudioManager::getHRTFSample(const Vector2& hrtf_dir) { - //hrtf_kemar_H-10e000a.wav - char szName[64]; - sprintf(szName, "hrtf_kemar_H%de%03da", int(hrtf_dir.x), abs(int(hrtf_dir.y))); - - return get(szName); + //hrtf_kemar_H-10e000a.wav + char szName[64]; + sprintf(szName, "hrtf_kemar_H%de%03da", int(hrtf_dir.x), abs(int(hrtf_dir.y))); + + return get(szName); } -KRDSP::SplitComplex KRAudioManager::getHRTFSpectral(const Vector2 &hrtf_dir, const int channel) +KRDSP::SplitComplex KRAudioManager::getHRTFSpectral(const Vector2& hrtf_dir, const int channel) { - Vector2 dir = hrtf_dir; - int sample_channel = channel; - if(dir.y < 0) { - dir.y = -dir.y; - sample_channel = (channel + 1) % 2; - } - return m_hrtf_spectral[sample_channel][dir]; + Vector2 dir = hrtf_dir; + int sample_channel = channel; + if (dir.y < 0) { + dir.y = -dir.y; + sample_channel = (channel + 1) % 2; + } + return m_hrtf_spectral[sample_channel][dir]; } -Vector2 KRAudioManager::getNearestHRTFSample(const Vector2 &dir) +Vector2 KRAudioManager::getNearestHRTFSample(const Vector2& dir) { - float elev_gran = 10.0f; + float elev_gran = 10.0f; - - Vector2 dir_deg = dir * (180.0f / (float)M_PI); - float elevation = floor(dir_deg.x / elev_gran + 0.5f) * elev_gran; - if(elevation < -40.0f) { - elevation = -40.0f; + + Vector2 dir_deg = dir * (180.0f / (float)M_PI); + float elevation = floor(dir_deg.x / elev_gran + 0.5f) * elev_gran; + if (elevation < -40.0f) { + elevation = -40.0f; + } + + Vector2 min_direction; + bool first = true; + float min_distance = 360.0f; + for (std::vector::iterator itr = m_hrtf_sample_locations.begin(); itr != m_hrtf_sample_locations.end(); itr++) { + if (first) { + first = false; + min_direction = (*itr); + } else if ((*itr).x == elevation) { + float distance = fabs(dir_deg.y - (*itr).y); + if (min_distance > distance) { + min_direction = (*itr); + min_distance = distance; + } + distance = fabs(dir_deg.y - -(*itr).y); + if (min_distance > distance) { + min_direction = (*itr); + min_direction.y = -min_direction.y; + min_distance = distance; + } } - - Vector2 min_direction; - bool first = true; - float min_distance = 360.0f; - for(std::vector::iterator itr = m_hrtf_sample_locations.begin(); itr != m_hrtf_sample_locations.end(); itr++) { - if(first) { - first = false; - min_direction = (*itr); - } else if((*itr).x == elevation) { - float distance = fabs(dir_deg.y - (*itr).y); - if(min_distance > distance) { - min_direction = (*itr); - min_distance = distance; - } - distance = fabs(dir_deg.y - -(*itr).y); - if(min_distance > distance) { - min_direction = (*itr); - min_direction.y = -min_direction.y; - min_distance = distance; - } - } - } - return min_direction; + } + return min_direction; } -void KRAudioManager::getHRTFMix(const Vector2 &dir, Vector2 &dir1, Vector2 &dir2, Vector2 &dir3, Vector2 &dir4, float &mix1, float &mix2, float &mix3, float &mix4) +void KRAudioManager::getHRTFMix(const Vector2& dir, Vector2& dir1, Vector2& dir2, Vector2& dir3, Vector2& dir4, float& mix1, float& mix2, float& mix3, float& mix4) { - float elev_gran = 10.0f; - - float elevation = dir.x * 180.0f / (float)M_PI; - float azimuth = dir.y * 180.0f / (float)M_PI; - - float elev1 = floor(elevation / elev_gran) * elev_gran; - float elev2 = ceil(elevation / elev_gran) * elev_gran; - float elev_blend = (elevation - elev1) / elev_gran; - if(elev1 < -40.0f) { - elev1 = -40.0f; - elev2 = -40.0f; - elev_blend = 0.0f; - } - - dir1.x = elev1; - dir2.x = elev1; - dir3.x = elev2; - dir4.x = elev2; - - bool first1 = true; - bool first2 = true; - bool first3 = true; - bool first4 = true; - for(std::vector::iterator itr = m_hrtf_sample_locations.begin(); itr != m_hrtf_sample_locations.end(); itr++) { - Vector2 sample_pos = *itr; - - if(sample_pos.x == elev1) { - if(sample_pos.y <= azimuth) { - if(first1) { - first1 = false; - dir1.y = sample_pos.y; - } else if(sample_pos.y > dir1.y) { - dir1.y = sample_pos.y; - } - } - if(-sample_pos.y <= azimuth) { - if(first1) { - first1 = false; - dir1.y = -sample_pos.y; - } else if(-sample_pos.y > dir1.y) { - dir1.y = -sample_pos.y; - } - } + float elev_gran = 10.0f; - if(sample_pos.y > azimuth) { - if(first2) { - first2 = false; - dir2.y = sample_pos.y; - } else if(sample_pos.y < dir2.y) { - dir2.y = sample_pos.y; - } - } - if(-sample_pos.y > azimuth) { - if(first2) { - first2 = false; - dir2.y = -sample_pos.y; - } else if(-sample_pos.y < dir2.y) { - dir2.y = -sample_pos.y; - } - } + float elevation = dir.x * 180.0f / (float)M_PI; + float azimuth = dir.y * 180.0f / (float)M_PI; + + float elev1 = floor(elevation / elev_gran) * elev_gran; + float elev2 = ceil(elevation / elev_gran) * elev_gran; + float elev_blend = (elevation - elev1) / elev_gran; + if (elev1 < -40.0f) { + elev1 = -40.0f; + elev2 = -40.0f; + elev_blend = 0.0f; + } + + dir1.x = elev1; + dir2.x = elev1; + dir3.x = elev2; + dir4.x = elev2; + + bool first1 = true; + bool first2 = true; + bool first3 = true; + bool first4 = true; + for (std::vector::iterator itr = m_hrtf_sample_locations.begin(); itr != m_hrtf_sample_locations.end(); itr++) { + Vector2 sample_pos = *itr; + + if (sample_pos.x == elev1) { + if (sample_pos.y <= azimuth) { + if (first1) { + first1 = false; + dir1.y = sample_pos.y; + } else if (sample_pos.y > dir1.y) { + dir1.y = sample_pos.y; } - if(sample_pos.x == elev2) { - if(sample_pos.y <= azimuth) { - if(first3) { - first3 = false; - dir3.y = sample_pos.y; - } else if(sample_pos.y > dir3.y) { - dir3.y = sample_pos.y; - } - } - if(-sample_pos.y <= azimuth) { - if(first3) { - first3 = false; - dir3.y = -sample_pos.y; - } else if(-sample_pos.y > dir3.y) { - dir3.y = -sample_pos.y; - } - } - - if(sample_pos.y > azimuth) { - if(first4) { - first4 = false; - dir4.y = sample_pos.y; - } else if(sample_pos.y < dir4.y) { - dir4.y = sample_pos.y; - } - } - if(-sample_pos.y > azimuth) { - if(first4) { - first4 = false; - dir4.y = -sample_pos.y; - } else if(-sample_pos.y < dir4.y) { - dir4.y = -sample_pos.y; - } - } + } + if (-sample_pos.y <= azimuth) { + if (first1) { + first1 = false; + dir1.y = -sample_pos.y; + } else if (-sample_pos.y > dir1.y) { + dir1.y = -sample_pos.y; } + } + + if (sample_pos.y > azimuth) { + if (first2) { + first2 = false; + dir2.y = sample_pos.y; + } else if (sample_pos.y < dir2.y) { + dir2.y = sample_pos.y; + } + } + if (-sample_pos.y > azimuth) { + if (first2) { + first2 = false; + dir2.y = -sample_pos.y; + } else if (-sample_pos.y < dir2.y) { + dir2.y = -sample_pos.y; + } + } } - - - float azim_blend1 = 0.0f; - if(dir2.y > dir1.y) { - azim_blend1 = (azimuth - dir1.y) / (dir2.y - dir1.y); + if (sample_pos.x == elev2) { + if (sample_pos.y <= azimuth) { + if (first3) { + first3 = false; + dir3.y = sample_pos.y; + } else if (sample_pos.y > dir3.y) { + dir3.y = sample_pos.y; + } + } + if (-sample_pos.y <= azimuth) { + if (first3) { + first3 = false; + dir3.y = -sample_pos.y; + } else if (-sample_pos.y > dir3.y) { + dir3.y = -sample_pos.y; + } + } + + if (sample_pos.y > azimuth) { + if (first4) { + first4 = false; + dir4.y = sample_pos.y; + } else if (sample_pos.y < dir4.y) { + dir4.y = sample_pos.y; + } + } + if (-sample_pos.y > azimuth) { + if (first4) { + first4 = false; + dir4.y = -sample_pos.y; + } else if (-sample_pos.y < dir4.y) { + dir4.y = -sample_pos.y; + } + } } - - float azim_blend2 = 0.0f; - if(dir4.y > dir3.y) { - azim_blend2 = (azimuth - dir3.y) / (dir4.y - dir3.y); - } - - mix1 = (1.0f - azim_blend1) * (1.0f - elev_blend); - mix2 = azim_blend1 * (1.0f - elev_blend); - mix3 = (1.0f - azim_blend2) * elev_blend; - mix4 = azim_blend2 * elev_blend; + } + + + float azim_blend1 = 0.0f; + if (dir2.y > dir1.y) { + azim_blend1 = (azimuth - dir1.y) / (dir2.y - dir1.y); + } + + float azim_blend2 = 0.0f; + if (dir4.y > dir3.y) { + azim_blend2 = (azimuth - dir3.y) / (dir4.y - dir3.y); + } + + mix1 = (1.0f - azim_blend1) * (1.0f - elev_blend); + mix2 = azim_blend1 * (1.0f - elev_blend); + mix3 = (1.0f - azim_blend2) * elev_blend; + mix4 = azim_blend2 * elev_blend; } void KRAudioManager::initAudio() { - if(!m_initialized) { - m_initialized = true; - m_output_sample = KRENGINE_AUDIO_BLOCK_LENGTH; - - // initialize double-buffer for reverb input - int buffer_size = sizeof(float) * KRENGINE_REVERB_MAX_SAMPLES; // Reverb input is a single channel, circular buffered - m_reverb_input_samples = (float *)malloc(buffer_size); - memset(m_reverb_input_samples, 0, buffer_size); - m_reverb_input_next_sample = 0; - - m_output_accumulation = (float *)malloc(buffer_size * 2); // 2 channels - memset(m_output_accumulation, 0, buffer_size * 2); - m_output_accumulation_block_start = 0; - - m_workspace_data = (float *)malloc(KRENGINE_REVERB_WORKSPACE_SIZE * 6 * sizeof(float)); - m_workspace[0].realp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 0; - m_workspace[0].imagp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 1; - m_workspace[1].realp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 2; - m_workspace[1].imagp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 3; - m_workspace[2].realp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 4; - m_workspace[2].imagp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 5; - - m_reverb_sequence = 0; - for(int i=KRENGINE_AUDIO_BLOCK_LOG2N; i <= KRENGINE_REVERB_MAX_FFT_LOG2; i++) { - m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N].create(i); - // FINDME, TODO.. Apple's vDSP only needs one - // KRDSP::FFTWorkspace, initialized with the maximum size - } + if (!m_initialized) { + m_initialized = true; + m_output_sample = KRENGINE_AUDIO_BLOCK_LENGTH; - // ----====---- Initialize HRTF Engine ----====---- - initHRTF(); + // initialize double-buffer for reverb input + int buffer_size = sizeof(float) * KRENGINE_REVERB_MAX_SAMPLES; // Reverb input is a single channel, circular buffered + m_reverb_input_samples = (float*)malloc(buffer_size); + memset(m_reverb_input_samples, 0, buffer_size); + m_reverb_input_next_sample = 0; + + m_output_accumulation = (float*)malloc(buffer_size * 2); // 2 channels + memset(m_output_accumulation, 0, buffer_size * 2); + m_output_accumulation_block_start = 0; + + m_workspace_data = (float*)malloc(KRENGINE_REVERB_WORKSPACE_SIZE * 6 * sizeof(float)); + m_workspace[0].realp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 0; + m_workspace[0].imagp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 1; + m_workspace[1].realp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 2; + m_workspace[1].imagp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 3; + m_workspace[2].realp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 4; + m_workspace[2].imagp = m_workspace_data + KRENGINE_REVERB_WORKSPACE_SIZE * 5; + + m_reverb_sequence = 0; + for (int i = KRENGINE_AUDIO_BLOCK_LOG2N; i <= KRENGINE_REVERB_MAX_FFT_LOG2; i++) { + m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N].create(i); + // FINDME, TODO.. Apple's vDSP only needs one + // KRDSP::FFTWorkspace, initialized with the maximum size + } + + // ----====---- Initialize HRTF Engine ----====---- + initHRTF(); #ifdef __APPLE__ - // Apple Core Audio - // ----====---- Initialize Core Audio Objects ----====---- - OSDEBUG(NewAUGraph(&m_auGraph)); - - // ---- Create output node ---- - AudioComponentDescription output_desc; - output_desc.componentType = kAudioUnitType_Output; + // Apple Core Audio + // ----====---- Initialize Core Audio Objects ----====---- + OSDEBUG(NewAUGraph(&m_auGraph)); + + // ---- Create output node ---- + AudioComponentDescription output_desc; + output_desc.componentType = kAudioUnitType_Output; #if TARGET_OS_IPHONE - output_desc.componentSubType = kAudioUnitSubType_RemoteIO; + output_desc.componentSubType = kAudioUnitSubType_RemoteIO; #else - output_desc.componentSubType = kAudioUnitSubType_DefaultOutput; + output_desc.componentSubType = kAudioUnitSubType_DefaultOutput; #endif - output_desc.componentFlags = 0; - output_desc.componentFlagsMask = 0; - output_desc.componentManufacturer = kAudioUnitManufacturer_Apple; - AUNode outputNode = 0; - OSDEBUG(AUGraphAddNode(m_auGraph, &output_desc, &outputNode)); - - // ---- Create mixer node ---- - AudioComponentDescription mixer_desc; - mixer_desc.componentType = kAudioUnitType_Mixer; - mixer_desc.componentSubType = kAudioUnitSubType_MultiChannelMixer; - mixer_desc.componentFlags = 0; - mixer_desc.componentFlagsMask = 0; - mixer_desc.componentManufacturer = kAudioUnitManufacturer_Apple; - AUNode mixerNode = 0; - OSDEBUG(AUGraphAddNode(m_auGraph, &mixer_desc, &mixerNode )); - - // ---- Connect mixer to output node ---- - OSDEBUG(AUGraphConnectNodeInput(m_auGraph, mixerNode, 0, outputNode, 0)); - - // ---- Open the audio graph ---- - OSDEBUG(AUGraphOpen(m_auGraph)); - - // ---- Get a handle to the mixer ---- - OSDEBUG(AUGraphNodeInfo(m_auGraph, mixerNode, NULL, &m_auMixer)); - - // ---- Add output channel to mixer ---- - UInt32 bus_count = 1; - OSDEBUG(AudioUnitSetProperty(m_auMixer, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &bus_count, sizeof(bus_count))); - - // ---- Attach render function to channel ---- - AURenderCallbackStruct renderCallbackStruct; - renderCallbackStruct.inputProc = &renderInput; - renderCallbackStruct.inputProcRefCon = this; - OSDEBUG(AUGraphSetNodeInputCallback(m_auGraph, mixerNode, 0, &renderCallbackStruct)); // 0 = mixer input number - - AudioStreamBasicDescription desc; - memset(&desc, 0, sizeof(desc)); - - UInt32 size = sizeof(desc); - memset(&desc, 0, sizeof(desc)); - OSDEBUG(AudioUnitGetProperty( m_auMixer, - kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, - 0, // 0 = mixer input number - &desc, - &size)); + output_desc.componentFlags = 0; + output_desc.componentFlagsMask = 0; + output_desc.componentManufacturer = kAudioUnitManufacturer_Apple; + AUNode outputNode = 0; + OSDEBUG(AUGraphAddNode(m_auGraph, &output_desc, &outputNode)); - KRSetAUCanonical(desc, 2, false); - desc.mSampleRate = 44100.0f; + // ---- Create mixer node ---- + AudioComponentDescription mixer_desc; + mixer_desc.componentType = kAudioUnitType_Mixer; + mixer_desc.componentSubType = kAudioUnitSubType_MultiChannelMixer; + mixer_desc.componentFlags = 0; + mixer_desc.componentFlagsMask = 0; + mixer_desc.componentManufacturer = kAudioUnitManufacturer_Apple; + AUNode mixerNode = 0; + OSDEBUG(AUGraphAddNode(m_auGraph, &mixer_desc, &mixerNode)); - OSDEBUG(AudioUnitSetProperty(m_auMixer, - kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, - 0, // 0 == mixer input number - &desc, - sizeof(desc))); - - // ---- Apply properties to mixer output ---- - OSDEBUG(AudioUnitSetProperty(m_auMixer, - kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Output, - 0, // Always 0 for output bus - &desc, - sizeof(desc))); - - - memset(&desc, 0, sizeof(desc)); - size = sizeof(desc); - OSDEBUG(AudioUnitGetProperty(m_auMixer, - kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Output, - 0, - &desc, - &size)); - - // ---- - KRSetAUCanonical(desc, 2, false); - desc.mSampleRate = 44100.0f; + // ---- Connect mixer to output node ---- + OSDEBUG(AUGraphConnectNodeInput(m_auGraph, mixerNode, 0, outputNode, 0)); - - // ---- + // ---- Open the audio graph ---- + OSDEBUG(AUGraphOpen(m_auGraph)); - OSDEBUG(AudioUnitSetProperty(m_auMixer, - kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Output, - 0, - &desc, - sizeof(desc))); - - - OSDEBUG(AudioUnitSetParameter(m_auMixer, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, 0, 1.0, 0)); - OSDEBUG(AudioUnitSetParameter(m_auMixer, kMultiChannelMixerParam_Volume, kAudioUnitScope_Output, 0, 1.0, 0)); - - OSDEBUG(AUGraphInitialize(m_auGraph)); - - // ----====---- Start the audio system ----====---- - OSDEBUG(AUGraphStart(m_auGraph)); - -// CAShow(m_auGraph); + // ---- Get a handle to the mixer ---- + OSDEBUG(AUGraphNodeInfo(m_auGraph, mixerNode, NULL, &m_auMixer)); + + // ---- Add output channel to mixer ---- + UInt32 bus_count = 1; + OSDEBUG(AudioUnitSetProperty(m_auMixer, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &bus_count, sizeof(bus_count))); + + // ---- Attach render function to channel ---- + AURenderCallbackStruct renderCallbackStruct; + renderCallbackStruct.inputProc = &renderInput; + renderCallbackStruct.inputProcRefCon = this; + OSDEBUG(AUGraphSetNodeInputCallback(m_auGraph, mixerNode, 0, &renderCallbackStruct)); // 0 = mixer input number + + AudioStreamBasicDescription desc; + memset(&desc, 0, sizeof(desc)); + + UInt32 size = sizeof(desc); + memset(&desc, 0, sizeof(desc)); + OSDEBUG(AudioUnitGetProperty(m_auMixer, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, // 0 = mixer input number + &desc, + &size)); + + KRSetAUCanonical(desc, 2, false); + desc.mSampleRate = 44100.0f; + + OSDEBUG(AudioUnitSetProperty(m_auMixer, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, // 0 == mixer input number + &desc, + sizeof(desc))); + + // ---- Apply properties to mixer output ---- + OSDEBUG(AudioUnitSetProperty(m_auMixer, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 0, // Always 0 for output bus + &desc, + sizeof(desc))); + + + memset(&desc, 0, sizeof(desc)); + size = sizeof(desc); + OSDEBUG(AudioUnitGetProperty(m_auMixer, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 0, + &desc, + &size)); + + // ---- + KRSetAUCanonical(desc, 2, false); + desc.mSampleRate = 44100.0f; + + + // ---- + + OSDEBUG(AudioUnitSetProperty(m_auMixer, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 0, + &desc, + sizeof(desc))); + + + OSDEBUG(AudioUnitSetParameter(m_auMixer, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, 0, 1.0, 0)); + OSDEBUG(AudioUnitSetParameter(m_auMixer, kMultiChannelMixerParam_Volume, kAudioUnitScope_Output, 0, 1.0, 0)); + + OSDEBUG(AUGraphInitialize(m_auGraph)); + + // ----====---- Start the audio system ----====---- + OSDEBUG(AUGraphStart(m_auGraph)); + + // CAShow(m_auGraph); #endif // Core Audio - } + } } @@ -1145,42 +1145,42 @@ void KRAudioManager::cleanupAudio() { #ifdef __APPLE__ // Apple Core Audio - if(m_auGraph) { - OSDEBUG(AUGraphStop(m_auGraph)); - OSDEBUG(DisposeAUGraph(m_auGraph)); - m_auGraph = NULL; - m_auMixer = NULL; - } + if (m_auGraph) { + OSDEBUG(AUGraphStop(m_auGraph)); + OSDEBUG(DisposeAUGraph(m_auGraph)); + m_auGraph = NULL; + m_auMixer = NULL; + } #endif - - if(m_reverb_input_samples) { - free(m_reverb_input_samples); - m_reverb_input_samples = NULL; - } - - if(m_output_accumulation) { - free(m_output_accumulation); - m_output_accumulation = NULL; - } - - if(m_workspace_data) { - free(m_workspace_data); - m_workspace_data = NULL; - } - - if(m_hrtf_data) { - free(m_hrtf_data); - m_hrtf_data = NULL; - } - - for(int i=0; i < KRENGINE_MAX_REVERB_IMPULSE_MIX; i++) { - m_reverb_impulse_responses[i] = NULL; - m_reverb_impulse_responses_weight[i] = 0.0f; - } - - for(int i=KRENGINE_AUDIO_BLOCK_LOG2N; i <= KRENGINE_REVERB_MAX_FFT_LOG2; i++) { - m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N].destroy(); - } + + if (m_reverb_input_samples) { + free(m_reverb_input_samples); + m_reverb_input_samples = NULL; + } + + if (m_output_accumulation) { + free(m_output_accumulation); + m_output_accumulation = NULL; + } + + if (m_workspace_data) { + free(m_workspace_data); + m_workspace_data = NULL; + } + + if (m_hrtf_data) { + free(m_hrtf_data); + m_hrtf_data = NULL; + } + + for (int i = 0; i < KRENGINE_MAX_REVERB_IMPULSE_MIX; i++) { + m_reverb_impulse_responses[i] = NULL; + m_reverb_impulse_responses_weight[i] = 0.0f; + } + + for (int i = KRENGINE_AUDIO_BLOCK_LOG2N; i <= KRENGINE_REVERB_MAX_FFT_LOG2; i++) { + m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N].destroy(); + } } KRAudioManager::~KRAudioManager() @@ -1207,54 +1207,54 @@ void KRAudioManager::destroy() void KRAudioManager::makeCurrentContext() { - initAudio(); + initAudio(); } -void KRAudioManager::setListenerOrientationFromModelMatrix(const Matrix4 &modelMatrix) +void KRAudioManager::setListenerOrientationFromModelMatrix(const Matrix4& modelMatrix) { - setListenerOrientation( - Matrix4::Dot(modelMatrix, Vector3::Create(0.0, 0.0, 0.0)), - Vector3::Normalize(Matrix4::Dot(modelMatrix, Vector3::Create(0.0, 0.0, -1.0)) - m_listener_position), - Vector3::Normalize(Matrix4::Dot(modelMatrix, Vector3::Create(0.0, 1.0, 0.0)) - m_listener_position) - ); + setListenerOrientation( + Matrix4::Dot(modelMatrix, Vector3::Create(0.0, 0.0, 0.0)), + Vector3::Normalize(Matrix4::Dot(modelMatrix, Vector3::Create(0.0, 0.0, -1.0)) - m_listener_position), + Vector3::Normalize(Matrix4::Dot(modelMatrix, Vector3::Create(0.0, 1.0, 0.0)) - m_listener_position) + ); } -Vector3 &KRAudioManager::getListenerForward() +Vector3& KRAudioManager::getListenerForward() { - return m_listener_forward; + return m_listener_forward; } -Vector3 &KRAudioManager::getListenerPosition() +Vector3& KRAudioManager::getListenerPosition() { - return m_listener_position; + return m_listener_position; } -Vector3 &KRAudioManager::getListenerUp() +Vector3& KRAudioManager::getListenerUp() { - return m_listener_up; + return m_listener_up; } -void KRAudioManager::setListenerOrientation(const Vector3 &position, const Vector3 &forward, const Vector3 &up) +void KRAudioManager::setListenerOrientation(const Vector3& position, const Vector3& forward, const Vector3& up) { - m_listener_position = position; - m_listener_forward = forward; - m_listener_up = up; + m_listener_position = position; + m_listener_forward = forward; + m_listener_up = up; - makeCurrentContext(); + makeCurrentContext(); } -void KRAudioManager::add(KRAudioSample *sound) +void KRAudioManager::add(KRAudioSample* sound) { - std::string lower_name = sound->getName(); - std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); - - unordered_map::iterator name_itr = m_sounds.find(lower_name); - if(name_itr != m_sounds.end()) { - delete (*name_itr).second; - (*name_itr).second = sound; - } else { - m_sounds[lower_name] = sound; - } + std::string lower_name = sound->getName(); + std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); + + unordered_map::iterator name_itr = m_sounds.find(lower_name); + if (name_itr != m_sounds.end()) { + delete (*name_itr).second; + (*name_itr).second = sound; + } else { + m_sounds[lower_name] = sound; + } } KRResource* KRAudioManager::loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) @@ -1276,679 +1276,684 @@ KRResource* KRAudioManager::getResource(const std::string& name, const std::stri return nullptr; } -KRAudioSample *KRAudioManager::load(const std::string &name, const std::string &extension, KRDataBlock *data) +KRAudioSample* KRAudioManager::load(const std::string& name, const std::string& extension, KRDataBlock* data) { - KRAudioSample *Sound = new KRAudioSample(getContext(), name, extension, data); - if(Sound) add(Sound); - return Sound; + KRAudioSample* Sound = new KRAudioSample(getContext(), name, extension, data); + if (Sound) add(Sound); + return Sound; } -KRAudioSample *KRAudioManager::get(const std::string &name) +KRAudioSample* KRAudioManager::get(const std::string& name) { - std::string lower_name = name; - std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); - return m_sounds[lower_name]; + std::string lower_name = name; + std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); + return m_sounds[lower_name]; } -KRDataBlock *KRAudioManager::getBufferData(int size) +KRDataBlock* KRAudioManager::getBufferData(int size) { - KRDataBlock *data; - // Note: We only store and recycle buffers with a size of CIRCA_AUDIO_MAX_BUFFER_SIZE - if(size == KRENGINE_AUDIO_MAX_BUFFER_SIZE && m_bufferPoolIdle.size() > 0) { - // Recycle a buffer from the pool - data = m_bufferPoolIdle.back(); - m_bufferPoolIdle.pop_back(); + KRDataBlock* data; + // Note: We only store and recycle buffers with a size of CIRCA_AUDIO_MAX_BUFFER_SIZE + if (size == KRENGINE_AUDIO_MAX_BUFFER_SIZE && m_bufferPoolIdle.size() > 0) { + // Recycle a buffer from the pool + data = m_bufferPoolIdle.back(); + m_bufferPoolIdle.pop_back(); + } else { + data = new KRDataBlock(); + data->expand(size); + } + data->lock(); + return data; +} + +void KRAudioManager::recycleBufferData(KRDataBlock* data) +{ + if (data != NULL) { + data->unlock(); + if (data->getSize() == KRENGINE_AUDIO_MAX_BUFFER_SIZE && m_bufferPoolIdle.size() < KRENGINE_AUDIO_MAX_POOL_SIZE) { + m_bufferPoolIdle.push_back(data); } else { - data = new KRDataBlock(); - data->expand(size); + delete data; } - data->lock(); - return data; + } } -void KRAudioManager::recycleBufferData(KRDataBlock *data) +void KRAudioManager::activateAudioSource(KRAudioSource* audioSource) { - if(data != NULL) { - data->unlock(); - if(data->getSize() == KRENGINE_AUDIO_MAX_BUFFER_SIZE && m_bufferPoolIdle.size() < KRENGINE_AUDIO_MAX_POOL_SIZE) { - m_bufferPoolIdle.push_back(data); - } else { - delete data; - } - } + m_activeAudioSources.insert(audioSource); } -void KRAudioManager::activateAudioSource(KRAudioSource *audioSource) +void KRAudioManager::deactivateAudioSource(KRAudioSource* audioSource) { - m_activeAudioSources.insert(audioSource); + m_activeAudioSources.erase(audioSource); } -void KRAudioManager::deactivateAudioSource(KRAudioSource *audioSource) +void KRAudioManager::_registerOpenAudioSample(KRAudioSample* audioSample) { - m_activeAudioSources.erase(audioSource); + m_openAudioSamples.insert(audioSample); } -void KRAudioManager::_registerOpenAudioSample(KRAudioSample *audioSample) +void KRAudioManager::_registerCloseAudioSample(KRAudioSample* audioSample) { - m_openAudioSamples.insert(audioSample); -} - -void KRAudioManager::_registerCloseAudioSample(KRAudioSample *audioSample) -{ - m_openAudioSamples.erase(audioSample); + m_openAudioSamples.erase(audioSample); } __int64_t KRAudioManager::getAudioFrame() { - return m_audio_frame; + return m_audio_frame; } -KRAudioBuffer *KRAudioManager::getBuffer(KRAudioSample &audio_sample, int buffer_index) +KRAudioBuffer* KRAudioManager::getBuffer(KRAudioSample& audio_sample, int buffer_index) { - // ----====---- Try to find the buffer in the cache ----====---- - for(std::vector::iterator itr=m_bufferCache.begin(); itr != m_bufferCache.end(); itr++) { - KRAudioBuffer *cache_buffer = *itr; - if(cache_buffer->getAudioSample() == &audio_sample && cache_buffer->getIndex() == buffer_index) { - return cache_buffer; - } + // ----====---- Try to find the buffer in the cache ----====---- + for (std::vector::iterator itr = m_bufferCache.begin(); itr != m_bufferCache.end(); itr++) { + KRAudioBuffer* cache_buffer = *itr; + if (cache_buffer->getAudioSample() == &audio_sample && cache_buffer->getIndex() == buffer_index) { + return cache_buffer; } - - // ----====---- Make room in the cache for a new buffer ----====---- - if(m_bufferCache.size() >= KRENGINE_AUDIO_MAX_POOL_SIZE) { - // delete a random entry from the cache + } + + // ----====---- Make room in the cache for a new buffer ----====---- + if (m_bufferCache.size() >= KRENGINE_AUDIO_MAX_POOL_SIZE) { + // delete a random entry from the cache #ifdef __APPLE__ - int index_to_delete = arc4random() % m_bufferCache.size(); + int index_to_delete = arc4random() % m_bufferCache.size(); #else - int index_to_delete = rand() % m_bufferCache.size(); + int index_to_delete = rand() % m_bufferCache.size(); #endif - std::vector::iterator itr_to_delete = m_bufferCache.begin() + index_to_delete; - delete *itr_to_delete; - m_bufferCache.erase(itr_to_delete); - } - - // ----====---- Request new buffer, add to cache, and return it ----====---- - KRAudioBuffer *buffer = audio_sample.getBuffer(buffer_index); - m_bufferCache.push_back(buffer); - return buffer; + std::vector::iterator itr_to_delete = m_bufferCache.begin() + index_to_delete; + delete* itr_to_delete; + m_bufferCache.erase(itr_to_delete); + } + + // ----====---- Request new buffer, add to cache, and return it ----====---- + KRAudioBuffer* buffer = audio_sample.getBuffer(buffer_index); + m_bufferCache.push_back(buffer); + return buffer; } float KRAudioManager::getGlobalReverbSendLevel() { - return m_global_reverb_send_level; + return m_global_reverb_send_level; } void KRAudioManager::setGlobalReverbSendLevel(float send_level) { - m_global_reverb_send_level = send_level; + m_global_reverb_send_level = send_level; } float KRAudioManager::getGlobalGain() { - return m_global_gain; + return m_global_gain; } void KRAudioManager::setGlobalGain(float gain) { - m_global_gain = gain; + m_global_gain = gain; } float KRAudioManager::getGlobalAmbientGain() { - return m_global_ambient_gain; + return m_global_ambient_gain; } void KRAudioManager::setGlobalAmbientGain(float gain) { - m_global_ambient_gain = gain; + m_global_ambient_gain = gain; } void KRAudioManager::startFrame(float deltaTime) { - m_mutex.lock(); - - // ----====---- Determine Ambient Zone Contributions ----====---- - m_ambient_zone_weights.clear(); - m_ambient_zone_total_weight = 0.0f; // For normalizing zone weights - if(m_listener_scene) { - std::set ambient_zones = m_listener_scene->getAmbientZones(); - - for(std::set::iterator itr=ambient_zones.begin(); itr != ambient_zones.end(); itr++) { - KRAmbientZone *sphere = *itr; - siren_ambient_zone_weight_info zi; - - zi.weight = sphere->getContainment(m_listener_position); - if(zi.weight > 0.0f) { - if(m_ambient_zone_weights.find(sphere->getZone()) == m_ambient_zone_weights.end()) { - zi.ambient_zone = sphere; - zi.ambient_sample = get(sphere->getAmbient()); - m_ambient_zone_weights[sphere->getZone()] = zi; - m_ambient_zone_total_weight += zi.weight; - } else { - float prev_weight = m_ambient_zone_weights[sphere->getZone()].weight; - if(zi.weight > prev_weight) { - m_ambient_zone_total_weight -= prev_weight; - m_ambient_zone_weights[sphere->getZone()].weight = zi.weight; - m_ambient_zone_total_weight += zi.weight; - } - } - } - } - } - - // ----====---- Determine Reverb Zone Contributions ----====---- - m_reverb_zone_weights.clear(); - m_reverb_zone_total_weight = 0.0f; // For normalizing zone weights - if(m_listener_scene) { - std::set reverb_zones = m_listener_scene->getReverbZones(); - - for(std::set::iterator itr=reverb_zones.begin(); itr != reverb_zones.end(); itr++) { - KRReverbZone *sphere = *itr; - siren_reverb_zone_weight_info zi; - - zi.weight = sphere->getContainment(m_listener_position); - if(zi.weight > 0.0f) { - if(m_reverb_zone_weights.find(sphere->getZone()) == m_reverb_zone_weights.end()) { - zi.reverb_zone = sphere; - zi.reverb_sample = get(sphere->getReverb()); - m_reverb_zone_weights[sphere->getZone()] = zi; - m_reverb_zone_total_weight += zi.weight; - } else { - float prev_weight = m_reverb_zone_weights[sphere->getZone()].weight; - if(zi.weight > prev_weight) { - m_reverb_zone_total_weight -= prev_weight; - m_reverb_zone_weights[sphere->getZone()].weight = zi.weight; - m_reverb_zone_total_weight += zi.weight; - } - } - } - } - } - - - - // ----====---- Map Source Directions and Gains ----====---- - m_prev_mapped_sources.clear(); - m_mapped_sources.swap(m_prev_mapped_sources); - - Vector3 listener_right = Vector3::Cross(m_listener_forward, m_listener_up); - std::set active_sources = m_activeAudioSources; - - - for(std::set::iterator itr=active_sources.begin(); itr != active_sources.end(); itr++) { - KRAudioSource *source = *itr; - Vector3 source_world_position = source->getWorldTranslation(); - Vector3 diff = source_world_position - m_listener_position; - float distance = diff.magnitude(); - float gain = source->getGain() * m_global_gain / pow(KRMAX(distance / source->getReferenceDistance(), 1.0f), source->getRolloffFactor()); - - // apply minimum-cutoff so that we don't waste cycles processing very quiet / distant sound sources - gain = KRMAX(gain - KRENGINE_AUDIO_CUTOFF, 0.0f) / (1.0f - KRENGINE_AUDIO_CUTOFF); - - if(gain > 0.0f) { - - Vector3 source_listener_space = Vector3::Create( - Vector3::Dot(listener_right, diff), - Vector3::Dot(m_listener_up, diff), - Vector3::Dot(m_listener_forward, diff) - ); - - - Vector3 source_dir = Vector3::Normalize(source_listener_space); - - - - if(source->getEnableOcclusion() && /* FINDME!! DISABLES CODE */ (false)) { - HitInfo hitinfo; - if(source->getScene().lineCast(m_listener_position, source_world_position, hitinfo, KRAKEN_COLLIDER_AUDIO)) { - gain = 0.0f; - } - } - - Vector2 source_dir2 = Vector2::Normalize(Vector2::Create(source_dir.x, source_dir.z)); - float azimuth = -atan2(source_dir2.x, -source_dir2.y); - float elevation = atan( source_dir.y / sqrt(source_dir.x * source_dir.x + source_dir.z * source_dir.z)); - - Vector2 adjusted_source_dir = Vector2::Create(elevation, azimuth); - - if(!m_high_quality_hrtf) { - adjusted_source_dir = getNearestHRTFSample(adjusted_source_dir); - } - - // Click Removal - Add ramping of gain changes for audio sources that are continuing to play - float gain_anticlick = 0.0f; - std::pair > >::iterator, unordered_multimap > >::iterator> prev_range = m_prev_mapped_sources.equal_range(adjusted_source_dir); - for(unordered_multimap > >::iterator prev_itr=prev_range.first; prev_itr != prev_range.second; prev_itr++) { - if( (*prev_itr).second.first == source) { - gain_anticlick = (*prev_itr).second.second.second; - break; - } - } - - m_mapped_sources.insert(std::pair > >(adjusted_source_dir, std::pair >(source, std::pair(gain_anticlick, gain)))); - } - } - - // Click Removal - Map audio sources for ramp-down of gain for audio sources that have been squelched by attenuation - for(unordered_multimap > >::iterator itr=m_prev_mapped_sources.begin(); itr != m_prev_mapped_sources.end(); itr++) { + m_mutex.lock(); - KRAudioSource *source = (*itr).second.first; - float source_prev_gain = (*itr).second.second.second; - if(source->isPlaying() && source_prev_gain > 0.0f) { - // Only create ramp-down channels for 3d sources that have been squelched by attenuation; this is not necessary if the sample has completed playing - Vector2 source_position = (*itr).first; - - std::pair > >::iterator, unordered_multimap > >::iterator> new_range = m_mapped_sources.equal_range(source_position); - bool already_merged = false; - for(unordered_multimap > >::iterator new_itr=new_range.first; new_itr != new_range.second; new_itr++) { - if( (*new_itr).second.first == source) { - already_merged = true; - break; - } - } - if(!already_merged) { - - // source gain becomes anticlick gain and gain becomes 0 for anti-click ramp-down. - m_mapped_sources.insert(std::pair > >(source_position, std::pair >(source, std::pair(source_prev_gain, 0.0f)))); - } + // ----====---- Determine Ambient Zone Contributions ----====---- + m_ambient_zone_weights.clear(); + m_ambient_zone_total_weight = 0.0f; // For normalizing zone weights + if (m_listener_scene) { + std::set ambient_zones = m_listener_scene->getAmbientZones(); + + for (std::set::iterator itr = ambient_zones.begin(); itr != ambient_zones.end(); itr++) { + KRAmbientZone* sphere = *itr; + siren_ambient_zone_weight_info zi; + + zi.weight = sphere->getContainment(m_listener_position); + if (zi.weight > 0.0f) { + if (m_ambient_zone_weights.find(sphere->getZone()) == m_ambient_zone_weights.end()) { + zi.ambient_zone = sphere; + zi.ambient_sample = get(sphere->getAmbient()); + m_ambient_zone_weights[sphere->getZone()] = zi; + m_ambient_zone_total_weight += zi.weight; + } else { + float prev_weight = m_ambient_zone_weights[sphere->getZone()].weight; + if (zi.weight > prev_weight) { + m_ambient_zone_total_weight -= prev_weight; + m_ambient_zone_weights[sphere->getZone()].weight = zi.weight; + m_ambient_zone_total_weight += zi.weight; + } } + } } - - m_anticlick_block = true; - m_mutex.unlock(); + } + + // ----====---- Determine Reverb Zone Contributions ----====---- + m_reverb_zone_weights.clear(); + m_reverb_zone_total_weight = 0.0f; // For normalizing zone weights + if (m_listener_scene) { + std::set reverb_zones = m_listener_scene->getReverbZones(); + + for (std::set::iterator itr = reverb_zones.begin(); itr != reverb_zones.end(); itr++) { + KRReverbZone* sphere = *itr; + siren_reverb_zone_weight_info zi; + + zi.weight = sphere->getContainment(m_listener_position); + if (zi.weight > 0.0f) { + if (m_reverb_zone_weights.find(sphere->getZone()) == m_reverb_zone_weights.end()) { + zi.reverb_zone = sphere; + zi.reverb_sample = get(sphere->getReverb()); + m_reverb_zone_weights[sphere->getZone()] = zi; + m_reverb_zone_total_weight += zi.weight; + } else { + float prev_weight = m_reverb_zone_weights[sphere->getZone()].weight; + if (zi.weight > prev_weight) { + m_reverb_zone_total_weight -= prev_weight; + m_reverb_zone_weights[sphere->getZone()].weight = zi.weight; + m_reverb_zone_total_weight += zi.weight; + } + } + } + } + } + + + + // ----====---- Map Source Directions and Gains ----====---- + m_prev_mapped_sources.clear(); + m_mapped_sources.swap(m_prev_mapped_sources); + + Vector3 listener_right = Vector3::Cross(m_listener_forward, m_listener_up); + std::set active_sources = m_activeAudioSources; + + + for (std::set::iterator itr = active_sources.begin(); itr != active_sources.end(); itr++) { + KRAudioSource* source = *itr; + Vector3 source_world_position = source->getWorldTranslation(); + Vector3 diff = source_world_position - m_listener_position; + float distance = diff.magnitude(); + float gain = source->getGain() * m_global_gain / pow(KRMAX(distance / source->getReferenceDistance(), 1.0f), source->getRolloffFactor()); + + // apply minimum-cutoff so that we don't waste cycles processing very quiet / distant sound sources + gain = KRMAX(gain - KRENGINE_AUDIO_CUTOFF, 0.0f) / (1.0f - KRENGINE_AUDIO_CUTOFF); + + if (gain > 0.0f) { + + Vector3 source_listener_space = Vector3::Create( + Vector3::Dot(listener_right, diff), + Vector3::Dot(m_listener_up, diff), + Vector3::Dot(m_listener_forward, diff) + ); + + + Vector3 source_dir = Vector3::Normalize(source_listener_space); + + + + if (source->getEnableOcclusion() && /* FINDME!! DISABLES CODE */ (false)) { + HitInfo hitinfo; + if (source->getScene().lineCast(m_listener_position, source_world_position, hitinfo, KRAKEN_COLLIDER_AUDIO)) { + gain = 0.0f; + } + } + + Vector2 source_dir2 = Vector2::Normalize(Vector2::Create(source_dir.x, source_dir.z)); + float azimuth = -atan2(source_dir2.x, -source_dir2.y); + float elevation = atan(source_dir.y / sqrt(source_dir.x * source_dir.x + source_dir.z * source_dir.z)); + + Vector2 adjusted_source_dir = Vector2::Create(elevation, azimuth); + + if (!m_high_quality_hrtf) { + adjusted_source_dir = getNearestHRTFSample(adjusted_source_dir); + } + + // Click Removal - Add ramping of gain changes for audio sources that are continuing to play + float gain_anticlick = 0.0f; + std::pair > >::iterator, unordered_multimap > >::iterator> prev_range = m_prev_mapped_sources.equal_range(adjusted_source_dir); + for (unordered_multimap > >::iterator prev_itr = prev_range.first; prev_itr != prev_range.second; prev_itr++) { + if ((*prev_itr).second.first == source) { + gain_anticlick = (*prev_itr).second.second.second; + break; + } + } + + m_mapped_sources.insert(std::pair > >(adjusted_source_dir, std::pair >(source, std::pair(gain_anticlick, gain)))); + } + } + + // Click Removal - Map audio sources for ramp-down of gain for audio sources that have been squelched by attenuation + for (unordered_multimap > >::iterator itr = m_prev_mapped_sources.begin(); itr != m_prev_mapped_sources.end(); itr++) { + + KRAudioSource* source = (*itr).second.first; + float source_prev_gain = (*itr).second.second.second; + if (source->isPlaying() && source_prev_gain > 0.0f) { + // Only create ramp-down channels for 3d sources that have been squelched by attenuation; this is not necessary if the sample has completed playing + Vector2 source_position = (*itr).first; + + std::pair > >::iterator, unordered_multimap > >::iterator> new_range = m_mapped_sources.equal_range(source_position); + bool already_merged = false; + for (unordered_multimap > >::iterator new_itr = new_range.first; new_itr != new_range.second; new_itr++) { + if ((*new_itr).second.first == source) { + already_merged = true; + break; + } + } + if (!already_merged) { + + // source gain becomes anticlick gain and gain becomes 0 for anti-click ramp-down. + m_mapped_sources.insert(std::pair > >(source_position, std::pair >(source, std::pair(source_prev_gain, 0.0f)))); + } + } + } + + m_anticlick_block = true; + m_mutex.unlock(); } void KRAudioManager::renderAmbient() { - if(m_listener_scene) { + if (m_listener_scene) { - int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); - float *buffer = m_workspace[0].realp; - - for(unordered_map::iterator zone_itr=m_ambient_zone_weights.begin(); zone_itr != m_ambient_zone_weights.end(); zone_itr++) { - siren_ambient_zone_weight_info zi = (*zone_itr).second; - float gain = (*zone_itr).second.weight * zi.ambient_zone->getAmbientGain() * m_global_ambient_gain * m_global_gain; - - KRAudioSample *source_sample = zi.ambient_sample; - if(source_sample) { - for(int channel=0; channel < KRENGINE_MAX_OUTPUT_CHANNELS; channel++) { - source_sample->sample(getContext().getAudioManager()->getAudioFrame(), KRENGINE_AUDIO_BLOCK_LENGTH, channel, buffer, gain, true); - KRDSP::Accumulate(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, - buffer, 1, - KRENGINE_AUDIO_BLOCK_LENGTH); - } - } + int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + float* buffer = m_workspace[0].realp; + + for (unordered_map::iterator zone_itr = m_ambient_zone_weights.begin(); zone_itr != m_ambient_zone_weights.end(); zone_itr++) { + siren_ambient_zone_weight_info zi = (*zone_itr).second; + float gain = (*zone_itr).second.weight * zi.ambient_zone->getAmbientGain() * m_global_ambient_gain * m_global_gain; + + KRAudioSample* source_sample = zi.ambient_sample; + if (source_sample) { + for (int channel = 0; channel < KRENGINE_MAX_OUTPUT_CHANNELS; channel++) { + source_sample->sample(getContext().getAudioManager()->getAudioFrame(), KRENGINE_AUDIO_BLOCK_LENGTH, channel, buffer, gain, true); + KRDSP::Accumulate(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, + buffer, 1, + KRENGINE_AUDIO_BLOCK_LENGTH); } + } } + } } void KRAudioManager::renderHRTF() { - KRDSP::SplitComplex *hrtf_accum = m_workspace + 0; - KRDSP::SplitComplex *hrtf_impulse = m_workspace + 1; - KRDSP::SplitComplex *hrtf_convolved = m_workspace + 1; // We only need hrtf_impulse or hrtf_convolved at once; we can recycle the buffer - KRDSP::SplitComplex *hrtf_sample = m_workspace + 2; - - int impulse_response_channels = 2; - int hrtf_frames = 128; - int fft_size = 256; - int fft_size_log2 = 8; - - for(int channel=0; channel > >::iterator itr=m_mapped_sources.begin(); - while(itr != m_mapped_sources.end()) { - // Batch together sound sources that are emitted from the same direction - Vector2 source_direction = (*itr).first; - KRAudioSource *source = (*itr).second.first; - float gain_anticlick = (*itr).second.second.first; - float gain = (*itr).second.second.second; + KRDSP::SplitComplex* hrtf_accum = m_workspace + 0; + KRDSP::SplitComplex* hrtf_impulse = m_workspace + 1; + KRDSP::SplitComplex* hrtf_convolved = m_workspace + 1; // We only need hrtf_impulse or hrtf_convolved at once; we can recycle the buffer + KRDSP::SplitComplex* hrtf_sample = m_workspace + 2; - - // If this is the first or only sample, write directly to the first half of the FFT input buffer - // Subsequent samples write to the second half of the FFT input buffer, which is then added to the first half (the second half will be zero'ed out anyways and works as a convenient temporary buffer) - float *sample_buffer = first_source ? hrtf_sample->realp : hrtf_sample->realp + KRENGINE_AUDIO_BLOCK_LENGTH; - - if(gain != gain_anticlick && m_anticlick_block) { - // Sample and perform anti-click filtering - source->sample(KRENGINE_AUDIO_BLOCK_LENGTH, 0, sample_buffer, 1.0); - float ramp_gain = gain_anticlick; - float ramp_step = (gain - gain_anticlick) / KRENGINE_AUDIO_ANTICLICK_SAMPLES; - KRDSP::ScaleRamp(sample_buffer, ramp_gain, ramp_step, KRENGINE_AUDIO_ANTICLICK_SAMPLES); - if(KRENGINE_AUDIO_BLOCK_LENGTH > KRENGINE_AUDIO_ANTICLICK_SAMPLES) { - KRDSP::Scale(sample_buffer + KRENGINE_AUDIO_ANTICLICK_SAMPLES, gain, KRENGINE_AUDIO_BLOCK_LENGTH - KRENGINE_AUDIO_ANTICLICK_SAMPLES); - } - } else { - // Don't need to perform anti-click filtering, so just sample - source->sample(KRENGINE_AUDIO_BLOCK_LENGTH, 0, sample_buffer, gain); - } + int impulse_response_channels = 2; + int hrtf_frames = 128; + int fft_size = 256; + int fft_size_log2 = 8; - if(first_source) { - first_source = false; - } else { - // Accumulate samples on subsequent sources - KRDSP::Accumulate(hrtf_sample->realp, 1, sample_buffer, 1, KRENGINE_AUDIO_BLOCK_LENGTH); - } - - itr++; + for (int channel = 0; channel < impulse_response_channels; channel++) { - bool end_of_group = false; - if(itr == m_mapped_sources.end()) { - end_of_group = true; - } else { - Vector2 next_direction = (*itr).first; - end_of_group = next_direction != source_direction; - } + bool first_source = true; + unordered_multimap > >::iterator itr = m_mapped_sources.begin(); + while (itr != m_mapped_sources.end()) { + // Batch together sound sources that are emitted from the same direction + Vector2 source_direction = (*itr).first; + KRAudioSource* source = (*itr).second.first; + float gain_anticlick = (*itr).second.second.first; + float gain = (*itr).second.second.second; - if(end_of_group) { - // ----====---- We have reached the end of a batch; convolve with HRTF impulse response and add to output accumulation buffer ----====---- - first_source = true; - - memset(hrtf_sample->realp + hrtf_frames, 0, sizeof(float) * hrtf_frames); - memset(hrtf_sample->imagp, 0, sizeof(float) * fft_size); - - KRDSP::SplitComplex hrtf_spectral; - - if(m_high_quality_hrtf) { - // High quality, interpolated HRTF - hrtf_spectral = *hrtf_accum; - - float mix[4]; - Vector2 dir[4]; - - getHRTFMix(source_direction, dir[0], dir[1], dir[2], dir[3], mix[0], mix[1], mix[2], mix[3]); - - - memset(hrtf_accum->realp, 0, sizeof(float) * fft_size); - memset(hrtf_accum->imagp, 0, sizeof(float) * fft_size); - - for(int i=0; i < 1 /*4 */; i++) { - if(mix[i] > 0.0f) { - KRDSP::SplitComplex hrtf_impulse_sample = getHRTFSpectral(dir[i], channel); - KRDSP::ScaleCopy(&hrtf_impulse_sample, mix[i], hrtf_impulse, fft_size); - KRDSP::Accumulate(hrtf_accum, hrtf_impulse, fft_size); - } - } - } else { - // Low quality, non-interpolated HRTF - hrtf_spectral = getHRTFSpectral(source_direction, channel); - } - - float scale = 0.5f / fft_size; - - KRDSP::FFTForward(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], hrtf_sample, fft_size_log2); - KRDSP::Multiply(hrtf_sample, &hrtf_spectral, hrtf_convolved, fft_size); - KRDSP::FFTInverse(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], hrtf_convolved, fft_size_log2); - KRDSP::Scale(hrtf_convolved->realp, scale, fft_size); - - int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); - int frames_left = fft_size; - while(frames_left) { - int frames_to_process = (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS - output_offset) / KRENGINE_MAX_OUTPUT_CHANNELS; - if(frames_to_process > frames_left) frames_to_process = frames_left; - KRDSP::Accumulate(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, - hrtf_convolved->realp + fft_size - frames_left, 1, - frames_to_process); - frames_left -= frames_to_process; - output_offset = (output_offset + frames_to_process * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); - } - } + + // If this is the first or only sample, write directly to the first half of the FFT input buffer + // Subsequent samples write to the second half of the FFT input buffer, which is then added to the first half (the second half will be zero'ed out anyways and works as a convenient temporary buffer) + float* sample_buffer = first_source ? hrtf_sample->realp : hrtf_sample->realp + KRENGINE_AUDIO_BLOCK_LENGTH; + + if (gain != gain_anticlick && m_anticlick_block) { + // Sample and perform anti-click filtering + source->sample(KRENGINE_AUDIO_BLOCK_LENGTH, 0, sample_buffer, 1.0); + float ramp_gain = gain_anticlick; + float ramp_step = (gain - gain_anticlick) / KRENGINE_AUDIO_ANTICLICK_SAMPLES; + KRDSP::ScaleRamp(sample_buffer, ramp_gain, ramp_step, KRENGINE_AUDIO_ANTICLICK_SAMPLES); + if (KRENGINE_AUDIO_BLOCK_LENGTH > KRENGINE_AUDIO_ANTICLICK_SAMPLES) { + KRDSP::Scale(sample_buffer + KRENGINE_AUDIO_ANTICLICK_SAMPLES, gain, KRENGINE_AUDIO_BLOCK_LENGTH - KRENGINE_AUDIO_ANTICLICK_SAMPLES); } + } else { + // Don't need to perform anti-click filtering, so just sample + source->sample(KRENGINE_AUDIO_BLOCK_LENGTH, 0, sample_buffer, gain); + } + + if (first_source) { + first_source = false; + } else { + // Accumulate samples on subsequent sources + KRDSP::Accumulate(hrtf_sample->realp, 1, sample_buffer, 1, KRENGINE_AUDIO_BLOCK_LENGTH); + } + + itr++; + + bool end_of_group = false; + if (itr == m_mapped_sources.end()) { + end_of_group = true; + } else { + Vector2 next_direction = (*itr).first; + end_of_group = next_direction != source_direction; + } + + if (end_of_group) { + // ----====---- We have reached the end of a batch; convolve with HRTF impulse response and add to output accumulation buffer ----====---- + first_source = true; + + memset(hrtf_sample->realp + hrtf_frames, 0, sizeof(float) * hrtf_frames); + memset(hrtf_sample->imagp, 0, sizeof(float) * fft_size); + + KRDSP::SplitComplex hrtf_spectral; + + if (m_high_quality_hrtf) { + // High quality, interpolated HRTF + hrtf_spectral = *hrtf_accum; + + float mix[4]; + Vector2 dir[4]; + + getHRTFMix(source_direction, dir[0], dir[1], dir[2], dir[3], mix[0], mix[1], mix[2], mix[3]); + + + memset(hrtf_accum->realp, 0, sizeof(float) * fft_size); + memset(hrtf_accum->imagp, 0, sizeof(float) * fft_size); + + for (int i = 0; i < 1 /*4 */; i++) { + if (mix[i] > 0.0f) { + KRDSP::SplitComplex hrtf_impulse_sample = getHRTFSpectral(dir[i], channel); + KRDSP::ScaleCopy(&hrtf_impulse_sample, mix[i], hrtf_impulse, fft_size); + KRDSP::Accumulate(hrtf_accum, hrtf_impulse, fft_size); + } + } + } else { + // Low quality, non-interpolated HRTF + hrtf_spectral = getHRTFSpectral(source_direction, channel); + } + + float scale = 0.5f / fft_size; + + KRDSP::FFTForward(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], hrtf_sample, fft_size_log2); + KRDSP::Multiply(hrtf_sample, &hrtf_spectral, hrtf_convolved, fft_size); + KRDSP::FFTInverse(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], hrtf_convolved, fft_size_log2); + KRDSP::Scale(hrtf_convolved->realp, scale, fft_size); + + int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + int frames_left = fft_size; + while (frames_left) { + int frames_to_process = (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS - output_offset) / KRENGINE_MAX_OUTPUT_CHANNELS; + if (frames_to_process > frames_left) frames_to_process = frames_left; + KRDSP::Accumulate(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, + hrtf_convolved->realp + fft_size - frames_left, 1, + frames_to_process); + frames_left -= frames_to_process; + output_offset = (output_offset + frames_to_process * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + } + } } + } } void KRAudioManager::renderITD() { - // FINDME, TODO - Need Inter-Temperal based phase shifting to support 3-d spatialized audio without headphones - - /* - - - // hrtf_kemar_H-10e000a.wav - - float speed_of_sound = 1126.0f; // feed per second FINDME - TODO - This needs to be configurable for scenes with different units - float head_radius = 0.7431f; // 0.74ft = 22cm - float half_max_itd_time = head_radius / speed_of_sound / 2.0f; // half of ITD time (Interaural time difference) when audio source is directly 90 degrees azimuth to one ear. - - // Vector3 m_listener_position; - // Vector3 m_listener_forward; - // Vector3 m_listener_up; - - Vector3 listener_right = Vector3::Cross(m_listener_forward, m_listener_up); - Vector3 listener_right_ear = m_listener_position + listener_right * head_radius / 2.0f; - Vector3 listener_left_ear = m_listener_position - listener_right * head_radius / 2.0f; - - // Get a pointer to the dataBuffer of the AudioBufferList - - Float32 *outA = (Float32 *)ioData->mBuffers[0].mData; - Float32 *outB = (Float32 *)ioData->mBuffers[1].mData; // Non-Interleaved only - - - // ----====---- Zero out accumulation / output buffer ----====---- - for (UInt32 i = 0; i < inNumberFrames; ++i) { - - // Interleaved - // outA[i*2] = (Float32)left_channel; - // outA[i*2 + 1] = (Float32)right_channel; - - // Non-Interleaved - outA[i] = (Float32)0.0f; - outB[i] = (Float32)0.0f; - } - - // ----====---- Render direct / HRTF audio ----====---- - for(std::set::iterator itr=m_activeAudioSources.begin(); itr != m_activeAudioSources.end(); itr++) { - KRAudioSource *source = *itr; - Vector3 listener_to_source = source->getWorldTranslation() - m_listener_position; - Vector3 right_ear_to_source = source->getWorldTranslation() - listener_right_ear; - Vector3 left_ear_to_source = source->getWorldTranslation() - listener_left_ear; - Vector3 source_direction = Vector3::Normalize(listener_to_source); - float right_ear_distance = right_ear_to_source.magnitude(); - float left_ear_distance = left_ear_to_source.magnitude(); - float right_itd_time = right_ear_distance / speed_of_sound; - float left_itd_time = left_ear_distance / speed_of_sound; - - float rolloff_factor = source->getRolloffFactor(); - float left_gain = 1.0f / pow(left_ear_distance / rolloff_factor, 2.0f); - float right_gain = 1.0f / pow(left_ear_distance / rolloff_factor, 2.0f); - if(left_gain > 1.0f) left_gain = 1.0f; - if(right_gain > 1.0f) right_gain = 1.0f; - left_gain *= source->getGain(); - right_gain *= source->getGain(); - int left_itd_offset = (int)(left_itd_time * 44100.0f); - int right_itd_offset = (int)(right_itd_time * 44100.0f); - KRAudioSample *sample = source->getAudioSample(); - if(sample) { - __int64_t source_start_frame = source->getStartAudioFrame(); - int sample_frame = (int)(m_audio_frame - source_start_frame); - for (UInt32 i = 0; i < inNumberFrames; ++i) { - float left_channel=sample->sample(sample_frame + left_itd_offset, 44100, 0) * left_gain; - float right_channel = sample->sample(sample_frame + right_itd_offset, 44100, 0) * right_gain; - - // left_channel = 0.0f; - // right_channel = 0.0f; - - // Interleaved - // outA[i*2] = (Float32)left_channel; - // outA[i*2 + 1] = (Float32)right_channel; - - // Non-Interleaved - outA[i] += (Float32)left_channel; - outB[i] += (Float32)right_channel; - sample_frame++; - } - } - } - - KRAudioSample *reverb_impulse_response = getContext().getAudioManager()->get("test_reverb"); - - // ----====---- Render Indirect / Reverb channel ----====---- - int buffer_frame_start=0; - int remaining_frames = inNumberFrames - buffer_frame_start; - while(remaining_frames) { - int frames_processed = remaining_frames; - if(frames_processed > KRENGINE_REVERB_FILTER_LENGTH) { - frames_processed = KRENGINE_REVERB_FILTER_LENGTH; - } - bool first_source = true; - for(std::set::iterator itr=m_activeAudioSources.begin(); itr != m_activeAudioSources.end(); itr++) { - KRAudioSource *source = *itr; - KRAudioSample *sample = source->getAudioSample(); - if(sample) { - __int64_t source_start_frame = source->getStartAudioFrame(); - int sample_frame = (int)(m_audio_frame - source_start_frame + buffer_frame_start); - - - - - for (UInt32 i = 0; i < inNumberFrames; ++i) { - if(first_source) { - sample->sample(sample_frame, 44100, 0, m_reverb_input_next_sample); - } - sample->sampleAdditive(sample_frame, 44100, 0, m_reverb_input_next_sample); - if(m_reverb_input_next_sample >= KRENGINE_REVERB_MAX_SAMPLES) { - m_reverb_input_next_sample -= KRENGINE_REVERB_MAX_SAMPLES; - } - } - } - first_source = false; - } - - - if(reverb_impulse_response) { - // Perform FFT Convolution for Impulse-response based reverb - - memcpy(m_reverb_accumulation, m_reverb_accumulation + KRENGINE_REVERB_FILTER_LENGTH, KRENGINE_REVERB_FILTER_LENGTH * sizeof(float)); - memset(m_reverb_accumulation + KRENGINE_REVERB_FILTER_LENGTH, 0, KRENGINE_REVERB_FILTER_LENGTH * sizeof(float)); - } - - buffer_frame_start += frames_processed; - remaining_frames = inNumberFrames - buffer_frame_start; - } - - - */ + // FINDME, TODO - Need Inter-Temperal based phase shifting to support 3-d spatialized audio without headphones + + /* + + + // hrtf_kemar_H-10e000a.wav + + float speed_of_sound = 1126.0f; // feed per second FINDME - TODO - This needs to be configurable for scenes with different units + float head_radius = 0.7431f; // 0.74ft = 22cm + float half_max_itd_time = head_radius / speed_of_sound / 2.0f; // half of ITD time (Interaural time difference) when audio source is directly 90 degrees azimuth to one ear. + + // Vector3 m_listener_position; + // Vector3 m_listener_forward; + // Vector3 m_listener_up; + + Vector3 listener_right = Vector3::Cross(m_listener_forward, m_listener_up); + Vector3 listener_right_ear = m_listener_position + listener_right * head_radius / 2.0f; + Vector3 listener_left_ear = m_listener_position - listener_right * head_radius / 2.0f; + + // Get a pointer to the dataBuffer of the AudioBufferList + + Float32 *outA = (Float32 *)ioData->mBuffers[0].mData; + Float32 *outB = (Float32 *)ioData->mBuffers[1].mData; // Non-Interleaved only + + + // ----====---- Zero out accumulation / output buffer ----====---- + for (UInt32 i = 0; i < inNumberFrames; ++i) { + + // Interleaved + // outA[i*2] = (Float32)left_channel; + // outA[i*2 + 1] = (Float32)right_channel; + + // Non-Interleaved + outA[i] = (Float32)0.0f; + outB[i] = (Float32)0.0f; + } + + // ----====---- Render direct / HRTF audio ----====---- + for(std::set::iterator itr=m_activeAudioSources.begin(); itr != m_activeAudioSources.end(); itr++) { + KRAudioSource *source = *itr; + Vector3 listener_to_source = source->getWorldTranslation() - m_listener_position; + Vector3 right_ear_to_source = source->getWorldTranslation() - listener_right_ear; + Vector3 left_ear_to_source = source->getWorldTranslation() - listener_left_ear; + Vector3 source_direction = Vector3::Normalize(listener_to_source); + float right_ear_distance = right_ear_to_source.magnitude(); + float left_ear_distance = left_ear_to_source.magnitude(); + float right_itd_time = right_ear_distance / speed_of_sound; + float left_itd_time = left_ear_distance / speed_of_sound; + + float rolloff_factor = source->getRolloffFactor(); + float left_gain = 1.0f / pow(left_ear_distance / rolloff_factor, 2.0f); + float right_gain = 1.0f / pow(left_ear_distance / rolloff_factor, 2.0f); + if(left_gain > 1.0f) left_gain = 1.0f; + if(right_gain > 1.0f) right_gain = 1.0f; + left_gain *= source->getGain(); + right_gain *= source->getGain(); + int left_itd_offset = (int)(left_itd_time * 44100.0f); + int right_itd_offset = (int)(right_itd_time * 44100.0f); + KRAudioSample *sample = source->getAudioSample(); + if(sample) { + __int64_t source_start_frame = source->getStartAudioFrame(); + int sample_frame = (int)(m_audio_frame - source_start_frame); + for (UInt32 i = 0; i < inNumberFrames; ++i) { + float left_channel=sample->sample(sample_frame + left_itd_offset, 44100, 0) * left_gain; + float right_channel = sample->sample(sample_frame + right_itd_offset, 44100, 0) * right_gain; + + // left_channel = 0.0f; + // right_channel = 0.0f; + + // Interleaved + // outA[i*2] = (Float32)left_channel; + // outA[i*2 + 1] = (Float32)right_channel; + + // Non-Interleaved + outA[i] += (Float32)left_channel; + outB[i] += (Float32)right_channel; + sample_frame++; + } + } + } + + KRAudioSample *reverb_impulse_response = getContext().getAudioManager()->get("test_reverb"); + + // ----====---- Render Indirect / Reverb channel ----====---- + int buffer_frame_start=0; + int remaining_frames = inNumberFrames - buffer_frame_start; + while(remaining_frames) { + int frames_processed = remaining_frames; + if(frames_processed > KRENGINE_REVERB_FILTER_LENGTH) { + frames_processed = KRENGINE_REVERB_FILTER_LENGTH; + } + bool first_source = true; + for(std::set::iterator itr=m_activeAudioSources.begin(); itr != m_activeAudioSources.end(); itr++) { + KRAudioSource *source = *itr; + KRAudioSample *sample = source->getAudioSample(); + if(sample) { + __int64_t source_start_frame = source->getStartAudioFrame(); + int sample_frame = (int)(m_audio_frame - source_start_frame + buffer_frame_start); + + + + + for (UInt32 i = 0; i < inNumberFrames; ++i) { + if(first_source) { + sample->sample(sample_frame, 44100, 0, m_reverb_input_next_sample); + } + sample->sampleAdditive(sample_frame, 44100, 0, m_reverb_input_next_sample); + if(m_reverb_input_next_sample >= KRENGINE_REVERB_MAX_SAMPLES) { + m_reverb_input_next_sample -= KRENGINE_REVERB_MAX_SAMPLES; + } + } + } + first_source = false; + } + + + if(reverb_impulse_response) { + // Perform FFT Convolution for Impulse-response based reverb + + memcpy(m_reverb_accumulation, m_reverb_accumulation + KRENGINE_REVERB_FILTER_LENGTH, KRENGINE_REVERB_FILTER_LENGTH * sizeof(float)); + memset(m_reverb_accumulation + KRENGINE_REVERB_FILTER_LENGTH, 0, KRENGINE_REVERB_FILTER_LENGTH * sizeof(float)); + } + + buffer_frame_start += frames_processed; + remaining_frames = inNumberFrames - buffer_frame_start; + } + + + */ } static bool audioIsMuted = false; static bool audioShouldBecomeMuted = false; static bool audioShouldBecomeUnmuted = false; -void audioLimit_Mute(bool onNotOff) { - if (onNotOff) { - if (audioIsMuted) { - audioShouldBecomeMuted = false; - audioShouldBecomeUnmuted = false; - return; - } - audioShouldBecomeMuted = true; - audioShouldBecomeUnmuted = false; +void audioLimit_Mute(bool onNotOff) +{ + if (onNotOff) { + if (audioIsMuted) { + audioShouldBecomeMuted = false; + audioShouldBecomeUnmuted = false; + return; } - else { - if (!audioIsMuted) { - audioShouldBecomeMuted = false; - audioShouldBecomeUnmuted = false; - return; - } - audioShouldBecomeMuted = false; - audioShouldBecomeUnmuted = true; + audioShouldBecomeMuted = true; + audioShouldBecomeUnmuted = false; + } else { + if (!audioIsMuted) { + audioShouldBecomeMuted = false; + audioShouldBecomeUnmuted = false; + return; } + audioShouldBecomeMuted = false; + audioShouldBecomeUnmuted = true; + } } -float audioGetLimitParameters_Stereo(float *buffer, unsigned long framesize, - unsigned long *attack_sample_position, float *peak) +float audioGetLimitParameters_Stereo(float* buffer, unsigned long framesize, + unsigned long* attack_sample_position, float* peak) { - float limitvol = 1.0f; - long attack_position = -1; - *peak = 0.0f; - float max = 0.0f; - float amplitude = 0.0f; - - float *src = buffer; - for (unsigned long i = 0; i < framesize * 2; i++) { - amplitude = fabs(*src); src++; - if (amplitude > max) max = amplitude; - if (amplitude > 0.995f) if (attack_position < 0) attack_position = (i+1) / 2; - } - if (max > 0.995f) limitvol = 0.995f / max; - *peak = max; - - if (attack_position < 0) attack_position = framesize; - *attack_sample_position = (unsigned long) attack_position; - return limitvol; + float limitvol = 1.0f; + long attack_position = -1; + *peak = 0.0f; + float max = 0.0f; + float amplitude = 0.0f; + + float* src = buffer; + for (unsigned long i = 0; i < framesize * 2; i++) { + amplitude = fabs(*src); src++; + if (amplitude > max) max = amplitude; + if (amplitude > 0.995f) if (attack_position < 0) attack_position = (i + 1) / 2; + } + if (max > 0.995f) limitvol = 0.995f / max; + *peak = max; + + if (attack_position < 0) attack_position = framesize; + *attack_sample_position = (unsigned long)attack_position; + return limitvol; } // returns the new limit volume, *attack_sample_position tells how fast we need to reach the new limit -void audioLimit_Stereo(float *stereo_buffer, unsigned long framesize) +void audioLimit_Stereo(float* stereo_buffer, unsigned long framesize) { - static float limit_value = 1.0; + static float limit_value = 1.0; - // (1) get the limiting parameters for the incoming audio data - float previouslimitvol = limit_value; - float peak; - unsigned long attack_sample_position = framesize; + // (1) get the limiting parameters for the incoming audio data + float previouslimitvol = limit_value; + float peak; + unsigned long attack_sample_position = framesize; - // (1a) check for a mute or unmute state then get the next limit volume - float nextlimitvol = 0.0; - if (audioIsMuted && audioShouldBecomeUnmuted) { audioIsMuted = false; audioShouldBecomeUnmuted = false; } - if (audioShouldBecomeMuted) { audioIsMuted = true; audioShouldBecomeMuted = false; } - if (!audioIsMuted) nextlimitvol = audioGetLimitParameters_Stereo(stereo_buffer, framesize, &attack_sample_position, &peak); + // (1a) check for a mute or unmute state then get the next limit volume + float nextlimitvol = 0.0; + if (audioIsMuted && audioShouldBecomeUnmuted) { + audioIsMuted = false; audioShouldBecomeUnmuted = false; + } + if (audioShouldBecomeMuted) { + audioIsMuted = true; audioShouldBecomeMuted = false; + } + if (!audioIsMuted) nextlimitvol = audioGetLimitParameters_Stereo(stereo_buffer, framesize, &attack_sample_position, &peak); - // (1b) if no limiting is needed then return - if ((1.0 == nextlimitvol) && (1.0 == previouslimitvol)) { return; } // no limiting necessary - - // (2) calculate limiting factors - float deltavol = 0.0; - if (previouslimitvol != nextlimitvol) { - deltavol = (nextlimitvol - previouslimitvol) / (float) attack_sample_position; + // (1b) if no limiting is needed then return + if ((1.0 == nextlimitvol) && (1.0 == previouslimitvol)) { + return; + } // no limiting necessary + +// (2) calculate limiting factors + float deltavol = 0.0; + if (previouslimitvol != nextlimitvol) { + deltavol = (nextlimitvol - previouslimitvol) / (float)attack_sample_position; + } + + // (3) do the limiting + float* src = stereo_buffer; + + if (0.0 == deltavol) { // fixed volume + for (unsigned long i = 0; i < framesize; i++) { + *src = *src * nextlimitvol; + src++; + *src = *src * nextlimitvol; + src++; } + } else { + for (unsigned long i = 0; i < attack_sample_position; i++) { // attack phase + *src = *src * previouslimitvol; + src++; + *src = *src * previouslimitvol; + src++; + previouslimitvol += deltavol; + } + if (nextlimitvol < 1.0) { // plateau phase + for (unsigned long i = attack_sample_position; i < framesize; i++) { + *src = *src * nextlimitvol; + src++; + *src = *src * nextlimitvol; + src++; + } + } + } - // (3) do the limiting - float *src = stereo_buffer; - - if (0.0 == deltavol) { // fixed volume - for (unsigned long i=0; i < framesize; i++) { - *src = *src * nextlimitvol; - src++; - *src = *src * nextlimitvol; - src++; - } - } - else { - for (unsigned long i=0; i < attack_sample_position; i++) { // attack phase - *src = *src * previouslimitvol; - src++; - *src = *src * previouslimitvol; - src++; - previouslimitvol += deltavol; - } - if (nextlimitvol < 1.0) { // plateau phase - for (unsigned long i = attack_sample_position; i < framesize; i++) { - *src = *src * nextlimitvol; - src++; - *src = *src * nextlimitvol; - src++; - } - } - } - - // (4) save our limit level for next time - limit_value = nextlimitvol; + // (4) save our limit level for next time + limit_value = nextlimitvol; } void KRAudioManager::mute(bool onNotOff) { - audioLimit_Mute(onNotOff); + audioLimit_Mute(onNotOff); } void KRAudioManager::renderLimiter() { - int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); - float *output = m_output_accumulation + output_offset; - unsigned long numframes = KRENGINE_AUDIO_BLOCK_LENGTH; - audioLimit_Stereo(output, numframes); + int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + float* output = m_output_accumulation + output_offset; + unsigned long numframes = KRENGINE_AUDIO_BLOCK_LENGTH; + audioLimit_Stereo(output, numframes); } void KRAudioManager::goToSleep() { - cleanupAudio(); + cleanupAudio(); } diff --git a/kraken/KRAudioManager.h b/kraken/KRAudioManager.h index 9639ceb..5310906 100755 --- a/kraken/KRAudioManager.h +++ b/kraken/KRAudioManager.h @@ -59,9 +59,9 @@ const int KRENGINE_AUDIO_BLOCK_LOG2N = 7; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = // 7 is 128 .. NOTE: the hrtf code uses magic numbers everywhere and is hardcoded to 128 samples per frame const int KRENGINE_AUDIO_BLOCK_LENGTH = 1 << KRENGINE_AUDIO_BLOCK_LOG2N; - // Length of one block to process. Determines the latency of the audio system and sets size for FFT's used in HRTF convolution - // the AUGraph works in 1024 sample chunks. At 128 we are making 8 consecutive calls to the renderBlock method for each - // render initiated by the AUGraph. +// Length of one block to process. Determines the latency of the audio system and sets size for FFT's used in HRTF convolution +// the AUGraph works in 1024 sample chunks. At 128 we are making 8 consecutive calls to the renderBlock method for each +// render initiated by the AUGraph. const int KRENGINE_REVERB_MAX_FFT_LOG2 = 15; const int KRENGINE_REVERB_WORKSPACE_SIZE = 1 << KRENGINE_REVERB_MAX_FFT_LOG2; @@ -79,177 +79,180 @@ const int KRENGINE_AUDIO_ANTICLICK_SAMPLES = 64; class KRAmbientZone; class KRReverbZone; -typedef struct { - float weight; - KRAmbientZone *ambient_zone; - KRAudioSample *ambient_sample; +typedef struct +{ + float weight; + KRAmbientZone* ambient_zone; + KRAudioSample* ambient_sample; } siren_ambient_zone_weight_info; -typedef struct { - float weight; - KRReverbZone *reverb_zone; - KRAudioSample *reverb_sample; +typedef struct +{ + float weight; + KRReverbZone* reverb_zone; + KRAudioSample* reverb_sample; } siren_reverb_zone_weight_info; -class KRAudioManager : public KRResourceManager { +class KRAudioManager : public KRResourceManager +{ public: - KRAudioManager(KRContext &context); - virtual ~KRAudioManager(); - void destroy(); + KRAudioManager(KRContext& context); + virtual ~KRAudioManager(); + void destroy(); - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - - unordered_map &getSounds(); - - void add(KRAudioSample *Sound); - - KRAudioSample *load(const std::string &name, const std::string &extension, KRDataBlock *data); - KRAudioSample *get(const std::string &name); - - // Listener position and orientation - KRScene *getListenerScene(); - void setListenerScene(KRScene *scene); - void setListenerOrientation(const Vector3 &position, const Vector3 &forward, const Vector3 &up); - void setListenerOrientationFromModelMatrix(const Matrix4 &modelMatrix); - Vector3 &getListenerForward(); - Vector3 &getListenerPosition(); - Vector3 &getListenerUp(); - - - // Global audio gain / attenuation - float getGlobalGain(); - void setGlobalGain(float gain); - float getGlobalReverbSendLevel(); - void setGlobalReverbSendLevel(float send_level); - float getGlobalAmbientGain(); - void setGlobalAmbientGain(float gain); + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - - - void makeCurrentContext(); - - KRDataBlock *getBufferData(int size); - void recycleBufferData(KRDataBlock *data); - - void activateAudioSource(KRAudioSource *audioSource); - void deactivateAudioSource(KRAudioSource *audioSource); - - __int64_t getAudioFrame(); - - KRAudioBuffer *getBuffer(KRAudioSample &audio_sample, int buffer_index); - - static void mute(bool onNotOff); - void goToSleep(); + unordered_map& getSounds(); + + void add(KRAudioSample* Sound); + + KRAudioSample* load(const std::string& name, const std::string& extension, KRDataBlock* data); + KRAudioSample* get(const std::string& name); + + // Listener position and orientation + KRScene* getListenerScene(); + void setListenerScene(KRScene* scene); + void setListenerOrientation(const Vector3& position, const Vector3& forward, const Vector3& up); + void setListenerOrientationFromModelMatrix(const Matrix4& modelMatrix); + Vector3& getListenerForward(); + Vector3& getListenerPosition(); + Vector3& getListenerUp(); + + + // Global audio gain / attenuation + float getGlobalGain(); + void setGlobalGain(float gain); + float getGlobalReverbSendLevel(); + void setGlobalReverbSendLevel(float send_level); + float getGlobalAmbientGain(); + void setGlobalAmbientGain(float gain); + + + + void makeCurrentContext(); + + KRDataBlock* getBufferData(int size); + void recycleBufferData(KRDataBlock* data); + + void activateAudioSource(KRAudioSource* audioSource); + void deactivateAudioSource(KRAudioSource* audioSource); + + __int64_t getAudioFrame(); + + KRAudioBuffer* getBuffer(KRAudioSample& audio_sample, int buffer_index); + + static void mute(bool onNotOff); + void goToSleep(); + + void startFrame(float deltaTime); + + bool getEnableAudio(); + void setEnableAudio(bool enable); + + bool getEnableHRTF(); + void setEnableHRTF(bool enable); + + bool getEnableReverb(); + void setEnableReverb(bool enable); + + float getReverbMaxLength(); + void setReverbMaxLength(float max_length); + + void _registerOpenAudioSample(KRAudioSample* audioSample); + void _registerCloseAudioSample(KRAudioSample* audioSample); - void startFrame(float deltaTime); - - bool getEnableAudio(); - void setEnableAudio(bool enable); - - bool getEnableHRTF(); - void setEnableHRTF(bool enable); - - bool getEnableReverb(); - void setEnableReverb(bool enable); - - float getReverbMaxLength(); - void setReverbMaxLength(float max_length); - - void _registerOpenAudioSample(KRAudioSample *audioSample); - void _registerCloseAudioSample(KRAudioSample *audioSample); - private: - bool m_enable_audio; - bool m_enable_hrtf; - bool m_enable_reverb; - float m_reverb_max_length; - - KRScene *m_listener_scene; // For now, only one scene is allowed to have active audio at once - - float m_global_reverb_send_level; - float m_global_ambient_gain; - float m_global_gain; - - Vector3 m_listener_position; - Vector3 m_listener_forward; - Vector3 m_listener_up; - - unordered_map m_sounds; - - std::vector m_bufferPoolIdle; - - std::vector m_bufferCache; - - std::set m_activeAudioSources; - - std::set m_openAudioSamples; - - void initAudio(); - void initHRTF(); - - void cleanupAudio(); - - bool m_initialized; + bool m_enable_audio; + bool m_enable_hrtf; + bool m_enable_reverb; + float m_reverb_max_length; + + KRScene* m_listener_scene; // For now, only one scene is allowed to have active audio at once + + float m_global_reverb_send_level; + float m_global_ambient_gain; + float m_global_gain; + + Vector3 m_listener_position; + Vector3 m_listener_forward; + Vector3 m_listener_up; + + unordered_map m_sounds; + + std::vector m_bufferPoolIdle; + + std::vector m_bufferCache; + + std::set m_activeAudioSources; + + std::set m_openAudioSamples; + + void initAudio(); + void initHRTF(); + + void cleanupAudio(); + + bool m_initialized; #ifdef __APPLE__ - // Apple Core Audio - AUGraph m_auGraph; - AudioUnit m_auMixer; + // Apple Core Audio + AUGraph m_auGraph; + AudioUnit m_auMixer; - static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); - void renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData); + static OSStatus renderInput(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData); + void renderAudio(UInt32 inNumberFrames, AudioBufferList* ioData); #endif - KRDSP::FFTWorkspace m_fft_setup[KRENGINE_REVERB_MAX_FFT_LOG2 - KRENGINE_AUDIO_BLOCK_LOG2N + 1]; + KRDSP::FFTWorkspace m_fft_setup[KRENGINE_REVERB_MAX_FFT_LOG2 - KRENGINE_AUDIO_BLOCK_LOG2N + 1]; - __int64_t m_audio_frame; // Number of audio frames processed since the start of the application - - float *m_reverb_input_samples; // Circular-buffered reverb input, single channel - int m_reverb_input_next_sample; // Pointer to next sample in reverb buffer - int m_reverb_sequence; - - KRAudioSample *m_reverb_impulse_responses[KRENGINE_MAX_REVERB_IMPULSE_MIX]; - float m_reverb_impulse_responses_weight[KRENGINE_MAX_REVERB_IMPULSE_MIX]; - - float *m_output_accumulation; // Interleaved output accumulation buffer - int m_output_accumulation_block_start; - int m_output_sample; - - float *m_workspace_data; - KRDSP::SplitComplex m_workspace[3]; - - float *getBlockAddress(int block_offset); - void renderBlock(); - void renderReverb(); - void renderAmbient(); - void renderHRTF(); - void renderITD(); - void renderReverbImpulseResponse(int impulse_response_offset, int frame_count_log2); - void renderLimiter(); - - std::vector m_hrtf_sample_locations; - float *m_hrtf_data; - unordered_map m_hrtf_spectral[2]; - - Vector2 getNearestHRTFSample(const Vector2 &dir); - void getHRTFMix(const Vector2 &dir, Vector2 &hrtf1, Vector2 &hrtf2, Vector2 &hrtf3, Vector2 &hrtf4, float &mix1, float &mix2, float &mix3, float &mix4); - KRAudioSample *getHRTFSample(const Vector2 &hrtf_dir); - KRDSP::SplitComplex getHRTFSpectral(const Vector2 &hrtf_dir, const int channel); - - unordered_map m_ambient_zone_weights; - float m_ambient_zone_total_weight = 0.0f; // For normalizing zone weights - - unordered_map m_reverb_zone_weights; - float m_reverb_zone_total_weight = 0.0f; // For normalizing zone weights - - std::mutex m_mutex; + __int64_t m_audio_frame; // Number of audio frames processed since the start of the application + + float* m_reverb_input_samples; // Circular-buffered reverb input, single channel + int m_reverb_input_next_sample; // Pointer to next sample in reverb buffer + int m_reverb_sequence; + + KRAudioSample* m_reverb_impulse_responses[KRENGINE_MAX_REVERB_IMPULSE_MIX]; + float m_reverb_impulse_responses_weight[KRENGINE_MAX_REVERB_IMPULSE_MIX]; + + float* m_output_accumulation; // Interleaved output accumulation buffer + int m_output_accumulation_block_start; + int m_output_sample; + + float* m_workspace_data; + KRDSP::SplitComplex m_workspace[3]; + + float* getBlockAddress(int block_offset); + void renderBlock(); + void renderReverb(); + void renderAmbient(); + void renderHRTF(); + void renderITD(); + void renderReverbImpulseResponse(int impulse_response_offset, int frame_count_log2); + void renderLimiter(); + + std::vector m_hrtf_sample_locations; + float* m_hrtf_data; + unordered_map m_hrtf_spectral[2]; + + Vector2 getNearestHRTFSample(const Vector2& dir); + void getHRTFMix(const Vector2& dir, Vector2& hrtf1, Vector2& hrtf2, Vector2& hrtf3, Vector2& hrtf4, float& mix1, float& mix2, float& mix3, float& mix4); + KRAudioSample* getHRTFSample(const Vector2& hrtf_dir); + KRDSP::SplitComplex getHRTFSpectral(const Vector2& hrtf_dir, const int channel); + + unordered_map m_ambient_zone_weights; + float m_ambient_zone_total_weight = 0.0f; // For normalizing zone weights + + unordered_map m_reverb_zone_weights; + float m_reverb_zone_total_weight = 0.0f; // For normalizing zone weights + + std::mutex m_mutex; #ifdef __APPLE__ - mach_timebase_info_data_t m_timebase_info; + mach_timebase_info_data_t m_timebase_info; #endif - - - unordered_multimap > > m_mapped_sources, m_prev_mapped_sources; - bool m_anticlick_block; - bool m_high_quality_hrtf; // If true, 4 HRTF samples will be interpolated; if false, the nearest HRTF sample will be used without interpolation + + + unordered_multimap > > m_mapped_sources, m_prev_mapped_sources; + bool m_anticlick_block; + bool m_high_quality_hrtf; // If true, 4 HRTF samples will be interpolated; if false, the nearest HRTF sample will be used without interpolation }; diff --git a/kraken/KRAudioSample.cpp b/kraken/KRAudioSample.cpp index 8868fd0..f227dcf 100755 --- a/kraken/KRAudioSample.cpp +++ b/kraken/KRAudioSample.cpp @@ -36,263 +36,263 @@ #include "KRContext.h" #include "KRDSP.h" -KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension) : KRResource(context, name) +KRAudioSample::KRAudioSample(KRContext& context, std::string name, std::string extension) : KRResource(context, name) { - m_pData = new KRDataBlock(); - m_extension = extension; + m_pData = new KRDataBlock(); + m_extension = extension; #ifdef __APPLE__ - // Apple Audio Toolbox - m_audio_file_id = 0; - m_fileRef = NULL; + // Apple Audio Toolbox + m_audio_file_id = 0; + m_fileRef = NULL; #endif - m_totalFrames = 0; - m_bytesPerFrame = 0; - m_frameRate = 0; - m_bufferCount = 0; - - m_last_frame_used = 0; + m_totalFrames = 0; + m_bytesPerFrame = 0; + m_frameRate = 0; + m_bufferCount = 0; + + m_last_frame_used = 0; } -KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension, KRDataBlock *data) : KRResource(context, name) +KRAudioSample::KRAudioSample(KRContext& context, std::string name, std::string extension, KRDataBlock* data) : KRResource(context, name) { - m_pData = data; - m_extension = extension; - + m_pData = data; + m_extension = extension; + #ifdef __APPLE__ - // Apple Audio Toolbox - m_audio_file_id = 0; - m_fileRef = NULL; + // Apple Audio Toolbox + m_audio_file_id = 0; + m_fileRef = NULL; #endif - m_totalFrames = 0; - m_bytesPerFrame = 0; - m_frameRate = 0; - m_bufferCount = 0; - - m_last_frame_used = 0; + m_totalFrames = 0; + m_bytesPerFrame = 0; + m_frameRate = 0; + m_bufferCount = 0; + + m_last_frame_used = 0; } KRAudioSample::~KRAudioSample() { - closeFile(); - delete m_pData; + closeFile(); + delete m_pData; } int KRAudioSample::getChannelCount() { - loadInfo(); - return m_channelsPerFrame; + loadInfo(); + return m_channelsPerFrame; } __int64_t KRAudioSample::getFrameCount() { - loadInfo(); - //return (int)((__int64_t)m_totalFrames * (__int64_t)frame_rate / (__int64_t)m_frameRate); - return m_totalFrames; + loadInfo(); + //return (int)((__int64_t)m_totalFrames * (__int64_t)frame_rate / (__int64_t)m_frameRate); + return m_totalFrames; } float KRAudioSample::sample(int frame_offset, int frame_rate, int channel) { - loadInfo(); - - int c = KRMIN(channel, m_channelsPerFrame - 1); + loadInfo(); - if(frame_offset < 0) { - return 0.0f; // Past the beginning of the recording + int c = KRMIN(channel, m_channelsPerFrame - 1); + + if (frame_offset < 0) { + return 0.0f; // Past the beginning of the recording + } else { + int sample_frame; + if (m_frameRate == frame_rate) { + // No resampling required + sample_frame = frame_offset; } else { - int sample_frame; - if(m_frameRate == frame_rate) { - // No resampling required - sample_frame = frame_offset; - } else { - // Need to resample from m_frameRate to frame_rate - sample_frame = (int)((__int64_t)frame_offset * (__int64_t)m_frameRate / (__int64_t)frame_rate); - } - int maxFramesPerBuffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / m_bytesPerFrame; - int buffer_index = sample_frame / maxFramesPerBuffer; - if(buffer_index >= m_bufferCount) { - return 0.0f; // Past the end of the recording - } else { - __int64_t buffer_offset = frame_offset - buffer_index * maxFramesPerBuffer; - - KRAudioBuffer *buffer = getContext().getAudioManager()->getBuffer(*this, buffer_index); - if(buffer == NULL) { - return 0.0f; - } else if(buffer_offset >= buffer->getFrameCount()) { - return 0.0f; // past the end of the recording - } else { - short *frame = buffer->getFrameData() + (buffer_offset * m_channelsPerFrame); - return frame[c] / 32767.0f; - } - } + // Need to resample from m_frameRate to frame_rate + sample_frame = (int)((__int64_t)frame_offset * (__int64_t)m_frameRate / (__int64_t)frame_rate); } + int maxFramesPerBuffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / m_bytesPerFrame; + int buffer_index = sample_frame / maxFramesPerBuffer; + if (buffer_index >= m_bufferCount) { + return 0.0f; // Past the end of the recording + } else { + __int64_t buffer_offset = frame_offset - buffer_index * maxFramesPerBuffer; + + KRAudioBuffer* buffer = getContext().getAudioManager()->getBuffer(*this, buffer_index); + if (buffer == NULL) { + return 0.0f; + } else if (buffer_offset >= buffer->getFrameCount()) { + return 0.0f; // past the end of the recording + } else { + short* frame = buffer->getFrameData() + (buffer_offset * m_channelsPerFrame); + return frame[c] / 32767.0f; + } + } + } } -void KRAudioSample::sample(__int64_t frame_offset, int frame_count, int channel, float *buffer, float amplitude, bool loop) +void KRAudioSample::sample(__int64_t frame_offset, int frame_count, int channel, float* buffer, float amplitude, bool loop) { - loadInfo(); - - m_last_frame_used = (int)getContext().getAudioManager()->getAudioFrame(); - - if(loop) { - int buffer_offset = 0; - int frames_left = frame_count; - int sample_length = (int)getFrameCount(); - while(frames_left) { - int next_frame = (int)(((__int64_t)frame_offset + (__int64_t)buffer_offset) % sample_length); - if(next_frame + frames_left >= sample_length) { - int frames_processed = sample_length - next_frame; - sample(next_frame, frames_processed, channel, buffer + buffer_offset, amplitude, false); - frames_left -= frames_processed; - buffer_offset += frames_processed; - } else { - sample(next_frame, frames_left, channel, buffer + buffer_offset, amplitude, false); - frames_left = 0; - } - } - } else { - int c = KRMIN(channel, m_channelsPerFrame - 1); - - if(frame_offset + frame_count <= 0) { - // Range is entirely before the sample - memset(buffer, 0, frame_count * sizeof(float)); - } else if(frame_offset >= m_totalFrames) { - // Range is entirely after the sample - memset(buffer, 0, frame_count * sizeof(float)); - } else { - int start_frame = (int)(frame_offset < 0 ? 0 : frame_offset); - int prefix_frames = (int)(frame_offset < 0 ? -frame_offset : 0); - if(prefix_frames > 0) { - // Prefix with padding of 0's - memset(buffer, 0, prefix_frames * sizeof(float)); - } - - int frames_per_buffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / m_bytesPerFrame; - - int buffer_index = start_frame / frames_per_buffer; - int buffer_offset = start_frame % frames_per_buffer; - int processed_frames = prefix_frames; - while(processed_frames < frame_count) { - int frames_left = frame_count - processed_frames; - if(buffer_index >= m_bufferCount) { - // Suffix with padding of 0's - memset(buffer + processed_frames, 0, frames_left * sizeof(float)); - processed_frames += frames_left; - } else { - KRAudioBuffer *source_buffer = getContext().getAudioManager()->getBuffer(*this, buffer_index); - int frames_to_copy = source_buffer->getFrameCount() - buffer_offset; - if(frames_to_copy > frames_left) frames_to_copy = frames_left; - if(frames_to_copy > 0) { - signed short *source_data = source_buffer->getFrameData() + buffer_offset * m_channelsPerFrame + c; - KRDSP::Int16ToFloat(source_data, m_channelsPerFrame, buffer + processed_frames, 1, frames_to_copy); - //memcpy(buffer + processed_frames, source_buffer->getFrameData() + buffer_offset, frames_to_copy * m_channelsPerFrame * sizeof(float)); - processed_frames += frames_to_copy; - } - buffer_index++; - buffer_offset = 0; - } - } - } - - float scale = amplitude / 32768.0f; - KRDSP::Scale(buffer, scale, frame_count); + loadInfo(); + + m_last_frame_used = (int)getContext().getAudioManager()->getAudioFrame(); + + if (loop) { + int buffer_offset = 0; + int frames_left = frame_count; + int sample_length = (int)getFrameCount(); + while (frames_left) { + int next_frame = (int)(((__int64_t)frame_offset + (__int64_t)buffer_offset) % sample_length); + if (next_frame + frames_left >= sample_length) { + int frames_processed = sample_length - next_frame; + sample(next_frame, frames_processed, channel, buffer + buffer_offset, amplitude, false); + frames_left -= frames_processed; + buffer_offset += frames_processed; + } else { + sample(next_frame, frames_left, channel, buffer + buffer_offset, amplitude, false); + frames_left = 0; + } } + } else { + int c = KRMIN(channel, m_channelsPerFrame - 1); + + if (frame_offset + frame_count <= 0) { + // Range is entirely before the sample + memset(buffer, 0, frame_count * sizeof(float)); + } else if (frame_offset >= m_totalFrames) { + // Range is entirely after the sample + memset(buffer, 0, frame_count * sizeof(float)); + } else { + int start_frame = (int)(frame_offset < 0 ? 0 : frame_offset); + int prefix_frames = (int)(frame_offset < 0 ? -frame_offset : 0); + if (prefix_frames > 0) { + // Prefix with padding of 0's + memset(buffer, 0, prefix_frames * sizeof(float)); + } + + int frames_per_buffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / m_bytesPerFrame; + + int buffer_index = start_frame / frames_per_buffer; + int buffer_offset = start_frame % frames_per_buffer; + int processed_frames = prefix_frames; + while (processed_frames < frame_count) { + int frames_left = frame_count - processed_frames; + if (buffer_index >= m_bufferCount) { + // Suffix with padding of 0's + memset(buffer + processed_frames, 0, frames_left * sizeof(float)); + processed_frames += frames_left; + } else { + KRAudioBuffer* source_buffer = getContext().getAudioManager()->getBuffer(*this, buffer_index); + int frames_to_copy = source_buffer->getFrameCount() - buffer_offset; + if (frames_to_copy > frames_left) frames_to_copy = frames_left; + if (frames_to_copy > 0) { + signed short* source_data = source_buffer->getFrameData() + buffer_offset * m_channelsPerFrame + c; + KRDSP::Int16ToFloat(source_data, m_channelsPerFrame, buffer + processed_frames, 1, frames_to_copy); + //memcpy(buffer + processed_frames, source_buffer->getFrameData() + buffer_offset, frames_to_copy * m_channelsPerFrame * sizeof(float)); + processed_frames += frames_to_copy; + } + buffer_index++; + buffer_offset = 0; + } + } + } + + float scale = amplitude / 32768.0f; + KRDSP::Scale(buffer, scale, frame_count); + } } #ifdef __APPLE__ // Apple Audio Toolbox OSStatus KRAudioSample::ReadProc( // AudioFile_ReadProc - void * inClientData, + void* inClientData, SInt64 inPosition, UInt32 requestCount, - void * buffer, - UInt32 * actualCount) + void* buffer, + UInt32* actualCount) { - KRAudioSample *sound = (KRAudioSample *)inClientData; - UInt32 max_count = sound->m_pData->getSize() - inPosition; - *actualCount = requestCount < max_count ? requestCount : max_count; - sound->m_pData->copy(buffer, inPosition, *actualCount); - return noErr; + KRAudioSample* sound = (KRAudioSample*)inClientData; + UInt32 max_count = sound->m_pData->getSize() - inPosition; + *actualCount = requestCount < max_count ? requestCount : max_count; + sound->m_pData->copy(buffer, inPosition, *actualCount); + return noErr; } SInt64 KRAudioSample::GetSizeProc( // AudioFile_GetSizeProc - void * inClientData) + void* inClientData) { - KRAudioSample *sound = (KRAudioSample *)inClientData; - return sound->m_pData->getSize(); + KRAudioSample* sound = (KRAudioSample*)inClientData; + return sound->m_pData->getSize(); } OSStatus KRAudioSample::SetSizeProc( // AudioFile_SetSizeProc - void * inClientData, + void* inClientData, SInt64 inSize) { - return -1; // Writing not supported + return -1; // Writing not supported } OSStatus KRAudioSample::WriteProc( // AudioFile_WriteProc - void * inClientData, + void* inClientData, SInt64 inPosition, UInt32 requestCount, - const void *buffer, - UInt32 * actualCount) + const void* buffer, + UInt32* actualCount) { - return -1; // Writing not supported + return -1; // Writing not supported } #endif // Apple Audio Toolbox void KRAudioSample::openFile() { #ifdef __APPLE__ -// Apple Audio Toolbox + // Apple Audio Toolbox - // AudioFileInitializeWithCallbacks - if(m_fileRef == NULL) { - -// printf("Call to KRAudioSample::openFile() with extension: %s\n", m_extension.c_str()); -// The m_extension is valid (it's either wav or mp3 for the files in Circa project) -// so we can key off the extension and use a different data handler for mp3 files if we want to -// + // AudioFileInitializeWithCallbacks + if (m_fileRef == NULL) { - // Temp variables - UInt32 propertySize; - - // ---- Open audio file ---- - assert(AudioFileOpenWithCallbacks((void *)this, ReadProc, WriteProc, GetSizeProc, SetSizeProc, 0, &m_audio_file_id) == noErr); - assert(ExtAudioFileWrapAudioFileID(m_audio_file_id, false, &m_fileRef) == noErr); - - // ---- Get file format information ---- - AudioStreamBasicDescription inputFormat; - propertySize = sizeof(inputFormat); - ExtAudioFileGetProperty(m_fileRef, kExtAudioFileProperty_FileDataFormat, &propertySize, &inputFormat); - - // ---- Set up output format ---- - AudioStreamBasicDescription outputFormat; - // Set the client format to 16 bit signed integer (native-endian) data - // Maintain the channel count and sample rate of the original source format - outputFormat.mSampleRate = inputFormat.mSampleRate; - outputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame; - outputFormat.mFormatID = kAudioFormatLinearPCM; - outputFormat.mBytesPerPacket = 2 * outputFormat.mChannelsPerFrame; - outputFormat.mFramesPerPacket = 1; - outputFormat.mBytesPerFrame = 2 * outputFormat.mChannelsPerFrame; - outputFormat.mBitsPerChannel = 16; - outputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; - ExtAudioFileSetProperty(m_fileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(outputFormat), &outputFormat); - - // ---- Get the buffer size and format parameters ---- - propertySize = sizeof(m_totalFrames); - ExtAudioFileGetProperty(m_fileRef, kExtAudioFileProperty_FileLengthFrames, &propertySize, &m_totalFrames); - - m_bytesPerFrame = outputFormat.mBytesPerFrame; - m_frameRate = outputFormat.mSampleRate; - - int maxFramesPerBuffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / m_bytesPerFrame; - m_bufferCount = (m_totalFrames+maxFramesPerBuffer-1)/maxFramesPerBuffer; // CEIL(_totalFrames / maxFramesPerBuffer) - - m_channelsPerFrame = outputFormat.mChannelsPerFrame; - - getContext().getAudioManager()->_registerOpenAudioSample(this); - } + // printf("Call to KRAudioSample::openFile() with extension: %s\n", m_extension.c_str()); + // The m_extension is valid (it's either wav or mp3 for the files in Circa project) + // so we can key off the extension and use a different data handler for mp3 files if we want to + // + + // Temp variables + UInt32 propertySize; + + // ---- Open audio file ---- + assert(AudioFileOpenWithCallbacks((void*)this, ReadProc, WriteProc, GetSizeProc, SetSizeProc, 0, &m_audio_file_id) == noErr); + assert(ExtAudioFileWrapAudioFileID(m_audio_file_id, false, &m_fileRef) == noErr); + + // ---- Get file format information ---- + AudioStreamBasicDescription inputFormat; + propertySize = sizeof(inputFormat); + ExtAudioFileGetProperty(m_fileRef, kExtAudioFileProperty_FileDataFormat, &propertySize, &inputFormat); + + // ---- Set up output format ---- + AudioStreamBasicDescription outputFormat; + // Set the client format to 16 bit signed integer (native-endian) data + // Maintain the channel count and sample rate of the original source format + outputFormat.mSampleRate = inputFormat.mSampleRate; + outputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame; + outputFormat.mFormatID = kAudioFormatLinearPCM; + outputFormat.mBytesPerPacket = 2 * outputFormat.mChannelsPerFrame; + outputFormat.mFramesPerPacket = 1; + outputFormat.mBytesPerFrame = 2 * outputFormat.mChannelsPerFrame; + outputFormat.mBitsPerChannel = 16; + outputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; + ExtAudioFileSetProperty(m_fileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(outputFormat), &outputFormat); + + // ---- Get the buffer size and format parameters ---- + propertySize = sizeof(m_totalFrames); + ExtAudioFileGetProperty(m_fileRef, kExtAudioFileProperty_FileLengthFrames, &propertySize, &m_totalFrames); + + m_bytesPerFrame = outputFormat.mBytesPerFrame; + m_frameRate = outputFormat.mSampleRate; + + int maxFramesPerBuffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / m_bytesPerFrame; + m_bufferCount = (m_totalFrames + maxFramesPerBuffer - 1) / maxFramesPerBuffer; // CEIL(_totalFrames / maxFramesPerBuffer) + + m_channelsPerFrame = outputFormat.mChannelsPerFrame; + + getContext().getAudioManager()->_registerOpenAudioSample(this); + } #else #pragma message ( "TODO - implement for Windows" ) #endif @@ -302,92 +302,92 @@ void KRAudioSample::closeFile() { #ifdef __APPLE__ // Apple Audio Toolbox - if(m_fileRef) { - ExtAudioFileDispose(m_fileRef); - m_fileRef = NULL; - } - - if(m_audio_file_id) { - AudioFileClose(m_audio_file_id); - m_audio_file_id = 0; - } + if (m_fileRef) { + ExtAudioFileDispose(m_fileRef); + m_fileRef = NULL; + } + + if (m_audio_file_id) { + AudioFileClose(m_audio_file_id); + m_audio_file_id = 0; + } #endif - - getContext().getAudioManager()->_registerCloseAudioSample(this); + + getContext().getAudioManager()->_registerCloseAudioSample(this); } void KRAudioSample::loadInfo() { - if(m_frameRate == 0) { - openFile(); - closeFile(); - } + if (m_frameRate == 0) { + openFile(); + closeFile(); + } } std::string KRAudioSample::getExtension() { - return m_extension; + return m_extension; } -bool KRAudioSample::save(KRDataBlock &data) +bool KRAudioSample::save(KRDataBlock& data) { - data.append(*m_pData); - return true; + data.append(*m_pData); + return true; } float KRAudioSample::getDuration() { - loadInfo(); - return (float)m_totalFrames / (float)m_frameRate; + loadInfo(); + return (float)m_totalFrames / (float)m_frameRate; } int KRAudioSample::getBufferCount() { - loadInfo(); - return m_bufferCount; + loadInfo(); + return m_bufferCount; } -void KRAudioSample::PopulateBuffer(KRAudioSample *sound, int index, void *data) +void KRAudioSample::PopulateBuffer(KRAudioSample* sound, int index, void* data) { - int maxFramesPerBuffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / sound->m_bytesPerFrame; - int startFrame = index * maxFramesPerBuffer; - __uint32_t frameCount = (__uint32_t)KRMIN(sound->m_totalFrames - startFrame, maxFramesPerBuffer); + int maxFramesPerBuffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / sound->m_bytesPerFrame; + int startFrame = index * maxFramesPerBuffer; + __uint32_t frameCount = (__uint32_t)KRMIN(sound->m_totalFrames - startFrame, maxFramesPerBuffer); #ifdef __APPLE__ - // Apple Audio Toolbox - AudioBufferList outputBufferInfo; - outputBufferInfo.mNumberBuffers = 1; - outputBufferInfo.mBuffers[0].mDataByteSize = frameCount * sound->m_bytesPerFrame; - outputBufferInfo.mBuffers[0].mNumberChannels = sound->m_channelsPerFrame; - outputBufferInfo.mBuffers[0].mData = data; - - // Read the data into an AudioBufferList - ExtAudioFileSeek(sound->m_fileRef, startFrame); - ExtAudioFileRead(sound->m_fileRef, (UInt32*)&frameCount, &outputBufferInfo); + // Apple Audio Toolbox + AudioBufferList outputBufferInfo; + outputBufferInfo.mNumberBuffers = 1; + outputBufferInfo.mBuffers[0].mDataByteSize = frameCount * sound->m_bytesPerFrame; + outputBufferInfo.mBuffers[0].mNumberChannels = sound->m_channelsPerFrame; + outputBufferInfo.mBuffers[0].mData = data; + + // Read the data into an AudioBufferList + ExtAudioFileSeek(sound->m_fileRef, startFrame); + ExtAudioFileRead(sound->m_fileRef, (UInt32*)&frameCount, &outputBufferInfo); #endif } -KRAudioBuffer *KRAudioSample::getBuffer(int index) +KRAudioBuffer* KRAudioSample::getBuffer(int index) { - openFile(); + openFile(); - int maxFramesPerBuffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / m_bytesPerFrame; - int startFrame = index * maxFramesPerBuffer; - __uint32_t frameCount = (__uint32_t)KRMIN(m_totalFrames - startFrame, maxFramesPerBuffer); - - KRAudioBuffer *buffer = new KRAudioBuffer(getContext().getAudioManager(), this, index, frameCount, m_frameRate, m_bytesPerFrame, PopulateBuffer); - - if(m_bufferCount == 1) { -// [self closeFile]; // We don't need to hold on to a file handle if not streaming - } - return buffer; + int maxFramesPerBuffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / m_bytesPerFrame; + int startFrame = index * maxFramesPerBuffer; + __uint32_t frameCount = (__uint32_t)KRMIN(m_totalFrames - startFrame, maxFramesPerBuffer); + + KRAudioBuffer* buffer = new KRAudioBuffer(getContext().getAudioManager(), this, index, frameCount, m_frameRate, m_bytesPerFrame, PopulateBuffer); + + if (m_bufferCount == 1) { + // [self closeFile]; // We don't need to hold on to a file handle if not streaming + } + return buffer; } void KRAudioSample::_endFrame() { - const __int64_t AUDIO_SAMPLE_EXPIRY_FRAMES = 500; - __int64_t current_frame = getContext().getAudioManager()->getAudioFrame(); - if(current_frame > m_last_frame_used + AUDIO_SAMPLE_EXPIRY_FRAMES) { - closeFile(); - } + const __int64_t AUDIO_SAMPLE_EXPIRY_FRAMES = 500; + __int64_t current_frame = getContext().getAudioManager()->getAudioFrame(); + if (current_frame > m_last_frame_used + AUDIO_SAMPLE_EXPIRY_FRAMES) { + closeFile(); + } } diff --git a/kraken/KRAudioSample.h b/kraken/KRAudioSample.h index fd9e291..42e5580 100755 --- a/kraken/KRAudioSample.h +++ b/kraken/KRAudioSample.h @@ -38,73 +38,74 @@ class KRAudioBuffer; -class KRAudioSample : public KRResource { - +class KRAudioSample : public KRResource +{ + public: - KRAudioSample(KRContext &context, std::string name, std::string extension); - KRAudioSample(KRContext &context, std::string name, std::string extension, KRDataBlock *data); - virtual ~KRAudioSample(); - - virtual std::string getExtension(); - - virtual bool save(KRDataBlock &data); - - float getDuration(); - KRAudioBuffer *getBuffer(int index); - int getBufferCount(); - - // Siren audio engine interface - int getChannelCount(); - __int64_t getFrameCount(); - float sample(int frame_offset, int frame_rate, int channel); - void sample(__int64_t frame_offset, int frame_count, int channel, float *buffer, float amplitude, bool loop); - - void _endFrame(); + KRAudioSample(KRContext& context, std::string name, std::string extension); + KRAudioSample(KRContext& context, std::string name, std::string extension, KRDataBlock* data); + virtual ~KRAudioSample(); + + virtual std::string getExtension(); + + virtual bool save(KRDataBlock& data); + + float getDuration(); + KRAudioBuffer* getBuffer(int index); + int getBufferCount(); + + // Siren audio engine interface + int getChannelCount(); + __int64_t getFrameCount(); + float sample(int frame_offset, int frame_rate, int channel); + void sample(__int64_t frame_offset, int frame_count, int channel, float* buffer, float amplitude, bool loop); + + void _endFrame(); private: - - __int64_t m_last_frame_used; - - std::string m_extension; - KRDataBlock *m_pData; + + __int64_t m_last_frame_used; + + std::string m_extension; + KRDataBlock* m_pData; #ifdef __APPLE__ - // Apple Audio Toolbox - AudioFileID m_audio_file_id; - ExtAudioFileRef m_fileRef; + // Apple Audio Toolbox + AudioFileID m_audio_file_id; + ExtAudioFileRef m_fileRef; - static OSStatus ReadProc( // AudioFile_ReadProc - void * inClientData, - SInt64 inPosition, - UInt32 requestCount, - void * buffer, - UInt32 * actualCount); + static OSStatus ReadProc( // AudioFile_ReadProc + void* inClientData, + SInt64 inPosition, + UInt32 requestCount, + void* buffer, + UInt32* actualCount); - static OSStatus WriteProc( // AudioFile_WriteProc - void * inClientData, - SInt64 inPosition, - UInt32 requestCount, - const void *buffer, - UInt32 * actualCount); + static OSStatus WriteProc( // AudioFile_WriteProc + void* inClientData, + SInt64 inPosition, + UInt32 requestCount, + const void* buffer, + UInt32* actualCount); - static SInt64 GetSizeProc( // AudioFile_GetSizeProc - void * inClientData); + static SInt64 GetSizeProc( // AudioFile_GetSizeProc + void* inClientData); - static OSStatus SetSizeProc( // AudioFile_SetSizeProc - void * inClientData, - SInt64 inSize); + static OSStatus SetSizeProc( // AudioFile_SetSizeProc + void* inClientData, + SInt64 inSize); #endif - - int m_bufferCount; - - __int64_t m_totalFrames; - int m_frameRate; - int m_bytesPerFrame; - int m_channelsPerFrame; - - void openFile(); - void closeFile(); - void loadInfo(); - static void PopulateBuffer(KRAudioSample *sound, int index, void *data); + int m_bufferCount; + + __int64_t m_totalFrames; + int m_frameRate; + int m_bytesPerFrame; + int m_channelsPerFrame; + + void openFile(); + void closeFile(); + void loadInfo(); + + static void PopulateBuffer(KRAudioSample* sound, int index, void* data); }; diff --git a/kraken/KRAudioSource.cpp b/kraken/KRAudioSource.cpp index c13002f..cb41b22 100755 --- a/kraken/KRAudioSource.cpp +++ b/kraken/KRAudioSource.cpp @@ -51,409 +51,410 @@ void KRAudioSource::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->audio_source.sample = -1; } -KRAudioSource::KRAudioSource(KRScene &scene, std::string name) : KRNode(scene, name) +KRAudioSource::KRAudioSource(KRScene& scene, std::string name) : KRNode(scene, name) { - m_currentBufferFrame = 0; - m_playing = false; - m_is3d = true; - m_isPrimed = false; - m_audioFile = NULL; - m_gain = 1.0f; - m_pitch = 1.0f; - m_looping = false; - - m_referenceDistance = 1.0f; - m_reverb = 0.0f; - m_rolloffFactor = 2.0f; - m_enable_occlusion = true; - m_enable_obstruction = true; - - m_start_audio_frame = -1; - m_paused_audio_frame = 0; + m_currentBufferFrame = 0; + m_playing = false; + m_is3d = true; + m_isPrimed = false; + m_audioFile = NULL; + m_gain = 1.0f; + m_pitch = 1.0f; + m_looping = false; + + m_referenceDistance = 1.0f; + m_reverb = 0.0f; + m_rolloffFactor = 2.0f; + m_enable_occlusion = true; + m_enable_obstruction = true; + + m_start_audio_frame = -1; + m_paused_audio_frame = 0; } KRAudioSource::~KRAudioSource() { - while(m_audioBuffers.size()) { - delete m_audioBuffers.front(); - m_audioBuffers.pop(); - } + while (m_audioBuffers.size()) { + delete m_audioBuffers.front(); + m_audioBuffers.pop(); + } } -std::string KRAudioSource::getElementName() { - return "audio_source"; -} - -tinyxml2::XMLElement *KRAudioSource::saveXML( tinyxml2::XMLNode *parent) +std::string KRAudioSource::getElementName() { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - e->SetAttribute("sample", m_audio_sample_name.c_str()); - e->SetAttribute("gain", m_gain); - e->SetAttribute("pitch", m_pitch); - e->SetAttribute("looping", m_looping ? "true" : "false"); - e->SetAttribute("is3d", m_is3d ? "true" : "false"); - e->SetAttribute("reference_distance", m_referenceDistance); - e->SetAttribute("reverb", m_reverb); - e->SetAttribute("rolloff_factor", m_rolloffFactor); - e->SetAttribute("enable_occlusion", m_enable_occlusion ? "true" : "false"); - e->SetAttribute("enable_obstruction", m_enable_obstruction ? "true" : "false"); - return e; + return "audio_source"; } -void KRAudioSource::loadXML(tinyxml2::XMLElement *e) +tinyxml2::XMLElement* KRAudioSource::saveXML(tinyxml2::XMLNode* parent) { - m_audio_sample_name = e->Attribute("sample"); - - float gain = 1.0f; - if(e->QueryFloatAttribute("gain", &gain) != tinyxml2::XML_SUCCESS) { - gain = 1.0f; - } - setGain(gain); - - float pitch = 1.0f; - if(e->QueryFloatAttribute("pitch", &pitch) != tinyxml2::XML_SUCCESS) { - pitch = 1.0f; - } - setPitch(m_pitch); - - bool looping = false; - if(e->QueryBoolAttribute("looping", &looping) != tinyxml2::XML_SUCCESS) { - looping = false; - } - setLooping(looping); - - bool is3d = true; - if(e->QueryBoolAttribute("is3d", &is3d) != tinyxml2::XML_SUCCESS) { - is3d = true; - } - setIs3D(is3d); - - float reference_distance = 1.0f; - if(e->QueryFloatAttribute("reference_distance", &reference_distance) != tinyxml2::XML_SUCCESS) { - reference_distance = 1.0f; - } - setReferenceDistance(reference_distance); - - float reverb = 0.0f; - if(e->QueryFloatAttribute("reverb", &reverb) != tinyxml2::XML_SUCCESS) { - reverb = 0.0f; - } - setReverb(reverb); - - float rolloff_factor = 2.0f; - if(e->QueryFloatAttribute("rolloff_factor", &rolloff_factor) != tinyxml2::XML_SUCCESS) { - rolloff_factor = 2.0f; - } - setRolloffFactor(rolloff_factor); - + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + e->SetAttribute("sample", m_audio_sample_name.c_str()); + e->SetAttribute("gain", m_gain); + e->SetAttribute("pitch", m_pitch); + e->SetAttribute("looping", m_looping ? "true" : "false"); + e->SetAttribute("is3d", m_is3d ? "true" : "false"); + e->SetAttribute("reference_distance", m_referenceDistance); + e->SetAttribute("reverb", m_reverb); + e->SetAttribute("rolloff_factor", m_rolloffFactor); + e->SetAttribute("enable_occlusion", m_enable_occlusion ? "true" : "false"); + e->SetAttribute("enable_obstruction", m_enable_obstruction ? "true" : "false"); + return e; +} + +void KRAudioSource::loadXML(tinyxml2::XMLElement* e) +{ + m_audio_sample_name = e->Attribute("sample"); + + float gain = 1.0f; + if (e->QueryFloatAttribute("gain", &gain) != tinyxml2::XML_SUCCESS) { + gain = 1.0f; + } + setGain(gain); + + float pitch = 1.0f; + if (e->QueryFloatAttribute("pitch", &pitch) != tinyxml2::XML_SUCCESS) { + pitch = 1.0f; + } + setPitch(m_pitch); + + bool looping = false; + if (e->QueryBoolAttribute("looping", &looping) != tinyxml2::XML_SUCCESS) { + looping = false; + } + setLooping(looping); + + bool is3d = true; + if (e->QueryBoolAttribute("is3d", &is3d) != tinyxml2::XML_SUCCESS) { + is3d = true; + } + setIs3D(is3d); + + float reference_distance = 1.0f; + if (e->QueryFloatAttribute("reference_distance", &reference_distance) != tinyxml2::XML_SUCCESS) { + reference_distance = 1.0f; + } + setReferenceDistance(reference_distance); + + float reverb = 0.0f; + if (e->QueryFloatAttribute("reverb", &reverb) != tinyxml2::XML_SUCCESS) { + reverb = 0.0f; + } + setReverb(reverb); + + float rolloff_factor = 2.0f; + if (e->QueryFloatAttribute("rolloff_factor", &rolloff_factor) != tinyxml2::XML_SUCCESS) { + rolloff_factor = 2.0f; + } + setRolloffFactor(rolloff_factor); + + m_enable_obstruction = true; + if (e->QueryBoolAttribute("enable_obstruction", &m_enable_obstruction) != tinyxml2::XML_SUCCESS) { m_enable_obstruction = true; - if(e->QueryBoolAttribute("enable_obstruction", &m_enable_obstruction) != tinyxml2::XML_SUCCESS) { - m_enable_obstruction = true; - } + } + m_enable_occlusion = true; + if (e->QueryBoolAttribute("enable_occlusion", &m_enable_occlusion) != tinyxml2::XML_SUCCESS) { m_enable_occlusion = true; - if(e->QueryBoolAttribute("enable_occlusion", &m_enable_occlusion) != tinyxml2::XML_SUCCESS) { - m_enable_occlusion = true; - } - - KRNode::loadXML(e); + } + + KRNode::loadXML(e); } void KRAudioSource::prime() { - if(!m_isPrimed) { - if(m_audioFile == NULL && m_audio_sample_name.size() != 0) { - m_audioFile = getContext().getAudioManager()->get(m_audio_sample_name); - } - if(m_audioFile) { - // Prime the buffer queue - m_nextBufferIndex = 0; - for(int i=0; i < KRENGINE_AUDIO_BUFFERS_PER_SOURCE; i++) { - queueBuffer(); - } - - m_isPrimed = true; - } + if (!m_isPrimed) { + if (m_audioFile == NULL && m_audio_sample_name.size() != 0) { + m_audioFile = getContext().getAudioManager()->get(m_audio_sample_name); } + if (m_audioFile) { + // Prime the buffer queue + m_nextBufferIndex = 0; + for (int i = 0; i < KRENGINE_AUDIO_BUFFERS_PER_SOURCE; i++) { + queueBuffer(); + } + + m_isPrimed = true; + } + } } void KRAudioSource::queueBuffer() { - KRAudioBuffer *buffer = m_audioFile->getBuffer(m_nextBufferIndex); - m_audioBuffers.push(buffer); - m_nextBufferIndex = (m_nextBufferIndex + 1) % m_audioFile->getBufferCount(); + KRAudioBuffer* buffer = m_audioFile->getBuffer(m_nextBufferIndex); + m_audioBuffers.push(buffer); + m_nextBufferIndex = (m_nextBufferIndex + 1) % m_audioFile->getBufferCount(); } void KRAudioSource::render(RenderInfo& ri) { - - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRNode::render(ri); - - bool bVisualize = false; - - if(ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) { - KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere"); - if (sphereModel) { - Matrix4 sphereModelMatrix = getModelMatrix(); - PipelineInfo info{}; - std::string shader_name("visualize_overlay"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAdditive; - info.modelFormat = sphereModel->getModelFormat(); - info.vertexAttributes = sphereModel->getVertexAttributes(); + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + KRNode::render(ri); - sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); - } // sphereModels.size() - } + bool bVisualize = false; + + if (ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) { + KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere"); + if (sphereModel) { + Matrix4 sphereModelMatrix = getModelMatrix(); + + PipelineInfo info{}; + std::string shader_name("visualize_overlay"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.renderPass = ri.renderPass; + info.rasterMode = RasterMode::kAdditive; + info.modelFormat = sphereModel->getModelFormat(); + info.vertexAttributes = sphereModel->getVertexAttributes(); + + KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + + sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); + } // sphereModels.size() + } } void KRAudioSource::setGain(float gain) { - m_gain = gain; + m_gain = gain; } float KRAudioSource::getGain() { - return m_gain; + return m_gain; } void KRAudioSource::setPitch(float pitch) { - m_pitch = pitch; + m_pitch = pitch; } float KRAudioSource::getReferenceDistance() { - return m_referenceDistance; + return m_referenceDistance; } void KRAudioSource::setReferenceDistance(float reference_distance) { - m_referenceDistance = reference_distance; + m_referenceDistance = reference_distance; } float KRAudioSource::getReverb() { - return m_reverb; + return m_reverb; } void KRAudioSource::setReverb(float reverb) { - m_reverb = reverb; + m_reverb = reverb; } float KRAudioSource::getRolloffFactor() { - return m_rolloffFactor; + return m_rolloffFactor; } void KRAudioSource::setRolloffFactor(float rolloff_factor) { - m_rolloffFactor = rolloff_factor; + m_rolloffFactor = rolloff_factor; } void KRAudioSource::setLooping(bool looping) { - // Enable or disable looping playback; Audio source must be stopped and re-started for loop mode changes to take effect - m_looping = looping; + // Enable or disable looping playback; Audio source must be stopped and re-started for loop mode changes to take effect + m_looping = looping; } bool KRAudioSource::getLooping() { - // Returns true if the playback will automatically loop - return m_looping; + // Returns true if the playback will automatically loop + return m_looping; } bool KRAudioSource::getEnableOcclusion() { - return m_enable_occlusion; + return m_enable_occlusion; } void KRAudioSource::setEnableOcclusion(bool enable_occlusion) { - m_enable_occlusion = enable_occlusion; + m_enable_occlusion = enable_occlusion; } bool KRAudioSource::getEnableObstruction() { - return m_enable_obstruction; + return m_enable_obstruction; } void KRAudioSource::setEnableObstruction(bool enable_obstruction) { - m_enable_obstruction = enable_obstruction; + m_enable_obstruction = enable_obstruction; } bool KRAudioSource::getIs3D() { - return m_is3d; + return m_is3d; } void KRAudioSource::setIs3D(bool is3D) { - // Audio source must be stopped and re-started for mode change to take effect - m_is3d = is3D; + // Audio source must be stopped and re-started for mode change to take effect + m_is3d = is3D; } void KRAudioSource::advanceBuffer() { - if(m_audioBuffers.size()) { - delete m_audioBuffers.front(); - m_audioBuffers.pop(); - } - queueBuffer(); + if (m_audioBuffers.size()) { + delete m_audioBuffers.front(); + m_audioBuffers.pop(); + } + queueBuffer(); } void KRAudioSource::physicsUpdate(float deltaTime) { - KRNode::physicsUpdate(deltaTime); - - KRAudioManager *audioManager = getContext().getAudioManager(); - audioManager->activateAudioSource(this); + KRNode::physicsUpdate(deltaTime); + + KRAudioManager* audioManager = getContext().getAudioManager(); + audioManager->activateAudioSource(this); } void KRAudioSource::play() { - // Start playback of audio at the current audio sample position. If audio is already playing, this has no effect. - // play() does not automatically seek to the beginning of the sample. Call setAudioFrame( 0 ) first if you wish the playback to begin at the start of the audio sample. - // If not set to looping, audio playback ends automatically at the end of the sample - - if(!m_playing) { - KRAudioManager *audioManager = getContext().getAudioManager(); - assert(m_start_audio_frame == -1); - m_start_audio_frame = audioManager->getAudioFrame() - m_paused_audio_frame; - m_paused_audio_frame = -1; - audioManager->activateAudioSource(this); - } - m_playing = true; + // Start playback of audio at the current audio sample position. If audio is already playing, this has no effect. + // play() does not automatically seek to the beginning of the sample. Call setAudioFrame( 0 ) first if you wish the playback to begin at the start of the audio sample. + // If not set to looping, audio playback ends automatically at the end of the sample + + if (!m_playing) { + KRAudioManager* audioManager = getContext().getAudioManager(); + assert(m_start_audio_frame == -1); + m_start_audio_frame = audioManager->getAudioFrame() - m_paused_audio_frame; + m_paused_audio_frame = -1; + audioManager->activateAudioSource(this); + } + m_playing = true; } void KRAudioSource::stop() { - // Stop playback of audio. If audio is already stopped, this has no effect. - // If play() is called afterwards, playback will continue at the current audio sample position. - - if(m_playing) { - m_paused_audio_frame = getAudioFrame(); - m_start_audio_frame = -1; - m_playing = false; - getContext().getAudioManager()->deactivateAudioSource(this); - } + // Stop playback of audio. If audio is already stopped, this has no effect. + // If play() is called afterwards, playback will continue at the current audio sample position. + + if (m_playing) { + m_paused_audio_frame = getAudioFrame(); + m_start_audio_frame = -1; + m_playing = false; + getContext().getAudioManager()->deactivateAudioSource(this); + } } bool KRAudioSource::isPlaying() { - // Returns true if audio is playing. Will return false if a non-looped playback has reached the end of the audio sample. - - return m_playing; + // Returns true if audio is playing. Will return false if a non-looped playback has reached the end of the audio sample. + + return m_playing; } -void KRAudioSource::setSample(const std::string &sound_name) +void KRAudioSource::setSample(const std::string& sound_name) { - m_audio_sample_name = sound_name; + m_audio_sample_name = sound_name; } std::string KRAudioSource::getSample() { - return m_audio_sample_name; + return m_audio_sample_name; } -KRAudioSample *KRAudioSource::getAudioSample() +KRAudioSample* KRAudioSource::getAudioSample() { - if(m_audioFile == NULL && m_audio_sample_name.size() != 0) { - m_audioFile = getContext().getAudioManager()->get(m_audio_sample_name); - } - return m_audioFile; + if (m_audioFile == NULL && m_audio_sample_name.size() != 0) { + m_audioFile = getContext().getAudioManager()->get(m_audio_sample_name); + } + return m_audioFile; } void KRAudioSource::advanceFrames(int frame_count) { - m_currentBufferFrame += frame_count; - - KRAudioBuffer *buffer = getBuffer(); - while(buffer != NULL && m_currentBufferFrame >= buffer->getFrameCount()) { - m_currentBufferFrame -= buffer->getFrameCount(); - advanceBuffer(); - buffer = getBuffer(); - } - - if(buffer == NULL) { - m_currentBufferFrame = 0; - stop(); - } + m_currentBufferFrame += frame_count; + + KRAudioBuffer* buffer = getBuffer(); + while (buffer != NULL && m_currentBufferFrame >= buffer->getFrameCount()) { + m_currentBufferFrame -= buffer->getFrameCount(); + advanceBuffer(); + buffer = getBuffer(); + } + + if (buffer == NULL) { + m_currentBufferFrame = 0; + stop(); + } } -KRAudioBuffer *KRAudioSource::getBuffer() +KRAudioBuffer* KRAudioSource::getBuffer() { - if(m_playing) { - prime(); - return m_audioBuffers.front(); - } else { - return NULL; - } + if (m_playing) { + prime(); + return m_audioBuffers.front(); + } else { + return NULL; + } } int KRAudioSource::getBufferFrame() { - return m_currentBufferFrame; + return m_currentBufferFrame; } __int64_t KRAudioSource::getAudioFrame() { - // Returns the audio playback position in units of integer audio frames. - - if(m_playing) { - return getContext().getAudioManager()->getAudioFrame() - m_start_audio_frame; - } else { - return m_paused_audio_frame; - } + // Returns the audio playback position in units of integer audio frames. + + if (m_playing) { + return getContext().getAudioManager()->getAudioFrame() - m_start_audio_frame; + } else { + return m_paused_audio_frame; + } } void KRAudioSource::setAudioFrame(__int64_t next_frame) { - // Sets the audio playback position with units of integer audio frames. - if(m_playing) { - m_start_audio_frame = getContext().getAudioManager()->getAudioFrame() - next_frame; - } else { - m_paused_audio_frame = next_frame; - } + // Sets the audio playback position with units of integer audio frames. + if (m_playing) { + m_start_audio_frame = getContext().getAudioManager()->getAudioFrame() - next_frame; + } else { + m_paused_audio_frame = next_frame; + } } float KRAudioSource::getAudioTime() { - // Gets the audio playback position with units of floating point seconds. - - return getAudioFrame() / 44100.0f; + // Gets the audio playback position with units of floating point seconds. + + return getAudioFrame() / 44100.0f; } void KRAudioSource::setAudioTime(float new_position) { - // Sets the audio playback position with units of floating point seconds. - setAudioFrame((__int64_t)(new_position * 44100.0f)); + // Sets the audio playback position with units of floating point seconds. + setAudioFrame((__int64_t)(new_position * 44100.0f)); } -void KRAudioSource::sample(int frame_count, int channel, float *buffer, float gain) +void KRAudioSource::sample(int frame_count, int channel, float* buffer, float gain) { - KRAudioSample *source_sample = getAudioSample(); - if(source_sample && m_playing) { - __int64_t next_frame = getAudioFrame(); - source_sample->sample(next_frame, frame_count, channel, buffer, gain, m_looping); - if(!m_looping && next_frame > source_sample->getFrameCount()) { - stop(); - } - } else { - memset(buffer, 0, sizeof(float) * frame_count); + KRAudioSample* source_sample = getAudioSample(); + if (source_sample && m_playing) { + __int64_t next_frame = getAudioFrame(); + source_sample->sample(next_frame, frame_count, channel, buffer, gain, m_looping); + if (!m_looping && next_frame > source_sample->getFrameCount()) { + stop(); } + } else { + memset(buffer, 0, sizeof(float) * frame_count); + } } diff --git a/kraken/KRAudioSource.h b/kraken/KRAudioSource.h index ce879a3..1dc6092 100755 --- a/kraken/KRAudioSource.h +++ b/kraken/KRAudioSource.h @@ -39,119 +39,120 @@ class KRAudioSample; class KRAudioBuffer; -class KRAudioSource : public KRNode { +class KRAudioSource : public KRNode +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); + static void InitNodeInfo(KrNodeInfo* nodeInfo); - KRAudioSource(KRScene &scene, std::string name); - virtual ~KRAudioSource(); - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - virtual void physicsUpdate(float deltaTime); - - void render(RenderInfo& ri); + KRAudioSource(KRScene& scene, std::string name); + virtual ~KRAudioSource(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + virtual void physicsUpdate(float deltaTime); - // ---- Audio Playback Controls ---- - - // Start playback of audio at the current audio sample position. If audio is already playing, this has no effect. - // play() does not automatically seek to the beginning of the sample. Call setAudioFrame( 0 ) first if you wish the playback to begin at the start of the audio sample. - // If not set to looping, audio playback ends automatically at the end of the sample - void play(); - - // Stop playback of audio. If audio is already stopped, this has no effect. - // If play() is called afterwards, playback will continue at the current audio sample position. - void stop(); - - // Returns true if audio is playing. Will return false if a non-looped playback has reached the end of the audio sample. - bool isPlaying(); - - // Returns the audio playback position in units of integer audio frames. - __int64_t getAudioFrame(); - - // Sets the audio playback position with units of integer audio frames. - void setAudioFrame(__int64_t next_frame); - - // Gets the audio playback position with units of floating point seconds. - float getAudioTime(); - - // Sets the audio playback position with units of floating point seconds. - void setAudioTime(float new_position); - - // Returns true if the playback will automatically loop - bool getLooping(); - - // Enable or disable looping playback; Audio source must be stopped and re-started for loop mode changes to take effect - void setLooping(bool looping); - - // ---- End: Audio Playback Controls ---- - - void setSample(const std::string &sound_name); - std::string getSample(); - - KRAudioSample *getAudioSample(); - - float getGain(); - void setGain(float gain); - - float getPitch(); - void setPitch(float pitch); - + void render(RenderInfo& ri); + + // ---- Audio Playback Controls ---- + + // Start playback of audio at the current audio sample position. If audio is already playing, this has no effect. + // play() does not automatically seek to the beginning of the sample. Call setAudioFrame( 0 ) first if you wish the playback to begin at the start of the audio sample. + // If not set to looping, audio playback ends automatically at the end of the sample + void play(); + + // Stop playback of audio. If audio is already stopped, this has no effect. + // If play() is called afterwards, playback will continue at the current audio sample position. + void stop(); + + // Returns true if audio is playing. Will return false if a non-looped playback has reached the end of the audio sample. + bool isPlaying(); + + // Returns the audio playback position in units of integer audio frames. + __int64_t getAudioFrame(); + + // Sets the audio playback position with units of integer audio frames. + void setAudioFrame(__int64_t next_frame); + + // Gets the audio playback position with units of floating point seconds. + float getAudioTime(); + + // Sets the audio playback position with units of floating point seconds. + void setAudioTime(float new_position); + + // Returns true if the playback will automatically loop + bool getLooping(); + + // Enable or disable looping playback; Audio source must be stopped and re-started for loop mode changes to take effect + void setLooping(bool looping); + + // ---- End: Audio Playback Controls ---- + + void setSample(const std::string& sound_name); + std::string getSample(); + + KRAudioSample* getAudioSample(); + + float getGain(); + void setGain(float gain); + + float getPitch(); + void setPitch(float pitch); + + + + bool getIs3D(); + void setIs3D(bool is3D); + + // 3d only properties: + float getReverb(); + void setReverb(float reverb); + + float getReferenceDistance(); + void setReferenceDistance(float reference_distance); + + float getRolloffFactor(); + void setRolloffFactor(float rolloff_factor); + + bool getEnableOcclusion(); + void setEnableOcclusion(bool enable_occlusion); + + bool getEnableObstruction(); + void setEnableObstruction(bool enable_obstruction); + + // ---- Siren Audio Engine Interface ---- + + void advanceFrames(int frame_count); + KRAudioBuffer* getBuffer(); + int getBufferFrame(); + + void sample(int frame_count, int channel, float* buffer, float gain); - - bool getIs3D(); - void setIs3D(bool is3D); - - // 3d only properties: - float getReverb(); - void setReverb(float reverb); - - float getReferenceDistance(); - void setReferenceDistance(float reference_distance); - - float getRolloffFactor(); - void setRolloffFactor(float rolloff_factor); - - bool getEnableOcclusion(); - void setEnableOcclusion(bool enable_occlusion); - - bool getEnableObstruction(); - void setEnableObstruction(bool enable_obstruction); - - // ---- Siren Audio Engine Interface ---- - - void advanceFrames(int frame_count); - KRAudioBuffer *getBuffer(); - int getBufferFrame(); - - void sample(int frame_count, int channel, float *buffer, float gain); - private: - __int64_t m_start_audio_frame; // Global audio frame that matches the start of the audio sample playback; when paused or not playing, this contains a value of -1 - __int64_t m_paused_audio_frame; // When paused or not playing, this contains the local audio frame number. When playing, this contains a value of -1 - int m_currentBufferFrame; // Siren Audio Engine frame number within current buffer - void advanceBuffer(); - - std::string m_audio_sample_name; - - KRAudioSample *m_audioFile; - unsigned int m_sourceID; - float m_gain; - float m_pitch; - bool m_looping; - std::queue m_audioBuffers; - int m_nextBufferIndex; - bool m_playing; - bool m_is3d; - bool m_isPrimed; - - void prime(); - void queueBuffer(); - - // 3d only properties: - float m_referenceDistance; - float m_reverb; // type ALfloat 0.0 (dry) - 1.0 (wet) (0-100% dry/wet mix, 0.0 default) - float m_rolloffFactor; - bool m_enable_occlusion; - bool m_enable_obstruction; + __int64_t m_start_audio_frame; // Global audio frame that matches the start of the audio sample playback; when paused or not playing, this contains a value of -1 + __int64_t m_paused_audio_frame; // When paused or not playing, this contains the local audio frame number. When playing, this contains a value of -1 + int m_currentBufferFrame; // Siren Audio Engine frame number within current buffer + void advanceBuffer(); + + std::string m_audio_sample_name; + + KRAudioSample* m_audioFile; + unsigned int m_sourceID; + float m_gain; + float m_pitch; + bool m_looping; + std::queue m_audioBuffers; + int m_nextBufferIndex; + bool m_playing; + bool m_is3d; + bool m_isPrimed; + + void prime(); + void queueBuffer(); + + // 3d only properties: + float m_referenceDistance; + float m_reverb; // type ALfloat 0.0 (dry) - 1.0 (wet) (0-100% dry/wet mix, 0.0 default) + float m_rolloffFactor; + bool m_enable_occlusion; + bool m_enable_obstruction; }; diff --git a/kraken/KRBehavior.cpp b/kraken/KRBehavior.cpp index 99872fc..24efedf 100755 --- a/kraken/KRBehavior.cpp +++ b/kraken/KRBehavior.cpp @@ -36,54 +36,54 @@ KRBehaviorFactoryFunctionMap m_factoryFunctions; KRBehavior::KRBehavior() { - __node = NULL; + __node = NULL; } KRBehavior::~KRBehavior() { - + } void KRBehavior::init() { - // Note: Subclasses are not expected to call this method + // Note: Subclasses are not expected to call this method } -KRNode *KRBehavior::getNode() const +KRNode* KRBehavior::getNode() const { - return __node; + return __node; } -void KRBehavior::__setNode(KRNode *node) +void KRBehavior::__setNode(KRNode* node) { - __node = node; + __node = node; } -KRBehavior *KRBehavior::LoadXML(KRNode *node, tinyxml2::XMLElement *e) +KRBehavior* KRBehavior::LoadXML(KRNode* node, tinyxml2::XMLElement* e) { - std::map attributes; - for(const tinyxml2::XMLAttribute *attribute = e->FirstAttribute(); attribute != NULL; attribute = attribute->Next()) { - attributes[attribute->Name()] = attribute->Value(); - } - - const char *szElementName = e->Attribute("type"); - if(szElementName == NULL) { - return NULL; - } - KRBehaviorFactoryFunctionMap::const_iterator itr = m_factoryFunctions.find(szElementName); - if(itr == m_factoryFunctions.end()) { - return NULL; - } - return (*itr->second)(attributes); + std::map attributes; + for (const tinyxml2::XMLAttribute* attribute = e->FirstAttribute(); attribute != NULL; attribute = attribute->Next()) { + attributes[attribute->Name()] = attribute->Value(); + } + + const char* szElementName = e->Attribute("type"); + if (szElementName == NULL) { + return NULL; + } + KRBehaviorFactoryFunctionMap::const_iterator itr = m_factoryFunctions.find(szElementName); + if (itr == m_factoryFunctions.end()) { + return NULL; + } + return (*itr->second)(attributes); } void KRBehavior::RegisterFactoryCTOR(std::string behaviorName, KRBehaviorFactoryFunction fnFactory) { - m_factoryFunctions[behaviorName] = fnFactory; + m_factoryFunctions[behaviorName] = fnFactory; } void KRBehavior::UnregisterFactoryCTOR(std::string behaviorName) { - m_factoryFunctions.erase(behaviorName); + m_factoryFunctions.erase(behaviorName); } diff --git a/kraken/KRBehavior.h b/kraken/KRBehavior.h index c5faf50..3e933e9 100755 --- a/kraken/KRBehavior.h +++ b/kraken/KRBehavior.h @@ -46,25 +46,25 @@ namespace tinyxml2 { class XMLElement; } // namespace tinyxml2 -typedef KRBehavior *(*KRBehaviorFactoryFunction)(std::map attributes); +typedef KRBehavior* (*KRBehaviorFactoryFunction)(std::map attributes); typedef std::map KRBehaviorFactoryFunctionMap; class KRBehavior { public: - static void RegisterFactoryCTOR(std::string behaviorName, KRBehaviorFactoryFunction fnFactory); - static void UnregisterFactoryCTOR(std::string behaviorName); + static void RegisterFactoryCTOR(std::string behaviorName, KRBehaviorFactoryFunction fnFactory); + static void UnregisterFactoryCTOR(std::string behaviorName); - KRBehavior(); - virtual ~KRBehavior(); - KRNode *getNode() const; + KRBehavior(); + virtual ~KRBehavior(); + KRNode* getNode() const; - virtual void init(); - virtual void update(float deltaTime) = 0; - virtual void visibleUpdate(float deltatime) = 0; - void __setNode(KRNode *node); + virtual void init(); + virtual void update(float deltaTime) = 0; + virtual void visibleUpdate(float deltatime) = 0; + void __setNode(KRNode* node); - static KRBehavior *LoadXML(KRNode *node, tinyxml2::XMLElement *e); + static KRBehavior* LoadXML(KRNode* node, tinyxml2::XMLElement* e); private: - KRNode *__node; + KRNode* __node; }; diff --git a/kraken/KRBone.cpp b/kraken/KRBone.cpp index fec7d72..82fa736 100755 --- a/kraken/KRBone.cpp +++ b/kraken/KRBone.cpp @@ -39,75 +39,76 @@ void KRBone::InitNodeInfo(KrNodeInfo* nodeInfo) // No additional members } -KRBone::KRBone(KRScene &scene, std::string name) : KRNode(scene, name) +KRBone::KRBone(KRScene& scene, std::string name) : KRNode(scene, name) { - setScaleCompensation(true); + setScaleCompensation(true); } KRBone::~KRBone() +{} + +std::string KRBone::getElementName() { + return "bone"; } -std::string KRBone::getElementName() { - return "bone"; -} - -tinyxml2::XMLElement *KRBone::saveXML( tinyxml2::XMLNode *parent) +tinyxml2::XMLElement* KRBone::saveXML(tinyxml2::XMLNode* parent) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); + tinyxml2::XMLElement* e = KRNode::saveXML(parent); - return e; + return e; } -void KRBone::loadXML(tinyxml2::XMLElement *e) +void KRBone::loadXML(tinyxml2::XMLElement* e) { - KRNode::loadXML(e); - setScaleCompensation(true); + KRNode::loadXML(e); + setScaleCompensation(true); } -AABB KRBone::getBounds() { - return AABB::Create(-Vector3::One(), Vector3::One(), getModelMatrix()); // Only required for bone debug visualization +AABB KRBone::getBounds() +{ + return AABB::Create(-Vector3::One(), Vector3::One(), getModelMatrix()); // Only required for bone debug visualization } void KRBone::render(RenderInfo& ri) { - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRNode::render(ri); - - bool bVisualize = ri.camera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_BONES; - - if(ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) { - KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere"); - if (sphereModel) { - Matrix4 sphereModelMatrix = getModelMatrix(); - - PipelineInfo info{}; - std::string shader_name("visualize_overlay"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAdditiveNoTest; - info.modelFormat = sphereModel->getModelFormat(); - info.vertexAttributes = sphereModel->getVertexAttributes(); + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + KRNode::render(ri); - sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); - } // sphereModel - } + bool bVisualize = ri.camera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_BONES; + + if (ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) { + KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere"); + if (sphereModel) { + Matrix4 sphereModelMatrix = getModelMatrix(); + + PipelineInfo info{}; + std::string shader_name("visualize_overlay"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.renderPass = ri.renderPass; + info.rasterMode = RasterMode::kAdditiveNoTest; + info.modelFormat = sphereModel->getModelFormat(); + info.vertexAttributes = sphereModel->getVertexAttributes(); + + KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + + sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); + } // sphereModel + } } -void KRBone::setBindPose(const Matrix4 &pose) +void KRBone::setBindPose(const Matrix4& pose) { - m_bind_pose = pose; + m_bind_pose = pose; } -const Matrix4 &KRBone::getBindPose() +const Matrix4& KRBone::getBindPose() { - return m_bind_pose; + return m_bind_pose; } diff --git a/kraken/KRBone.h b/kraken/KRBone.h index a126875..7f96509 100755 --- a/kraken/KRBone.h +++ b/kraken/KRBone.h @@ -37,21 +37,22 @@ class RenderInfo; -class KRBone : public KRNode { +class KRBone : public KRNode +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); + static void InitNodeInfo(KrNodeInfo* nodeInfo); - KRBone(KRScene &scene, std::string name); - virtual ~KRBone(); - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - virtual AABB getBounds(); - - void render(RenderInfo& ri); + KRBone(KRScene& scene, std::string name); + virtual ~KRBone(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + virtual AABB getBounds(); - void setBindPose(const Matrix4 &pose); - const Matrix4 &getBindPose(); + void render(RenderInfo& ri); + + void setBindPose(const Matrix4& pose); + const Matrix4& getBindPose(); private: - Matrix4 m_bind_pose; + Matrix4 m_bind_pose; }; diff --git a/kraken/KRBundle.cpp b/kraken/KRBundle.cpp index 160e774..9173b0b 100755 --- a/kraken/KRBundle.cpp +++ b/kraken/KRBundle.cpp @@ -37,133 +37,134 @@ const int KRENGINE_KRBUNDLE_HEADER_SIZE = 512; typedef struct _tar_header { - char file_name[100]; - char file_mode[8]; - char owner_id[8]; // Owner's numeric user ID (OCTAL!) - char group_id[8]; // Group's numeric user ID (OCTAL!) - char file_size[12]; // File size in bytes (OCTAL!) - char mod_time[12]; // Last modification time in numeric Unix time format - char checksum[8]; // Checksum for header block - char file_type[1]; // Link indicator (file type) - char linked_file[100]; // Name of linked file - + char file_name[100]; + char file_mode[8]; + char owner_id[8]; // Owner's numeric user ID (OCTAL!) + char group_id[8]; // Group's numeric user ID (OCTAL!) + char file_size[12]; // File size in bytes (OCTAL!) + char mod_time[12]; // Last modification time in numeric Unix time format + char checksum[8]; // Checksum for header block + char file_type[1]; // Link indicator (file type) + char linked_file[100]; // Name of linked file + } tar_header_type; -KRBundle::KRBundle(KRContext &context, std::string name, KRDataBlock *pData) : KRResource(context, name) +KRBundle::KRBundle(KRContext& context, std::string name, KRDataBlock* pData) : KRResource(context, name) { - m_pData = pData; - - __int64_t file_pos = 0; - while(file_pos < (__int64_t)m_pData->getSize()) { - tar_header_type file_header; - m_pData->copy(&file_header, (int)file_pos, sizeof(file_header)); - size_t file_size = strtol(file_header.file_size, NULL, 8); - file_pos += 512; // Skip past the header to the file contents - if(file_header.file_name[0] != '\0' && file_header.file_name[0] != '.') { - // We ignore the last two records in the tar file, which are zero'ed out tar_header structures - KRDataBlock *pFileData = pData->getSubBlock((int)file_pos, (int)file_size); - context.loadResource(file_header.file_name, pFileData); - } - file_pos += RoundUpSize(file_size); + m_pData = pData; + + __int64_t file_pos = 0; + while (file_pos < (__int64_t)m_pData->getSize()) { + tar_header_type file_header; + m_pData->copy(&file_header, (int)file_pos, sizeof(file_header)); + size_t file_size = strtol(file_header.file_size, NULL, 8); + file_pos += 512; // Skip past the header to the file contents + if (file_header.file_name[0] != '\0' && file_header.file_name[0] != '.') { + // We ignore the last two records in the tar file, which are zero'ed out tar_header structures + KRDataBlock* pFileData = pData->getSubBlock((int)file_pos, (int)file_size); + context.loadResource(file_header.file_name, pFileData); } + file_pos += RoundUpSize(file_size); + } } -KRBundle::KRBundle(KRContext &context, std::string name) : KRResource(context, name) +KRBundle::KRBundle(KRContext& context, std::string name) : KRResource(context, name) { - // Create an empty krbundle (tar) file, initialized with two zero-ed out file headers, which terminate it. - m_pData = new KRDataBlock(); - m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE * 2); - m_pData->lock(); - memset(m_pData->getStart(), 0, m_pData->getSize()); - m_pData->unlock(); + // Create an empty krbundle (tar) file, initialized with two zero-ed out file headers, which terminate it. + m_pData = new KRDataBlock(); + m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE * 2); + m_pData->lock(); + memset(m_pData->getStart(), 0, m_pData->getSize()); + m_pData->unlock(); } size_t KRBundle::RoundUpSize(size_t s) { - // Get amount of padding needed to increase s to a 512 byte alignment - if((s & 0x01ff) == 0) { - // file size is a multiple of 512 bytes, we can just add it - return s; - } else { - // We would not be on a 512 byte boundary, round up to the next one - return (s + 0x0200) - (s & 0x1ff); - } + // Get amount of padding needed to increase s to a 512 byte alignment + if ((s & 0x01ff) == 0) { + // file size is a multiple of 512 bytes, we can just add it + return s; + } else { + // We would not be on a 512 byte boundary, round up to the next one + return (s + 0x0200) - (s & 0x1ff); + } } KRBundle::~KRBundle() { - delete m_pData; + delete m_pData; } std::string KRBundle::getExtension() { - return "krbundle"; + return "krbundle"; } bool KRBundle::save(const std::string& path) { - return m_pData->save(path); + return m_pData->save(path); } -bool KRBundle::save(KRDataBlock &data) { - if(m_pData->getSize() > KRENGINE_KRBUNDLE_HEADER_SIZE * 2) { - // Only output krbundles that contain files - data.append(*m_pData); - } - return true; -} - -KRDataBlock* KRBundle::append(KRResource &resource) +bool KRBundle::save(KRDataBlock& data) { - // Serialize resource to binary representation - KRDataBlock resource_data; - resource.save(resource_data); - - std::string file_name = resource.getName() + "." + resource.getExtension(); - - // Padding is added at the end of file to align next header to a 512 byte boundary. Padding at the end of the archive includes an additional 1024 bytes -- two zero-ed out file headers that mark the end of the archive - size_t padding_size = RoundUpSize(resource_data.getSize()) - resource_data.getSize() + KRENGINE_KRBUNDLE_HEADER_SIZE * 2; - size_t resource_data_start = m_pData->getSize() + KRENGINE_KRBUNDLE_HEADER_SIZE; - m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE + resource_data.getSize() + padding_size - KRENGINE_KRBUNDLE_HEADER_SIZE * 2); // We will overwrite the existing zero-ed out file headers that marked the end of the archive, so we don't have to include their size here - - m_pData->lock(); - - // Get location of file header - tar_header_type *file_header = (tar_header_type *)((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize() - KRENGINE_KRBUNDLE_HEADER_SIZE); - - // Zero out new file header - memset(file_header, 0, KRENGINE_KRBUNDLE_HEADER_SIZE); - - // Copy resource data - resource_data.lock(); - memcpy((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize(), resource_data.getStart(), resource_data.getSize()); - resource_data.unlock(); - - // Zero out alignment padding and terminating set of file header blocks - memset((unsigned char *)m_pData->getEnd() - padding_size, 0, padding_size); - - // Populate new file header fields - strncpy(file_header->file_name, file_name.c_str(), 100); - strcpy(file_header->file_mode, "000644 "); - strcpy(file_header->owner_id, "000000 "); - strcpy(file_header->group_id, "000000 "); - sprintf(file_header->file_size, "%011o", (int)resource_data.getSize()); - file_header->file_size[11] = ' '; // Terminate with space rather than '\0' - sprintf(file_header->mod_time, "%011o", (int)time(NULL)); - file_header->mod_time[11] = ' '; // Terminate with space rather than '\0' - - // Calculate and write checksum for header - memset(file_header->checksum, ' ', 8); // Must be filled with spaces and no null terminator during checksum calculation - int check_sum = 0; - for(int i=0; i < KRENGINE_KRBUNDLE_HEADER_SIZE; i++) { - unsigned char *byte_ptr = (unsigned char *)file_header; - check_sum += byte_ptr[i]; - } - sprintf(file_header->checksum, "%07o", check_sum); - - m_pData->unlock(); - - KRDataBlock *pFileData = m_pData->getSubBlock((int)resource_data_start, (int)resource_data.getSize()); - return pFileData; + if (m_pData->getSize() > KRENGINE_KRBUNDLE_HEADER_SIZE * 2) { + // Only output krbundles that contain files + data.append(*m_pData); + } + return true; +} + +KRDataBlock* KRBundle::append(KRResource& resource) +{ + // Serialize resource to binary representation + KRDataBlock resource_data; + resource.save(resource_data); + + std::string file_name = resource.getName() + "." + resource.getExtension(); + + // Padding is added at the end of file to align next header to a 512 byte boundary. Padding at the end of the archive includes an additional 1024 bytes -- two zero-ed out file headers that mark the end of the archive + size_t padding_size = RoundUpSize(resource_data.getSize()) - resource_data.getSize() + KRENGINE_KRBUNDLE_HEADER_SIZE * 2; + size_t resource_data_start = m_pData->getSize() + KRENGINE_KRBUNDLE_HEADER_SIZE; + m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE + resource_data.getSize() + padding_size - KRENGINE_KRBUNDLE_HEADER_SIZE * 2); // We will overwrite the existing zero-ed out file headers that marked the end of the archive, so we don't have to include their size here + + m_pData->lock(); + + // Get location of file header + tar_header_type* file_header = (tar_header_type*)((unsigned char*)m_pData->getEnd() - padding_size - resource_data.getSize() - KRENGINE_KRBUNDLE_HEADER_SIZE); + + // Zero out new file header + memset(file_header, 0, KRENGINE_KRBUNDLE_HEADER_SIZE); + + // Copy resource data + resource_data.lock(); + memcpy((unsigned char*)m_pData->getEnd() - padding_size - resource_data.getSize(), resource_data.getStart(), resource_data.getSize()); + resource_data.unlock(); + + // Zero out alignment padding and terminating set of file header blocks + memset((unsigned char*)m_pData->getEnd() - padding_size, 0, padding_size); + + // Populate new file header fields + strncpy(file_header->file_name, file_name.c_str(), 100); + strcpy(file_header->file_mode, "000644 "); + strcpy(file_header->owner_id, "000000 "); + strcpy(file_header->group_id, "000000 "); + sprintf(file_header->file_size, "%011o", (int)resource_data.getSize()); + file_header->file_size[11] = ' '; // Terminate with space rather than '\0' + sprintf(file_header->mod_time, "%011o", (int)time(NULL)); + file_header->mod_time[11] = ' '; // Terminate with space rather than '\0' + + // Calculate and write checksum for header + memset(file_header->checksum, ' ', 8); // Must be filled with spaces and no null terminator during checksum calculation + int check_sum = 0; + for (int i = 0; i < KRENGINE_KRBUNDLE_HEADER_SIZE; i++) { + unsigned char* byte_ptr = (unsigned char*)file_header; + check_sum += byte_ptr[i]; + } + sprintf(file_header->checksum, "%07o", check_sum); + + m_pData->unlock(); + + KRDataBlock* pFileData = m_pData->getSubBlock((int)resource_data_start, (int)resource_data.getSize()); + return pFileData; } diff --git a/kraken/KRBundle.h b/kraken/KRBundle.h index 34937b7..873540e 100755 --- a/kraken/KRBundle.h +++ b/kraken/KRBundle.h @@ -34,18 +34,19 @@ #include "KRResource.h" #include "KRDataBlock.h" -class KRBundle : public KRResource { +class KRBundle : public KRResource +{ public: - KRBundle(KRContext &context, std::string name, KRDataBlock *pData); - KRBundle(KRContext &context, std::string name); - virtual ~KRBundle(); - virtual std::string getExtension(); - virtual bool save(const std::string& path); - virtual bool save(KRDataBlock &data); - - KRDataBlock* append(KRResource &resource); - + KRBundle(KRContext& context, std::string name, KRDataBlock* pData); + KRBundle(KRContext& context, std::string name); + virtual ~KRBundle(); + virtual std::string getExtension(); + virtual bool save(const std::string& path); + virtual bool save(KRDataBlock& data); + + KRDataBlock* append(KRResource& resource); + private: - KRDataBlock *m_pData; - static size_t RoundUpSize(size_t s); + KRDataBlock* m_pData; + static size_t RoundUpSize(size_t s); }; diff --git a/kraken/KRBundleManager.cpp b/kraken/KRBundleManager.cpp index 9931d8e..23969ef 100755 --- a/kraken/KRBundleManager.cpp +++ b/kraken/KRBundleManager.cpp @@ -33,21 +33,23 @@ #include "KRBundle.h" -KRBundleManager::KRBundleManager(KRContext &context) : KRResourceManager(context) { - +KRBundleManager::KRBundleManager(KRContext& context) : KRResourceManager(context) +{ + } -KRBundleManager::~KRBundleManager() { - for(unordered_map::iterator itr = m_bundles.begin(); itr != m_bundles.end(); ++itr){ - delete (*itr).second; - } - m_bundles.clear(); +KRBundleManager::~KRBundleManager() +{ + for (unordered_map::iterator itr = m_bundles.begin(); itr != m_bundles.end(); ++itr) { + delete (*itr).second; + } + m_bundles.clear(); } KRResource* KRBundleManager::loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) { if (extension.compare("krbundle") == 0) { - return loadBundle(name.c_str() , data); + return loadBundle(name.c_str(), data); } return nullptr; } @@ -59,25 +61,27 @@ KRResource* KRBundleManager::getResource(const std::string& name, const std::str return nullptr; } -KRBundle *KRBundleManager::loadBundle(const char *szName, KRDataBlock *pData) +KRBundle* KRBundleManager::loadBundle(const char* szName, KRDataBlock* pData) { - KRBundle *pBundle = new KRBundle(*m_pContext, szName, pData); - m_bundles[szName] = pBundle; - return pBundle; -} - -KRBundle *KRBundleManager::createBundle(const char *szName) -{ - // TODO: Check for name conflicts - KRBundle *pBundle = new KRBundle(*m_pContext, szName); + KRBundle* pBundle = new KRBundle(*m_pContext, szName, pData); m_bundles[szName] = pBundle; return pBundle; } -KRBundle *KRBundleManager::getBundle(const char *szName) { - return m_bundles[szName]; +KRBundle* KRBundleManager::createBundle(const char* szName) +{ + // TODO: Check for name conflicts + KRBundle* pBundle = new KRBundle(*m_pContext, szName); + m_bundles[szName] = pBundle; + return pBundle; } -unordered_map KRBundleManager::getBundles() { - return m_bundles; +KRBundle* KRBundleManager::getBundle(const char* szName) +{ + return m_bundles[szName]; +} + +unordered_map KRBundleManager::getBundles() +{ + return m_bundles; } \ No newline at end of file diff --git a/kraken/KRBundleManager.h b/kraken/KRBundleManager.h index 267ba8b..1c52549 100755 --- a/kraken/KRBundleManager.h +++ b/kraken/KRBundleManager.h @@ -40,21 +40,22 @@ class KRContext; class KRBundle; -class KRBundleManager : public KRResourceManager { +class KRBundleManager : public KRResourceManager +{ public: - KRBundleManager(KRContext &context); - ~KRBundleManager(); + KRBundleManager(KRContext& context); + ~KRBundleManager(); + + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; + + KRBundle* loadBundle(const char* szName, KRDataBlock* pData); + KRBundle* getBundle(const char* szName); + KRBundle* createBundle(const char* szName); + + std::vector getBundleNames(); + unordered_map getBundles(); - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - - KRBundle *loadBundle(const char *szName, KRDataBlock *pData); - KRBundle *getBundle(const char *szName); - KRBundle* createBundle(const char* szName); - - std::vector getBundleNames(); - unordered_map getBundles(); - private: - unordered_map m_bundles; + unordered_map m_bundles; }; diff --git a/kraken/KRCamera.cpp b/kraken/KRCamera.cpp index 0a84e42..5a98167 100755 --- a/kraken/KRCamera.cpp +++ b/kraken/KRCamera.cpp @@ -42,377 +42,381 @@ void KRCamera::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->camera.skybox_texture = -1; } -KRCamera::KRCamera(KRScene &scene, std::string name) : KRNode(scene, name) { - m_last_frame_start = 0; - - m_particlesAbsoluteTime = 0.0f; - volumetricBufferWidth = 0; - volumetricBufferHeight = 0; - m_pSkyBoxTexture = NULL; - - compositeDepthTexture = 0; - compositeColorTexture = 0; - lightAccumulationTexture = 0; - compositeFramebuffer = 0; - lightAccumulationBuffer = 0; - - volumetricLightAccumulationBuffer = 0; - volumetricLightAccumulationTexture = 0; - m_frame_times_filled = 0; - m_downsample = Vector2::One(); - - m_fade_color = Vector4::Zero(); +KRCamera::KRCamera(KRScene& scene, std::string name) : KRNode(scene, name) +{ + m_last_frame_start = 0; - m_debug_text_vbo_data.init(m_pContext->getMeshManager(), &m_debug_text_vertices, nullptr, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true, KRMeshManager::KRVBOData::IMMEDIATE + m_particlesAbsoluteTime = 0.0f; + volumetricBufferWidth = 0; + volumetricBufferHeight = 0; + m_pSkyBoxTexture = NULL; + + compositeDepthTexture = 0; + compositeColorTexture = 0; + lightAccumulationTexture = 0; + compositeFramebuffer = 0; + lightAccumulationBuffer = 0; + + volumetricLightAccumulationBuffer = 0; + volumetricLightAccumulationTexture = 0; + m_frame_times_filled = 0; + m_downsample = Vector2::One(); + + m_fade_color = Vector4::Zero(); + + m_debug_text_vbo_data.init(m_pContext->getMeshManager(), &m_debug_text_vertices, nullptr, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true, KRMeshManager::KRVBOData::IMMEDIATE #if KRENGINE_DEBUG_GPU_LABELS - , "Debug Text" + , "Debug Text" #endif - ); + ); } -KRCamera::~KRCamera() { - destroyBuffers(); -} - -std::string KRCamera::getElementName() { - return "camera"; -} - -tinyxml2::XMLElement *KRCamera::saveXML( tinyxml2::XMLNode *parent) +KRCamera::~KRCamera() { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - e->SetAttribute("skybox", m_skyBox.c_str()); - - return e; + destroyBuffers(); +} + +std::string KRCamera::getElementName() +{ + return "camera"; +} + +tinyxml2::XMLElement* KRCamera::saveXML(tinyxml2::XMLNode* parent) +{ + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + e->SetAttribute("skybox", m_skyBox.c_str()); + + return e; } -void KRCamera::loadXML(tinyxml2::XMLElement *e) +void KRCamera::loadXML(tinyxml2::XMLElement* e) { - KRNode::loadXML(e); - const char *szSkyBoxName = e->Attribute("skybox"); - m_skyBox = szSkyBoxName ? szSkyBoxName : ""; + KRNode::loadXML(e); + const char* szSkyBoxName = e->Attribute("skybox"); + m_skyBox = szSkyBoxName ? szSkyBoxName : ""; } -void KRCamera::setSkyBox(const std::string &skyBox) +void KRCamera::setSkyBox(const std::string& skyBox) { - m_pSkyBoxTexture = NULL; - m_skyBox = skyBox; - + m_pSkyBoxTexture = NULL; + m_skyBox = skyBox; + } const std::string KRCamera::getSkyBox() const { - return m_skyBox; + return m_skyBox; } void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeSurface) { - // ----====---- Record timing information for measuring FPS ----====---- - uint64_t current_time = m_pContext->getAbsoluteTimeMilliseconds(); - if(m_last_frame_start != 0) { - m_frame_times[m_pContext->getCurrentFrame() % KRAKEN_FPS_AVERAGE_FRAME_COUNT] = (int)(current_time - m_last_frame_start); - if(m_frame_times_filled < KRAKEN_FPS_AVERAGE_FRAME_COUNT) m_frame_times_filled++; + // ----====---- Record timing information for measuring FPS ----====---- + uint64_t current_time = m_pContext->getAbsoluteTimeMilliseconds(); + if (m_last_frame_start != 0) { + m_frame_times[m_pContext->getCurrentFrame() % KRAKEN_FPS_AVERAGE_FRAME_COUNT] = (int)(current_time - m_last_frame_start); + if (m_frame_times_filled < KRAKEN_FPS_AVERAGE_FRAME_COUNT) m_frame_times_filled++; + } + m_last_frame_start = current_time; + + createBuffers(compositeSurface.getWidth(), compositeSurface.getHeight()); + + KRScene& scene = getScene(); + + Matrix4 modelMatrix = getModelMatrix(); + Matrix4 viewMatrix = Matrix4::LookAt(Matrix4::Dot(modelMatrix, Vector3::Zero()), Matrix4::Dot(modelMatrix, Vector3::Forward()), Vector3::Normalize(Matrix4::DotNoTranslate(modelMatrix, Vector3::Up()))); + + //Matrix4 viewMatrix = Matrix4::Invert(getModelMatrix()); + + settings.setViewportSize(Vector2::Create((float)compositeSurface.getWidth(), (float)compositeSurface.getHeight())); + Matrix4 projectionMatrix{}; + projectionMatrix.perspective(settings.perspective_fov, settings.m_viewportSize.x / settings.m_viewportSize.y, settings.perspective_nearz, settings.perspective_farz); + m_viewport = KRViewport(settings.getViewportSize(), viewMatrix, projectionMatrix); + m_viewport.setLODBias(settings.getLODBias()); + + Vector3 vecCameraDirection = m_viewport.getCameraDirection(); + + + scene.updateOctree(m_viewport); + + // ----====---- Pre-stream resources ----====---- + scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_PRESTREAM, true); + + // ----====---- Generate Shadowmaps for Lights ----====---- + if (settings.m_cShadowBuffers > 0) { + GL_PUSH_GROUP_MARKER("Generate Shadowmaps"); + + scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, false /*settings.bEnableDeferredLighting*/); + GLDEBUG(glViewport(0, 0, (GLsizei)m_viewport.getSize().x, (GLsizei)m_viewport.getSize().y)); + GL_POP_GROUP_MARKER; + } + + if (settings.bEnableDeferredLighting) { + + // ----====---- Opaque Geometry, Deferred rendering Pass 1 ----====---- + + GL_PUSH_GROUP_MARKER("Deferred Lighting - Pass 1 (Opaque)"); + + // Start render pass + KRRenderPass& deferredGBufferPass = compositeSurface.getDeferredGBufferPass(); + deferredGBufferPass.begin(commandBuffer, compositeSurface, Vector4::Zero()); + + // Render the geometry + scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER, false); + + // End render pass + deferredGBufferPass.end(commandBuffer); + + GL_POP_GROUP_MARKER; + + + + // ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====---- + + GL_PUSH_GROUP_MARKER("Deferred Lighting - Pass 2 (Opaque)"); + + // Set render target + GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, lightAccumulationBuffer)); + GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0)); + GLDEBUG(glViewport(0, 0, (GLsizei)(m_viewport.getSize().x * m_downsample.x), (GLsizei)(m_viewport.getSize().y * m_downsample.y))); + GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); + GLDEBUG(glClear(GL_COLOR_BUFFER_BIT)); + + // Set source to buffers from pass 1 + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 6, compositeColorTexture); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 7, compositeDepthTexture); + + // Render the geometry + scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_LIGHTS, false); + + GL_POP_GROUP_MARKER; + + // ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====---- + + GL_PUSH_GROUP_MARKER("Deferred Lighting - Pass 3 (Opaque)"); + + // Start render pass + KRRenderPass& deferredOpaquePass = compositeSurface.getDeferredOpaquePass(); + deferredOpaquePass.begin(commandBuffer, compositeSurface, Vector4::Create(0.0f, 0.0f, 0.0f, 1.0f)); + + // Set source to buffers from pass 2 + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 6, lightAccumulationTexture); + + // Render the geometry + // TODO: At this point, we only want to render octree nodes that produced fragments during the 1st pass into the GBuffer + scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE, false); + + // End render pass + deferredOpaquePass.end(commandBuffer); + + GL_POP_GROUP_MARKER; + } else { + // ----====---- Opaque Geometry, Forward Rendering ----====---- + GL_PUSH_GROUP_MARKER("Forward Rendering - Opaque"); + /* + + GLDEBUG(glViewport(0, 0, (GLsizei)(m_viewport.getSize().x * m_downsample.x), (GLsizei)(m_viewport.getSize().y * m_downsample.y))); + */ + + // Start render pass + KRRenderPass& forwardOpaquePass = compositeSurface.getForwardOpaquePass(); + forwardOpaquePass.begin(commandBuffer, compositeSurface, Vector4::Create(0.0f, 0.0f, 0.0f, 1.0f)); + + // Render the geometry + scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE, false); + + GL_POP_GROUP_MARKER; + + // ---------- Start: Vulkan Debug Code ---------- + + KRMesh* sphereMesh = getContext().getMeshManager()->getMaxLODModel("__sphere"); + if (sphereMesh && sphereMesh->isReady()) { + PipelineInfo info{}; + std::string shader_name("vulkan_test"); + info.shader_name = &shader_name; + info.pCamera = this; + info.renderPass = KRNode::RENDER_PASS_FORWARD_TRANSPARENT; + info.rasterMode = RasterMode::kAlphaBlend; + info.vertexAttributes = sphereMesh->getVertexAttributes(); + info.modelFormat = sphereMesh->getModelFormat(); + KRPipeline* testPipeline = m_pContext->getPipelineManager()->getPipeline(compositeSurface, info); + testPipeline->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_OPAQUE); + sphereMesh->renderNoMaterials(commandBuffer, info.renderPass, "Vulkan Test", "vulkan_test", 1.0); } - m_last_frame_start = current_time; - createBuffers(compositeSurface.getWidth(), compositeSurface.getHeight()); - - KRScene &scene = getScene(); - - Matrix4 modelMatrix = getModelMatrix(); - Matrix4 viewMatrix = Matrix4::LookAt(Matrix4::Dot(modelMatrix, Vector3::Zero()), Matrix4::Dot(modelMatrix, Vector3::Forward()), Vector3::Normalize(Matrix4::DotNoTranslate(modelMatrix, Vector3::Up()))); - - //Matrix4 viewMatrix = Matrix4::Invert(getModelMatrix()); - - settings.setViewportSize(Vector2::Create((float)compositeSurface.getWidth(), (float)compositeSurface.getHeight())); - Matrix4 projectionMatrix{}; - projectionMatrix.perspective(settings.perspective_fov, settings.m_viewportSize.x / settings.m_viewportSize.y, settings.perspective_nearz, settings.perspective_farz); - m_viewport = KRViewport(settings.getViewportSize(), viewMatrix, projectionMatrix); - m_viewport.setLODBias(settings.getLODBias()); + // ---------- End: Vulkan Debug Code ---------- - Vector3 vecCameraDirection = m_viewport.getCameraDirection(); - - - scene.updateOctree(m_viewport); - - // ----====---- Pre-stream resources ----====---- - scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_PRESTREAM, true); - - // ----====---- Generate Shadowmaps for Lights ----====---- - if(settings.m_cShadowBuffers > 0) { - GL_PUSH_GROUP_MARKER("Generate Shadowmaps"); - - scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, false /*settings.bEnableDeferredLighting*/); - GLDEBUG(glViewport(0, 0, (GLsizei)m_viewport.getSize().x, (GLsizei)m_viewport.getSize().y)); - GL_POP_GROUP_MARKER; - } - - if(settings.bEnableDeferredLighting) { - - // ----====---- Opaque Geometry, Deferred rendering Pass 1 ----====---- - - GL_PUSH_GROUP_MARKER("Deferred Lighting - Pass 1 (Opaque)"); - - // Start render pass - KRRenderPass& deferredGBufferPass = compositeSurface.getDeferredGBufferPass(); - deferredGBufferPass.begin(commandBuffer, compositeSurface, Vector4::Zero()); - - // Render the geometry - scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER, false); - // End render pass - deferredGBufferPass.end(commandBuffer); - - GL_POP_GROUP_MARKER; - - - - // ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====---- - - GL_PUSH_GROUP_MARKER("Deferred Lighting - Pass 2 (Opaque)"); - - // Set render target - GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, lightAccumulationBuffer)); - GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0)); - GLDEBUG(glViewport(0, 0, (GLsizei)(m_viewport.getSize().x * m_downsample.x), (GLsizei)(m_viewport.getSize().y * m_downsample.y))); - GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); - GLDEBUG(glClear(GL_COLOR_BUFFER_BIT)); - - // Set source to buffers from pass 1 - m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 6, compositeColorTexture); - m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 7, compositeDepthTexture); - - // Render the geometry - scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_LIGHTS, false); - - GL_POP_GROUP_MARKER; - - // ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====---- - - GL_PUSH_GROUP_MARKER("Deferred Lighting - Pass 3 (Opaque)"); + forwardOpaquePass.end(commandBuffer); + } - // Start render pass - KRRenderPass& deferredOpaquePass = compositeSurface.getDeferredOpaquePass(); - deferredOpaquePass.begin(commandBuffer, compositeSurface, Vector4::Create(0.0f, 0.0f, 0.0f, 1.0f)); - - // Set source to buffers from pass 2 - m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 6, lightAccumulationTexture); - - // Render the geometry - // TODO: At this point, we only want to render octree nodes that produced fragments during the 1st pass into the GBuffer - scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE, false); - - // End render pass - deferredOpaquePass.end(commandBuffer); - - GL_POP_GROUP_MARKER; + // ----====---- Sky Box ----====---- + + GL_PUSH_GROUP_MARKER("Sky Box"); + + if (!m_pSkyBoxTexture && m_skyBox.length()) { + m_pSkyBoxTexture = getContext().getTextureManager()->getTextureCube(m_skyBox.c_str()); + } + + if (m_pSkyBoxTexture) { + + std::string shader_name("sky_box"); + PipelineInfo info{}; + info.shader_name = &shader_name; + info.pCamera = this; + info.renderPass = KRNode::RENDER_PASS_FORWARD_OPAQUE; + info.rasterMode = RasterMode::kOpaqueNoDepthWrite; + info.cullMode = CullMode::kCullNone; + + KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(compositeSurface, info); + pPipeline->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_OPAQUE); + + getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture, 0.0f, KRTexture::TEXTURE_USAGE_SKY_CUBE); + + // Render a full screen quad + m_pContext->getMeshManager()->bindVBO(commandBuffer, &getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES, 1.0f); + GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); + } + + GL_POP_GROUP_MARKER; + + + // ----====---- Transparent Geometry, Forward Rendering ----====---- + + GL_PUSH_GROUP_MARKER("Forward Rendering - Transparent"); + + // Render all transparent geometry + scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, false); + + GL_POP_GROUP_MARKER; + + // ----====---- Particle Occlusion Tests ----====---- + + GL_PUSH_GROUP_MARKER("Particle Occlusion Tests"); + + // ----====---- Perform Occlusion Tests ----====---- + scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, RENDER_PASS_PARTICLE_OCCLUSION, false); + + GL_POP_GROUP_MARKER; + + // ----====---- Flares ----====---- + + GL_PUSH_GROUP_MARKER("Additive Particles"); + + // Render all flares + scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_ADDITIVE_PARTICLES, false); + + GL_POP_GROUP_MARKER; + + // ----====---- Volumetric Lighting ----====---- + + if (settings.volumetric_environment_enable) { + + GL_PUSH_GROUP_MARKER("Volumetric Lighting"); + + KRViewport volumetricLightingViewport = KRViewport(Vector2::Create((float)volumetricBufferWidth, (float)volumetricBufferHeight), m_viewport.getViewMatrix(), m_viewport.getProjectionMatrix()); + + if (settings.volumetric_environment_downsample != 0) { + // Set render target + GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, volumetricLightAccumulationBuffer)); + GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); + GLDEBUG(glClear(GL_COLOR_BUFFER_BIT)); + + // Disable z-buffer test + GLDEBUG(glDisable(GL_DEPTH_TEST)); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 0, compositeDepthTexture); + + GLDEBUG(glViewport(0, 0, (GLsizei)volumetricLightingViewport.getSize().x, (GLsizei)volumetricLightingViewport.getSize().y)); } else { - // ----====---- Opaque Geometry, Forward Rendering ----====---- - GL_PUSH_GROUP_MARKER("Forward Rendering - Opaque"); - /* - - GLDEBUG(glViewport(0, 0, (GLsizei)(m_viewport.getSize().x * m_downsample.x), (GLsizei)(m_viewport.getSize().y * m_downsample.y))); - */ - - // Start render pass - KRRenderPass& forwardOpaquePass = compositeSurface.getForwardOpaquePass(); - forwardOpaquePass.begin(commandBuffer, compositeSurface, Vector4::Create(0.0f, 0.0f, 0.0f, 1.0f)); - - // Render the geometry - scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE, false); - - GL_POP_GROUP_MARKER; - - // ---------- Start: Vulkan Debug Code ---------- - - KRMesh* sphereMesh = getContext().getMeshManager()->getMaxLODModel("__sphere"); - if (sphereMesh && sphereMesh->isReady()) { - PipelineInfo info{}; - std::string shader_name("vulkan_test"); - info.shader_name = &shader_name; - info.pCamera = this; - info.renderPass = KRNode::RENDER_PASS_FORWARD_TRANSPARENT; - info.rasterMode = RasterMode::kAlphaBlend; - info.vertexAttributes = sphereMesh->getVertexAttributes(); - info.modelFormat = sphereMesh->getModelFormat(); - KRPipeline* testPipeline = m_pContext->getPipelineManager()->getPipeline(compositeSurface, info); - testPipeline->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_OPAQUE); - sphereMesh->renderNoMaterials(commandBuffer, info.renderPass, "Vulkan Test", "vulkan_test", 1.0); - } - - // ---------- End: Vulkan Debug Code ---------- - - - forwardOpaquePass.end(commandBuffer); - } - - // ----====---- Sky Box ----====---- - - GL_PUSH_GROUP_MARKER("Sky Box"); - - if(!m_pSkyBoxTexture && m_skyBox.length()) { - m_pSkyBoxTexture = getContext().getTextureManager()->getTextureCube(m_skyBox.c_str()); - } - - if(m_pSkyBoxTexture) { - - std::string shader_name("sky_box"); - PipelineInfo info{}; - info.shader_name = &shader_name; - info.pCamera = this; - info.renderPass = KRNode::RENDER_PASS_FORWARD_OPAQUE; - info.rasterMode = RasterMode::kOpaqueNoDepthWrite; - info.cullMode = CullMode::kCullNone; - - KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(compositeSurface, info); - pPipeline->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_OPAQUE); - - getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture, 0.0f, KRTexture::TEXTURE_USAGE_SKY_CUBE); - - // Render a full screen quad - m_pContext->getMeshManager()->bindVBO(commandBuffer, &getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES, 1.0f); - GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); - } - - GL_POP_GROUP_MARKER; - - - // ----====---- Transparent Geometry, Forward Rendering ----====---- - - GL_PUSH_GROUP_MARKER("Forward Rendering - Transparent"); - - // Render all transparent geometry - scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, false); - - GL_POP_GROUP_MARKER; - - // ----====---- Particle Occlusion Tests ----====---- - - GL_PUSH_GROUP_MARKER("Particle Occlusion Tests"); - - // ----====---- Perform Occlusion Tests ----====---- - scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, RENDER_PASS_PARTICLE_OCCLUSION, false); - - GL_POP_GROUP_MARKER; - - // ----====---- Flares ----====---- - - GL_PUSH_GROUP_MARKER("Additive Particles"); - - // Render all flares - scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_ADDITIVE_PARTICLES, false); - - GL_POP_GROUP_MARKER; - - // ----====---- Volumetric Lighting ----====---- - - if(settings.volumetric_environment_enable) { - - GL_PUSH_GROUP_MARKER("Volumetric Lighting"); - - KRViewport volumetricLightingViewport = KRViewport(Vector2::Create((float)volumetricBufferWidth, (float)volumetricBufferHeight), m_viewport.getViewMatrix(), m_viewport.getProjectionMatrix()); - - if(settings.volumetric_environment_downsample != 0) { - // Set render target - GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, volumetricLightAccumulationBuffer)); - GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); - GLDEBUG(glClear(GL_COLOR_BUFFER_BIT)); - - // Disable z-buffer test - GLDEBUG(glDisable(GL_DEPTH_TEST)); - m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 0, compositeDepthTexture); - - GLDEBUG(glViewport(0, 0, (GLsizei)volumetricLightingViewport.getSize().x, (GLsizei)volumetricLightingViewport.getSize().y)); - } else { - // Enable z-buffer test - GLDEBUG(glEnable(GL_DEPTH_TEST)); - GLDEBUG(glDepthFunc(GL_LEQUAL)); - GLDEBUG(glDepthRangef(0.0, 1.0)); - } - - scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), volumetricLightingViewport, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, false); - - GL_POP_GROUP_MARKER; + // Enable z-buffer test + GLDEBUG(glEnable(GL_DEPTH_TEST)); + GLDEBUG(glDepthFunc(GL_LEQUAL)); + GLDEBUG(glDepthRangef(0.0, 1.0)); } - - - // ----====---- Debug Overlay ----====---- - - GL_PUSH_GROUP_MARKER("Debug Overlays"); - - if(settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_OCTREE) { - KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_3D_CUBE_VERTICES; + scene.render(commandBuffer, compositeSurface, this, m_viewport.getVisibleBounds(), volumetricLightingViewport, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, false); - PipelineInfo info{}; - std::string shader_name("visualize_overlay"); - info.shader_name = &shader_name; - info.pCamera = this; - info.renderPass = KRNode::RENDER_PASS_FORWARD_TRANSPARENT; - info.rasterMode = RasterMode::kAdditive; - info.vertexAttributes = vertices.getVertexAttributes(); - info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; - KRPipeline *pVisShader = getContext().getPipelineManager()->getPipeline(compositeSurface, info); - - m_pContext->getMeshManager()->bindVBO(commandBuffer, &vertices, 1.0f); - for(unordered_map::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) { - Matrix4 matModel = Matrix4(); - matModel.scale((*itr).first.size() * 0.5f); - matModel.translate((*itr).first.center()); - pVisShader->bind(commandBuffer, *this, m_viewport, matModel, nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - vkCmdDraw(commandBuffer, 14, 1, 0, 0); - } + GL_POP_GROUP_MARKER; + } + + + + // ----====---- Debug Overlay ----====---- + + GL_PUSH_GROUP_MARKER("Debug Overlays"); + + if (settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_OCTREE) { + KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_3D_CUBE_VERTICES; + + PipelineInfo info{}; + std::string shader_name("visualize_overlay"); + info.shader_name = &shader_name; + info.pCamera = this; + info.renderPass = KRNode::RENDER_PASS_FORWARD_TRANSPARENT; + info.rasterMode = RasterMode::kAdditive; + info.vertexAttributes = vertices.getVertexAttributes(); + info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; + KRPipeline* pVisShader = getContext().getPipelineManager()->getPipeline(compositeSurface, info); + + m_pContext->getMeshManager()->bindVBO(commandBuffer, &vertices, 1.0f); + for (unordered_map::iterator itr = m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) { + Matrix4 matModel = Matrix4(); + matModel.scale((*itr).first.size() * 0.5f); + matModel.translate((*itr).first.center()); + pVisShader->bind(commandBuffer, *this, m_viewport, matModel, nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + vkCmdDraw(commandBuffer, 14, 1, 0, 0); } - GL_POP_GROUP_MARKER; + } + GL_POP_GROUP_MARKER; -// fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i/%i Kbyte (active/total) Shader Handles: %i Visible Bounds: %i Max Texture LOD: %i\n", (int)m_pContext->getMeshManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getActiveMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024, (int)m_pContext->getPipelineManager()->getShaderHandlesUsed(), (int)m_visibleBounds.size(), m_pContext->getTextureManager()->getLODDimCap()); + // fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i/%i Kbyte (active/total) Shader Handles: %i Visible Bounds: %i Max Texture LOD: %i\n", (int)m_pContext->getMeshManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getActiveMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024, (int)m_pContext->getPipelineManager()->getShaderHandlesUsed(), (int)m_visibleBounds.size(), m_pContext->getTextureManager()->getLODDimCap()); - GL_PUSH_GROUP_MARKER("Post Processing"); + GL_PUSH_GROUP_MARKER("Post Processing"); - renderPost(commandBuffer, compositeSurface); - - GL_POP_GROUP_MARKER; + renderPost(commandBuffer, compositeSurface); + + GL_POP_GROUP_MARKER; } -void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) { +void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) +{ // TODO - Vulkan Refactoring.. /* if(renderBufferWidth != m_backingWidth || renderBufferHeight != m_backingHeight) { m_backingWidth = renderBufferWidth; m_backingHeight = renderBufferHeight; - + if (compositeDepthTexture) { GLDEBUG(glDeleteTextures(1, &compositeDepthTexture)); compositeDepthTexture = 0; } - + if (compositeColorTexture) { GLDEBUG(glDeleteTextures(1, &compositeColorTexture)); compositeColorTexture = 0; } - + if (lightAccumulationTexture) { GLDEBUG(glDeleteTextures(1, &lightAccumulationTexture)); lightAccumulationTexture = 0; } - + if (compositeFramebuffer) { GLDEBUG(glDeleteFramebuffers(1, &compositeFramebuffer)); compositeFramebuffer = 0; } - + if (lightAccumulationBuffer) { GLDEBUG(glDeleteFramebuffers(1, &lightAccumulationBuffer)); lightAccumulationBuffer = 0; } - + // ===== Create offscreen compositing framebuffer object ===== GLDEBUG(glGenFramebuffers(1, &compositeFramebuffer)); GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer)); - + // ----- Create texture color buffer for compositeFramebuffer ----- GLDEBUG(glGenTextures(1, &compositeColorTexture)); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeColorTexture)); @@ -422,7 +426,7 @@ void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_backingWidth, m_backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, compositeColorTexture, 0)); - + // ----- Create Depth Texture for compositeFramebuffer ----- GLDEBUG(glGenTextures(1, &compositeDepthTexture)); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); @@ -434,11 +438,11 @@ void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) //GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, m_backingWidth, m_backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); //GLDEBUG(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, m_backingWidth, m_backingHeight)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0)); - + // ===== Create offscreen compositing framebuffer object ===== GLDEBUG(glGenFramebuffers(1, &lightAccumulationBuffer)); GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, lightAccumulationBuffer)); - + // ----- Create texture color buffer for compositeFramebuffer ----- GLDEBUG(glGenTextures(1, &lightAccumulationTexture)); GLDEBUG(glBindTexture(GL_TEXTURE_2D, lightAccumulationTexture)); @@ -449,35 +453,35 @@ void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_backingWidth, m_backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightAccumulationTexture, 0)); } - + int targetVolumetricBufferWidth = 0; int targetVolumetricBufferHeight = 0; if(settings.volumetric_environment_enable && settings.volumetric_environment_downsample != 0) { targetVolumetricBufferWidth = renderBufferWidth >> settings.volumetric_environment_downsample; targetVolumetricBufferHeight = renderBufferHeight >> settings.volumetric_environment_downsample; } - - + + if(targetVolumetricBufferWidth != volumetricBufferWidth || targetVolumetricBufferHeight != volumetricBufferHeight) { volumetricBufferWidth = targetVolumetricBufferWidth; volumetricBufferHeight = targetVolumetricBufferHeight; - + if (volumetricLightAccumulationTexture) { GLDEBUG(glDeleteTextures(1, &volumetricLightAccumulationTexture)); volumetricLightAccumulationTexture = 0; } - + if (volumetricLightAccumulationBuffer) { GLDEBUG(glDeleteFramebuffers(1, &volumetricLightAccumulationBuffer)); volumetricLightAccumulationBuffer = 0; } - - + + if(targetVolumetricBufferWidth != 0 && targetVolumetricBufferHeight != 0) { // ===== Create offscreen compositing framebuffer object for volumetric lighting ===== GLDEBUG(glGenFramebuffers(1, &volumetricLightAccumulationBuffer)); GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, volumetricLightAccumulationBuffer)); - + // ----- Create texture color buffer for compositeFramebuffer for volumetric lighting ----- GLDEBUG(glGenTextures(1, &volumetricLightAccumulationTexture)); GLDEBUG(glBindTexture(GL_TEXTURE_2D, volumetricLightAccumulationTexture)); @@ -500,32 +504,32 @@ void KRCamera::destroyBuffers() GLDEBUG(glDeleteTextures(1, &compositeDepthTexture)); compositeDepthTexture = 0; } - + if (compositeColorTexture) { - GLDEBUG(glDeleteTextures(1, &compositeColorTexture)); - compositeColorTexture = 0; - } - + GLDEBUG(glDeleteTextures(1, &compositeColorTexture)); + compositeColorTexture = 0; + } + if (lightAccumulationTexture) { GLDEBUG(glDeleteTextures(1, &lightAccumulationTexture)); lightAccumulationTexture = 0; } - + if (compositeFramebuffer) { GLDEBUG(glDeleteFramebuffers(1, &compositeFramebuffer)); compositeFramebuffer = 0; } - + if (lightAccumulationBuffer) { GLDEBUG(glDeleteFramebuffers(1, &lightAccumulationBuffer)); lightAccumulationBuffer = 0; } - + if (volumetricLightAccumulationTexture) { GLDEBUG(glDeleteTextures(1, &volumetricLightAccumulationTexture)); volumetricLightAccumulationTexture = 0; } - + if (volumetricLightAccumulationBuffer) { GLDEBUG(glDeleteFramebuffers(1, &volumetricLightAccumulationBuffer)); volumetricLightAccumulationBuffer = 0; @@ -549,422 +553,422 @@ void KRCamera::renderPost(VkCommandBuffer& commandBuffer, KRSurface& surface) info.vertexAttributes = vertices.getVertexAttributes(); KRPipeline *postShader = m_pContext->getPipelineManager()->getPipeline(surface, info); - + postShader->setUniform(KRPipeline::Uniform::fade_color, m_fade_color); postShader->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 0, compositeDepthTexture); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 1, compositeColorTexture); if(settings.volumetric_environment_enable) { m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 2, volumetricLightAccumulationTexture); } - - // Update attribute values. + + // Update attribute values. m_pContext->getMeshManager()->bindVBO(commandBuffer, &vertices, 1.0f); - + vkCmdDraw(commandBuffer, 4, 1, 0, 0); */ - - -// if(bShowShadowBuffer) { -// KRPipeline *blitShader = m_pContext->getPipelineManager()->getShader("simple_blit", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); -// -// for(int iShadow=0; iShadow < m_cShadowBuffers; iShadow++) { -// Matrix4 viewMatrix = Matrix4(); -// viewMatrix.scale(0.20, 0.20, 0.20); -// viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0); -// getContext().getPipelineManager()->selectShader(blitShader, KRViewport(getViewportSize(), viewMatrix, Matrix4()), shadowViewports, Matrix4(), Vector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); -// m_pContext->getTextureManager()->selectTexture(1, NULL); -// m_pContext->getMeshManager()->bindVBO(&getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES); -// m_pContext->getTextureManager()->_setActiveTexture(0); -// GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow])); -//#if GL_EXT_shadow_samplers -// GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_NONE)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available -//#endif -// GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); -//#if GL_EXT_shadow_samplers -// GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_COMPARE_REF_TO_TEXTURE_EXT)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available -//#endif -// } -// -// m_pContext->getTextureManager()->selectTexture(0, NULL); -// m_pContext->getTextureManager()->_setActiveTexture(0); -// GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); -// } - const char *szText = settings.m_debug_text.c_str(); - - std::string debug_text; - if(settings.debug_display != KRRenderSettings::KRENGINE_DEBUG_DISPLAY_NONE) { - debug_text = getDebugText();; - if(debug_text.length() > 0) { - szText = debug_text.c_str(); - } - } - // TODO - Test code for Vulkan conversion, remove once texture streaming working - szText = "Hello, earthlings!"; - - if(*szText) { - int row_count = 1; - const int MAX_TABS = 5; - const int TAB_EXTRA = 2; - int tab_cols[MAX_TABS] = {0, 0, 0, 0, 0}; - int iCol = 0; - int iTab = 0; - const char *pChar = szText; - while(*pChar) { - char c = *pChar++; - if(c == '\n') { - row_count++; - iCol = 0; - iTab = 0; - } else if(c == '\t') { - iCol = 0; - iTab++; - } else { - iCol++; - if(iCol > tab_cols[iTab]) tab_cols[iTab] = iCol; - } - } - + + // if(bShowShadowBuffer) { + // KRPipeline *blitShader = m_pContext->getPipelineManager()->getShader("simple_blit", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + // + // for(int iShadow=0; iShadow < m_cShadowBuffers; iShadow++) { + // Matrix4 viewMatrix = Matrix4(); + // viewMatrix.scale(0.20, 0.20, 0.20); + // viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0); + // getContext().getPipelineManager()->selectShader(blitShader, KRViewport(getViewportSize(), viewMatrix, Matrix4()), shadowViewports, Matrix4(), Vector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + // m_pContext->getTextureManager()->selectTexture(1, NULL); + // m_pContext->getMeshManager()->bindVBO(&getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES); + // m_pContext->getTextureManager()->_setActiveTexture(0); + // GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow])); + //#if GL_EXT_shadow_samplers + // GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_NONE)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available + //#endif + // GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); + //#if GL_EXT_shadow_samplers + // GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_COMPARE_REF_TO_TEXTURE_EXT)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available + //#endif + // } + // + // m_pContext->getTextureManager()->selectTexture(0, NULL); + // m_pContext->getTextureManager()->_setActiveTexture(0); + // GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); + // } + const char* szText = settings.m_debug_text.c_str(); + + std::string debug_text; + if (settings.debug_display != KRRenderSettings::KRENGINE_DEBUG_DISPLAY_NONE) { + debug_text = getDebugText();; + if (debug_text.length() > 0) { + szText = debug_text.c_str(); + } + } + + // TODO - Test code for Vulkan conversion, remove once texture streaming working + szText = "Hello, earthlings!"; + + if (*szText) { + int row_count = 1; + const int MAX_TABS = 5; + const int TAB_EXTRA = 2; + int tab_cols[MAX_TABS] = { 0, 0, 0, 0, 0 }; + int iCol = 0; + int iTab = 0; + const char* pChar = szText; + while (*pChar) { + char c = *pChar++; + if (c == '\n') { + row_count++; iCol = 0; - for(iTab=0; iTab < MAX_TABS; iTab++) { - iCol += tab_cols[iTab] + TAB_EXTRA; - tab_cols[iTab] = iCol; - } - - const int DEBUG_TEXT_COLUMNS = 256; - const int DEBUG_TEXT_ROWS = 128; - - if(m_debug_text_vertices.getSize() == 0) { - m_debug_text_vertices.expand(sizeof(DebugTextVertexData) * DEBUG_TEXT_COLUMNS * DEBUG_TEXT_ROWS * 6); - } - int vertex_count = 0; - - m_debug_text_vertices.lock(); - DebugTextVertexData *vertex_data = (DebugTextVertexData *)m_debug_text_vertices.getStart(); - - pChar = szText; - float dScaleX = 2.0f / (1024.0f / 16.0f); - float dScaleY = 2.0f / (768.0f / 16.0f); - float dTexScale = 1.0f / 16.0f; - int iRow = row_count - 1; iCol = 0; iTab = 0; - while(*pChar) { - char c = *pChar++; - if(c == '\n') { - iCol = 0; - iTab = 0; - iRow--; - } else if(c == '\t') { - iCol = tab_cols[iTab++]; - } else { - if(iCol < DEBUG_TEXT_COLUMNS && iRow < DEBUG_TEXT_ROWS) { - int iChar = c - '\0'; - int iTexCol = iChar % 16; - int iTexRow = 15 - (iChar - iTexCol) / 16; - - Vector2 top_left_pos = Vector2::Create(-1.0f + dScaleX * iCol, dScaleY * iRow - 1.0f); - Vector2 bottom_right_pos = Vector2::Create(-1.0f + dScaleX * (iCol + 1), dScaleY * iRow + dScaleY - 1.0f); - top_left_pos += Vector2::Create(1.0f / 2048.0f * 0.5f, 1.0f / 1536.0f * 0.5f); - bottom_right_pos += Vector2::Create(1.0f / 2048.0f * 0.5f, 1.0f / 1536.0f * 0.5f); - Vector2 top_left_uv = Vector2::Create(dTexScale * iTexCol, dTexScale * iTexRow); - Vector2 bottom_right_uv = Vector2::Create(dTexScale * iTexCol + dTexScale, dTexScale * iTexRow + dTexScale); - - vertex_data[vertex_count].x = top_left_pos.x; - vertex_data[vertex_count].y = top_left_pos.y; - vertex_data[vertex_count].z = 0.0f; - vertex_data[vertex_count].u = top_left_uv.x; - vertex_data[vertex_count].v = top_left_uv.y; - vertex_count++; - - vertex_data[vertex_count].x = bottom_right_pos.x; - vertex_data[vertex_count].y = bottom_right_pos.y; - vertex_data[vertex_count].z = 0.0f; - vertex_data[vertex_count].u = bottom_right_uv.x; - vertex_data[vertex_count].v = bottom_right_uv.y; - vertex_count++; - - vertex_data[vertex_count].x = top_left_pos.x; - vertex_data[vertex_count].y = bottom_right_pos.y; - vertex_data[vertex_count].z = 0.0f; - vertex_data[vertex_count].u = top_left_uv.x; - vertex_data[vertex_count].v = bottom_right_uv.y; - vertex_count++; - - - vertex_data[vertex_count].x = top_left_pos.x; - vertex_data[vertex_count].y = top_left_pos.y; - vertex_data[vertex_count].z = 0.0f; - vertex_data[vertex_count].u = top_left_uv.x; - vertex_data[vertex_count].v = top_left_uv.y; - vertex_count++; - - vertex_data[vertex_count].x = bottom_right_pos.x; - vertex_data[vertex_count].y = top_left_pos.y; - vertex_data[vertex_count].z = 0.0f; - vertex_data[vertex_count].u = bottom_right_uv.x; - vertex_data[vertex_count].v = top_left_uv.y; - vertex_count++; - - vertex_data[vertex_count].x = bottom_right_pos.x; - vertex_data[vertex_count].y = bottom_right_pos.y; - vertex_data[vertex_count].z = 0.0f; - vertex_data[vertex_count].u = bottom_right_uv.x; - vertex_data[vertex_count].v = bottom_right_uv.y; - vertex_count++; - } - - iCol++; - } - } - - PipelineInfo info{}; - std::string shader_name("debug_font"); - info.shader_name = &shader_name; - info.pCamera = this; - info.renderPass = KRNode::RENDER_PASS_FORWARD_TRANSPARENT; - info.rasterMode = RasterMode::kAlphaBlendNoTest; - info.cullMode = CullMode::kCullNone; - info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); - info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; - KRPipeline *fontShader = m_pContext->getPipelineManager()->getPipeline(surface, info); - fontShader->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - - m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font"), 0.0f, KRTexture::TEXTURE_USAGE_UI); - - m_debug_text_vbo_data.load(commandBuffer); - m_debug_text_vbo_data.bind(commandBuffer); - - // vkCmdDraw(commandBuffer, vertex_count, 1, 0, 0); - - m_debug_text_vertices.unlock(); - - } else { - if(m_debug_text_vertices.getSize() > 0) { - m_debug_text_vertices = KRDataBlock(); - } + iTab = 0; + } else if (c == '\t') { + iCol = 0; + iTab++; + } else { + iCol++; + if (iCol > tab_cols[iTab]) tab_cols[iTab] = iCol; + } } + + iCol = 0; + for (iTab = 0; iTab < MAX_TABS; iTab++) { + iCol += tab_cols[iTab] + TAB_EXTRA; + tab_cols[iTab] = iCol; + } + + const int DEBUG_TEXT_COLUMNS = 256; + const int DEBUG_TEXT_ROWS = 128; + + if (m_debug_text_vertices.getSize() == 0) { + m_debug_text_vertices.expand(sizeof(DebugTextVertexData) * DEBUG_TEXT_COLUMNS * DEBUG_TEXT_ROWS * 6); + } + int vertex_count = 0; + + m_debug_text_vertices.lock(); + DebugTextVertexData* vertex_data = (DebugTextVertexData*)m_debug_text_vertices.getStart(); + + pChar = szText; + float dScaleX = 2.0f / (1024.0f / 16.0f); + float dScaleY = 2.0f / (768.0f / 16.0f); + float dTexScale = 1.0f / 16.0f; + int iRow = row_count - 1; iCol = 0; iTab = 0; + while (*pChar) { + char c = *pChar++; + if (c == '\n') { + iCol = 0; + iTab = 0; + iRow--; + } else if (c == '\t') { + iCol = tab_cols[iTab++]; + } else { + if (iCol < DEBUG_TEXT_COLUMNS && iRow < DEBUG_TEXT_ROWS) { + int iChar = c - '\0'; + int iTexCol = iChar % 16; + int iTexRow = 15 - (iChar - iTexCol) / 16; + + Vector2 top_left_pos = Vector2::Create(-1.0f + dScaleX * iCol, dScaleY * iRow - 1.0f); + Vector2 bottom_right_pos = Vector2::Create(-1.0f + dScaleX * (iCol + 1), dScaleY * iRow + dScaleY - 1.0f); + top_left_pos += Vector2::Create(1.0f / 2048.0f * 0.5f, 1.0f / 1536.0f * 0.5f); + bottom_right_pos += Vector2::Create(1.0f / 2048.0f * 0.5f, 1.0f / 1536.0f * 0.5f); + Vector2 top_left_uv = Vector2::Create(dTexScale * iTexCol, dTexScale * iTexRow); + Vector2 bottom_right_uv = Vector2::Create(dTexScale * iTexCol + dTexScale, dTexScale * iTexRow + dTexScale); + + vertex_data[vertex_count].x = top_left_pos.x; + vertex_data[vertex_count].y = top_left_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = top_left_uv.x; + vertex_data[vertex_count].v = top_left_uv.y; + vertex_count++; + + vertex_data[vertex_count].x = bottom_right_pos.x; + vertex_data[vertex_count].y = bottom_right_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = bottom_right_uv.x; + vertex_data[vertex_count].v = bottom_right_uv.y; + vertex_count++; + + vertex_data[vertex_count].x = top_left_pos.x; + vertex_data[vertex_count].y = bottom_right_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = top_left_uv.x; + vertex_data[vertex_count].v = bottom_right_uv.y; + vertex_count++; + + + vertex_data[vertex_count].x = top_left_pos.x; + vertex_data[vertex_count].y = top_left_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = top_left_uv.x; + vertex_data[vertex_count].v = top_left_uv.y; + vertex_count++; + + vertex_data[vertex_count].x = bottom_right_pos.x; + vertex_data[vertex_count].y = top_left_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = bottom_right_uv.x; + vertex_data[vertex_count].v = top_left_uv.y; + vertex_count++; + + vertex_data[vertex_count].x = bottom_right_pos.x; + vertex_data[vertex_count].y = bottom_right_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = bottom_right_uv.x; + vertex_data[vertex_count].v = bottom_right_uv.y; + vertex_count++; + } + + iCol++; + } + } + + PipelineInfo info{}; + std::string shader_name("debug_font"); + info.shader_name = &shader_name; + info.pCamera = this; + info.renderPass = KRNode::RENDER_PASS_FORWARD_TRANSPARENT; + info.rasterMode = RasterMode::kAlphaBlendNoTest; + info.cullMode = CullMode::kCullNone; + info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); + info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; + KRPipeline* fontShader = m_pContext->getPipelineManager()->getPipeline(surface, info); + fontShader->bind(commandBuffer, *this, m_viewport, Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + + m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font"), 0.0f, KRTexture::TEXTURE_USAGE_UI); + + m_debug_text_vbo_data.load(commandBuffer); + m_debug_text_vbo_data.bind(commandBuffer); + + // vkCmdDraw(commandBuffer, vertex_count, 1, 0, 0); + + m_debug_text_vertices.unlock(); + + } else { + if (m_debug_text_vertices.getSize() > 0) { + m_debug_text_vertices = KRDataBlock(); + } + } } std::string KRCamera::getDebugText() { - std::stringstream stream; - stream.precision(std::numeric_limits::digits10); - - - - uint64_t fps = 0; - if(m_frame_times_filled == KRAKEN_FPS_AVERAGE_FRAME_COUNT) { - for(int i=0; i < KRAKEN_FPS_AVERAGE_FRAME_COUNT; i++) { - fps += m_frame_times[i]; - } - fps = 1000000 / (fps / KRAKEN_FPS_AVERAGE_FRAME_COUNT); // Order of division chosen to prevent overflow + std::stringstream stream; + stream.precision(std::numeric_limits::digits10); + + + + uint64_t fps = 0; + if (m_frame_times_filled == KRAKEN_FPS_AVERAGE_FRAME_COUNT) { + for (int i = 0; i < KRAKEN_FPS_AVERAGE_FRAME_COUNT; i++) { + fps += m_frame_times[i]; } - - switch(settings.debug_display) { - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_NONE: // ----====---- No debug display ----====---- - break; - - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_TIME: // ----====---- Time / FPS ----====---- - { - if(fps > 0) { - stream << "FPS\t" << fps; - } - } - break; - - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_MEMORY: // ----====---- Memory Utilization ----=====---- - { + fps = 1000000 / (fps / KRAKEN_FPS_AVERAGE_FRAME_COUNT); // Order of division chosen to prevent overflow + } + + switch (settings.debug_display) { + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_NONE: // ----====---- No debug display ----====---- + break; + + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_TIME: // ----====---- Time / FPS ----====---- + { + if (fps > 0) { + stream << "FPS\t" << fps; + } + } + break; + + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_MEMORY: // ----====---- Memory Utilization ----=====---- + { #if defined(__APPLE__) - // ---- CPU Memory ---- - - struct task_basic_info info; - mach_msg_type_number_t size = sizeof(info); - kern_return_t kerr = task_info(mach_task_self(), - TASK_BASIC_INFO, - (task_info_t)&info, - &size); - if( kerr == KERN_SUCCESS ) { - stream << "\tResident\tVirtual\tTotal"; - stream << "\nCPU\t" << (info.resident_size / 1024 / 1024) << " MB\t" << (info.virtual_size / 1024 / 1024) << " MB\t" << ((info.resident_size + info.virtual_size) / 1024 / 1024) << " MB"; - } else { - stream << "\nERROR: Could not get CPU memory utilization."; - } - - - mach_port_t host_port = mach_host_self(); - mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); - vm_size_t pagesize = 0; - vm_statistics_data_t vm_stat; - if(host_page_size(host_port, &pagesize) != KERN_SUCCESS) { - stream << "\n\nERROR: Could not get VM page size."; - } else if(host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) { - stream << "\n\nERROR: Could not get VM stats."; - } else { - stream << "\n\n\n\tWired\tActive\tInactive\tFree\tTotal"; - stream << "\nVM\t"; - stream << (vm_stat.wire_count * pagesize / 1024 / 1024) << " MB\t"; - stream << (vm_stat.active_count * pagesize / 1024 / 1024) << " MB\t"; - stream << (vm_stat.inactive_count * pagesize / 1024 / 1024) << " MB\t"; - stream << (vm_stat.free_count * pagesize / 1024 / 1024) << " MB\t"; - stream << ((vm_stat.wire_count + vm_stat.active_count + vm_stat.inactive_count) * pagesize / 1024 / 1024) << " MB"; - } + // ---- CPU Memory ---- + + struct task_basic_info info; + mach_msg_type_number_t size = sizeof(info); + kern_return_t kerr = task_info(mach_task_self(), + TASK_BASIC_INFO, + (task_info_t)&info, + &size); + if (kerr == KERN_SUCCESS) { + stream << "\tResident\tVirtual\tTotal"; + stream << "\nCPU\t" << (info.resident_size / 1024 / 1024) << " MB\t" << (info.virtual_size / 1024 / 1024) << " MB\t" << ((info.resident_size + info.virtual_size) / 1024 / 1024) << " MB"; + } else { + stream << "\nERROR: Could not get CPU memory utilization."; + } + + + mach_port_t host_port = mach_host_self(); + mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); + vm_size_t pagesize = 0; + vm_statistics_data_t vm_stat; + if (host_page_size(host_port, &pagesize) != KERN_SUCCESS) { + stream << "\n\nERROR: Could not get VM page size."; + } else if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) { + stream << "\n\nERROR: Could not get VM stats."; + } else { + stream << "\n\n\n\tWired\tActive\tInactive\tFree\tTotal"; + stream << "\nVM\t"; + stream << (vm_stat.wire_count * pagesize / 1024 / 1024) << " MB\t"; + stream << (vm_stat.active_count * pagesize / 1024 / 1024) << " MB\t"; + stream << (vm_stat.inactive_count * pagesize / 1024 / 1024) << " MB\t"; + stream << (vm_stat.free_count * pagesize / 1024 / 1024) << " MB\t"; + stream << ((vm_stat.wire_count + vm_stat.active_count + vm_stat.inactive_count) * pagesize / 1024 / 1024) << " MB"; + } #endif // defined(__APPLE__) - // ---- GPU Memory ---- - size_t texture_count_active = m_pContext->getTextureManager()->getActiveTextures().size(); - size_t texture_count = texture_count_active; - long texture_mem_active = m_pContext->getTextureManager()->getMemActive(); - long texture_mem_used = m_pContext->getTextureManager()->getMemUsed(); - long texture_mem_throughput = m_pContext->getTextureManager()->getMemoryTransferedThisFrame(); - - size_t vbo_count_active = m_pContext->getMeshManager()->getActiveVBOCount(); - long vbo_mem_active = m_pContext->getMeshManager()->getMemActive(); - long vbo_mem_used = m_pContext->getMeshManager()->getMemUsed(); - long vbo_mem_throughput = m_pContext->getMeshManager()->getMemoryTransferedThisFrame(); - - long total_mem_active = texture_mem_active + vbo_mem_active; - long total_mem_used = texture_mem_used + vbo_mem_used; - long total_mem_throughput = texture_mem_throughput + vbo_mem_throughput; - - stream << "\n\n\n\t# Active\t# Used\tActive\tUsed\tThroughput\n"; - - stream << "Textures\t" << texture_count_active << "\t" << texture_count << "\t" << (texture_mem_active / 1024) << " KB\t" << (texture_mem_used / 1024) << " KB\t" << (texture_mem_throughput / 1024) << " KB / frame\n"; - stream << "VBO's\t" << vbo_count_active << "\t" << vbo_count_active << "\t" << (vbo_mem_active / 1024) <<" KB\t" << (vbo_mem_used / 1024) << " KB\t" << (vbo_mem_throughput / 1024) << " KB / frame\n"; - stream << "\nGPU Total\t\t\t" << (total_mem_active / 1024) << " KB\t" << (total_mem_used / 1024) << " KB\t" << (total_mem_throughput / 1024) << " KB / frame"; - } - break; - - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_TEXTURES: // ----====---- List Active Textures ----====---- - { - bool first = true; - int texture_count = 0; - std::set active_textures = m_pContext->getTextureManager()->getActiveTextures(); - for(std::set::iterator itr=active_textures.begin(); itr != active_textures.end(); itr++) { - KRTexture *texture = *itr; - if(first) { - first = false; - } else { - stream << "\n"; - } - stream << texture->getName(); - stream << "\t"; - stream << texture->getMemSize() / 1024; - stream << " KB"; - stream << "\t"; - stream << texture->getMaxMipMap(); - if(texture->hasMipmaps() && texture->getCurrentLodMaxDim() != texture->getMaxMipMap()) { - stream << " px => "; - stream << texture->getCurrentLodMaxDim(); - } - stream << " px"; - texture_count++; - } - - stream << "\n\nTOTAL: "; - stream << texture_count; - stream << " textures\t"; - stream << (m_pContext->getTextureManager()->getMemActive() / 1024) << " KB"; - } - break; - - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_DRAW_CALLS: // ----====---- List Draw Calls ----====---- - { - std::vector draw_calls = m_pContext->getMeshManager()->getDrawCalls(); - - long draw_call_count = 0; - long vertex_count = 0; - stream << "\tVerts\tPass\tObject\tMaterial"; - for(std::vector::iterator itr = draw_calls.begin(); itr != draw_calls.end(); itr++) { - draw_call_count++; - stream << "\n" << draw_call_count << "\t" << (*itr).vertex_count << "\t"; - switch((*itr).pass) { - case KRNode::RENDER_PASS_FORWARD_OPAQUE: - stream << "opaq"; - break; - case KRNode::RENDER_PASS_DEFERRED_GBUFFER: - stream << "d gb"; - break; - case KRNode::RENDER_PASS_DEFERRED_LIGHTS: - stream << "d light"; - break; - case KRNode::RENDER_PASS_DEFERRED_OPAQUE: - stream << "d opaq"; - break; - case KRNode::RENDER_PASS_FORWARD_TRANSPARENT: - stream << "trans"; - break; - case KRNode::RENDER_PASS_PARTICLE_OCCLUSION: - stream << "p occl"; - break; - case KRNode::RENDER_PASS_ADDITIVE_PARTICLES: - stream << "a part"; - break; - case KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE: - stream << "vol add"; - break; - case KRNode::RENDER_PASS_GENERATE_SHADOWMAPS: - stream << "g shadow"; - break; - case KRNode::RENDER_PASS_SHADOWMAP: - stream << "shadow"; - break; - default: - // Suppress warnings - break; - } - stream << "\t" << (*itr).object_name << "\t" << (*itr).material_name; - vertex_count += (*itr).vertex_count; - } - stream << "\n\n\t\tTOTAL:\t" << draw_call_count << " draw calls\t" << vertex_count << " vertices"; - } - break; - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_OCTREE: - stream << "Octree Visualization"; - break; - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_COLLIDERS: - stream << "Collider Visualization"; - break; - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_BONES: - stream << "Bone Visualization"; - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_SIREN_REVERB_ZONES: - stream << "Siren - Reverb Zones"; - break; - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_SIREN_AMBIENT_ZONES: - stream << "Siren - Ambient Zones"; - break; - case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_NUMBER: - // Suppress warning - break; + // ---- GPU Memory ---- + size_t texture_count_active = m_pContext->getTextureManager()->getActiveTextures().size(); + size_t texture_count = texture_count_active; + long texture_mem_active = m_pContext->getTextureManager()->getMemActive(); + long texture_mem_used = m_pContext->getTextureManager()->getMemUsed(); + long texture_mem_throughput = m_pContext->getTextureManager()->getMemoryTransferedThisFrame(); + + size_t vbo_count_active = m_pContext->getMeshManager()->getActiveVBOCount(); + long vbo_mem_active = m_pContext->getMeshManager()->getMemActive(); + long vbo_mem_used = m_pContext->getMeshManager()->getMemUsed(); + long vbo_mem_throughput = m_pContext->getMeshManager()->getMemoryTransferedThisFrame(); + + long total_mem_active = texture_mem_active + vbo_mem_active; + long total_mem_used = texture_mem_used + vbo_mem_used; + long total_mem_throughput = texture_mem_throughput + vbo_mem_throughput; + + stream << "\n\n\n\t# Active\t# Used\tActive\tUsed\tThroughput\n"; + + stream << "Textures\t" << texture_count_active << "\t" << texture_count << "\t" << (texture_mem_active / 1024) << " KB\t" << (texture_mem_used / 1024) << " KB\t" << (texture_mem_throughput / 1024) << " KB / frame\n"; + stream << "VBO's\t" << vbo_count_active << "\t" << vbo_count_active << "\t" << (vbo_mem_active / 1024) << " KB\t" << (vbo_mem_used / 1024) << " KB\t" << (vbo_mem_throughput / 1024) << " KB / frame\n"; + stream << "\nGPU Total\t\t\t" << (total_mem_active / 1024) << " KB\t" << (total_mem_used / 1024) << " KB\t" << (total_mem_throughput / 1024) << " KB / frame"; + } + break; + + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_TEXTURES: // ----====---- List Active Textures ----====---- + { + bool first = true; + int texture_count = 0; + std::set active_textures = m_pContext->getTextureManager()->getActiveTextures(); + for (std::set::iterator itr = active_textures.begin(); itr != active_textures.end(); itr++) { + KRTexture* texture = *itr; + if (first) { + first = false; + } else { + stream << "\n"; + } + stream << texture->getName(); + stream << "\t"; + stream << texture->getMemSize() / 1024; + stream << " KB"; + stream << "\t"; + stream << texture->getMaxMipMap(); + if (texture->hasMipmaps() && texture->getCurrentLodMaxDim() != texture->getMaxMipMap()) { + stream << " px => "; + stream << texture->getCurrentLodMaxDim(); + } + stream << " px"; + texture_count++; } - return stream.str(); + + stream << "\n\nTOTAL: "; + stream << texture_count; + stream << " textures\t"; + stream << (m_pContext->getTextureManager()->getMemActive() / 1024) << " KB"; + } + break; + + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_DRAW_CALLS: // ----====---- List Draw Calls ----====---- + { + std::vector draw_calls = m_pContext->getMeshManager()->getDrawCalls(); + + long draw_call_count = 0; + long vertex_count = 0; + stream << "\tVerts\tPass\tObject\tMaterial"; + for (std::vector::iterator itr = draw_calls.begin(); itr != draw_calls.end(); itr++) { + draw_call_count++; + stream << "\n" << draw_call_count << "\t" << (*itr).vertex_count << "\t"; + switch ((*itr).pass) { + case KRNode::RENDER_PASS_FORWARD_OPAQUE: + stream << "opaq"; + break; + case KRNode::RENDER_PASS_DEFERRED_GBUFFER: + stream << "d gb"; + break; + case KRNode::RENDER_PASS_DEFERRED_LIGHTS: + stream << "d light"; + break; + case KRNode::RENDER_PASS_DEFERRED_OPAQUE: + stream << "d opaq"; + break; + case KRNode::RENDER_PASS_FORWARD_TRANSPARENT: + stream << "trans"; + break; + case KRNode::RENDER_PASS_PARTICLE_OCCLUSION: + stream << "p occl"; + break; + case KRNode::RENDER_PASS_ADDITIVE_PARTICLES: + stream << "a part"; + break; + case KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE: + stream << "vol add"; + break; + case KRNode::RENDER_PASS_GENERATE_SHADOWMAPS: + stream << "g shadow"; + break; + case KRNode::RENDER_PASS_SHADOWMAP: + stream << "shadow"; + break; + default: + // Suppress warnings + break; + } + stream << "\t" << (*itr).object_name << "\t" << (*itr).material_name; + vertex_count += (*itr).vertex_count; + } + stream << "\n\n\t\tTOTAL:\t" << draw_call_count << " draw calls\t" << vertex_count << " vertices"; + } + break; + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_OCTREE: + stream << "Octree Visualization"; + break; + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_COLLIDERS: + stream << "Collider Visualization"; + break; + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_BONES: + stream << "Bone Visualization"; + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_SIREN_REVERB_ZONES: + stream << "Siren - Reverb Zones"; + break; + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_SIREN_AMBIENT_ZONES: + stream << "Siren - Ambient Zones"; + break; + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_NUMBER: + // Suppress warning + break; + } + return stream.str(); } -const KRViewport &KRCamera::getViewport() const +const KRViewport& KRCamera::getViewport() const { - return m_viewport; + return m_viewport; } Vector2 KRCamera::getDownsample() { - return m_downsample; + return m_downsample; } void KRCamera::setDownsample(float v) { - m_downsample = Vector2::Create(v); + m_downsample = Vector2::Create(v); } -void KRCamera::setFadeColor(const Vector4 &fade_color) +void KRCamera::setFadeColor(const Vector4& fade_color) { - m_fade_color = fade_color; + m_fade_color = fade_color; } Vector4 KRCamera::getFadeColor() { - return m_fade_color; + return m_fade_color; } diff --git a/kraken/KRCamera.h b/kraken/KRCamera.h index c8a4c21..0a9f5e8 100755 --- a/kraken/KRCamera.h +++ b/kraken/KRCamera.h @@ -48,74 +48,76 @@ class KRScene; class KRViewport; class KRSurface; -class KRCamera : public KRNode { +class KRCamera : public KRNode +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); - KRCamera(KRScene &scene, std::string name); - virtual ~KRCamera(); + static void InitNodeInfo(KrNodeInfo* nodeInfo); + KRCamera(KRScene& scene, std::string name); + virtual ~KRCamera(); - void renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeSurface); - - KRRenderSettings settings; - - const KRViewport &getViewport() const; - - - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - - std::string getDebugText(); - - void flushSkybox(); // this will delete the skybox and cause the camera to reload a new skybox based on the settings - Vector2 getDownsample(); - void setDownsample(float v); - - void setFadeColor(const Vector4 &fade_color); - Vector4 getFadeColor(); - - void setSkyBox(const std::string &skyBox); - const std::string getSkyBox() const; + void renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeSurface); + + KRRenderSettings settings; + + const KRViewport& getViewport() const; + + + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + + std::string getDebugText(); + + void flushSkybox(); // this will delete the skybox and cause the camera to reload a new skybox based on the settings + Vector2 getDownsample(); + void setDownsample(float v); + + void setFadeColor(const Vector4& fade_color); + Vector4 getFadeColor(); + + void setSkyBox(const std::string& skyBox); + const std::string getSkyBox() const; private: - void createBuffers(GLint renderBufferWidth, GLint renderBufferHeight); - - GLint volumetricBufferWidth, volumetricBufferHeight; - - GLuint compositeFramebuffer, compositeDepthTexture, compositeColorTexture; - GLuint lightAccumulationBuffer, lightAccumulationTexture; - - - GLuint volumetricLightAccumulationBuffer, volumetricLightAccumulationTexture; - - void renderPost(VkCommandBuffer& commandBuffer, KRSurface& surface); - - void destroyBuffers(); - - KRTexture *m_pSkyBoxTexture; - std::string m_skyBox; - KRViewport m_viewport; - - float m_particlesAbsoluteTime; - - Vector2 m_downsample; - - Vector4 m_fade_color; - - typedef struct { - float x; - float y; - float z; - float u; - float v; - } DebugTextVertexData; - - KRDataBlock m_debug_text_vertices; - KRMeshManager::KRVBOData m_debug_text_vbo_data; - -// std::string getDebugText(); - - uint64_t m_last_frame_start; - int m_frame_times[KRAKEN_FPS_AVERAGE_FRAME_COUNT]; - int m_frame_times_filled; + void createBuffers(GLint renderBufferWidth, GLint renderBufferHeight); + + GLint volumetricBufferWidth, volumetricBufferHeight; + + GLuint compositeFramebuffer, compositeDepthTexture, compositeColorTexture; + GLuint lightAccumulationBuffer, lightAccumulationTexture; + + + GLuint volumetricLightAccumulationBuffer, volumetricLightAccumulationTexture; + + void renderPost(VkCommandBuffer& commandBuffer, KRSurface& surface); + + void destroyBuffers(); + + KRTexture* m_pSkyBoxTexture; + std::string m_skyBox; + KRViewport m_viewport; + + float m_particlesAbsoluteTime; + + Vector2 m_downsample; + + Vector4 m_fade_color; + + typedef struct + { + float x; + float y; + float z; + float u; + float v; + } DebugTextVertexData; + + KRDataBlock m_debug_text_vertices; + KRMeshManager::KRVBOData m_debug_text_vbo_data; + + // std::string getDebugText(); + + uint64_t m_last_frame_start; + int m_frame_times[KRAKEN_FPS_AVERAGE_FRAME_COUNT]; + int m_frame_times_filled; }; diff --git a/kraken/KRCollider.cpp b/kraken/KRCollider.cpp index 3a57378..079b73e 100755 --- a/kraken/KRCollider.cpp +++ b/kraken/KRCollider.cpp @@ -43,187 +43,193 @@ void KRCollider::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->collider.mesh = -1; } -KRCollider::KRCollider(KRScene &scene, std::string collider_name, std::string model_name, unsigned int layer_mask, float audio_occlusion) : KRNode(scene, collider_name) { - m_model_name = model_name; - m_layer_mask = layer_mask; - m_audio_occlusion = audio_occlusion; - m_model = nullptr; -} - -KRCollider::~KRCollider() { - -} - -std::string KRCollider::getElementName() { - return "collider"; -} - -tinyxml2::XMLElement *KRCollider::saveXML( tinyxml2::XMLNode *parent) +KRCollider::KRCollider(KRScene& scene, std::string collider_name, std::string model_name, unsigned int layer_mask, float audio_occlusion) : KRNode(scene, collider_name) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - e->SetAttribute("mesh", m_model_name.c_str()); - e->SetAttribute("layer_mask", m_layer_mask); - e->SetAttribute("audio_occlusion", m_audio_occlusion); - return e; + m_model_name = model_name; + m_layer_mask = layer_mask; + m_audio_occlusion = audio_occlusion; + m_model = nullptr; } -void KRCollider::loadXML(tinyxml2::XMLElement *e) { - KRNode::loadXML(e); +KRCollider::~KRCollider() +{ - m_model_name = e->Attribute("mesh"); - +} + +std::string KRCollider::getElementName() +{ + return "collider"; +} + +tinyxml2::XMLElement* KRCollider::saveXML(tinyxml2::XMLNode* parent) +{ + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + e->SetAttribute("mesh", m_model_name.c_str()); + e->SetAttribute("layer_mask", m_layer_mask); + e->SetAttribute("audio_occlusion", m_audio_occlusion); + return e; +} + +void KRCollider::loadXML(tinyxml2::XMLElement* e) +{ + KRNode::loadXML(e); + + m_model_name = e->Attribute("mesh"); + + m_layer_mask = 65535; + if (e->QueryUnsignedAttribute("layer_mask", &m_layer_mask) != tinyxml2::XML_SUCCESS) { m_layer_mask = 65535; - if(e->QueryUnsignedAttribute("layer_mask", &m_layer_mask) != tinyxml2::XML_SUCCESS) { - m_layer_mask = 65535; - } - + } + + m_audio_occlusion = 1.0f; + if (e->QueryFloatAttribute("audio_occlusion", &m_audio_occlusion) != tinyxml2::XML_SUCCESS) { m_audio_occlusion = 1.0f; - if(e->QueryFloatAttribute("audio_occlusion", &m_audio_occlusion) != tinyxml2::XML_SUCCESS) { - m_audio_occlusion = 1.0f; - } + } } -void KRCollider::loadModel() { - if(m_model == nullptr) { - m_model = m_pContext->getMeshManager()->getMaxLODModel(m_model_name.c_str()); - if(m_model) { - getScene().notify_sceneGraphModify(this); - } +void KRCollider::loadModel() +{ + if (m_model == nullptr) { + m_model = m_pContext->getMeshManager()->getMaxLODModel(m_model_name.c_str()); + if (m_model) { + getScene().notify_sceneGraphModify(this); } + } } -AABB KRCollider::getBounds() { +AABB KRCollider::getBounds() +{ loadModel(); - if(m_model) { + if (m_model) { return AABB::Create(m_model->getMinPoint(), m_model->getMaxPoint(), getModelMatrix()); } else { return AABB::Infinite(); } } -bool KRCollider::lineCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo, unsigned int layer_mask) +bool KRCollider::lineCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo, unsigned int layer_mask) { - if(layer_mask & m_layer_mask ) { // Only test if layer masks have a common bit set - loadModel(); - if(m_model) { - if(getBounds().intersectsLine(v0, v1)) { - Vector3 v0_model_space = Matrix4::Dot(getInverseModelMatrix(), v0); - Vector3 v1_model_space = Matrix4::Dot(getInverseModelMatrix(), v1); - HitInfo hitinfo_model_space; - if(hitinfo.didHit()) { - Vector3 hit_position_model_space = Matrix4::Dot(getInverseModelMatrix(), hitinfo.getPosition()); - hitinfo_model_space = HitInfo(hit_position_model_space, Matrix4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), (hit_position_model_space - v0_model_space).magnitude(), hitinfo.getNode()); - } - - if(m_model->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) { - Vector3 hit_position_world_space = Matrix4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()); - hitinfo = HitInfo(hit_position_world_space, Vector3::Normalize(Matrix4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal())), (hit_position_world_space - v0).magnitude(), this); - return true; - } - } + if (layer_mask & m_layer_mask) { // Only test if layer masks have a common bit set + loadModel(); + if (m_model) { + if (getBounds().intersectsLine(v0, v1)) { + Vector3 v0_model_space = Matrix4::Dot(getInverseModelMatrix(), v0); + Vector3 v1_model_space = Matrix4::Dot(getInverseModelMatrix(), v1); + HitInfo hitinfo_model_space; + if (hitinfo.didHit()) { + Vector3 hit_position_model_space = Matrix4::Dot(getInverseModelMatrix(), hitinfo.getPosition()); + hitinfo_model_space = HitInfo(hit_position_model_space, Matrix4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), (hit_position_model_space - v0_model_space).magnitude(), hitinfo.getNode()); } + + if (m_model->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) { + Vector3 hit_position_world_space = Matrix4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()); + hitinfo = HitInfo(hit_position_world_space, Vector3::Normalize(Matrix4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal())), (hit_position_world_space - v0).magnitude(), this); + return true; + } + } } - return false; + } + return false; } -bool KRCollider::rayCast(const Vector3 &v0, const Vector3 &dir, HitInfo &hitinfo, unsigned int layer_mask) +bool KRCollider::rayCast(const Vector3& v0, const Vector3& dir, HitInfo& hitinfo, unsigned int layer_mask) { - if(layer_mask & m_layer_mask) { // Only test if layer masks have a common bit set - loadModel(); - if(m_model) { - if(getBounds().intersectsRay(v0, dir)) { - Vector3 v0_model_space = Matrix4::Dot(getInverseModelMatrix(), v0); - Vector3 dir_model_space = Vector3::Normalize(Matrix4::DotNoTranslate(getInverseModelMatrix(), dir)); - HitInfo hitinfo_model_space; - if(hitinfo.didHit()) { - Vector3 hit_position_model_space = Matrix4::Dot(getInverseModelMatrix(), hitinfo.getPosition()); - hitinfo_model_space = HitInfo(hit_position_model_space, Vector3::Normalize(Matrix4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal())), (hit_position_model_space - v0_model_space).magnitude(), hitinfo.getNode()); - } - - if(m_model->rayCast(v0_model_space, dir_model_space, hitinfo_model_space)) { - Vector3 hit_position_world_space = Matrix4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()); - hitinfo = HitInfo(hit_position_world_space, Vector3::Normalize(Matrix4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal())), (hit_position_world_space - v0).magnitude(), this); - return true; - } - } + if (layer_mask & m_layer_mask) { // Only test if layer masks have a common bit set + loadModel(); + if (m_model) { + if (getBounds().intersectsRay(v0, dir)) { + Vector3 v0_model_space = Matrix4::Dot(getInverseModelMatrix(), v0); + Vector3 dir_model_space = Vector3::Normalize(Matrix4::DotNoTranslate(getInverseModelMatrix(), dir)); + HitInfo hitinfo_model_space; + if (hitinfo.didHit()) { + Vector3 hit_position_model_space = Matrix4::Dot(getInverseModelMatrix(), hitinfo.getPosition()); + hitinfo_model_space = HitInfo(hit_position_model_space, Vector3::Normalize(Matrix4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal())), (hit_position_model_space - v0_model_space).magnitude(), hitinfo.getNode()); } + + if (m_model->rayCast(v0_model_space, dir_model_space, hitinfo_model_space)) { + Vector3 hit_position_world_space = Matrix4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()); + hitinfo = HitInfo(hit_position_world_space, Vector3::Normalize(Matrix4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal())), (hit_position_world_space - v0).magnitude(), this); + return true; + } + } } - return false; + } + return false; } -bool KRCollider::sphereCast(const Vector3 &v0, const Vector3 &v1, float radius, HitInfo &hitinfo, unsigned int layer_mask) +bool KRCollider::sphereCast(const Vector3& v0, const Vector3& v1, float radius, HitInfo& hitinfo, unsigned int layer_mask) { - if(layer_mask & m_layer_mask) { // Only test if layer masks have a common bit set - loadModel(); - if(m_model) { - AABB sphereCastBounds = AABB::Create( // TODO - Need to cache this; perhaps encasulate within a "spherecast" class to be passed through these functions - Vector3::Create(KRMIN(v0.x, v1.x) - radius, KRMIN(v0.y, v1.y) - radius, KRMIN(v0.z, v1.z) - radius), - Vector3::Create(KRMAX(v0.x, v1.x) + radius, KRMAX(v0.y, v1.y) + radius, KRMAX(v0.z, v1.z) + radius) - ); - - if(getBounds().intersects(sphereCastBounds)) { - if(m_model->sphereCast(getModelMatrix(), v0, v1, radius, hitinfo)) { - hitinfo = HitInfo(hitinfo.getPosition(), hitinfo.getNormal(), hitinfo.getDistance(), this); - return true; - } - } + if (layer_mask & m_layer_mask) { // Only test if layer masks have a common bit set + loadModel(); + if (m_model) { + AABB sphereCastBounds = AABB::Create( // TODO - Need to cache this; perhaps encasulate within a "spherecast" class to be passed through these functions + Vector3::Create(KRMIN(v0.x, v1.x) - radius, KRMIN(v0.y, v1.y) - radius, KRMIN(v0.z, v1.z) - radius), + Vector3::Create(KRMAX(v0.x, v1.x) + radius, KRMAX(v0.y, v1.y) + radius, KRMAX(v0.z, v1.z) + radius) + ); + + if (getBounds().intersects(sphereCastBounds)) { + if (m_model->sphereCast(getModelMatrix(), v0, v1, radius, hitinfo)) { + hitinfo = HitInfo(hitinfo.getPosition(), hitinfo.getNormal(), hitinfo.getDistance(), this); + return true; } + } } - return false; + } + return false; } unsigned int KRCollider::getLayerMask() { - return m_layer_mask; + return m_layer_mask; } void KRCollider::setLayerMask(unsigned int layer_mask) { - m_layer_mask = layer_mask; + m_layer_mask = layer_mask; } float KRCollider::getAudioOcclusion() { - return m_audio_occlusion; + return m_audio_occlusion; } void KRCollider::setAudioOcclusion(float audio_occlusion) { - m_audio_occlusion = audio_occlusion; + m_audio_occlusion = audio_occlusion; } void KRCollider::render(RenderInfo& ri) { - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRNode::render(ri); - - if(ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && ri.camera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_COLLIDERS) { - loadModel(); - if(m_model) { - - GL_PUSH_GROUP_MARKER("Debug Overlays"); - - PipelineInfo info{}; - std::string shader_name("visualize_overlay"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAdditive; - info.modelFormat = m_model->getModelFormat(); - info.vertexAttributes = m_model->getVertexAttributes(); + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + KRNode::render(ri); - pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); - - m_model->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); - - GL_POP_GROUP_MARKER; - } + if (ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && ri.camera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_COLLIDERS) { + loadModel(); + if (m_model) { + + GL_PUSH_GROUP_MARKER("Debug Overlays"); + + PipelineInfo info{}; + std::string shader_name("visualize_overlay"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.renderPass = ri.renderPass; + info.rasterMode = RasterMode::kAdditive; + info.modelFormat = m_model->getModelFormat(); + info.vertexAttributes = m_model->getVertexAttributes(); + + KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + + m_model->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); + + GL_POP_GROUP_MARKER; } + } } diff --git a/kraken/KRCollider.h b/kraken/KRCollider.h index 5abdd16..3c1fcbb 100755 --- a/kraken/KRCollider.h +++ b/kraken/KRCollider.h @@ -46,37 +46,38 @@ #include "KRMesh.h" #include "KRTexture.h" -class KRCollider : public KRNode { - -public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); +class KRCollider : public KRNode +{ + +public: + static void InitNodeInfo(KrNodeInfo* nodeInfo); + + KRCollider(KRScene& scene, std::string collider_name, std::string model_name, unsigned int layer_mask, float audio_occlusion); + virtual ~KRCollider(); + + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + virtual AABB getBounds(); + + bool lineCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo, unsigned int layer_mask); + bool rayCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo, unsigned int layer_mask); + bool sphereCast(const Vector3& v0, const Vector3& v1, float radius, HitInfo& hitinfo, unsigned int layer_mask); + + unsigned int getLayerMask(); + void setLayerMask(unsigned int layer_mask); + + float getAudioOcclusion(); + void setAudioOcclusion(float audio_occlusion); + + void render(RenderInfo& ri); - KRCollider(KRScene &scene, std::string collider_name, std::string model_name, unsigned int layer_mask, float audio_occlusion); - virtual ~KRCollider(); - - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - virtual AABB getBounds(); - - bool lineCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo, unsigned int layer_mask); - bool rayCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo, unsigned int layer_mask); - bool sphereCast(const Vector3 &v0, const Vector3 &v1, float radius, HitInfo &hitinfo, unsigned int layer_mask); - - unsigned int getLayerMask(); - void setLayerMask(unsigned int layer_mask); - - float getAudioOcclusion(); - void setAudioOcclusion(float audio_occlusion); - - void render(RenderInfo& ri); - private: - KRMesh* m_model; - std::string m_model_name; - - unsigned int m_layer_mask; - float m_audio_occlusion; - - void loadModel(); + KRMesh* m_model; + std::string m_model_name; + + unsigned int m_layer_mask; + float m_audio_occlusion; + + void loadModel(); }; diff --git a/kraken/KRContext.cpp b/kraken/KRContext.cpp index 3a97469..6c02ef3 100755 --- a/kraken/KRContext.cpp +++ b/kraken/KRContext.cpp @@ -79,326 +79,343 @@ int KRContext::KRENGINE_SYS_PAGE_SIZE; std::mutex KRContext::g_SurfaceInfoMutex; std::mutex KRContext::g_DeviceInfoMutex; -KRContext::log_callback *KRContext::s_log_callback = NULL; -void *KRContext::s_log_callback_user_data = NULL; +KRContext::log_callback* KRContext::s_log_callback = NULL; +void* KRContext::s_log_callback_user_data = NULL; KRContext::KRContext(const KrInitializeInfo* initializeInfo) : m_resourceMapSize(initializeInfo->resourceMapSize) { - m_presentationThread = std::make_unique(*this); - m_streamerThread = std::make_unique(*this); - m_resourceMap = (KRResource **)malloc(sizeof(KRResource*) * m_resourceMapSize); - memset(m_resourceMap, 0, m_resourceMapSize * sizeof(KRResource*)); - m_streamingEnabled = false; + m_presentationThread = std::make_unique(*this); + m_streamerThread = std::make_unique(*this); + m_resourceMap = (KRResource**)malloc(sizeof(KRResource*) * m_resourceMapSize); + memset(m_resourceMap, 0, m_resourceMapSize * sizeof(KRResource*)); + m_streamingEnabled = false; #ifdef __APPLE__ - mach_timebase_info(&m_timebase_info); + mach_timebase_info(&m_timebase_info); #endif - - m_current_frame = 0; - m_last_memory_warning_frame = 0; - m_last_fully_streamed_frame = 0; - m_absolute_time = 0.0f; - - m_pBundleManager = std::make_unique(*this); - m_pPipelineManager = std::make_unique(*this); - m_pTextureManager = std::make_unique(*this); - m_pMaterialManager = std::make_unique(*this, m_pTextureManager.get(), m_pPipelineManager.get()); - m_pMeshManager = std::make_unique(*this); - m_pMeshManager->init(); - m_pSceneManager = std::make_unique(*this); - m_pAnimationManager = std::make_unique(*this); - m_pAnimationCurveManager = std::make_unique(*this); - m_pSoundManager = std::make_unique(*this); - m_pUnknownManager = std::make_unique(*this); - m_pShaderManager = std::make_unique(*this); - m_pSourceManager = std::make_unique(*this); - m_deviceManager = std::make_unique(*this); - m_surfaceManager = std::make_unique(*this); - m_streamingEnabled = true; + + m_current_frame = 0; + m_last_memory_warning_frame = 0; + m_last_fully_streamed_frame = 0; + m_absolute_time = 0.0f; + + m_pBundleManager = std::make_unique(*this); + m_pPipelineManager = std::make_unique(*this); + m_pTextureManager = std::make_unique(*this); + m_pMaterialManager = std::make_unique(*this, m_pTextureManager.get(), m_pPipelineManager.get()); + m_pMeshManager = std::make_unique(*this); + m_pMeshManager->init(); + m_pSceneManager = std::make_unique(*this); + m_pAnimationManager = std::make_unique(*this); + m_pAnimationCurveManager = std::make_unique(*this); + m_pSoundManager = std::make_unique(*this); + m_pUnknownManager = std::make_unique(*this); + m_pShaderManager = std::make_unique(*this); + m_pSourceManager = std::make_unique(*this); + m_deviceManager = std::make_unique(*this); + m_surfaceManager = std::make_unique(*this); + m_streamingEnabled = true; #if defined(_WIN32) || defined(_WIN64) - SYSTEM_INFO winSysInfo; - GetSystemInfo(&winSysInfo); - KRENGINE_SYS_ALLOCATION_GRANULARITY = winSysInfo.dwAllocationGranularity; - KRENGINE_SYS_PAGE_SIZE = winSysInfo.dwPageSize; + SYSTEM_INFO winSysInfo; + GetSystemInfo(&winSysInfo); + KRENGINE_SYS_ALLOCATION_GRANULARITY = winSysInfo.dwAllocationGranularity; + KRENGINE_SYS_PAGE_SIZE = winSysInfo.dwPageSize; #elif defined(__APPLE__) || defined(ANDROID) - KRENGINE_SYS_PAGE_SIZE = getpagesize(); - KRENGINE_SYS_ALLOCATION_GRANULARITY = KRENGINE_SYS_PAGE_SIZE; + KRENGINE_SYS_PAGE_SIZE = getpagesize(); + KRENGINE_SYS_ALLOCATION_GRANULARITY = KRENGINE_SYS_PAGE_SIZE; #else #error Unsupported #endif - - m_deviceManager->initialize(); - - m_presentationThread->start(); - m_streamerThread->start(); + + m_deviceManager->initialize(); + + m_presentationThread->start(); + m_streamerThread->start(); } -KRContext::~KRContext() { - m_presentationThread->stop(); - m_streamerThread->stop(); - m_pSceneManager.reset(); - m_pMeshManager.reset(); - m_pMaterialManager.reset(); - m_pTextureManager->destroy(); - m_pTextureManager.reset(); - m_pPipelineManager.reset(); - m_pAnimationManager.reset(); - m_pAnimationCurveManager.reset(); - m_pSoundManager->destroy(); - m_pSoundManager.reset(); - m_pSourceManager.reset(); - m_pUnknownManager.reset(); - m_pShaderManager.reset(); - m_surfaceManager.reset(); - m_deviceManager.reset(); - - // The bundles must be destroyed last, as the other objects may be using mmap'ed data from bundles - m_pBundleManager.reset(); - - - if (m_resourceMap) { - delete m_resourceMap; - m_resourceMap = NULL; - } -} - -void KRContext::SetLogCallback(log_callback *log_callback, void *user_data) +KRContext::~KRContext() { - s_log_callback = log_callback; - s_log_callback_user_data = user_data; + m_presentationThread->stop(); + m_streamerThread->stop(); + m_pSceneManager.reset(); + m_pMeshManager.reset(); + m_pMaterialManager.reset(); + m_pTextureManager->destroy(); + m_pTextureManager.reset(); + m_pPipelineManager.reset(); + m_pAnimationManager.reset(); + m_pAnimationCurveManager.reset(); + m_pSoundManager->destroy(); + m_pSoundManager.reset(); + m_pSourceManager.reset(); + m_pUnknownManager.reset(); + m_pShaderManager.reset(); + m_surfaceManager.reset(); + m_deviceManager.reset(); + + // The bundles must be destroyed last, as the other objects may be using mmap'ed data from bundles + m_pBundleManager.reset(); + + + if (m_resourceMap) { + delete m_resourceMap; + m_resourceMap = NULL; + } +} + +void KRContext::SetLogCallback(log_callback* log_callback, void* user_data) +{ + s_log_callback = log_callback; + s_log_callback_user_data = user_data; } void KRContext::Log(log_level level, const std::string message_format, ...) { - va_list args; - va_start(args, message_format); - - if(s_log_callback) { - const int LOG_BUFFER_SIZE = 32768; - char log_buffer[LOG_BUFFER_SIZE]; - vsnprintf(log_buffer, LOG_BUFFER_SIZE, message_format.c_str(), args); - s_log_callback(s_log_callback_user_data, std::string(log_buffer), level); - } else { - FILE *out_file = level == LOG_LEVEL_INFORMATION ? stdout : stderr; - fprintf(out_file, "Kraken - INFO: "); - vfprintf(out_file, message_format.c_str(), args); - fprintf(out_file, "\n"); - } - - va_end(args); + va_list args; + va_start(args, message_format); + + if (s_log_callback) { + const int LOG_BUFFER_SIZE = 32768; + char log_buffer[LOG_BUFFER_SIZE]; + vsnprintf(log_buffer, LOG_BUFFER_SIZE, message_format.c_str(), args); + s_log_callback(s_log_callback_user_data, std::string(log_buffer), level); + } else { + FILE* out_file = level == LOG_LEVEL_INFORMATION ? stdout : stderr; + fprintf(out_file, "Kraken - INFO: "); + vfprintf(out_file, message_format.c_str(), args); + fprintf(out_file, "\n"); + } + + va_end(args); } -KRBundleManager *KRContext::getBundleManager() { - return m_pBundleManager.get(); +KRBundleManager* KRContext::getBundleManager() +{ + return m_pBundleManager.get(); } -KRSceneManager *KRContext::getSceneManager() { - return m_pSceneManager.get(); +KRSceneManager* KRContext::getSceneManager() +{ + return m_pSceneManager.get(); } -KRTextureManager *KRContext::getTextureManager() { - return m_pTextureManager.get(); +KRTextureManager* KRContext::getTextureManager() +{ + return m_pTextureManager.get(); } -KRMaterialManager *KRContext::getMaterialManager() { - return m_pMaterialManager.get(); +KRMaterialManager* KRContext::getMaterialManager() +{ + return m_pMaterialManager.get(); } -KRPipelineManager *KRContext::getPipelineManager() { - return m_pPipelineManager.get(); +KRPipelineManager* KRContext::getPipelineManager() +{ + return m_pPipelineManager.get(); } -KRMeshManager *KRContext::getMeshManager() { - return m_pMeshManager.get(); +KRMeshManager* KRContext::getMeshManager() +{ + return m_pMeshManager.get(); } -KRAnimationManager *KRContext::getAnimationManager() { - return m_pAnimationManager.get(); +KRAnimationManager* KRContext::getAnimationManager() +{ + return m_pAnimationManager.get(); } -KRAnimationCurveManager *KRContext::getAnimationCurveManager() { - return m_pAnimationCurveManager.get(); +KRAnimationCurveManager* KRContext::getAnimationCurveManager() +{ + return m_pAnimationCurveManager.get(); } -KRAudioManager *KRContext::getAudioManager() { - return m_pSoundManager.get(); +KRAudioManager* KRContext::getAudioManager() +{ + return m_pSoundManager.get(); } -KRShaderManager *KRContext::getShaderManager() { - return m_pShaderManager.get(); +KRShaderManager* KRContext::getShaderManager() +{ + return m_pShaderManager.get(); } -KRSourceManager *KRContext::getSourceManager() { - return m_pSourceManager.get(); +KRSourceManager* KRContext::getSourceManager() +{ + return m_pSourceManager.get(); } -KRSurfaceManager* KRContext::getSurfaceManager() { +KRSurfaceManager* KRContext::getSurfaceManager() +{ return m_surfaceManager.get(); } -KRDeviceManager* KRContext::getDeviceManager() { +KRDeviceManager* KRContext::getDeviceManager() +{ return m_deviceManager.get(); } -KRUnknownManager *KRContext::getUnknownManager() { - return m_pUnknownManager.get(); -} -std::vector KRContext::getResources() +KRUnknownManager* KRContext::getUnknownManager() { - std::vector resources; - - for(unordered_map::iterator itr = m_pSceneManager->getScenes().begin(); itr != m_pSceneManager->getScenes().end(); itr++) { - resources.push_back((*itr).second); - } - for(unordered_map::iterator itr = m_pTextureManager->getTextures().begin(); itr != m_pTextureManager->getTextures().end(); itr++) { - resources.push_back((*itr).second); - } - for(unordered_map::iterator itr = m_pMaterialManager->getMaterials().begin(); itr != m_pMaterialManager->getMaterials().end(); itr++) { - resources.push_back((*itr).second); - } - for(unordered_multimap::iterator itr = m_pMeshManager->getModels().begin(); itr != m_pMeshManager->getModels().end(); itr++) { - resources.push_back((*itr).second); - } - for(unordered_map::iterator itr = m_pAnimationManager->getAnimations().begin(); itr != m_pAnimationManager->getAnimations().end(); itr++) { - resources.push_back((*itr).second); - } - for(unordered_map::iterator itr = m_pAnimationCurveManager->getAnimationCurves().begin(); itr != m_pAnimationCurveManager->getAnimationCurves().end(); itr++) { - resources.push_back((*itr).second); - } - for(unordered_map::iterator itr = m_pSoundManager->getSounds().begin(); itr != m_pSoundManager->getSounds().end(); itr++) { - resources.push_back((*itr).second); - } + return m_pUnknownManager.get(); +} +std::vector KRContext::getResources() +{ + std::vector resources; - unordered_map > sources = m_pSourceManager->getSources(); - for(unordered_map >::iterator itr = sources.begin(); itr != sources.end(); itr++) { - for(unordered_map::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) { - resources.push_back((*itr2).second); - } - } + for (unordered_map::iterator itr = m_pSceneManager->getScenes().begin(); itr != m_pSceneManager->getScenes().end(); itr++) { + resources.push_back((*itr).second); + } + for (unordered_map::iterator itr = m_pTextureManager->getTextures().begin(); itr != m_pTextureManager->getTextures().end(); itr++) { + resources.push_back((*itr).second); + } + for (unordered_map::iterator itr = m_pMaterialManager->getMaterials().begin(); itr != m_pMaterialManager->getMaterials().end(); itr++) { + resources.push_back((*itr).second); + } + for (unordered_multimap::iterator itr = m_pMeshManager->getModels().begin(); itr != m_pMeshManager->getModels().end(); itr++) { + resources.push_back((*itr).second); + } + for (unordered_map::iterator itr = m_pAnimationManager->getAnimations().begin(); itr != m_pAnimationManager->getAnimations().end(); itr++) { + resources.push_back((*itr).second); + } + for (unordered_map::iterator itr = m_pAnimationCurveManager->getAnimationCurves().begin(); itr != m_pAnimationCurveManager->getAnimationCurves().end(); itr++) { + resources.push_back((*itr).second); + } + for (unordered_map::iterator itr = m_pSoundManager->getSounds().begin(); itr != m_pSoundManager->getSounds().end(); itr++) { + resources.push_back((*itr).second); + } - unordered_map > shaders = m_pShaderManager->getShaders(); - for(unordered_map >::iterator itr = shaders.begin(); itr != shaders.end(); itr++) { - for(unordered_map::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) { - resources.push_back((*itr2).second); - } + unordered_map > sources = m_pSourceManager->getSources(); + for (unordered_map >::iterator itr = sources.begin(); itr != sources.end(); itr++) { + for (unordered_map::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) { + resources.push_back((*itr2).second); } - - unordered_map > unknowns = m_pUnknownManager->getUnknowns(); - for(unordered_map >::iterator itr = unknowns.begin(); itr != unknowns.end(); itr++) { - for(unordered_map::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) { - resources.push_back((*itr2).second); - } + } + + unordered_map > shaders = m_pShaderManager->getShaders(); + for (unordered_map >::iterator itr = shaders.begin(); itr != shaders.end(); itr++) { + for (unordered_map::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) { + resources.push_back((*itr2).second); } - - return resources; + } + + unordered_map > unknowns = m_pUnknownManager->getUnknowns(); + for (unordered_map >::iterator itr = unknowns.begin(); itr != unknowns.end(); itr++) { + for (unordered_map::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) { + resources.push_back((*itr2).second); + } + } + + return resources; } -KRResource* KRContext::loadResource(const std::string &file_name, KRDataBlock *data) { - std::string name = KRResource::GetFileBase(file_name); - std::string extension = KRResource::GetFileExtension(file_name); +KRResource* KRContext::loadResource(const std::string& file_name, KRDataBlock* data) +{ + std::string name = KRResource::GetFileBase(file_name); + std::string extension = KRResource::GetFileExtension(file_name); - KRResource *resource = nullptr; - -// fprintf(stderr, "KRContext::loadResource - Loading: %s\n", file_name.c_str()); - - if(extension.compare("krbundle") == 0) { - resource = m_pBundleManager->loadBundle(name.c_str(), data); - } else if(extension.compare("krmesh") == 0) { - resource = m_pMeshManager->loadModel(name.c_str(), data); - } else if(extension.compare("krscene") == 0) { - resource = m_pSceneManager->loadScene(name.c_str(), data); - } else if(extension.compare("kranimation") == 0) { - resource = m_pAnimationManager->loadAnimation(name.c_str(), data); - } else if(extension.compare("kranimationcurve") == 0) { - resource = m_pAnimationCurveManager->loadAnimationCurve(name.c_str(), data); - } else if(extension.compare("pvr") == 0) { - resource = m_pTextureManager->loadTexture(name.c_str(), extension.c_str(), data); - } else if(extension.compare("ktx") == 0) { - resource = m_pTextureManager->loadTexture(name.c_str(), extension.c_str(), data); - } else if(extension.compare("tga") == 0) { - resource = m_pTextureManager->loadTexture(name.c_str(), extension.c_str(), data); - } else if(extension.compare("spv") == 0) { - // SPIR-V shader binary - resource = m_pShaderManager->load(name, extension, data); - } else if(extension.compare("vert") == 0) { - // vertex shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("frag") == 0) { - // fragment shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("tesc") == 0) { - // tessellation control shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("tese") == 0) { - // tessellation evaluation shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("geom") == 0) { - // geometry shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("comp") == 0) { - // compute shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("mesh") == 0) { - // mesh shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("task") == 0) { - // task shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("rgen") == 0) { - // ray generation shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("rint") == 0) { - // ray intersection shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("rahit") == 0) { - // ray any hit shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("rchit") == 0) { - // ray closest hit shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("rmiss") == 0) { - // ray miss shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("rcall") == 0) { - // ray callable shader - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("glsl") == 0) { - // glsl included by other shaders - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("options") == 0) { - // shader pre-processor options definition file - resource = m_pSourceManager->load(name, extension, data); - } else if(extension.compare("mtl") == 0) { - resource = m_pMaterialManager->load(name.c_str(), data); - } else if(extension.compare("mp3") == 0) { - resource = m_pSoundManager->load(name.c_str(), extension, data); - } else if(extension.compare("wav") == 0) { - resource = m_pSoundManager->load(name.c_str(), extension, data); - } else if(extension.compare("aac") == 0) { - resource = m_pSoundManager->load(name.c_str(), extension, data); - } else if(extension.compare("obj") == 0) { - resource = KRResource::LoadObj(*this, file_name); + KRResource* resource = nullptr; + + // fprintf(stderr, "KRContext::loadResource - Loading: %s\n", file_name.c_str()); + + if (extension.compare("krbundle") == 0) { + resource = m_pBundleManager->loadBundle(name.c_str(), data); + } else if (extension.compare("krmesh") == 0) { + resource = m_pMeshManager->loadModel(name.c_str(), data); + } else if (extension.compare("krscene") == 0) { + resource = m_pSceneManager->loadScene(name.c_str(), data); + } else if (extension.compare("kranimation") == 0) { + resource = m_pAnimationManager->loadAnimation(name.c_str(), data); + } else if (extension.compare("kranimationcurve") == 0) { + resource = m_pAnimationCurveManager->loadAnimationCurve(name.c_str(), data); + } else if (extension.compare("pvr") == 0) { + resource = m_pTextureManager->loadTexture(name.c_str(), extension.c_str(), data); + } else if (extension.compare("ktx") == 0) { + resource = m_pTextureManager->loadTexture(name.c_str(), extension.c_str(), data); + } else if (extension.compare("tga") == 0) { + resource = m_pTextureManager->loadTexture(name.c_str(), extension.c_str(), data); + } else if (extension.compare("spv") == 0) { + // SPIR-V shader binary + resource = m_pShaderManager->load(name, extension, data); + } else if (extension.compare("vert") == 0) { + // vertex shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("frag") == 0) { + // fragment shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("tesc") == 0) { + // tessellation control shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("tese") == 0) { + // tessellation evaluation shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("geom") == 0) { + // geometry shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("comp") == 0) { + // compute shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("mesh") == 0) { + // mesh shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("task") == 0) { + // task shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("rgen") == 0) { + // ray generation shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("rint") == 0) { + // ray intersection shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("rahit") == 0) { + // ray any hit shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("rchit") == 0) { + // ray closest hit shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("rmiss") == 0) { + // ray miss shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("rcall") == 0) { + // ray callable shader + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("glsl") == 0) { + // glsl included by other shaders + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("options") == 0) { + // shader pre-processor options definition file + resource = m_pSourceManager->load(name, extension, data); + } else if (extension.compare("mtl") == 0) { + resource = m_pMaterialManager->load(name.c_str(), data); + } else if (extension.compare("mp3") == 0) { + resource = m_pSoundManager->load(name.c_str(), extension, data); + } else if (extension.compare("wav") == 0) { + resource = m_pSoundManager->load(name.c_str(), extension, data); + } else if (extension.compare("aac") == 0) { + resource = m_pSoundManager->load(name.c_str(), extension, data); + } else if (extension.compare("obj") == 0) { + resource = KRResource::LoadObj(*this, file_name); #if !TARGET_OS_IPHONE -/* - // FINDME, TODO, HACK! - Uncomment - } else if(extension.compare("fbx") == 0) { - resource = KRResource::LoadFbx(*this, file_name); -*/ - } else if(extension.compare("blend") == 0) { - resource = KRResource::LoadBlenderScene(*this, file_name); + /* + // FINDME, TODO, HACK! - Uncomment + } else if(extension.compare("fbx") == 0) { + resource = KRResource::LoadFbx(*this, file_name); + */ + } else if (extension.compare("blend") == 0) { + resource = KRResource::LoadBlenderScene(*this, file_name); #endif - } else { - resource = m_pUnknownManager->load(name, extension, data); - } - return resource; + } else { + resource = m_pUnknownManager->load(name, extension, data); + } + return resource; } -KrResult KRContext::loadResource(const KrLoadResourceInfo* loadResourceInfo) { - if (loadResourceInfo->resourceHandle < 0 || loadResourceInfo->resourceHandle >= m_resourceMapSize) { - return KR_ERROR_OUT_OF_BOUNDS; - } - KRDataBlock *data = new KRDataBlock(); - if(!data->load(loadResourceInfo->pResourcePath)) { - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KRContext::loadResource - Failed to open file: %s", loadResourceInfo->pResourcePath); - delete data; - return KR_ERROR_UNEXPECTED; - } +KrResult KRContext::loadResource(const KrLoadResourceInfo* loadResourceInfo) +{ + if (loadResourceInfo->resourceHandle < 0 || loadResourceInfo->resourceHandle >= m_resourceMapSize) { + return KR_ERROR_OUT_OF_BOUNDS; + } + KRDataBlock* data = new KRDataBlock(); + if (!data->load(loadResourceInfo->pResourcePath)) { + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KRContext::loadResource - Failed to open file: %s", loadResourceInfo->pResourcePath); + delete data; + return KR_ERROR_UNEXPECTED; + } - KRResource *resource = loadResource(loadResourceInfo->pResourcePath, data); - m_resourceMap[loadResourceInfo->resourceHandle] = resource; - return KR_SUCCESS; + KRResource* resource = loadResource(loadResourceInfo->pResourcePath, data); + m_resourceMap[loadResourceInfo->resourceHandle] = resource; + return KR_SUCCESS; } KrResult KRContext::unloadResource(const KrUnloadResourceInfo* unloadResourceInfo) @@ -472,7 +489,7 @@ KrResult KRContext::getResourceData(const KrGetResourceDataInfo* getResourceData result.result = KR_ERROR_UNEXPECTED; callback(result); } - + return KR_SUCCESS; } @@ -574,69 +591,69 @@ KrResult KRContext::saveResource(const KrSaveResourceInfo* saveResourceInfo) void KRContext::startFrame(float deltaTime) { - m_pTextureManager->startFrame(deltaTime); - m_pAnimationManager->startFrame(deltaTime); - m_pSoundManager->startFrame(deltaTime); - m_pMeshManager->startFrame(deltaTime); + m_pTextureManager->startFrame(deltaTime); + m_pAnimationManager->startFrame(deltaTime); + m_pSoundManager->startFrame(deltaTime); + m_pMeshManager->startFrame(deltaTime); } void KRContext::endFrame(float deltaTime) { - m_pTextureManager->endFrame(deltaTime); - m_pAnimationManager->endFrame(deltaTime); - m_pMeshManager->endFrame(deltaTime); - m_current_frame++; - m_absolute_time += deltaTime; + m_pTextureManager->endFrame(deltaTime); + m_pAnimationManager->endFrame(deltaTime); + m_pMeshManager->endFrame(deltaTime); + m_current_frame++; + m_absolute_time += deltaTime; } long KRContext::getCurrentFrame() const { - return m_current_frame; + return m_current_frame; } long KRContext::getLastFullyStreamedFrame() const { - return m_last_fully_streamed_frame; + return m_last_fully_streamed_frame; } float KRContext::getAbsoluteTime() const { - return m_absolute_time; + return m_absolute_time; } long KRContext::getAbsoluteTimeMilliseconds() { #if defined(ANDROID) - return std::chrono::duration_cast< std::chrono::milliseconds >( - std::chrono::system_clock::now().time_since_epoch()).count(); + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); #elif defined(__APPLE__) - return (long)(mach_absolute_time() / 1000 * m_timebase_info.numer / m_timebase_info.denom); // Division done first to avoid potential overflow + return (long)(mach_absolute_time() / 1000 * m_timebase_info.numer / m_timebase_info.denom); // Division done first to avoid potential overflow #else - return (long)GetTickCount64(); + return (long)GetTickCount64(); #endif } #if TARGET_OS_IPHONE || TARGET_OS_MAC -void KRContext::getMemoryStats(long &free_memory) +void KRContext::getMemoryStats(long& free_memory) { - free_memory = 0; + free_memory = 0; - mach_port_t host_port = mach_host_self(); - mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); - vm_size_t pagesize = 0; - vm_statistics_data_t vm_stat; - // int total_ram = 256 * 1024 * 1024; - if(host_page_size(host_port, &pagesize) != KERN_SUCCESS) { - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Could not get VM page size."); - } else if(host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) { - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Could not get VM stats."); - } else { - // total_ram = (vm_stat.wire_count + vm_stat.active_count + vm_stat.inactive_count + vm_stat.free_count) * pagesize; - - free_memory = (vm_stat.free_count + vm_stat.inactive_count) * pagesize; - } + mach_port_t host_port = mach_host_self(); + mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); + vm_size_t pagesize = 0; + vm_statistics_data_t vm_stat; + // int total_ram = 256 * 1024 * 1024; + if (host_page_size(host_port, &pagesize) != KERN_SUCCESS) { + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Could not get VM page size."); + } else if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) { + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Could not get VM stats."); + } else { + // total_ram = (vm_stat.wire_count + vm_stat.active_count + vm_stat.inactive_count + vm_stat.free_count) * pagesize; + + free_memory = (vm_stat.free_count + vm_stat.inactive_count) * pagesize; + } } #endif @@ -823,7 +840,7 @@ KrResult KRContext::createWindowSurface(const KrCreateWindowSurfaceInfo* createW if (result != KR_SUCCESS) { return result; } - + m_surfaceHandleMap.insert(std::pair(createWindowSurfaceInfo->surfaceHandle, surfaceHandle)); return KR_SUCCESS; @@ -848,6 +865,6 @@ KrResult KRContext::deleteWindowSurface(const KrDeleteWindowSurfaceInfo* deleteW } KrSurfaceHandle surfaceHandle = (*handleItr).second; m_surfaceHandleMap.erase(handleItr); - + return m_surfaceManager->destroy(surfaceHandle); } diff --git a/kraken/KRContext.h b/kraken/KRContext.h index ba326f5..9157fed 100755 --- a/kraken/KRContext.h +++ b/kraken/KRContext.h @@ -54,141 +54,143 @@ class KRStreamerThread; class KRDeviceManager; class KRSurfaceManager; -class KRContext { +class KRContext +{ public: - static int KRENGINE_MAX_PIPELINE_HANDLES; - static int KRENGINE_GPU_MEM_MAX; - static int KRENGINE_GPU_MEM_TARGET; - static int KRENGINE_MAX_TEXTURE_DIM; - static int KRENGINE_MIN_TEXTURE_DIM; - static int KRENGINE_PRESTREAM_DISTANCE; - static int KRENGINE_SYS_ALLOCATION_GRANULARITY; - static int KRENGINE_SYS_PAGE_SIZE; - - - KRContext(const KrInitializeInfo* initializeInfo); - ~KRContext(); - - KrResult createWindowSurface(const KrCreateWindowSurfaceInfo* createWindowSurfaceInfo); - KrResult deleteWindowSurface(const KrDeleteWindowSurfaceInfo* deleteWindowSurfaceInfo); - - KrResult createBundle(const KrCreateBundleInfo* createBundleInfo); - KrResult moveToBundle(const KrMoveToBundleInfo* moveToBundleInfo); - KrResult loadResource(const KrLoadResourceInfo* loadResourceInfo); - KrResult unloadResource(const KrUnloadResourceInfo* unloadResourceInfo); - KrResult getResourceData(const KrGetResourceDataInfo* getResourceDataInfo, KrGetResourceDataCallback callback); - KrResult mapResource(const KrMapResourceInfo* mapResourceInfo); - KrResult unmapResource(const KrUnmapResourceInfo* unmapResourceInfo); - KrResult saveResource(const KrSaveResourceInfo* saveResourceInfo); - - KrResult compileAllShaders(const KrCompileAllShadersInfo* pCompileAllShadersInfo); - - KrResult createScene(const KrCreateSceneInfo* createSceneInfo); - KrResult findNodeByName(const KrFindNodeByNameInfo* pFindNodeByNameInfo); - KrResult findAdjacentNodes(const KrFindAdjacentNodesInfo* pFindAdjacentNodesInfo); - KrResult setNodeLocalTransform(const KrSetNodeLocalTransformInfo* pSetNodeLocalTransform); - KrResult setNodeWorldTransform(const KrSetNodeWorldTransformInfo* pSetNodeWorldTransform); - KrResult deleteNode(const KrDeleteNodeInfo* pDeleteNodeInfo); - KrResult deleteNodeChildren(const KrDeleteNodeChildrenInfo* pDeleteNodeChildrenInfo); - KrResult appendBeforeNode(const KrAppendBeforeNodeInfo* pAppendBeforeNodeInfo); - KrResult appendAfterNode(const KrAppendAfterNodeInfo* pAppendAfterNodeInfo); - KrResult appendFirstChildNode(const KrAppendFirstChildNodeInfo* pAppendFirstChildNodeInfo); - KrResult appendLastChildNode(const KrAppendLastChildNodeInfo* pAppendLastChildNodeInfo); - KrResult updateNode(const KrUpdateNodeInfo* pUpdateNodeInfo); + static int KRENGINE_MAX_PIPELINE_HANDLES; + static int KRENGINE_GPU_MEM_MAX; + static int KRENGINE_GPU_MEM_TARGET; + static int KRENGINE_MAX_TEXTURE_DIM; + static int KRENGINE_MIN_TEXTURE_DIM; + static int KRENGINE_PRESTREAM_DISTANCE; + static int KRENGINE_SYS_ALLOCATION_GRANULARITY; + static int KRENGINE_SYS_PAGE_SIZE; - KRResource* loadResource(const std::string &file_name, KRDataBlock *data); - - - KRBundleManager *getBundleManager(); - KRSceneManager *getSceneManager(); - KRTextureManager *getTextureManager(); - KRMaterialManager *getMaterialManager(); - KRPipelineManager *getPipelineManager(); - KRMeshManager *getMeshManager(); - KRAnimationManager *getAnimationManager(); - KRAnimationCurveManager *getAnimationCurveManager(); - KRAudioManager *getAudioManager(); - KRUnknownManager *getUnknownManager(); - KRShaderManager *getShaderManager(); - KRSourceManager *getSourceManager(); - KRSurfaceManager* getSurfaceManager(); - KRDeviceManager* getDeviceManager(); - - void startFrame(float deltaTime); - void endFrame(float deltaTime); - - long getCurrentFrame() const; - long getLastFullyStreamedFrame() const; - float getAbsoluteTime() const; - - long getAbsoluteTimeMilliseconds(); - - std::vector getResources(); - + KRContext(const KrInitializeInfo* initializeInfo); + ~KRContext(); + + KrResult createWindowSurface(const KrCreateWindowSurfaceInfo* createWindowSurfaceInfo); + KrResult deleteWindowSurface(const KrDeleteWindowSurfaceInfo* deleteWindowSurfaceInfo); + + KrResult createBundle(const KrCreateBundleInfo* createBundleInfo); + KrResult moveToBundle(const KrMoveToBundleInfo* moveToBundleInfo); + KrResult loadResource(const KrLoadResourceInfo* loadResourceInfo); + KrResult unloadResource(const KrUnloadResourceInfo* unloadResourceInfo); + KrResult getResourceData(const KrGetResourceDataInfo* getResourceDataInfo, KrGetResourceDataCallback callback); + KrResult mapResource(const KrMapResourceInfo* mapResourceInfo); + KrResult unmapResource(const KrUnmapResourceInfo* unmapResourceInfo); + KrResult saveResource(const KrSaveResourceInfo* saveResourceInfo); + + KrResult compileAllShaders(const KrCompileAllShadersInfo* pCompileAllShadersInfo); + + KrResult createScene(const KrCreateSceneInfo* createSceneInfo); + KrResult findNodeByName(const KrFindNodeByNameInfo* pFindNodeByNameInfo); + KrResult findAdjacentNodes(const KrFindAdjacentNodesInfo* pFindAdjacentNodesInfo); + KrResult setNodeLocalTransform(const KrSetNodeLocalTransformInfo* pSetNodeLocalTransform); + KrResult setNodeWorldTransform(const KrSetNodeWorldTransformInfo* pSetNodeWorldTransform); + KrResult deleteNode(const KrDeleteNodeInfo* pDeleteNodeInfo); + KrResult deleteNodeChildren(const KrDeleteNodeChildrenInfo* pDeleteNodeChildrenInfo); + KrResult appendBeforeNode(const KrAppendBeforeNodeInfo* pAppendBeforeNodeInfo); + KrResult appendAfterNode(const KrAppendAfterNodeInfo* pAppendAfterNodeInfo); + KrResult appendFirstChildNode(const KrAppendFirstChildNodeInfo* pAppendFirstChildNodeInfo); + KrResult appendLastChildNode(const KrAppendLastChildNodeInfo* pAppendLastChildNodeInfo); + KrResult updateNode(const KrUpdateNodeInfo* pUpdateNodeInfo); + + + KRResource* loadResource(const std::string& file_name, KRDataBlock* data); + + + KRBundleManager* getBundleManager(); + KRSceneManager* getSceneManager(); + KRTextureManager* getTextureManager(); + KRMaterialManager* getMaterialManager(); + KRPipelineManager* getPipelineManager(); + KRMeshManager* getMeshManager(); + KRAnimationManager* getAnimationManager(); + KRAnimationCurveManager* getAnimationCurveManager(); + KRAudioManager* getAudioManager(); + KRUnknownManager* getUnknownManager(); + KRShaderManager* getShaderManager(); + KRSourceManager* getSourceManager(); + KRSurfaceManager* getSurfaceManager(); + KRDeviceManager* getDeviceManager(); + + void startFrame(float deltaTime); + void endFrame(float deltaTime); + + long getCurrentFrame() const; + long getLastFullyStreamedFrame() const; + float getAbsoluteTime() const; + + long getAbsoluteTimeMilliseconds(); + + std::vector getResources(); + #if TARGET_OS_IPHONE || TARGET_OS_MAC - // XXX This doesn't belong here, and might not actually be needed at all - void getMemoryStats(long &free_memory); + // XXX This doesn't belong here, and might not actually be needed at all + void getMemoryStats(long& free_memory); #endif - typedef enum { - LOG_LEVEL_INFORMATION, - LOG_LEVEL_WARNING, - LOG_LEVEL_ERROR - } log_level; - - typedef void log_callback(void *userdata, const std::string &message, log_level level); - - static void SetLogCallback(log_callback *log_callback, void *user_data); - static void Log(log_level level, const std::string message_format, ...); - - void doStreaming(); - void receivedMemoryWarning(); + typedef enum + { + LOG_LEVEL_INFORMATION, + LOG_LEVEL_WARNING, + LOG_LEVEL_ERROR + } log_level; - static std::mutex g_SurfaceInfoMutex; - static std::mutex g_DeviceInfoMutex; + typedef void log_callback(void* userdata, const std::string& message, log_level level); - void addResource(KRResource* resource, const std::string& name); - void removeResource(KRResource* resource); + static void SetLogCallback(log_callback* log_callback, void* user_data); + static void Log(log_level level, const std::string message_format, ...); + + void doStreaming(); + void receivedMemoryWarning(); + + static std::mutex g_SurfaceInfoMutex; + static std::mutex g_DeviceInfoMutex; + + void addResource(KRResource* resource, const std::string& name); + void removeResource(KRResource* resource); private: - std::unique_ptr m_pBundleManager; - std::unique_ptr m_pSceneManager; - std::unique_ptr m_pTextureManager; - std::unique_ptr m_pMaterialManager; - std::unique_ptr m_pPipelineManager; - std::unique_ptr m_pMeshManager; - std::unique_ptr m_pAnimationManager; - std::unique_ptr m_pAnimationCurveManager; - std::unique_ptr m_pSoundManager; - std::unique_ptr m_pUnknownManager; - std::unique_ptr m_pShaderManager; - std::unique_ptr m_pSourceManager; - std::unique_ptr m_deviceManager; - std::unique_ptr m_surfaceManager; + std::unique_ptr m_pBundleManager; + std::unique_ptr m_pSceneManager; + std::unique_ptr m_pTextureManager; + std::unique_ptr m_pMaterialManager; + std::unique_ptr m_pPipelineManager; + std::unique_ptr m_pMeshManager; + std::unique_ptr m_pAnimationManager; + std::unique_ptr m_pAnimationCurveManager; + std::unique_ptr m_pSoundManager; + std::unique_ptr m_pUnknownManager; + std::unique_ptr m_pShaderManager; + std::unique_ptr m_pSourceManager; + std::unique_ptr m_deviceManager; + std::unique_ptr m_surfaceManager; + + KRResource** m_resourceMap; + size_t m_resourceMapSize; + + long m_current_frame; // TODO - Does this need to be atomic? + long m_last_memory_warning_frame; // TODO - Does this need to be atomic? + long m_last_fully_streamed_frame; // TODO - Does this need to be atomic? + float m_absolute_time; - KRResource** m_resourceMap; - size_t m_resourceMapSize; - - long m_current_frame; // TODO - Does this need to be atomic? - long m_last_memory_warning_frame; // TODO - Does this need to be atomic? - long m_last_fully_streamed_frame; // TODO - Does this need to be atomic? - float m_absolute_time; - #ifdef __APPLE__ - mach_timebase_info_data_t m_timebase_info; + mach_timebase_info_data_t m_timebase_info; #endif - // m_streamingEnabled is set to true once all managers are loaded - std::atomic m_streamingEnabled; - - static log_callback *s_log_callback; - static void *s_log_callback_user_data; - - unordered_multimap m_resources; + // m_streamingEnabled is set to true once all managers are loaded + std::atomic m_streamingEnabled; - - std::unique_ptr m_streamerThread; - std::unique_ptr m_presentationThread; + static log_callback* s_log_callback; + static void* s_log_callback_user_data; - unordered_map m_surfaceHandleMap; + unordered_multimap m_resources; + + + std::unique_ptr m_streamerThread; + std::unique_ptr m_presentationThread; + + unordered_map m_surfaceHandleMap; }; diff --git a/kraken/KRContextObject.cpp b/kraken/KRContextObject.cpp index 381317b..61290b0 100755 --- a/kraken/KRContextObject.cpp +++ b/kraken/KRContextObject.cpp @@ -31,17 +31,17 @@ #include "KRContextObject.h" -KRContextObject::KRContextObject(KRContext &context) +KRContextObject::KRContextObject(KRContext& context) { - m_pContext = &context; + m_pContext = &context; } KRContextObject::~KRContextObject() { - + } -KRContext &KRContextObject::getContext() const +KRContext& KRContextObject::getContext() const { - return *m_pContext; + return *m_pContext; } \ No newline at end of file diff --git a/kraken/KRContextObject.h b/kraken/KRContextObject.h index 4a90656..30b80a7 100755 --- a/kraken/KRContextObject.h +++ b/kraken/KRContextObject.h @@ -33,13 +33,14 @@ class KRContext; -class KRContextObject { +class KRContextObject +{ public: - KRContextObject(KRContext &context); - ~KRContextObject(); - - KRContext &getContext() const; + KRContextObject(KRContext& context); + ~KRContextObject(); + + KRContext& getContext() const; protected: - KRContext *m_pContext; + KRContext* m_pContext; }; diff --git a/kraken/KRDSP.h b/kraken/KRDSP.h index f530197..078c2dd 100644 --- a/kraken/KRDSP.h +++ b/kraken/KRDSP.h @@ -39,53 +39,56 @@ namespace KRDSP { #define KRDSP_APPLE_VDSP #include #else - // Slow, but portable fallback implementation +// Slow, but portable fallback implementation #define KRDSP_SLOW #endif #if defined(KRDSP_APPLE_VDSP) // Apple vDSP - typedef DSPSplitComplex SplitComplex; - struct FFTWorkspace { - FFTSetup setup; +typedef DSPSplitComplex SplitComplex; +struct FFTWorkspace +{ + FFTSetup setup; - void create(size_t length); - void destroy(); - FFTWorkspace(); - ~FFTWorkspace(); - }; + void create(size_t length); + void destroy(); + FFTWorkspace(); + ~FFTWorkspace(); +}; #elif defined(KRDSP_SLOW) - typedef struct { - float *realp; - float *imagp; - } SplitComplex; +typedef struct +{ + float* realp; + float* imagp; +} SplitComplex; - struct FFTWorkspace { - float *sin_table; - float *cos_table; +struct FFTWorkspace +{ + float* sin_table; + float* cos_table; - void create(size_t length); - void destroy(); - FFTWorkspace(); - ~FFTWorkspace(); - }; + void create(size_t length); + void destroy(); + FFTWorkspace(); + ~FFTWorkspace(); +}; #else #error Not Implemented #endif -void FFTForward(const FFTWorkspace &workspace, SplitComplex *src, size_t count); -void FFTInverse(const FFTWorkspace &workspace, SplitComplex *src, size_t count); -void Int16ToFloat(const short *src, size_t srcStride, float *dest, size_t destStride, size_t count); -void Scale(float *buffer, float scale, size_t count); -void ScaleCopy(const float *src, float scale, float *dest, size_t count); -void ScaleCopy(const SplitComplex *src, float scale, SplitComplex *dest, size_t count); -void ScaleRamp(float *buffer, float scaleStart, float scaleStep, size_t count); -void Accumulate(float *buffer, size_t bufferStride, const float *buffer2, size_t buffer2Stride, size_t count); -void Accumulate(SplitComplex *buffer, const SplitComplex *buffer2, size_t count); -void Multiply(const SplitComplex *a, const SplitComplex *b, SplitComplex *c, size_t count); +void FFTForward(const FFTWorkspace& workspace, SplitComplex* src, size_t count); +void FFTInverse(const FFTWorkspace& workspace, SplitComplex* src, size_t count); +void Int16ToFloat(const short* src, size_t srcStride, float* dest, size_t destStride, size_t count); +void Scale(float* buffer, float scale, size_t count); +void ScaleCopy(const float* src, float scale, float* dest, size_t count); +void ScaleCopy(const SplitComplex* src, float scale, SplitComplex* dest, size_t count); +void ScaleRamp(float* buffer, float scaleStart, float scaleStep, size_t count); +void Accumulate(float* buffer, size_t bufferStride, const float* buffer2, size_t buffer2Stride, size_t count); +void Accumulate(SplitComplex* buffer, const SplitComplex* buffer2, size_t count); +void Multiply(const SplitComplex* a, const SplitComplex* b, SplitComplex* c, size_t count); } // namespace KRDSP diff --git a/kraken/KRDSP_slow.cpp b/kraken/KRDSP_slow.cpp index 9649ae1..c2ae1be 100644 --- a/kraken/KRDSP_slow.cpp +++ b/kraken/KRDSP_slow.cpp @@ -72,7 +72,7 @@ void FFTWorkspace::destroy() } } -void FFTForward(const FFTWorkspace &workspace, SplitComplex *src, size_t count) +void FFTForward(const FFTWorkspace& workspace, SplitComplex* src, size_t count) { // Radix-2 Decimation in Time FFT Algorithm // http://en.dsplib.org/content/fft_dec_in_time.html @@ -119,7 +119,7 @@ void FFTForward(const FFTWorkspace &workspace, SplitComplex *src, size_t count) } } -void FFTInverse(const FFTWorkspace &workspace, SplitComplex *src, size_t count) +void FFTInverse(const FFTWorkspace& workspace, SplitComplex* src, size_t count) { SplitComplex swapped; swapped.imagp = src->realp; @@ -127,10 +127,10 @@ void FFTInverse(const FFTWorkspace &workspace, SplitComplex *src, size_t count) FFTForward(workspace, &swapped, count); } -void Int16ToFloat(const short *src, size_t srcStride, float *dest, size_t destStride, size_t count) +void Int16ToFloat(const short* src, size_t srcStride, float* dest, size_t destStride, size_t count) { - const short *r = src; - float *w = dest; + const short* r = src; + float* w = dest; while (w < dest + destStride * count) { *w = (float)*r; r += srcStride; @@ -138,19 +138,19 @@ void Int16ToFloat(const short *src, size_t srcStride, float *dest, size_t destSt } } -void Scale(float *buffer, float scale, size_t count) +void Scale(float* buffer, float scale, size_t count) { - float *w = buffer; + float* w = buffer; while (w < buffer + count) { *w *= scale; w++; } } -void ScaleCopy(const float *src, float scale, float *dest, size_t count) +void ScaleCopy(const float* src, float scale, float* dest, size_t count) { - const float *r = src; - float *w = dest; + const float* r = src; + float* w = dest; while (w < dest + count) { *w = *r * scale; w++; @@ -158,15 +158,15 @@ void ScaleCopy(const float *src, float scale, float *dest, size_t count) } } -void ScaleCopy(const SplitComplex *src, float scale, SplitComplex *dest, size_t count) +void ScaleCopy(const SplitComplex* src, float scale, SplitComplex* dest, size_t count) { ScaleCopy(src->realp, scale, dest->realp, count); ScaleCopy(src->imagp, scale, dest->imagp, count); } -void ScaleRamp(float *buffer, float scaleStart, float scaleStep, size_t count) +void ScaleRamp(float* buffer, float scaleStart, float scaleStep, size_t count) { - float *w = buffer; + float* w = buffer; float s = scaleStart; while (w < buffer + count) { *w *= s; @@ -175,10 +175,10 @@ void ScaleRamp(float *buffer, float scaleStart, float scaleStep, size_t count) } } -void Accumulate(float *buffer, size_t bufferStride, const float *buffer2, size_t buffer2Stride, size_t count) +void Accumulate(float* buffer, size_t bufferStride, const float* buffer2, size_t buffer2Stride, size_t count) { - float *w = buffer; - const float *r = buffer2; + float* w = buffer; + const float* r = buffer2; while (w < buffer + bufferStride * count) { *w *= *r; w += bufferStride; @@ -186,7 +186,7 @@ void Accumulate(float *buffer, size_t bufferStride, const float *buffer2, size_t } } -void Accumulate(SplitComplex *buffer, const SplitComplex *buffer2, size_t count) +void Accumulate(SplitComplex* buffer, const SplitComplex* buffer2, size_t count) { for (size_t i = 0; i < count; i++) { buffer->imagp[i] += buffer2->imagp[i]; @@ -194,7 +194,7 @@ void Accumulate(SplitComplex *buffer, const SplitComplex *buffer2, size_t count) } } -void Multiply(const SplitComplex *a, const SplitComplex *b, SplitComplex *c, size_t count) +void Multiply(const SplitComplex* a, const SplitComplex* b, SplitComplex* c, size_t count) { for (size_t i = 0; i < count; i++) { c->realp[i] = a->realp[i] * b->realp[i] - a->imagp[i] * b->imagp[i]; diff --git a/kraken/KRDSP_vDSP.cpp b/kraken/KRDSP_vDSP.cpp index f6f16b6..b59ccfa 100644 --- a/kraken/KRDSP_vDSP.cpp +++ b/kraken/KRDSP_vDSP.cpp @@ -62,54 +62,54 @@ void FFTWorkspace::destroy() } } -void FFTForward(const FFTWorkspace &workspace, SplitComplex *src, size_t count) +void FFTForward(const FFTWorkspace& workspace, SplitComplex* src, size_t count) { vDSP_fft_zip(workspace.setup, src, 1, count, kFFTDirection_Forward); } -void FFTInverse(const FFTWorkspace &workspace, SplitComplex *src, size_t count) +void FFTInverse(const FFTWorkspace& workspace, SplitComplex* src, size_t count) { vDSP_fft_zip(workspace.setup, src, 1, count, kFFTDirection_Inverse); } -void Int16ToFloat(const short *src, size_t srcStride, float *dest, size_t destStride, size_t count) +void Int16ToFloat(const short* src, size_t srcStride, float* dest, size_t destStride, size_t count) { vDSP_vflt16(src, srcStride, dest, destStride, count); } -void Scale(float *buffer, float scale, size_t count) +void Scale(float* buffer, float scale, size_t count) { vDSP_vsmul(buffer, 1, &scale, buffer, 1, count); } -void ScaleCopy(const float *src, float scale, float *dest, size_t count) +void ScaleCopy(const float* src, float scale, float* dest, size_t count) { vDSP_vsmul(src, 1, &scale, dest, 1, count); } -void ScaleCopy(const SplitComplex *src, float scale, SplitComplex *dest, size_t count) +void ScaleCopy(const SplitComplex* src, float scale, SplitComplex* dest, size_t count) { ScaleCopy(src->realp, scale, dest->realp, count); ScaleCopy(src->imagp, scale, dest->imagp, count); } -void ScaleRamp(float *buffer, float scaleStart, float scaleStep, size_t count) +void ScaleRamp(float* buffer, float scaleStart, float scaleStep, size_t count) { vDSP_vrampmul(buffer, 1, &scaleStart, &scaleStep, buffer, 1, count); } -void Accumulate(float *buffer, size_t bufferStride, const float *buffer2, size_t buffer2Stride, size_t count) +void Accumulate(float* buffer, size_t bufferStride, const float* buffer2, size_t buffer2Stride, size_t count) { vDSP_vadd(buffer, bufferStride, buffer2, buffer2Stride, buffer, bufferStride, count); } -void Accumulate(SplitComplex *buffer, const SplitComplex *buffer2, size_t count) +void Accumulate(SplitComplex* buffer, const SplitComplex* buffer2, size_t count) { vDSP_zvadd(buffer2, 1, buffer, 1, buffer, 1, count); } -void Multiply(const SplitComplex *a, const SplitComplex *b, SplitComplex *c, size_t count) +void Multiply(const SplitComplex* a, const SplitComplex* b, SplitComplex* c, size_t count) { vDSP_zvmul(a, 1, b, 1, c, 1, count, 1); } diff --git a/kraken/KRDataBlock.cpp b/kraken/KRDataBlock.cpp index bbae3f6..94a2839 100755 --- a/kraken/KRDataBlock.cpp +++ b/kraken/KRDataBlock.cpp @@ -47,236 +47,245 @@ int m_mapCount = 0; size_t m_mapSize = 0; size_t m_mapOverhead = 0; -KRDataBlock::KRDataBlock() { - m_data = NULL; - m_data_size = 0; - m_data_offset = 0; +KRDataBlock::KRDataBlock() +{ + m_data = NULL; + m_data_size = 0; + m_data_offset = 0; #if defined(_WIN32) || defined(_WIN64) - m_hPackFile = INVALID_HANDLE_VALUE; - m_hFileMapping = NULL; + m_hPackFile = INVALID_HANDLE_VALUE; + m_hFileMapping = NULL; #elif defined(__APPLE__) - m_fdPackFile = 0; + m_fdPackFile = 0; #endif - m_fileName = ""; - m_mmapData = NULL; - m_fileOwnerDataBlock = NULL; - m_bMalloced = false; - m_lockCount = 0; - m_bReadOnly = false; + m_fileName = ""; + m_mmapData = NULL; + m_fileOwnerDataBlock = NULL; + m_bMalloced = false; + m_lockCount = 0; + m_bReadOnly = false; } -KRDataBlock::KRDataBlock(void *data, size_t size) { - m_data = NULL; - m_data_size = 0; - m_data_offset = 0; +KRDataBlock::KRDataBlock(void* data, size_t size) +{ + m_data = NULL; + m_data_size = 0; + m_data_offset = 0; #if defined(_WIN32) || defined(_WIN64) - m_hPackFile = INVALID_HANDLE_VALUE; - m_hFileMapping = NULL; + m_hPackFile = INVALID_HANDLE_VALUE; + m_hFileMapping = NULL; #elif defined(__APPLE__) - m_fdPackFile = 0; + m_fdPackFile = 0; #endif - m_fileName = ""; - m_mmapData = NULL; - m_fileOwnerDataBlock = NULL; - m_bMalloced = false; - m_lockCount = 0; - m_bReadOnly = false; - load(data, size); + m_fileName = ""; + m_mmapData = NULL; + m_fileOwnerDataBlock = NULL; + m_bMalloced = false; + m_lockCount = 0; + m_bReadOnly = false; + load(data, size); } -KRDataBlock::~KRDataBlock() { - unload(); +KRDataBlock::~KRDataBlock() +{ + unload(); } // Unload a file, releasing any mmap'ed file handles or malloc'ed ram that was in use void KRDataBlock::unload() { - assert(m_lockCount == 0); + assert(m_lockCount == 0); #if defined(_WIN32) || defined(_WIN64) - if (m_hPackFile != INVALID_HANDLE_VALUE) { - // Memory mapped file - if (m_fileOwnerDataBlock == this) { - CloseHandle(m_hPackFile); - } - m_hPackFile = INVALID_HANDLE_VALUE; + if (m_hPackFile != INVALID_HANDLE_VALUE) { + // Memory mapped file + if (m_fileOwnerDataBlock == this) { + CloseHandle(m_hPackFile); } + m_hPackFile = INVALID_HANDLE_VALUE; + } #elif defined(__APPLE__) - if(m_fdPackFile) { - // Memory mapped file - if(m_fileOwnerDataBlock == this) { - close(m_fdPackFile); - } - m_fdPackFile = 0; + if (m_fdPackFile) { + // Memory mapped file + if (m_fileOwnerDataBlock == this) { + close(m_fdPackFile); } + m_fdPackFile = 0; + } #endif - if(m_data != NULL && m_bMalloced) { - // Malloc'ed data - free(m_data); - } + if (m_data != NULL && m_bMalloced) { + // Malloc'ed data + free(m_data); + } - m_bMalloced = false; - m_data = NULL; - m_data_size = 0; - m_data_offset = 0; - m_fileName = ""; - m_mmapData = NULL; - m_fileOwnerDataBlock = NULL; - m_bReadOnly = false; + m_bMalloced = false; + m_data = NULL; + m_data_size = 0; + m_data_offset = 0; + m_fileName = ""; + m_mmapData = NULL; + m_fileOwnerDataBlock = NULL; + m_bReadOnly = false; } // Encapsulate a pointer. Note - The pointer will not be free'ed -bool KRDataBlock::load(void *data, size_t size) +bool KRDataBlock::load(void* data, size_t size) { - unload(); - m_data = data; - m_data_size = size; - m_data_offset = 0; - m_bReadOnly = false; - return true; + unload(); + m_data = data; + m_data_size = size; + m_data_offset = 0; + m_bReadOnly = false; + return true; } // Load a file into memory using mmap. The data pointer will be protected as read-only until append() or expand() is called -bool KRDataBlock::load(const std::string &path) +bool KRDataBlock::load(const std::string& path) { - bool success = false; - unload(); + bool success = false; + unload(); - m_bReadOnly = true; + m_bReadOnly = true; #if defined(_WIN32) || defined(_WIN64) - m_hPackFile = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if(m_hPackFile != INVALID_HANDLE_VALUE) { - m_fileOwnerDataBlock = this; - m_fileName = KRResource::GetFileBase(path); - FILE_STANDARD_INFO fileInfo; - if(GetFileInformationByHandleEx(m_hPackFile, FileStandardInfo, &fileInfo, sizeof(fileInfo))) { - m_data_size = fileInfo.EndOfFile.QuadPart; - m_data_offset = 0; - success = true; - } + m_hPackFile = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (m_hPackFile != INVALID_HANDLE_VALUE) { + m_fileOwnerDataBlock = this; + m_fileName = KRResource::GetFileBase(path); + FILE_STANDARD_INFO fileInfo; + if (GetFileInformationByHandleEx(m_hPackFile, FileStandardInfo, &fileInfo, sizeof(fileInfo))) { + m_data_size = fileInfo.EndOfFile.QuadPart; + m_data_offset = 0; + success = true; } + } #elif defined(__APPLE__) - m_fdPackFile = open(path.c_str(), O_RDONLY); - if(m_fdPackFile >= 0) { - m_fileOwnerDataBlock = this; - m_fileName = KRResource::GetFileBase(path); - struct stat statbuf; - if(fstat(m_fdPackFile, &statbuf) >= 0) { - m_data_size = statbuf.st_size; - m_data_offset = 0; - success = true; - } + m_fdPackFile = open(path.c_str(), O_RDONLY); + if (m_fdPackFile >= 0) { + m_fileOwnerDataBlock = this; + m_fileName = KRResource::GetFileBase(path); + struct stat statbuf; + if (fstat(m_fdPackFile, &statbuf) >= 0) { + m_data_size = statbuf.st_size; + m_data_offset = 0; + success = true; } + } #endif - if(!success) { - // If anything failed, don't leave the object in an invalid state - unload(); - } - return success; + if (!success) { + // If anything failed, don't leave the object in an invalid state + unload(); + } + return success; } // Create a KRDataBlock encapsulating a sub-region of this block. The caller is responsible to free the object. -KRDataBlock *KRDataBlock::getSubBlock(int start, int length) +KRDataBlock* KRDataBlock::getSubBlock(int start, int length) { - KRDataBlock *new_block = new KRDataBlock(); + KRDataBlock* new_block = new KRDataBlock(); - new_block->m_data_size = length; + new_block->m_data_size = length; #if defined(_WIN32) || defined(_WIN64) - if(m_hPackFile != INVALID_HANDLE_VALUE) { - new_block->m_hPackFile = m_hPackFile; + if (m_hPackFile != INVALID_HANDLE_VALUE) { + new_block->m_hPackFile = m_hPackFile; #elif defined(__APPLE__) || defined(ANDROID) - if (m_fdPackFile) { - new_block->m_fdPackFile = m_fdPackFile; + if (m_fdPackFile) { + new_block->m_fdPackFile = m_fdPackFile; #else #error Unsupported #endif - new_block->m_fileOwnerDataBlock = m_fileOwnerDataBlock; - new_block->m_data_offset = start + m_data_offset; - } else if(m_bMalloced) { - new_block->m_data = (unsigned char *)m_data + start + m_data_offset; - } - new_block->m_bReadOnly = true; + new_block->m_fileOwnerDataBlock = m_fileOwnerDataBlock; + new_block->m_data_offset = start + m_data_offset; + } else if (m_bMalloced) { + new_block->m_data = (unsigned char*)m_data + start + m_data_offset; + } + new_block->m_bReadOnly = true; - return new_block; + return new_block; } // Return a pointer to the start of the data block -void *KRDataBlock::getStart() { - assertLocked(); - return m_data; +void* KRDataBlock::getStart() +{ + assertLocked(); + return m_data; } // Return a pointer to the byte after the end of the data block -void *KRDataBlock::getEnd() { - assertLocked(); - return (unsigned char *)m_data + m_data_size; +void* KRDataBlock::getEnd() +{ + assertLocked(); + return (unsigned char*)m_data + m_data_size; } // Return the size of the data block. Use append() or expand() to make the data block larger -size_t KRDataBlock::getSize() const { - return m_data_size; +size_t KRDataBlock::getSize() const +{ + return m_data_size; } // Expand the data block, and switch it to read-write mode. Note - this may result in a mmap'ed file being copied to malloc'ed ram and then closed void KRDataBlock::expand(size_t size) { #if defined(_WIN32) || defined(_WIN64) - if(m_data == NULL && m_hPackFile == INVALID_HANDLE_VALUE) { + if (m_data == NULL && m_hPackFile == INVALID_HANDLE_VALUE) { #elif defined(__APPLE__) || defined(ANDROID) - if (m_data == NULL && m_fdPackFile == 0) { + if (m_data == NULL && m_fdPackFile == 0) { #else #error Unsupported #endif - // Starting with an empty data block; allocate memory on the heap - m_data = malloc(size); - assert(m_data != NULL); - m_data_size = size; - m_data_offset = 0; - m_bMalloced = true; - } else if(m_bMalloced) { - // Starting with a malloc'ed data block; realloc it expand - m_data = realloc(m_data, m_data_size + size); - m_data_size += size; - } else { - // Starting with a mmap'ed data block, an encapsulated pointer, or a sub-block; copy it to ram before expanding to avoid updating the original file until save() is called - // ... Or starting with a pointer reference, we must make our own copy and must not free the pointer - void *pNewData = malloc(m_data_size + size); - assert(pNewData != NULL); + // Starting with an empty data block; allocate memory on the heap + m_data = malloc(size); + assert(m_data != NULL); + m_data_size = size; + m_data_offset = 0; + m_bMalloced = true; + } else if (m_bMalloced) { + // Starting with a malloc'ed data block; realloc it expand + m_data = realloc(m_data, m_data_size + size); + m_data_size += size; + } else { + // Starting with a mmap'ed data block, an encapsulated pointer, or a sub-block; copy it to ram before expanding to avoid updating the original file until save() is called + // ... Or starting with a pointer reference, we must make our own copy and must not free the pointer + void* pNewData = malloc(m_data_size + size); + assert(pNewData != NULL); - // Copy exising data - copy(pNewData); + // Copy exising data + copy(pNewData); - // Unload existing data allocation, which is now redundant - size_t new_size = m_data_size + size; // We need to store this before unload() as unload() will reset it - unload(); - m_bMalloced = true; - m_data = pNewData; - m_data_size = new_size; - m_data_offset = 0; - } + // Unload existing data allocation, which is now redundant + size_t new_size = m_data_size + size; // We need to store this before unload() as unload() will reset it + unload(); + m_bMalloced = true; + m_data = pNewData; + m_data_size = new_size; + m_data_offset = 0; + } } // Append data to the end of the block, increasing the size of the block and making it read-write. -void KRDataBlock::append(void *data, size_t size) { - // Expand the data block - expand(size); +void KRDataBlock::append(void* data, size_t size) +{ + // Expand the data block + expand(size); - // Fill the new space with the data to append - lock(); - memcpy((unsigned char *)m_data + m_data_size - size, data, size); - unlock(); + // Fill the new space with the data to append + lock(); + memcpy((unsigned char*)m_data + m_data_size - size, data, size); + unlock(); } // Copy the entire data block to the destination pointer -void KRDataBlock::copy(void *dest) { - copy(dest, 0, (int)m_data_size); +void KRDataBlock::copy(void* dest) +{ + copy(dest, 0, (int)m_data_size); } // Copy a range of data to the destination pointer -void KRDataBlock::copy(void *dest, int start, int count) { +void KRDataBlock::copy(void* dest, int start, int count) +{ #if defined(_WIN32) || defined(_WIN64) if (m_lockCount == 0 && m_hPackFile != INVALID_HANDLE_VALUE) { // Optimization: If we haven't mmap'ed or malloced the data already, ReadFile() it directly from the file into the buffer @@ -285,41 +294,42 @@ void KRDataBlock::copy(void *dest, int start, int count) { bool success = SetFilePointerEx(m_hPackFile, distance, NULL, FILE_BEGIN); assert(success); - void *w = dest; + void* w = dest; DWORD bytes_remaining = count; - while(bytes_remaining > 0) { + while (bytes_remaining > 0) { DWORD bytes_read = 0; success = ReadFile(m_hPackFile, w, bytes_remaining, &bytes_read, NULL); assert(success); assert(bytes_read > 0); - w = (unsigned char *)w + bytes_read; + w = (unsigned char*)w + bytes_read; bytes_remaining -= bytes_read; } assert(bytes_remaining == 0); #elif defined(__APPLE__) || defined(ANDROID) - if(m_lockCount == 0 && m_fdPackFile != 0) { - // Optimization: If we haven't mmap'ed or malloced the data already, pread() it directly from the file into the buffer - ssize_t r = pread(m_fdPackFile, dest, count, start + m_data_offset); - assert(r != -1); + if (m_lockCount == 0 && m_fdPackFile != 0) { + // Optimization: If we haven't mmap'ed or malloced the data already, pread() it directly from the file into the buffer + ssize_t r = pread(m_fdPackFile, dest, count, start + m_data_offset); + assert(r != -1); #else #error Unsupported #endif - } else { - lock(); - memcpy((unsigned char *)dest, (unsigned char *)m_data + start, count); - unlock(); - } + } else { + lock(); + memcpy((unsigned char*)dest, (unsigned char*)m_data + start, count); + unlock(); +} } // Append data to the end of the block, increasing the size of the block and making it read-write. -void KRDataBlock::append(KRDataBlock &data) { - data.lock(); - append(data.getStart(), data.getSize()); - data.unlock(); +void KRDataBlock::append(KRDataBlock & data) +{ + data.lock(); + append(data.getStart(), data.getSize()); + data.unlock(); } // Append string to the end of the block, increasing the size of the block and making it read-write. The resulting datablock includes a terminating character -void KRDataBlock::append(const std::string &s) +void KRDataBlock::append(const std::string & s) { const char* szText = s.c_str(); size_t text_length = strlen(szText); @@ -339,12 +349,13 @@ void KRDataBlock::append(const std::string &s) } // Save the data to a file. -bool KRDataBlock::save(const std::string& path) { +bool KRDataBlock::save(const std::string & path) +{ #if defined(_WIN32) || defined(_WIN64) bool success = true; HANDLE hNewFile = INVALID_HANDLE_VALUE; HANDLE hFileMapping = NULL; - void *pNewData = NULL; + void* pNewData = NULL; hNewFile = CreateFile(path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hNewFile == INVALID_HANDLE_VALUE) { @@ -385,32 +396,32 @@ bool KRDataBlock::save(const std::string& path) { return success; #elif defined(__APPLE__) || defined(ANDROID) - int fdNewFile = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); - if(fdNewFile == -1) { - return false; - } + int fdNewFile = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); + if (fdNewFile == -1) { + return false; + } - // Seek to end of file and write a byte to enlarge it - lseek(fdNewFile, m_data_size-1, SEEK_SET); - write(fdNewFile, "", 1); + // Seek to end of file and write a byte to enlarge it + lseek(fdNewFile, m_data_size - 1, SEEK_SET); + write(fdNewFile, "", 1); - // Now map it... - void *pNewData = mmap(0, m_data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdNewFile, 0); - if(pNewData == (caddr_t) -1) { - close(fdNewFile); - return false; - } - if(m_data != NULL) { - // Copy data to new file - copy(pNewData); + // Now map it... + void* pNewData = mmap(0, m_data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdNewFile, 0); + if (pNewData == (caddr_t)-1) { + close(fdNewFile); + return false; + } + if (m_data != NULL) { + // Copy data to new file + copy(pNewData); - // Unmap the new file - munmap(pNewData, m_data_size); + // Unmap the new file + munmap(pNewData, m_data_size); - // Close the new file - close(fdNewFile); - } - return true; + // Close the new file + close(fdNewFile); + } + return true; #else #error Unsupported @@ -420,13 +431,13 @@ bool KRDataBlock::save(const std::string& path) { // Get contents as a string std::string KRDataBlock::getString() { - KRDataBlock b; - b.append(*this); - b.append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely - b.lock(); - std::string ret = std::string((char *)b.getStart()); - b.unlock(); - return ret; + KRDataBlock b; + b.append(*this); + b.append((void*)"\0", 1); // Ensure data is null terminated, to read as a string safely + b.lock(); + std::string ret = std::string((char*)b.getStart()); + b.unlock(); + return ret; } #if defined(_WIN32) || defined(_WIN64) @@ -462,133 +473,133 @@ void ReportWindowsLastError(LPCTSTR lpszFunction) // Lock the memory, forcing it to be loaded into a contiguous block of address space void KRDataBlock::lock() { - if(m_lockCount == 0) { + if (m_lockCount == 0) { - // Memory mapped file; ensure data is mapped to ram + // Memory mapped file; ensure data is mapped to ram #if defined(_WIN32) || defined(_WIN64) - if(m_hPackFile != INVALID_HANDLE_VALUE) { + if (m_hPackFile != INVALID_HANDLE_VALUE) { #elif defined(__APPLE__) || defined(ANDROID) - if(m_fdPackFile) { + if (m_fdPackFile) { #else #error Unsupported #endif - if(m_data_size < KRENGINE_MIN_MMAP) { - m_data = malloc(m_data_size); - assert(m_data != NULL); - copy(m_data); - } else { - size_t alignment_offset = m_data_offset & (KRContext::KRENGINE_SYS_ALLOCATION_GRANULARITY - 1); - assert(m_mmapData == NULL); + if (m_data_size < KRENGINE_MIN_MMAP) { + m_data = malloc(m_data_size); + assert(m_data != NULL); + copy(m_data); + } else { + size_t alignment_offset = m_data_offset & (KRContext::KRENGINE_SYS_ALLOCATION_GRANULARITY - 1); + assert(m_mmapData == NULL); #if defined(_WIN32) || defined(_WIN64) - m_hFileMapping = CreateFileMappingFromApp(m_hPackFile, NULL, m_bReadOnly ? PAGE_READONLY : PAGE_READWRITE, m_fileOwnerDataBlock->getSize(), NULL); - if(m_hFileMapping == NULL) { - ReportWindowsLastError("CreateFileMappingFromApp"); - } - assert(m_hFileMapping != NULL); + m_hFileMapping = CreateFileMappingFromApp(m_hPackFile, NULL, m_bReadOnly ? PAGE_READONLY : PAGE_READWRITE, m_fileOwnerDataBlock->getSize(), NULL); + if (m_hFileMapping == NULL) { + ReportWindowsLastError("CreateFileMappingFromApp"); + } + assert(m_hFileMapping != NULL); - m_mmapData = MapViewOfFileFromApp(m_hFileMapping, m_bReadOnly ? FILE_MAP_READ | FILE_MAP_COPY : FILE_MAP_WRITE, m_data_offset - alignment_offset, m_data_size + alignment_offset); - if(m_mmapData == NULL) { - ReportWindowsLastError("MapViewOfFileFromApp"); - } - assert(m_mmapData != NULL); + m_mmapData = MapViewOfFileFromApp(m_hFileMapping, m_bReadOnly ? FILE_MAP_READ | FILE_MAP_COPY : FILE_MAP_WRITE, m_data_offset - alignment_offset, m_data_size + alignment_offset); + if (m_mmapData == NULL) { + ReportWindowsLastError("MapViewOfFileFromApp"); + } + assert(m_mmapData != NULL); #elif defined(__APPLE__) || defined(ANDROID) - //fprintf(stderr, "KRDataBlock::lock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); - // Round m_data_offset down to the next memory page, as required by mmap + //fprintf(stderr, "KRDataBlock::lock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); + // Round m_data_offset down to the next memory page, as required by mmap - if ((m_mmapData = mmap(0, m_data_size + alignment_offset, m_bReadOnly ? PROT_READ : PROT_WRITE, MAP_SHARED, m_fdPackFile, m_data_offset - alignment_offset)) == (caddr_t) -1) { - int iError = errno; - switch(iError) { - case EACCES: - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EACCES"); - break; - case EBADF: - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EBADF"); - break; - case EMFILE: - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EMFILE"); - break; - case EINVAL: - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EINVAL"); - break; - case ENOMEM: - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with ENOMEM"); - break; - case ENXIO: - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with ENXIO"); - break; - case EOVERFLOW: - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EOVERFLOW"); - break; - default: - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with errno: %i", iError); - break; - } - assert(false); // mmap() failed. - } -#else -#error Unsupported -#endif - m_mapCount++; - m_mapSize += m_data_size; - m_mapOverhead += alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; - // fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); - m_data = (unsigned char *)m_mmapData + alignment_offset; - } + if ((m_mmapData = mmap(0, m_data_size + alignment_offset, m_bReadOnly ? PROT_READ : PROT_WRITE, MAP_SHARED, m_fdPackFile, m_data_offset - alignment_offset)) == (caddr_t)-1) { + int iError = errno; + switch (iError) { + case EACCES: + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EACCES"); + break; + case EBADF: + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EBADF"); + break; + case EMFILE: + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EMFILE"); + break; + case EINVAL: + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EINVAL"); + break; + case ENOMEM: + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with ENOMEM"); + break; + case ENXIO: + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with ENXIO"); + break; + case EOVERFLOW: + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EOVERFLOW"); + break; + default: + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with errno: %i", iError); + break; } + assert(false); // mmap() failed. + } +#else +#error Unsupported +#endif + m_mapCount++; + m_mapSize += m_data_size; + m_mapOverhead += alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; + // fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); + m_data = (unsigned char*)m_mmapData + alignment_offset; } - m_lockCount++; + } + } +m_lockCount++; } // Unlock the memory, releasing the address space for use by other allocations void KRDataBlock::unlock() { - // We expect that the data block was previously locked - assertLocked(); + // We expect that the data block was previously locked + assertLocked(); - if(m_lockCount == 1) { + if (m_lockCount == 1) { - // Memory mapped file; ensure data is unmapped from ram + // Memory mapped file; ensure data is unmapped from ram #if defined(_WIN32) || defined(_WIN64) - if (m_hPackFile != INVALID_HANDLE_VALUE) { + if (m_hPackFile != INVALID_HANDLE_VALUE) { #elif defined(__APPLE__) || defined(ANDROID) - if(m_fdPackFile) { + if (m_fdPackFile) { #else #error Undefined #endif - if(m_data_size < KRENGINE_MIN_MMAP) { - free(m_data); - m_data = NULL; - } else { - //fprintf(stderr, "KRDataBlock::unlock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); + if (m_data_size < KRENGINE_MIN_MMAP) { + free(m_data); + m_data = NULL; + } else { + //fprintf(stderr, "KRDataBlock::unlock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount); #if defined(_WIN32) || defined(_WIN64) - if (m_mmapData != NULL) { - UnmapViewOfFile(m_mmapData); - } - if(m_hFileMapping != NULL) { - CloseHandle(m_hFileMapping); - m_hFileMapping = NULL; - } + if (m_mmapData != NULL) { + UnmapViewOfFile(m_mmapData); + } + if (m_hFileMapping != NULL) { + CloseHandle(m_hFileMapping); + m_hFileMapping = NULL; + } #elif defined(__APPLE__) || defined(ANDROID) - munmap(m_mmapData, m_data_size); + munmap(m_mmapData, m_data_size); #else #error Undefined #endif - m_data = NULL; - m_mmapData = NULL; - m_mapCount--; - m_mapSize -= m_data_size; - size_t alignment_offset = m_data_offset & (KRContext::KRENGINE_SYS_ALLOCATION_GRANULARITY - 1); - m_mapOverhead -= alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; - // fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); - } - } + m_data = NULL; + m_mmapData = NULL; + m_mapCount--; + m_mapSize -= m_data_size; + size_t alignment_offset = m_data_offset & (KRContext::KRENGINE_SYS_ALLOCATION_GRANULARITY - 1); + m_mapOverhead -= alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset; + // fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead); } - m_lockCount--; + } + } +m_lockCount--; } // Assert if not locked void KRDataBlock::assertLocked() { - assert(m_lockCount > 0); + assert(m_lockCount > 0); } diff --git a/kraken/KRDataBlock.h b/kraken/KRDataBlock.h index 8c0b1a5..e42dfc6 100755 --- a/kraken/KRDataBlock.h +++ b/kraken/KRDataBlock.h @@ -39,90 +39,91 @@ #define KRENGINE_MIN_MMAP 32768 -class KRDataBlock { +class KRDataBlock +{ public: - KRDataBlock(); - KRDataBlock(void *data, size_t size); - ~KRDataBlock(); - - // Encapsulate a pointer. Note - The pointer will not be free'ed - bool load(void *data, size_t size); - - // Load a file into memory using mmap. The data pointer will be protected as read-only until append() or expand() is called - bool load(const std::string &path); - - // Save the data to a file. - bool save(const std::string& path); - - // Create a KRDataBlock encapsulating a sub-region of this block. The caller is responsible to free the object. - KRDataBlock *getSubBlock(int start, int length); - - // Append data to the end of the block, increasing the size of the block and making it read-write. - void append(void *data, size_t size); - - // Append data to the end of the block, increasing the size of the block and making it read-write. - void append(KRDataBlock &data); - - // Append string to the end of the block, increasing the size of the block and making it read-write. The null terminating character is included - void append(const std::string &s); - - // Expand or shrink the data block, and switch it to read-write mode. Note - this may result in a mmap'ed file being copied to malloc'ed ram and then closed - void expand(size_t size); - - // Unload a file, releasing any mmap'ed file handles or malloc'ed ram that was in use - void unload(); - - // Return a pointer to the start of the data block - void *getStart(); - - // Return a pointer to the one byte after the end of the data block - void *getEnd(); - - // Return the size of the data block. Use append() or expand() to make the data block larger - size_t getSize() const; - - // Get the contents as a string - std::string getString(); - - // Copy the entire data block to the destination pointer - void copy(void *dest); - - // Copy a range of data to the destination pointer - void copy(void *dest, int start, int count); - - // Lock the memory, forcing it to be loaded into a contiguous block of address space - void lock(); - - // Unlock the memory, releasing the address space for use by other allocations - void unlock(); - + KRDataBlock(); + KRDataBlock(void* data, size_t size); + ~KRDataBlock(); + + // Encapsulate a pointer. Note - The pointer will not be free'ed + bool load(void* data, size_t size); + + // Load a file into memory using mmap. The data pointer will be protected as read-only until append() or expand() is called + bool load(const std::string& path); + + // Save the data to a file. + bool save(const std::string& path); + + // Create a KRDataBlock encapsulating a sub-region of this block. The caller is responsible to free the object. + KRDataBlock* getSubBlock(int start, int length); + + // Append data to the end of the block, increasing the size of the block and making it read-write. + void append(void* data, size_t size); + + // Append data to the end of the block, increasing the size of the block and making it read-write. + void append(KRDataBlock& data); + + // Append string to the end of the block, increasing the size of the block and making it read-write. The null terminating character is included + void append(const std::string& s); + + // Expand or shrink the data block, and switch it to read-write mode. Note - this may result in a mmap'ed file being copied to malloc'ed ram and then closed + void expand(size_t size); + + // Unload a file, releasing any mmap'ed file handles or malloc'ed ram that was in use + void unload(); + + // Return a pointer to the start of the data block + void* getStart(); + + // Return a pointer to the one byte after the end of the data block + void* getEnd(); + + // Return the size of the data block. Use append() or expand() to make the data block larger + size_t getSize() const; + + // Get the contents as a string + std::string getString(); + + // Copy the entire data block to the destination pointer + void copy(void* dest); + + // Copy a range of data to the destination pointer + void copy(void* dest, int start, int count); + + // Lock the memory, forcing it to be loaded into a contiguous block of address space + void lock(); + + // Unlock the memory, releasing the address space for use by other allocations + void unlock(); + private: - void *m_data; - size_t m_data_size; - size_t m_data_offset; - - // For memory mapped objects: + void* m_data; + size_t m_data_size; + size_t m_data_offset; + + // For memory mapped objects: #if defined(_WIN32) || defined(_WIN64) - HANDLE m_hPackFile; - HANDLE m_hFileMapping; + HANDLE m_hPackFile; + HANDLE m_hFileMapping; #elif defined(__APPLE__) || defined(ANDROID) - int m_fdPackFile; + int m_fdPackFile; #endif - - std::string m_fileName; - KRDataBlock *m_fileOwnerDataBlock; - void *m_mmapData; - - // For malloc'ed objects: - bool m_bMalloced; - - // Lock refcount - int m_lockCount; - - // Read-only allocation - bool m_bReadOnly; - - // Assert if not locked - void assertLocked(); + + std::string m_fileName; + KRDataBlock* m_fileOwnerDataBlock; + void* m_mmapData; + + // For malloc'ed objects: + bool m_bMalloced; + + // Lock refcount + int m_lockCount; + + // Read-only allocation + bool m_bReadOnly; + + // Assert if not locked + void assertLocked(); }; diff --git a/kraken/KRDevice.cpp b/kraken/KRDevice.cpp index 8061a98..7a5f733 100644 --- a/kraken/KRDevice.cpp +++ b/kraken/KRDevice.cpp @@ -81,7 +81,7 @@ void KRDevice::destroy() vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr); m_graphicsCommandPool = VK_NULL_HANDLE; } - + if (m_computeCommandPool != VK_NULL_HANDLE) { vkDestroyCommandPool(m_logicalDevice, m_computeCommandPool, nullptr); m_computeCommandPool = VK_NULL_HANDLE; @@ -91,7 +91,7 @@ void KRDevice::destroy() vkDestroyCommandPool(m_logicalDevice, m_transferCommandPool, nullptr); m_transferCommandPool = VK_NULL_HANDLE; } - + if (m_logicalDevice != VK_NULL_HANDLE) { vkDestroyDevice(m_logicalDevice, nullptr); m_logicalDevice = VK_NULL_HANDLE; @@ -398,7 +398,7 @@ bool KRDevice::initStagingBuffers() #if KRENGINE_DEBUG_GPU_LABELS , "Streaming Staging Buffer" #endif // KRENGINE_DEBUG_GPU_LABELS - )) { + )) { return false; } @@ -412,7 +412,7 @@ bool KRDevice::initStagingBuffers() #if KRENGINE_DEBUG_GPU_LABELS , "Graphics Staging Buffer" #endif // KRENGINE_DEBUG_GPU_LABELS - )) { + )) { return false; } return true; @@ -422,7 +422,7 @@ bool KRDevice::initStagingBuffer(VkDeviceSize size, StagingBufferInfo* info #if KRENGINE_DEBUG_GPU_LABELS , const char* debug_label #endif // KRENGINE_DEBUG_GPU_LABELS - ) +) { if (!createBuffer( size, @@ -433,7 +433,7 @@ bool KRDevice::initStagingBuffer(VkDeviceSize size, StagingBufferInfo* info #if KRENGINE_DEBUG_GPU_LABELS , debug_label #endif // KRENGINE_DEBUG_GPU_LABELS - )) { + )) { return false; } if (vmaMapMemory(m_allocator, info->allocation, &info->data) != VK_SUCCESS) { @@ -561,7 +561,7 @@ bool KRDevice::createImage(Vector2i dimensions, VkImageCreateFlags imageCreateFl imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; imageInfo.flags = imageCreateFlags; - + uint32_t queueFamilyIndices[2] = {}; imageInfo.pQueueFamilyIndices = queueFamilyIndices; diff --git a/kraken/KRDevice.h b/kraken/KRDevice.h index 8a18dc4..37ba5bf 100644 --- a/kraken/KRDevice.h +++ b/kraken/KRDevice.h @@ -76,7 +76,7 @@ public: void streamStart(); void streamUpload(KRDataBlock& data, VkBuffer destination); - void streamUpload(void *data, size_t size, VkBuffer destination); + void streamUpload(void* data, size_t size, VkBuffer destination); void streamUpload(void* data, size_t size, Vector2i dimensions, VkImage destination); void streamEnd(); @@ -101,7 +101,8 @@ public: std::vector m_transferCommandBuffers; VmaAllocator m_allocator; - struct StagingBufferInfo { + struct StagingBufferInfo + { VkBuffer buffer; VmaAllocation allocation; size_t size; diff --git a/kraken/KRDeviceManager.cpp b/kraken/KRDeviceManager.cpp index 481558f..685aba6 100644 --- a/kraken/KRDeviceManager.cpp +++ b/kraken/KRDeviceManager.cpp @@ -48,7 +48,7 @@ KRDeviceManager::KRDeviceManager(KRContext& context) KRDeviceManager::~KRDeviceManager() { destroyDevices(); - + if (m_vulkanInstance != VK_NULL_HANDLE) { vkDestroyInstance(m_vulkanInstance, NULL); m_vulkanInstance = VK_NULL_HANDLE; @@ -65,7 +65,7 @@ bool KRDeviceManager::haveDevice() const return !m_devices.empty(); } -void +void KRDeviceManager::destroyDevices() { const std::lock_guard lock(KRContext::g_DeviceInfoMutex); @@ -162,23 +162,19 @@ void KRDeviceManager::createDevices() bool addDevice = false; if (candidateDevices.empty()) { addDevice = true; - } - else { + } else { VkPhysicalDeviceType collectedType = candidateDevices[0]->m_deviceProperties.deviceType; if (collectedType == device->m_deviceProperties.deviceType) { addDevice = true; - } - else if (device->m_deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { + } else if (device->m_deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { // Discrete GPU's are always the best choice candidateDevices.clear(); addDevice = true; - } - else if (collectedType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && device->m_deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) { + } else if (collectedType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && device->m_deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) { // Integrated GPU's are the second best choice candidateDevices.clear(); addDevice = true; - } - else if (collectedType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && collectedType != VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU && device->m_deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) { + } else if (collectedType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && collectedType != VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU && device->m_deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) { // Virtual GPU's are the 3rd best choice candidateDevices.clear(); addDevice = true; @@ -204,7 +200,7 @@ void KRDeviceManager::createDevices() snprintf(label, kMaxLabel, "GPU %i", iDevice + 1); } device->setDebugLabel(device->m_logicalDevice, label); - + #endif m_devices[++m_topDeviceHandle] = std::move(device); diff --git a/kraken/KRDirectionalLight.cpp b/kraken/KRDirectionalLight.cpp index bc9048f..0aa7a78 100755 --- a/kraken/KRDirectionalLight.cpp +++ b/kraken/KRDirectionalLight.cpp @@ -43,127 +43,132 @@ void KRDirectionalLight::InitNodeInfo(KrNodeInfo* nodeInfo) // No additional members } -KRDirectionalLight::KRDirectionalLight(KRScene &scene, std::string name) : KRLight(scene, name) +KRDirectionalLight::KRDirectionalLight(KRScene& scene, std::string name) : KRLight(scene, name) { } KRDirectionalLight::~KRDirectionalLight() { - + } -std::string KRDirectionalLight::getElementName() { - return "directional_light"; +std::string KRDirectionalLight::getElementName() +{ + return "directional_light"; } -Vector3 KRDirectionalLight::getWorldLightDirection() { - return Matrix4::Dot(getWorldRotation().rotationMatrix(), getLocalLightDirection()); +Vector3 KRDirectionalLight::getWorldLightDirection() +{ + return Matrix4::Dot(getWorldRotation().rotationMatrix(), getLocalLightDirection()); } -Vector3 KRDirectionalLight::getLocalLightDirection() { - return Vector3::Up(); //&KRF HACK changed from Vector3::Forward(); - to compensate for the way Maya handles post rotation. +Vector3 KRDirectionalLight::getLocalLightDirection() +{ + return Vector3::Up(); //&KRF HACK changed from Vector3::Forward(); - to compensate for the way Maya handles post rotation. } -int KRDirectionalLight::configureShadowBufferViewports(const KRViewport &viewport) { - - const float KRENGINE_SHADOW_BOUNDS_EXTRA_SCALE = 1.25f; // Scale to apply to view frustrum bounds so that we don't need to refresh shadows on every frame - int cShadows = 1; - for(int iShadow=0; iShadow < cShadows; iShadow++) { - /* - TODO - Determine if we still need this... - - GLfloat shadowMinDepths[3][3] = {{0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f},{0.0f, 0.05f, 0.3f}}; - GLfloat shadowMaxDepths[3][3] = {{0.0f, 0.0f, 1.0f},{0.1f, 0.0f, 0.0f},{0.1f, 0.3f, 1.0f}}; - - float min_depth = 0.0f; - float max_depth = 1.0f; - */ - - AABB worldSpacefrustrumSliceBounds = AABB::Create(Vector3::Create(-1.0f, -1.0f, -1.0f), Vector3::Create(1.0f, 1.0f, 1.0f), Matrix4::Invert(viewport.getViewProjectionMatrix())); - worldSpacefrustrumSliceBounds.scale(KRENGINE_SHADOW_BOUNDS_EXTRA_SCALE); - - Vector3 shadowLook = -Vector3::Normalize(getWorldLightDirection()); - - Vector3 shadowUp = Vector3::Create(0.0, 1.0, 0.0); - if(Vector3::Dot(shadowUp, shadowLook) > 0.99f) shadowUp = Vector3::Create(0.0, 0.0, 1.0); // Ensure shadow look direction is not parallel with the shadowUp direction - +int KRDirectionalLight::configureShadowBufferViewports(const KRViewport& viewport) +{ + + const float KRENGINE_SHADOW_BOUNDS_EXTRA_SCALE = 1.25f; // Scale to apply to view frustrum bounds so that we don't need to refresh shadows on every frame + int cShadows = 1; + for (int iShadow = 0; iShadow < cShadows; iShadow++) { + /* + TODO - Determine if we still need this... + + GLfloat shadowMinDepths[3][3] = {{0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f},{0.0f, 0.05f, 0.3f}}; + GLfloat shadowMaxDepths[3][3] = {{0.0f, 0.0f, 1.0f},{0.1f, 0.0f, 0.0f},{0.1f, 0.3f, 1.0f}}; + + float min_depth = 0.0f; + float max_depth = 1.0f; + */ + + AABB worldSpacefrustrumSliceBounds = AABB::Create(Vector3::Create(-1.0f, -1.0f, -1.0f), Vector3::Create(1.0f, 1.0f, 1.0f), Matrix4::Invert(viewport.getViewProjectionMatrix())); + worldSpacefrustrumSliceBounds.scale(KRENGINE_SHADOW_BOUNDS_EXTRA_SCALE); + + Vector3 shadowLook = -Vector3::Normalize(getWorldLightDirection()); + + Vector3 shadowUp = Vector3::Create(0.0, 1.0, 0.0); + if (Vector3::Dot(shadowUp, shadowLook) > 0.99f) shadowUp = Vector3::Create(0.0, 0.0, 1.0); // Ensure shadow look direction is not parallel with the shadowUp direction + // Matrix4 matShadowView = Matrix4::LookAt(viewport.getCameraPosition() - shadowLook, viewport.getCameraPosition(), shadowUp); // Matrix4 matShadowProjection = Matrix4(); // matShadowProjection.scale(0.001, 0.001, 0.001); - - Matrix4 matShadowView = Matrix4::LookAt(worldSpacefrustrumSliceBounds.center() - shadowLook, worldSpacefrustrumSliceBounds.center(), shadowUp); - Matrix4 matShadowProjection = Matrix4(); - AABB shadowSpaceFrustrumSliceBounds = AABB::Create(worldSpacefrustrumSliceBounds.min, worldSpacefrustrumSliceBounds.max, Matrix4::Invert(matShadowProjection)); - AABB shadowSpaceSceneBounds = AABB::Create(getScene().getRootOctreeBounds().min, getScene().getRootOctreeBounds().max, Matrix4::Invert(matShadowProjection)); - if(shadowSpaceSceneBounds.min.z < shadowSpaceFrustrumSliceBounds.min.z) shadowSpaceFrustrumSliceBounds.min.z = shadowSpaceSceneBounds.min.z; // Include any potential shadow casters that are outside the view frustrum - matShadowProjection.scale(1.0f / shadowSpaceFrustrumSliceBounds.size().x, 1.0f / shadowSpaceFrustrumSliceBounds.size().y, 1.0f / shadowSpaceFrustrumSliceBounds.size().z); - - Matrix4 matBias; - matBias.bias(); - matShadowProjection *= matBias; - - KRViewport newShadowViewport = KRViewport(Vector2::Create(KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT), matShadowView, matShadowProjection); - AABB prevShadowBounds = AABB::Create(-Vector3::One(), Vector3::One(), Matrix4::Invert(m_shadowViewports[iShadow].getViewProjectionMatrix())); - AABB minimumShadowBounds = AABB::Create(-Vector3::One(), Vector3::One(), Matrix4::Invert(newShadowViewport.getViewProjectionMatrix())); - minimumShadowBounds.scale(1.0f / KRENGINE_SHADOW_BOUNDS_EXTRA_SCALE); - if(!prevShadowBounds.contains(minimumShadowBounds) || !shadowValid[iShadow] || true) { // FINDME, HACK - Re-generating the shadow map every frame. This should only be needed if the shadow contains non-static geometry - m_shadowViewports[iShadow] = newShadowViewport; - shadowValid[iShadow] = false; - fprintf(stderr, "Kraken - Generate shadow maps...\n"); - } - } - return 1; + Matrix4 matShadowView = Matrix4::LookAt(worldSpacefrustrumSliceBounds.center() - shadowLook, worldSpacefrustrumSliceBounds.center(), shadowUp); + Matrix4 matShadowProjection = Matrix4(); + AABB shadowSpaceFrustrumSliceBounds = AABB::Create(worldSpacefrustrumSliceBounds.min, worldSpacefrustrumSliceBounds.max, Matrix4::Invert(matShadowProjection)); + AABB shadowSpaceSceneBounds = AABB::Create(getScene().getRootOctreeBounds().min, getScene().getRootOctreeBounds().max, Matrix4::Invert(matShadowProjection)); + if (shadowSpaceSceneBounds.min.z < shadowSpaceFrustrumSliceBounds.min.z) shadowSpaceFrustrumSliceBounds.min.z = shadowSpaceSceneBounds.min.z; // Include any potential shadow casters that are outside the view frustrum + matShadowProjection.scale(1.0f / shadowSpaceFrustrumSliceBounds.size().x, 1.0f / shadowSpaceFrustrumSliceBounds.size().y, 1.0f / shadowSpaceFrustrumSliceBounds.size().z); + + Matrix4 matBias; + matBias.bias(); + matShadowProjection *= matBias; + + KRViewport newShadowViewport = KRViewport(Vector2::Create(KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT), matShadowView, matShadowProjection); + AABB prevShadowBounds = AABB::Create(-Vector3::One(), Vector3::One(), Matrix4::Invert(m_shadowViewports[iShadow].getViewProjectionMatrix())); + AABB minimumShadowBounds = AABB::Create(-Vector3::One(), Vector3::One(), Matrix4::Invert(newShadowViewport.getViewProjectionMatrix())); + minimumShadowBounds.scale(1.0f / KRENGINE_SHADOW_BOUNDS_EXTRA_SCALE); + if (!prevShadowBounds.contains(minimumShadowBounds) || !shadowValid[iShadow] || true) { // FINDME, HACK - Re-generating the shadow map every frame. This should only be needed if the shadow contains non-static geometry + m_shadowViewports[iShadow] = newShadowViewport; + shadowValid[iShadow] = false; + fprintf(stderr, "Kraken - Generate shadow maps...\n"); + } + } + + return 1; } -void KRDirectionalLight::render(RenderInfo& ri) { - - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRLight::render(ri); +void KRDirectionalLight::render(RenderInfo& ri) +{ - if(ri.renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) { - // Lights are rendered on the second pass of the deferred renderer - - std::vector this_light; - this_light.push_back(this); + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - Matrix4 matModelViewInverseTranspose = ri.viewport.getViewMatrix() * getModelMatrix(); - matModelViewInverseTranspose.transpose(); - matModelViewInverseTranspose.invert(); - - Vector3 light_direction_view_space = getWorldLightDirection(); - light_direction_view_space = Matrix4::Dot(matModelViewInverseTranspose, light_direction_view_space); - light_direction_view_space.normalize(); + KRLight::render(ri); - KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES; - - PipelineInfo info{}; - std::string shader_name("light_directional"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.directional_lights = &this_light; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAdditiveNoTest; + if (ri.renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) { + // Lights are rendered on the second pass of the deferred renderer - info.vertexAttributes = vertices.getVertexAttributes(); - info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; + std::vector this_light; + this_light.push_back(this); - KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->setUniform(KRPipeline::Uniform::light_direction_view_space, light_direction_view_space); - pShader->setUniform(KRPipeline::Uniform::light_color, m_color); - pShader->setUniform(KRPipeline::Uniform::light_intensity, m_intensity * 0.01f); - pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), nullptr, &this_light, nullptr, ri.renderPass); - - // Render a full screen quad - m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &vertices, 1.0f); - vkCmdDraw(ri.commandBuffer, 4, 1, 0, 0); - } + Matrix4 matModelViewInverseTranspose = ri.viewport.getViewMatrix() * getModelMatrix(); + matModelViewInverseTranspose.transpose(); + matModelViewInverseTranspose.invert(); + + Vector3 light_direction_view_space = getWorldLightDirection(); + light_direction_view_space = Matrix4::Dot(matModelViewInverseTranspose, light_direction_view_space); + light_direction_view_space.normalize(); + + KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES; + + PipelineInfo info{}; + std::string shader_name("light_directional"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.directional_lights = &this_light; + info.renderPass = ri.renderPass; + info.rasterMode = RasterMode::kAdditiveNoTest; + + info.vertexAttributes = vertices.getVertexAttributes(); + info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; + + KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + pShader->setUniform(KRPipeline::Uniform::light_direction_view_space, light_direction_view_space); + pShader->setUniform(KRPipeline::Uniform::light_color, m_color); + pShader->setUniform(KRPipeline::Uniform::light_intensity, m_intensity * 0.01f); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), nullptr, &this_light, nullptr, ri.renderPass); + + // Render a full screen quad + m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &vertices, 1.0f); + vkCmdDraw(ri.commandBuffer, 4, 1, 0, 0); + } } AABB KRDirectionalLight::getBounds() { - return AABB::Infinite(); + return AABB::Infinite(); } diff --git a/kraken/KRDirectionalLight.h b/kraken/KRDirectionalLight.h index e186ec8..4d4a3a4 100755 --- a/kraken/KRDirectionalLight.h +++ b/kraken/KRDirectionalLight.h @@ -33,24 +33,25 @@ #include "KRLight.h" -class KRDirectionalLight : public KRLight { - -public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); - - KRDirectionalLight(KRScene &scene, std::string name); - virtual ~KRDirectionalLight(); - - virtual std::string getElementName(); - Vector3 getLocalLightDirection(); - Vector3 getWorldLightDirection(); +class KRDirectionalLight : public KRLight +{ + +public: + static void InitNodeInfo(KrNodeInfo* nodeInfo); + + KRDirectionalLight(KRScene& scene, std::string name); + virtual ~KRDirectionalLight(); + + virtual std::string getElementName(); + Vector3 getLocalLightDirection(); + Vector3 getWorldLightDirection(); + + virtual void render(RenderInfo& ri); + virtual AABB getBounds(); - virtual void render(RenderInfo& ri); - virtual AABB getBounds(); - protected: - - virtual int configureShadowBufferViewports(const KRViewport &viewport); - + + virtual int configureShadowBufferViewports(const KRViewport& viewport); + }; diff --git a/kraken/KREngine-common.h b/kraken/KREngine-common.h index 6c7efc0..a736191 100755 --- a/kraken/KREngine-common.h +++ b/kraken/KREngine-common.h @@ -253,10 +253,11 @@ fprintf(stderr, "Error at line number %d, in file %s. Returned %d for call %s\n" #endif -typedef enum { - STREAM_LEVEL_OUT, - STREAM_LEVEL_IN_LQ, - STREAM_LEVEL_IN_HQ +typedef enum +{ + STREAM_LEVEL_OUT, + STREAM_LEVEL_IN_LQ, + STREAM_LEVEL_IN_HQ } kraken_stream_level; typedef int KrDeviceHandle; diff --git a/kraken/KREngine.h b/kraken/KREngine.h index 4290e33..c9c205e 100755 --- a/kraken/KREngine.h +++ b/kraken/KREngine.h @@ -37,43 +37,46 @@ #include "KREngine-common.h" -typedef enum KREngineParameterType {KRENGINE_PARAMETER_INT, KRENGINE_PARAMETER_FLOAT, KRENGINE_PARAMETER_BOOL} KREngineParameterType; +typedef enum KREngineParameterType +{ + KRENGINE_PARAMETER_INT, KRENGINE_PARAMETER_FLOAT, KRENGINE_PARAMETER_BOOL +} KREngineParameterType; namespace kraken { - void set_parameter(const std::string ¶meter_name, float parameter_value); - void set_debug_text(const std::string &print_text); +void set_parameter(const std::string& parameter_name, float parameter_value); +void set_debug_text(const std::string& print_text); }; #ifdef __OBJC__ @interface KREngine : NSObject -+ (KREngine *)sharedInstance; ++ (KREngine*)sharedInstance; -@property(nonatomic, readonly) NSDictionary *parameter_names; -@property(nonatomic, assign) KRContext *context; -@property(nonatomic, retain) NSString *debug_text; -@property(nonatomic, assign, readonly) KRRenderSettings *settings; +@property(nonatomic, readonly) NSDictionary* parameter_names; +@property(nonatomic, assign) KRContext* context; +@property(nonatomic, retain) NSString* debug_text; +@property(nonatomic, assign, readonly) KRRenderSettings* settings; -- (id)init; -- (BOOL)loadResource:(NSString *)path; +-(id)init; +-(BOOL)loadResource:(NSString*)path; // Parameter enumeration interface -(int)getParameterCount; --(NSString *)getParameterNameWithIndex: (int)i; --(NSString *)getParameterLabelWithIndex: (int)i; +-(NSString*)getParameterNameWithIndex: (int)i; +-(NSString*)getParameterLabelWithIndex: (int)i; -(KREngineParameterType)getParameterTypeWithIndex: (int)i; -(float)getParameterMinWithIndex: (int)i; -(float)getParameterMaxWithIndex: (int)i; -(float)getParameterValueWithIndex: (int)i; --(void)setParameterValueWithIndex: (int)i Value: (float)v; --(void)setParameterValueWithName: (NSString *)name Value: (float)v; --(int)getParameterIndexWithName: (NSString *)name; +-(void)setParameterValueWithIndex: (int)i Value : (float)v; +-(void)setParameterValueWithName: (NSString*)name Value : (float)v; +-(int)getParameterIndexWithName: (NSString*)name; -- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime AndWidth: (int)width AndHeight: (int)height AndDefaultFBO: (GLint)defaultFBO; +-(void)renderScene: (KRScene*)pScene WithDeltaTime : (float)deltaTime AndWidth : (int)width AndHeight : (int)height AndDefaultFBO : (GLint)defaultFBO; //- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime; -- (void)setNearZ: (float)dNearZ; -- (void)setFarZ: (float)dFarZ; +-(void)setNearZ: (float)dNearZ; +-(void)setFarZ: (float)dFarZ; @end diff --git a/kraken/KRHelpers.cpp b/kraken/KRHelpers.cpp index caa6841..9979797 100644 --- a/kraken/KRHelpers.cpp +++ b/kraken/KRHelpers.cpp @@ -35,7 +35,7 @@ namespace kraken { -void setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const Vector3 &value, const Vector3 &default_value) +void setXMLAttribute(const std::string& base_name, tinyxml2::XMLElement* e, const Vector3& value, const Vector3& default_value) { // TODO - Increase number of digits after the decimal in floating point format (6 -> 12?) // FINDME, TODO - This needs optimization... @@ -46,7 +46,7 @@ void setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, cons } } -const Vector3 getXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const Vector3 &default_value) +const Vector3 getXMLAttribute(const std::string& base_name, tinyxml2::XMLElement* e, const Vector3& default_value) { Vector3 value; if (e->QueryFloatAttribute((base_name + "_x").c_str(), &value.x) == tinyxml2::XML_SUCCESS diff --git a/kraken/KRHelpers.h b/kraken/KRHelpers.h index aeac46f..04e8769 100644 --- a/kraken/KRHelpers.h +++ b/kraken/KRHelpers.h @@ -60,7 +60,7 @@ float const PI = 3.141592653589793f; float const D2R = PI * 2 / 360; namespace kraken { - void setXMLAttribute(const std::string &base_name, ::tinyxml2::XMLElement *e, const Vector3 &value, const Vector3 &default_value); - const Vector3 getXMLAttribute(const std::string &base_name, ::tinyxml2::XMLElement *e, const Vector3 &default_value); +void setXMLAttribute(const std::string& base_name, ::tinyxml2::XMLElement* e, const Vector3& value, const Vector3& default_value); +const Vector3 getXMLAttribute(const std::string& base_name, ::tinyxml2::XMLElement* e, const Vector3& default_value); } // namespace kraken diff --git a/kraken/KRLODGroup.cpp b/kraken/KRLODGroup.cpp index 629e4e1..98eba9f 100755 --- a/kraken/KRLODGroup.cpp +++ b/kraken/KRLODGroup.cpp @@ -44,164 +44,164 @@ void KRLODGroup::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->lod_group.use_world_units = true; } -KRLODGroup::KRLODGroup(KRScene &scene, std::string name) : KRNode(scene, name) +KRLODGroup::KRLODGroup(KRScene& scene, std::string name) : KRNode(scene, name) { - m_min_distance = 0.0f; - m_max_distance = 0.0f; - m_reference = AABB::Create(Vector3::Zero(), Vector3::Zero()); - m_use_world_units = true; + m_min_distance = 0.0f; + m_max_distance = 0.0f; + m_reference = AABB::Create(Vector3::Zero(), Vector3::Zero()); + m_use_world_units = true; } KRLODGroup::~KRLODGroup() +{} + +std::string KRLODGroup::getElementName() { + return "lod_group"; } -std::string KRLODGroup::getElementName() { - return "lod_group"; +tinyxml2::XMLElement* KRLODGroup::saveXML(tinyxml2::XMLNode* parent) +{ + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + e->SetAttribute("min_distance", m_min_distance); + e->SetAttribute("max_distance", m_max_distance); + + e->SetAttribute("reference_min_x", m_reference.min.x); + e->SetAttribute("reference_min_y", m_reference.min.y); + e->SetAttribute("reference_min_z", m_reference.min.z); + + + e->SetAttribute("reference_max_x", m_reference.max.x); + e->SetAttribute("reference_max_y", m_reference.max.y); + e->SetAttribute("reference_max_z", m_reference.max.z); + + e->SetAttribute("use_world_units", m_use_world_units ? "true" : "false"); + return e; } -tinyxml2::XMLElement *KRLODGroup::saveXML( tinyxml2::XMLNode *parent) +void KRLODGroup::loadXML(tinyxml2::XMLElement* e) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - e->SetAttribute("min_distance", m_min_distance); - e->SetAttribute("max_distance", m_max_distance); - - e->SetAttribute("reference_min_x", m_reference.min.x); - e->SetAttribute("reference_min_y", m_reference.min.y); - e->SetAttribute("reference_min_z", m_reference.min.z); - - - e->SetAttribute("reference_max_x", m_reference.max.x); - e->SetAttribute("reference_max_y", m_reference.max.y); - e->SetAttribute("reference_max_z", m_reference.max.z); - - e->SetAttribute("use_world_units", m_use_world_units ? "true" : "false"); - return e; -} - -void KRLODGroup::loadXML(tinyxml2::XMLElement *e) -{ - KRNode::loadXML(e); + KRNode::loadXML(e); + m_min_distance = 0.0f; + if (e->QueryFloatAttribute("min_distance", &m_min_distance) != tinyxml2::XML_SUCCESS) { m_min_distance = 0.0f; - if(e->QueryFloatAttribute("min_distance", &m_min_distance) != tinyxml2::XML_SUCCESS) { - m_min_distance = 0.0f; - } - + } + + m_max_distance = 0.0f; + if (e->QueryFloatAttribute("max_distance", &m_max_distance) != tinyxml2::XML_SUCCESS) { m_max_distance = 0.0f; - if(e->QueryFloatAttribute("max_distance", &m_max_distance) != tinyxml2::XML_SUCCESS) { - m_max_distance = 0.0f; - } - - - float x=0.0f, y=0.0f, z=0.0f; - if(e->QueryFloatAttribute("reference_min_x", &x) != tinyxml2::XML_SUCCESS) { - x = 0.0f; - } - if(e->QueryFloatAttribute("reference_min_y", &y) != tinyxml2::XML_SUCCESS) { - y = 0.0f; - } - if(e->QueryFloatAttribute("reference_min_z", &z) != tinyxml2::XML_SUCCESS) { - z = 0.0f; - } - - m_reference.min = Vector3::Create(x,y,z); - - x=0.0f; y=0.0f; z=0.0f; - if(e->QueryFloatAttribute("reference_max_x", &x) != tinyxml2::XML_SUCCESS) { - x = 0.0f; - } - if(e->QueryFloatAttribute("reference_max_y", &y) != tinyxml2::XML_SUCCESS) { - y = 0.0f; - } - if(e->QueryFloatAttribute("reference_max_z", &z) != tinyxml2::XML_SUCCESS) { - z = 0.0f; - } - m_reference.max = Vector3::Create(x,y,z); - + } + + + float x = 0.0f, y = 0.0f, z = 0.0f; + if (e->QueryFloatAttribute("reference_min_x", &x) != tinyxml2::XML_SUCCESS) { + x = 0.0f; + } + if (e->QueryFloatAttribute("reference_min_y", &y) != tinyxml2::XML_SUCCESS) { + y = 0.0f; + } + if (e->QueryFloatAttribute("reference_min_z", &z) != tinyxml2::XML_SUCCESS) { + z = 0.0f; + } + + m_reference.min = Vector3::Create(x, y, z); + + x = 0.0f; y = 0.0f; z = 0.0f; + if (e->QueryFloatAttribute("reference_max_x", &x) != tinyxml2::XML_SUCCESS) { + x = 0.0f; + } + if (e->QueryFloatAttribute("reference_max_y", &y) != tinyxml2::XML_SUCCESS) { + y = 0.0f; + } + if (e->QueryFloatAttribute("reference_max_z", &z) != tinyxml2::XML_SUCCESS) { + z = 0.0f; + } + m_reference.max = Vector3::Create(x, y, z); + + m_use_world_units = true; + if (e->QueryBoolAttribute("use_world_units", &m_use_world_units) != tinyxml2::XML_SUCCESS) { m_use_world_units = true; - if(e->QueryBoolAttribute("use_world_units", &m_use_world_units) != tinyxml2::XML_SUCCESS) { - m_use_world_units = true; - } + } } -const AABB &KRLODGroup::getReference() const +const AABB& KRLODGroup::getReference() const { - return m_reference; + return m_reference; } -void KRLODGroup::setReference(const AABB &reference) +void KRLODGroup::setReference(const AABB& reference) { - m_reference = reference; + m_reference = reference; } -KRNode::LodVisibility KRLODGroup::calcLODVisibility(const KRViewport &viewport) +KRNode::LodVisibility KRLODGroup::calcLODVisibility(const KRViewport& viewport) { - if(m_min_distance == 0 && m_max_distance == 0) { - return LOD_VISIBILITY_VISIBLE; + if (m_min_distance == 0 && m_max_distance == 0) { + return LOD_VISIBILITY_VISIBLE; + } else { + float lod_bias = viewport.getLODBias(); + lod_bias = pow(2.0f, -lod_bias); + + // Compare using squared distances as sqrt is expensive + float sqr_distance; + float sqr_prestream_distance; + + Vector3 world_camera_position = viewport.getCameraPosition(); + Vector3 local_camera_position = worldToLocal(world_camera_position); + Vector3 local_reference_point = m_reference.nearestPoint(local_camera_position); + + if (m_use_world_units) { + Vector3 world_reference_point = localToWorld(local_reference_point); + sqr_distance = (world_camera_position - world_reference_point).sqrMagnitude() * (lod_bias * lod_bias); + sqr_prestream_distance = (float)(getContext().KRENGINE_PRESTREAM_DISTANCE * getContext().KRENGINE_PRESTREAM_DISTANCE); } else { - float lod_bias = viewport.getLODBias(); - lod_bias = pow(2.0f, -lod_bias); - - // Compare using squared distances as sqrt is expensive - float sqr_distance; - float sqr_prestream_distance; - - Vector3 world_camera_position = viewport.getCameraPosition(); - Vector3 local_camera_position = worldToLocal(world_camera_position); - Vector3 local_reference_point = m_reference.nearestPoint(local_camera_position); - - if(m_use_world_units) { - Vector3 world_reference_point = localToWorld(local_reference_point); - sqr_distance = (world_camera_position - world_reference_point).sqrMagnitude() * (lod_bias * lod_bias); - sqr_prestream_distance = (float)(getContext().KRENGINE_PRESTREAM_DISTANCE * getContext().KRENGINE_PRESTREAM_DISTANCE); - } else { - sqr_distance = (local_camera_position - local_reference_point).sqrMagnitude() * (lod_bias * lod_bias); - - Vector3 world_reference_point = localToWorld(local_reference_point); - sqr_prestream_distance = worldToLocal(Vector3::Normalize(world_reference_point - world_camera_position) * (float)getContext().KRENGINE_PRESTREAM_DISTANCE).sqrMagnitude(); // TODO, FINDME - Optimize with precalc? - - } - - float sqr_min_visible_distance = m_min_distance * m_min_distance; - float sqr_max_visible_distance = m_max_distance * m_max_distance; - if((sqr_distance >= sqr_min_visible_distance || m_min_distance == 0) && (sqr_distance < sqr_max_visible_distance || m_max_distance == 0)) { - return LOD_VISIBILITY_VISIBLE; - } else if((sqr_distance >= sqr_min_visible_distance - sqr_prestream_distance || m_min_distance == 0) && (sqr_distance < sqr_max_visible_distance + sqr_prestream_distance || m_max_distance == 0)) { - return LOD_VISIBILITY_PRESTREAM; - } else { - return LOD_VISIBILITY_HIDDEN; - } + sqr_distance = (local_camera_position - local_reference_point).sqrMagnitude() * (lod_bias * lod_bias); + + Vector3 world_reference_point = localToWorld(local_reference_point); + sqr_prestream_distance = worldToLocal(Vector3::Normalize(world_reference_point - world_camera_position) * (float)getContext().KRENGINE_PRESTREAM_DISTANCE).sqrMagnitude(); // TODO, FINDME - Optimize with precalc? + } + + float sqr_min_visible_distance = m_min_distance * m_min_distance; + float sqr_max_visible_distance = m_max_distance * m_max_distance; + if ((sqr_distance >= sqr_min_visible_distance || m_min_distance == 0) && (sqr_distance < sqr_max_visible_distance || m_max_distance == 0)) { + return LOD_VISIBILITY_VISIBLE; + } else if ((sqr_distance >= sqr_min_visible_distance - sqr_prestream_distance || m_min_distance == 0) && (sqr_distance < sqr_max_visible_distance + sqr_prestream_distance || m_max_distance == 0)) { + return LOD_VISIBILITY_PRESTREAM; + } else { + return LOD_VISIBILITY_HIDDEN; + } + } } float KRLODGroup::getMinDistance() { - return m_min_distance; + return m_min_distance; } float KRLODGroup::getMaxDistance() { - return m_max_distance; + return m_max_distance; } void KRLODGroup::setMinDistance(float min_distance) { - m_min_distance = min_distance; + m_min_distance = min_distance; } void KRLODGroup::setMaxDistance(float max_distance) { - m_max_distance = max_distance; + m_max_distance = max_distance; } void KRLODGroup::setUseWorldUnits(bool use_world_units) { - m_use_world_units = use_world_units; + m_use_world_units = use_world_units; } bool KRLODGroup::getUseWorldUnits() const { - return m_use_world_units; + return m_use_world_units; } diff --git a/kraken/KRLODGroup.h b/kraken/KRLODGroup.h index be3254f..f155f58 100755 --- a/kraken/KRLODGroup.h +++ b/kraken/KRLODGroup.h @@ -34,30 +34,31 @@ #include "KRResource.h" #include "KRNode.h" -class KRLODGroup : public KRNode { +class KRLODGroup : public KRNode +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); - KRLODGroup(KRScene &scene, std::string name); - virtual ~KRLODGroup(); - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - - float getMinDistance(); - float getMaxDistance(); - void setMinDistance(float min_distance); - void setMaxDistance(float max_distance); - - const AABB &getReference() const; - void setReference(const AABB &reference); - void setUseWorldUnits(bool use_world_units); - bool getUseWorldUnits() const; - - LodVisibility calcLODVisibility(const KRViewport &viewport); - + static void InitNodeInfo(KrNodeInfo* nodeInfo); + KRLODGroup(KRScene& scene, std::string name); + virtual ~KRLODGroup(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + + float getMinDistance(); + float getMaxDistance(); + void setMinDistance(float min_distance); + void setMaxDistance(float max_distance); + + const AABB& getReference() const; + void setReference(const AABB& reference); + void setUseWorldUnits(bool use_world_units); + bool getUseWorldUnits() const; + + LodVisibility calcLODVisibility(const KRViewport& viewport); + private: - float m_min_distance; - float m_max_distance; - AABB m_reference; // Point of reference, used for distance calculation. Usually set to the bounding box center - bool m_use_world_units; + float m_min_distance; + float m_max_distance; + AABB m_reference; // Point of reference, used for distance calculation. Usually set to the bounding box center + bool m_use_world_units; }; diff --git a/kraken/KRLODSet.cpp b/kraken/KRLODSet.cpp index d0ca674..4835875 100755 --- a/kraken/KRLODSet.cpp +++ b/kraken/KRLODSet.cpp @@ -40,109 +40,109 @@ void KRLODSet::InitNodeInfo(KrNodeInfo* nodeInfo) // No additional members } -KRLODSet::KRLODSet(KRScene &scene, std::string name) : KRNode(scene, name) +KRLODSet::KRLODSet(KRScene& scene, std::string name) : KRNode(scene, name) { } KRLODSet::~KRLODSet() +{} + +std::string KRLODSet::getElementName() { + return "lod_set"; } -std::string KRLODSet::getElementName() { - return "lod_set"; +tinyxml2::XMLElement* KRLODSet::saveXML(tinyxml2::XMLNode* parent) +{ + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + + return e; } -tinyxml2::XMLElement *KRLODSet::saveXML( tinyxml2::XMLNode *parent) +void KRLODSet::loadXML(tinyxml2::XMLElement* e) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - - return e; -} - -void KRLODSet::loadXML(tinyxml2::XMLElement *e) -{ - KRNode::loadXML(e); + KRNode::loadXML(e); } -void KRLODSet::updateLODVisibility(const KRViewport &viewport) +void KRLODSet::updateLODVisibility(const KRViewport& viewport) { - if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM) { - /* - // FINDME, TODO, HACK - Disabled streamer delayed LOD load due to performance issues: - KRLODGroup *new_active_lod_group = NULL; - */ - - // Upgrade and downgrade LOD groups as needed - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - KRLODGroup *lod_group = dynamic_cast(*itr); - assert(lod_group != NULL); - LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible); - /* - // FINDME, TODO, HACK - Disabled streamer delayed LOD load due to performance issues: - if(group_lod_visibility == LOD_VISIBILITY_VISIBLE) { - new_active_lod_group = lod_group; - } - */ - lod_group->setLODVisibility(group_lod_visibility); - } - - /* - // FINDME, TODO, HACK - Disabled streamer delayed LOD load due to performance issues: - bool streamer_ready = false; - if(new_active_lod_group == NULL) { - streamer_ready = true; - } else if(new_active_lod_group->getStreamLevel(viewport) >= kraken_stream_level::STREAM_LEVEL_IN_LQ) { - streamer_ready = true; - } - */ - bool streamer_ready = true; - - if(streamer_ready) { - // Upgrade and downgrade LOD groups as needed - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - KRLODGroup *lod_group = dynamic_cast(*itr); - assert(lod_group != NULL); - LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible); - lod_group->setLODVisibility(group_lod_visibility); - } - } - - KRNode::updateLODVisibility(viewport); + if (m_lod_visible >= LOD_VISIBILITY_PRESTREAM) { + /* + // FINDME, TODO, HACK - Disabled streamer delayed LOD load due to performance issues: + KRLODGroup *new_active_lod_group = NULL; + */ + + // Upgrade and downgrade LOD groups as needed + for (std::set::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRLODGroup* lod_group = dynamic_cast(*itr); + assert(lod_group != NULL); + LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible); + /* + // FINDME, TODO, HACK - Disabled streamer delayed LOD load due to performance issues: + if(group_lod_visibility == LOD_VISIBILITY_VISIBLE) { + new_active_lod_group = lod_group; + } + */ + lod_group->setLODVisibility(group_lod_visibility); } + + /* + // FINDME, TODO, HACK - Disabled streamer delayed LOD load due to performance issues: + bool streamer_ready = false; + if(new_active_lod_group == NULL) { + streamer_ready = true; + } else if(new_active_lod_group->getStreamLevel(viewport) >= kraken_stream_level::STREAM_LEVEL_IN_LQ) { + streamer_ready = true; + } + */ + bool streamer_ready = true; + + if (streamer_ready) { + // Upgrade and downgrade LOD groups as needed + for (std::set::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRLODGroup* lod_group = dynamic_cast(*itr); + assert(lod_group != NULL); + LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible); + lod_group->setLODVisibility(group_lod_visibility); + } + } + + KRNode::updateLODVisibility(viewport); + } } void KRLODSet::setLODVisibility(KRNode::LodVisibility lod_visibility) { - if(lod_visibility == LOD_VISIBILITY_HIDDEN) { - KRNode::setLODVisibility(lod_visibility); - } else if(m_lod_visible != lod_visibility) { - // Don't automatically recurse into our children, as only one of those will be activated, by updateLODVisibility - if(m_lod_visible == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) { - getScene().notify_sceneGraphCreate(this); - } - m_lod_visible = lod_visibility; + if (lod_visibility == LOD_VISIBILITY_HIDDEN) { + KRNode::setLODVisibility(lod_visibility); + } else if (m_lod_visible != lod_visibility) { + // Don't automatically recurse into our children, as only one of those will be activated, by updateLODVisibility + if (m_lod_visible == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) { + getScene().notify_sceneGraphCreate(this); } + m_lod_visible = lod_visibility; + } } -kraken_stream_level KRLODSet::getStreamLevel(const KRViewport &viewport) +kraken_stream_level KRLODSet::getStreamLevel(const KRViewport& viewport) { - KRLODGroup *new_active_lod_group = NULL; + KRLODGroup* new_active_lod_group = NULL; - // Upgrade and downgrade LOD groups as needed - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - KRLODGroup *lod_group = dynamic_cast(*itr); - assert(lod_group != NULL); - if(lod_group->calcLODVisibility(viewport) == LOD_VISIBILITY_VISIBLE) { - new_active_lod_group = lod_group; - } - } - - if(new_active_lod_group) { - return new_active_lod_group->getStreamLevel(viewport); - } else { - return kraken_stream_level::STREAM_LEVEL_IN_HQ; + // Upgrade and downgrade LOD groups as needed + for (std::set::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRLODGroup* lod_group = dynamic_cast(*itr); + assert(lod_group != NULL); + if (lod_group->calcLODVisibility(viewport) == LOD_VISIBILITY_VISIBLE) { + new_active_lod_group = lod_group; } + } + + if (new_active_lod_group) { + return new_active_lod_group->getStreamLevel(viewport); + } else { + return kraken_stream_level::STREAM_LEVEL_IN_HQ; + } } diff --git a/kraken/KRLODSet.h b/kraken/KRLODSet.h index 718cac7..c885ed7 100755 --- a/kraken/KRLODSet.h +++ b/kraken/KRLODSet.h @@ -36,18 +36,19 @@ class KRLODGroup; -class KRLODSet : public KRNode { +class KRLODSet : public KRNode +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); - KRLODSet(KRScene &scene, std::string name); - virtual ~KRLODSet(); - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - - virtual void updateLODVisibility(const KRViewport &viewport); - - virtual void setLODVisibility(LodVisibility lod_visibility); - - virtual kraken_stream_level getStreamLevel(const KRViewport &viewport); + static void InitNodeInfo(KrNodeInfo* nodeInfo); + KRLODSet(KRScene& scene, std::string name); + virtual ~KRLODSet(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + + virtual void updateLODVisibility(const KRViewport& viewport); + + virtual void setLODVisibility(LodVisibility lod_visibility); + + virtual kraken_stream_level getStreamLevel(const KRViewport& viewport); }; diff --git a/kraken/KRLight.cpp b/kraken/KRLight.cpp index 1339b1a..9782514 100755 --- a/kraken/KRLight.cpp +++ b/kraken/KRLight.cpp @@ -60,497 +60,509 @@ void KRLight::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->light.light_shafts = true; } -KRLight::KRLight(KRScene &scene, std::string name) : KRNode(scene, name) +KRLight::KRLight(KRScene& scene, std::string name) : KRNode(scene, name) { - m_intensity = 1.0f; - m_dust_particle_intensity = 1.0f; - m_color = Vector3::One(); - m_flareTexture = ""; - m_pFlareTexture = NULL; - m_flareSize = 0.0f; - m_flareOcclusionSize = 0.05f; - m_casts_shadow = true; - m_light_shafts = true; - m_dust_particle_density = 0.1f; - m_dust_particle_size = 1.0f; - m_dust_particle_intensity = 1.0f; - m_occlusionQuery = 0; - m_decayStart = 0; - - // Initialize shadow buffers - m_cShadowBuffers = 0; - for(int iBuffer=0; iBuffer < KRENGINE_MAX_SHADOW_BUFFERS; iBuffer++) { - shadowFramebuffer[iBuffer] = 0; - shadowDepthTexture[iBuffer] = 0; - shadowValid[iBuffer] = false; - } + m_intensity = 1.0f; + m_dust_particle_intensity = 1.0f; + m_color = Vector3::One(); + m_flareTexture = ""; + m_pFlareTexture = NULL; + m_flareSize = 0.0f; + m_flareOcclusionSize = 0.05f; + m_casts_shadow = true; + m_light_shafts = true; + m_dust_particle_density = 0.1f; + m_dust_particle_size = 1.0f; + m_dust_particle_intensity = 1.0f; + m_occlusionQuery = 0; + m_decayStart = 0; + + // Initialize shadow buffers + m_cShadowBuffers = 0; + for (int iBuffer = 0; iBuffer < KRENGINE_MAX_SHADOW_BUFFERS; iBuffer++) { + shadowFramebuffer[iBuffer] = 0; + shadowDepthTexture[iBuffer] = 0; + shadowValid[iBuffer] = false; + } } KRLight::~KRLight() { - if(m_occlusionQuery) { - GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery)); - m_occlusionQuery = 0; - } - allocateShadowBuffers(0); + if (m_occlusionQuery) { + GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery)); + m_occlusionQuery = 0; + } + allocateShadowBuffers(0); } -tinyxml2::XMLElement *KRLight::saveXML( tinyxml2::XMLNode *parent) +tinyxml2::XMLElement* KRLight::saveXML(tinyxml2::XMLNode* parent) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - e->SetAttribute("intensity", m_intensity); - e->SetAttribute("color_r", m_color.x); - e->SetAttribute("color_g", m_color.y); - e->SetAttribute("color_b", m_color.z); - e->SetAttribute("decay_start", m_decayStart); - e->SetAttribute("flare_size", m_flareSize); - e->SetAttribute("flare_occlusion_size", m_flareOcclusionSize); - e->SetAttribute("flare_texture", m_flareTexture.c_str()); - e->SetAttribute("casts_shadow", m_casts_shadow ? "true" : "false"); - e->SetAttribute("light_shafts", m_light_shafts ? "true" : "false"); - e->SetAttribute("dust_particle_density", m_dust_particle_density); - e->SetAttribute("dust_particle_size", m_dust_particle_size); - e->SetAttribute("dust_particle_intensity", m_dust_particle_intensity); - return e; + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + e->SetAttribute("intensity", m_intensity); + e->SetAttribute("color_r", m_color.x); + e->SetAttribute("color_g", m_color.y); + e->SetAttribute("color_b", m_color.z); + e->SetAttribute("decay_start", m_decayStart); + e->SetAttribute("flare_size", m_flareSize); + e->SetAttribute("flare_occlusion_size", m_flareOcclusionSize); + e->SetAttribute("flare_texture", m_flareTexture.c_str()); + e->SetAttribute("casts_shadow", m_casts_shadow ? "true" : "false"); + e->SetAttribute("light_shafts", m_light_shafts ? "true" : "false"); + e->SetAttribute("dust_particle_density", m_dust_particle_density); + e->SetAttribute("dust_particle_size", m_dust_particle_size); + e->SetAttribute("dust_particle_intensity", m_dust_particle_intensity); + return e; } -void KRLight::loadXML(tinyxml2::XMLElement *e) { - KRNode::loadXML(e); - float x=1.0f,y=1.0f,z=1.0f; - if(e->QueryFloatAttribute("color_r", &x) != tinyxml2::XML_SUCCESS) { - x = 1.0; - } - if(e->QueryFloatAttribute("color_g", &y) != tinyxml2::XML_SUCCESS) { - y = 1.0; - } - if(e->QueryFloatAttribute("color_b", &z) != tinyxml2::XML_SUCCESS) { - z = 1.0; - } - m_color = Vector3::Create(x,y,z); - - if(e->QueryFloatAttribute("intensity", &m_intensity) != tinyxml2::XML_SUCCESS) { - m_intensity = 100.0; - } - - if(e->QueryFloatAttribute("decay_start", &m_decayStart) != tinyxml2::XML_SUCCESS) { - m_decayStart = 0.0; - } - - if(e->QueryFloatAttribute("flare_size", &m_flareSize) != tinyxml2::XML_SUCCESS) { - m_flareSize = 0.0; - } - - if(e->QueryFloatAttribute("flare_occlusion_size", &m_flareOcclusionSize) != tinyxml2::XML_SUCCESS) { - m_flareOcclusionSize = 0.05f; - } - - if(e->QueryBoolAttribute("casts_shadow", &m_casts_shadow) != tinyxml2::XML_SUCCESS) { - m_casts_shadow = true; - } - - if(e->QueryBoolAttribute("light_shafts", &m_light_shafts) != tinyxml2::XML_SUCCESS) { - m_light_shafts = true; - } - +void KRLight::loadXML(tinyxml2::XMLElement* e) +{ + KRNode::loadXML(e); + float x = 1.0f, y = 1.0f, z = 1.0f; + if (e->QueryFloatAttribute("color_r", &x) != tinyxml2::XML_SUCCESS) { + x = 1.0; + } + if (e->QueryFloatAttribute("color_g", &y) != tinyxml2::XML_SUCCESS) { + y = 1.0; + } + if (e->QueryFloatAttribute("color_b", &z) != tinyxml2::XML_SUCCESS) { + z = 1.0; + } + m_color = Vector3::Create(x, y, z); + + if (e->QueryFloatAttribute("intensity", &m_intensity) != tinyxml2::XML_SUCCESS) { + m_intensity = 100.0; + } + + if (e->QueryFloatAttribute("decay_start", &m_decayStart) != tinyxml2::XML_SUCCESS) { + m_decayStart = 0.0; + } + + if (e->QueryFloatAttribute("flare_size", &m_flareSize) != tinyxml2::XML_SUCCESS) { + m_flareSize = 0.0; + } + + if (e->QueryFloatAttribute("flare_occlusion_size", &m_flareOcclusionSize) != tinyxml2::XML_SUCCESS) { + m_flareOcclusionSize = 0.05f; + } + + if (e->QueryBoolAttribute("casts_shadow", &m_casts_shadow) != tinyxml2::XML_SUCCESS) { + m_casts_shadow = true; + } + + if (e->QueryBoolAttribute("light_shafts", &m_light_shafts) != tinyxml2::XML_SUCCESS) { + m_light_shafts = true; + } + + m_dust_particle_density = 0.1f; + if (e->QueryFloatAttribute("dust_particle_density", &m_dust_particle_density) != tinyxml2::XML_SUCCESS) { m_dust_particle_density = 0.1f; - if(e->QueryFloatAttribute("dust_particle_density", &m_dust_particle_density) != tinyxml2::XML_SUCCESS) { - m_dust_particle_density = 0.1f; - } - + } + + m_dust_particle_size = 1.0f; + if (e->QueryFloatAttribute("dust_particle_size", &m_dust_particle_size) != tinyxml2::XML_SUCCESS) { m_dust_particle_size = 1.0f; - if(e->QueryFloatAttribute("dust_particle_size", &m_dust_particle_size) != tinyxml2::XML_SUCCESS) { - m_dust_particle_size = 1.0f; - } - + } + + m_dust_particle_intensity = 1.0f; + if (e->QueryFloatAttribute("dust_particle_intensity", &m_dust_particle_intensity) != tinyxml2::XML_SUCCESS) { m_dust_particle_intensity = 1.0f; - if(e->QueryFloatAttribute("dust_particle_intensity", &m_dust_particle_intensity) != tinyxml2::XML_SUCCESS) { - m_dust_particle_intensity = 1.0f; - } - - const char *szFlareTexture = e->Attribute("flare_texture"); - if(szFlareTexture) { - m_flareTexture = szFlareTexture; - } else { - m_flareTexture = ""; - } - m_pFlareTexture = NULL; + } + + const char* szFlareTexture = e->Attribute("flare_texture"); + if (szFlareTexture) { + m_flareTexture = szFlareTexture; + } else { + m_flareTexture = ""; + } + m_pFlareTexture = NULL; } -void KRLight::setFlareTexture(std::string flare_texture) { - m_flareTexture = flare_texture; - m_pFlareTexture = NULL; +void KRLight::setFlareTexture(std::string flare_texture) +{ + m_flareTexture = flare_texture; + m_pFlareTexture = NULL; } -void KRLight::setFlareSize(float flare_size) { - m_flareSize = flare_size; +void KRLight::setFlareSize(float flare_size) +{ + m_flareSize = flare_size; } -void KRLight::setFlareOcclusionSize(float occlusion_size) { - m_flareOcclusionSize = occlusion_size; +void KRLight::setFlareOcclusionSize(float occlusion_size) +{ + m_flareOcclusionSize = occlusion_size; } -void KRLight::setIntensity(float intensity) { - m_intensity = intensity; +void KRLight::setIntensity(float intensity) +{ + m_intensity = intensity; } -float KRLight::getIntensity() { - return m_intensity; +float KRLight::getIntensity() +{ + return m_intensity; } -const Vector3 &KRLight::getColor() { - return m_color; +const Vector3& KRLight::getColor() +{ + return m_color; } -void KRLight::setColor(const Vector3 &color) { - m_color = color; +void KRLight::setColor(const Vector3& color) +{ + m_color = color; } -void KRLight::setDecayStart(float decayStart) { - m_decayStart = decayStart; +void KRLight::setDecayStart(float decayStart) +{ + m_decayStart = decayStart; } -float KRLight::getDecayStart() { - return m_decayStart; +float KRLight::getDecayStart() +{ + return m_decayStart; } -void KRLight::render(RenderInfo& ri) { +void KRLight::render(RenderInfo& ri) +{ - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRNode::render(ri); - - if(ri.renderPass == KRNode::RENDER_PASS_GENERATE_SHADOWMAPS && (ri.camera->settings.volumetric_environment_enable || ri.camera->settings.dust_particle_enable || (ri.camera->settings.m_cShadowBuffers > 0 && m_casts_shadow))) { - allocateShadowBuffers(configureShadowBufferViewports(ri.viewport)); - renderShadowBuffers(ri); - } - - if(ri.renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES && ri.camera->settings.dust_particle_enable) { - // Render brownian particles for dust floating in air - if(m_cShadowBuffers >= 1 && shadowValid[0] && m_dust_particle_density > 0.0f && m_dust_particle_size > 0.0f && m_dust_particle_intensity > 0.0f) { - - if(ri.viewport.visible(getBounds()) || true) { // FINDME, HACK need to remove "|| true"? - - float particle_range = 600.0f; - - int particle_count = (int)(m_dust_particle_density * pow(particle_range, 3)); - if (particle_count > KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES) { - particle_count = KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES; - } + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - Matrix4 particleModelMatrix; - particleModelMatrix.scale(particle_range); // Scale the box symetrically to ensure that we don't have an uneven distribution of particles for different angles of the view frustrum - particleModelMatrix.translate(ri.viewport.getCameraPosition()); - - std::vector this_directional_light; - std::vector this_spot_light; - std::vector this_point_light; - KRDirectionalLight *directional_light = dynamic_cast(this); - KRSpotLight *spot_light = dynamic_cast(this); - KRPointLight *point_light = dynamic_cast(this); - if(directional_light) { - this_directional_light.push_back(directional_light); - } - if(spot_light) { - this_spot_light.push_back(spot_light); - } - if(point_light) { - this_point_light.push_back(point_light); - } - - PipelineInfo info{}; - std::string shader_name("dust_particle"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &this_point_light; - info.directional_lights = &this_directional_light; - info.spot_lights = &this_spot_light; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAdditive; - info.cullMode = CullMode::kCullNone; - info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); - info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; - KRPipeline *pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); + KRNode::render(ri); - pParticleShader->setUniform(KRPipeline::Uniform::light_color, m_color * ri.camera->settings.dust_particle_intensity * m_dust_particle_intensity * m_intensity); - pParticleShader->setUniform(KRPipeline::Uniform::particle_origin, Matrix4::DotWDiv(Matrix4::Invert(particleModelMatrix), Vector3::Zero())); - pParticleShader->setUniform(KRPipeline::Uniform::flare_size, m_dust_particle_size); - pParticleShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, particleModelMatrix, &this_point_light, &this_directional_light, &this_spot_light, ri.renderPass); - - m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_RANDOM_PARTICLES, 1.0f); + if (ri.renderPass == KRNode::RENDER_PASS_GENERATE_SHADOWMAPS && (ri.camera->settings.volumetric_environment_enable || ri.camera->settings.dust_particle_enable || (ri.camera->settings.m_cShadowBuffers > 0 && m_casts_shadow))) { + allocateShadowBuffers(configureShadowBufferViewports(ri.viewport)); + renderShadowBuffers(ri); + } - vkCmdDraw(ri.commandBuffer, particle_count * 3, 1, 0, 0); - } + if (ri.renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES && ri.camera->settings.dust_particle_enable) { + // Render brownian particles for dust floating in air + if (m_cShadowBuffers >= 1 && shadowValid[0] && m_dust_particle_density > 0.0f && m_dust_particle_size > 0.0f && m_dust_particle_intensity > 0.0f) { + + if (ri.viewport.visible(getBounds()) || true) { // FINDME, HACK need to remove "|| true"? + + float particle_range = 600.0f; + + int particle_count = (int)(m_dust_particle_density * pow(particle_range, 3)); + if (particle_count > KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES) { + particle_count = KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES; } - } - - if(ri.renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE && ri.camera->settings.volumetric_environment_enable && m_light_shafts) { - std::string shader_name = ri.camera->settings.volumetric_environment_downsample != 0 ? "volumetric_fog_downsampled" : "volumetric_fog"; - - std::vector this_directional_light; - std::vector this_spot_light; - std::vector this_point_light; - KRDirectionalLight *directional_light = dynamic_cast(this); - KRSpotLight *spot_light = dynamic_cast(this); - KRPointLight *point_light = dynamic_cast(this); - if(directional_light) { - this_directional_light.push_back(directional_light); + Matrix4 particleModelMatrix; + particleModelMatrix.scale(particle_range); // Scale the box symetrically to ensure that we don't have an uneven distribution of particles for different angles of the view frustrum + particleModelMatrix.translate(ri.viewport.getCameraPosition()); + + std::vector this_directional_light; + std::vector this_spot_light; + std::vector this_point_light; + KRDirectionalLight* directional_light = dynamic_cast(this); + KRSpotLight* spot_light = dynamic_cast(this); + KRPointLight* point_light = dynamic_cast(this); + if (directional_light) { + this_directional_light.push_back(directional_light); } - if(spot_light) { - this_spot_light.push_back(spot_light); + if (spot_light) { + this_spot_light.push_back(spot_light); } - if(point_light) { - this_point_light.push_back(point_light); + if (point_light) { + this_point_light.push_back(point_light); } PipelineInfo info{}; + std::string shader_name("dust_particle"); info.shader_name = &shader_name; info.pCamera = ri.camera; info.point_lights = &this_point_light; info.directional_lights = &this_directional_light; info.spot_lights = &this_spot_light; - info.renderPass = KRNode::RENDER_PASS_ADDITIVE_PARTICLES; + info.renderPass = ri.renderPass; info.rasterMode = RasterMode::kAdditive; info.cullMode = CullMode::kCullNone; - info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); + info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; - - KRPipeline *pFogShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); + KRPipeline* pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); - int slice_count = (int)(ri.camera->settings.volumetric_environment_quality * 495.0) + 5; - - float slice_near = -ri.camera->settings.getPerspectiveNearZ(); - float slice_far = -ri.camera->settings.volumetric_environment_max_distance; - float slice_spacing = (slice_far - slice_near) / slice_count; - - pFogShader->setUniform(KRPipeline::Uniform::slice_depth_scale, Vector2::Create(slice_near, slice_spacing)); - pFogShader->setUniform(KRPipeline::Uniform::light_color, (m_color * ri.camera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f)); - pFogShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, Matrix4(), &this_point_light, &this_directional_light, &this_spot_light, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE); - - m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_VOLUMETRIC_LIGHTING, 1.0f); - vkCmdDraw(ri.commandBuffer, slice_count * 6, 1, 0, 0); + pParticleShader->setUniform(KRPipeline::Uniform::light_color, m_color * ri.camera->settings.dust_particle_intensity * m_dust_particle_intensity * m_intensity); + pParticleShader->setUniform(KRPipeline::Uniform::particle_origin, Matrix4::DotWDiv(Matrix4::Invert(particleModelMatrix), Vector3::Zero())); + pParticleShader->setUniform(KRPipeline::Uniform::flare_size, m_dust_particle_size); + pParticleShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, particleModelMatrix, &this_point_light, &this_directional_light, &this_spot_light, ri.renderPass); + m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_RANDOM_PARTICLES, 1.0f); + + vkCmdDraw(ri.commandBuffer, particle_count * 3, 1, 0, 0); + } } - - if(ri.renderPass == KRNode::RENDER_PASS_PARTICLE_OCCLUSION) { - if(m_flareTexture.size() && m_flareSize > 0.0f) { - KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere"); - if (sphereModel) { - - Matrix4 occlusion_test_sphere_matrix = Matrix4(); - occlusion_test_sphere_matrix.scale(m_localScale * m_flareOcclusionSize); - occlusion_test_sphere_matrix.translate(m_localTranslation); - if(m_parentNode) { - occlusion_test_sphere_matrix *= m_parentNode->getModelMatrix(); - } + } - PipelineInfo info{}; - std::string shader_name("occlusion_test"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAdditive; - info.cullMode = CullMode::kCullNone; - info.modelFormat = sphereModel->getModelFormat(); - info.vertexAttributes = sphereModel->getVertexAttributes(); - KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pPipeline->bind(ri.commandBuffer, *info.pCamera, ri.viewport, occlusion_test_sphere_matrix, info.point_lights, info.directional_lights, info.spot_lights, info.renderPass); + if (ri.renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE && ri.camera->settings.volumetric_environment_enable && m_light_shafts) { + std::string shader_name = ri.camera->settings.volumetric_environment_downsample != 0 ? "volumetric_fog_downsampled" : "volumetric_fog"; - GLDEBUG(glGenQueriesEXT(1, &m_occlusionQuery)); - #if TARGET_OS_IPHONE || defined(ANDROID) - GLDEBUG(glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, m_occlusionQuery)); - #else - GLDEBUG(glBeginQuery(GL_SAMPLES_PASSED, m_occlusionQuery)); - #endif + std::vector this_directional_light; + std::vector this_spot_light; + std::vector this_point_light; + KRDirectionalLight* directional_light = dynamic_cast(this); + KRSpotLight* spot_light = dynamic_cast(this); + KRPointLight* point_light = dynamic_cast(this); + if (directional_light) { + this_directional_light.push_back(directional_light); + } + if (spot_light) { + this_spot_light.push_back(spot_light); + } + if (point_light) { + this_point_light.push_back(point_light); + } - sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "occlusion_test", 1.0f); + PipelineInfo info{}; + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &this_point_light; + info.directional_lights = &this_directional_light; + info.spot_lights = &this_spot_light; + info.renderPass = KRNode::RENDER_PASS_ADDITIVE_PARTICLES; + info.rasterMode = RasterMode::kAdditive; + info.cullMode = CullMode::kCullNone; + info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); + info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; + + KRPipeline* pFogShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); + + int slice_count = (int)(ri.camera->settings.volumetric_environment_quality * 495.0) + 5; + + float slice_near = -ri.camera->settings.getPerspectiveNearZ(); + float slice_far = -ri.camera->settings.volumetric_environment_max_distance; + float slice_spacing = (slice_far - slice_near) / slice_count; + + pFogShader->setUniform(KRPipeline::Uniform::slice_depth_scale, Vector2::Create(slice_near, slice_spacing)); + pFogShader->setUniform(KRPipeline::Uniform::light_color, (m_color * ri.camera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f)); + pFogShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, Matrix4(), &this_point_light, &this_directional_light, &this_spot_light, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE); + + m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_VOLUMETRIC_LIGHTING, 1.0f); + vkCmdDraw(ri.commandBuffer, slice_count * 6, 1, 0, 0); + + } + + if (ri.renderPass == KRNode::RENDER_PASS_PARTICLE_OCCLUSION) { + if (m_flareTexture.size() && m_flareSize > 0.0f) { + KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere"); + if (sphereModel) { + + Matrix4 occlusion_test_sphere_matrix = Matrix4(); + occlusion_test_sphere_matrix.scale(m_localScale * m_flareOcclusionSize); + occlusion_test_sphere_matrix.translate(m_localTranslation); + if (m_parentNode) { + occlusion_test_sphere_matrix *= m_parentNode->getModelMatrix(); + } + + PipelineInfo info{}; + std::string shader_name("occlusion_test"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.renderPass = ri.renderPass; + info.rasterMode = RasterMode::kAdditive; + info.cullMode = CullMode::kCullNone; + info.modelFormat = sphereModel->getModelFormat(); + info.vertexAttributes = sphereModel->getVertexAttributes(); + + KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + pPipeline->bind(ri.commandBuffer, *info.pCamera, ri.viewport, occlusion_test_sphere_matrix, info.point_lights, info.directional_lights, info.spot_lights, info.renderPass); + + GLDEBUG(glGenQueriesEXT(1, &m_occlusionQuery)); +#if TARGET_OS_IPHONE || defined(ANDROID) + GLDEBUG(glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, m_occlusionQuery)); +#else + GLDEBUG(glBeginQuery(GL_SAMPLES_PASSED, m_occlusionQuery)); +#endif + + sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "occlusion_test", 1.0f); #if TARGET_OS_IPHONE || defined(ANDROID) - GLDEBUG(glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT)); + GLDEBUG(glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT)); #else - GLDEBUG(glEndQuery(GL_SAMPLES_PASSED)); + GLDEBUG(glEndQuery(GL_SAMPLES_PASSED)); #endif - } + } - } } - - if(ri.renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { - if(m_flareTexture.size() && m_flareSize > 0.0f) { - - if(m_occlusionQuery) { - GLuint params = 0; - GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms)); - GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery)); - - if(params) { - - if(!m_pFlareTexture && m_flareTexture.size()) { - m_pFlareTexture = getContext().getTextureManager()->getTexture(m_flareTexture); - } - - if(m_pFlareTexture) { - KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES; + } - // Render light flare on transparency pass - PipelineInfo info{}; - std::string shader_name("flare"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAdditiveNoTest; - info.cullMode = CullMode::kCullNone; - info.vertexAttributes = vertices.getVertexAttributes(); - info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; + if (ri.renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { + if (m_flareTexture.size() && m_flareSize > 0.0f) { + + if (m_occlusionQuery) { + GLuint params = 0; + GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms)); + GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery)); + + if (params) { + + if (!m_pFlareTexture && m_flareTexture.size()) { + m_pFlareTexture = getContext().getTextureManager()->getTexture(m_flareTexture); + } + + if (m_pFlareTexture) { + KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES; + + // Render light flare on transparency pass + PipelineInfo info{}; + std::string shader_name("flare"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.renderPass = ri.renderPass; + info.rasterMode = RasterMode::kAdditiveNoTest; + info.cullMode = CullMode::kCullNone; + info.vertexAttributes = vertices.getVertexAttributes(); + info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; - KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->setUniform(KRPipeline::Uniform::material_alpha, 1.0f); - pShader->setUniform(KRPipeline::Uniform::flare_size, m_flareSize); - pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + pShader->setUniform(KRPipeline::Uniform::material_alpha, 1.0f); + pShader->setUniform(KRPipeline::Uniform::flare_size, m_flareSize); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); - m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture, 0.0f, KRTexture::TEXTURE_USAGE_LIGHT_FLARE); - m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &vertices, 1.0f); - vkCmdDraw(ri.commandBuffer, 4, 1, 0, 0); - } - } - } + m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture, 0.0f, KRTexture::TEXTURE_USAGE_LIGHT_FLARE); + m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &vertices, 1.0f); + vkCmdDraw(ri.commandBuffer, 4, 1, 0, 0); + } } - + } } + + } } -void KRLight::allocateShadowBuffers(int cBuffers) { - // First deallocate buffers no longer needed - for(int iShadow = cBuffers; iShadow < KRENGINE_MAX_SHADOW_BUFFERS; iShadow++) { - if (shadowDepthTexture[iShadow]) { - GLDEBUG(glDeleteTextures(1, shadowDepthTexture + iShadow)); - shadowDepthTexture[iShadow] = 0; - } - - if (shadowFramebuffer[iShadow]) { - GLDEBUG(glDeleteFramebuffers(1, shadowFramebuffer + iShadow)); - shadowFramebuffer[iShadow] = 0; - } +void KRLight::allocateShadowBuffers(int cBuffers) +{ + // First deallocate buffers no longer needed + for (int iShadow = cBuffers; iShadow < KRENGINE_MAX_SHADOW_BUFFERS; iShadow++) { + if (shadowDepthTexture[iShadow]) { + GLDEBUG(glDeleteTextures(1, shadowDepthTexture + iShadow)); + shadowDepthTexture[iShadow] = 0; } - - // Allocate newly required buffers - for(int iShadow = 0; iShadow < cBuffers; iShadow++) { - Vector2 viewportSize = m_shadowViewports[iShadow].getSize(); - - if(!shadowDepthTexture[iShadow]) { - shadowValid[iShadow] = false; - - GLDEBUG(glGenFramebuffers(1, shadowFramebuffer + iShadow)); - GLDEBUG(glGenTextures(1, shadowDepthTexture + iShadow)); - // ===== Create offscreen shadow framebuffer object ===== - - GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow])); - - // ----- Create Depth Texture for shadowFramebuffer ----- - GLDEBUG( glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow])); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - m_pContext->getTextureManager()->_setWrapModeS(shadowDepthTexture[iShadow], GL_CLAMP_TO_EDGE); - m_pContext->getTextureManager()->_setWrapModeT(shadowDepthTexture[iShadow], GL_CLAMP_TO_EDGE); + + if (shadowFramebuffer[iShadow]) { + GLDEBUG(glDeleteFramebuffers(1, shadowFramebuffer + iShadow)); + shadowFramebuffer[iShadow] = 0; + } + } + + // Allocate newly required buffers + for (int iShadow = 0; iShadow < cBuffers; iShadow++) { + Vector2 viewportSize = m_shadowViewports[iShadow].getSize(); + + if (!shadowDepthTexture[iShadow]) { + shadowValid[iShadow] = false; + + GLDEBUG(glGenFramebuffers(1, shadowFramebuffer + iShadow)); + GLDEBUG(glGenTextures(1, shadowDepthTexture + iShadow)); + // ===== Create offscreen shadow framebuffer object ===== + + GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow])); + + // ----- Create Depth Texture for shadowFramebuffer ----- + GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow])); + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + m_pContext->getTextureManager()->_setWrapModeS(shadowDepthTexture[iShadow], GL_CLAMP_TO_EDGE); + m_pContext->getTextureManager()->_setWrapModeT(shadowDepthTexture[iShadow], GL_CLAMP_TO_EDGE); #if GL_EXT_shadow_samplers - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_COMPARE_REF_TO_TEXTURE_EXT)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_EXT, GL_LEQUAL)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_COMPARE_REF_TO_TEXTURE_EXT)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_EXT, GL_LEQUAL)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available #endif - GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, (GLsizei)viewportSize.x, (GLsizei)viewportSize.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); - - GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowDepthTexture[iShadow], 0)); - } + GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, (GLsizei)viewportSize.x, (GLsizei)viewportSize.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); + + GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowDepthTexture[iShadow], 0)); } - - m_cShadowBuffers = cBuffers; + } + + m_cShadowBuffers = cBuffers; } void KRLight::deleteBuffers() { - // Called when this light wasn't used in the last frame, so we can free the resources for use by other lights - allocateShadowBuffers(0); + // Called when this light wasn't used in the last frame, so we can free the resources for use by other lights + allocateShadowBuffers(0); } void KRLight::invalidateShadowBuffers() { - for(int iShadow=0; iShadow < m_cShadowBuffers; iShadow++) { - shadowValid[iShadow] = false; - } + for (int iShadow = 0; iShadow < m_cShadowBuffers; iShadow++) { + shadowValid[iShadow] = false; + } } -int KRLight::configureShadowBufferViewports(const KRViewport &viewport) +int KRLight::configureShadowBufferViewports(const KRViewport& viewport) { - return 0; + return 0; } void KRLight::renderShadowBuffers(RenderInfo& ri) { - for(int iShadow=0; iShadow < m_cShadowBuffers; iShadow++) { - if(!shadowValid[iShadow]) { - shadowValid[iShadow] = true; - - GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow])); - GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowDepthTexture[iShadow], 0)); - - GLDEBUG(glViewport(0, 0, (GLsizei)m_shadowViewports[iShadow].getSize().x, (GLsizei)m_shadowViewports[iShadow].getSize().y)); - - GLDEBUG(glClearDepthf(0.0f)); - GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT)); - - GLDEBUG(glViewport(1, 1, (GLsizei)m_shadowViewports[iShadow].getSize().x - 2, (GLsizei)m_shadowViewports[iShadow].getSize().y - 2)); + for (int iShadow = 0; iShadow < m_cShadowBuffers; iShadow++) { + if (!shadowValid[iShadow]) { + shadowValid[iShadow] = true; - GLDEBUG(glClearDepthf(1.0f)); - - GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT)); - - GLDEBUG(glDisable(GL_DITHER)); - - // Use shader program - PipelineInfo info{}; - std::string shader_name("ShadowShader"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.renderPass = KRNode::RENDER_PASS_FORWARD_TRANSPARENT; - info.rasterMode = RasterMode::kOpaqueLessTest; // TODO - This is sub-optimal. Evaluate increasing depth buffer resolution instead of disabling depth test. - info.cullMode = CullMode::kCullNone; // Disabling culling, which eliminates some self-cast shadow artifacts - KRPipeline *shadowShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); + GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow])); + GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowDepthTexture[iShadow], 0)); - shadowShader->bind(ri.commandBuffer, *ri.camera, m_shadowViewports[iShadow], Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_SHADOWMAP); - - getScene().render(ri.commandBuffer, *ri.surface, ri.camera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, true); - } + GLDEBUG(glViewport(0, 0, (GLsizei)m_shadowViewports[iShadow].getSize().x, (GLsizei)m_shadowViewports[iShadow].getSize().y)); + + GLDEBUG(glClearDepthf(0.0f)); + GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT)); + + GLDEBUG(glViewport(1, 1, (GLsizei)m_shadowViewports[iShadow].getSize().x - 2, (GLsizei)m_shadowViewports[iShadow].getSize().y - 2)); + + GLDEBUG(glClearDepthf(1.0f)); + + GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT)); + + GLDEBUG(glDisable(GL_DITHER)); + + // Use shader program + PipelineInfo info{}; + std::string shader_name("ShadowShader"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.renderPass = KRNode::RENDER_PASS_FORWARD_TRANSPARENT; + info.rasterMode = RasterMode::kOpaqueLessTest; // TODO - This is sub-optimal. Evaluate increasing depth buffer resolution instead of disabling depth test. + info.cullMode = CullMode::kCullNone; // Disabling culling, which eliminates some self-cast shadow artifacts + KRPipeline* shadowShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); + + shadowShader->bind(ri.commandBuffer, *ri.camera, m_shadowViewports[iShadow], Matrix4(), nullptr, nullptr, nullptr, KRNode::RENDER_PASS_SHADOWMAP); + + getScene().render(ri.commandBuffer, *ri.surface, ri.camera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, true); } + } } int KRLight::getShadowBufferCount() { - int cBuffers=0; - for(int iBuffer=0; iBuffer < m_cShadowBuffers; iBuffer++) { - if(shadowValid[iBuffer]) { - cBuffers++; - } else { - break; - } + int cBuffers = 0; + for (int iBuffer = 0; iBuffer < m_cShadowBuffers; iBuffer++) { + if (shadowValid[iBuffer]) { + cBuffers++; + } else { + break; } - return cBuffers; + } + return cBuffers; } -GLuint *KRLight::getShadowTextures() +GLuint* KRLight::getShadowTextures() { - return shadowDepthTexture; + return shadowDepthTexture; } -KRViewport *KRLight::getShadowViewports() +KRViewport* KRLight::getShadowViewports() { - return m_shadowViewports; + return m_shadowViewports; } diff --git a/kraken/KRLight.h b/kraken/KRLight.h index cb0b995..8a8ed29 100755 --- a/kraken/KRLight.h +++ b/kraken/KRLight.h @@ -42,64 +42,65 @@ static const float KRLIGHT_MIN_INFLUENCE = 0.15f; // 0.05f #define KRENGINE_SHADOW_MAP_WIDTH 1024 #define KRENGINE_SHADOW_MAP_HEIGHT 1024 -class KRLight : public KRNode { +class KRLight : public KRNode +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); - - virtual ~KRLight(); - virtual std::string getElementName() = 0; - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - - void setIntensity(float intensity); - float getIntensity(); - void setDecayStart(float decayStart); - float getDecayStart(); - const Vector3 &getColor(); - void setColor(const Vector3 &color); - - void setFlareTexture(std::string flare_texture); - void setFlareSize(float flare_size); - void setFlareOcclusionSize(float occlusion_size); - void deleteBuffers(); + static void InitNodeInfo(KrNodeInfo* nodeInfo); + + virtual ~KRLight(); + virtual std::string getElementName() = 0; + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + + void setIntensity(float intensity); + float getIntensity(); + void setDecayStart(float decayStart); + float getDecayStart(); + const Vector3& getColor(); + void setColor(const Vector3& color); + + void setFlareTexture(std::string flare_texture); + void setFlareSize(float flare_size); + void setFlareOcclusionSize(float occlusion_size); + void deleteBuffers(); + + virtual void render(RenderInfo& ri); + + int getShadowBufferCount(); + GLuint* getShadowTextures(); + KRViewport* getShadowViewports(); + - virtual void render(RenderInfo& ri); - - int getShadowBufferCount(); - GLuint *getShadowTextures(); - KRViewport *getShadowViewports(); - - protected: - KRLight(KRScene &scene, std::string name); - - float m_intensity; - float m_decayStart; - Vector3 m_color; - - std::string m_flareTexture; - KRTexture *m_pFlareTexture; - float m_flareSize; - float m_flareOcclusionSize; - - bool m_casts_shadow; - bool m_light_shafts; - float m_dust_particle_density; - float m_dust_particle_size; - float m_dust_particle_intensity; - - GLuint m_occlusionQuery; // Occlusion query for attenuating occluded flares - - - // Shadow Maps - int m_cShadowBuffers; - GLuint shadowFramebuffer[KRENGINE_MAX_SHADOW_BUFFERS], shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS]; - bool shadowValid[KRENGINE_MAX_SHADOW_BUFFERS]; - KRViewport m_shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS]; - - void allocateShadowBuffers(int cBuffers); - void invalidateShadowBuffers(); - - virtual int configureShadowBufferViewports(const KRViewport &viewport); - void renderShadowBuffers(RenderInfo& ri); + KRLight(KRScene& scene, std::string name); + + float m_intensity; + float m_decayStart; + Vector3 m_color; + + std::string m_flareTexture; + KRTexture* m_pFlareTexture; + float m_flareSize; + float m_flareOcclusionSize; + + bool m_casts_shadow; + bool m_light_shafts; + float m_dust_particle_density; + float m_dust_particle_size; + float m_dust_particle_intensity; + + GLuint m_occlusionQuery; // Occlusion query for attenuating occluded flares + + + // Shadow Maps + int m_cShadowBuffers; + GLuint shadowFramebuffer[KRENGINE_MAX_SHADOW_BUFFERS], shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS]; + bool shadowValid[KRENGINE_MAX_SHADOW_BUFFERS]; + KRViewport m_shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS]; + + void allocateShadowBuffers(int cBuffers); + void invalidateShadowBuffers(); + + virtual int configureShadowBufferViewports(const KRViewport& viewport); + void renderShadowBuffers(RenderInfo& ri); }; diff --git a/kraken/KRLocator.cpp b/kraken/KRLocator.cpp index 0252518..04f71aa 100755 --- a/kraken/KRLocator.cpp +++ b/kraken/KRLocator.cpp @@ -39,47 +39,47 @@ void KRLocator::InitNodeInfo(KrNodeInfo* nodeInfo) // No additional members } -KRLocator::KRLocator(KRScene &scene, std::string name) : KRNode(scene, name) +KRLocator::KRLocator(KRScene& scene, std::string name) : KRNode(scene, name) { - + } KRLocator::~KRLocator() +{} + +std::string KRLocator::getElementName() { + return "locator"; } -std::string KRLocator::getElementName() { - return "locator"; +tinyxml2::XMLElement* KRLocator::saveXML(tinyxml2::XMLNode* parent) +{ + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + + return e; } -tinyxml2::XMLElement *KRLocator::saveXML( tinyxml2::XMLNode *parent) +void KRLocator::loadXML(tinyxml2::XMLElement* e) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - - return e; + KRNode::loadXML(e); } -void KRLocator::loadXML(tinyxml2::XMLElement *e) +unordered_map& KRLocator::getUserIntAttributes() { - KRNode::loadXML(e); + return m_userIntAttributes; } -unordered_map &KRLocator::getUserIntAttributes() +unordered_map& KRLocator::getUserDoubleAttributes() { - return m_userIntAttributes; + return m_userDoubleAttributes; } -unordered_map &KRLocator::getUserDoubleAttributes() +unordered_map& KRLocator::getUserBoolAttributes() { - return m_userDoubleAttributes; + return m_userBoolAttributes; } -unordered_map &KRLocator::getUserBoolAttributes() +unordered_map& KRLocator::getUserStringAttributes() { - return m_userBoolAttributes; -} - -unordered_map &KRLocator::getUserStringAttributes() -{ - return m_userStringAttributes; + return m_userStringAttributes; } diff --git a/kraken/KRLocator.h b/kraken/KRLocator.h index cd34ba3..833136e 100755 --- a/kraken/KRLocator.h +++ b/kraken/KRLocator.h @@ -35,23 +35,24 @@ #include "KRNode.h" #include "KRTexture.h" -class KRLocator : public KRNode { +class KRLocator : public KRNode +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); + static void InitNodeInfo(KrNodeInfo* nodeInfo); + + KRLocator(KRScene& scene, std::string name); + virtual ~KRLocator(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + unordered_map& getUserIntAttributes(); + unordered_map& getUserDoubleAttributes(); + unordered_map& getUserBoolAttributes(); + unordered_map& getUserStringAttributes(); - KRLocator(KRScene &scene, std::string name); - virtual ~KRLocator(); - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - unordered_map &getUserIntAttributes(); - unordered_map &getUserDoubleAttributes(); - unordered_map &getUserBoolAttributes(); - unordered_map &getUserStringAttributes(); - private: - unordered_map m_userIntAttributes; - unordered_map m_userDoubleAttributes; - unordered_map m_userBoolAttributes; - unordered_map m_userStringAttributes; + unordered_map m_userIntAttributes; + unordered_map m_userDoubleAttributes; + unordered_map m_userBoolAttributes; + unordered_map m_userStringAttributes; }; diff --git a/kraken/KRMaterial.cpp b/kraken/KRMaterial.cpp index f0d1fd9..9f3144a 100755 --- a/kraken/KRMaterial.cpp +++ b/kraken/KRMaterial.cpp @@ -36,415 +36,434 @@ #include "KRContext.h" -KRMaterial::KRMaterial(KRContext &context, const char *szName) : KRResource(context, szName) { - m_name = szName; - m_pAmbientMap = NULL; - m_pDiffuseMap = NULL; - m_pSpecularMap = NULL; - m_pNormalMap = NULL; - m_pReflectionMap = NULL; - m_pReflectionCube = NULL; - m_ambientColor = Vector3::Zero(); - m_diffuseColor = Vector3::One(); - m_specularColor = Vector3::One(); - m_reflectionColor = Vector3::Zero(); - m_tr = 1.0f; - m_ns = 0.0f; - m_ambientMap = ""; - m_diffuseMap = ""; - m_specularMap = ""; - m_normalMap = ""; - m_reflectionMap = ""; - m_reflectionCube = ""; - m_ambientMapOffset = Vector2::Create(0.0f, 0.0f); - m_specularMapOffset = Vector2::Create(0.0f, 0.0f); - m_diffuseMapOffset = Vector2::Create(0.0f, 0.0f); - m_ambientMapScale = Vector2::Create(1.0f, 1.0f); - m_specularMapScale = Vector2::Create(1.0f, 1.0f); - m_diffuseMapScale = Vector2::Create(1.0f, 1.0f); - m_reflectionMapOffset = Vector2::Create(0.0f, 0.0f); - m_reflectionMapScale = Vector2::Create(1.0f, 1.0f); - m_alpha_mode = KRMATERIAL_ALPHA_MODE_OPAQUE; +KRMaterial::KRMaterial(KRContext& context, const char* szName) : KRResource(context, szName) +{ + m_name = szName; + m_pAmbientMap = NULL; + m_pDiffuseMap = NULL; + m_pSpecularMap = NULL; + m_pNormalMap = NULL; + m_pReflectionMap = NULL; + m_pReflectionCube = NULL; + m_ambientColor = Vector3::Zero(); + m_diffuseColor = Vector3::One(); + m_specularColor = Vector3::One(); + m_reflectionColor = Vector3::Zero(); + m_tr = 1.0f; + m_ns = 0.0f; + m_ambientMap = ""; + m_diffuseMap = ""; + m_specularMap = ""; + m_normalMap = ""; + m_reflectionMap = ""; + m_reflectionCube = ""; + m_ambientMapOffset = Vector2::Create(0.0f, 0.0f); + m_specularMapOffset = Vector2::Create(0.0f, 0.0f); + m_diffuseMapOffset = Vector2::Create(0.0f, 0.0f); + m_ambientMapScale = Vector2::Create(1.0f, 1.0f); + m_specularMapScale = Vector2::Create(1.0f, 1.0f); + m_diffuseMapScale = Vector2::Create(1.0f, 1.0f); + m_reflectionMapOffset = Vector2::Create(0.0f, 0.0f); + m_reflectionMapScale = Vector2::Create(1.0f, 1.0f); + m_alpha_mode = KRMATERIAL_ALPHA_MODE_OPAQUE; } -KRMaterial::~KRMaterial() { - +KRMaterial::~KRMaterial() +{ + } -std::string KRMaterial::getExtension() { - return "mtl"; +std::string KRMaterial::getExtension() +{ + return "mtl"; } bool KRMaterial::needsVertexTangents() { - return m_normalMap.size() > 0; + return m_normalMap.size() > 0; } -bool KRMaterial::save(KRDataBlock &data) { - std::stringstream stream; - stream.precision(std::numeric_limits::digits10); - stream.setf(std::ios::fixed,std::ios::floatfield); - - stream << "newmtl " << m_name; - stream << "\nka " << m_ambientColor.x << " " << m_ambientColor.y << " " << m_ambientColor.z; - stream << "\nkd " << m_diffuseColor.x << " " << m_diffuseColor.y << " " << m_diffuseColor.z; - stream << "\nks " << m_specularColor.x << " " << m_specularColor.y << " " << m_specularColor.z; - stream << "\nkr " << m_reflectionColor.x << " " << m_reflectionColor.y << " " << m_reflectionColor.z; - stream << "\nTr " << m_tr; - stream << "\nNs " << m_ns; - if(m_ambientMap.size()) { - stream << "\nmap_Ka " << m_ambientMap << ".pvr -s " << m_ambientMapScale.x << " " << m_ambientMapScale.y << " -o " << m_ambientMapOffset.x << " " << m_ambientMapOffset.y; - } else { - stream << "\n# map_Ka filename.pvr -s 1.0 1.0 -o 0.0 0.0"; - } - if(m_diffuseMap.size()) { - stream << "\nmap_Kd " << m_diffuseMap << ".pvr -s " << m_diffuseMapScale.x << " " << m_diffuseMapScale.y << " -o " << m_diffuseMapOffset.x << " " << m_diffuseMapOffset.y; - } else { - stream << "\n# map_Kd filename.pvr -s 1.0 1.0 -o 0.0 0.0"; - } - if(m_specularMap.size()) { - stream << "\nmap_Ks " << m_specularMap << ".pvr -s " << m_specularMapScale.x << " " << m_specularMapScale.y << " -o " << m_specularMapOffset.x << " " << m_specularMapOffset.y << "\n"; - } else { - stream << "\n# map_Ks filename.pvr -s 1.0 1.0 -o 0.0 0.0"; - } - if(m_normalMap.size()) { - stream << "\nmap_Normal " << m_normalMap << ".pvr -s " << m_normalMapScale.x << " " << m_normalMapScale.y << " -o " << m_normalMapOffset.x << " " << m_normalMapOffset.y; - } else { - stream << "\n# map_Normal filename.pvr -s 1.0 1.0 -o 0.0 0.0"; - } - if(m_reflectionMap.size()) { - stream << "\nmap_Reflection " << m_reflectionMap << ".pvr -s " << m_reflectionMapScale.x << " " << m_reflectionMapScale.y << " -o " << m_reflectionMapOffset.x << " " << m_reflectionMapOffset.y; - } else { - stream << "\n# map_Reflection filename.pvr -s 1.0 1.0 -o 0.0 0.0"; - } - if(m_reflectionCube.size()) { - stream << "\nmap_ReflectionCube " << m_reflectionCube << ".pvr"; - } else { - stream << "\n# map_ReflectionCube cubemapname"; - } - switch(m_alpha_mode) { - case KRMATERIAL_ALPHA_MODE_OPAQUE: - stream << "\nalpha_mode opaque"; - break; - case KRMATERIAL_ALPHA_MODE_TEST: - stream << "\nalpha_mode test"; - break; - case KRMATERIAL_ALPHA_MODE_BLENDONESIDE: - stream << "\nalpha_mode blendoneside"; - break; - case KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE: - stream << "\nalpha_mode blendtwoside"; - break; - } - stream << "\n# alpha_mode opaque, test, blendoneside, or blendtwoside"; - - stream << "\n"; - data.append(stream.str()); +bool KRMaterial::save(KRDataBlock& data) +{ + std::stringstream stream; + stream.precision(std::numeric_limits::digits10); + stream.setf(std::ios::fixed, std::ios::floatfield); - return true; + stream << "newmtl " << m_name; + stream << "\nka " << m_ambientColor.x << " " << m_ambientColor.y << " " << m_ambientColor.z; + stream << "\nkd " << m_diffuseColor.x << " " << m_diffuseColor.y << " " << m_diffuseColor.z; + stream << "\nks " << m_specularColor.x << " " << m_specularColor.y << " " << m_specularColor.z; + stream << "\nkr " << m_reflectionColor.x << " " << m_reflectionColor.y << " " << m_reflectionColor.z; + stream << "\nTr " << m_tr; + stream << "\nNs " << m_ns; + if (m_ambientMap.size()) { + stream << "\nmap_Ka " << m_ambientMap << ".pvr -s " << m_ambientMapScale.x << " " << m_ambientMapScale.y << " -o " << m_ambientMapOffset.x << " " << m_ambientMapOffset.y; + } else { + stream << "\n# map_Ka filename.pvr -s 1.0 1.0 -o 0.0 0.0"; + } + if (m_diffuseMap.size()) { + stream << "\nmap_Kd " << m_diffuseMap << ".pvr -s " << m_diffuseMapScale.x << " " << m_diffuseMapScale.y << " -o " << m_diffuseMapOffset.x << " " << m_diffuseMapOffset.y; + } else { + stream << "\n# map_Kd filename.pvr -s 1.0 1.0 -o 0.0 0.0"; + } + if (m_specularMap.size()) { + stream << "\nmap_Ks " << m_specularMap << ".pvr -s " << m_specularMapScale.x << " " << m_specularMapScale.y << " -o " << m_specularMapOffset.x << " " << m_specularMapOffset.y << "\n"; + } else { + stream << "\n# map_Ks filename.pvr -s 1.0 1.0 -o 0.0 0.0"; + } + if (m_normalMap.size()) { + stream << "\nmap_Normal " << m_normalMap << ".pvr -s " << m_normalMapScale.x << " " << m_normalMapScale.y << " -o " << m_normalMapOffset.x << " " << m_normalMapOffset.y; + } else { + stream << "\n# map_Normal filename.pvr -s 1.0 1.0 -o 0.0 0.0"; + } + if (m_reflectionMap.size()) { + stream << "\nmap_Reflection " << m_reflectionMap << ".pvr -s " << m_reflectionMapScale.x << " " << m_reflectionMapScale.y << " -o " << m_reflectionMapOffset.x << " " << m_reflectionMapOffset.y; + } else { + stream << "\n# map_Reflection filename.pvr -s 1.0 1.0 -o 0.0 0.0"; + } + if (m_reflectionCube.size()) { + stream << "\nmap_ReflectionCube " << m_reflectionCube << ".pvr"; + } else { + stream << "\n# map_ReflectionCube cubemapname"; + } + switch (m_alpha_mode) { + case KRMATERIAL_ALPHA_MODE_OPAQUE: + stream << "\nalpha_mode opaque"; + break; + case KRMATERIAL_ALPHA_MODE_TEST: + stream << "\nalpha_mode test"; + break; + case KRMATERIAL_ALPHA_MODE_BLENDONESIDE: + stream << "\nalpha_mode blendoneside"; + break; + case KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE: + stream << "\nalpha_mode blendtwoside"; + break; + } + stream << "\n# alpha_mode opaque, test, blendoneside, or blendtwoside"; + + stream << "\n"; + data.append(stream.str()); + + return true; } -void KRMaterial::setAmbientMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset) { - m_ambientMap = texture_name; - m_ambientMapScale = texture_scale; - m_ambientMapOffset = texture_offset; +void KRMaterial::setAmbientMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset) +{ + m_ambientMap = texture_name; + m_ambientMapScale = texture_scale; + m_ambientMapOffset = texture_offset; } -void KRMaterial::setDiffuseMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset) { - m_diffuseMap = texture_name; - m_diffuseMapScale = texture_scale; - m_diffuseMapOffset = texture_offset; +void KRMaterial::setDiffuseMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset) +{ + m_diffuseMap = texture_name; + m_diffuseMapScale = texture_scale; + m_diffuseMapOffset = texture_offset; } -void KRMaterial::setSpecularMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset) { - m_specularMap = texture_name; - m_specularMapScale = texture_scale; - m_specularMapOffset = texture_offset; +void KRMaterial::setSpecularMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset) +{ + m_specularMap = texture_name; + m_specularMapScale = texture_scale; + m_specularMapOffset = texture_offset; } -void KRMaterial::setNormalMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset) { - m_normalMap = texture_name; - m_normalMapScale = texture_scale; - m_normalMapOffset = texture_offset; +void KRMaterial::setNormalMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset) +{ + m_normalMap = texture_name; + m_normalMapScale = texture_scale; + m_normalMapOffset = texture_offset; } -void KRMaterial::setReflectionMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset) { - m_reflectionMap = texture_name; - m_reflectionMapScale = texture_scale; - m_reflectionMapOffset = texture_offset; +void KRMaterial::setReflectionMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset) +{ + m_reflectionMap = texture_name; + m_reflectionMapScale = texture_scale; + m_reflectionMapOffset = texture_offset; } -void KRMaterial::setReflectionCube(std::string texture_name) { - m_reflectionCube = texture_name; +void KRMaterial::setReflectionCube(std::string texture_name) +{ + m_reflectionCube = texture_name; } -void KRMaterial::setAlphaMode(KRMaterial::alpha_mode_type alpha_mode) { - m_alpha_mode = alpha_mode; +void KRMaterial::setAlphaMode(KRMaterial::alpha_mode_type alpha_mode) +{ + m_alpha_mode = alpha_mode; } -KRMaterial::alpha_mode_type KRMaterial::getAlphaMode() { - return m_alpha_mode; +KRMaterial::alpha_mode_type KRMaterial::getAlphaMode() +{ + return m_alpha_mode; } -void KRMaterial::setAmbient(const Vector3 &c) { - m_ambientColor = c; +void KRMaterial::setAmbient(const Vector3& c) +{ + m_ambientColor = c; } -void KRMaterial::setDiffuse(const Vector3 &c) { - m_diffuseColor = c; +void KRMaterial::setDiffuse(const Vector3& c) +{ + m_diffuseColor = c; } -void KRMaterial::setSpecular(const Vector3 &c) { - m_specularColor = c; +void KRMaterial::setSpecular(const Vector3& c) +{ + m_specularColor = c; } -void KRMaterial::setReflection(const Vector3 &c) { - m_reflectionColor = c; +void KRMaterial::setReflection(const Vector3& c) +{ + m_reflectionColor = c; } -void KRMaterial::setTransparency(float a) { - if(a < 1.0f && m_alpha_mode == KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE) { - setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE); - } - m_tr = a; +void KRMaterial::setTransparency(float a) +{ + if (a < 1.0f && m_alpha_mode == KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE) { + setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE); + } + m_tr = a; } -void KRMaterial::setShininess(float s) { - m_ns = s; +void KRMaterial::setShininess(float s) +{ + m_ns = s; } -bool KRMaterial::isTransparent() { - return m_tr < 1.0 || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE; +bool KRMaterial::isTransparent() +{ + return m_tr < 1.0 || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE; } void KRMaterial::preStream(float lodCoverage) { - getTextures(); - - if(m_pAmbientMap) { - m_pAmbientMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_AMBIENT_MAP); - } - - if(m_pDiffuseMap) { - m_pDiffuseMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP); - } - - if(m_pNormalMap) { - m_pNormalMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP); - } - - if(m_pSpecularMap) { - m_pSpecularMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP); - } - - if(m_pReflectionMap) { - m_pReflectionMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP); - } - - if(m_pReflectionCube) { - m_pReflectionCube->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE); - } + getTextures(); + + if (m_pAmbientMap) { + m_pAmbientMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_AMBIENT_MAP); + } + + if (m_pDiffuseMap) { + m_pDiffuseMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP); + } + + if (m_pNormalMap) { + m_pNormalMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP); + } + + if (m_pSpecularMap) { + m_pSpecularMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP); + } + + if (m_pReflectionMap) { + m_pReflectionMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP); + } + + if (m_pReflectionCube) { + m_pReflectionCube->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE); + } } kraken_stream_level KRMaterial::getStreamLevel() { - kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; - - getTextures(); - - if(m_pAmbientMap) { - stream_level = KRMIN(stream_level, m_pAmbientMap->getStreamLevel(KRTexture::TEXTURE_USAGE_AMBIENT_MAP)); - } + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; - if(m_pDiffuseMap) { - stream_level = KRMIN(stream_level, m_pDiffuseMap->getStreamLevel(KRTexture::TEXTURE_USAGE_DIFFUSE_MAP)); - } + getTextures(); - if(m_pNormalMap) { - stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(KRTexture::TEXTURE_USAGE_NORMAL_MAP)); - } + if (m_pAmbientMap) { + stream_level = KRMIN(stream_level, m_pAmbientMap->getStreamLevel(KRTexture::TEXTURE_USAGE_AMBIENT_MAP)); + } - if(m_pSpecularMap) { - stream_level = KRMIN(stream_level, m_pSpecularMap->getStreamLevel(KRTexture::TEXTURE_USAGE_SPECULAR_MAP)); - } + if (m_pDiffuseMap) { + stream_level = KRMIN(stream_level, m_pDiffuseMap->getStreamLevel(KRTexture::TEXTURE_USAGE_DIFFUSE_MAP)); + } - if(m_pReflectionMap) { - stream_level = KRMIN(stream_level, m_pReflectionMap->getStreamLevel(KRTexture::TEXTURE_USAGE_REFLECTION_MAP)); - } + if (m_pNormalMap) { + stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(KRTexture::TEXTURE_USAGE_NORMAL_MAP)); + } - if(m_pReflectionCube) { - stream_level = KRMIN(stream_level, m_pReflectionCube->getStreamLevel(KRTexture::TEXTURE_USAGE_REFECTION_CUBE)); - } - - return stream_level; + if (m_pSpecularMap) { + stream_level = KRMIN(stream_level, m_pSpecularMap->getStreamLevel(KRTexture::TEXTURE_USAGE_SPECULAR_MAP)); + } + + if (m_pReflectionMap) { + stream_level = KRMIN(stream_level, m_pReflectionMap->getStreamLevel(KRTexture::TEXTURE_USAGE_REFLECTION_MAP)); + } + + if (m_pReflectionCube) { + stream_level = KRMIN(stream_level, m_pReflectionCube->getStreamLevel(KRTexture::TEXTURE_USAGE_REFECTION_CUBE)); + } + + return stream_level; } void KRMaterial::getTextures() { - if(!m_pAmbientMap && m_ambientMap.size()) { - m_pAmbientMap = getContext().getTextureManager()->getTexture(m_ambientMap); - } - if(!m_pDiffuseMap && m_diffuseMap.size()) { - m_pDiffuseMap = getContext().getTextureManager()->getTexture(m_diffuseMap); - } - if(!m_pNormalMap && m_normalMap.size()) { - m_pNormalMap = getContext().getTextureManager()->getTexture(m_normalMap); - } - if(!m_pSpecularMap && m_specularMap.size()) { - m_pSpecularMap = getContext().getTextureManager()->getTexture(m_specularMap); - } - if(!m_pReflectionMap && m_reflectionMap.size()) { - m_pReflectionMap = getContext().getTextureManager()->getTexture(m_reflectionMap); - } - if(!m_pReflectionCube && m_reflectionCube.size()) { - m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str()); - } + if (!m_pAmbientMap && m_ambientMap.size()) { + m_pAmbientMap = getContext().getTextureManager()->getTexture(m_ambientMap); + } + if (!m_pDiffuseMap && m_diffuseMap.size()) { + m_pDiffuseMap = getContext().getTextureManager()->getTexture(m_diffuseMap); + } + if (!m_pNormalMap && m_normalMap.size()) { + m_pNormalMap = getContext().getTextureManager()->getTexture(m_normalMap); + } + if (!m_pSpecularMap && m_specularMap.size()) { + m_pSpecularMap = getContext().getTextureManager()->getTexture(m_specularMap); + } + if (!m_pReflectionMap && m_reflectionMap.size()) { + m_pReflectionMap = getContext().getTextureManager()->getTexture(m_reflectionMap); + } + if (!m_pReflectionCube && m_reflectionCube.size()) { + m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str()); + } } -void KRMaterial::bind(const KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector &bones, const std::vector &bind_poses, const Matrix4 &matModel, KRTexture *pLightMap, const Vector3 &rim_color, float rim_power, float lod_coverage) +void KRMaterial::bind(const KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector& bones, const std::vector& bind_poses, const Matrix4& matModel, KRTexture* pLightMap, const Vector3& rim_color, float rim_power, float lod_coverage) { - bool bLightMap = pLightMap && ri.camera->settings.bEnableLightMap; - - getTextures(); - - Vector2 default_scale = Vector2::One(); - Vector2 default_offset = Vector2::Zero(); - - bool bHasReflection = m_reflectionColor != Vector3::Zero(); - bool bDiffuseMap = m_pDiffuseMap != NULL && ri.camera->settings.bEnableDiffuseMap; - bool bNormalMap = m_pNormalMap != NULL && ri.camera->settings.bEnableNormalMap; - bool bSpecMap = m_pSpecularMap != NULL && ri.camera->settings.bEnableSpecMap; - bool bReflectionMap = m_pReflectionMap != NULL && ri.camera->settings.bEnableReflectionMap && ri.camera->settings.bEnableReflection && bHasReflection; - bool bReflectionCubeMap = m_pReflectionCube != NULL && ri.camera->settings.bEnableReflection && bHasReflection; - bool bAlphaTest = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_TEST) && bDiffuseMap; - bool bAlphaBlend = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE) || (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); - - PipelineInfo info{}; - std::string shader_name("ObjectShader"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.bone_count = (int)bones.size(); - info.renderPass = ri.renderPass; - info.bDiffuseMap = bDiffuseMap; - info.bNormalMap = bNormalMap; - info.bSpecMap = bSpecMap; - info.bReflectionMap = bReflectionMap; - info.bReflectionCubeMap = bReflectionCubeMap; - info.bLightMap = bLightMap; - info.bDiffuseMapScale = m_diffuseMapScale != default_scale && bDiffuseMap; - info.bSpecMapScale = m_specularMapScale != default_scale && bSpecMap; - info.bNormalMapScale = m_normalMapScale != default_scale && bNormalMap; - info.bReflectionMapScale = m_reflectionMapScale != default_scale && bReflectionMap; - info.bDiffuseMapOffset = m_diffuseMapOffset != default_offset && bDiffuseMap; - info.bSpecMapOffset = m_specularMapOffset != default_offset && bSpecMap; - info.bNormalMapOffset = m_normalMapOffset != default_offset && bNormalMap; - info.bReflectionMapOffset = m_reflectionMapOffset != default_offset && bReflectionMap; - info.bAlphaTest = bAlphaTest; - info.rasterMode = bAlphaBlend ? RasterMode::kAlphaBlend : RasterMode::kOpaque; - info.bRimColor = rim_power != 0.0f; - info.renderPass = ri.renderPass; - info.modelFormat = modelFormat; - info.vertexAttributes = vertexAttributes; - info.cullMode = cullMode; - KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + bool bLightMap = pLightMap && ri.camera->settings.bEnableLightMap; - // Rim highlighting parameters - pShader->setUniform(KRPipeline::Uniform::rim_color, rim_color); - pShader->setUniform(KRPipeline::Uniform::rim_power, rim_power); - - // Bind bones - if(pShader->hasUniform(KRPipeline::Uniform::bone_transforms)) { - float bone_mats[256 * 16]; - float *bone_mat_component = bone_mats; - for(int bone_index=0; bone_index < bones.size(); bone_index++) { - KRBone *bone = bones[bone_index]; - -// Vector3 initialRotation = bone->getInitialLocalRotation(); -// Vector3 rotation = bone->getLocalRotation(); -// Vector3 initialTranslation = bone->getInitialLocalTranslation(); -// Vector3 translation = bone->getLocalTranslation(); -// Vector3 initialScale = bone->getInitialLocalScale(); -// Vector3 scale = bone->getLocalScale(); -// - //printf("%s - delta rotation: %.4f %.4f %.4f\n", bone->getName().c_str(), (rotation.x - initialRotation.x) * 180.0 / M_PI, (rotation.y - initialRotation.y) * 180.0 / M_PI, (rotation.z - initialRotation.z) * 180.0 / M_PI); - //printf("%s - delta translation: %.4f %.4f %.4f\n", bone->getName().c_str(), translation.x - initialTranslation.x, translation.y - initialTranslation.y, translation.z - initialTranslation.z); -// printf("%s - delta scale: %.4f %.4f %.4f\n", bone->getName().c_str(), scale.x - initialScale.x, scale.y - initialScale.y, scale.z - initialScale.z); - - Matrix4 skin_bone_bind_pose = bind_poses[bone_index]; - Matrix4 active_mat = bone->getActivePoseMatrix(); - Matrix4 inv_bind_mat = bone->getInverseBindPoseMatrix(); - Matrix4 inv_bind_mat2 = Matrix4::Invert(bind_poses[bone_index]); - Matrix4 t = (inv_bind_mat * active_mat); - Matrix4 t2 = inv_bind_mat2 * bone->getModelMatrix(); - for(int i=0; i < 16; i++) { - *bone_mat_component++ = t[i]; - } - } - if(pShader->hasUniform(KRPipeline::Uniform::bone_transforms)) { - pShader->setUniform(KRPipeline::Uniform::bone_transforms, (Matrix4*)bone_mats, bones.size()); - } - } + getTextures(); - - pShader->setUniform(KRPipeline::Uniform::material_ambient, m_ambientColor + ri.camera->settings.ambient_intensity); - - if(ri.renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { - // We pre-multiply the light color with the material color in the forward renderer - pShader->setUniform(KRPipeline::Uniform::material_diffuse, Vector3::Create(m_diffuseColor.x * ri.camera->settings.light_intensity.x, m_diffuseColor.y * ri.camera->settings.light_intensity.y, m_diffuseColor.z * ri.camera->settings.light_intensity.z)); - } else { - pShader->setUniform(KRPipeline::Uniform::material_diffuse, m_diffuseColor); - } - - if(ri.renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { - // We pre-multiply the light color with the material color in the forward renderer - pShader->setUniform(KRPipeline::Uniform::material_specular, Vector3::Create(m_specularColor.x * ri.camera->settings.light_intensity.x, m_specularColor.y * ri.camera->settings.light_intensity.y, m_specularColor.z * ri.camera->settings.light_intensity.z)); - } else { - pShader->setUniform(KRPipeline::Uniform::material_specular, m_specularColor); - } - - pShader->setUniform(KRPipeline::Uniform::material_shininess, m_ns); - pShader->setUniform(KRPipeline::Uniform::material_reflection, m_reflectionColor); - pShader->setUniform(KRPipeline::Uniform::diffusetexture_scale, m_diffuseMapScale); - pShader->setUniform(KRPipeline::Uniform::speculartexture_scale, m_specularMapScale); - pShader->setUniform(KRPipeline::Uniform::reflectiontexture_scale, m_reflectionMapScale); - pShader->setUniform(KRPipeline::Uniform::normaltexture_scale, m_normalMapScale); - pShader->setUniform(KRPipeline::Uniform::diffusetexture_offset, m_diffuseMapOffset); - pShader->setUniform(KRPipeline::Uniform::speculartexture_offset, m_specularMapOffset); - pShader->setUniform(KRPipeline::Uniform::reflectiontexture_offset, m_reflectionMapOffset); - pShader->setUniform(KRPipeline::Uniform::normaltexture_offset, m_normalMapOffset); + Vector2 default_scale = Vector2::One(); + Vector2 default_offset = Vector2::Zero(); - pShader->setUniform(KRPipeline::Uniform::material_alpha, m_tr); - - if(bDiffuseMap) { - m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap, lod_coverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP); - } - - if(bSpecMap) { - m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap, lod_coverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP); - } + bool bHasReflection = m_reflectionColor != Vector3::Zero(); + bool bDiffuseMap = m_pDiffuseMap != NULL && ri.camera->settings.bEnableDiffuseMap; + bool bNormalMap = m_pNormalMap != NULL && ri.camera->settings.bEnableNormalMap; + bool bSpecMap = m_pSpecularMap != NULL && ri.camera->settings.bEnableSpecMap; + bool bReflectionMap = m_pReflectionMap != NULL && ri.camera->settings.bEnableReflectionMap && ri.camera->settings.bEnableReflection && bHasReflection; + bool bReflectionCubeMap = m_pReflectionCube != NULL && ri.camera->settings.bEnableReflection && bHasReflection; + bool bAlphaTest = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_TEST) && bDiffuseMap; + bool bAlphaBlend = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE) || (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); - if(bNormalMap) { - m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap, lod_coverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP); - } - - if(bReflectionCubeMap && (ri.renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || ri.renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { - m_pContext->getTextureManager()->selectTexture(4, m_pReflectionCube, lod_coverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE); - } - - if(bReflectionMap && (ri.renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || ri.renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { - // GL_TEXTURE7 is used for reading the depth buffer in gBuffer pass 2 and re-used for the reflection map in gBuffer Pass 3 and in forward rendering - m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap, lod_coverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP); - } + PipelineInfo info{}; + std::string shader_name("ObjectShader"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.bone_count = (int)bones.size(); + info.renderPass = ri.renderPass; + info.bDiffuseMap = bDiffuseMap; + info.bNormalMap = bNormalMap; + info.bSpecMap = bSpecMap; + info.bReflectionMap = bReflectionMap; + info.bReflectionCubeMap = bReflectionCubeMap; + info.bLightMap = bLightMap; + info.bDiffuseMapScale = m_diffuseMapScale != default_scale && bDiffuseMap; + info.bSpecMapScale = m_specularMapScale != default_scale && bSpecMap; + info.bNormalMapScale = m_normalMapScale != default_scale && bNormalMap; + info.bReflectionMapScale = m_reflectionMapScale != default_scale && bReflectionMap; + info.bDiffuseMapOffset = m_diffuseMapOffset != default_offset && bDiffuseMap; + info.bSpecMapOffset = m_specularMapOffset != default_offset && bSpecMap; + info.bNormalMapOffset = m_normalMapOffset != default_offset && bNormalMap; + info.bReflectionMapOffset = m_reflectionMapOffset != default_offset && bReflectionMap; + info.bAlphaTest = bAlphaTest; + info.rasterMode = bAlphaBlend ? RasterMode::kAlphaBlend : RasterMode::kOpaque; + info.bRimColor = rim_power != 0.0f; + info.renderPass = ri.renderPass; + info.modelFormat = modelFormat; + info.vertexAttributes = vertexAttributes; + info.cullMode = cullMode; + KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, matModel, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + // Rim highlighting parameters + pShader->setUniform(KRPipeline::Uniform::rim_color, rim_color); + pShader->setUniform(KRPipeline::Uniform::rim_power, rim_power); + + // Bind bones + if (pShader->hasUniform(KRPipeline::Uniform::bone_transforms)) { + float bone_mats[256 * 16]; + float* bone_mat_component = bone_mats; + for (int bone_index = 0; bone_index < bones.size(); bone_index++) { + KRBone* bone = bones[bone_index]; + + // Vector3 initialRotation = bone->getInitialLocalRotation(); + // Vector3 rotation = bone->getLocalRotation(); + // Vector3 initialTranslation = bone->getInitialLocalTranslation(); + // Vector3 translation = bone->getLocalTranslation(); + // Vector3 initialScale = bone->getInitialLocalScale(); + // Vector3 scale = bone->getLocalScale(); + // + //printf("%s - delta rotation: %.4f %.4f %.4f\n", bone->getName().c_str(), (rotation.x - initialRotation.x) * 180.0 / M_PI, (rotation.y - initialRotation.y) * 180.0 / M_PI, (rotation.z - initialRotation.z) * 180.0 / M_PI); + //printf("%s - delta translation: %.4f %.4f %.4f\n", bone->getName().c_str(), translation.x - initialTranslation.x, translation.y - initialTranslation.y, translation.z - initialTranslation.z); + // printf("%s - delta scale: %.4f %.4f %.4f\n", bone->getName().c_str(), scale.x - initialScale.x, scale.y - initialScale.y, scale.z - initialScale.z); + + Matrix4 skin_bone_bind_pose = bind_poses[bone_index]; + Matrix4 active_mat = bone->getActivePoseMatrix(); + Matrix4 inv_bind_mat = bone->getInverseBindPoseMatrix(); + Matrix4 inv_bind_mat2 = Matrix4::Invert(bind_poses[bone_index]); + Matrix4 t = (inv_bind_mat * active_mat); + Matrix4 t2 = inv_bind_mat2 * bone->getModelMatrix(); + for (int i = 0; i < 16; i++) { + *bone_mat_component++ = t[i]; + } + } + if (pShader->hasUniform(KRPipeline::Uniform::bone_transforms)) { + pShader->setUniform(KRPipeline::Uniform::bone_transforms, (Matrix4*)bone_mats, bones.size()); + } + } + + + pShader->setUniform(KRPipeline::Uniform::material_ambient, m_ambientColor + ri.camera->settings.ambient_intensity); + + if (ri.renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { + // We pre-multiply the light color with the material color in the forward renderer + pShader->setUniform(KRPipeline::Uniform::material_diffuse, Vector3::Create(m_diffuseColor.x * ri.camera->settings.light_intensity.x, m_diffuseColor.y * ri.camera->settings.light_intensity.y, m_diffuseColor.z * ri.camera->settings.light_intensity.z)); + } else { + pShader->setUniform(KRPipeline::Uniform::material_diffuse, m_diffuseColor); + } + + if (ri.renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { + // We pre-multiply the light color with the material color in the forward renderer + pShader->setUniform(KRPipeline::Uniform::material_specular, Vector3::Create(m_specularColor.x * ri.camera->settings.light_intensity.x, m_specularColor.y * ri.camera->settings.light_intensity.y, m_specularColor.z * ri.camera->settings.light_intensity.z)); + } else { + pShader->setUniform(KRPipeline::Uniform::material_specular, m_specularColor); + } + + pShader->setUniform(KRPipeline::Uniform::material_shininess, m_ns); + pShader->setUniform(KRPipeline::Uniform::material_reflection, m_reflectionColor); + pShader->setUniform(KRPipeline::Uniform::diffusetexture_scale, m_diffuseMapScale); + pShader->setUniform(KRPipeline::Uniform::speculartexture_scale, m_specularMapScale); + pShader->setUniform(KRPipeline::Uniform::reflectiontexture_scale, m_reflectionMapScale); + pShader->setUniform(KRPipeline::Uniform::normaltexture_scale, m_normalMapScale); + pShader->setUniform(KRPipeline::Uniform::diffusetexture_offset, m_diffuseMapOffset); + pShader->setUniform(KRPipeline::Uniform::speculartexture_offset, m_specularMapOffset); + pShader->setUniform(KRPipeline::Uniform::reflectiontexture_offset, m_reflectionMapOffset); + pShader->setUniform(KRPipeline::Uniform::normaltexture_offset, m_normalMapOffset); + + pShader->setUniform(KRPipeline::Uniform::material_alpha, m_tr); + + if (bDiffuseMap) { + m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap, lod_coverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP); + } + + if (bSpecMap) { + m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap, lod_coverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP); + } + + if (bNormalMap) { + m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap, lod_coverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP); + } + + if (bReflectionCubeMap && (ri.renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || ri.renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { + m_pContext->getTextureManager()->selectTexture(4, m_pReflectionCube, lod_coverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE); + } + + if (bReflectionMap && (ri.renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || ri.renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { + // GL_TEXTURE7 is used for reading the depth buffer in gBuffer pass 2 and re-used for the reflection map in gBuffer Pass 3 and in forward rendering + m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap, lod_coverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP); + } + + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, matModel, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); } -const std::string &KRMaterial::getName() const +const std::string& KRMaterial::getName() const { - return m_name; + return m_name; } diff --git a/kraken/KRMaterial.h b/kraken/KRMaterial.h index d01097d..7d75dc6 100755 --- a/kraken/KRMaterial.h +++ b/kraken/KRMaterial.h @@ -50,89 +50,91 @@ class KRTextureManager; class KRContext; class KRSurface; -class KRMaterial : public KRResource { +class KRMaterial : public KRResource +{ public: - typedef enum { - KRMATERIAL_ALPHA_MODE_OPAQUE, // Non-transparent materials - KRMATERIAL_ALPHA_MODE_TEST, // Alpha in diffuse texture is interpreted as punch-through when < 0.5 - KRMATERIAL_ALPHA_MODE_BLENDONESIDE, // Blended alpha with backface culling - KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces. - } alpha_mode_type; - - KRMaterial(KRContext &context, const char *szName); - virtual ~KRMaterial(); - - virtual std::string getExtension(); - virtual bool save(KRDataBlock &data); - - - void setAmbientMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset); - void setDiffuseMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset); - void setSpecularMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset); - void setReflectionMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset); - void setReflectionCube(std::string texture_name); - void setNormalMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset); - void setAmbient(const Vector3 &c); - void setDiffuse(const Vector3 &c); - void setSpecular(const Vector3 &c); - void setReflection(const Vector3 &c); - void setTransparency(float a); - void setShininess(float s); - void setAlphaMode(alpha_mode_type blend_mode); - alpha_mode_type getAlphaMode(); - + typedef enum + { + KRMATERIAL_ALPHA_MODE_OPAQUE, // Non-transparent materials + KRMATERIAL_ALPHA_MODE_TEST, // Alpha in diffuse texture is interpreted as punch-through when < 0.5 + KRMATERIAL_ALPHA_MODE_BLENDONESIDE, // Blended alpha with backface culling + KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces. + } alpha_mode_type; + + KRMaterial(KRContext& context, const char* szName); + virtual ~KRMaterial(); + + virtual std::string getExtension(); + virtual bool save(KRDataBlock& data); + + + void setAmbientMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset); + void setDiffuseMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset); + void setSpecularMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset); + void setReflectionMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset); + void setReflectionCube(std::string texture_name); + void setNormalMap(std::string texture_name, Vector2 texture_scale, Vector2 texture_offset); + void setAmbient(const Vector3& c); + void setDiffuse(const Vector3& c); + void setSpecular(const Vector3& c); + void setReflection(const Vector3& c); + void setTransparency(float a); + void setShininess(float s); + void setAlphaMode(alpha_mode_type blend_mode); + alpha_mode_type getAlphaMode(); + + + bool isTransparent(); + const std::string& getName() const; + + void bind(const KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector& bones, const std::vector& bind_poses, const Matrix4& matModel, KRTexture* pLightMap, const Vector3& rim_color, float rim_power, float lod_coverage = 0.0f); + + bool needsVertexTangents(); + + kraken_stream_level getStreamLevel(); + void preStream(float lodCoverage); - bool isTransparent(); - const std::string &getName() const; - - void bind(const KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector& bones, const std::vector& bind_poses, const Matrix4& matModel, KRTexture* pLightMap, const Vector3& rim_color, float rim_power, float lod_coverage = 0.0f); - - bool needsVertexTangents(); - - kraken_stream_level getStreamLevel(); - void preStream(float lodCoverage); - private: - std::string m_name; - - KRTexture *m_pAmbientMap; // mtl map_Ka value - KRTexture *m_pDiffuseMap; // mtl map_Kd value - KRTexture *m_pSpecularMap; // mtl map_Ks value - KRTexture *m_pReflectionMap; // mtl refl value - KRTexture *m_pReflectionCube; - KRTexture *m_pNormalMap; // mtl map_Normal value - std::string m_ambientMap; - std::string m_diffuseMap; - std::string m_specularMap; - std::string m_reflectionMap; - std::string m_reflectionCube; - std::string m_normalMap; - - Vector2 m_ambientMapScale; - Vector2 m_ambientMapOffset; - Vector2 m_diffuseMapScale; - Vector2 m_diffuseMapOffset; - Vector2 m_specularMapScale; - Vector2 m_specularMapOffset; - Vector2 m_reflectionMapScale; - Vector2 m_reflectionMapOffset; - Vector2 m_normalMapScale; - Vector2 m_normalMapOffset; - - Vector3 m_ambientColor; // Ambient rgb - Vector3 m_diffuseColor; // Diffuse rgb - Vector3 m_specularColor; // Specular rgb - Vector3 m_reflectionColor; // Reflection rgb - - //float m_ka_r, m_ka_g, m_ka_b; // Ambient rgb - //float m_kd_r, m_kd_g, m_kd_b; // Diffuse rgb - //float m_ks_r, m_ks_g, m_ks_b; // Specular rgb - //float m_kr_r, m_kr_g, m_kr_b; // Reflection rgb - - float m_tr; // Transparency - float m_ns; // Shininess - - alpha_mode_type m_alpha_mode; - - void getTextures(); + std::string m_name; + + KRTexture* m_pAmbientMap; // mtl map_Ka value + KRTexture* m_pDiffuseMap; // mtl map_Kd value + KRTexture* m_pSpecularMap; // mtl map_Ks value + KRTexture* m_pReflectionMap; // mtl refl value + KRTexture* m_pReflectionCube; + KRTexture* m_pNormalMap; // mtl map_Normal value + std::string m_ambientMap; + std::string m_diffuseMap; + std::string m_specularMap; + std::string m_reflectionMap; + std::string m_reflectionCube; + std::string m_normalMap; + + Vector2 m_ambientMapScale; + Vector2 m_ambientMapOffset; + Vector2 m_diffuseMapScale; + Vector2 m_diffuseMapOffset; + Vector2 m_specularMapScale; + Vector2 m_specularMapOffset; + Vector2 m_reflectionMapScale; + Vector2 m_reflectionMapOffset; + Vector2 m_normalMapScale; + Vector2 m_normalMapOffset; + + Vector3 m_ambientColor; // Ambient rgb + Vector3 m_diffuseColor; // Diffuse rgb + Vector3 m_specularColor; // Specular rgb + Vector3 m_reflectionColor; // Reflection rgb + + //float m_ka_r, m_ka_g, m_ka_b; // Ambient rgb + //float m_kd_r, m_kd_g, m_kd_b; // Diffuse rgb + //float m_ks_r, m_ks_g, m_ks_b; // Specular rgb + //float m_kr_r, m_kr_g, m_kr_b; // Reflection rgb + + float m_tr; // Transparency + float m_ns; // Shininess + + alpha_mode_type m_alpha_mode; + + void getTextures(); }; diff --git a/kraken/KRMaterialManager.cpp b/kraken/KRMaterialManager.cpp index 9da005f..7b0e65d 100755 --- a/kraken/KRMaterialManager.cpp +++ b/kraken/KRMaterialManager.cpp @@ -33,13 +33,14 @@ #include "KRMaterialManager.h" -KRMaterialManager::KRMaterialManager(KRContext &context, KRTextureManager *pTextureManager, KRPipelineManager *pPipelineManager) : KRResourceManager(context) +KRMaterialManager::KRMaterialManager(KRContext& context, KRTextureManager* pTextureManager, KRPipelineManager* pPipelineManager) : KRResourceManager(context) { - m_pTextureManager = pTextureManager; - m_pPipelineManager = pPipelineManager; + m_pTextureManager = pTextureManager; + m_pPipelineManager = pPipelineManager; } -KRMaterialManager::~KRMaterialManager() { +KRMaterialManager::~KRMaterialManager() +{ } @@ -62,222 +63,225 @@ KRResource* KRMaterialManager::getResource(const std::string& name, const std::s return nullptr; } -unordered_map &KRMaterialManager::getMaterials() +unordered_map& KRMaterialManager::getMaterials() { - return m_materials; -} + return m_materials; +} -KRMaterial *KRMaterialManager::getMaterial(const std::string &name) { - std::string lowerName = name; - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - - - unordered_map::iterator itr = m_materials.find(lowerName); - if(itr == m_materials.end()) { - KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Material not found: %s", name.c_str()); - // Not found - return NULL; +KRMaterial* KRMaterialManager::getMaterial(const std::string& name) +{ + std::string lowerName = name; + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + + + unordered_map::iterator itr = m_materials.find(lowerName); + if (itr == m_materials.end()) { + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Material not found: %s", name.c_str()); + // Not found + return NULL; + } else { + return (*itr).second; + } +} + +void KRMaterialManager::add(KRMaterial* new_material) +{ + // FINDME, TODO - Potential memory leak if multiple materials with the same name are added + std::string lowerName = new_material->getName(); + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + + m_materials[lowerName] = new_material; +} + +KRMaterial* KRMaterialManager::load(const char* szName, KRDataBlock* data) +{ + KRMaterial* pMaterial = NULL; + char szSymbol[16][256]; + data->lock(); + + char* pScan = (char*)data->getStart(); + char* pEnd = (char*)data->getEnd(); + while (pScan < pEnd) { + + // Scan through whitespace + while (pScan < pEnd && (*pScan == ' ' || *pScan == '\t' || *pScan == '\r' || *pScan == '\n')) { + pScan++; + } + + if (*pScan == '#') { + // Line is a comment line + + // Scan to the end of the line + while (pScan < pEnd && *pScan != '\r' && *pScan != '\n') { + pScan++; + } } else { - return (*itr).second; - } -} + int cSymbols = 0; + while (pScan < pEnd && *pScan != '\n' && *pScan != '\r') { -void KRMaterialManager::add(KRMaterial *new_material) { - // FINDME, TODO - Potential memory leak if multiple materials with the same name are added - std::string lowerName = new_material->getName(); - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - - m_materials[lowerName] = new_material; -} - -KRMaterial* KRMaterialManager::load(const char *szName, KRDataBlock *data) { - KRMaterial *pMaterial = NULL; - char szSymbol[16][256]; - data->lock(); - - char *pScan = (char *)data->getStart(); - char *pEnd = (char *)data->getEnd(); - while(pScan < pEnd) { - - // Scan through whitespace - while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t' || *pScan == '\r' || *pScan == '\n')) { - pScan++; + char* pDest = szSymbol[cSymbols++]; + while (pScan < pEnd && *pScan != ' ' && *pScan != '\n' && *pScan != '\r') { + if (*pScan >= 'A' && *pScan <= 'Z') { + *pDest++ = *pScan++ + 'a' - 'A'; // convert to lower case for case sensitve comparison later + } else { + *pDest++ = *pScan++; + } } - - if(*pScan == '#') { - // Line is a comment line - - // Scan to the end of the line - while(pScan < pEnd && *pScan != '\r' && *pScan != '\n') { - pScan++; - } - } else { - int cSymbols = 0; - while(pScan < pEnd && *pScan != '\n' && *pScan != '\r') { - - char *pDest = szSymbol[cSymbols++]; - while(pScan < pEnd && *pScan != ' ' && *pScan != '\n' && *pScan != '\r') { - if(*pScan >= 'A' && *pScan <= 'Z') { - *pDest++ = *pScan++ + 'a' - 'A'; // convert to lower case for case sensitve comparison later - } else { - *pDest++ = *pScan++; - } - } - *pDest = '\0'; - - // Scan through whitespace, but don't advance to next line - while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t')) { - pScan++; - } - } - - if(cSymbols > 0) { - - if(strcmp(szSymbol[0], "newmtl") == 0 && cSymbols >= 2) { - - pMaterial = new KRMaterial(*m_pContext, szSymbol[1]); - m_materials[szSymbol[1]] = pMaterial; - } - if(pMaterial != NULL) { - if(strcmp(szSymbol[0], "alpha_mode") == 0) { - if(cSymbols == 2) { - if(strcmp(szSymbol[1], "test") == 0) { - pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_TEST); - } else if(strcmp(szSymbol[1], "blendoneside") == 0) { - pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE); - } else if(strcmp(szSymbol[1], "blendtwoside") == 0) { - pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); - } else { - pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE); - } - } - } else if(strcmp(szSymbol[0], "ka") == 0) { - char *pScan2 = szSymbol[1]; - float r = strtof(pScan2, &pScan2); - if(cSymbols == 2) { - pMaterial->setAmbient(Vector3::Create(r, r, r)); - } else if(cSymbols == 4) { - pScan2 = szSymbol[2]; - float g = strtof(pScan2, &pScan2); - pScan2 = szSymbol[3]; - float b = strtof(pScan2, &pScan2); - pMaterial->setAmbient(Vector3::Create(r, g, b)); - } - } else if(strcmp(szSymbol[0], "kd") == 0) { - char *pScan2 = szSymbol[1]; - float r = strtof(pScan2, &pScan2); - if(cSymbols == 2) { - pMaterial->setDiffuse(Vector3::Create(r, r, r)); - } else if(cSymbols == 4) { - pScan2 = szSymbol[2]; - float g = strtof(pScan2, &pScan2); - pScan2 = szSymbol[3]; - float b = strtof(pScan2, &pScan2); - pMaterial->setDiffuse(Vector3::Create(r, g, b)); - } - } else if(strcmp(szSymbol[0], "ks") == 0) { - char *pScan2 = szSymbol[1]; - float r = strtof(pScan2, &pScan2); - if(cSymbols == 2) { - pMaterial->setSpecular(Vector3::Create(r, r, r)); - } else if(cSymbols == 4) { - pScan2 = szSymbol[2]; - float g = strtof(pScan2, &pScan2); - pScan2 = szSymbol[3]; - float b = strtof(pScan2, &pScan2); - pMaterial->setSpecular(Vector3::Create(r, g, b)); - } - } else if(strcmp(szSymbol[0], "kr") == 0) { - char *pScan2 = szSymbol[1]; - float r = strtof(pScan2, &pScan2); - if(cSymbols == 2) { - pMaterial->setReflection(Vector3::Create(r, r, r)); - } else if(cSymbols == 4) { - pScan2 = szSymbol[2]; - float g = strtof(pScan2, &pScan2); - pScan2 = szSymbol[3]; - float b = strtof(pScan2, &pScan2); - pMaterial->setReflection(Vector3::Create(r, g, b)); - } - } else if(strcmp(szSymbol[0], "tr") == 0) { - char *pScan2 = szSymbol[1]; - float a = strtof(pScan2, &pScan2); - pMaterial->setTransparency(a); - } else if(strcmp(szSymbol[0], "ns") == 0) { - char *pScan2 = szSymbol[1]; - float a = strtof(pScan2, &pScan2); - pMaterial->setShininess(a); - } else if(strncmp(szSymbol[0], "map", 3) == 0) { - // Truncate file extension - char *pScan2 = szSymbol[1]; - char *pLastPeriod = NULL; - while(*pScan2 != '\0') { - if(*pScan2 == '.') { - pLastPeriod = pScan2; - } - pScan2++; - } - if(pLastPeriod) { - *pLastPeriod = '\0'; - } + *pDest = '\0'; - Vector2 texture_scale = Vector2::Create(1.0f, 1.0f); - Vector2 texture_offset = Vector2::Create(0.0f, 0.0f); - - int iScanSymbol = 2; - int iScaleParam = -1; - int iOffsetParam = -1; - while(iScanSymbol < cSymbols) { - if(strcmp(szSymbol[iScanSymbol], "-s") == 0) { - // Scale - iScaleParam = 0; - iOffsetParam = -1; - } else if(strcmp(szSymbol[iScanSymbol], "-o") == 0) { - // Offset - iOffsetParam = 0; - iScaleParam = -1; - } else { - char *pScan3 = szSymbol[iScanSymbol]; - float v = strtof(pScan3, &pScan3); - if(iScaleParam == 0) { - texture_scale.x = v; - iScaleParam++; - } else if(iScaleParam == 1) { - texture_scale.y = v; - iScaleParam++; - } else if(iOffsetParam == 0) { - texture_offset.x = v; - iOffsetParam++; - } else if(iOffsetParam == 1) { - texture_offset.y = v; - iOffsetParam++; - } - } - iScanSymbol++; - } - - if(strcmp(szSymbol[0], "map_ka") == 0) { - pMaterial->setAmbientMap(szSymbol[1], texture_scale, texture_offset); - } else if(strcmp(szSymbol[0], "map_kd") == 0) { - pMaterial->setDiffuseMap(szSymbol[1], texture_scale, texture_offset); - } else if(strcmp(szSymbol[0], "map_ks") == 0) { - pMaterial->setSpecularMap(szSymbol[1], texture_scale, texture_offset); - } else if(strcmp(szSymbol[0], "map_normal") == 0) { - pMaterial->setNormalMap(szSymbol[1], texture_scale, texture_offset); - } else if(strcmp(szSymbol[0], "map_reflection") == 0) { - pMaterial->setReflectionMap(szSymbol[1], texture_scale, texture_offset); - } else if(strcmp(szSymbol[0], "map_reflectioncube") == 0) { - pMaterial->setReflectionCube(szSymbol[1]); - } - } - } - } + // Scan through whitespace, but don't advance to next line + while (pScan < pEnd && (*pScan == ' ' || *pScan == '\t')) { + pScan++; } + } + if (cSymbols > 0) { + + if (strcmp(szSymbol[0], "newmtl") == 0 && cSymbols >= 2) { + + pMaterial = new KRMaterial(*m_pContext, szSymbol[1]); + m_materials[szSymbol[1]] = pMaterial; + } + if (pMaterial != NULL) { + if (strcmp(szSymbol[0], "alpha_mode") == 0) { + if (cSymbols == 2) { + if (strcmp(szSymbol[1], "test") == 0) { + pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_TEST); + } else if (strcmp(szSymbol[1], "blendoneside") == 0) { + pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE); + } else if (strcmp(szSymbol[1], "blendtwoside") == 0) { + pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); + } else { + pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE); + } + } + } else if (strcmp(szSymbol[0], "ka") == 0) { + char* pScan2 = szSymbol[1]; + float r = strtof(pScan2, &pScan2); + if (cSymbols == 2) { + pMaterial->setAmbient(Vector3::Create(r, r, r)); + } else if (cSymbols == 4) { + pScan2 = szSymbol[2]; + float g = strtof(pScan2, &pScan2); + pScan2 = szSymbol[3]; + float b = strtof(pScan2, &pScan2); + pMaterial->setAmbient(Vector3::Create(r, g, b)); + } + } else if (strcmp(szSymbol[0], "kd") == 0) { + char* pScan2 = szSymbol[1]; + float r = strtof(pScan2, &pScan2); + if (cSymbols == 2) { + pMaterial->setDiffuse(Vector3::Create(r, r, r)); + } else if (cSymbols == 4) { + pScan2 = szSymbol[2]; + float g = strtof(pScan2, &pScan2); + pScan2 = szSymbol[3]; + float b = strtof(pScan2, &pScan2); + pMaterial->setDiffuse(Vector3::Create(r, g, b)); + } + } else if (strcmp(szSymbol[0], "ks") == 0) { + char* pScan2 = szSymbol[1]; + float r = strtof(pScan2, &pScan2); + if (cSymbols == 2) { + pMaterial->setSpecular(Vector3::Create(r, r, r)); + } else if (cSymbols == 4) { + pScan2 = szSymbol[2]; + float g = strtof(pScan2, &pScan2); + pScan2 = szSymbol[3]; + float b = strtof(pScan2, &pScan2); + pMaterial->setSpecular(Vector3::Create(r, g, b)); + } + } else if (strcmp(szSymbol[0], "kr") == 0) { + char* pScan2 = szSymbol[1]; + float r = strtof(pScan2, &pScan2); + if (cSymbols == 2) { + pMaterial->setReflection(Vector3::Create(r, r, r)); + } else if (cSymbols == 4) { + pScan2 = szSymbol[2]; + float g = strtof(pScan2, &pScan2); + pScan2 = szSymbol[3]; + float b = strtof(pScan2, &pScan2); + pMaterial->setReflection(Vector3::Create(r, g, b)); + } + } else if (strcmp(szSymbol[0], "tr") == 0) { + char* pScan2 = szSymbol[1]; + float a = strtof(pScan2, &pScan2); + pMaterial->setTransparency(a); + } else if (strcmp(szSymbol[0], "ns") == 0) { + char* pScan2 = szSymbol[1]; + float a = strtof(pScan2, &pScan2); + pMaterial->setShininess(a); + } else if (strncmp(szSymbol[0], "map", 3) == 0) { + // Truncate file extension + char* pScan2 = szSymbol[1]; + char* pLastPeriod = NULL; + while (*pScan2 != '\0') { + if (*pScan2 == '.') { + pLastPeriod = pScan2; + } + pScan2++; + } + if (pLastPeriod) { + *pLastPeriod = '\0'; + } + + Vector2 texture_scale = Vector2::Create(1.0f, 1.0f); + Vector2 texture_offset = Vector2::Create(0.0f, 0.0f); + + int iScanSymbol = 2; + int iScaleParam = -1; + int iOffsetParam = -1; + while (iScanSymbol < cSymbols) { + if (strcmp(szSymbol[iScanSymbol], "-s") == 0) { + // Scale + iScaleParam = 0; + iOffsetParam = -1; + } else if (strcmp(szSymbol[iScanSymbol], "-o") == 0) { + // Offset + iOffsetParam = 0; + iScaleParam = -1; + } else { + char* pScan3 = szSymbol[iScanSymbol]; + float v = strtof(pScan3, &pScan3); + if (iScaleParam == 0) { + texture_scale.x = v; + iScaleParam++; + } else if (iScaleParam == 1) { + texture_scale.y = v; + iScaleParam++; + } else if (iOffsetParam == 0) { + texture_offset.x = v; + iOffsetParam++; + } else if (iOffsetParam == 1) { + texture_offset.y = v; + iOffsetParam++; + } + } + iScanSymbol++; + } + + if (strcmp(szSymbol[0], "map_ka") == 0) { + pMaterial->setAmbientMap(szSymbol[1], texture_scale, texture_offset); + } else if (strcmp(szSymbol[0], "map_kd") == 0) { + pMaterial->setDiffuseMap(szSymbol[1], texture_scale, texture_offset); + } else if (strcmp(szSymbol[0], "map_ks") == 0) { + pMaterial->setSpecularMap(szSymbol[1], texture_scale, texture_offset); + } else if (strcmp(szSymbol[0], "map_normal") == 0) { + pMaterial->setNormalMap(szSymbol[1], texture_scale, texture_offset); + } else if (strcmp(szSymbol[0], "map_reflection") == 0) { + pMaterial->setReflectionMap(szSymbol[1], texture_scale, texture_offset); + } else if (strcmp(szSymbol[0], "map_reflectioncube") == 0) { + pMaterial->setReflectionCube(szSymbol[1]); + } + } + } + } } - data->unlock(); - delete data; - return pMaterial; + + } + data->unlock(); + delete data; + return pMaterial; } diff --git a/kraken/KRMaterialManager.h b/kraken/KRMaterialManager.h index 59c2044..3c80c92 100755 --- a/kraken/KRMaterialManager.h +++ b/kraken/KRMaterialManager.h @@ -43,23 +43,24 @@ class KRMaterial; using std::map; -class KRMaterialManager : public KRResourceManager { +class KRMaterialManager : public KRResourceManager +{ public: - KRMaterialManager(KRContext &context, KRTextureManager *pTextureManager, KRPipelineManager *pPipelineManager); - virtual ~KRMaterialManager(); + KRMaterialManager(KRContext& context, KRTextureManager* pTextureManager, KRPipelineManager* pPipelineManager); + virtual ~KRMaterialManager(); + + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; + + KRMaterial* load(const char* szName, KRDataBlock* data); + void add(KRMaterial* new_material); + KRMaterial* getMaterial(const std::string& name); + + unordered_map& getMaterials(); - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - - KRMaterial* load(const char *szName, KRDataBlock *data); - void add(KRMaterial *new_material); - KRMaterial *getMaterial(const std::string &name); - - unordered_map &getMaterials(); - private: - unordered_map m_materials; - KRTextureManager *m_pTextureManager; - KRPipelineManager *m_pPipelineManager; + unordered_map m_materials; + KRTextureManager* m_pTextureManager; + KRPipelineManager* m_pPipelineManager; }; diff --git a/kraken/KRMesh.cpp b/kraken/KRMesh.cpp index 914c433..743deb7 100755 --- a/kraken/KRMesh.cpp +++ b/kraken/KRMesh.cpp @@ -39,26 +39,28 @@ #include "KRContext.h" #include "../3rdparty/forsyth/forsyth.h" -KRMesh::KRMesh(KRContext &context, std::string name) : KRResource(context, name) { - setName(name); - - m_hasTransparency = false; - m_pData = NULL; - m_pMetaData = NULL; - m_pIndexBaseData = NULL; - m_constant = false; +KRMesh::KRMesh(KRContext& context, std::string name) : KRResource(context, name) +{ + setName(name); + + m_hasTransparency = false; + m_pData = NULL; + m_pMetaData = NULL; + m_pIndexBaseData = NULL; + m_constant = false; } -KRMesh::KRMesh(KRContext &context, std::string name, KRDataBlock *data) : KRResource(context, name) { - setName(name); - - m_hasTransparency = false; - m_pData = NULL; - m_pMetaData = NULL; - m_pIndexBaseData = NULL; - m_constant = false; - - loadPack(data); +KRMesh::KRMesh(KRContext& context, std::string name, KRDataBlock* data) : KRResource(context, name) +{ + setName(name); + + m_hasTransparency = false; + m_pData = NULL; + m_pMetaData = NULL; + m_pIndexBaseData = NULL; + m_constant = false; + + loadPack(data); } @@ -83,350 +85,360 @@ void KRMesh::parseName(const std::string& name, std::string& lodBaseName, int& l } } -void KRMesh::setName(const std::string name) { +void KRMesh::setName(const std::string name) +{ parseName(name, m_lodBaseName, m_lodCoverage); m_lodCoverage = 100; m_lodBaseName = name; } -int KRMesh::GetLODCoverage(const std::string &name) +int KRMesh::GetLODCoverage(const std::string& name) { - int lod_coverage = 100; - size_t last_underscore_pos = name.find_last_of('_'); - if(last_underscore_pos != std::string::npos) { - // Found an underscore - std::string suffix = name.substr(last_underscore_pos + 1); - if(suffix.find("lod") == 0) { - std::string lod_level_string = suffix.substr(3); - char *end = NULL; - int c = (int)strtol(lod_level_string.c_str(), &end, 10); - if(c >= 0 && c <= 100 && *end == '\0') { - lod_coverage = c; - //m_lodBaseName = name.substr(0, last_underscore_pos); - } - } + int lod_coverage = 100; + size_t last_underscore_pos = name.find_last_of('_'); + if (last_underscore_pos != std::string::npos) { + // Found an underscore + std::string suffix = name.substr(last_underscore_pos + 1); + if (suffix.find("lod") == 0) { + std::string lod_level_string = suffix.substr(3); + char* end = NULL; + int c = (int)strtol(lod_level_string.c_str(), &end, 10); + if (c >= 0 && c <= 100 && *end == '\0') { + lod_coverage = c; + //m_lodBaseName = name.substr(0, last_underscore_pos); + } } - return lod_coverage; + } + return lod_coverage; } -KRMesh::~KRMesh() { - releaseData(); +KRMesh::~KRMesh() +{ + releaseData(); } -void KRMesh::releaseData() { - m_hasTransparency = false; - m_submeshes.clear(); - if(m_pIndexBaseData) { - m_pIndexBaseData->unlock(); - delete m_pIndexBaseData; - m_pIndexBaseData = NULL; - } - if(m_pMetaData) { - m_pMetaData->unlock(); - delete m_pMetaData; - m_pMetaData = NULL; - } - if(m_pData) { - delete m_pData; - m_pData = NULL; - } +void KRMesh::releaseData() +{ + m_hasTransparency = false; + m_submeshes.clear(); + if (m_pIndexBaseData) { + m_pIndexBaseData->unlock(); + delete m_pIndexBaseData; + m_pIndexBaseData = NULL; + } + if (m_pMetaData) { + m_pMetaData->unlock(); + delete m_pMetaData; + m_pMetaData = NULL; + } + if (m_pData) { + delete m_pData; + m_pData = NULL; + } } -std::string KRMesh::getExtension() { - return "krmesh"; +std::string KRMesh::getExtension() +{ + return "krmesh"; } -bool KRMesh::save(const std::string& path) { - return m_pData->save(path); +bool KRMesh::save(const std::string& path) +{ + return m_pData->save(path); } -bool KRMesh::save(KRDataBlock &data) { - data.append(*m_pData); - return true; +bool KRMesh::save(KRDataBlock& data) +{ + data.append(*m_pData); + return true; } -void KRMesh::loadPack(KRDataBlock *data) { - releaseData(); - - m_pData = data; - - pack_header ph; - m_pData->copy((void *)&ph, 0, sizeof(ph)); - m_pMetaData = m_pData->getSubBlock(0, sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count); - m_pMetaData->lock(); - - m_pIndexBaseData = m_pData->getSubBlock(sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count + KRALIGN(2 * ph.index_count), ph.index_base_count * 8); - m_pIndexBaseData->lock(); - - m_minPoint = Vector3::Create(ph.minx, ph.miny, ph.minz); - m_maxPoint = Vector3::Create(ph.maxx, ph.maxy, ph.maxz); - - updateAttributeOffsets(); +void KRMesh::loadPack(KRDataBlock* data) +{ + releaseData(); + + m_pData = data; + + pack_header ph; + m_pData->copy((void*)&ph, 0, sizeof(ph)); + m_pMetaData = m_pData->getSubBlock(0, sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count); + m_pMetaData->lock(); + + m_pIndexBaseData = m_pData->getSubBlock(sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count + KRALIGN(2 * ph.index_count), ph.index_base_count * 8); + m_pIndexBaseData->lock(); + + m_minPoint = Vector3::Create(ph.minx, ph.miny, ph.minz); + m_maxPoint = Vector3::Create(ph.maxx, ph.maxy, ph.maxz); + + updateAttributeOffsets(); } void KRMesh::getMaterials() { - if(m_materials.size() == 0) { - - for(std::vector::iterator itr = m_submeshes.begin(); itr != m_submeshes.end(); itr++) { - const char *szMaterialName = (*itr)->szMaterialName; - KRMaterial *pMaterial = nullptr; - if(*szMaterialName != '\0') { - pMaterial = getContext().getMaterialManager()->getMaterial(szMaterialName); - } - m_materials.push_back(pMaterial); - if(pMaterial) { - m_uniqueMaterials.insert(pMaterial); - } else if(*szMaterialName != '\0') { - KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Missing material: %s", szMaterialName); - } - } - - m_hasTransparency = false; - for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { - if((*mat_itr)->isTransparent()) { - m_hasTransparency = true; - break; - } - } + if (m_materials.size() == 0) { + + for (std::vector::iterator itr = m_submeshes.begin(); itr != m_submeshes.end(); itr++) { + const char* szMaterialName = (*itr)->szMaterialName; + KRMaterial* pMaterial = nullptr; + if (*szMaterialName != '\0') { + pMaterial = getContext().getMaterialManager()->getMaterial(szMaterialName); + } + m_materials.push_back(pMaterial); + if (pMaterial) { + m_uniqueMaterials.insert(pMaterial); + } else if (*szMaterialName != '\0') { + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Missing material: %s", szMaterialName); + } } + + m_hasTransparency = false; + for (std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + if ((*mat_itr)->isTransparent()) { + m_hasTransparency = true; + break; + } + } + } } void KRMesh::preStream(float lodCoverage) { - getSubmeshes(); - getMaterials(); - - for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { - (*mat_itr)->preStream(lodCoverage); - } - - int cSubmeshes = (int)m_submeshes.size(); - for(int iSubmesh=0; iSubmeshvbo_data_blocks.begin(); vbo_data_itr != m_submeshes[iSubmesh]->vbo_data_blocks.end(); vbo_data_itr++) { - (*vbo_data_itr)->resetPoolExpiry(lodCoverage); - } + getSubmeshes(); + getMaterials(); + + for (std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + (*mat_itr)->preStream(lodCoverage); + } + + int cSubmeshes = (int)m_submeshes.size(); + for (int iSubmesh = 0; iSubmesh < cSubmeshes; iSubmesh++) { + for (auto vbo_data_itr = m_submeshes[iSubmesh]->vbo_data_blocks.begin(); vbo_data_itr != m_submeshes[iSubmesh]->vbo_data_blocks.end(); vbo_data_itr++) { + (*vbo_data_itr)->resetPoolExpiry(lodCoverage); } + } } kraken_stream_level KRMesh::getStreamLevel() { - kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; - getSubmeshes(); - getMaterials(); - - for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { - stream_level = KRMIN(stream_level, (*mat_itr)->getStreamLevel()); + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + getSubmeshes(); + getMaterials(); + + for (std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + stream_level = KRMIN(stream_level, (*mat_itr)->getStreamLevel()); + } + bool all_vbo_data_loaded = true; + bool vbo_data_loaded = false; + int cSubmeshes = (int)m_submeshes.size(); + for (int iSubmesh = 0; iSubmesh < cSubmeshes; iSubmesh++) { + for (auto vbo_data_itr = m_submeshes[iSubmesh]->vbo_data_blocks.begin(); vbo_data_itr != m_submeshes[iSubmesh]->vbo_data_blocks.end(); vbo_data_itr++) { + if ((*vbo_data_itr)->isVBOReady()) { + vbo_data_loaded = true; + } else { + all_vbo_data_loaded = false; + } } - bool all_vbo_data_loaded = true; - bool vbo_data_loaded = false; - int cSubmeshes = (int)m_submeshes.size(); - for(int iSubmesh=0; iSubmeshvbo_data_blocks.begin(); vbo_data_itr != m_submeshes[iSubmesh]->vbo_data_blocks.end(); vbo_data_itr++) { - if((*vbo_data_itr)->isVBOReady()) { - vbo_data_loaded = true; - } else { - all_vbo_data_loaded = false; - } - } - } - - if(!vbo_data_loaded || !all_vbo_data_loaded) { - stream_level = kraken_stream_level::STREAM_LEVEL_OUT; - } - - return stream_level; + } + + if (!vbo_data_loaded || !all_vbo_data_loaded) { + stream_level = kraken_stream_level::STREAM_LEVEL_OUT; + } + + return stream_level; } void KRMesh::render(const KRNode::RenderInfo& ri, const std::string& object_name, const Matrix4& matModel, KRTexture* pLightMap, const std::vector& bones, const Vector3& rim_color, float rim_power, float lod_coverage) { - //fprintf(stderr, "Rendering model: %s\n", m_name.c_str()); - if(ri.renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && ri.renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && ri.renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { - preStream(lod_coverage); - if(getStreamLevel() == kraken_stream_level::STREAM_LEVEL_OUT) { - - } else { - - getSubmeshes(); - getMaterials(); - - int cSubmeshes = (int)m_submeshes.size(); - if(ri.renderPass == KRNode::RENDER_PASS_SHADOWMAP) { - for(int iSubmesh=0; iSubmeshisTransparent()) { - // Exclude transparent and semi-transparent meshes from shadow maps - renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); - } - } - - } - } else { - // Apply submeshes in per-material batches to reduce number of state changes - for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { - for(int iSubmesh=0; iSubmeshisTransparent() && ri.renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { - std::vector bone_bind_poses; - for(int i=0; i < (int)bones.size(); i++) { - bone_bind_poses.push_back(getBoneBindPose(i)); - } - - - switch(pMaterial->getAlphaMode()) { - case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials - case KRMaterial::KRMATERIAL_ALPHA_MODE_TEST: // Alpha in diffuse texture is interpreted as punch-through when < 0.5 - pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullBack, bones, bone_bind_poses, matModel, pLightMap, rim_color, rim_power, lod_coverage); - renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); - break; - case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE: // Blended alpha with backface culling - pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullBack, bones, bone_bind_poses, matModel, pLightMap, rim_color, rim_power, lod_coverage); - renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); - break; - case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE: // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces. - // Render back faces first - pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullFront, bones, bone_bind_poses, matModel, pLightMap, rim_color, rim_power, lod_coverage); - renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); + } else { - // Render front faces second - pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullBack, bones, bone_bind_poses, matModel, pLightMap, rim_color, rim_power, lod_coverage); - renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); - break; - } - } - } - } - } + getSubmeshes(); + getMaterials(); + + int cSubmeshes = (int)m_submeshes.size(); + if (ri.renderPass == KRNode::RENDER_PASS_SHADOWMAP) { + for (int iSubmesh = 0; iSubmesh < cSubmeshes; iSubmesh++) { + KRMaterial* pMaterial = m_materials[iSubmesh]; + + if (pMaterial != NULL) { + + if (!pMaterial->isTransparent()) { + // Exclude transparent and semi-transparent meshes from shadow maps + renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); } + } + } + } else { + // Apply submeshes in per-material batches to reduce number of state changes + for (std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + for (int iSubmesh = 0; iSubmesh < cSubmeshes; iSubmesh++) { + KRMaterial* pMaterial = m_materials[iSubmesh]; + + if (pMaterial != NULL && pMaterial == (*mat_itr)) { + if ((!pMaterial->isTransparent() && ri.renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { + std::vector bone_bind_poses; + for (int i = 0; i < (int)bones.size(); i++) { + bone_bind_poses.push_back(getBoneBindPose(i)); + } + + + switch (pMaterial->getAlphaMode()) { + case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials + case KRMaterial::KRMATERIAL_ALPHA_MODE_TEST: // Alpha in diffuse texture is interpreted as punch-through when < 0.5 + pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullBack, bones, bone_bind_poses, matModel, pLightMap, rim_color, rim_power, lod_coverage); + renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); + break; + case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE: // Blended alpha with backface culling + pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullBack, bones, bone_bind_poses, matModel, pLightMap, rim_color, rim_power, lod_coverage); + renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); + break; + case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE: // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces. + // Render back faces first + pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullFront, bones, bone_bind_poses, matModel, pLightMap, rim_color, rim_power, lod_coverage); + renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); + + // Render front faces second + pMaterial->bind(ri, getModelFormat(), getVertexAttributes(), CullMode::kCullBack, bones, bone_bind_poses, matModel, pLightMap, rim_color, rim_power, lod_coverage); + renderSubmesh(ri.commandBuffer, iSubmesh, ri.renderPass, object_name, pMaterial->getName(), lod_coverage); + break; + } + } + } + } + } + } } + } } -float KRMesh::getMaxDimension() { +float KRMesh::getMaxDimension() +{ float m = 0.0; - if(m_maxPoint.x - m_minPoint.x > m) m = m_maxPoint.x - m_minPoint.x; - if(m_maxPoint.y - m_minPoint.y > m) m = m_maxPoint.y - m_minPoint.y; - if(m_maxPoint.z - m_minPoint.z > m) m = m_maxPoint.z - m_minPoint.z; - return m; + if (m_maxPoint.x - m_minPoint.x > m) m = m_maxPoint.x - m_minPoint.x; + if (m_maxPoint.y - m_minPoint.y > m) m = m_maxPoint.y - m_minPoint.y; + if (m_maxPoint.z - m_minPoint.z > m) m = m_maxPoint.z - m_minPoint.z; + return m; } -bool KRMesh::hasTransparency() { - return m_hasTransparency; +bool KRMesh::hasTransparency() +{ + return m_hasTransparency; } -void KRMesh::getSubmeshes() { - if(m_submeshes.size() == 0) { - pack_header *pHeader = getHeader(); - pack_material *pPackMaterials = (pack_material *)(pHeader+1); - m_submeshes.clear(); - for(int iMaterial=0; iMaterial < pHeader->submesh_count; iMaterial++) { - pack_material *pPackMaterial = pPackMaterials + iMaterial; - - Submesh *pSubmesh = new Submesh(); - pSubmesh->start_vertex = pPackMaterial->start_vertex; - pSubmesh->vertex_count = pPackMaterial->vertex_count; - - strncpy(pSubmesh->szMaterialName, pPackMaterial->szName, KRENGINE_MAX_NAME_LENGTH); - pSubmesh->szMaterialName[KRENGINE_MAX_NAME_LENGTH-1] = '\0'; - //fprintf(stderr, "Submesh material: \"%s\"\n", pSubmesh->szMaterialName); - m_submeshes.push_back(pSubmesh); - } - createDataBlocks(m_constant ? KRMeshManager::KRVBOData::CONSTANT : KRMeshManager::KRVBOData::STREAMING); +void KRMesh::getSubmeshes() +{ + if (m_submeshes.size() == 0) { + pack_header* pHeader = getHeader(); + pack_material* pPackMaterials = (pack_material*)(pHeader + 1); + m_submeshes.clear(); + for (int iMaterial = 0; iMaterial < pHeader->submesh_count; iMaterial++) { + pack_material* pPackMaterial = pPackMaterials + iMaterial; + + Submesh* pSubmesh = new Submesh(); + pSubmesh->start_vertex = pPackMaterial->start_vertex; + pSubmesh->vertex_count = pPackMaterial->vertex_count; + + strncpy(pSubmesh->szMaterialName, pPackMaterial->szName, KRENGINE_MAX_NAME_LENGTH); + pSubmesh->szMaterialName[KRENGINE_MAX_NAME_LENGTH - 1] = '\0'; + //fprintf(stderr, "Submesh material: \"%s\"\n", pSubmesh->szMaterialName); + m_submeshes.push_back(pSubmesh); } + createDataBlocks(m_constant ? KRMeshManager::KRVBOData::CONSTANT : KRMeshManager::KRVBOData::STREAMING); + } } void KRMesh::createDataBlocks(KRMeshManager::KRVBOData::vbo_type t) { - int cSubmeshes = (int)m_submeshes.size(); - for(int iSubmesh=0; iSubmesh < cSubmeshes; iSubmesh++) { - - Submesh *pSubmesh = m_submeshes[iSubmesh]; - int cVertexes = pSubmesh->vertex_count; - int vertex_data_offset =(int)getVertexDataOffset(); - int index_data_offset = (int)getIndexDataOffset(); - pack_header *pHeader = getHeader(); - int32_t vertex_attrib_flags = pHeader->vertex_attrib_flags; - int32_t vertex_count = pHeader->vertex_count; - - int vbo_index=0; - if(getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES - || getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP) { - - int index_group = getSubmesh(iSubmesh)->index_group; - int index_group_offset = getSubmesh(iSubmesh)->index_group_offset; - while(cVertexes > 0) { - - int start_index_offset, start_vertex_offset, index_count, vertex_count; - getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - - if((int)m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) { - KRDataBlock *vertex_data_block = m_pData->getSubBlock(vertex_data_offset + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size); - KRDataBlock *index_data_block = m_pData->getSubBlock(index_data_offset + start_index_offset * 2, index_count * 2); - KRMeshManager::KRVBOData *vbo_data_block = new KRMeshManager::KRVBOData(getContext().getMeshManager(), vertex_data_block, index_data_block, vertex_attrib_flags, true, t -#if KRENGINE_DEBUG_GPU_LABELS - , m_lodBaseName.c_str() -#endif - - ); - m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block); - m_submeshes[iSubmesh]->index_data_blocks.push_back(index_data_block); - m_submeshes[iSubmesh]->vbo_data_blocks.push_back(vbo_data_block); - } - vbo_index++; - - - int vertex_draw_count = cVertexes; - if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; - - cVertexes -= vertex_draw_count; - index_group_offset = 0; - } - } else { - int cBuffers = (vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE; - int iVertex = pSubmesh->start_vertex; - int iBuffer = iVertex / MAX_VBO_SIZE; - iVertex = iVertex % MAX_VBO_SIZE; - while(cVertexes > 0) { - GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : vertex_count % MAX_VBO_SIZE; - int vertex_size = m_vertex_size; - - if((int)m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) { - KRDataBlock *index_data_block = NULL; - KRDataBlock *vertex_data_block = m_pData->getSubBlock(vertex_data_offset + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes); - KRMeshManager::KRVBOData *vbo_data_block = new KRMeshManager::KRVBOData(getContext().getMeshManager(), vertex_data_block, index_data_block, vertex_attrib_flags, true, t -#if KRENGINE_DEBUG_GPU_LABELS - , m_lodBaseName.c_str() -#endif - ); - m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block); - m_submeshes[iSubmesh]->vbo_data_blocks.push_back(vbo_data_block); - } - vbo_index++; - - if(iVertex + cVertexes >= MAX_VBO_SIZE) { - assert(iVertex + (MAX_VBO_SIZE - iVertex) <= cBufferVertexes); + int cSubmeshes = (int)m_submeshes.size(); + for (int iSubmesh = 0; iSubmesh < cSubmeshes; iSubmesh++) { - cVertexes -= (MAX_VBO_SIZE - iVertex); - iVertex = 0; - iBuffer++; - } else { - assert(iVertex + cVertexes <= cBufferVertexes); - - cVertexes = 0; - } - - } + Submesh* pSubmesh = m_submeshes[iSubmesh]; + int cVertexes = pSubmesh->vertex_count; + int vertex_data_offset = (int)getVertexDataOffset(); + int index_data_offset = (int)getIndexDataOffset(); + pack_header* pHeader = getHeader(); + int32_t vertex_attrib_flags = pHeader->vertex_attrib_flags; + int32_t vertex_count = pHeader->vertex_count; + + int vbo_index = 0; + if (getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES + || getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP) { + + int index_group = getSubmesh(iSubmesh)->index_group; + int index_group_offset = getSubmesh(iSubmesh)->index_group_offset; + while (cVertexes > 0) { + + int start_index_offset, start_vertex_offset, index_count, vertex_count; + getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); + + if ((int)m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) { + KRDataBlock* vertex_data_block = m_pData->getSubBlock(vertex_data_offset + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size); + KRDataBlock* index_data_block = m_pData->getSubBlock(index_data_offset + start_index_offset * 2, index_count * 2); + KRMeshManager::KRVBOData* vbo_data_block = new KRMeshManager::KRVBOData(getContext().getMeshManager(), vertex_data_block, index_data_block, vertex_attrib_flags, true, t +#if KRENGINE_DEBUG_GPU_LABELS + , m_lodBaseName.c_str() +#endif + + ); + m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block); + m_submeshes[iSubmesh]->index_data_blocks.push_back(index_data_block); + m_submeshes[iSubmesh]->vbo_data_blocks.push_back(vbo_data_block); } + vbo_index++; + + + int vertex_draw_count = cVertexes; + if (vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; + + cVertexes -= vertex_draw_count; + index_group_offset = 0; + } + } else { + int cBuffers = (vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE; + int iVertex = pSubmesh->start_vertex; + int iBuffer = iVertex / MAX_VBO_SIZE; + iVertex = iVertex % MAX_VBO_SIZE; + while (cVertexes > 0) { + GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : vertex_count % MAX_VBO_SIZE; + int vertex_size = m_vertex_size; + + if ((int)m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) { + KRDataBlock* index_data_block = NULL; + KRDataBlock* vertex_data_block = m_pData->getSubBlock(vertex_data_offset + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes); + KRMeshManager::KRVBOData* vbo_data_block = new KRMeshManager::KRVBOData(getContext().getMeshManager(), vertex_data_block, index_data_block, vertex_attrib_flags, true, t +#if KRENGINE_DEBUG_GPU_LABELS + , m_lodBaseName.c_str() +#endif + ); + m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block); + m_submeshes[iSubmesh]->vbo_data_blocks.push_back(vbo_data_block); + } + vbo_index++; + + if (iVertex + cVertexes >= MAX_VBO_SIZE) { + assert(iVertex + (MAX_VBO_SIZE - iVertex) <= cBufferVertexes); + + cVertexes -= (MAX_VBO_SIZE - iVertex); + iVertex = 0; + iBuffer++; + } else { + assert(iVertex + cVertexes <= cBufferVertexes); + + cVertexes = 0; + } + + } } + } } void KRMesh::renderNoMaterials(VkCommandBuffer& commandBuffer, KRNode::RenderPass renderPass, const std::string& object_name, const std::string& material_name, float lodCoverage) @@ -452,428 +464,439 @@ bool KRMesh::isReady() const return true; } -void KRMesh::renderSubmesh(VkCommandBuffer& commandBuffer, int iSubmesh, KRNode::RenderPass renderPass, const std::string &object_name, const std::string &material_name, float lodCoverage) { - getSubmeshes(); - - Submesh *pSubmesh = m_submeshes[iSubmesh]; - int cVertexes = pSubmesh->vertex_count; - - int vbo_index=0; - if(getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) { - - int index_group = getSubmesh(iSubmesh)->index_group; - int index_group_offset = getSubmesh(iSubmesh)->index_group_offset; - while(cVertexes > 0) { - - int start_index_offset, start_vertex_offset, index_count, vertex_count; - getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - - KRMeshManager::KRVBOData *vbo_data_block = m_submeshes[iSubmesh]->vbo_data_blocks[vbo_index++]; - assert(vbo_data_block->isVBOReady()); - - m_pContext->getMeshManager()->bindVBO(commandBuffer, vbo_data_block, lodCoverage); - - - int vertex_draw_count = cVertexes; - if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; - - vkCmdDrawIndexed(commandBuffer, vertex_draw_count, 1, index_group_offset, 0, 0); - m_pContext->getMeshManager()->log_draw_call(renderPass, object_name, material_name, vertex_draw_count); - cVertexes -= vertex_draw_count; - index_group_offset = 0; +void KRMesh::renderSubmesh(VkCommandBuffer& commandBuffer, int iSubmesh, KRNode::RenderPass renderPass, const std::string& object_name, const std::string& material_name, float lodCoverage) +{ + getSubmeshes(); + + Submesh* pSubmesh = m_submeshes[iSubmesh]; + int cVertexes = pSubmesh->vertex_count; + + int vbo_index = 0; + if (getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) { + + int index_group = getSubmesh(iSubmesh)->index_group; + int index_group_offset = getSubmesh(iSubmesh)->index_group_offset; + while (cVertexes > 0) { + + int start_index_offset, start_vertex_offset, index_count, vertex_count; + getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); + + KRMeshManager::KRVBOData* vbo_data_block = m_submeshes[iSubmesh]->vbo_data_blocks[vbo_index++]; + assert(vbo_data_block->isVBOReady()); + + m_pContext->getMeshManager()->bindVBO(commandBuffer, vbo_data_block, lodCoverage); + + + int vertex_draw_count = cVertexes; + if (vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; + + vkCmdDrawIndexed(commandBuffer, vertex_draw_count, 1, index_group_offset, 0, 0); + m_pContext->getMeshManager()->log_draw_call(renderPass, object_name, material_name, vertex_draw_count); + cVertexes -= vertex_draw_count; + index_group_offset = 0; + } + + } else { + int cBuffers = (cVertexes + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE; + int iVertex = pSubmesh->start_vertex; + int iBuffer = iVertex / MAX_VBO_SIZE; + iVertex = iVertex % MAX_VBO_SIZE; + while (cVertexes > 0) { + GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : cVertexes % MAX_VBO_SIZE; + + KRMeshManager::KRVBOData* vbo_data_block = m_submeshes[iSubmesh]->vbo_data_blocks[vbo_index++]; + assert(vbo_data_block->isVBOReady()); + m_pContext->getMeshManager()->bindVBO(commandBuffer, vbo_data_block, lodCoverage); + + + if (iVertex + cVertexes >= MAX_VBO_SIZE) { + assert(iVertex + (MAX_VBO_SIZE - iVertex) <= cBufferVertexes); + switch (getModelFormat()) { + case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: + case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: + vkCmdDraw(commandBuffer, (MAX_VBO_SIZE - iVertex), 1, iVertex, 0); + break; + case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: + case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP: + vkCmdDrawIndexed(commandBuffer, (MAX_VBO_SIZE - iVertex), 1, iVertex, 0, 0); + break; } - + m_pContext->getMeshManager()->log_draw_call(renderPass, object_name, material_name, (MAX_VBO_SIZE - iVertex)); + + cVertexes -= (MAX_VBO_SIZE - iVertex); + iVertex = 0; + iBuffer++; + } else { + assert(iVertex + cVertexes <= cBufferVertexes); + + switch (getModelFormat()) { + case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: + case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: + vkCmdDraw(commandBuffer, cVertexes, 1, iVertex, 0); + break; + default: + break; + } + m_pContext->getMeshManager()->log_draw_call(renderPass, object_name, material_name, cVertexes); + + cVertexes = 0; + } + + } + } +} + +void KRMesh::LoadData(const KRMesh::mesh_info& mi, bool calculate_normals, bool calculate_tangents) +{ + + releaseData(); + + // TODO, FINDME - These values should be passed as a parameter and set by GUI flags + bool use_short_vertexes = false; + bool use_short_normals = true; + bool use_short_tangents = true; + bool use_short_uva = true; + bool use_short_uvb = true; + + if (use_short_vertexes) { + for (std::vector::const_iterator itr = mi.vertices.begin(); itr != mi.vertices.end(); itr++) { + if (fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f || fabsf((*itr).z) > 1.0f) { + use_short_vertexes = false; + } + } + } + + if (use_short_uva) { + for (std::vector::const_iterator itr = mi.uva.begin(); itr != mi.uva.end(); itr++) { + if (fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) { + use_short_uva = false; + } + } + } + + if (use_short_uvb) { + for (std::vector::const_iterator itr = mi.uvb.begin(); itr != mi.uvb.end(); itr++) { + if (fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) { + use_short_uvb = false; + } + } + } + + __int32_t vertex_attrib_flags = 0; + if (mi.vertices.size()) { + if (use_short_vertexes) { + vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX_SHORT); } else { - int cBuffers = (cVertexes + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE; - int iVertex = pSubmesh->start_vertex; - int iBuffer = iVertex / MAX_VBO_SIZE; - iVertex = iVertex % MAX_VBO_SIZE; - while(cVertexes > 0) { - GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : cVertexes % MAX_VBO_SIZE; - - KRMeshManager::KRVBOData *vbo_data_block = m_submeshes[iSubmesh]->vbo_data_blocks[vbo_index++]; - assert(vbo_data_block->isVBOReady()); - m_pContext->getMeshManager()->bindVBO(commandBuffer, vbo_data_block, lodCoverage); - - - if(iVertex + cVertexes >= MAX_VBO_SIZE) { - assert(iVertex + (MAX_VBO_SIZE - iVertex) <= cBufferVertexes); - switch (getModelFormat()) { - case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: - case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: - vkCmdDraw(commandBuffer, (MAX_VBO_SIZE - iVertex), 1, iVertex, 0); - break; - case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: - case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP: - vkCmdDrawIndexed(commandBuffer, (MAX_VBO_SIZE - iVertex), 1, iVertex, 0, 0); - break; - } - m_pContext->getMeshManager()->log_draw_call(renderPass, object_name, material_name, (MAX_VBO_SIZE - iVertex)); - - cVertexes -= (MAX_VBO_SIZE - iVertex); - iVertex = 0; - iBuffer++; - } else { - assert(iVertex + cVertexes <= cBufferVertexes); - - switch (getModelFormat()) { - case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: - case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: - vkCmdDraw(commandBuffer, cVertexes, 1, iVertex, 0); - break; - default: - break; - } - m_pContext->getMeshManager()->log_draw_call(renderPass, object_name, material_name, cVertexes); - - cVertexes = 0; - } - - } + vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX); } + } + 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 (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 (mi.uva.size()) { + if (use_short_uva) { + vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA_SHORT); + } else { + vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA); + } + } + 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 (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 = 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 = new KRDataBlock(); + m_pMetaData = m_pData; + m_pData->expand(new_file_size); + m_pData->lock(); + pack_header* pHeader = getHeader(); + memset(pHeader, 0, sizeof(pack_header)); + pHeader->vertex_attrib_flags = vertex_attrib_flags; + pHeader->submesh_count = (__int32_t)submesh_count; + pHeader->vertex_count = (__int32_t)vertex_count; + 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 = (__int32_t)mi.format; + strcpy(pHeader->szTag, "KROBJPACK1.2 "); + updateAttributeOffsets(); + + pack_material* pPackMaterials = (pack_material*)(pHeader + 1); + + for (int iMaterial = 0; iMaterial < pHeader->submesh_count; iMaterial++) { + pack_material* pPackMaterial = pPackMaterials + 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, 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, 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 * (int)mi.vertices.size()); + for (int iVertex = 0; iVertex < (int)mi.vertices.size(); iVertex++) { + Vector3 source_vertex = mi.vertices[iVertex]; + setVertexPosition(iVertex, source_vertex); + 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, mi.bone_indexes[iVertex][bone_weight_index]); + setBoneWeight(iVertex, bone_weight_index, mi.bone_weights[iVertex][bone_weight_index]); + } + } + if (bFirstVertex) { + bFirstVertex = false; + m_minPoint = source_vertex; + m_maxPoint = source_vertex; + } else { + if (source_vertex.x < m_minPoint.x) m_minPoint.x = source_vertex.x; + if (source_vertex.y < m_minPoint.y) m_minPoint.y = source_vertex.y; + if (source_vertex.z < m_minPoint.z) m_minPoint.z = source_vertex.z; + if (source_vertex.x > m_maxPoint.x) m_maxPoint.x = source_vertex.x; + 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 ((int)mi.uva.size() > iVertex) { + setVertexUVA(iVertex, mi.uva[iVertex]); + } + if ((int)mi.uvb.size() > iVertex) { + setVertexUVB(iVertex, mi.uvb[iVertex]); + } + if ((int)mi.normals.size() > iVertex) { + setVertexNormal(iVertex, Vector3::Normalize(mi.normals[iVertex])); + } + if ((int)mi.tangents.size() > iVertex) { + setVertexTangent(iVertex, Vector3::Normalize(mi.tangents[iVertex])); + } + } + + pHeader->minx = m_minPoint.x; + pHeader->miny = m_minPoint.y; + pHeader->minz = m_minPoint.z; + pHeader->maxx = m_maxPoint.x; + pHeader->maxy = m_maxPoint.y; + pHeader->maxz = m_maxPoint.z; + + + __uint16_t* index_data = getIndexData(); + 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 >::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; + } + + if (getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES) { + // Calculate missing surface normals and tangents + //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 < (int)mi.vertices.size(); iVertex += 3) { + Vector3 p1 = getVertexPosition(iVertex); + Vector3 p2 = getVertexPosition(iVertex + 1); + Vector3 p3 = getVertexPosition(iVertex + 2); + Vector3 v1 = p2 - p1; + Vector3 v2 = p3 - p1; + + + // -- Calculate normal if missing -- + if (calculate_normals) { + Vector3 first_normal = getVertexNormal(iVertex); + if (first_normal.x == 0.0f && first_normal.y == 0.0f && first_normal.z == 0.0f) { + // Note - We don't take into consideration smoothing groups or smoothing angles when generating normals; all generated normals represent flat shaded polygons + Vector3 normal = Vector3::Cross(v1, v2); + + normal.normalize(); + setVertexNormal(iVertex, normal); + setVertexNormal(iVertex + 1, normal); + setVertexNormal(iVertex + 2, normal); + } + } + + // -- Calculate tangent vector for normal mapping -- + if (calculate_tangents) { + Vector3 first_tangent = getVertexTangent(iVertex); + if (first_tangent.x == 0.0f && first_tangent.y == 0.0f && first_tangent.z == 0.0f) { + + Vector2 uv0 = getVertexUVA(iVertex); + Vector2 uv1 = getVertexUVA(iVertex + 1); + Vector2 uv2 = getVertexUVA(iVertex + 2); + + Vector2 st1 = Vector2::Create(uv1.x - uv0.x, uv1.y - uv0.y); + Vector2 st2 = Vector2::Create(uv2.x - uv0.x, uv2.y - uv0.y); + float coef = 1 / (st1.x * st2.y - st2.x * st1.y); + + Vector3 tangent = Vector3::Create( + coef * ((v1.x * st2.y) + (v2.x * -st1.y)), + coef * ((v1.y * st2.y) + (v2.y * -st1.y)), + coef * ((v1.z * st2.y) + (v2.z * -st1.y)) + ); + + tangent.normalize(); + setVertexTangent(iVertex, tangent); + setVertexTangent(iVertex + 1, tangent); + setVertexTangent(iVertex + 2, tangent); + } + } + } + } + } + m_pData->unlock(); + + // ---- + + pack_header ph; + m_pData->copy((void*)&ph, 0, sizeof(ph)); + m_pMetaData = m_pData->getSubBlock(0, sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count); + m_pMetaData->lock(); + m_pIndexBaseData = m_pData->getSubBlock(sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count + KRALIGN(2 * ph.index_count), ph.index_base_count * 8); + m_pIndexBaseData->lock(); + + // ---- + + optimize(); + + if (m_constant) { + // Ensure that constant models loaded immediately by the streamer + getSubmeshes(); + getMaterials(); + } } -void KRMesh::LoadData(const KRMesh::mesh_info &mi, bool calculate_normals, bool calculate_tangents) { - - releaseData(); - - // TODO, FINDME - These values should be passed as a parameter and set by GUI flags - bool use_short_vertexes = false; - bool use_short_normals = true; - bool use_short_tangents = true; - bool use_short_uva = true; - bool use_short_uvb = true; - - if(use_short_vertexes) { - for(std::vector::const_iterator itr=mi.vertices.begin(); itr != mi.vertices.end(); itr++) { - if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f || fabsf((*itr).z) > 1.0f) { - use_short_vertexes = false; - } - } - } - - if(use_short_uva) { - for(std::vector::const_iterator itr=mi.uva.begin(); itr != mi.uva.end(); itr++) { - if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) { - use_short_uva = false; - } - } - } - - if(use_short_uvb) { - for(std::vector::const_iterator itr=mi.uvb.begin(); itr != mi.uvb.end(); itr++) { - if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) { - use_short_uvb = false; - } - } - } - - __int32_t vertex_attrib_flags = 0; - 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(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(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(mi.uva.size()) { - if(use_short_uva) { - vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA_SHORT); - } else { - vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA); - } - } - 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(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 = 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 = new KRDataBlock(); - m_pMetaData = m_pData; - m_pData->expand(new_file_size); - m_pData->lock(); - pack_header *pHeader = getHeader(); - memset(pHeader, 0, sizeof(pack_header)); - pHeader->vertex_attrib_flags = vertex_attrib_flags; - pHeader->submesh_count = (__int32_t)submesh_count; - pHeader->vertex_count = (__int32_t)vertex_count; - 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 = (__int32_t)mi.format; - strcpy(pHeader->szTag, "KROBJPACK1.2 "); - updateAttributeOffsets(); - - pack_material *pPackMaterials = (pack_material *)(pHeader+1); - - for(int iMaterial=0; iMaterial < pHeader->submesh_count; iMaterial++) { - pack_material *pPackMaterial = pPackMaterials + 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, 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, 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 * (int)mi.vertices.size()); - for(int iVertex=0; iVertex < (int)mi.vertices.size(); iVertex++) { - Vector3 source_vertex = mi.vertices[iVertex]; - setVertexPosition(iVertex, source_vertex); - if(mi.bone_names.size()) { - for(int bone_weight_index=0; bone_weight_index m_maxPoint.x) m_maxPoint.x = source_vertex.x; - 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((int)mi.uva.size() > iVertex) { - setVertexUVA(iVertex, mi.uva[iVertex]); - } - if((int)mi.uvb.size() > iVertex) { - setVertexUVB(iVertex, mi.uvb[iVertex]); - } - if((int)mi.normals.size() > iVertex) { - setVertexNormal(iVertex, Vector3::Normalize(mi.normals[iVertex])); - } - if((int)mi.tangents.size() > iVertex) { - setVertexTangent(iVertex, Vector3::Normalize(mi.tangents[iVertex])); - } - } - - pHeader->minx = m_minPoint.x; - pHeader->miny = m_minPoint.y; - pHeader->minz = m_minPoint.z; - pHeader->maxx = m_maxPoint.x; - pHeader->maxy = m_maxPoint.y; - pHeader->maxz = m_maxPoint.z; - - - __uint16_t *index_data = getIndexData(); - 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 >::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; - } - - if(getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES) { - // Calculate missing surface normals and tangents - //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 < (int)mi.vertices.size(); iVertex+= 3) { - Vector3 p1 = getVertexPosition(iVertex); - Vector3 p2 = getVertexPosition(iVertex+1); - Vector3 p3 = getVertexPosition(iVertex+2); - Vector3 v1 = p2 - p1; - Vector3 v2 = p3 - p1; - - - // -- Calculate normal if missing -- - if(calculate_normals) { - Vector3 first_normal = getVertexNormal(iVertex); - if(first_normal.x == 0.0f && first_normal.y == 0.0f && first_normal.z == 0.0f) { - // Note - We don't take into consideration smoothing groups or smoothing angles when generating normals; all generated normals represent flat shaded polygons - Vector3 normal = Vector3::Cross(v1, v2); - - normal.normalize(); - setVertexNormal(iVertex, normal); - setVertexNormal(iVertex+1, normal); - setVertexNormal(iVertex+2, normal); - } - } - - // -- Calculate tangent vector for normal mapping -- - if(calculate_tangents) { - Vector3 first_tangent = getVertexTangent(iVertex); - if(first_tangent.x == 0.0f && first_tangent.y == 0.0f && first_tangent.z == 0.0f) { - - Vector2 uv0 = getVertexUVA(iVertex); - Vector2 uv1 = getVertexUVA(iVertex + 1); - Vector2 uv2 = getVertexUVA(iVertex + 2); - - Vector2 st1 = Vector2::Create(uv1.x - uv0.x, uv1.y - uv0.y); - Vector2 st2 = Vector2::Create(uv2.x - uv0.x, uv2.y - uv0.y); - float coef = 1/ (st1.x * st2.y - st2.x * st1.y); - - Vector3 tangent = Vector3::Create( - coef * ((v1.x * st2.y) + (v2.x * -st1.y)), - coef * ((v1.y * st2.y) + (v2.y * -st1.y)), - coef * ((v1.z * st2.y) + (v2.z * -st1.y)) - ); - - tangent.normalize(); - setVertexTangent(iVertex, tangent); - setVertexTangent(iVertex+1, tangent); - setVertexTangent(iVertex+2, tangent); - } - } - } - } - } - m_pData->unlock(); - - // ---- - - pack_header ph; - m_pData->copy((void *)&ph, 0, sizeof(ph)); - m_pMetaData = m_pData->getSubBlock(0, sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count); - m_pMetaData->lock(); - m_pIndexBaseData = m_pData->getSubBlock(sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count + KRALIGN(2 * ph.index_count), ph.index_base_count * 8); - m_pIndexBaseData->lock(); - - // ---- - - optimize(); - - if (m_constant) { - // Ensure that constant models loaded immediately by the streamer - getSubmeshes(); - getMaterials(); - } +Vector3 KRMesh::getMinPoint() const +{ + return m_minPoint; } -Vector3 KRMesh::getMinPoint() const { - return m_minPoint; +Vector3 KRMesh::getMaxPoint() const +{ + return m_maxPoint; } -Vector3 KRMesh::getMaxPoint() const { - return m_maxPoint; +int KRMesh::getLODCoverage() const +{ + return m_lodCoverage; } -int KRMesh::getLODCoverage() const { - return m_lodCoverage; -} - -std::string KRMesh::getLODBaseName() const { - return m_lodBaseName; +std::string KRMesh::getLODBaseName() const +{ + return m_lodBaseName; } // Predicate used with std::sort to sort by highest detail model first, decending to lowest detail LOD model -bool KRMesh::lod_sort_predicate(const KRMesh *m1, const KRMesh *m2) +bool KRMesh::lod_sort_predicate(const KRMesh* m1, const KRMesh* m2) { - return m1->m_lodCoverage > m2->m_lodCoverage; + return m1->m_lodCoverage > m2->m_lodCoverage; } bool KRMesh::has_vertex_attribute(vertex_attrib_t attribute_type) const { - //return (getHeader()->vertex_attrib_flags & (1 << attribute_type)) != 0; - return has_vertex_attribute(getHeader()->vertex_attrib_flags, attribute_type); + //return (getHeader()->vertex_attrib_flags & (1 << attribute_type)) != 0; + return has_vertex_attribute(getHeader()->vertex_attrib_flags, attribute_type); } bool KRMesh::has_vertex_attribute(int vertex_attrib_flags, vertex_attrib_t attribute_type) { - return (vertex_attrib_flags & (1 << attribute_type)) != 0; + return (vertex_attrib_flags & (1 << attribute_type)) != 0; } -KRMesh::pack_header *KRMesh::getHeader() const +KRMesh::pack_header* KRMesh::getHeader() const { - return (pack_header *)m_pMetaData->getStart(); + return (pack_header*)m_pMetaData->getStart(); } -KRMesh::pack_bone *KRMesh::getBone(int index) +KRMesh::pack_bone* KRMesh::getBone(int index) { - pack_header *header = getHeader(); - return (pack_bone *)((unsigned char *)m_pMetaData->getStart() + sizeof(pack_header) + sizeof(pack_material) * header->submesh_count + sizeof(pack_bone) * index); + pack_header* header = getHeader(); + return (pack_bone*)((unsigned char*)m_pMetaData->getStart() + sizeof(pack_header) + sizeof(pack_material) * header->submesh_count + sizeof(pack_bone) * index); } -unsigned char *KRMesh::getVertexData() const { - return ((unsigned char *)m_pData->getStart()) + getVertexDataOffset(); -} - -size_t KRMesh::getVertexDataOffset() const { - pack_header *pHeader = getHeader(); - return sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count) + KRALIGN(8 * pHeader->index_base_count); -} - -__uint16_t *KRMesh::getIndexData() const { - - return (__uint16_t *)((unsigned char *)m_pData->getStart() + getIndexDataOffset()); -} - -size_t KRMesh::getIndexDataOffset() const { - pack_header *pHeader = getHeader(); - return sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count; -} - -__uint32_t *KRMesh::getIndexBaseData() const { - if(m_pIndexBaseData == NULL) { - pack_header *pHeader = getHeader(); - return (__uint32_t *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count)); - } else { - return (__uint32_t *)m_pIndexBaseData->getStart(); - } -} - - -KRMesh::pack_material *KRMesh::getSubmesh(int mesh_index) const +unsigned char* KRMesh::getVertexData() const { - return (pack_material *)((unsigned char *)m_pMetaData->getStart() + sizeof(pack_header)) + mesh_index; + return ((unsigned char*)m_pData->getStart()) + getVertexDataOffset(); } -unsigned char *KRMesh::getVertexData(int index) const +size_t KRMesh::getVertexDataOffset() const { - return getVertexData() + m_vertex_size * index; + pack_header* pHeader = getHeader(); + return sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count) + KRALIGN(8 * pHeader->index_base_count); +} + +__uint16_t* KRMesh::getIndexData() const +{ + + return (__uint16_t*)((unsigned char*)m_pData->getStart() + getIndexDataOffset()); +} + +size_t KRMesh::getIndexDataOffset() const +{ + pack_header* pHeader = getHeader(); + return sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count; +} + +__uint32_t* KRMesh::getIndexBaseData() const +{ + if (m_pIndexBaseData == NULL) { + pack_header* pHeader = getHeader(); + return (__uint32_t*)((unsigned char*)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count)); + } else { + return (__uint32_t*)m_pIndexBaseData->getStart(); + } +} + + +KRMesh::pack_material* KRMesh::getSubmesh(int mesh_index) const +{ + return (pack_material*)((unsigned char*)m_pMetaData->getStart() + sizeof(pack_header)) + mesh_index; +} + +unsigned char* KRMesh::getVertexData(int index) const +{ + return getVertexData() + m_vertex_size * index; } int KRMesh::getSubmeshCount() const { - pack_header *header = getHeader(); - int submesh_count = header->submesh_count; - return submesh_count; + pack_header* header = getHeader(); + int submesh_count = header->submesh_count; + return submesh_count; } int KRMesh::getVertexCount(int submesh) const { - return getSubmesh(submesh)->vertex_count; + return getSubmesh(submesh)->vertex_count; } __uint32_t KRMesh::getVertexAttributes() const @@ -885,789 +908,790 @@ __uint32_t KRMesh::getVertexAttributes() const Vector3 KRMesh::getVertexPosition(int index) const { - if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { - short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX_SHORT]); - return Vector3::Create((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f); - } else if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) { - return Vector3::Create((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX])); - } else { - return Vector3::Zero(); - } + if (has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { + short* v = (short*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX_SHORT]); + return Vector3::Create((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f); + } else if (has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) { + return Vector3::Create((float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX])); + } else { + return Vector3::Zero(); + } } Vector3 KRMesh::getVertexNormal(int index) const { - if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { - short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL_SHORT]); - return Vector3::Create((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f); - } else if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) { - return Vector3::Create((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL])); - } else { - return Vector3::Zero(); - } + if (has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { + short* v = (short*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL_SHORT]); + return Vector3::Create((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f); + } else if (has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) { + return Vector3::Create((float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL])); + } else { + return Vector3::Zero(); + } } Vector3 KRMesh::getVertexTangent(int index) const { - if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { - short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT_SHORT]); - return Vector3::Create((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f); - } else if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) { - return Vector3::Create((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT])); - } else { - return Vector3::Zero(); - } + if (has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { + short* v = (short*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT_SHORT]); + return Vector3::Create((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f); + } else if (has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) { + return Vector3::Create((float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT])); + } else { + return Vector3::Zero(); + } } Vector2 KRMesh::getVertexUVA(int index) const { - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { - short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA_SHORT]); - return Vector2::Create((float)v[0] / 32767.0f, (float)v[1] / 32767.0f); - } else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) { - return Vector2::Create((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA])); - } else { - return Vector2::Zero(); - } + if (has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { + short* v = (short*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA_SHORT]); + return Vector2::Create((float)v[0] / 32767.0f, (float)v[1] / 32767.0f); + } else if (has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) { + return Vector2::Create((float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA])); + } else { + return Vector2::Zero(); + } } Vector2 KRMesh::getVertexUVB(int index) const { - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { - short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB_SHORT]); - return Vector2::Create((float)v[0] / 32767.0f, (float)v[1] / 32767.0f); - } else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) { - return Vector2::Create((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB])); - } else { - return Vector2::Zero(); - } + if (has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { + short* v = (short*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB_SHORT]); + return Vector2::Create((float)v[0] / 32767.0f, (float)v[1] / 32767.0f); + } else if (has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) { + return Vector2::Create((float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB])); + } else { + return Vector2::Zero(); + } } -void KRMesh::setVertexPosition(int index, const Vector3 &v) +void KRMesh::setVertexPosition(int index, const Vector3& v) { - if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { - short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX_SHORT]); - vert[0] = (short)(v.x * 32767.0f); - vert[1] = (short)(v.y * 32767.0f); - vert[2] = (short)(v.z * 32767.0f); - } else if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX]); - vert[0] = v.x; - vert[1] = v.y; - vert[2] = v.z; - } + if (has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { + short* vert = (short*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX_SHORT]); + vert[0] = (short)(v.x * 32767.0f); + vert[1] = (short)(v.y * 32767.0f); + vert[2] = (short)(v.z * 32767.0f); + } else if (has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) { + float* vert = (float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX]); + vert[0] = v.x; + vert[1] = v.y; + vert[2] = v.z; + } } -void KRMesh::setVertexNormal(int index, const Vector3 &v) +void KRMesh::setVertexNormal(int index, const Vector3& v) { - if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { - short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL_SHORT]); - vert[0] = (short)(v.x * 32767.0f); - vert[1] = (short)(v.y * 32767.0f); - vert[2] = (short)(v.z * 32767.0f); - } else if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL]); - vert[0] = v.x; - vert[1] = v.y; - vert[2] = v.z; - } + if (has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { + short* vert = (short*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL_SHORT]); + vert[0] = (short)(v.x * 32767.0f); + vert[1] = (short)(v.y * 32767.0f); + vert[2] = (short)(v.z * 32767.0f); + } else if (has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) { + float* vert = (float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL]); + vert[0] = v.x; + vert[1] = v.y; + vert[2] = v.z; + } } -void KRMesh::setVertexTangent(int index, const Vector3 & v) +void KRMesh::setVertexTangent(int index, const Vector3& v) { - if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { - short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT_SHORT]); - vert[0] = (short)(v.x * 32767.0f); - vert[1] = (short)(v.y * 32767.0f); - vert[2] = (short)(v.z * 32767.0f); - } else if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT]); - vert[0] = v.x; - vert[1] = v.y; - vert[2] = v.z; - } + if (has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { + short* vert = (short*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT_SHORT]); + vert[0] = (short)(v.x * 32767.0f); + vert[1] = (short)(v.y * 32767.0f); + vert[2] = (short)(v.z * 32767.0f); + } else if (has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) { + float* vert = (float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT]); + vert[0] = v.x; + vert[1] = v.y; + vert[2] = v.z; + } } -void KRMesh::setVertexUVA(int index, const Vector2 &v) +void KRMesh::setVertexUVA(int index, const Vector2& v) { - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { - short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA_SHORT]); - vert[0] = (short)(v.x * 32767.0f); - vert[1] = (short)(v.y * 32767.0f); - } else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA]); - vert[0] = v.x; - vert[1] = v.y; - } + if (has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { + short* vert = (short*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA_SHORT]); + vert[0] = (short)(v.x * 32767.0f); + vert[1] = (short)(v.y * 32767.0f); + } else if (has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) { + float* vert = (float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA]); + vert[0] = v.x; + vert[1] = v.y; + } } -void KRMesh::setVertexUVB(int index, const Vector2 &v) +void KRMesh::setVertexUVB(int index, const Vector2& v) { - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { - short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB_SHORT]); - vert[0] = (short)(v.x * 32767.0f); - vert[1] = (short)(v.y * 32767.0f); - } else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB]); - vert[0] = v.x; - vert[1] = v.y; - } + if (has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { + short* vert = (short*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB_SHORT]); + vert[0] = (short)(v.x * 32767.0f); + vert[1] = (short)(v.y * 32767.0f); + } else if (has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) { + float* vert = (float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB]); + vert[0] = v.x; + vert[1] = v.y; + } } int KRMesh::getBoneIndex(int index, int weight_index) const { - unsigned char *vert = (unsigned char *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEINDEXES]); - return vert[weight_index]; + unsigned char* vert = (unsigned char*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEINDEXES]); + return vert[weight_index]; } void KRMesh::setBoneIndex(int index, int weight_index, int bone_index) { - unsigned char *vert = (unsigned char *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEINDEXES]); - vert[weight_index] = bone_index; + unsigned char* vert = (unsigned char*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEINDEXES]); + vert[weight_index] = bone_index; } float KRMesh::getBoneWeight(int index, int weight_index) const { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEWEIGHTS]); - return vert[weight_index]; + float* vert = (float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEWEIGHTS]); + return vert[weight_index]; } void KRMesh::setBoneWeight(int index, int weight_index, float bone_weight) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEWEIGHTS]); - vert[weight_index] = bone_weight; + float* vert = (float*)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_BONEWEIGHTS]); + vert[weight_index] = bone_weight; } size_t KRMesh::VertexSizeForAttributes(__int32_t vertex_attrib_flags) { - size_t data_size = 0; - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_VERTEX)) { - data_size += sizeof(float) * 3; - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_NORMAL)) { - data_size += sizeof(float) * 3; - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TANGENT)) { - data_size += sizeof(float) * 3; - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVA)) { - data_size += sizeof(float) * 2; - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVB)) { - data_size += sizeof(float) * 2; - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_BONEINDEXES)) { - data_size += 4; // 4 bytes - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_BONEWEIGHTS)) { - data_size += sizeof(float) * 4; - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_VERTEX_SHORT)) { - data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute... - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_NORMAL_SHORT)) { - data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute... - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TANGENT_SHORT)) { - data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute... - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVA_SHORT)) { - data_size += sizeof(short) * 2; - } - if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVB_SHORT)) { - data_size += sizeof(short) * 2; - } - return data_size; + size_t data_size = 0; + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_VERTEX)) { + data_size += sizeof(float) * 3; + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_NORMAL)) { + data_size += sizeof(float) * 3; + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TANGENT)) { + data_size += sizeof(float) * 3; + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVA)) { + data_size += sizeof(float) * 2; + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVB)) { + data_size += sizeof(float) * 2; + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_BONEINDEXES)) { + data_size += 4; // 4 bytes + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_BONEWEIGHTS)) { + data_size += sizeof(float) * 4; + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_VERTEX_SHORT)) { + data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute... + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_NORMAL_SHORT)) { + data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute... + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TANGENT_SHORT)) { + data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute... + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVA_SHORT)) { + data_size += sizeof(short) * 2; + } + if (has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVB_SHORT)) { + data_size += sizeof(short) * 2; + } + return data_size; } void KRMesh::updateAttributeOffsets() { - pack_header *header = getHeader(); - int mask = 0; - for(size_t i=0; i < KRENGINE_NUM_ATTRIBUTES; i++) { - if(has_vertex_attribute((vertex_attrib_t)i)) { - m_vertex_attribute_offset[i] = (int)VertexSizeForAttributes(header->vertex_attrib_flags & mask); - } else { - m_vertex_attribute_offset[i] = -1; - } - mask = (mask << 1) | 1; + pack_header* header = getHeader(); + int mask = 0; + for (size_t i = 0; i < KRENGINE_NUM_ATTRIBUTES; i++) { + if (has_vertex_attribute((vertex_attrib_t)i)) { + m_vertex_attribute_offset[i] = (int)VertexSizeForAttributes(header->vertex_attrib_flags & mask); + } else { + m_vertex_attribute_offset[i] = -1; } - m_vertex_size = (int)VertexSizeForAttributes(header->vertex_attrib_flags); + mask = (mask << 1) | 1; + } + m_vertex_size = (int)VertexSizeForAttributes(header->vertex_attrib_flags); } size_t KRMesh::AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_flags) { - int mask = 0; - for(int i=0; i < vertex_attrib; i++) { - if(vertex_attrib_flags & (1 << i)) { - mask |= (1 << i); - } + int mask = 0; + for (int i = 0; i < vertex_attrib; i++) { + if (vertex_attrib_flags & (1 << i)) { + mask |= (1 << i); } - return VertexSizeForAttributes(mask); + } + return VertexSizeForAttributes(mask); } VkFormat KRMesh::AttributeVulkanFormat(__int32 vertex_attrib) { switch (vertex_attrib) { - case KRENGINE_ATTRIB_VERTEX: - case KRENGINE_ATTRIB_NORMAL: - case KRENGINE_ATTRIB_TANGENT: - case KRENGINE_ATTRIB_BONEWEIGHTS: - return VK_FORMAT_R32G32B32_SFLOAT; - case KRENGINE_ATTRIB_TEXUVA: - case KRENGINE_ATTRIB_TEXUVB: - return VK_FORMAT_R32G32_SFLOAT; - case KRENGINE_ATTRIB_BONEINDEXES: - return VK_FORMAT_R8G8B8A8_UINT; - case KRENGINE_ATTRIB_VERTEX_SHORT: - case KRENGINE_ATTRIB_NORMAL_SHORT: - case KRENGINE_ATTRIB_TANGENT_SHORT: - return VK_FORMAT_R16G16B16A16_SNORM; - case KRENGINE_ATTRIB_TEXUVA_SHORT: - case KRENGINE_ATTRIB_TEXUVB_SHORT: - return VK_FORMAT_R16G16_SNORM; + case KRENGINE_ATTRIB_VERTEX: + case KRENGINE_ATTRIB_NORMAL: + case KRENGINE_ATTRIB_TANGENT: + case KRENGINE_ATTRIB_BONEWEIGHTS: + return VK_FORMAT_R32G32B32_SFLOAT; + case KRENGINE_ATTRIB_TEXUVA: + case KRENGINE_ATTRIB_TEXUVB: + return VK_FORMAT_R32G32_SFLOAT; + case KRENGINE_ATTRIB_BONEINDEXES: + return VK_FORMAT_R8G8B8A8_UINT; + case KRENGINE_ATTRIB_VERTEX_SHORT: + case KRENGINE_ATTRIB_NORMAL_SHORT: + case KRENGINE_ATTRIB_TANGENT_SHORT: + return VK_FORMAT_R16G16B16A16_SNORM; + case KRENGINE_ATTRIB_TEXUVA_SHORT: + case KRENGINE_ATTRIB_TEXUVB_SHORT: + return VK_FORMAT_R16G16_SNORM; } } int KRMesh::getBoneCount() { - pack_header *header = getHeader(); - int bone_count = header->bone_count; - return bone_count; + pack_header* header = getHeader(); + int bone_count = header->bone_count; + return bone_count; } -char *KRMesh::getBoneName(int bone_index) +char* KRMesh::getBoneName(int bone_index) { - return getBone(bone_index)->szName; + return getBone(bone_index)->szName; } Matrix4 KRMesh::getBoneBindPose(int bone_index) { - return Matrix4::Create(getBone(bone_index)->bind_pose); + return Matrix4::Create(getBone(bone_index)->bind_pose); } ModelFormat KRMesh::getModelFormat() const { - ModelFormat f = (ModelFormat)getHeader()->model_format; - return f; + ModelFormat f = (ModelFormat)getHeader()->model_format; + return f; } -bool KRMesh::rayCast(const Vector3 &start, const Vector3 &dir, const Triangle3 &tri, const Vector3 &tri_n0, const Vector3 &tri_n1, const Vector3 &tri_n2, HitInfo &hitinfo) +bool KRMesh::rayCast(const Vector3& start, const Vector3& dir, const Triangle3& tri, const Vector3& tri_n0, const Vector3& tri_n1, const Vector3& tri_n2, HitInfo& hitinfo) { - Vector3 hit_point; - if(tri.rayCast(start, dir, hit_point)) { - // ---===--- hit_point is in triangle ---===--- - - float new_hit_distance = (hit_point - start).magnitude(); - if(new_hit_distance < hitinfo.getDistance() || !hitinfo.didHit()) { - // Update the hitinfo object if this hit is closer than the prior hit - - // Interpolate between the three vertex normals, performing a 3-way lerp of tri_n0, tri_n1, and tri_n2 - float distance_v0 = (tri[0] - hit_point).magnitude(); - float distance_v1 = (tri[1] - hit_point).magnitude(); - float distance_v2 = (tri[2] - hit_point).magnitude(); - float distance_total = distance_v0 + distance_v1 + distance_v2; - distance_v0 /= distance_total; - distance_v1 /= distance_total; - distance_v2 /= distance_total; - Vector3 normal = Vector3::Normalize(tri_n0 * (1.0f - distance_v0) + tri_n1 * (1.0f - distance_v1) + tri_n2 * (1.0f - distance_v2)); - - hitinfo = HitInfo(hit_point, normal, new_hit_distance); - return true; - } else { - return false; // The hit was farther than an existing hit - } + Vector3 hit_point; + if (tri.rayCast(start, dir, hit_point)) { + // ---===--- hit_point is in triangle ---===--- + float new_hit_distance = (hit_point - start).magnitude(); + if (new_hit_distance < hitinfo.getDistance() || !hitinfo.didHit()) { + // Update the hitinfo object if this hit is closer than the prior hit + + // Interpolate between the three vertex normals, performing a 3-way lerp of tri_n0, tri_n1, and tri_n2 + float distance_v0 = (tri[0] - hit_point).magnitude(); + float distance_v1 = (tri[1] - hit_point).magnitude(); + float distance_v2 = (tri[2] - hit_point).magnitude(); + float distance_total = distance_v0 + distance_v1 + distance_v2; + distance_v0 /= distance_total; + distance_v1 /= distance_total; + distance_v2 /= distance_total; + Vector3 normal = Vector3::Normalize(tri_n0 * (1.0f - distance_v0) + tri_n1 * (1.0f - distance_v1) + tri_n2 * (1.0f - distance_v2)); + + hitinfo = HitInfo(hit_point, normal, new_hit_distance); + return true; } else { - // Dit not hit the triangle - return false; + return false; // The hit was farther than an existing hit } -} - - -bool KRMesh::rayCast(const Vector3 &start, const Vector3 &dir, HitInfo &hitinfo) const -{ - m_pData->lock(); - bool hit_found = false; - for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) { -// int vertex_start = getSubmesh(submesh_index)->start_vertex; - int vertex_count = getVertexCount(submesh_index); - switch(getModelFormat()) { - case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: - case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: - for(int triangle_index=0; triangle_index < vertex_count / 3; triangle_index++) { - int tri_vert_index[3]; // FINDME, HACK! This is not very efficient for indexed collider meshes... - tri_vert_index[0] = getTriangleVertexIndex(submesh_index, triangle_index*3); - tri_vert_index[1] = getTriangleVertexIndex(submesh_index, triangle_index*3 + 1); - tri_vert_index[2] = getTriangleVertexIndex(submesh_index, triangle_index*3 + 2); - - Triangle3 tri = Triangle3::Create(getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[2])); - - if(rayCast(start, dir, tri, getVertexNormal(tri_vert_index[0]), getVertexNormal(tri_vert_index[1]), getVertexNormal(tri_vert_index[2]), hitinfo)) hit_found = true; - } - break; - /* - - NOTE: Not yet supported: - - case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: - case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP: - for(int triangle_index=0; triangle_index < vertex_count - 2; triangle_index++) { - int tri_vert_index[3]; - tri_vert_index[0] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3); - tri_vert_index[1] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 1); - tri_vert_index[2] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 2); - - if(rayCast(v0, dir, getVertexPosition(vertex_start + triangle_index), getVertexPosition(vertex_start + triangle_index+1), getVertexPosition(vertex_start + triangle_index+2), getVertexNormal(vertex_start + triangle_index), getVertexNormal(vertex_start + triangle_index+1), getVertexNormal(vertex_start + triangle_index+2), hitinfo)) hit_found = true; - } - break; - */ - default: - break; - } - } - m_pData->unlock(); - return hit_found; -} - - -bool KRMesh::sphereCast(const Matrix4 &model_to_world, const Vector3 &v0, const Vector3 &v1, float radius, HitInfo &hitinfo) const -{ - m_pData->lock(); - - bool hit_found = false; - for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) { - int vertex_count = getVertexCount(submesh_index); - switch(getModelFormat()) { - case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: - case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: - for(int triangle_index=0; triangle_index < vertex_count / 3; triangle_index++) { - int tri_vert_index[3]; // FINDME, HACK! This is not very efficient for indexed collider meshes... - tri_vert_index[0] = getTriangleVertexIndex(submesh_index, triangle_index*3); - tri_vert_index[1] = getTriangleVertexIndex(submesh_index, triangle_index*3 + 1); - tri_vert_index[2] = getTriangleVertexIndex(submesh_index, triangle_index*3 + 2); - - Triangle3 tri = Triangle3::Create(getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[2])); - - if(sphereCast(model_to_world, v0, v1, radius, tri, hitinfo)) hit_found = true; - - /* - Triangle3 tri2 = Triangle3(getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[2])); - - if(sphereCast(model_to_world, v0, v1, radius, tri2, new_hitinfo)) hit_found = true; - */ - } - break; - /* - - NOTE: Not yet supported: - - case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: - case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP: - for(int triangle_index=0; triangle_index < vertex_count - 2; triangle_index++) { - int tri_vert_index[3]; - tri_vert_index[0] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3); - tri_vert_index[1] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 1); - tri_vert_index[2] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 2); - - if(sphereCast(model_to_world, v0, v1, getVertexPosition(vertex_start + triangle_index), getVertexPosition(vertex_start + triangle_index+1), getVertexPosition(vertex_start + triangle_index+2), getVertexNormal(vertex_start + triangle_index), getVertexNormal(vertex_start + triangle_index+1), getVertexNormal(vertex_start + triangle_index+2), new_hitinfo)) hit_found = true; - } - break; - */ - default: - break; - } - } - m_pData->unlock(); - - return hit_found; -} - -bool KRMesh::sphereCast(const Matrix4 &model_to_world, const Vector3 &v0, const Vector3 &v1, float radius, const Triangle3 &tri, HitInfo &hitinfo) -{ - - Vector3 dir = Vector3::Normalize(v1 - v0); - Vector3 start = v0; - - Vector3 new_hit_point; - float new_hit_distance; - - Triangle3 world_tri = Triangle3::Create(Matrix4::Dot(model_to_world, tri[0]), Matrix4::Dot(model_to_world, tri[1]), Matrix4::Dot(model_to_world, tri[2])); - - if(world_tri.sphereCast(start, dir, radius, new_hit_point, new_hit_distance)) { - if((!hitinfo.didHit() || hitinfo.getDistance() > new_hit_distance) && new_hit_distance <= (v1 - v0).magnitude()) { - - /* - // Interpolate between the three vertex normals, performing a 3-way lerp of tri_n0, tri_n1, and tri_n2 - float distance_v0 = (tri[0] - new_hit_point).magnitude(); - float distance_v1 = (tri[1] - new_hit_point).magnitude(); - float distance_v2 = (tri[2] - new_hit_point).magnitude(); - float distance_total = distance_v0 + distance_v1 + distance_v2; - distance_v0 /= distance_total; - distance_v1 /= distance_total; - distance_v2 /= distance_total; - Vector3 normal = Vector3::Normalize(Matrix4::DotNoTranslate(model_to_world, (tri_n0 * (1.0 - distance_v0) + tri_n1 * (1.0 - distance_v1) + tri_n2 * (1.0 - distance_v2)))); - */ - hitinfo = HitInfo(new_hit_point, world_tri.calculateNormal(), new_hit_distance); - return true; - } - } - + } else { + // Dit not hit the triangle return false; + } + } -bool KRMesh::lineCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo) const + +bool KRMesh::rayCast(const Vector3& start, const Vector3& dir, HitInfo& hitinfo) const { - m_pData->lock(); - HitInfo new_hitinfo; - Vector3 dir = Vector3::Normalize(v1 - v0); - if(rayCast(v0, dir, new_hitinfo)) { - if((new_hitinfo.getPosition() - v0).sqrMagnitude() <= (v1 - v0).sqrMagnitude()) { - // The hit was between v1 and v2 - hitinfo = new_hitinfo; - m_pData->unlock(); - return true; - } + m_pData->lock(); + bool hit_found = false; + for (int submesh_index = 0; submesh_index < getSubmeshCount(); submesh_index++) { + // int vertex_start = getSubmesh(submesh_index)->start_vertex; + int vertex_count = getVertexCount(submesh_index); + switch (getModelFormat()) { + case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: + case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: + for (int triangle_index = 0; triangle_index < vertex_count / 3; triangle_index++) { + int tri_vert_index[3]; // FINDME, HACK! This is not very efficient for indexed collider meshes... + tri_vert_index[0] = getTriangleVertexIndex(submesh_index, triangle_index * 3); + tri_vert_index[1] = getTriangleVertexIndex(submesh_index, triangle_index * 3 + 1); + tri_vert_index[2] = getTriangleVertexIndex(submesh_index, triangle_index * 3 + 2); + + Triangle3 tri = Triangle3::Create(getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[2])); + + if (rayCast(start, dir, tri, getVertexNormal(tri_vert_index[0]), getVertexNormal(tri_vert_index[1]), getVertexNormal(tri_vert_index[2]), hitinfo)) hit_found = true; + } + break; + /* + + NOTE: Not yet supported: + + case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: + case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP: + for(int triangle_index=0; triangle_index < vertex_count - 2; triangle_index++) { + int tri_vert_index[3]; + tri_vert_index[0] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3); + tri_vert_index[1] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 1); + tri_vert_index[2] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 2); + + if(rayCast(v0, dir, getVertexPosition(vertex_start + triangle_index), getVertexPosition(vertex_start + triangle_index+1), getVertexPosition(vertex_start + triangle_index+2), getVertexNormal(vertex_start + triangle_index), getVertexNormal(vertex_start + triangle_index+1), getVertexNormal(vertex_start + triangle_index+2), hitinfo)) hit_found = true; + } + break; + */ + default: + break; } - m_pData->unlock(); - return false; // Either no hit, or the hit was beyond v1 + } + m_pData->unlock(); + return hit_found; +} + + +bool KRMesh::sphereCast(const Matrix4& model_to_world, const Vector3& v0, const Vector3& v1, float radius, HitInfo& hitinfo) const +{ + m_pData->lock(); + + bool hit_found = false; + for (int submesh_index = 0; submesh_index < getSubmeshCount(); submesh_index++) { + int vertex_count = getVertexCount(submesh_index); + switch (getModelFormat()) { + case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: + case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: + for (int triangle_index = 0; triangle_index < vertex_count / 3; triangle_index++) { + int tri_vert_index[3]; // FINDME, HACK! This is not very efficient for indexed collider meshes... + tri_vert_index[0] = getTriangleVertexIndex(submesh_index, triangle_index * 3); + tri_vert_index[1] = getTriangleVertexIndex(submesh_index, triangle_index * 3 + 1); + tri_vert_index[2] = getTriangleVertexIndex(submesh_index, triangle_index * 3 + 2); + + Triangle3 tri = Triangle3::Create(getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[2])); + + if (sphereCast(model_to_world, v0, v1, radius, tri, hitinfo)) hit_found = true; + + /* + Triangle3 tri2 = Triangle3(getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[2])); + + if(sphereCast(model_to_world, v0, v1, radius, tri2, new_hitinfo)) hit_found = true; + */ + } + break; + /* + + NOTE: Not yet supported: + + case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: + case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP: + for(int triangle_index=0; triangle_index < vertex_count - 2; triangle_index++) { + int tri_vert_index[3]; + tri_vert_index[0] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3); + tri_vert_index[1] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 1); + tri_vert_index[2] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 2); + + if(sphereCast(model_to_world, v0, v1, getVertexPosition(vertex_start + triangle_index), getVertexPosition(vertex_start + triangle_index+1), getVertexPosition(vertex_start + triangle_index+2), getVertexNormal(vertex_start + triangle_index), getVertexNormal(vertex_start + triangle_index+1), getVertexNormal(vertex_start + triangle_index+2), new_hitinfo)) hit_found = true; + } + break; + */ + default: + break; + } + } + m_pData->unlock(); + + return hit_found; +} + +bool KRMesh::sphereCast(const Matrix4& model_to_world, const Vector3& v0, const Vector3& v1, float radius, const Triangle3& tri, HitInfo& hitinfo) +{ + + Vector3 dir = Vector3::Normalize(v1 - v0); + Vector3 start = v0; + + Vector3 new_hit_point; + float new_hit_distance; + + Triangle3 world_tri = Triangle3::Create(Matrix4::Dot(model_to_world, tri[0]), Matrix4::Dot(model_to_world, tri[1]), Matrix4::Dot(model_to_world, tri[2])); + + if (world_tri.sphereCast(start, dir, radius, new_hit_point, new_hit_distance)) { + if ((!hitinfo.didHit() || hitinfo.getDistance() > new_hit_distance) && new_hit_distance <= (v1 - v0).magnitude()) { + + /* + // Interpolate between the three vertex normals, performing a 3-way lerp of tri_n0, tri_n1, and tri_n2 + float distance_v0 = (tri[0] - new_hit_point).magnitude(); + float distance_v1 = (tri[1] - new_hit_point).magnitude(); + float distance_v2 = (tri[2] - new_hit_point).magnitude(); + float distance_total = distance_v0 + distance_v1 + distance_v2; + distance_v0 /= distance_total; + distance_v1 /= distance_total; + distance_v2 /= distance_total; + Vector3 normal = Vector3::Normalize(Matrix4::DotNoTranslate(model_to_world, (tri_n0 * (1.0 - distance_v0) + tri_n1 * (1.0 - distance_v1) + tri_n2 * (1.0 - distance_v2)))); + */ + hitinfo = HitInfo(new_hit_point, world_tri.calculateNormal(), new_hit_distance); + return true; + } + } + + return false; +} + +bool KRMesh::lineCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo) const +{ + m_pData->lock(); + HitInfo new_hitinfo; + Vector3 dir = Vector3::Normalize(v1 - v0); + if (rayCast(v0, dir, new_hitinfo)) { + if ((new_hitinfo.getPosition() - v0).sqrMagnitude() <= (v1 - v0).sqrMagnitude()) { + // The hit was between v1 and v2 + hitinfo = new_hitinfo; + m_pData->unlock(); + return true; + } + } + m_pData->unlock(); + return false; // Either no hit, or the hit was beyond v1 } void KRMesh::convertToIndexed() { - m_pData->lock(); - 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 - int vertex_index_offset = 0; - int vertex_index_base_start_vertex = 0; - - mesh_info mi; - - int bone_count = getBoneCount(); - for(int bone_index=0; bone_index < bone_count; bone_index++) { - mi.bone_names.push_back(getBoneName(bone_index)); - mi.bone_bind_poses.push_back(getBoneBindPose(bone_index)); + m_pData->lock(); + 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 + int vertex_index_offset = 0; + int vertex_index_base_start_vertex = 0; + + mesh_info mi; + + int bone_count = getBoneCount(); + for (int bone_index = 0; bone_index < bone_count; 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++) { + mi.material_names.push_back(getSubmesh(submesh_index)->szName); + + int vertexes_remaining = getVertexCount(submesh_index); + + int vertex_count = vertexes_remaining; + if (vertex_count > 0xffff) { + vertex_count = 0xffff; } - - for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) { - mi.material_names.push_back(getSubmesh(submesh_index)->szName); - - int vertexes_remaining = getVertexCount(submesh_index); - - int vertex_count = vertexes_remaining; - if(vertex_count > 0xffff) { - vertex_count = 0xffff; - } - - if(submesh_index == 0 || vertex_index_offset + vertex_count > 0xffff) { - mi.vertex_index_bases.push_back(std::pair((int)mi.vertex_indexes.size(), (int)mi.vertices.size())); - vertex_index_offset = 0; - vertex_index_base_start_vertex = (int)mi.vertices.size(); - } - - mi.submesh_starts.push_back((int)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; - - - while(vertexes_remaining) { - - //typedef std::pair, std::vector > vertex_key_t; - typedef std::string vertex_key_t; - - unordered_map prev_indexes = unordered_map(); - - for(int i=0; i < vertex_count; i++) { - - Vector3 vertex_position = getVertexPosition(source_index); - Vector2 vertex_uva = getVertexUVA(source_index); - Vector2 vertex_uvb = getVertexUVB(source_index); - Vector3 vertex_normal = getVertexNormal(source_index); - Vector3 vertex_tangent = getVertexTangent(source_index); - std::vector vertex_bone_indexes; - if(has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) { - vertex_bone_indexes.push_back(getBoneIndex(source_index, 0)); - vertex_bone_indexes.push_back(getBoneIndex(source_index, 1)); - vertex_bone_indexes.push_back(getBoneIndex(source_index, 2)); - vertex_bone_indexes.push_back(getBoneIndex(source_index, 3)); - } - std::vector vertex_bone_weights; - if(has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS)) { - vertex_bone_weights.push_back(getBoneWeight(source_index, 0)); - vertex_bone_weights.push_back(getBoneWeight(source_index, 1)); - vertex_bone_weights.push_back(getBoneWeight(source_index, 2)); - vertex_bone_weights.push_back(getBoneWeight(source_index, 3)); - } - - - - unsigned char *vertex_data = (unsigned char *)getVertexData(source_index); - for(int b=0; b < m_vertex_size; b++) { - const char *szHex = "0123456789ABCDEF"; - szKey[b*2] = szHex[vertex_data[b] & 0x0f]; - szKey[b*2+1] = szHex[((vertex_data[b] & 0xf0) >> 4)]; - } - szKey[m_vertex_size * 2] = '\0'; - - vertex_key_t vertex_key = szKey; - /* - - vertex_key_t vertex_key = std::make_pair(std::vector(), std::vector()); - - if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX) || has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { - vertex_key.first.push_back(vertex_position.x); - vertex_key.first.push_back(vertex_position.y); - vertex_key.first.push_back(vertex_position.z); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL) || has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { - vertex_key.first.push_back(vertex_normal.x); - vertex_key.first.push_back(vertex_normal.y); - vertex_key.first.push_back(vertex_normal.z); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { - vertex_key.first.push_back(vertex_uva.x); - vertex_key.first.push_back(vertex_uva.y); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { - vertex_key.first.push_back(vertex_uvb.x); - vertex_key.first.push_back(vertex_uvb.y); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT) || has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { - vertex_key.first.push_back(vertex_tangent.x); - vertex_key.first.push_back(vertex_tangent.y); - vertex_key.first.push_back(vertex_tangent.z); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) { - vertex_key.second.push_back(vertex_bone_indexes[0]); - vertex_key.second.push_back(vertex_bone_indexes[1]); - vertex_key.second.push_back(vertex_bone_indexes[2]); - vertex_key.second.push_back(vertex_bone_indexes[3]); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS)) { - vertex_key.first.push_back(vertex_bone_weights[0]); - vertex_key.first.push_back(vertex_bone_weights[1]); - vertex_key.first.push_back(vertex_bone_weights[2]); - vertex_key.first.push_back(vertex_bone_weights[3]); - } - */ - int found_index = -1; - if(prev_indexes.count(vertex_key) == 0) { - found_index = (int)mi.vertices.size() - vertex_index_base_start_vertex; - if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX) || has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { - mi.vertices.push_back(vertex_position); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL) || has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { - mi.normals.push_back(vertex_normal); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT) || has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { - mi.tangents.push_back(vertex_tangent); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { - mi.uva.push_back(vertex_uva); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { - mi.uvb.push_back(vertex_uvb); - } - if(has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) { - mi.bone_indexes.push_back(vertex_bone_indexes); - - } - if(has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS)) { - mi.bone_weights.push_back(vertex_bone_weights); - } - prev_indexes[vertex_key] = found_index; - } else { - found_index = prev_indexes[vertex_key]; - } - - 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++; - } - - vertexes_remaining -= vertex_count; - vertex_index_offset += vertex_count; - - - vertex_count = vertexes_remaining; - if(vertex_count > 0xffff) { - vertex_count = 0xffff; - } - - if(vertex_index_offset + vertex_count > 0xffff) { - mi.vertex_index_bases.push_back(std::pair((int)mi.vertex_indexes.size(), (int)mi.vertices.size())); - vertex_index_offset = 0; - vertex_index_base_start_vertex = (int)mi.vertices.size(); - } - } + + if (submesh_index == 0 || vertex_index_offset + vertex_count > 0xffff) { + mi.vertex_index_bases.push_back(std::pair((int)mi.vertex_indexes.size(), (int)mi.vertices.size())); + vertex_index_offset = 0; + vertex_index_base_start_vertex = (int)mi.vertices.size(); } - - delete[] szKey; - - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Convert to indexed, before: %i after: %i (%.2f%% saving)", getHeader()->vertex_count, mi.vertices.size(), ((float)getHeader()->vertex_count - (float)mi.vertices.size()) / (float)getHeader()->vertex_count * 100.0f); - - switch (getModelFormat()) { - case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: - mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES; - break; - case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: - mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP; - break; - default: - assert(false); + + mi.submesh_starts.push_back((int)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; + + + while (vertexes_remaining) { + + //typedef std::pair, std::vector > vertex_key_t; + typedef std::string vertex_key_t; + + unordered_map prev_indexes = unordered_map(); + + for (int i = 0; i < vertex_count; i++) { + + Vector3 vertex_position = getVertexPosition(source_index); + Vector2 vertex_uva = getVertexUVA(source_index); + Vector2 vertex_uvb = getVertexUVB(source_index); + Vector3 vertex_normal = getVertexNormal(source_index); + Vector3 vertex_tangent = getVertexTangent(source_index); + std::vector vertex_bone_indexes; + if (has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) { + vertex_bone_indexes.push_back(getBoneIndex(source_index, 0)); + vertex_bone_indexes.push_back(getBoneIndex(source_index, 1)); + vertex_bone_indexes.push_back(getBoneIndex(source_index, 2)); + vertex_bone_indexes.push_back(getBoneIndex(source_index, 3)); + } + std::vector vertex_bone_weights; + if (has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS)) { + vertex_bone_weights.push_back(getBoneWeight(source_index, 0)); + vertex_bone_weights.push_back(getBoneWeight(source_index, 1)); + vertex_bone_weights.push_back(getBoneWeight(source_index, 2)); + vertex_bone_weights.push_back(getBoneWeight(source_index, 3)); + } + + + + unsigned char* vertex_data = (unsigned char*)getVertexData(source_index); + for (int b = 0; b < m_vertex_size; b++) { + const char* szHex = "0123456789ABCDEF"; + szKey[b * 2] = szHex[vertex_data[b] & 0x0f]; + szKey[b * 2 + 1] = szHex[((vertex_data[b] & 0xf0) >> 4)]; + } + szKey[m_vertex_size * 2] = '\0'; + + vertex_key_t vertex_key = szKey; + /* + + vertex_key_t vertex_key = std::make_pair(std::vector(), std::vector()); + + if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX) || has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { + vertex_key.first.push_back(vertex_position.x); + vertex_key.first.push_back(vertex_position.y); + vertex_key.first.push_back(vertex_position.z); + } + if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL) || has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { + vertex_key.first.push_back(vertex_normal.x); + vertex_key.first.push_back(vertex_normal.y); + vertex_key.first.push_back(vertex_normal.z); + } + if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { + vertex_key.first.push_back(vertex_uva.x); + vertex_key.first.push_back(vertex_uva.y); + } + if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { + vertex_key.first.push_back(vertex_uvb.x); + vertex_key.first.push_back(vertex_uvb.y); + } + if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT) || has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { + vertex_key.first.push_back(vertex_tangent.x); + vertex_key.first.push_back(vertex_tangent.y); + vertex_key.first.push_back(vertex_tangent.z); + } + if(has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) { + vertex_key.second.push_back(vertex_bone_indexes[0]); + vertex_key.second.push_back(vertex_bone_indexes[1]); + vertex_key.second.push_back(vertex_bone_indexes[2]); + vertex_key.second.push_back(vertex_bone_indexes[3]); + } + if(has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS)) { + vertex_key.first.push_back(vertex_bone_weights[0]); + vertex_key.first.push_back(vertex_bone_weights[1]); + vertex_key.first.push_back(vertex_bone_weights[2]); + vertex_key.first.push_back(vertex_bone_weights[3]); + } + */ + int found_index = -1; + if (prev_indexes.count(vertex_key) == 0) { + found_index = (int)mi.vertices.size() - vertex_index_base_start_vertex; + if (has_vertex_attribute(KRENGINE_ATTRIB_VERTEX) || has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { + mi.vertices.push_back(vertex_position); + } + if (has_vertex_attribute(KRENGINE_ATTRIB_NORMAL) || has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { + mi.normals.push_back(vertex_normal); + } + if (has_vertex_attribute(KRENGINE_ATTRIB_TANGENT) || has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { + mi.tangents.push_back(vertex_tangent); + } + if (has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { + mi.uva.push_back(vertex_uva); + } + if (has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { + mi.uvb.push_back(vertex_uvb); + } + if (has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) { + mi.bone_indexes.push_back(vertex_bone_indexes); + + } + if (has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS)) { + mi.bone_weights.push_back(vertex_bone_weights); + } + prev_indexes[vertex_key] = found_index; + } else { + found_index = prev_indexes[vertex_key]; + } + + 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++; + } + + vertexes_remaining -= vertex_count; + vertex_index_offset += vertex_count; + + + vertex_count = vertexes_remaining; + if (vertex_count > 0xffff) { + vertex_count = 0xffff; + } + + if (vertex_index_offset + vertex_count > 0xffff) { + mi.vertex_index_bases.push_back(std::pair((int)mi.vertex_indexes.size(), (int)mi.vertices.size())); + vertex_index_offset = 0; + vertex_index_base_start_vertex = (int)mi.vertices.size(); + } } - - m_pData->unlock(); - LoadData(mi, false, false); + } + + delete[] szKey; + + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Convert to indexed, before: %i after: %i (%.2f%% saving)", getHeader()->vertex_count, mi.vertices.size(), ((float)getHeader()->vertex_count - (float)mi.vertices.size()) / (float)getHeader()->vertex_count * 100.0f); + + switch (getModelFormat()) { + case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: + mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES; + break; + case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: + mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP; + break; + default: + assert(false); + } + + m_pData->unlock(); + LoadData(mi, false, false); } void KRMesh::optimize() { - switch(getModelFormat()) { - case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: - case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP: - optimizeIndexes(); - break; - case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: - case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: - convertToIndexed(); // HACK, FINDME, TODO - This may not be ideal in every case and should be exposed through the API independently - break; - } + switch (getModelFormat()) { + case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: + case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP: + optimizeIndexes(); + break; + case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP: + case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES: + convertToIndexed(); // HACK, FINDME, TODO - This may not be ideal in every case and should be exposed through the API independently + break; + } } -void KRMesh::getIndexedRange(int index_group, int &start_index_offset, int &start_vertex_offset, int &index_count, int &vertex_count) const { - pack_header *h = getHeader(); - __uint32_t *index_base_data = getIndexBaseData(); - start_index_offset = index_base_data[index_group * 2]; - start_vertex_offset = index_base_data[index_group * 2 + 1]; - if(index_group + 1 < h->index_base_count) { - index_count = index_base_data[index_group * 2 + 2] - start_index_offset; - vertex_count = index_base_data[index_group * 2 + 3] - start_vertex_offset; - } else { - index_count = h->index_count - start_index_offset; - vertex_count = h->vertex_count - start_vertex_offset; - } +void KRMesh::getIndexedRange(int index_group, int& start_index_offset, int& start_vertex_offset, int& index_count, int& vertex_count) const +{ + pack_header* h = getHeader(); + __uint32_t* index_base_data = getIndexBaseData(); + start_index_offset = index_base_data[index_group * 2]; + start_vertex_offset = index_base_data[index_group * 2 + 1]; + if (index_group + 1 < h->index_base_count) { + index_count = index_base_data[index_group * 2 + 2] - start_index_offset; + vertex_count = index_base_data[index_group * 2 + 3] - start_vertex_offset; + } else { + index_count = h->index_count - start_index_offset; + vertex_count = h->vertex_count - start_vertex_offset; + } } int KRMesh::getTriangleVertexIndex(int submesh, int index) const { - switch(getModelFormat()) { - case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: - { - __uint16_t *index_data = getIndexData(); - - - int start_index_offset, start_vertex_offset, index_count, vertex_count; - int index_group = getSubmesh(submesh)->index_group; - int index_group_offset = getSubmesh(submesh)->index_group_offset; - int remaining_vertices = index_group_offset + index; - getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - while(remaining_vertices >= index_count) { - remaining_vertices -= index_count; - getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - } - return index_data[start_index_offset + remaining_vertices] + start_vertex_offset; - } - break; - default: - return getSubmesh(submesh)->start_vertex + index; - break; + switch (getModelFormat()) { + case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: + { + __uint16_t* index_data = getIndexData(); + + + int start_index_offset, start_vertex_offset, index_count, vertex_count; + int index_group = getSubmesh(submesh)->index_group; + int index_group_offset = getSubmesh(submesh)->index_group_offset; + int remaining_vertices = index_group_offset + index; + getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); + while (remaining_vertices >= index_count) { + remaining_vertices -= index_count; + getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); } + return index_data[start_index_offset + remaining_vertices] + start_vertex_offset; + } + break; + default: + return getSubmesh(submesh)->start_vertex + index; + break; + } } void KRMesh::optimizeIndexes() { - // TODO - Re-enable this once crash with KRMeshSphere vertices is corrected - return; + // TODO - Re-enable this once crash with KRMeshSphere vertices is corrected + return; - m_pData->lock(); - // TODO - Implement optimization for indexed strips - if(getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) { + m_pData->lock(); + // TODO - Implement optimization for indexed strips + if (getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) { - __uint16_t *new_indices = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t)); - __uint16_t *vertex_mapping = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t)); - unsigned char *new_vertex_data = (unsigned char *)malloc(m_vertex_size * 0x10000); - - // FINDME, TODO, HACK - This will segfault if the KRData object is still mmap'ed to a read-only file. Need to detach from the file before calling this function. Currently, this function is only being used during the import process, so it isn't going to cause any problems for now. - - pack_header *header = getHeader(); - - __uint16_t *index_data = getIndexData(); - // unsigned char *vertex_data = getVertexData(); // Uncomment when re-enabling Step 2 below - - for(int submesh_index=0; submesh_index < header->submesh_count; submesh_index++) { - pack_material *submesh = getSubmesh(submesh_index); - int vertexes_remaining = submesh->vertex_count; - int index_group = getSubmesh(submesh_index)->index_group; - int index_group_offset = getSubmesh(submesh_index)->index_group_offset; - while(vertexes_remaining > 0) { - int start_index_offset, start_vertex_offset, index_count, vertex_count; - getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - - int vertexes_to_process = vertexes_remaining; - if(vertexes_to_process + index_group_offset > 0xffff) { - vertexes_to_process = 0xffff - index_group_offset; - } - - __uint16_t *index_data_start = index_data + start_index_offset + index_group_offset; - - - // ----====---- Step 1: Optimize triangle drawing order to maximize use of the GPU's post-transform vertex cache ----====---- - Forsyth::OptimizeFaces(index_data_start, vertexes_to_process, vertex_count, new_indices, 16); // FINDME, TODO - GPU post-transform vertex cache size of 16 should be configureable - memcpy(index_data_start, new_indices, vertexes_to_process * sizeof(__uint16_t)); - vertexes_remaining -= vertexes_to_process; - - /* - - unsigned char * vertex_data_start = vertex_data + start_vertex_offset; - - // ----====---- Step 2: Re-order the vertex data to maintain cache coherency ----====---- - for(int i=0; i < vertex_count; i++) { - vertex_mapping[i] = i; - } - int new_vertex_index=0; - for(int index_number=0; index_number new_vertex_index) { - // Swap prev_vertex_index and new_vertex_index - - for(int i=0; i < index_count; i++) { - if(index_data_start[i] == prev_vertex_index) { - index_data_start[i] = new_vertex_index; - } else if(index_data_start[i] == new_vertex_index) { - index_data_start[i] = prev_vertex_index; - } - } - - int tmp = vertex_mapping[prev_vertex_index]; - vertex_mapping[prev_vertex_index] = vertex_mapping[new_vertex_index]; - vertex_mapping[new_vertex_index] = tmp; - - - new_vertex_index++; + __uint16_t* new_indices = (__uint16_t*)malloc(0x10000 * sizeof(__uint16_t)); + __uint16_t* vertex_mapping = (__uint16_t*)malloc(0x10000 * sizeof(__uint16_t)); + unsigned char* new_vertex_data = (unsigned char*)malloc(m_vertex_size * 0x10000); + + // FINDME, TODO, HACK - This will segfault if the KRData object is still mmap'ed to a read-only file. Need to detach from the file before calling this function. Currently, this function is only being used during the import process, so it isn't going to cause any problems for now. + + pack_header* header = getHeader(); + + __uint16_t* index_data = getIndexData(); + // unsigned char *vertex_data = getVertexData(); // Uncomment when re-enabling Step 2 below + + for (int submesh_index = 0; submesh_index < header->submesh_count; submesh_index++) { + pack_material* submesh = getSubmesh(submesh_index); + int vertexes_remaining = submesh->vertex_count; + int index_group = getSubmesh(submesh_index)->index_group; + int index_group_offset = getSubmesh(submesh_index)->index_group_offset; + while (vertexes_remaining > 0) { + int start_index_offset, start_vertex_offset, index_count, vertex_count; + getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); + + int vertexes_to_process = vertexes_remaining; + if (vertexes_to_process + index_group_offset > 0xffff) { + vertexes_to_process = 0xffff - index_group_offset; + } + + __uint16_t* index_data_start = index_data + start_index_offset + index_group_offset; + + + // ----====---- Step 1: Optimize triangle drawing order to maximize use of the GPU's post-transform vertex cache ----====---- + Forsyth::OptimizeFaces(index_data_start, vertexes_to_process, vertex_count, new_indices, 16); // FINDME, TODO - GPU post-transform vertex cache size of 16 should be configureable + memcpy(index_data_start, new_indices, vertexes_to_process * sizeof(__uint16_t)); + vertexes_remaining -= vertexes_to_process; + + /* + + unsigned char * vertex_data_start = vertex_data + start_vertex_offset; + + // ----====---- Step 2: Re-order the vertex data to maintain cache coherency ----====---- + for(int i=0; i < vertex_count; i++) { + vertex_mapping[i] = i; + } + int new_vertex_index=0; + for(int index_number=0; index_number new_vertex_index) { + // Swap prev_vertex_index and new_vertex_index + + for(int i=0; i < index_count; i++) { + if(index_data_start[i] == prev_vertex_index) { + index_data_start[i] = new_vertex_index; + } else if(index_data_start[i] == new_vertex_index) { + index_data_start[i] = prev_vertex_index; } } - - for(int i=0; i < vertex_count; i++) { - memcpy(new_vertex_data + vertex_mapping[i] * m_vertex_size, vertex_data_start + i * m_vertex_size, m_vertex_size); - } - memcpy(vertex_data_start, new_vertex_data, vertex_count * m_vertex_size); - */ - - - - index_group_offset = 0; + + int tmp = vertex_mapping[prev_vertex_index]; + vertex_mapping[prev_vertex_index] = vertex_mapping[new_vertex_index]; + vertex_mapping[new_vertex_index] = tmp; + + + new_vertex_index++; } } - - free(new_indices); - free(vertex_mapping); - free(new_vertex_data); - } // if(getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) - - m_pData->unlock(); + + for(int i=0; i < vertex_count; i++) { + memcpy(new_vertex_data + vertex_mapping[i] * m_vertex_size, vertex_data_start + i * m_vertex_size, m_vertex_size); + } + memcpy(vertex_data_start, new_vertex_data, vertex_count * m_vertex_size); + */ + + + + index_group_offset = 0; + } + } + + free(new_indices); + free(vertex_mapping); + free(new_vertex_data); + } // if(getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) + + m_pData->unlock(); } diff --git a/kraken/KRMesh.h b/kraken/KRMesh.h index 0c2e47c..b795c65 100755 --- a/kraken/KRMesh.h +++ b/kraken/KRMesh.h @@ -65,230 +65,241 @@ enum class ModelFormat : __uint8_t KRENGINE_MODEL_FORMAT_INDEXED_STRIP }; -class KRMesh : public KRResource { +class KRMesh : public KRResource +{ public: - static void parseName(const std::string& name, std::string& lodBaseName, int& lodCoverage); + static void parseName(const std::string& name, std::string& lodBaseName, int& lodCoverage); - KRMesh(KRContext &context, std::string name, KRDataBlock *data); - KRMesh(KRContext &context, std::string name); - virtual ~KRMesh(); + KRMesh(KRContext& context, std::string name, KRDataBlock* data); + KRMesh(KRContext& context, std::string name); + virtual ~KRMesh(); - kraken_stream_level getStreamLevel(); - void preStream(float lodCoverage); + kraken_stream_level getStreamLevel(); + void preStream(float lodCoverage); - bool hasTransparency(); + bool hasTransparency(); - typedef enum { - KRENGINE_ATTRIB_VERTEX = 0, - KRENGINE_ATTRIB_NORMAL, - KRENGINE_ATTRIB_TANGENT, - KRENGINE_ATTRIB_TEXUVA, - KRENGINE_ATTRIB_TEXUVB, - KRENGINE_ATTRIB_BONEINDEXES, - KRENGINE_ATTRIB_BONEWEIGHTS, - KRENGINE_ATTRIB_VERTEX_SHORT, - KRENGINE_ATTRIB_NORMAL_SHORT, - KRENGINE_ATTRIB_TANGENT_SHORT, - KRENGINE_ATTRIB_TEXUVA_SHORT, - KRENGINE_ATTRIB_TEXUVB_SHORT, - KRENGINE_NUM_ATTRIBUTES - } vertex_attrib_t; + typedef enum + { + KRENGINE_ATTRIB_VERTEX = 0, + KRENGINE_ATTRIB_NORMAL, + KRENGINE_ATTRIB_TANGENT, + KRENGINE_ATTRIB_TEXUVA, + KRENGINE_ATTRIB_TEXUVB, + KRENGINE_ATTRIB_BONEINDEXES, + KRENGINE_ATTRIB_BONEWEIGHTS, + KRENGINE_ATTRIB_VERTEX_SHORT, + KRENGINE_ATTRIB_NORMAL_SHORT, + KRENGINE_ATTRIB_TANGENT_SHORT, + KRENGINE_ATTRIB_TEXUVA_SHORT, + KRENGINE_ATTRIB_TEXUVB_SHORT, + KRENGINE_NUM_ATTRIBUTES + } vertex_attrib_t; - typedef struct { - ModelFormat format; - std::vector vertices; - std::vector<__uint16_t> vertex_indexes; - std::vector > vertex_index_bases; - std::vector uva; - std::vector uvb; - std::vector normals; - std::vector tangents; - std::vector submesh_starts; - std::vector submesh_lengths; - std::vector material_names; - std::vector bone_names; - std::vector > bone_indexes; - std::vector bone_bind_poses; - std::vector > bone_weights; - } mesh_info; + typedef struct + { + ModelFormat format; + std::vector vertices; + std::vector<__uint16_t> vertex_indexes; + std::vector > vertex_index_bases; + std::vector uva; + std::vector uvb; + std::vector normals; + std::vector tangents; + std::vector submesh_starts; + std::vector submesh_lengths; + std::vector material_names; + std::vector bone_names; + std::vector > bone_indexes; + std::vector bone_bind_poses; + std::vector > bone_weights; + } mesh_info; - void render(const KRNode::RenderInfo& ri, const std::string &object_name, const Matrix4 &matModel, KRTexture *pLightMap, const std::vector &bones, const Vector3 &rim_color, float rim_power, float lod_coverage = 0.0f); + void render(const KRNode::RenderInfo& ri, const std::string& object_name, const Matrix4& matModel, KRTexture* pLightMap, const std::vector& bones, const Vector3& rim_color, float rim_power, float lod_coverage = 0.0f); - std::string m_lodBaseName; + std::string m_lodBaseName; - virtual std::string getExtension(); - virtual bool save(const std::string& path); - virtual bool save(KRDataBlock &data); + virtual std::string getExtension(); + virtual bool save(const std::string& path); + virtual bool save(KRDataBlock& data); - void LoadData(const mesh_info &mi, bool calculate_normals, bool calculate_tangents); - void loadPack(KRDataBlock *data); + void LoadData(const mesh_info& mi, bool calculate_normals, bool calculate_tangents); + void loadPack(KRDataBlock* data); - void convertToIndexed(); - void optimize(); - void optimizeIndexes(); + void convertToIndexed(); + void optimize(); + void optimizeIndexes(); - void renderNoMaterials(VkCommandBuffer& commandBuffer, KRNode::RenderPass renderPass, const std::string& object_name, const std::string& material_name, float lodCoverage); - bool isReady() const; + void renderNoMaterials(VkCommandBuffer& commandBuffer, KRNode::RenderPass renderPass, const std::string& object_name, const std::string& material_name, float lodCoverage); + bool isReady() const; - float getMaxDimension(); + float getMaxDimension(); - Vector3 getMinPoint() const; - Vector3 getMaxPoint() const; + Vector3 getMinPoint() const; + Vector3 getMaxPoint() const; - class Submesh { - public: - Submesh() {}; - ~Submesh() { - for(auto itr = vbo_data_blocks.begin(); itr != vbo_data_blocks.end(); itr++) { - delete (*itr); - } - for(auto itr = vertex_data_blocks.begin(); itr != vertex_data_blocks.end(); itr++) { - delete (*itr); - } - for(auto itr = index_data_blocks.begin(); itr != index_data_blocks.end(); itr++) { - delete (*itr); - } - }; - - GLint start_vertex; - GLsizei vertex_count; - char szMaterialName[KRENGINE_MAX_NAME_LENGTH]; - vector vertex_data_blocks; - vector index_data_blocks; - vector vbo_data_blocks; + class Submesh + { + public: + Submesh() + {}; + ~Submesh() + { + for (auto itr = vbo_data_blocks.begin(); itr != vbo_data_blocks.end(); itr++) { + delete (*itr); + } + for (auto itr = vertex_data_blocks.begin(); itr != vertex_data_blocks.end(); itr++) { + delete (*itr); + } + for (auto itr = index_data_blocks.begin(); itr != index_data_blocks.end(); itr++) { + delete (*itr); + } }; - typedef struct { - union { - struct { // For Indexed triangles / strips - uint16_t index_group; - uint16_t index_group_offset; - }; - int32_t start_vertex; // For non-indexed trigangles / strips - }; - int32_t vertex_count; - char szName[KRENGINE_MAX_NAME_LENGTH]; - } pack_material; + GLint start_vertex; + GLsizei vertex_count; + char szMaterialName[KRENGINE_MAX_NAME_LENGTH]; + vector vertex_data_blocks; + vector index_data_blocks; + vector vbo_data_blocks; + }; - typedef struct { - char szName[KRENGINE_MAX_NAME_LENGTH]; - float bind_pose[16]; - } pack_bone; + typedef struct + { + union + { + struct + { // For Indexed triangles / strips + uint16_t index_group; + uint16_t index_group_offset; + }; + int32_t start_vertex; // For non-indexed trigangles / strips + }; + int32_t vertex_count; + char szName[KRENGINE_MAX_NAME_LENGTH]; + } pack_material; - int getLODCoverage() const; - std::string getLODBaseName() const; + typedef struct + { + char szName[KRENGINE_MAX_NAME_LENGTH]; + float bind_pose[16]; + } pack_bone; + + int getLODCoverage() const; + std::string getLODBaseName() const; - static bool lod_sort_predicate(const KRMesh *m1, const KRMesh *m2); - bool has_vertex_attribute(vertex_attrib_t attribute_type) const; - static bool has_vertex_attribute(int vertex_attrib_flags, vertex_attrib_t attribute_type); + static bool lod_sort_predicate(const KRMesh* m1, const KRMesh* m2); + bool has_vertex_attribute(vertex_attrib_t attribute_type) const; + static bool has_vertex_attribute(int vertex_attrib_flags, vertex_attrib_t attribute_type); - int getSubmeshCount() const; - int getVertexCount(int submesh) const; - __uint32_t getVertexAttributes() const; - - int getTriangleVertexIndex(int submesh, int index) const; - Vector3 getVertexPosition(int index) const; - Vector3 getVertexNormal(int index) const; - Vector3 getVertexTangent(int index) const; - Vector2 getVertexUVA(int index) const; - Vector2 getVertexUVB(int index) const; - int getBoneIndex(int index, int weight_index) const; - float getBoneWeight(int index, int weight_index) const; + int getSubmeshCount() const; + int getVertexCount(int submesh) const; + __uint32_t getVertexAttributes() const; - void setVertexPosition(int index, const Vector3 &v); - void setVertexNormal(int index, const Vector3 &v); - void setVertexTangent(int index, const Vector3 & v); - void setVertexUVA(int index, const Vector2 &v); - void setVertexUVB(int index, const Vector2 &v); - void setBoneIndex(int index, int weight_index, int bone_index); - void setBoneWeight(int index, int weight_index, float bone_weight); + int getTriangleVertexIndex(int submesh, int index) const; + Vector3 getVertexPosition(int index) const; + Vector3 getVertexNormal(int index) const; + Vector3 getVertexTangent(int index) const; + Vector2 getVertexUVA(int index) const; + Vector2 getVertexUVB(int index) const; + int getBoneIndex(int index, int weight_index) const; + float getBoneWeight(int index, int weight_index) const; - static size_t VertexSizeForAttributes(__int32_t vertex_attrib_flags); - static size_t AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_flags); - static VkFormat AttributeVulkanFormat(__int32 vertex_attrib); + void setVertexPosition(int index, const Vector3& v); + void setVertexNormal(int index, const Vector3& v); + void setVertexTangent(int index, const Vector3& v); + void setVertexUVA(int index, const Vector2& v); + void setVertexUVB(int index, const Vector2& v); + void setBoneIndex(int index, int weight_index, int bone_index); + void setBoneWeight(int index, int weight_index, float bone_weight); - int getBoneCount(); - char *getBoneName(int bone_index); - Matrix4 getBoneBindPose(int bone_index); + static size_t VertexSizeForAttributes(__int32_t vertex_attrib_flags); + static size_t AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_flags); + static VkFormat AttributeVulkanFormat(__int32 vertex_attrib); + + int getBoneCount(); + char* getBoneName(int bone_index); + Matrix4 getBoneBindPose(int bone_index); - ModelFormat getModelFormat() const; + ModelFormat getModelFormat() const; - bool lineCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo) const; - bool rayCast(const Vector3 &v0, const Vector3 &dir, HitInfo &hitinfo) const; - bool sphereCast(const Matrix4 &model_to_world, const Vector3 &v0, const Vector3 &v1, float radius, HitInfo &hitinfo) const; + bool lineCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo) const; + bool rayCast(const Vector3& v0, const Vector3& dir, HitInfo& hitinfo) const; + bool sphereCast(const Matrix4& model_to_world, const Vector3& v0, const Vector3& v1, float radius, HitInfo& hitinfo) const; - static int GetLODCoverage(const std::string &name); + static int GetLODCoverage(const std::string& name); protected: - bool m_constant; // TRUE if this should be always loaded and should not be passed through the streamer + bool m_constant; // TRUE if this should be always loaded and should not be passed through the streamer private: - KRDataBlock *m_pData; - KRDataBlock *m_pMetaData; - KRDataBlock *m_pIndexBaseData; + KRDataBlock* m_pData; + KRDataBlock* m_pMetaData; + KRDataBlock* m_pIndexBaseData; - void getSubmeshes(); - void getMaterials(); - void renderSubmesh(VkCommandBuffer& commandBuffer, int iSubmesh, KRNode::RenderPass renderPass, const std::string& object_name, const std::string& material_name, float lodCoverage); + void getSubmeshes(); + void getMaterials(); + void renderSubmesh(VkCommandBuffer& commandBuffer, int iSubmesh, KRNode::RenderPass renderPass, const std::string& object_name, const std::string& material_name, float lodCoverage); - static bool rayCast(const Vector3 &start, const Vector3 &dir, const Triangle3 &tri, const Vector3 &tri_n0, const Vector3 &tri_n1, const Vector3 &tri_n2, HitInfo &hitinfo); - static bool sphereCast(const Matrix4 &model_to_world, const Vector3 &v0, const Vector3 &v1, float radius, const Triangle3 &tri, HitInfo &hitinfo); + static bool rayCast(const Vector3& start, const Vector3& dir, const Triangle3& tri, const Vector3& tri_n0, const Vector3& tri_n1, const Vector3& tri_n2, HitInfo& hitinfo); + static bool sphereCast(const Matrix4& model_to_world, const Vector3& v0, const Vector3& v1, float radius, const Triangle3& tri, HitInfo& hitinfo); - int m_lodCoverage; // This LOD level is activated when the bounding box of the model will cover less than this percent of the screen (100 = highest detail model) - vector m_materials; - set m_uniqueMaterials; + int m_lodCoverage; // This LOD level is activated when the bounding box of the model will cover less than this percent of the screen (100 = highest detail model) + vector m_materials; + set m_uniqueMaterials; - bool m_hasTransparency; + bool m_hasTransparency; - Vector3 m_minPoint, m_maxPoint; + Vector3 m_minPoint, m_maxPoint; - typedef struct { - char szTag[16]; - int32_t model_format; // 0 == Triangle list, 1 == Triangle strips, 2 == Indexed triangle list, 3 == Indexed triangle strips, rest are reserved (model_format_t enum) - int32_t vertex_attrib_flags; - int32_t vertex_count; - int32_t submesh_count; - int32_t bone_count; - float minx, miny, minz, maxx, maxy, maxz; // Axis aligned bounding box, in model's coordinate space - int32_t index_count; - int32_t index_base_count; - unsigned char reserved[444]; // Pad out to 512 bytes - } pack_header; + typedef struct + { + char szTag[16]; + int32_t model_format; // 0 == Triangle list, 1 == Triangle strips, 2 == Indexed triangle list, 3 == Indexed triangle strips, rest are reserved (model_format_t enum) + int32_t vertex_attrib_flags; + int32_t vertex_count; + int32_t submesh_count; + int32_t bone_count; + float minx, miny, minz, maxx, maxy, maxz; // Axis aligned bounding box, in model's coordinate space + int32_t index_count; + int32_t index_base_count; + unsigned char reserved[444]; // Pad out to 512 bytes + } pack_header; - vector m_submeshes; - int m_vertex_attribute_offset[KRENGINE_NUM_ATTRIBUTES]; - int m_vertex_size; - void updateAttributeOffsets(); + vector m_submeshes; + int m_vertex_attribute_offset[KRENGINE_NUM_ATTRIBUTES]; + int m_vertex_size; + void updateAttributeOffsets(); - void setName(const std::string name); + void setName(const std::string name); - pack_material *getSubmesh(int mesh_index) const; - unsigned char *getVertexData() const; - size_t getVertexDataOffset() const; - unsigned char *getVertexData(int index) const; - __uint16_t *getIndexData() const; - size_t getIndexDataOffset() const; - __uint32_t *getIndexBaseData() const; - pack_header *getHeader() const; - pack_bone *getBone(int index); + pack_material* getSubmesh(int mesh_index) const; + unsigned char* getVertexData() const; + size_t getVertexDataOffset() const; + unsigned char* getVertexData(int index) const; + __uint16_t* getIndexData() const; + size_t getIndexDataOffset() const; + __uint32_t* getIndexBaseData() const; + pack_header* getHeader() const; + pack_bone* getBone(int index); - void getIndexedRange(int index_group, int &start_index_offset, int &start_vertex_offset, int &index_count, int &vertex_count) const; + void getIndexedRange(int index_group, int& start_index_offset, int& start_vertex_offset, int& index_count, int& vertex_count) const; - void releaseData(); + void releaseData(); - void createDataBlocks(KRMeshManager::KRVBOData::vbo_type t); + void createDataBlocks(KRMeshManager::KRVBOData::vbo_type t); }; diff --git a/kraken/KRMeshCube.cpp b/kraken/KRMeshCube.cpp index 5348f65..6dd9f25 100755 --- a/kraken/KRMeshCube.cpp +++ b/kraken/KRMeshCube.cpp @@ -32,38 +32,38 @@ #include "KRMeshCube.h" -KRMeshCube::KRMeshCube(KRContext &context) : KRMesh(context, "__cube") +KRMeshCube::KRMeshCube(KRContext& context) : KRMesh(context, "__cube") { - m_constant = true; - - KRMesh::mesh_info mi; - - mi.vertices.push_back(Vector3::Create(1.0, 1.0, 1.0)); - mi.vertices.push_back(Vector3::Create(-1.0, 1.0, 1.0)); - mi.vertices.push_back(Vector3::Create(1.0,-1.0, 1.0)); - mi.vertices.push_back(Vector3::Create(-1.0,-1.0, 1.0)); - mi.vertices.push_back(Vector3::Create(-1.0,-1.0,-1.0)); - mi.vertices.push_back(Vector3::Create(-1.0, 1.0, 1.0)); - mi.vertices.push_back(Vector3::Create(-1.0, 1.0,-1.0)); - mi.vertices.push_back(Vector3::Create(1.0, 1.0, 1.0)); - mi.vertices.push_back(Vector3::Create(1.0, 1.0,-1.0)); - mi.vertices.push_back(Vector3::Create(1.0,-1.0, 1.0)); - mi.vertices.push_back(Vector3::Create(1.0,-1.0,-1.0)); - mi.vertices.push_back(Vector3::Create(-1.0,-1.0,-1.0)); - mi.vertices.push_back(Vector3::Create(1.0, 1.0,-1.0)); - mi.vertices.push_back(Vector3::Create(-1.0, 1.0,-1.0)); - - - mi.submesh_starts.push_back(0); - mi.submesh_lengths.push_back((int)mi.vertices.size()); - mi.material_names.push_back(""); - mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; + m_constant = true; - - LoadData(mi, true, true); + KRMesh::mesh_info mi; + + mi.vertices.push_back(Vector3::Create(1.0, 1.0, 1.0)); + mi.vertices.push_back(Vector3::Create(-1.0, 1.0, 1.0)); + mi.vertices.push_back(Vector3::Create(1.0, -1.0, 1.0)); + mi.vertices.push_back(Vector3::Create(-1.0, -1.0, 1.0)); + mi.vertices.push_back(Vector3::Create(-1.0, -1.0, -1.0)); + mi.vertices.push_back(Vector3::Create(-1.0, 1.0, 1.0)); + mi.vertices.push_back(Vector3::Create(-1.0, 1.0, -1.0)); + mi.vertices.push_back(Vector3::Create(1.0, 1.0, 1.0)); + mi.vertices.push_back(Vector3::Create(1.0, 1.0, -1.0)); + mi.vertices.push_back(Vector3::Create(1.0, -1.0, 1.0)); + mi.vertices.push_back(Vector3::Create(1.0, -1.0, -1.0)); + mi.vertices.push_back(Vector3::Create(-1.0, -1.0, -1.0)); + mi.vertices.push_back(Vector3::Create(1.0, 1.0, -1.0)); + mi.vertices.push_back(Vector3::Create(-1.0, 1.0, -1.0)); + + + mi.submesh_starts.push_back(0); + mi.submesh_lengths.push_back((int)mi.vertices.size()); + mi.material_names.push_back(""); + mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; + + + LoadData(mi, true, true); } KRMeshCube::~KRMeshCube() { - + } diff --git a/kraken/KRMeshCube.h b/kraken/KRMeshCube.h index 47e02bb..b350510 100755 --- a/kraken/KRMeshCube.h +++ b/kraken/KRMeshCube.h @@ -33,10 +33,11 @@ #include "KRMesh.h" -class KRMeshCube : public KRMesh { +class KRMeshCube : public KRMesh +{ public: - KRMeshCube(KRContext &context); - virtual ~KRMeshCube(); + KRMeshCube(KRContext& context); + virtual ~KRMeshCube(); private: }; diff --git a/kraken/KRMeshManager.cpp b/kraken/KRMeshManager.cpp index 0dc1d33..0b15a67 100755 --- a/kraken/KRMeshManager.cpp +++ b/kraken/KRMeshManager.cpp @@ -47,72 +47,74 @@ KRMeshManager::KRMeshManager(KRContext& context) , m_draw_call_logging_enabled(false) , m_draw_call_log_used(false) { - + } -void KRMeshManager::init() { - addModel(new KRMeshCube(*m_pContext)); - addModel(new KRMeshQuad(*m_pContext)); - addModel(new KRMeshSphere(*m_pContext)); - - // ---- Initialize stock models ---- - static const float _KRENGINE_VBO_3D_CUBE_VERTEX_DATA[] = { - 1.0, 1.0, 1.0, - -1.0, 1.0, 1.0, - 1.0,-1.0, 1.0, - -1.0,-1.0, 1.0, - -1.0,-1.0,-1.0, - -1.0, 1.0, 1.0, - -1.0, 1.0,-1.0, - 1.0, 1.0, 1.0, - 1.0, 1.0,-1.0, - 1.0,-1.0, 1.0, - 1.0,-1.0,-1.0, - -1.0,-1.0,-1.0, - 1.0, 1.0,-1.0, - -1.0, 1.0,-1.0 - }; - - KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); - KRENGINE_VBO_3D_CUBE_VERTICES.expand(sizeof(float) * 3 * 14); - KRENGINE_VBO_3D_CUBE_VERTICES.lock(); - memcpy(KRENGINE_VBO_3D_CUBE_VERTICES.getStart(), _KRENGINE_VBO_3D_CUBE_VERTEX_DATA, sizeof(float) * 3 * 14); - KRENGINE_VBO_3D_CUBE_VERTICES.unlock(); - - KRENGINE_VBO_DATA_3D_CUBE_VERTICES.init(this, &KRENGINE_VBO_3D_CUBE_VERTICES, nullptr, KRENGINE_VBO_3D_CUBE_ATTRIBS, false, KRVBOData::CONSTANT -#if KRENGINE_DEBUG_GPU_LABELS - , "Cube Mesh [built-in]" -#endif - ); +void KRMeshManager::init() +{ + addModel(new KRMeshCube(*m_pContext)); + addModel(new KRMeshQuad(*m_pContext)); + addModel(new KRMeshSphere(*m_pContext)); - initRandomParticles(); - initVolumetricLightingVertexes(); - - static const float _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA[] = { - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, - -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f - }; - KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); - KRENGINE_VBO_2D_SQUARE_VERTICES.expand(sizeof(float) * 5 * 4); - KRENGINE_VBO_2D_SQUARE_VERTICES.lock(); - memcpy(KRENGINE_VBO_2D_SQUARE_VERTICES.getStart(), _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA, sizeof(float) * 5 * 4); - KRENGINE_VBO_2D_SQUARE_VERTICES.unlock(); - - KRENGINE_VBO_DATA_2D_SQUARE_VERTICES.init(this, &KRENGINE_VBO_2D_SQUARE_VERTICES, nullptr, KRENGINE_VBO_2D_SQUARE_ATTRIBS, false, KRVBOData::CONSTANT + // ---- Initialize stock models ---- + static const float _KRENGINE_VBO_3D_CUBE_VERTEX_DATA[] = { + 1.0, 1.0, 1.0, + -1.0, 1.0, 1.0, + 1.0,-1.0, 1.0, + -1.0,-1.0, 1.0, + -1.0,-1.0,-1.0, + -1.0, 1.0, 1.0, + -1.0, 1.0,-1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0,-1.0, + 1.0,-1.0, 1.0, + 1.0,-1.0,-1.0, + -1.0,-1.0,-1.0, + 1.0, 1.0,-1.0, + -1.0, 1.0,-1.0 + }; + + KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); + KRENGINE_VBO_3D_CUBE_VERTICES.expand(sizeof(float) * 3 * 14); + KRENGINE_VBO_3D_CUBE_VERTICES.lock(); + memcpy(KRENGINE_VBO_3D_CUBE_VERTICES.getStart(), _KRENGINE_VBO_3D_CUBE_VERTEX_DATA, sizeof(float) * 3 * 14); + KRENGINE_VBO_3D_CUBE_VERTICES.unlock(); + + KRENGINE_VBO_DATA_3D_CUBE_VERTICES.init(this, &KRENGINE_VBO_3D_CUBE_VERTICES, nullptr, KRENGINE_VBO_3D_CUBE_ATTRIBS, false, KRVBOData::CONSTANT #if KRENGINE_DEBUG_GPU_LABELS - , "Square Mesh [built-in]" + , "Cube Mesh [built-in]" #endif - ); - + ); + + initRandomParticles(); + initVolumetricLightingVertexes(); + + static const float _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA[] = { + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f + }; + KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); + KRENGINE_VBO_2D_SQUARE_VERTICES.expand(sizeof(float) * 5 * 4); + KRENGINE_VBO_2D_SQUARE_VERTICES.lock(); + memcpy(KRENGINE_VBO_2D_SQUARE_VERTICES.getStart(), _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA, sizeof(float) * 5 * 4); + KRENGINE_VBO_2D_SQUARE_VERTICES.unlock(); + + KRENGINE_VBO_DATA_2D_SQUARE_VERTICES.init(this, &KRENGINE_VBO_2D_SQUARE_VERTICES, nullptr, KRENGINE_VBO_2D_SQUARE_ATTRIBS, false, KRVBOData::CONSTANT +#if KRENGINE_DEBUG_GPU_LABELS + , "Square Mesh [built-in]" +#endif + ); + } -KRMeshManager::~KRMeshManager() { - for(unordered_multimap::iterator itr = m_models.begin(); itr != m_models.end(); ++itr){ - delete (*itr).second; - } - m_models.clear(); +KRMeshManager::~KRMeshManager() +{ + for (unordered_multimap::iterator itr = m_models.begin(); itr != m_models.end(); ++itr) { + delete (*itr).second; + } + m_models.clear(); } KRResource* KRMeshManager::loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) @@ -138,21 +140,24 @@ KRResource* KRMeshManager::getResource(const std::string& name, const std::strin return nullptr; } -KRMesh *KRMeshManager::loadModel(const char *szName, KRDataBlock *pData) { - KRMesh *pModel = new KRMesh(*m_pContext, szName, pData); - addModel(pModel); - return pModel; +KRMesh* KRMeshManager::loadModel(const char* szName, KRDataBlock* pData) +{ + KRMesh* pModel = new KRMesh(*m_pContext, szName, pData); + addModel(pModel); + return pModel; } -void KRMeshManager::addModel(KRMesh *model) { - std::string lowerName = model->getLODBaseName(); - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - - m_models.insert(std::pair(lowerName, model)); +void KRMeshManager::addModel(KRMesh* model) +{ + std::string lowerName = model->getLODBaseName(); + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + + m_models.insert(std::pair(lowerName, model)); } -KRMesh* KRMeshManager::getMaxLODModel(const char* szName) { +KRMesh* KRMeshManager::getMaxLODModel(const char* szName) +{ std::vector models = getModel(szName); // models are always in order of highest LOD first if (models.size()) { @@ -161,112 +166,114 @@ KRMesh* KRMeshManager::getMaxLODModel(const char* szName) { return nullptr; } -std::vector KRMeshManager::getModel(const char *szName) { - std::string lowerName = szName; - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - - - std::vector matching_models; - - std::pair::iterator, unordered_multimap::iterator> range = m_models.equal_range(lowerName); - for(unordered_multimap::iterator itr_match = range.first; itr_match != range.second; itr_match++) { - matching_models.push_back(itr_match->second); - } - - std::sort(matching_models.begin(), matching_models.end(), KRMesh::lod_sort_predicate); - - if(matching_models.size() == 0) { - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Model not found: %s", lowerName.c_str()); - } - - return matching_models; -} - -unordered_multimap &KRMeshManager::getModels() { - return m_models; -} - -void KRMeshManager::bindVBO(VkCommandBuffer& commandBuffer, KRVBOData *vbo_data, float lodCoverage) +std::vector KRMeshManager::getModel(const char* szName) { - vbo_data->resetPoolExpiry(lodCoverage); - - bool vbo_changed = false; - if(m_currentVBO == NULL) { - vbo_changed = true; - } else if(m_currentVBO->m_data != vbo_data->m_data) { - vbo_changed = true; - } - - if(vbo_changed) { - - if(m_vbosActive.find(vbo_data->m_data) != m_vbosActive.end()) { - m_currentVBO = m_vbosActive[vbo_data->m_data]; - } else { - m_currentVBO = vbo_data; - - m_vbosActive[vbo_data->m_data] = m_currentVBO; - } - - m_currentVBO->bind(commandBuffer); + std::string lowerName = szName; + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + + + std::vector matching_models; + + std::pair::iterator, unordered_multimap::iterator> range = m_models.equal_range(lowerName); + for (unordered_multimap::iterator itr_match = range.first; itr_match != range.second; itr_match++) { + matching_models.push_back(itr_match->second); + } + + std::sort(matching_models.begin(), matching_models.end(), KRMesh::lod_sort_predicate); + + if (matching_models.size() == 0) { + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Model not found: %s", lowerName.c_str()); + } + + return matching_models; +} + +unordered_multimap& KRMeshManager::getModels() +{ + return m_models; +} + +void KRMeshManager::bindVBO(VkCommandBuffer& commandBuffer, KRVBOData* vbo_data, float lodCoverage) +{ + vbo_data->resetPoolExpiry(lodCoverage); + + bool vbo_changed = false; + if (m_currentVBO == NULL) { + vbo_changed = true; + } else if (m_currentVBO->m_data != vbo_data->m_data) { + vbo_changed = true; + } + + if (vbo_changed) { + + if (m_vbosActive.find(vbo_data->m_data) != m_vbosActive.end()) { + m_currentVBO = m_vbosActive[vbo_data->m_data]; + } else { + m_currentVBO = vbo_data; + + m_vbosActive[vbo_data->m_data] = m_currentVBO; } + + m_currentVBO->bind(commandBuffer); + } } void KRMeshManager::startFrame(float deltaTime) { - m_memoryTransferredThisFrame = 0; - if(m_draw_call_log_used) { - // Only log draw calls on the next frame if the draw call log was used on last frame - m_draw_call_log_used = false; - m_draw_call_logging_enabled = true; + m_memoryTransferredThisFrame = 0; + if (m_draw_call_log_used) { + // Only log draw calls on the next frame if the draw call log was used on last frame + m_draw_call_log_used = false; + m_draw_call_logging_enabled = true; + } + m_draw_calls.clear(); + + // TODO - Implement proper double-buffering to reduce copy operations + m_streamerFenceMutex.lock(); + + if (m_streamerComplete) { + assert(m_activeVBOs_streamer_copy.size() == 0); // The streamer should have emptied this if it really did complete + + const long KRENGINE_VBO_EXPIRY_FRAMES = 1; + + std::set expiredVBOs; + for (auto itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { + KRVBOData* activeVBO = (*itr).second; + activeVBO->_swapHandles(); + if (activeVBO->getType() == KRVBOData::CONSTANT) { + // Ensure that CONSTANT data is always loaded + float priority = std::numeric_limits::max(); + m_activeVBOs_streamer_copy.push_back(std::pair(priority, activeVBO)); + } else if (activeVBO->getLastFrameUsed() + KRENGINE_VBO_EXPIRY_FRAMES < getContext().getCurrentFrame()) { + // Expire VBO's that haven't been used in a long time + + switch (activeVBO->getType()) { + case KRVBOData::STREAMING: + case KRVBOData::IMMEDIATE: + activeVBO->unload(); + break; + case KRVBOData::CONSTANT: + // CONSTANT VBO's are not unloaded + break; + } + + expiredVBOs.insert(activeVBO); + } else if (activeVBO->getType() == KRVBOData::STREAMING) { + float priority = activeVBO->getStreamPriority(); + m_activeVBOs_streamer_copy.push_back(std::pair(priority, activeVBO)); + } } - m_draw_calls.clear(); - - // TODO - Implement proper double-buffering to reduce copy operations - m_streamerFenceMutex.lock(); - - if(m_streamerComplete) { - assert(m_activeVBOs_streamer_copy.size() == 0); // The streamer should have emptied this if it really did complete - - const long KRENGINE_VBO_EXPIRY_FRAMES = 1; - - std::set expiredVBOs; - for(auto itr=m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { - KRVBOData *activeVBO = (*itr).second; - activeVBO->_swapHandles(); - if (activeVBO->getType() == KRVBOData::CONSTANT) { - // Ensure that CONSTANT data is always loaded - float priority = std::numeric_limits::max(); - m_activeVBOs_streamer_copy.push_back(std::pair(priority, activeVBO)); - } else if(activeVBO->getLastFrameUsed() + KRENGINE_VBO_EXPIRY_FRAMES < getContext().getCurrentFrame()) { - // Expire VBO's that haven't been used in a long time - - switch(activeVBO->getType()) { - case KRVBOData::STREAMING: - case KRVBOData::IMMEDIATE: - activeVBO->unload(); - break; - case KRVBOData::CONSTANT: - // CONSTANT VBO's are not unloaded - break; - } - - expiredVBOs.insert(activeVBO); - } else if(activeVBO->getType() == KRVBOData::STREAMING) { - float priority = activeVBO->getStreamPriority(); - m_activeVBOs_streamer_copy.push_back(std::pair(priority, activeVBO)); - } - } - for(std::set::iterator itr=expiredVBOs.begin(); itr != expiredVBOs.end(); itr++) { - m_vbosActive.erase((*itr)->m_data); - } - - if(m_activeVBOs_streamer_copy.size() > 0) { - m_streamerComplete = false; - } + for (std::set::iterator itr = expiredVBOs.begin(); itr != expiredVBOs.end(); itr++) { + m_vbosActive.erase((*itr)->m_data); } - m_streamerFenceMutex.unlock(); - + + if (m_activeVBOs_streamer_copy.size() > 0) { + m_streamerComplete = false; + } + } + m_streamerFenceMutex.unlock(); + } void KRMeshManager::endFrame(float deltaTime) @@ -274,218 +281,218 @@ void KRMeshManager::endFrame(float deltaTime) m_currentVBO = nullptr; } -void KRMeshManager::doStreaming(long &memoryRemaining, long &memoryRemainingThisFrame) +void KRMeshManager::doStreaming(long& memoryRemaining, long& memoryRemainingThisFrame) { - - // TODO - Implement proper double-buffering to reduce copy operations + + // TODO - Implement proper double-buffering to reduce copy operations + m_streamerFenceMutex.lock(); + m_activeVBOs_streamer = std::move(m_activeVBOs_streamer_copy); + m_streamerFenceMutex.unlock(); + + if (m_activeVBOs_streamer.size() > 0) { + balanceVBOMemory(memoryRemaining, memoryRemainingThisFrame); + m_streamerFenceMutex.lock(); - m_activeVBOs_streamer = std::move(m_activeVBOs_streamer_copy); + m_streamerComplete = true; m_streamerFenceMutex.unlock(); - - if(m_activeVBOs_streamer.size() > 0) { - balanceVBOMemory(memoryRemaining, memoryRemainingThisFrame); - - m_streamerFenceMutex.lock(); - m_streamerComplete = true; - m_streamerFenceMutex.unlock(); - } else { - memoryRemaining -= getMemUsed(); - } + } else { + memoryRemaining -= getMemUsed(); + } } -void KRMeshManager::balanceVBOMemory(long &memoryRemaining, long &memoryRemainingThisFrame) +void KRMeshManager::balanceVBOMemory(long& memoryRemaining, long& memoryRemainingThisFrame) { - std::sort(m_activeVBOs_streamer.begin(), m_activeVBOs_streamer.end(), std::greater>()); - + std::sort(m_activeVBOs_streamer.begin(), m_activeVBOs_streamer.end(), std::greater>()); - for(auto vbo_itr = m_activeVBOs_streamer.begin(); vbo_itr != m_activeVBOs_streamer.end(); vbo_itr++) { - KRVBOData *vbo_data = (*vbo_itr).second; - long vbo_size = vbo_data->getSize(); - if(!vbo_data->isVBOLoaded()) { - if(memoryRemainingThisFrame > vbo_size) { - vbo_data->load(); - memoryRemainingThisFrame -= vbo_size; - } - } - memoryRemaining -= vbo_size; + + for (auto vbo_itr = m_activeVBOs_streamer.begin(); vbo_itr != m_activeVBOs_streamer.end(); vbo_itr++) { + KRVBOData* vbo_data = (*vbo_itr).second; + long vbo_size = vbo_data->getSize(); + if (!vbo_data->isVBOLoaded()) { + if (memoryRemainingThisFrame > vbo_size) { + vbo_data->load(); + memoryRemainingThisFrame -= vbo_size; + } } + memoryRemaining -= vbo_size; + } } long KRMeshManager::getMemUsed() { - return m_vboMemUsed; + return m_vboMemUsed; } long KRMeshManager::getMemActive() { - long mem_active = 0; - for(unordered_map::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { - mem_active += (*itr).second->getSize(); - } - return mem_active; + long mem_active = 0; + for (unordered_map::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { + mem_active += (*itr).second->getSize(); + } + return mem_active; } void KRMeshManager::initVolumetricLightingVertexes() { - if(m_volumetricLightingVertexData.getSize() == 0) { - m_volumetricLightingVertexData.expand(sizeof(VolumetricLightingVertexData) * KRENGINE_MAX_VOLUMETRIC_PLANES * 6); - m_volumetricLightingVertexData.lock(); - VolumetricLightingVertexData * vertex_data = (VolumetricLightingVertexData *)m_volumetricLightingVertexData.getStart(); - int iVertex=0; - for(int iPlane=0; iPlane < KRENGINE_MAX_VOLUMETRIC_PLANES; iPlane++) { - vertex_data[iVertex].vertex.x = -1.0f; - vertex_data[iVertex].vertex.y = -1.0f; - vertex_data[iVertex].vertex.z = (float)iPlane; - iVertex++; - - vertex_data[iVertex].vertex.x = 1.0f; - vertex_data[iVertex].vertex.y = -1.0f; - vertex_data[iVertex].vertex.z = (float)iPlane; - iVertex++; - - vertex_data[iVertex].vertex.x = -1.0f; - vertex_data[iVertex].vertex.y = 1.0f; - vertex_data[iVertex].vertex.z = (float)iPlane; - iVertex++; - - vertex_data[iVertex].vertex.x = -1.0f; - vertex_data[iVertex].vertex.y = 1.0f; - vertex_data[iVertex].vertex.z = (float)iPlane; - iVertex++; - - vertex_data[iVertex].vertex.x = 1.0f; - vertex_data[iVertex].vertex.y = -1.0f; - vertex_data[iVertex].vertex.z = (float)iPlane; - iVertex++; - - vertex_data[iVertex].vertex.x = 1.0f; - vertex_data[iVertex].vertex.y = 1.0f; - vertex_data[iVertex].vertex.z = (float)iPlane; - iVertex++; + if (m_volumetricLightingVertexData.getSize() == 0) { + m_volumetricLightingVertexData.expand(sizeof(VolumetricLightingVertexData) * KRENGINE_MAX_VOLUMETRIC_PLANES * 6); + m_volumetricLightingVertexData.lock(); + VolumetricLightingVertexData* vertex_data = (VolumetricLightingVertexData*)m_volumetricLightingVertexData.getStart(); + int iVertex = 0; + for (int iPlane = 0; iPlane < KRENGINE_MAX_VOLUMETRIC_PLANES; iPlane++) { + vertex_data[iVertex].vertex.x = -1.0f; + vertex_data[iVertex].vertex.y = -1.0f; + vertex_data[iVertex].vertex.z = (float)iPlane; + iVertex++; - } + vertex_data[iVertex].vertex.x = 1.0f; + vertex_data[iVertex].vertex.y = -1.0f; + vertex_data[iVertex].vertex.z = (float)iPlane; + iVertex++; - KRENGINE_VBO_DATA_VOLUMETRIC_LIGHTING.init(this, &m_volumetricLightingVertexData, nullptr, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), false, KRVBOData::CONSTANT -#if KRENGINE_DEBUG_GPU_LABELS - , "Volumetric Lighting Planes [built-in]" -#endif - ); + vertex_data[iVertex].vertex.x = -1.0f; + vertex_data[iVertex].vertex.y = 1.0f; + vertex_data[iVertex].vertex.z = (float)iPlane; + iVertex++; + + vertex_data[iVertex].vertex.x = -1.0f; + vertex_data[iVertex].vertex.y = 1.0f; + vertex_data[iVertex].vertex.z = (float)iPlane; + iVertex++; + + vertex_data[iVertex].vertex.x = 1.0f; + vertex_data[iVertex].vertex.y = -1.0f; + vertex_data[iVertex].vertex.z = (float)iPlane; + iVertex++; + + vertex_data[iVertex].vertex.x = 1.0f; + vertex_data[iVertex].vertex.y = 1.0f; + vertex_data[iVertex].vertex.z = (float)iPlane; + iVertex++; - m_volumetricLightingVertexData.unlock(); } + + KRENGINE_VBO_DATA_VOLUMETRIC_LIGHTING.init(this, &m_volumetricLightingVertexData, nullptr, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), false, KRVBOData::CONSTANT +#if KRENGINE_DEBUG_GPU_LABELS + , "Volumetric Lighting Planes [built-in]" +#endif + ); + + m_volumetricLightingVertexData.unlock(); + } } void KRMeshManager::initRandomParticles() { - if(m_randomParticleVertexData.getSize() == 0) { - m_randomParticleVertexData.expand(sizeof(RandomParticleVertexData) * KRENGINE_MAX_RANDOM_PARTICLES * 3); - m_randomParticleVertexData.lock(); - RandomParticleVertexData *vertex_data = (RandomParticleVertexData *)m_randomParticleVertexData.getStart(); - - // Generate vertices for randomly placed equilateral triangles with a side length of 1 and an origin point centered so that an inscribed circle can be efficiently rendered without wasting fill - - float equilateral_triangle_height = sqrt(3.0f) * 0.5f; - float inscribed_circle_radius = 1.0f / (2.0f * sqrt(3.0f)); - - int iVertex=0; - for(int iParticle=0; iParticle < KRENGINE_MAX_RANDOM_PARTICLES; iParticle++) { - vertex_data[iVertex].vertex.x = (float)(rand() % 2000) / 1000.0f - 1000.0f; - vertex_data[iVertex].vertex.y = (float)(rand() % 2000) / 1000.0f - 1000.0f; - vertex_data[iVertex].vertex.z = (float)(rand() % 2000) / 1000.0f - 1000.0f; - vertex_data[iVertex].uva.x = -0.5f; - vertex_data[iVertex].uva.y = -inscribed_circle_radius; - iVertex++; - - vertex_data[iVertex].vertex.x = vertex_data[iVertex-1].vertex.x; - vertex_data[iVertex].vertex.y = vertex_data[iVertex-1].vertex.y; - vertex_data[iVertex].vertex.z = vertex_data[iVertex-1].vertex.z; - vertex_data[iVertex].uva.x = 0.5f; - vertex_data[iVertex].uva.y = -inscribed_circle_radius; - iVertex++; - - vertex_data[iVertex].vertex.x = vertex_data[iVertex-1].vertex.x; - vertex_data[iVertex].vertex.y = vertex_data[iVertex-1].vertex.y; - vertex_data[iVertex].vertex.z = vertex_data[iVertex-1].vertex.z; - vertex_data[iVertex].uva.x = 0.0f; - vertex_data[iVertex].uva.y = -inscribed_circle_radius + equilateral_triangle_height; - iVertex++; - } - - KRENGINE_VBO_DATA_RANDOM_PARTICLES.init(this, &m_randomParticleVertexData, nullptr, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false, KRVBOData::CONSTANT -#if KRENGINE_DEBUG_GPU_LABELS - , "Random Particles [built-in]" -#endif - ); + if (m_randomParticleVertexData.getSize() == 0) { + m_randomParticleVertexData.expand(sizeof(RandomParticleVertexData) * KRENGINE_MAX_RANDOM_PARTICLES * 3); + m_randomParticleVertexData.lock(); + RandomParticleVertexData* vertex_data = (RandomParticleVertexData*)m_randomParticleVertexData.getStart(); - m_randomParticleVertexData.unlock(); + // Generate vertices for randomly placed equilateral triangles with a side length of 1 and an origin point centered so that an inscribed circle can be efficiently rendered without wasting fill + + float equilateral_triangle_height = sqrt(3.0f) * 0.5f; + float inscribed_circle_radius = 1.0f / (2.0f * sqrt(3.0f)); + + int iVertex = 0; + for (int iParticle = 0; iParticle < KRENGINE_MAX_RANDOM_PARTICLES; iParticle++) { + vertex_data[iVertex].vertex.x = (float)(rand() % 2000) / 1000.0f - 1000.0f; + vertex_data[iVertex].vertex.y = (float)(rand() % 2000) / 1000.0f - 1000.0f; + vertex_data[iVertex].vertex.z = (float)(rand() % 2000) / 1000.0f - 1000.0f; + vertex_data[iVertex].uva.x = -0.5f; + vertex_data[iVertex].uva.y = -inscribed_circle_radius; + iVertex++; + + vertex_data[iVertex].vertex.x = vertex_data[iVertex - 1].vertex.x; + vertex_data[iVertex].vertex.y = vertex_data[iVertex - 1].vertex.y; + vertex_data[iVertex].vertex.z = vertex_data[iVertex - 1].vertex.z; + vertex_data[iVertex].uva.x = 0.5f; + vertex_data[iVertex].uva.y = -inscribed_circle_radius; + iVertex++; + + vertex_data[iVertex].vertex.x = vertex_data[iVertex - 1].vertex.x; + vertex_data[iVertex].vertex.y = vertex_data[iVertex - 1].vertex.y; + vertex_data[iVertex].vertex.z = vertex_data[iVertex - 1].vertex.z; + vertex_data[iVertex].uva.x = 0.0f; + vertex_data[iVertex].uva.y = -inscribed_circle_radius + equilateral_triangle_height; + iVertex++; } + + KRENGINE_VBO_DATA_RANDOM_PARTICLES.init(this, &m_randomParticleVertexData, nullptr, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false, KRVBOData::CONSTANT +#if KRENGINE_DEBUG_GPU_LABELS + , "Random Particles [built-in]" +#endif + ); + + m_randomParticleVertexData.unlock(); + } } long KRMeshManager::getMemoryTransferedThisFrame() { - return m_memoryTransferredThisFrame; + return m_memoryTransferredThisFrame; } size_t KRMeshManager::getActiveVBOCount() { - return m_vbosActive.size(); + return m_vbosActive.size(); } -void KRMeshManager::log_draw_call(KRNode::RenderPass pass, const std::string &object_name, const std::string &material_name, int vertex_count) +void KRMeshManager::log_draw_call(KRNode::RenderPass pass, const std::string& object_name, const std::string& material_name, int vertex_count) { - if(m_draw_call_logging_enabled) { - draw_call_info info; - info.pass = pass; - strncpy(info.object_name, object_name.c_str(), 256); - strncpy(info.material_name, material_name.c_str(), 256); - info.vertex_count = vertex_count; - m_draw_calls.push_back(info); - } + if (m_draw_call_logging_enabled) { + draw_call_info info; + info.pass = pass; + strncpy(info.object_name, object_name.c_str(), 256); + strncpy(info.material_name, material_name.c_str(), 256); + info.vertex_count = vertex_count; + m_draw_calls.push_back(info); + } } std::vector KRMeshManager::getDrawCalls() { - m_draw_call_log_used = true; - return m_draw_calls; + m_draw_call_log_used = true; + return m_draw_calls; } KRMeshManager::KRVBOData::KRVBOData() { - m_debugLabel[0] = '\0'; - m_is_vbo_loaded = false; - m_is_vbo_ready = false; - m_manager = NULL; - m_type = STREAMING; - m_data = NULL; - m_index_data = NULL; - m_vertex_attrib_flags = 0; - m_size = 0; - - m_last_frame_used = 0; - m_last_frame_max_lod_coverage = 0.0f; + m_debugLabel[0] = '\0'; + m_is_vbo_loaded = false; + m_is_vbo_ready = false; + m_manager = NULL; + m_type = STREAMING; + m_data = NULL; + m_index_data = NULL; + m_vertex_attrib_flags = 0; + m_size = 0; - memset(m_allocations, 0, sizeof(AllocationInfo) * KRENGINE_MAX_GPU_COUNT); + m_last_frame_used = 0; + m_last_frame_max_lod_coverage = 0.0f; + + memset(m_allocations, 0, sizeof(AllocationInfo) * KRENGINE_MAX_GPU_COUNT); } -KRMeshManager::KRVBOData::KRVBOData(KRMeshManager *manager, KRDataBlock *data, KRDataBlock *index_data, int vertex_attrib_flags, bool static_vbo, vbo_type t +KRMeshManager::KRVBOData::KRVBOData(KRMeshManager* manager, KRDataBlock* data, KRDataBlock* index_data, int vertex_attrib_flags, bool static_vbo, vbo_type t #if KRENGINE_DEBUG_GPU_LABELS , const char* debug_label #endif ) { - m_debugLabel[0] = '\0'; - memset(m_allocations, 0, sizeof(AllocationInfo) * KRENGINE_MAX_GPU_COUNT); - m_is_vbo_loaded = false; - m_is_vbo_ready = false; - init(manager, data,index_data,vertex_attrib_flags, static_vbo, t + m_debugLabel[0] = '\0'; + memset(m_allocations, 0, sizeof(AllocationInfo) * KRENGINE_MAX_GPU_COUNT); + m_is_vbo_loaded = false; + m_is_vbo_ready = false; + init(manager, data, index_data, vertex_attrib_flags, static_vbo, t #if KRENGINE_DEBUG_GPU_LABELS - , debug_label + , debug_label #endif - ); + ); } -void KRMeshManager::KRVBOData::init(KRMeshManager *manager, KRDataBlock *data, KRDataBlock *index_data, int vertex_attrib_flags, bool static_vbo, vbo_type t +void KRMeshManager::KRVBOData::init(KRMeshManager* manager, KRDataBlock* data, KRDataBlock* index_data, int vertex_attrib_flags, bool static_vbo, vbo_type t #if KRENGINE_DEBUG_GPU_LABELS , const char* debug_label #endif @@ -494,27 +501,27 @@ void KRMeshManager::KRVBOData::init(KRMeshManager *manager, KRDataBlock *data, K #if KRENGINE_DEBUG_GPU_LABELS snprintf(m_debugLabel, KRENGINE_DEBUG_GPU_LABEL_MAX_LEN, debug_label); #endif //KRENGINE_DEBUG_GPU_LABELS - m_manager = manager; - m_type = t; - m_static_vbo = static_vbo; - m_data = data; - m_index_data = index_data; - m_vertex_attrib_flags = vertex_attrib_flags; - - m_size = m_data->getSize(); - if(m_index_data != NULL) { - m_size += m_index_data->getSize(); - } + m_manager = manager; + m_type = t; + m_static_vbo = static_vbo; + m_data = data; + m_index_data = index_data; + m_vertex_attrib_flags = vertex_attrib_flags; - if (t == KRVBOData::CONSTANT) { - m_manager->primeVBO(this); - } + m_size = m_data->getSize(); + if (m_index_data != NULL) { + m_size += m_index_data->getSize(); + } + + if (t == KRVBOData::CONSTANT) { + m_manager->primeVBO(this); + } } KRMeshManager::KRVBOData::~KRVBOData() { - // TODO - This needs to be done by the streamer thread, and asserted here... - unload(); + // TODO - This needs to be done by the streamer thread, and asserted here... + unload(); } void KRMeshManager::KRVBOData::load() @@ -526,90 +533,90 @@ void KRMeshManager::KRVBOData::load() void KRMeshManager::KRVBOData::load(VkCommandBuffer& commandBuffer) { - // TODO - We should load on each GPU only if there is a surface using the mesh - if(isVBOLoaded()) { - return; + // TODO - We should load on each GPU only if there is a surface using the mesh + if (isVBOLoaded()) { + return; + } + + KRDeviceManager* deviceManager = m_manager->getContext().getDeviceManager(); + int iAllocation = 0; + + for (auto deviceItr = deviceManager->getDevices().begin(); deviceItr != deviceManager->getDevices().end() && iAllocation < KRENGINE_MAX_GPU_COUNT; deviceItr++, iAllocation++) { + KRDevice& device = *(*deviceItr).second; + KrDeviceHandle deviceHandle = (*deviceItr).first; + VmaAllocator allocator = device.getAllocator(); + AllocationInfo& allocation = m_allocations[iAllocation]; + allocation.device = deviceHandle; + +#if KRENGINE_DEBUG_GPU_LABELS + char debug_label[KRENGINE_DEBUG_GPU_LABEL_MAX_LEN]; + + char* type_label = ""; + + switch (m_type) { + case vbo_type::STREAMING: + type_label = "Streaming"; + break; + case vbo_type::CONSTANT: + type_label = "Constant"; + break; + case vbo_type::IMMEDIATE: + type_label = "Immediate"; + break; + default: + assert(false); } - KRDeviceManager* deviceManager = m_manager->getContext().getDeviceManager(); - int iAllocation = 0; - - for (auto deviceItr = deviceManager->getDevices().begin(); deviceItr != deviceManager->getDevices().end() && iAllocation < KRENGINE_MAX_GPU_COUNT; deviceItr++, iAllocation++) { - KRDevice& device = *(*deviceItr).second; - KrDeviceHandle deviceHandle = (*deviceItr).first; - VmaAllocator allocator = device.getAllocator(); - AllocationInfo& allocation = m_allocations[iAllocation]; - allocation.device = deviceHandle; - -#if KRENGINE_DEBUG_GPU_LABELS - char debug_label[KRENGINE_DEBUG_GPU_LABEL_MAX_LEN]; - - char* type_label = ""; - - switch (m_type) { - case vbo_type::STREAMING: - type_label = "Streaming"; - break; - case vbo_type::CONSTANT: - type_label = "Constant"; - break; - case vbo_type::IMMEDIATE: - type_label = "Immediate"; - break; - default: - assert(false); - } - - snprintf(debug_label, KRENGINE_DEBUG_GPU_LABEL_MAX_LEN, "%s Vertices: %s", type_label, m_debugLabel); + snprintf(debug_label, KRENGINE_DEBUG_GPU_LABEL_MAX_LEN, "%s Vertices: %s", type_label, m_debugLabel); #endif // KRENGINE_DEBUG_GPU_LABELS + device.createBuffer( + m_data->getSize(), + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + &allocation.vertex_buffer, + &allocation.vertex_allocation +#if KRENGINE_DEBUG_GPU_LABELS + , debug_label +#endif // KRENGINE_DEBUG_GPU_LABELS + ); + if (m_type == vbo_type::IMMEDIATE) { + device.graphicsUpload(commandBuffer, *m_data, allocation.vertex_buffer); + } else { + device.streamUpload(*m_data, allocation.vertex_buffer); + } + + + if (m_index_data && m_index_data->getSize() > 0) { +#if KRENGINE_DEBUG_GPU_LABELS + snprintf(debug_label, KRENGINE_DEBUG_GPU_LABEL_MAX_LEN, "%s Indexes: %s", type_label, m_debugLabel); +#endif // KRENGINE_DEBUG_GPU_LABELS device.createBuffer( - m_data->getSize(), - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + m_index_data->getSize(), + VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - &allocation.vertex_buffer, - &allocation.vertex_allocation + &allocation.index_buffer, + &allocation.index_allocation #if KRENGINE_DEBUG_GPU_LABELS , debug_label -#endif // KRENGINE_DEBUG_GPU_LABELS +#endif ); if (m_type == vbo_type::IMMEDIATE) { - device.graphicsUpload(commandBuffer, *m_data, allocation.vertex_buffer); + device.graphicsUpload(commandBuffer, *m_index_data, allocation.index_buffer); } else { - device.streamUpload(*m_data, allocation.vertex_buffer); - } - - - if (m_index_data && m_index_data->getSize() > 0) { -#if KRENGINE_DEBUG_GPU_LABELS - snprintf(debug_label, KRENGINE_DEBUG_GPU_LABEL_MAX_LEN, "%s Indexes: %s", type_label, m_debugLabel); -#endif // KRENGINE_DEBUG_GPU_LABELS - device.createBuffer( - m_index_data->getSize(), - VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - &allocation.index_buffer, - &allocation.index_allocation -#if KRENGINE_DEBUG_GPU_LABELS - , debug_label -#endif - ); - if (m_type == vbo_type::IMMEDIATE) { - device.graphicsUpload(commandBuffer, *m_index_data, allocation.index_buffer); - } else { - device.streamUpload(*m_index_data, allocation.index_buffer); - } + device.streamUpload(*m_index_data, allocation.index_buffer); } } - - m_is_vbo_loaded = true; + } - m_manager->m_vboMemUsed += getSize(); - m_manager->m_memoryTransferredThisFrame += getSize(); - - if(m_type != STREAMING) { - _swapHandles(); - } + m_is_vbo_loaded = true; + + m_manager->m_vboMemUsed += getSize(); + m_manager->m_memoryTransferredThisFrame += getSize(); + + if (m_type != STREAMING) { + _swapHandles(); + } } void KRMeshManager::KRVBOData::unload() @@ -630,10 +637,10 @@ void KRMeshManager::KRVBOData::unload() memset(&allocation, 0, sizeof(AllocationInfo)); } - if(isVBOLoaded()) { - m_manager->m_vboMemUsed -= getSize(); + if (isVBOLoaded()) { + m_manager->m_vboMemUsed -= getSize(); } - + m_is_vbo_loaded = false; m_is_vbo_ready = false; } @@ -652,37 +659,37 @@ void KRMeshManager::KRVBOData::bind(VkCommandBuffer& commandBuffer) void KRMeshManager::KRVBOData::resetPoolExpiry(float lodCoverage) { - long current_frame = m_manager->getContext().getCurrentFrame(); - if(current_frame != m_last_frame_used) { - m_last_frame_used = current_frame; - m_last_frame_max_lod_coverage = 0.0f; - - m_manager->primeVBO(this); - } - m_last_frame_max_lod_coverage = KRMAX(lodCoverage, m_last_frame_max_lod_coverage); + long current_frame = m_manager->getContext().getCurrentFrame(); + if (current_frame != m_last_frame_used) { + m_last_frame_used = current_frame; + m_last_frame_max_lod_coverage = 0.0f; + + m_manager->primeVBO(this); + } + m_last_frame_max_lod_coverage = KRMAX(lodCoverage, m_last_frame_max_lod_coverage); } float KRMeshManager::KRVBOData::getStreamPriority() { - long current_frame = m_manager->getContext().getCurrentFrame(); - if(current_frame > m_last_frame_used + 5) { - return 1.0f - KRCLAMP((float)(current_frame - m_last_frame_used) / 60.0f, 0.0f, 1.0f); - } else { - return 10000.0f + m_last_frame_max_lod_coverage * 10.0f; - } + long current_frame = m_manager->getContext().getCurrentFrame(); + if (current_frame > m_last_frame_used + 5) { + return 1.0f - KRCLAMP((float)(current_frame - m_last_frame_used) / 60.0f, 0.0f, 1.0f); + } else { + return 10000.0f + m_last_frame_max_lod_coverage * 10.0f; + } } void KRMeshManager::KRVBOData::_swapHandles() { - m_is_vbo_ready = m_is_vbo_loaded; + m_is_vbo_ready = m_is_vbo_loaded; } -void KRMeshManager::primeVBO(KRVBOData *vbo_data) +void KRMeshManager::primeVBO(KRVBOData* vbo_data) { - if(m_vbosActive.find(vbo_data->m_data) == m_vbosActive.end()) { - m_vbosActive[vbo_data->m_data] = vbo_data; - } + if (m_vbosActive.find(vbo_data->m_data) == m_vbosActive.end()) { + m_vbosActive[vbo_data->m_data] = vbo_data; + } } diff --git a/kraken/KRMeshManager.h b/kraken/KRMeshManager.h index c4b38b5..63f4f8b 100755 --- a/kraken/KRMeshManager.h +++ b/kraken/KRMeshManager.h @@ -41,184 +41,206 @@ class KRContext; class KRMesh; -class KRMeshManager : public KRResourceManager { +class KRMeshManager : public KRResourceManager +{ public: - static const int KRENGINE_MAX_VOLUMETRIC_PLANES=500; - static const int KRENGINE_MAX_RANDOM_PARTICLES=150000; - - KRMeshManager(KRContext &context); - void init(); - virtual ~KRMeshManager(); + static const int KRENGINE_MAX_VOLUMETRIC_PLANES = 500; + static const int KRENGINE_MAX_RANDOM_PARTICLES = 150000; - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - - void startFrame(float deltaTime); - void endFrame(float deltaTime); - - KRMesh *loadModel(const char *szName, KRDataBlock *pData); - std::vector getModel(const char *szName); - KRMesh* KRMeshManager::getMaxLODModel(const char* szName); - void addModel(KRMesh *model); - - std::vector getModelNames(); - unordered_multimap &getModels(); - - class KRVBOData { - - public: - - typedef enum { - STREAMING, - // STREAMING data is loaded asynchronously, with transfer queues in the streamer thread. - - CONSTANT, - // CONSTANT data is loaded asyncrhronously, with transfer queues in the streamer thread, but is not unloaded. + KRMeshManager(KRContext& context); + void init(); + virtual ~KRMeshManager(); - IMMEDIATE - // IMMEDIATE data is loaded synchronously, with graphics queues in the presentation threads. - // IMMEDIATE data is available for use immediately on the same frame it is generated. - } vbo_type; - - KRVBOData(); - KRVBOData(KRMeshManager *manager, KRDataBlock *data, KRDataBlock *index_data, int vertex_attrib_flags, bool static_vbo, vbo_type t + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; + + void startFrame(float deltaTime); + void endFrame(float deltaTime); + + KRMesh* loadModel(const char* szName, KRDataBlock* pData); + std::vector getModel(const char* szName); + KRMesh* KRMeshManager::getMaxLODModel(const char* szName); + void addModel(KRMesh* model); + + std::vector getModelNames(); + unordered_multimap& getModels(); + + class KRVBOData + { + + public: + + typedef enum + { + STREAMING, + // STREAMING data is loaded asynchronously, with transfer queues in the streamer thread. + + CONSTANT, + // CONSTANT data is loaded asyncrhronously, with transfer queues in the streamer thread, but is not unloaded. + + IMMEDIATE + // IMMEDIATE data is loaded synchronously, with graphics queues in the presentation threads. + // IMMEDIATE data is available for use immediately on the same frame it is generated. + } vbo_type; + + KRVBOData(); + KRVBOData(KRMeshManager* manager, KRDataBlock* data, KRDataBlock* index_data, int vertex_attrib_flags, bool static_vbo, vbo_type t #if KRENGINE_DEBUG_GPU_LABELS - , const char* debug_label + , const char* debug_label #endif - ); - void init(KRMeshManager *manager, KRDataBlock *data, KRDataBlock *index_data, int vertex_attrib_flags, bool static_vbo, vbo_type t + ); + void init(KRMeshManager* manager, KRDataBlock* data, KRDataBlock* index_data, int vertex_attrib_flags, bool static_vbo, vbo_type t #if KRENGINE_DEBUG_GPU_LABELS - , const char* debug_label + , const char* debug_label #endif - ); - ~KRVBOData(); - - - KRDataBlock *m_data; - KRDataBlock *m_index_data; - - bool isVBOLoaded() { return m_is_vbo_loaded; } - bool isVBOReady() { return m_is_vbo_ready; } - void load(); - void load(VkCommandBuffer& commandBuffer); - void unload(); - void bind(VkCommandBuffer& commandBuffer); - - // Disable copy constructors - KRVBOData(const KRVBOData& o) = delete; - KRVBOData& operator=(const KRVBOData& o) = delete; - - long getSize() { return (long)m_size; } - - void resetPoolExpiry(float lodCoverage); - long getLastFrameUsed() { return m_last_frame_used; } - - vbo_type getType() { return m_type; } - - float getStreamPriority(); - - void _swapHandles(); + ); + ~KRVBOData(); - VkBuffer& getVertexBuffer(); - VkBuffer& getIndexBuffer(); - uint32_t getVertexAttributes(); - - private: - KRMeshManager *m_manager; - int m_vertex_attrib_flags; - long m_size; - - long m_last_frame_used; - float m_last_frame_max_lod_coverage; - vbo_type m_type; - bool m_static_vbo; - bool m_is_vbo_loaded; - bool m_is_vbo_ready; - typedef struct { - KrDeviceHandle device; - VkBuffer vertex_buffer; - VmaAllocation vertex_allocation; - VkBuffer index_buffer; - VmaAllocation index_allocation; - } AllocationInfo; + KRDataBlock* m_data; + KRDataBlock* m_index_data; - AllocationInfo m_allocations[KRENGINE_MAX_GPU_COUNT]; + bool isVBOLoaded() + { + return m_is_vbo_loaded; + } + bool isVBOReady() + { + return m_is_vbo_ready; + } + void load(); + void load(VkCommandBuffer& commandBuffer); + void unload(); + void bind(VkCommandBuffer& commandBuffer); + + // Disable copy constructors + KRVBOData(const KRVBOData& o) = delete; + KRVBOData& operator=(const KRVBOData& o) = delete; + + long getSize() + { + return (long)m_size; + } + + void resetPoolExpiry(float lodCoverage); + long getLastFrameUsed() + { + return m_last_frame_used; + } + + vbo_type getType() + { + return m_type; + } + + float getStreamPriority(); + + void _swapHandles(); + + VkBuffer& getVertexBuffer(); + VkBuffer& getIndexBuffer(); + uint32_t getVertexAttributes(); + + private: + KRMeshManager* m_manager; + int m_vertex_attrib_flags; + long m_size; + + long m_last_frame_used; + float m_last_frame_max_lod_coverage; + vbo_type m_type; + bool m_static_vbo; + bool m_is_vbo_loaded; + bool m_is_vbo_ready; + + typedef struct + { + KrDeviceHandle device; + VkBuffer vertex_buffer; + VmaAllocation vertex_allocation; + VkBuffer index_buffer; + VmaAllocation index_allocation; + } AllocationInfo; + + AllocationInfo m_allocations[KRENGINE_MAX_GPU_COUNT]; #if KRENGINE_DEBUG_GPU_LABELS - char m_debugLabel[KRENGINE_DEBUG_GPU_LABEL_MAX_LEN]; + char m_debugLabel[KRENGINE_DEBUG_GPU_LABEL_MAX_LEN]; #endif - }; - - void bindVBO(VkCommandBuffer& commandBuffer, KRVBOData *vbo_data, float lodCoverage); - long getMemUsed(); - long getMemActive(); - - typedef struct { - Vector3 vertex; - Vector2 uva; - } RandomParticleVertexData; - - typedef struct { - Vector3 vertex; - } VolumetricLightingVertexData; - - long getMemoryTransferedThisFrame(); + }; - size_t getActiveVBOCount(); - - struct draw_call_info { - KRNode::RenderPass pass; - char object_name[256]; - char material_name[256]; - int vertex_count; - }; - - void log_draw_call(KRNode::RenderPass pass, const std::string &object_name, const std::string &material_name, int vertex_count); - std::vector getDrawCalls(); - - + void bindVBO(VkCommandBuffer& commandBuffer, KRVBOData* vbo_data, float lodCoverage); + long getMemUsed(); + long getMemActive(); - KRVBOData KRENGINE_VBO_DATA_3D_CUBE_VERTICES; - KRVBOData KRENGINE_VBO_DATA_2D_SQUARE_VERTICES; - KRVBOData KRENGINE_VBO_DATA_RANDOM_PARTICLES; - KRVBOData KRENGINE_VBO_DATA_VOLUMETRIC_LIGHTING; + typedef struct + { + Vector3 vertex; + Vector2 uva; + } RandomParticleVertexData; + + typedef struct + { + Vector3 vertex; + } VolumetricLightingVertexData; + + long getMemoryTransferedThisFrame(); + + size_t getActiveVBOCount(); + + struct draw_call_info + { + KRNode::RenderPass pass; + char object_name[256]; + char material_name[256]; + int vertex_count; + }; + + void log_draw_call(KRNode::RenderPass pass, const std::string& object_name, const std::string& material_name, int vertex_count); + std::vector getDrawCalls(); + + + + KRVBOData KRENGINE_VBO_DATA_3D_CUBE_VERTICES; + KRVBOData KRENGINE_VBO_DATA_2D_SQUARE_VERTICES; + KRVBOData KRENGINE_VBO_DATA_RANDOM_PARTICLES; + KRVBOData KRENGINE_VBO_DATA_VOLUMETRIC_LIGHTING; + + + void doStreaming(long& memoryRemaining, long& memoryRemainingThisFrame); - - void doStreaming(long &memoryRemaining, long &memoryRemainingThisFrame); - private: - KRDataBlock KRENGINE_VBO_3D_CUBE_VERTICES; - __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS; - KRDataBlock KRENGINE_VBO_2D_SQUARE_VERTICES; - __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS; - - unordered_multimap m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model - - long m_vboMemUsed; - KRVBOData *m_currentVBO; - - unordered_map m_vbosActive; - std::vector > m_activeVBOs_streamer; - std::vector > m_activeVBOs_streamer_copy; - - KRDataBlock m_randomParticleVertexData; - KRDataBlock m_volumetricLightingVertexData; - - long m_memoryTransferredThisFrame; - - std::vector m_draw_calls; - bool m_draw_call_logging_enabled; - bool m_draw_call_log_used; - - std::mutex m_streamerFenceMutex; - bool m_streamerComplete; - - void balanceVBOMemory(long &memoryRemaining, long &memoryRemainingThisFrame); - - void primeVBO(KRVBOData *vbo_data); + KRDataBlock KRENGINE_VBO_3D_CUBE_VERTICES; + __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS; + KRDataBlock KRENGINE_VBO_2D_SQUARE_VERTICES; + __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS; - void initRandomParticles(); - void initVolumetricLightingVertexes(); + unordered_multimap m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model + + long m_vboMemUsed; + KRVBOData* m_currentVBO; + + unordered_map m_vbosActive; + std::vector > m_activeVBOs_streamer; + std::vector > m_activeVBOs_streamer_copy; + + KRDataBlock m_randomParticleVertexData; + KRDataBlock m_volumetricLightingVertexData; + + long m_memoryTransferredThisFrame; + + std::vector m_draw_calls; + bool m_draw_call_logging_enabled; + bool m_draw_call_log_used; + + std::mutex m_streamerFenceMutex; + bool m_streamerComplete; + + void balanceVBOMemory(long& memoryRemaining, long& memoryRemainingThisFrame); + + void primeVBO(KRVBOData* vbo_data); + + void initRandomParticles(); + void initVolumetricLightingVertexes(); }; diff --git a/kraken/KRMeshQuad.cpp b/kraken/KRMeshQuad.cpp index e978501..fa5a540 100755 --- a/kraken/KRMeshQuad.cpp +++ b/kraken/KRMeshQuad.cpp @@ -32,32 +32,32 @@ #include "KRMeshQuad.h" -KRMeshQuad::KRMeshQuad(KRContext &context) : KRMesh(context, "__quad") +KRMeshQuad::KRMeshQuad(KRContext& context) : KRMesh(context, "__quad") { - m_constant = true; - - KRMesh::mesh_info mi; - - mi.vertices.push_back(Vector3::Create(-1.0f, -1.0f, 0.0f)); - mi.vertices.push_back(Vector3::Create(1.0f, -1.0f, 0.0f)); - mi.vertices.push_back(Vector3::Create(-1.0f, 1.0f, 0.0f)); - mi.vertices.push_back(Vector3::Create(1.0f, 1.0f, 0.0f)); - - mi.uva.push_back(Vector2::Create(0.0f, 0.0f)); - mi.uva.push_back(Vector2::Create(1.0f, 0.0f)); - mi.uva.push_back(Vector2::Create(0.0f, 1.0f)); - mi.uva.push_back(Vector2::Create(1.0f, 1.0f)); - - - mi.submesh_starts.push_back(0); - mi.submesh_lengths.push_back((int)mi.vertices.size()); - mi.material_names.push_back(""); - mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; - - LoadData(mi, true, true); + m_constant = true; + + KRMesh::mesh_info mi; + + mi.vertices.push_back(Vector3::Create(-1.0f, -1.0f, 0.0f)); + mi.vertices.push_back(Vector3::Create(1.0f, -1.0f, 0.0f)); + mi.vertices.push_back(Vector3::Create(-1.0f, 1.0f, 0.0f)); + mi.vertices.push_back(Vector3::Create(1.0f, 1.0f, 0.0f)); + + mi.uva.push_back(Vector2::Create(0.0f, 0.0f)); + mi.uva.push_back(Vector2::Create(1.0f, 0.0f)); + mi.uva.push_back(Vector2::Create(0.0f, 1.0f)); + mi.uva.push_back(Vector2::Create(1.0f, 1.0f)); + + + mi.submesh_starts.push_back(0); + mi.submesh_lengths.push_back((int)mi.vertices.size()); + mi.material_names.push_back(""); + mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; + + LoadData(mi, true, true); } KRMeshQuad::~KRMeshQuad() { - + } diff --git a/kraken/KRMeshQuad.h b/kraken/KRMeshQuad.h index 0ca1efa..15ce7ef 100755 --- a/kraken/KRMeshQuad.h +++ b/kraken/KRMeshQuad.h @@ -33,9 +33,10 @@ #include "KRMesh.h" -class KRMeshQuad : public KRMesh { +class KRMeshQuad : public KRMesh +{ public: - KRMeshQuad(KRContext &context); - virtual ~KRMeshQuad(); + KRMeshQuad(KRContext& context); + virtual ~KRMeshQuad(); private: }; diff --git a/kraken/KRMeshSphere.cpp b/kraken/KRMeshSphere.cpp index 087e720..21298c1 100755 --- a/kraken/KRMeshSphere.cpp +++ b/kraken/KRMeshSphere.cpp @@ -32,97 +32,97 @@ #include "KRMeshSphere.h" -KRMeshSphere::KRMeshSphere(KRContext &context) : KRMesh(context, "__sphere") +KRMeshSphere::KRMeshSphere(KRContext& context) : KRMesh(context, "__sphere") { - m_constant = true; - - KRMesh::mesh_info mi; - - // Create a triangular facet approximation to a sphere - // Based on algorithm from Paul Bourke: http://paulbourke.net/miscellaneous/sphere_cylinder/ - - int iterations = 3; - int facet_count = (int)(pow(4, iterations) * 8.0f); - - std::vector f = std::vector(facet_count); - - int i,it; - float a; - Vector3 p[6] = { - Vector3::Create(0,0,1), - Vector3::Create(0,0,-1), - Vector3::Create(-1,-1,0), - Vector3::Create(1,-1,0), - Vector3::Create(1,1,0), - Vector3::Create(-1,1,0) - }; - - Vector3 pa,pb,pc; - int nt = 0,ntold; - - /* Create the level 0 object */ - a = 1.0f / sqrtf(2.0f); - for (i=0;i<6;i++) { - p[i].x *= a; - p[i].y *= a; - } - f[0][0] = p[0]; f[0][1] = p[3]; f[0][2] = p[4]; - f[1][0] = p[0]; f[1][1] = p[4]; f[1][2] = p[5]; - f[2][0] = p[0]; f[2][1] = p[5]; f[2][2] = p[2]; - f[3][0] = p[0]; f[3][1] = p[2]; f[3][2] = p[3]; - f[4][0] = p[1]; f[4][1] = p[4]; f[4][2] = p[3]; - f[5][0] = p[1]; f[5][1] = p[5]; f[5][2] = p[4]; - f[6][0] = p[1]; f[6][1] = p[2]; f[6][2] = p[5]; - f[7][0] = p[1]; f[7][1] = p[3]; f[7][2] = p[2]; - nt = 8; - - /* Bisect each edge and move to the surface of a unit sphere */ - for (it=0;it f = std::vector(facet_count); + + int i, it; + float a; + Vector3 p[6] = { + Vector3::Create(0,0,1), + Vector3::Create(0,0,-1), + Vector3::Create(-1,-1,0), + Vector3::Create(1,-1,0), + Vector3::Create(1,1,0), + Vector3::Create(-1,1,0) + }; + + Vector3 pa, pb, pc; + int nt = 0, ntold; + + /* Create the level 0 object */ + a = 1.0f / sqrtf(2.0f); + for (i = 0; i < 6; i++) { + p[i].x *= a; + p[i].y *= a; + } + f[0][0] = p[0]; f[0][1] = p[3]; f[0][2] = p[4]; + f[1][0] = p[0]; f[1][1] = p[4]; f[1][2] = p[5]; + f[2][0] = p[0]; f[2][1] = p[5]; f[2][2] = p[2]; + f[3][0] = p[0]; f[3][1] = p[2]; f[3][2] = p[3]; + f[4][0] = p[1]; f[4][1] = p[4]; f[4][2] = p[3]; + f[5][0] = p[1]; f[5][1] = p[5]; f[5][2] = p[4]; + f[6][0] = p[1]; f[6][1] = p[2]; f[6][2] = p[5]; + f[7][0] = p[1]; f[7][1] = p[3]; f[7][2] = p[2]; + nt = 8; + + /* Bisect each edge and move to the surface of a unit sphere */ + for (it = 0; it < iterations; it++) { + ntold = nt; + for (i = 0; i < ntold; i++) { + pa.x = (f[i][0].x + f[i][1].x) / 2; + pa.y = (f[i][0].y + f[i][1].y) / 2; + pa.z = (f[i][0].z + f[i][1].z) / 2; + pb.x = (f[i][1].x + f[i][2].x) / 2; + pb.y = (f[i][1].y + f[i][2].y) / 2; + pb.z = (f[i][1].z + f[i][2].z) / 2; + pc.x = (f[i][2].x + f[i][0].x) / 2; + pc.y = (f[i][2].y + f[i][0].y) / 2; + pc.z = (f[i][2].z + f[i][0].z) / 2; + pa.normalize(); + pb.normalize(); + pc.normalize(); + f[nt][0] = f[i][0]; f[nt][1] = pa; f[nt][2] = pc; nt++; + f[nt][0] = pa; f[nt][1] = f[i][1]; f[nt][2] = pb; nt++; + f[nt][0] = pb; f[nt][1] = f[i][2]; f[nt][2] = pc; nt++; + f[i][0] = pa; + f[i][1] = pb; + f[i][2] = pc; + } + } + + for (int facet_index = 0; facet_index < facet_count; facet_index++) { + mi.vertices.push_back(f[facet_index][0]); + mi.vertices.push_back(f[facet_index][1]); + mi.vertices.push_back(f[facet_index][2]); + } + + mi.submesh_starts.push_back(0); + mi.submesh_lengths.push_back((int)mi.vertices.size()); + mi.material_names.push_back(""); + + + mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; + + // Generate normals pointing away from center of sphere. + for (int vertex_index = 0; vertex_index < mi.vertices.size(); vertex_index++) { + mi.normals.push_back(Vector3::Normalize(mi.vertices[vertex_index] - Vector3::Zero())); + } + + LoadData(mi, true, true); } KRMeshSphere::~KRMeshSphere() { - + } diff --git a/kraken/KRMeshSphere.h b/kraken/KRMeshSphere.h index 8cc68b3..9510a5c 100755 --- a/kraken/KRMeshSphere.h +++ b/kraken/KRMeshSphere.h @@ -33,9 +33,10 @@ #include "KRMesh.h" -class KRMeshSphere : public KRMesh { +class KRMeshSphere : public KRMesh +{ public: - KRMeshSphere(KRContext &context); - virtual ~KRMeshSphere(); + KRMeshSphere(KRContext& context); + virtual ~KRMeshSphere(); private: }; diff --git a/kraken/KRModel.cpp b/kraken/KRModel.cpp index 5a4bc64..d2657de 100755 --- a/kraken/KRModel.cpp +++ b/kraken/KRModel.cpp @@ -49,234 +49,240 @@ void KRModel::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->model.rim_power = 0.0f; } -KRModel::KRModel(KRScene &scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage, bool receives_shadow, bool faces_camera, Vector3 rim_color, float rim_power) : KRNode(scene, instance_name) { - m_lightMap = light_map; - m_pLightMap = NULL; - m_model_name = model_name; - m_min_lod_coverage = lod_min_coverage; - m_receivesShadow = receives_shadow; - m_faces_camera = faces_camera; - m_rim_color = rim_color; - m_rim_power = rim_power; - - m_boundsCachedMat.c[0] = -1.0f; - m_boundsCachedMat.c[1] = -1.0f; - m_boundsCachedMat.c[2] = -1.0f; - m_boundsCachedMat.c[3] = -1.0f; - m_boundsCachedMat.c[4] = -1.0f; - m_boundsCachedMat.c[5] = -1.0f; - m_boundsCachedMat.c[6] = -1.0f; - m_boundsCachedMat.c[7] = -1.0f; - m_boundsCachedMat.c[8] = -1.0f; - m_boundsCachedMat.c[9] = -1.0f; - m_boundsCachedMat.c[10] = -1.0f; - m_boundsCachedMat.c[11] = -1.0f; - m_boundsCachedMat.c[12] = -1.0f; - m_boundsCachedMat.c[13] = -1.0f; - m_boundsCachedMat.c[14] = -1.0f; - m_boundsCachedMat.c[15] = -1.0f; -} - -KRModel::~KRModel() { - -} - -std::string KRModel::getElementName() { - return "model"; -} - -tinyxml2::XMLElement *KRModel::saveXML( tinyxml2::XMLNode *parent) +KRModel::KRModel(KRScene& scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage, bool receives_shadow, bool faces_camera, Vector3 rim_color, float rim_power) : KRNode(scene, instance_name) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - e->SetAttribute("mesh", m_model_name.c_str()); - e->SetAttribute("light_map", m_lightMap.c_str()); - e->SetAttribute("lod_min_coverage", m_min_lod_coverage); - e->SetAttribute("receives_shadow", m_receivesShadow ? "true" : "false"); - e->SetAttribute("faces_camera", m_faces_camera ? "true" : "false"); - kraken::setXMLAttribute("rim_color", e, m_rim_color, Vector3::Zero()); - e->SetAttribute("rim_power", m_rim_power); - return e; + m_lightMap = light_map; + m_pLightMap = NULL; + m_model_name = model_name; + m_min_lod_coverage = lod_min_coverage; + m_receivesShadow = receives_shadow; + m_faces_camera = faces_camera; + m_rim_color = rim_color; + m_rim_power = rim_power; + + m_boundsCachedMat.c[0] = -1.0f; + m_boundsCachedMat.c[1] = -1.0f; + m_boundsCachedMat.c[2] = -1.0f; + m_boundsCachedMat.c[3] = -1.0f; + m_boundsCachedMat.c[4] = -1.0f; + m_boundsCachedMat.c[5] = -1.0f; + m_boundsCachedMat.c[6] = -1.0f; + m_boundsCachedMat.c[7] = -1.0f; + m_boundsCachedMat.c[8] = -1.0f; + m_boundsCachedMat.c[9] = -1.0f; + m_boundsCachedMat.c[10] = -1.0f; + m_boundsCachedMat.c[11] = -1.0f; + m_boundsCachedMat.c[12] = -1.0f; + m_boundsCachedMat.c[13] = -1.0f; + m_boundsCachedMat.c[14] = -1.0f; + m_boundsCachedMat.c[15] = -1.0f; } -void KRModel::setRimColor(const Vector3 &rim_color) +KRModel::~KRModel() { - m_rim_color = rim_color; + +} + +std::string KRModel::getElementName() +{ + return "model"; +} + +tinyxml2::XMLElement* KRModel::saveXML(tinyxml2::XMLNode* parent) +{ + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + e->SetAttribute("mesh", m_model_name.c_str()); + e->SetAttribute("light_map", m_lightMap.c_str()); + e->SetAttribute("lod_min_coverage", m_min_lod_coverage); + e->SetAttribute("receives_shadow", m_receivesShadow ? "true" : "false"); + e->SetAttribute("faces_camera", m_faces_camera ? "true" : "false"); + kraken::setXMLAttribute("rim_color", e, m_rim_color, Vector3::Zero()); + e->SetAttribute("rim_power", m_rim_power); + return e; +} + +void KRModel::setRimColor(const Vector3& rim_color) +{ + m_rim_color = rim_color; } void KRModel::setRimPower(float rim_power) { - m_rim_power = rim_power; + m_rim_power = rim_power; } Vector3 KRModel::getRimColor() { - return m_rim_color; + return m_rim_color; } float KRModel::getRimPower() { - return m_rim_power; + return m_rim_power; } -void KRModel::setLightMap(const std::string &name) +void KRModel::setLightMap(const std::string& name) { - m_lightMap = name; - m_pLightMap = NULL; + m_lightMap = name; + m_pLightMap = NULL; } std::string KRModel::getLightMap() { - return m_lightMap; + return m_lightMap; } -void KRModel::loadModel() { - if(m_models.size() == 0) { - std::vector models = m_pContext->getMeshManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first - unordered_map > bones; - if(models.size() > 0) { - bool all_bones_found = true; - for(std::vector::iterator model_itr = models.begin(); model_itr != models.end(); model_itr++) { - KRMesh *model = *model_itr; - std::vector model_bones; - int bone_count = model->getBoneCount(); - for(int bone_index=0; bone_index < bone_count; bone_index++) { - KRBone *matching_bone = dynamic_cast(getScene().getRootNode()->find(model->getBoneName(bone_index))); - if(matching_bone) { - model_bones.push_back(matching_bone); - } else { - all_bones_found = false; // Reject when there are any missing bones or multiple matches - } - } - bones[model] = model_bones; - } - if(all_bones_found) { - m_models = models; - m_bones = bones; - getScene().notify_sceneGraphModify(this); - } - - invalidateBounds(); - } - } -} - -void KRModel::render(KRNode::RenderInfo& ri) { - - if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM && ri.renderPass == KRNode::RENDER_PASS_PRESTREAM) { - preStream(ri.viewport); - } - - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRNode::render(ri); - - if(ri.renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS - && ri.renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES - && ri.renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION - && ri.renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE - && ri.renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS - && ri.renderPass != KRNode::RENDER_PASS_PRESTREAM) { - loadModel(); - - if(m_models.size() > 0) { - // Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied - - /* - float lod_coverage = 0.0f; - if(m_models.size() > 1) { - lod_coverage = viewport.coverage(getBounds()); // This also checks the view frustrum culling - } else if(viewport.visible(getBounds())) { - lod_coverage = 1.0f; - } - */ - - float lod_coverage = ri.viewport.coverage(getBounds()); // This also checks the view frustrum culling - - if(lod_coverage > m_min_lod_coverage) { - - // ---===--- Select the best LOD model based on screen coverage ---===--- - std::vector::iterator itr=m_models.begin(); - KRMesh *pModel = *itr++; - - while(itr != m_models.end()) { - KRMesh *pLODModel = *itr++; - if((float)pLODModel->getLODCoverage() / 100.0f > lod_coverage && pLODModel->getLODCoverage() < pModel->getLODCoverage()) { - pModel = pLODModel; - } else { - break; - } - } - - if(m_pLightMap == NULL && m_lightMap.size()) { - m_pLightMap = getContext().getTextureManager()->getTexture(m_lightMap); - } - - if(m_pLightMap && ri.camera->settings.bEnableLightMap && ri.renderPass != RENDER_PASS_SHADOWMAP && ri.renderPass != RENDER_PASS_GENERATE_SHADOWMAPS) { - m_pContext->getTextureManager()->selectTexture(5, m_pLightMap, lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP); - } - - Matrix4 matModel = getModelMatrix(); - if(m_faces_camera) { - Vector3 model_center = Matrix4::Dot(matModel, Vector3::Zero()); - Vector3 camera_pos = ri.viewport.getCameraPosition(); - matModel = Quaternion::Create(Vector3::Forward(), Vector3::Normalize(camera_pos - model_center)).rotationMatrix() * matModel; - } - - pModel->render(ri, getName(), matModel, m_pLightMap, m_bones[pModel], m_rim_color, m_rim_power, lod_coverage); - } - } - } -} - -void KRModel::preStream(const KRViewport &viewport) +void KRModel::loadModel() { - loadModel(); - float lod_coverage = viewport.coverage(getBounds()); - - for(auto itr = m_models.begin(); itr != m_models.end(); itr++) { - (*itr)->preStream(lod_coverage); - } - - if(m_pLightMap == NULL && m_lightMap.size()) { - m_pLightMap = getContext().getTextureManager()->getTexture(m_lightMap); - } - - if(m_pLightMap) { - m_pLightMap->resetPoolExpiry(lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP); - } -} - - -kraken_stream_level KRModel::getStreamLevel(const KRViewport &viewport) -{ - kraken_stream_level stream_level = KRNode::getStreamLevel(viewport); - - loadModel(); - - for(auto itr = m_models.begin(); itr != m_models.end(); itr++) { - stream_level = KRMIN(stream_level, (*itr)->getStreamLevel()); - } - - return stream_level; -} - -AABB KRModel::getBounds() { - loadModel(); - if(m_models.size() > 0) { - if(m_faces_camera) { - AABB normal_bounds = AABB::Create(m_models[0]->getMinPoint(), m_models[0]->getMaxPoint(), getModelMatrix()); - float max_dimension = normal_bounds.longest_radius(); - return AABB::Create(normal_bounds.center()-Vector3::Create(max_dimension), normal_bounds.center() + Vector3::Create(max_dimension)); - } else { - - if(!(m_boundsCachedMat == getModelMatrix())) { - m_boundsCachedMat = getModelMatrix(); - m_boundsCached = AABB::Create(m_models[0]->getMinPoint(), m_models[0]->getMaxPoint(), getModelMatrix()); - } - return m_boundsCached; + if (m_models.size() == 0) { + std::vector models = m_pContext->getMeshManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first + unordered_map > bones; + if (models.size() > 0) { + bool all_bones_found = true; + for (std::vector::iterator model_itr = models.begin(); model_itr != models.end(); model_itr++) { + KRMesh* model = *model_itr; + std::vector model_bones; + int bone_count = model->getBoneCount(); + for (int bone_index = 0; bone_index < bone_count; bone_index++) { + KRBone* matching_bone = dynamic_cast(getScene().getRootNode()->find(model->getBoneName(bone_index))); + if (matching_bone) { + model_bones.push_back(matching_bone); + } else { + all_bones_found = false; // Reject when there are any missing bones or multiple matches + } } + bones[model] = model_bones; + } + if (all_bones_found) { + m_models = models; + m_bones = bones; + getScene().notify_sceneGraphModify(this); + } + + invalidateBounds(); + } + } +} + +void KRModel::render(KRNode::RenderInfo& ri) +{ + + if (m_lod_visible >= LOD_VISIBILITY_PRESTREAM && ri.renderPass == KRNode::RENDER_PASS_PRESTREAM) { + preStream(ri.viewport); + } + + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + + KRNode::render(ri); + + if (ri.renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS + && ri.renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES + && ri.renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION + && ri.renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE + && ri.renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS + && ri.renderPass != KRNode::RENDER_PASS_PRESTREAM) { + loadModel(); + + if (m_models.size() > 0) { + // Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied + + /* + float lod_coverage = 0.0f; + if(m_models.size() > 1) { + lod_coverage = viewport.coverage(getBounds()); // This also checks the view frustrum culling + } else if(viewport.visible(getBounds())) { + lod_coverage = 1.0f; + } + */ + + float lod_coverage = ri.viewport.coverage(getBounds()); // This also checks the view frustrum culling + + if (lod_coverage > m_min_lod_coverage) { + + // ---===--- Select the best LOD model based on screen coverage ---===--- + std::vector::iterator itr = m_models.begin(); + KRMesh* pModel = *itr++; + + while (itr != m_models.end()) { + KRMesh* pLODModel = *itr++; + if ((float)pLODModel->getLODCoverage() / 100.0f > lod_coverage && pLODModel->getLODCoverage() < pModel->getLODCoverage()) { + pModel = pLODModel; + } else { + break; + } + } + + if (m_pLightMap == NULL && m_lightMap.size()) { + m_pLightMap = getContext().getTextureManager()->getTexture(m_lightMap); + } + + if (m_pLightMap && ri.camera->settings.bEnableLightMap && ri.renderPass != RENDER_PASS_SHADOWMAP && ri.renderPass != RENDER_PASS_GENERATE_SHADOWMAPS) { + m_pContext->getTextureManager()->selectTexture(5, m_pLightMap, lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP); + } + + Matrix4 matModel = getModelMatrix(); + if (m_faces_camera) { + Vector3 model_center = Matrix4::Dot(matModel, Vector3::Zero()); + Vector3 camera_pos = ri.viewport.getCameraPosition(); + matModel = Quaternion::Create(Vector3::Forward(), Vector3::Normalize(camera_pos - model_center)).rotationMatrix() * matModel; + } + + pModel->render(ri, getName(), matModel, m_pLightMap, m_bones[pModel], m_rim_color, m_rim_power, lod_coverage); + } + } + } +} + +void KRModel::preStream(const KRViewport& viewport) +{ + loadModel(); + float lod_coverage = viewport.coverage(getBounds()); + + for (auto itr = m_models.begin(); itr != m_models.end(); itr++) { + (*itr)->preStream(lod_coverage); + } + + if (m_pLightMap == NULL && m_lightMap.size()) { + m_pLightMap = getContext().getTextureManager()->getTexture(m_lightMap); + } + + if (m_pLightMap) { + m_pLightMap->resetPoolExpiry(lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP); + } +} + + +kraken_stream_level KRModel::getStreamLevel(const KRViewport& viewport) +{ + kraken_stream_level stream_level = KRNode::getStreamLevel(viewport); + + loadModel(); + + for (auto itr = m_models.begin(); itr != m_models.end(); itr++) { + stream_level = KRMIN(stream_level, (*itr)->getStreamLevel()); + } + + return stream_level; +} + +AABB KRModel::getBounds() +{ + loadModel(); + if (m_models.size() > 0) { + if (m_faces_camera) { + AABB normal_bounds = AABB::Create(m_models[0]->getMinPoint(), m_models[0]->getMaxPoint(), getModelMatrix()); + float max_dimension = normal_bounds.longest_radius(); + return AABB::Create(normal_bounds.center() - Vector3::Create(max_dimension), normal_bounds.center() + Vector3::Create(max_dimension)); } else { - return AABB::Infinite(); + + if (!(m_boundsCachedMat == getModelMatrix())) { + m_boundsCachedMat = getModelMatrix(); + m_boundsCached = AABB::Create(m_models[0]->getMinPoint(), m_models[0]->getMaxPoint(), getModelMatrix()); + } + return m_boundsCached; } + } else { + return AABB::Infinite(); + } } diff --git a/kraken/KRModel.h b/kraken/KRModel.h index 276f6e2..9252105 100755 --- a/kraken/KRModel.h +++ b/kraken/KRModel.h @@ -43,52 +43,53 @@ #include "KRTexture.h" #include "KRBone.h" -class KRModel : public KRNode { - +class KRModel : public KRNode +{ + public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); + static void InitNodeInfo(KrNodeInfo* nodeInfo); - KRModel(KRScene &scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage, bool receives_shadow, bool faces_camera, Vector3 rim_color = Vector3::Zero(), float rim_power = 0.0f); - virtual ~KRModel(); - - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); + KRModel(KRScene& scene, std::string instance_name, std::string model_name, std::string light_map, float lod_min_coverage, bool receives_shadow, bool faces_camera, Vector3 rim_color = Vector3::Zero(), float rim_power = 0.0f); + virtual ~KRModel(); + + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + + virtual void render(KRNode::RenderInfo& ri); + + virtual AABB getBounds(); + + void setRimColor(const Vector3& rim_color); + void setRimPower(float rim_power); + Vector3 getRimColor(); + float getRimPower(); + + void setLightMap(const std::string& name); + std::string getLightMap(); + + virtual kraken_stream_level getStreamLevel(const KRViewport& viewport); - virtual void render(KRNode::RenderInfo& ri); - - virtual AABB getBounds(); - - void setRimColor(const Vector3 &rim_color); - void setRimPower(float rim_power); - Vector3 getRimColor(); - float getRimPower(); - - void setLightMap(const std::string &name); - std::string getLightMap(); - - virtual kraken_stream_level getStreamLevel(const KRViewport &viewport); - private: - void preStream(const KRViewport &viewport); - - std::vector m_models; - unordered_map > m_bones; // Outer std::map connects model to set of bones - KRTexture *m_pLightMap; - std::string m_lightMap; - std::string m_model_name; - - - float m_min_lod_coverage; - void loadModel(); - - bool m_receivesShadow; - bool m_faces_camera; - - - Matrix4 m_boundsCachedMat; - AABB m_boundsCached; - - - Vector3 m_rim_color; - float m_rim_power; + void preStream(const KRViewport& viewport); + + std::vector m_models; + unordered_map > m_bones; // Outer std::map connects model to set of bones + KRTexture* m_pLightMap; + std::string m_lightMap; + std::string m_model_name; + + + float m_min_lod_coverage; + void loadModel(); + + bool m_receivesShadow; + bool m_faces_camera; + + + Matrix4 m_boundsCachedMat; + AABB m_boundsCached; + + + Vector3 m_rim_color; + float m_rim_power; }; diff --git a/kraken/KRNode.cpp b/kraken/KRNode.cpp index 6a7ebf8..68b492f 100755 --- a/kraken/KRNode.cpp +++ b/kraken/KRNode.cpp @@ -63,939 +63,964 @@ void KRNode::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->scale_pivot = Vector3::Zero(); } -KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getContext()) +KRNode::KRNode(KRScene& scene, std::string name) : KRContextObject(scene.getContext()) { - m_name = name; - m_localScale = Vector3::One(); - m_localRotation = Vector3::Zero(); - m_localTranslation = Vector3::Zero(); - m_initialLocalTranslation = m_localTranslation; - m_initialLocalScale = m_localScale; - m_initialLocalRotation = m_localRotation; - - - - m_rotationOffset = Vector3::Zero(); - m_scalingOffset = Vector3::Zero(); - m_rotationPivot = Vector3::Zero(); - m_scalingPivot = Vector3::Zero(); - m_preRotation = Vector3::Zero(); - m_postRotation = Vector3::Zero(); - - m_initialRotationOffset = Vector3::Zero(); - m_initialScalingOffset = Vector3::Zero(); - m_initialRotationPivot = Vector3::Zero(); - m_initialScalingPivot = Vector3::Zero(); - m_initialPreRotation = Vector3::Zero(); - m_initialPostRotation = Vector3::Zero(); - - m_parentNode = NULL; - m_pScene = &scene; - m_modelMatrixValid = false; - m_inverseModelMatrixValid = false; - m_bindPoseMatrixValid = false; - m_activePoseMatrixValid = false; - m_inverseBindPoseMatrixValid = false; - m_modelMatrix = Matrix4(); - m_bindPoseMatrix = Matrix4(); - m_activePoseMatrix = Matrix4(); - m_lod_visible = LOD_VISIBILITY_HIDDEN; - m_scale_compensation = false; - m_boundsValid = false; - - m_lastRenderFrame = -1000; - for(int i=0; i < KRENGINE_NODE_ATTRIBUTE_COUNT; i++) { - m_animation_mask[i] = false; - } + m_name = name; + m_localScale = Vector3::One(); + m_localRotation = Vector3::Zero(); + m_localTranslation = Vector3::Zero(); + m_initialLocalTranslation = m_localTranslation; + m_initialLocalScale = m_localScale; + m_initialLocalRotation = m_localRotation; + + + + m_rotationOffset = Vector3::Zero(); + m_scalingOffset = Vector3::Zero(); + m_rotationPivot = Vector3::Zero(); + m_scalingPivot = Vector3::Zero(); + m_preRotation = Vector3::Zero(); + m_postRotation = Vector3::Zero(); + + m_initialRotationOffset = Vector3::Zero(); + m_initialScalingOffset = Vector3::Zero(); + m_initialRotationPivot = Vector3::Zero(); + m_initialScalingPivot = Vector3::Zero(); + m_initialPreRotation = Vector3::Zero(); + m_initialPostRotation = Vector3::Zero(); + + m_parentNode = NULL; + m_pScene = &scene; + m_modelMatrixValid = false; + m_inverseModelMatrixValid = false; + m_bindPoseMatrixValid = false; + m_activePoseMatrixValid = false; + m_inverseBindPoseMatrixValid = false; + m_modelMatrix = Matrix4(); + m_bindPoseMatrix = Matrix4(); + m_activePoseMatrix = Matrix4(); + m_lod_visible = LOD_VISIBILITY_HIDDEN; + m_scale_compensation = false; + m_boundsValid = false; + + m_lastRenderFrame = -1000; + for (int i = 0; i < KRENGINE_NODE_ATTRIBUTE_COUNT; i++) { + m_animation_mask[i] = false; + } } -KRNode::~KRNode() { - - - while(m_childNodes.size() > 0) { - delete *m_childNodes.begin(); - } - - for(std::set::iterator itr = m_behaviors.begin(); itr != m_behaviors.end(); itr++) { - delete *itr; - } - m_behaviors.clear(); +KRNode::~KRNode() +{ - if(m_parentNode) { - m_parentNode->childDeleted(this); - } - getScene().notify_sceneGraphDelete(this); - + while (m_childNodes.size() > 0) { + delete* m_childNodes.begin(); + } + + for (std::set::iterator itr = m_behaviors.begin(); itr != m_behaviors.end(); itr++) { + delete* itr; + } + m_behaviors.clear(); + + if (m_parentNode) { + m_parentNode->childDeleted(this); + } + + getScene().notify_sceneGraphDelete(this); + } void KRNode::setScaleCompensation(bool scale_compensation) { - if(m_scale_compensation != scale_compensation) { - m_scale_compensation = scale_compensation; - invalidateModelMatrix(); - invalidateBindPoseMatrix(); - } + if (m_scale_compensation != scale_compensation) { + m_scale_compensation = scale_compensation; + invalidateModelMatrix(); + invalidateBindPoseMatrix(); + } } bool KRNode::getScaleCompensation() { - return m_scale_compensation; + return m_scale_compensation; } -void KRNode::childDeleted(KRNode *child_node) +void KRNode::childDeleted(KRNode* child_node) { - m_childNodes.erase(child_node); - invalidateBounds(); - getScene().notify_sceneGraphModify(this); + m_childNodes.erase(child_node); + invalidateBounds(); + getScene().notify_sceneGraphModify(this); } -void KRNode::addChild(KRNode *child) { - assert(child->m_parentNode == NULL); - child->m_parentNode = this; - m_childNodes.insert(child); - child->setLODVisibility(m_lod_visible); // Child node inherits LOD visibility status from parent -} - -tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) { - tinyxml2::XMLDocument *doc = parent->GetDocument(); - tinyxml2::XMLElement *e = doc->NewElement(getElementName().c_str()); - tinyxml2::XMLNode *n = parent->InsertEndChild(e); - e->SetAttribute("name", m_name.c_str()); - kraken::setXMLAttribute("translate", e, m_localTranslation, Vector3::Zero()); - kraken::setXMLAttribute("scale", e, m_localScale, Vector3::One()); - kraken::setXMLAttribute("rotate", e, (m_localRotation * (180.0f / (float)M_PI)), Vector3::Zero()); - kraken::setXMLAttribute("rotate_offset", e, m_rotationOffset, Vector3::Zero()); - kraken::setXMLAttribute("scale_offset", e, m_scalingOffset, Vector3::Zero()); - kraken::setXMLAttribute("rotate_pivot", e, m_rotationPivot, Vector3::Zero()); - kraken::setXMLAttribute("scale_pivot", e, m_scalingPivot, Vector3::Zero()); - kraken::setXMLAttribute("pre_rotate", e, (m_preRotation * (180.0f / (float)M_PI)), Vector3::Zero()); - kraken::setXMLAttribute("post_rotate", e, (m_postRotation * (180.0f / (float)M_PI)), Vector3::Zero()); - - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - KRNode *child = (*itr); - child->saveXML(n); - } - return e; -} - -void KRNode::loadXML(tinyxml2::XMLElement *e) { - m_name = e->Attribute("name"); - m_localTranslation = kraken::getXMLAttribute("translate", e, Vector3::Zero()); - m_localScale = kraken::getXMLAttribute("scale", e, Vector3::One()); - m_localRotation = kraken::getXMLAttribute("rotate", e, Vector3::Zero()); - m_localRotation *= (float)M_PI / 180.0f; // Convert degrees to radians - m_preRotation = kraken::getXMLAttribute("pre_rotate", e, Vector3::Zero()); - m_preRotation *= (float)M_PI / 180.0f; // Convert degrees to radians - m_postRotation = kraken::getXMLAttribute("post_rotate", e, Vector3::Zero()); - m_postRotation *= (float)M_PI / 180.0f; // Convert degrees to radians - - m_rotationOffset = kraken::getXMLAttribute("rotate_offset", e, Vector3::Zero()); - m_scalingOffset = kraken::getXMLAttribute("scale_offset", e, Vector3::Zero()); - m_rotationPivot = kraken::getXMLAttribute("rotate_pivot", e, Vector3::Zero()); - m_scalingPivot = kraken::getXMLAttribute("scale_pivot", e, Vector3::Zero()); - - m_initialLocalTranslation = m_localTranslation; - m_initialLocalScale = m_localScale; - m_initialLocalRotation = m_localRotation; - - m_initialRotationOffset = m_rotationOffset; - m_initialScalingOffset = m_scalingOffset; - m_initialRotationPivot = m_rotationPivot; - m_initialScalingPivot = m_scalingPivot; - m_initialPreRotation = m_preRotation; - m_initialPostRotation = m_postRotation; - - m_bindPoseMatrixValid = false; - m_activePoseMatrixValid = false; - m_inverseBindPoseMatrixValid = false; - m_modelMatrixValid = false; - m_inverseModelMatrixValid = false; - - for(tinyxml2::XMLElement *child_element=e->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { - const char *szElementName = child_element->Name(); - if(strcmp(szElementName, "behavior") == 0) { - KRBehavior *behavior = KRBehavior::LoadXML(this, child_element); - if(behavior) { - addBehavior(behavior); - behavior->init(); - } - } else { - KRNode *child_node = KRNode::LoadXML(getScene(), child_element); - - if(child_node) { - addChild(child_node); - } - } - } -} - -void KRNode::setLocalTranslation(const Vector3 &v, bool set_original) { - m_localTranslation = v; - if(set_original) { - m_initialLocalTranslation = v; - invalidateBindPoseMatrix(); - } - invalidateModelMatrix(); -} - -void KRNode::setWorldTranslation(const Vector3 &v) +void KRNode::addChild(KRNode* child) { - if(m_parentNode) { - setLocalTranslation(Matrix4::Dot(m_parentNode->getInverseModelMatrix(), v)); + assert(child->m_parentNode == NULL); + child->m_parentNode = this; + m_childNodes.insert(child); + child->setLODVisibility(m_lod_visible); // Child node inherits LOD visibility status from parent +} + +tinyxml2::XMLElement* KRNode::saveXML(tinyxml2::XMLNode* parent) +{ + tinyxml2::XMLDocument* doc = parent->GetDocument(); + tinyxml2::XMLElement* e = doc->NewElement(getElementName().c_str()); + tinyxml2::XMLNode* n = parent->InsertEndChild(e); + e->SetAttribute("name", m_name.c_str()); + kraken::setXMLAttribute("translate", e, m_localTranslation, Vector3::Zero()); + kraken::setXMLAttribute("scale", e, m_localScale, Vector3::One()); + kraken::setXMLAttribute("rotate", e, (m_localRotation * (180.0f / (float)M_PI)), Vector3::Zero()); + kraken::setXMLAttribute("rotate_offset", e, m_rotationOffset, Vector3::Zero()); + kraken::setXMLAttribute("scale_offset", e, m_scalingOffset, Vector3::Zero()); + kraken::setXMLAttribute("rotate_pivot", e, m_rotationPivot, Vector3::Zero()); + kraken::setXMLAttribute("scale_pivot", e, m_scalingPivot, Vector3::Zero()); + kraken::setXMLAttribute("pre_rotate", e, (m_preRotation * (180.0f / (float)M_PI)), Vector3::Zero()); + kraken::setXMLAttribute("post_rotate", e, (m_postRotation * (180.0f / (float)M_PI)), Vector3::Zero()); + + for (std::set::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRNode* child = (*itr); + child->saveXML(n); + } + return e; +} + +void KRNode::loadXML(tinyxml2::XMLElement* e) +{ + m_name = e->Attribute("name"); + m_localTranslation = kraken::getXMLAttribute("translate", e, Vector3::Zero()); + m_localScale = kraken::getXMLAttribute("scale", e, Vector3::One()); + m_localRotation = kraken::getXMLAttribute("rotate", e, Vector3::Zero()); + m_localRotation *= (float)M_PI / 180.0f; // Convert degrees to radians + m_preRotation = kraken::getXMLAttribute("pre_rotate", e, Vector3::Zero()); + m_preRotation *= (float)M_PI / 180.0f; // Convert degrees to radians + m_postRotation = kraken::getXMLAttribute("post_rotate", e, Vector3::Zero()); + m_postRotation *= (float)M_PI / 180.0f; // Convert degrees to radians + + m_rotationOffset = kraken::getXMLAttribute("rotate_offset", e, Vector3::Zero()); + m_scalingOffset = kraken::getXMLAttribute("scale_offset", e, Vector3::Zero()); + m_rotationPivot = kraken::getXMLAttribute("rotate_pivot", e, Vector3::Zero()); + m_scalingPivot = kraken::getXMLAttribute("scale_pivot", e, Vector3::Zero()); + + m_initialLocalTranslation = m_localTranslation; + m_initialLocalScale = m_localScale; + m_initialLocalRotation = m_localRotation; + + m_initialRotationOffset = m_rotationOffset; + m_initialScalingOffset = m_scalingOffset; + m_initialRotationPivot = m_rotationPivot; + m_initialScalingPivot = m_scalingPivot; + m_initialPreRotation = m_preRotation; + m_initialPostRotation = m_postRotation; + + m_bindPoseMatrixValid = false; + m_activePoseMatrixValid = false; + m_inverseBindPoseMatrixValid = false; + m_modelMatrixValid = false; + m_inverseModelMatrixValid = false; + + for (tinyxml2::XMLElement* child_element = e->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { + const char* szElementName = child_element->Name(); + if (strcmp(szElementName, "behavior") == 0) { + KRBehavior* behavior = KRBehavior::LoadXML(this, child_element); + if (behavior) { + addBehavior(behavior); + behavior->init(); + } } else { - setLocalTranslation(v); + KRNode* child_node = KRNode::LoadXML(getScene(), child_element); + + if (child_node) { + addChild(child_node); + } } + } +} + +void KRNode::setLocalTranslation(const Vector3& v, bool set_original) +{ + m_localTranslation = v; + if (set_original) { + m_initialLocalTranslation = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} + +void KRNode::setWorldTranslation(const Vector3& v) +{ + if (m_parentNode) { + setLocalTranslation(Matrix4::Dot(m_parentNode->getInverseModelMatrix(), v)); + } else { + setLocalTranslation(v); + } } -void KRNode::setWorldRotation(const Vector3 &v) +void KRNode::setWorldRotation(const Vector3& v) { - if(m_parentNode) { - setLocalRotation((Quaternion::Create(v) * -m_parentNode->getWorldRotation()).eulerXYZ()); - setPreRotation(Vector3::Zero()); - setPostRotation(Vector3::Zero()); - } else { - setLocalRotation(v); - setPreRotation(Vector3::Zero()); - setPostRotation(Vector3::Zero()); + if (m_parentNode) { + setLocalRotation((Quaternion::Create(v) * -m_parentNode->getWorldRotation()).eulerXYZ()); + setPreRotation(Vector3::Zero()); + setPostRotation(Vector3::Zero()); + } else { + setLocalRotation(v); + setPreRotation(Vector3::Zero()); + setPostRotation(Vector3::Zero()); + } +} + + +void KRNode::setWorldScale(const Vector3& v) +{ + if (m_parentNode) { + setLocalScale(Matrix4::DotNoTranslate(m_parentNode->getInverseModelMatrix(), v)); + } else { + setLocalScale(v); + } +} + +void KRNode::setLocalScale(const Vector3& v, bool set_original) +{ + m_localScale = v; + if (set_original) { + m_initialLocalScale = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} + +void KRNode::setLocalRotation(const Vector3& v, bool set_original) +{ + m_localRotation = v; + if (set_original) { + m_initialLocalRotation = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} + + +void KRNode::setRotationOffset(const Vector3& v, bool set_original) +{ + m_rotationOffset = v; + if (set_original) { + m_initialRotationOffset = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} + +void KRNode::setScalingOffset(const Vector3& v, bool set_original) +{ + m_scalingOffset = v; + if (set_original) { + m_initialScalingOffset = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} + +void KRNode::setRotationPivot(const Vector3& v, bool set_original) +{ + m_rotationPivot = v; + if (set_original) { + m_initialRotationPivot = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} +void KRNode::setScalingPivot(const Vector3& v, bool set_original) +{ + m_scalingPivot = v; + if (set_original) { + m_initialScalingPivot = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} +void KRNode::setPreRotation(const Vector3& v, bool set_original) +{ + m_preRotation = v; + if (set_original) { + m_initialPreRotation = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} +void KRNode::setPostRotation(const Vector3& v, bool set_original) +{ + m_postRotation = v; + if (set_original) { + m_initialPostRotation = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} + +const Vector3& KRNode::getRotationOffset() +{ + return m_rotationOffset; +} +const Vector3& KRNode::getScalingOffset() +{ + return m_scalingOffset; +} +const Vector3& KRNode::getRotationPivot() +{ + return m_rotationPivot; +} +const Vector3& KRNode::getScalingPivot() +{ + return m_scalingPivot; +} +const Vector3& KRNode::getPreRotation() +{ + return m_preRotation; +} +const Vector3& KRNode::getPostRotation() +{ + return m_postRotation; +} +const Vector3& KRNode::getInitialRotationOffset() +{ + return m_initialRotationOffset; +} +const Vector3& KRNode::getInitialScalingOffset() +{ + return m_initialScalingOffset; +} +const Vector3& KRNode::getInitialRotationPivot() +{ + return m_initialRotationPivot; +} +const Vector3& KRNode::getInitialScalingPivot() +{ + return m_initialScalingPivot; +} +const Vector3& KRNode::getInitialPreRotation() +{ + return m_initialPreRotation; +} +const Vector3& KRNode::getInitialPostRotation() +{ + return m_initialPostRotation; +} + +const Vector3& KRNode::getLocalTranslation() +{ + return m_localTranslation; +} +const Vector3& KRNode::getLocalScale() +{ + return m_localScale; +} +const Vector3& KRNode::getLocalRotation() +{ + return m_localRotation; +} + +const Vector3& KRNode::getInitialLocalTranslation() +{ + return m_initialLocalTranslation; +} +const Vector3& KRNode::getInitialLocalScale() +{ + return m_initialLocalScale; +} +const Vector3& KRNode::getInitialLocalRotation() +{ + return m_initialLocalRotation; +} + +const Vector3 KRNode::getWorldTranslation() +{ + return localToWorld(Vector3::Zero()); +} + +const Vector3 KRNode::getWorldScale() +{ + return Matrix4::DotNoTranslate(getModelMatrix(), m_localScale); +} + +std::string KRNode::getElementName() +{ + return "node"; +} + +KRNode* KRNode::LoadXML(KRScene& scene, tinyxml2::XMLElement* e) +{ + KRNode* new_node = NULL; + const char* szElementName = e->Name(); + const char* szName = e->Attribute("name"); + if (strcmp(szElementName, "node") == 0) { + new_node = new KRNode(scene, szName); + } else if (strcmp(szElementName, "lod_set") == 0) { + new_node = new KRLODSet(scene, szName); + } else if (strcmp(szElementName, "lod_group") == 0) { + new_node = new KRLODGroup(scene, szName); + } else if (strcmp(szElementName, "point_light") == 0) { + new_node = new KRPointLight(scene, szName); + } else if (strcmp(szElementName, "directional_light") == 0) { + new_node = new KRDirectionalLight(scene, szName); + } else if (strcmp(szElementName, "spot_light") == 0) { + new_node = new KRSpotLight(scene, szName); + } else if (strcmp(szElementName, "particles_newtonian") == 0) { + new_node = new KRParticleSystemNewtonian(scene, szName); + } else if (strcmp(szElementName, "sprite") == 0) { + new_node = new KRSprite(scene, szName); + } else if (strcmp(szElementName, "model") == 0) { + float lod_min_coverage = 0.0f; + if (e->QueryFloatAttribute("lod_min_coverage", &lod_min_coverage) != tinyxml2::XML_SUCCESS) { + lod_min_coverage = 0.0f; } -} - - -void KRNode::setWorldScale(const Vector3 &v) -{ - if(m_parentNode) { - setLocalScale(Matrix4::DotNoTranslate(m_parentNode->getInverseModelMatrix(), v)); - } else { - setLocalScale(v); + bool receives_shadow = true; + if (e->QueryBoolAttribute("receives_shadow", &receives_shadow) != tinyxml2::XML_SUCCESS) { + receives_shadow = true; } -} - -void KRNode::setLocalScale(const Vector3 &v, bool set_original) { - m_localScale = v; - if(set_original) { - m_initialLocalScale = v; - invalidateBindPoseMatrix(); + bool faces_camera = false; + if (e->QueryBoolAttribute("faces_camera", &faces_camera) != tinyxml2::XML_SUCCESS) { + faces_camera = false; } - invalidateModelMatrix(); -} - -void KRNode::setLocalRotation(const Vector3 &v, bool set_original) { - m_localRotation = v; - if(set_original) { - m_initialLocalRotation = v; - invalidateBindPoseMatrix(); + float rim_power = 0.0f; + if (e->QueryFloatAttribute("rim_power", &rim_power) != tinyxml2::XML_SUCCESS) { + rim_power = 0.0f; } - invalidateModelMatrix(); -} + Vector3 rim_color = Vector3::Zero(); + rim_color = kraken::getXMLAttribute("rim_color", e, Vector3::Zero()); + new_node = new KRModel(scene, szName, e->Attribute("mesh"), e->Attribute("light_map"), lod_min_coverage, receives_shadow, faces_camera, rim_color, rim_power); + } else if (strcmp(szElementName, "collider") == 0) { + new_node = new KRCollider(scene, szName, e->Attribute("mesh"), 65535, 1.0f); + } else if (strcmp(szElementName, "bone") == 0) { + new_node = new KRBone(scene, szName); + } else if (strcmp(szElementName, "locator") == 0) { + new_node = new KRLocator(scene, szName); + } else if (strcmp(szElementName, "audio_source") == 0) { + new_node = new KRAudioSource(scene, szName); + } else if (strcmp(szElementName, "ambient_zone") == 0) { + new_node = new KRAmbientZone(scene, szName); + } else if (strcmp(szElementName, "reverb_zone") == 0) { + new_node = new KRReverbZone(scene, szName); + } else if (strcmp(szElementName, "camera") == 0) { + new_node = new KRCamera(scene, szName); + } + if (new_node) { + new_node->loadXML(e); + } -void KRNode::setRotationOffset(const Vector3 &v, bool set_original) -{ - m_rotationOffset = v; - if(set_original) { - m_initialRotationOffset = v; - invalidateBindPoseMatrix(); - } - invalidateModelMatrix(); -} - -void KRNode::setScalingOffset(const Vector3 &v, bool set_original) -{ - m_scalingOffset = v; - if(set_original) { - m_initialScalingOffset = v; - invalidateBindPoseMatrix(); - } - invalidateModelMatrix(); -} - -void KRNode::setRotationPivot(const Vector3 &v, bool set_original) -{ - m_rotationPivot = v; - if(set_original) { - m_initialRotationPivot = v; - invalidateBindPoseMatrix(); - } - invalidateModelMatrix(); -} -void KRNode::setScalingPivot(const Vector3 &v, bool set_original) -{ - m_scalingPivot = v; - if(set_original) { - m_initialScalingPivot = v; - invalidateBindPoseMatrix(); - } - invalidateModelMatrix(); -} -void KRNode::setPreRotation(const Vector3 &v, bool set_original) -{ - m_preRotation = v; - if(set_original) { - m_initialPreRotation = v; - invalidateBindPoseMatrix(); - } - invalidateModelMatrix(); -} -void KRNode::setPostRotation(const Vector3 &v, bool set_original) -{ - m_postRotation = v; - if(set_original) { - m_initialPostRotation = v; - invalidateBindPoseMatrix(); - } - invalidateModelMatrix(); -} - -const Vector3 &KRNode::getRotationOffset() -{ - return m_rotationOffset; -} -const Vector3 &KRNode::getScalingOffset() -{ - return m_scalingOffset; -} -const Vector3 &KRNode::getRotationPivot() -{ - return m_rotationPivot; -} -const Vector3 &KRNode::getScalingPivot() -{ - return m_scalingPivot; -} -const Vector3 &KRNode::getPreRotation() -{ - return m_preRotation; -} -const Vector3 &KRNode::getPostRotation() -{ - return m_postRotation; -} -const Vector3 &KRNode::getInitialRotationOffset() -{ - return m_initialRotationOffset; -} -const Vector3 &KRNode::getInitialScalingOffset() -{ - return m_initialScalingOffset; -} -const Vector3 &KRNode::getInitialRotationPivot() -{ - return m_initialRotationPivot; -} -const Vector3 &KRNode::getInitialScalingPivot() -{ - return m_initialScalingPivot; -} -const Vector3 &KRNode::getInitialPreRotation() -{ - return m_initialPreRotation; -} -const Vector3 &KRNode::getInitialPostRotation() -{ - return m_initialPostRotation; -} - -const Vector3 &KRNode::getLocalTranslation() { - return m_localTranslation; -} -const Vector3 &KRNode::getLocalScale() { - return m_localScale; -} -const Vector3 &KRNode::getLocalRotation() { - return m_localRotation; -} - -const Vector3 &KRNode::getInitialLocalTranslation() { - return m_initialLocalTranslation; -} -const Vector3 &KRNode::getInitialLocalScale() { - return m_initialLocalScale; -} -const Vector3 &KRNode::getInitialLocalRotation() { - return m_initialLocalRotation; -} - -const Vector3 KRNode::getWorldTranslation() { - return localToWorld(Vector3::Zero()); -} - -const Vector3 KRNode::getWorldScale() { - return Matrix4::DotNoTranslate(getModelMatrix(), m_localScale); -} - -std::string KRNode::getElementName() { - return "node"; -} - -KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) { - KRNode *new_node = NULL; - const char *szElementName = e->Name(); - const char *szName = e->Attribute("name"); - if(strcmp(szElementName, "node") == 0) { - new_node = new KRNode(scene, szName); - } else if(strcmp(szElementName, "lod_set") == 0) { - new_node = new KRLODSet(scene, szName); - } else if(strcmp(szElementName, "lod_group") == 0) { - new_node = new KRLODGroup(scene, szName); - } else if(strcmp(szElementName, "point_light") == 0) { - new_node = new KRPointLight(scene, szName); - } else if(strcmp(szElementName, "directional_light") == 0) { - new_node = new KRDirectionalLight(scene, szName); - } else if(strcmp(szElementName, "spot_light") == 0) { - new_node = new KRSpotLight(scene, szName); - } else if(strcmp(szElementName, "particles_newtonian") == 0) { - new_node = new KRParticleSystemNewtonian(scene, szName); - } else if(strcmp(szElementName, "sprite") == 0) { - new_node = new KRSprite(scene, szName); - } else if(strcmp(szElementName, "model") == 0) { - float lod_min_coverage = 0.0f; - if(e->QueryFloatAttribute("lod_min_coverage", &lod_min_coverage) != tinyxml2::XML_SUCCESS) { - lod_min_coverage = 0.0f; - } - bool receives_shadow = true; - if(e->QueryBoolAttribute("receives_shadow", &receives_shadow) != tinyxml2::XML_SUCCESS) { - receives_shadow = true; - } - bool faces_camera = false; - if(e->QueryBoolAttribute("faces_camera", &faces_camera) != tinyxml2::XML_SUCCESS) { - faces_camera = false; - } - float rim_power = 0.0f; - if(e->QueryFloatAttribute("rim_power", &rim_power) != tinyxml2::XML_SUCCESS) { - rim_power = 0.0f; - } - Vector3 rim_color = Vector3::Zero(); - rim_color = kraken::getXMLAttribute("rim_color", e, Vector3::Zero()); - new_node = new KRModel(scene, szName, e->Attribute("mesh"), e->Attribute("light_map"), lod_min_coverage, receives_shadow, faces_camera, rim_color, rim_power); - } else if(strcmp(szElementName, "collider") == 0) { - new_node = new KRCollider(scene, szName, e->Attribute("mesh"), 65535, 1.0f); - } else if(strcmp(szElementName, "bone") == 0) { - new_node = new KRBone(scene, szName); - } else if(strcmp(szElementName, "locator") == 0) { - new_node = new KRLocator(scene, szName); - } else if(strcmp(szElementName, "audio_source") == 0) { - new_node = new KRAudioSource(scene, szName); - } else if(strcmp(szElementName, "ambient_zone") == 0) { - new_node = new KRAmbientZone(scene, szName); - } else if(strcmp(szElementName, "reverb_zone") == 0) { - new_node = new KRReverbZone(scene, szName); - } else if(strcmp(szElementName, "camera") == 0) { - new_node = new KRCamera(scene, szName); - } - - if(new_node) { - new_node->loadXML(e); - } - - return new_node; + return new_node; } void KRNode::render(const RenderInfo& ri) { - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - m_lastRenderFrame = getContext().getCurrentFrame(); + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + + m_lastRenderFrame = getContext().getCurrentFrame(); } -const std::set &KRNode::getChildren() { - return m_childNodes; +const std::set& KRNode::getChildren() +{ + return m_childNodes; } -KRNode *KRNode::getParent() { - return m_parentNode; +KRNode* KRNode::getParent() +{ + return m_parentNode; } -const std::string &KRNode::getName() const { - return m_name; +const std::string& KRNode::getName() const +{ + return m_name; } -KRScene &KRNode::getScene() { - return *m_pScene; +KRScene& KRNode::getScene() +{ + return *m_pScene; } -AABB KRNode::getBounds() { - if(!m_boundsValid) { - AABB bounds = AABB::Zero(); +AABB KRNode::getBounds() +{ + if (!m_boundsValid) { + AABB bounds = AABB::Zero(); - bool first_child = true; - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - KRNode *child = (*itr); - if(child->getBounds() != AABB::Zero()) { - if(first_child) { - first_child = false; - bounds = child->getBounds(); - } else { - bounds.encapsulate(child->getBounds()); - } - } + bool first_child = true; + for (std::set::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRNode* child = (*itr); + if (child->getBounds() != AABB::Zero()) { + if (first_child) { + first_child = false; + bounds = child->getBounds(); + } else { + bounds.encapsulate(child->getBounds()); } - - m_bounds = bounds; - m_boundsValid = true; + } } - return m_bounds; + + m_bounds = bounds; + m_boundsValid = true; + } + return m_bounds; } void KRNode::invalidateModelMatrix() { - m_modelMatrixValid = false; - m_activePoseMatrixValid = false; - m_inverseModelMatrixValid = false; - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - KRNode *child = (*itr); - child->invalidateModelMatrix(); - } - - invalidateBounds(); - getScene().notify_sceneGraphModify(this); + m_modelMatrixValid = false; + m_activePoseMatrixValid = false; + m_inverseModelMatrixValid = false; + for (std::set::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRNode* child = (*itr); + child->invalidateModelMatrix(); + } + + invalidateBounds(); + getScene().notify_sceneGraphModify(this); } void KRNode::invalidateBindPoseMatrix() { - m_bindPoseMatrixValid = false; - m_inverseBindPoseMatrixValid = false; - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - KRNode *child = (*itr); - child->invalidateBindPoseMatrix(); - } + m_bindPoseMatrixValid = false; + m_inverseBindPoseMatrixValid = false; + for (std::set::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRNode* child = (*itr); + child->invalidateBindPoseMatrix(); + } } -const Matrix4 &KRNode::getModelMatrix() +const Matrix4& KRNode::getModelMatrix() { - - if(!m_modelMatrixValid) { - m_modelMatrix = Matrix4(); - - bool parent_is_bone = false; - if(dynamic_cast(m_parentNode)) { - parent_is_bone = true; - } - - if(getScaleCompensation() && parent_is_bone) { - - - // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 - m_modelMatrix = Matrix4::Translation(-m_scalingPivot) - * Matrix4::Scaling(m_localScale) - * Matrix4::Translation(m_scalingPivot) - * Matrix4::Translation(m_scalingOffset) - * Matrix4::Translation(-m_rotationPivot) - //* (Quaternion(m_postRotation) * Quaternion(m_localRotation) * Quaternion(m_preRotation)).rotationMatrix() - * Matrix4::Rotation(m_postRotation) - * Matrix4::Rotation(m_localRotation) - * Matrix4::Rotation(m_preRotation) - * Matrix4::Translation(m_rotationPivot) - * Matrix4::Translation(m_rotationOffset); - - if(m_parentNode) { - - m_modelMatrix.rotate(m_parentNode->getWorldRotation()); - m_modelMatrix.translate(Matrix4::Dot(m_parentNode->getModelMatrix(), m_localTranslation)); - } else { - m_modelMatrix.translate(m_localTranslation); - } - } else { - // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 - m_modelMatrix = Matrix4::Translation(-m_scalingPivot) - * Matrix4::Scaling(m_localScale) - * Matrix4::Translation(m_scalingPivot) - * Matrix4::Translation(m_scalingOffset) - * Matrix4::Translation(-m_rotationPivot) - //* (Quaternion(m_postRotation) * Quaternion(m_localRotation) * Quaternion(m_preRotation)).rotationMatrix() - * Matrix4::Rotation(m_postRotation) - * Matrix4::Rotation(m_localRotation) - * Matrix4::Rotation(m_preRotation) - * Matrix4::Translation(m_rotationPivot) - * Matrix4::Translation(m_rotationOffset) - * Matrix4::Translation(m_localTranslation); + if (!m_modelMatrixValid) { + m_modelMatrix = Matrix4(); - if(m_parentNode) { - m_modelMatrix *= m_parentNode->getModelMatrix(); - } - } - - m_modelMatrixValid = true; - + bool parent_is_bone = false; + if (dynamic_cast(m_parentNode)) { + parent_is_bone = true; } - return m_modelMatrix; + + if (getScaleCompensation() && parent_is_bone) { + + + // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 + m_modelMatrix = Matrix4::Translation(-m_scalingPivot) + * Matrix4::Scaling(m_localScale) + * Matrix4::Translation(m_scalingPivot) + * Matrix4::Translation(m_scalingOffset) + * Matrix4::Translation(-m_rotationPivot) + //* (Quaternion(m_postRotation) * Quaternion(m_localRotation) * Quaternion(m_preRotation)).rotationMatrix() + * Matrix4::Rotation(m_postRotation) + * Matrix4::Rotation(m_localRotation) + * Matrix4::Rotation(m_preRotation) + * Matrix4::Translation(m_rotationPivot) + * Matrix4::Translation(m_rotationOffset); + + if (m_parentNode) { + + m_modelMatrix.rotate(m_parentNode->getWorldRotation()); + m_modelMatrix.translate(Matrix4::Dot(m_parentNode->getModelMatrix(), m_localTranslation)); + } else { + m_modelMatrix.translate(m_localTranslation); + } + } else { + + // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 + m_modelMatrix = Matrix4::Translation(-m_scalingPivot) + * Matrix4::Scaling(m_localScale) + * Matrix4::Translation(m_scalingPivot) + * Matrix4::Translation(m_scalingOffset) + * Matrix4::Translation(-m_rotationPivot) + //* (Quaternion(m_postRotation) * Quaternion(m_localRotation) * Quaternion(m_preRotation)).rotationMatrix() + * Matrix4::Rotation(m_postRotation) + * Matrix4::Rotation(m_localRotation) + * Matrix4::Rotation(m_preRotation) + * Matrix4::Translation(m_rotationPivot) + * Matrix4::Translation(m_rotationOffset) + * Matrix4::Translation(m_localTranslation); + + if (m_parentNode) { + m_modelMatrix *= m_parentNode->getModelMatrix(); + } + } + + m_modelMatrixValid = true; + + } + return m_modelMatrix; } -const Matrix4 &KRNode::getBindPoseMatrix() +const Matrix4& KRNode::getBindPoseMatrix() { - if(!m_bindPoseMatrixValid) { - m_bindPoseMatrix = Matrix4(); - - bool parent_is_bone = false; - if(dynamic_cast(m_parentNode)) { - parent_is_bone = true; - } - - if(getScaleCompensation() && parent_is_bone) { - m_bindPoseMatrix = Matrix4::Translation(-m_initialScalingPivot) - * Matrix4::Scaling(m_initialLocalScale) - * Matrix4::Translation(m_initialScalingPivot) - * Matrix4::Translation(m_initialScalingOffset) - * Matrix4::Translation(-m_initialRotationPivot) - //* (Quaternion(m_initialPostRotation) * Quaternion(m_initialLocalRotation) * Quaternion(m_initialPreRotation)).rotationMatrix() - * Matrix4::Rotation(m_initialPostRotation) - * Matrix4::Rotation(m_initialLocalRotation) - * Matrix4::Rotation(m_initialPreRotation) - * Matrix4::Translation(m_initialRotationPivot) - * Matrix4::Translation(m_initialRotationOffset); - //m_bindPoseMatrix.translate(m_localTranslation); - if(m_parentNode) { - - m_bindPoseMatrix.rotate(m_parentNode->getBindPoseWorldRotation()); - m_bindPoseMatrix.translate(Matrix4::Dot(m_parentNode->getBindPoseMatrix(), m_localTranslation)); - } else { - m_bindPoseMatrix.translate(m_localTranslation); - } - } else { - - // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 - - m_bindPoseMatrix = Matrix4::Translation(-m_initialScalingPivot) - * Matrix4::Scaling(m_initialLocalScale) - * Matrix4::Translation(m_initialScalingPivot) - * Matrix4::Translation(m_initialScalingOffset) - * Matrix4::Translation(-m_initialRotationPivot) - // * (Quaternion(m_initialPostRotation) * Quaternion(m_initialLocalRotation) * Quaternion(m_initialPreRotation)).rotationMatrix() - * Matrix4::Rotation(m_initialPostRotation) - * Matrix4::Rotation(m_initialLocalRotation) - * Matrix4::Rotation(m_initialPreRotation) - * Matrix4::Translation(m_initialRotationPivot) - * Matrix4::Translation(m_initialRotationOffset) - * Matrix4::Translation(m_initialLocalTranslation); - - if(m_parentNode && parent_is_bone) { + if (!m_bindPoseMatrixValid) { + m_bindPoseMatrix = Matrix4(); - m_bindPoseMatrix *= m_parentNode->getBindPoseMatrix(); - } - } - - m_bindPoseMatrixValid = true; - + bool parent_is_bone = false; + if (dynamic_cast(m_parentNode)) { + parent_is_bone = true; } - return m_bindPoseMatrix; + + if (getScaleCompensation() && parent_is_bone) { + m_bindPoseMatrix = Matrix4::Translation(-m_initialScalingPivot) + * Matrix4::Scaling(m_initialLocalScale) + * Matrix4::Translation(m_initialScalingPivot) + * Matrix4::Translation(m_initialScalingOffset) + * Matrix4::Translation(-m_initialRotationPivot) + //* (Quaternion(m_initialPostRotation) * Quaternion(m_initialLocalRotation) * Quaternion(m_initialPreRotation)).rotationMatrix() + * Matrix4::Rotation(m_initialPostRotation) + * Matrix4::Rotation(m_initialLocalRotation) + * Matrix4::Rotation(m_initialPreRotation) + * Matrix4::Translation(m_initialRotationPivot) + * Matrix4::Translation(m_initialRotationOffset); + //m_bindPoseMatrix.translate(m_localTranslation); + if (m_parentNode) { + + m_bindPoseMatrix.rotate(m_parentNode->getBindPoseWorldRotation()); + m_bindPoseMatrix.translate(Matrix4::Dot(m_parentNode->getBindPoseMatrix(), m_localTranslation)); + } else { + m_bindPoseMatrix.translate(m_localTranslation); + } + } else { + + // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 + + m_bindPoseMatrix = Matrix4::Translation(-m_initialScalingPivot) + * Matrix4::Scaling(m_initialLocalScale) + * Matrix4::Translation(m_initialScalingPivot) + * Matrix4::Translation(m_initialScalingOffset) + * Matrix4::Translation(-m_initialRotationPivot) + // * (Quaternion(m_initialPostRotation) * Quaternion(m_initialLocalRotation) * Quaternion(m_initialPreRotation)).rotationMatrix() + * Matrix4::Rotation(m_initialPostRotation) + * Matrix4::Rotation(m_initialLocalRotation) + * Matrix4::Rotation(m_initialPreRotation) + * Matrix4::Translation(m_initialRotationPivot) + * Matrix4::Translation(m_initialRotationOffset) + * Matrix4::Translation(m_initialLocalTranslation); + + if (m_parentNode && parent_is_bone) { + + m_bindPoseMatrix *= m_parentNode->getBindPoseMatrix(); + } + } + + m_bindPoseMatrixValid = true; + + } + return m_bindPoseMatrix; } -const Matrix4 &KRNode::getActivePoseMatrix() +const Matrix4& KRNode::getActivePoseMatrix() { - - if(!m_activePoseMatrixValid) { - m_activePoseMatrix = Matrix4(); - - bool parent_is_bone = false; - if(dynamic_cast(m_parentNode)) { - parent_is_bone = true; - } - - if(getScaleCompensation() && parent_is_bone) { - m_activePoseMatrix= Matrix4::Translation(-m_scalingPivot) - * Matrix4::Scaling(m_localScale) - * Matrix4::Translation(m_scalingPivot) - * Matrix4::Translation(m_scalingOffset) - * Matrix4::Translation(-m_rotationPivot) - * Matrix4::Rotation(m_postRotation) - * Matrix4::Rotation(m_localRotation) - * Matrix4::Rotation(m_preRotation) - * Matrix4::Translation(m_rotationPivot) - * Matrix4::Translation(m_rotationOffset); - - if(m_parentNode) { - - m_activePoseMatrix.rotate(m_parentNode->getActivePoseWorldRotation()); - m_activePoseMatrix.translate(Matrix4::Dot(m_parentNode->getActivePoseMatrix(), m_localTranslation)); - } else { - m_activePoseMatrix.translate(m_localTranslation); - } - } else { - - // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 - m_activePoseMatrix = Matrix4::Translation(-m_scalingPivot) - * Matrix4::Scaling(m_localScale) - * Matrix4::Translation(m_scalingPivot) - * Matrix4::Translation(m_scalingOffset) - * Matrix4::Translation(-m_rotationPivot) - * Matrix4::Rotation(m_postRotation) - * Matrix4::Rotation(m_localRotation) - * Matrix4::Rotation(m_preRotation) - * Matrix4::Translation(m_rotationPivot) - * Matrix4::Translation(m_rotationOffset) - * Matrix4::Translation(m_localTranslation); - - - if(m_parentNode && parent_is_bone) { - m_activePoseMatrix *= m_parentNode->getActivePoseMatrix(); - } - } - - m_activePoseMatrixValid = true; - + + if (!m_activePoseMatrixValid) { + m_activePoseMatrix = Matrix4(); + + bool parent_is_bone = false; + if (dynamic_cast(m_parentNode)) { + parent_is_bone = true; } - return m_activePoseMatrix; + + if (getScaleCompensation() && parent_is_bone) { + m_activePoseMatrix = Matrix4::Translation(-m_scalingPivot) + * Matrix4::Scaling(m_localScale) + * Matrix4::Translation(m_scalingPivot) + * Matrix4::Translation(m_scalingOffset) + * Matrix4::Translation(-m_rotationPivot) + * Matrix4::Rotation(m_postRotation) + * Matrix4::Rotation(m_localRotation) + * Matrix4::Rotation(m_preRotation) + * Matrix4::Translation(m_rotationPivot) + * Matrix4::Translation(m_rotationOffset); + + if (m_parentNode) { + + m_activePoseMatrix.rotate(m_parentNode->getActivePoseWorldRotation()); + m_activePoseMatrix.translate(Matrix4::Dot(m_parentNode->getActivePoseMatrix(), m_localTranslation)); + } else { + m_activePoseMatrix.translate(m_localTranslation); + } + } else { + + // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 + m_activePoseMatrix = Matrix4::Translation(-m_scalingPivot) + * Matrix4::Scaling(m_localScale) + * Matrix4::Translation(m_scalingPivot) + * Matrix4::Translation(m_scalingOffset) + * Matrix4::Translation(-m_rotationPivot) + * Matrix4::Rotation(m_postRotation) + * Matrix4::Rotation(m_localRotation) + * Matrix4::Rotation(m_preRotation) + * Matrix4::Translation(m_rotationPivot) + * Matrix4::Translation(m_rotationOffset) + * Matrix4::Translation(m_localTranslation); + + + if (m_parentNode && parent_is_bone) { + m_activePoseMatrix *= m_parentNode->getActivePoseMatrix(); + } + } + + m_activePoseMatrixValid = true; + + } + return m_activePoseMatrix; } -const Quaternion KRNode::getWorldRotation() { - Quaternion world_rotation = Quaternion::Create(m_postRotation) * Quaternion::Create(m_localRotation) * Quaternion::Create(m_preRotation); - if(m_parentNode) { - world_rotation = world_rotation * m_parentNode->getWorldRotation(); - } - return world_rotation; -} - -const Quaternion KRNode::getBindPoseWorldRotation() { - Quaternion world_rotation = Quaternion::Create(m_initialPostRotation) * Quaternion::Create(m_initialLocalRotation) * Quaternion::Create(m_initialPreRotation); - if(dynamic_cast(m_parentNode)) { - world_rotation = world_rotation * m_parentNode->getBindPoseWorldRotation(); - } - return world_rotation; -} - -const Quaternion KRNode::getActivePoseWorldRotation() { - Quaternion world_rotation = Quaternion::Create(m_postRotation) * Quaternion::Create(m_localRotation) * Quaternion::Create(m_preRotation); - if(dynamic_cast(m_parentNode)) { - world_rotation = world_rotation * m_parentNode->getActivePoseWorldRotation(); - } - return world_rotation; -} - -const Matrix4 &KRNode::getInverseModelMatrix() +const Quaternion KRNode::getWorldRotation() { - if(!m_inverseModelMatrixValid) { - m_inverseModelMatrix = Matrix4::Invert(getModelMatrix()); - } - return m_inverseModelMatrix; + Quaternion world_rotation = Quaternion::Create(m_postRotation) * Quaternion::Create(m_localRotation) * Quaternion::Create(m_preRotation); + if (m_parentNode) { + world_rotation = world_rotation * m_parentNode->getWorldRotation(); + } + return world_rotation; } -const Matrix4 &KRNode::getInverseBindPoseMatrix() +const Quaternion KRNode::getBindPoseWorldRotation() { - if(!m_inverseBindPoseMatrixValid ) { - m_inverseBindPoseMatrix = Matrix4::Invert(getBindPoseMatrix()); - m_inverseBindPoseMatrixValid = true; - } - return m_inverseBindPoseMatrix; + Quaternion world_rotation = Quaternion::Create(m_initialPostRotation) * Quaternion::Create(m_initialLocalRotation) * Quaternion::Create(m_initialPreRotation); + if (dynamic_cast(m_parentNode)) { + world_rotation = world_rotation * m_parentNode->getBindPoseWorldRotation(); + } + return world_rotation; +} + +const Quaternion KRNode::getActivePoseWorldRotation() +{ + Quaternion world_rotation = Quaternion::Create(m_postRotation) * Quaternion::Create(m_localRotation) * Quaternion::Create(m_preRotation); + if (dynamic_cast(m_parentNode)) { + world_rotation = world_rotation * m_parentNode->getActivePoseWorldRotation(); + } + return world_rotation; +} + +const Matrix4& KRNode::getInverseModelMatrix() +{ + if (!m_inverseModelMatrixValid) { + m_inverseModelMatrix = Matrix4::Invert(getModelMatrix()); + } + return m_inverseModelMatrix; +} + +const Matrix4& KRNode::getInverseBindPoseMatrix() +{ + if (!m_inverseBindPoseMatrixValid) { + m_inverseBindPoseMatrix = Matrix4::Invert(getBindPoseMatrix()); + m_inverseBindPoseMatrixValid = true; + } + return m_inverseBindPoseMatrix; } void KRNode::physicsUpdate(float deltaTime) { - const long MIN_DISPLAY_FRAMES = 10; - bool visible = m_lastRenderFrame + MIN_DISPLAY_FRAMES >= getContext().getCurrentFrame(); - for(std::set::iterator itr=m_behaviors.begin(); itr != m_behaviors.end(); itr++) { - (*itr)->update(deltaTime); - if(visible) { - (*itr)->visibleUpdate(deltaTime); - } + const long MIN_DISPLAY_FRAMES = 10; + bool visible = m_lastRenderFrame + MIN_DISPLAY_FRAMES >= getContext().getCurrentFrame(); + for (std::set::iterator itr = m_behaviors.begin(); itr != m_behaviors.end(); itr++) { + (*itr)->update(deltaTime); + if (visible) { + (*itr)->visibleUpdate(deltaTime); } + } } bool KRNode::hasPhysics() { - return m_behaviors.size() > 0; + 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 = (float)M_PI / 180.0f; - - //printf("%s - ", m_name.c_str()); - switch(attrib) { - case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X: - setLocalTranslation(Vector3::Create(v, m_localTranslation.y, m_localTranslation.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y: - setLocalTranslation(Vector3::Create(m_localTranslation.x, v, m_localTranslation.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z: - setLocalTranslation(Vector3::Create(m_localTranslation.x, m_localTranslation.y, v)); - break; - case KRENGINE_NODE_ATTRIBUTE_SCALE_X: - setLocalScale(Vector3::Create(v, m_localScale.y, m_localScale.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_SCALE_Y: - setLocalScale(Vector3::Create(m_localScale.x, v, m_localScale.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_SCALE_Z: - setLocalScale(Vector3::Create(m_localScale.x, m_localScale.y, v)); - break; - case KRENGINE_NODE_ATTRIBUTE_ROTATE_X: - setLocalRotation(Vector3::Create(v * DEGREES_TO_RAD, m_localRotation.y, m_localRotation.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_ROTATE_Y: - setLocalRotation(Vector3::Create(m_localRotation.x, v * DEGREES_TO_RAD, m_localRotation.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_ROTATE_Z: - setLocalRotation(Vector3::Create(m_localRotation.x, m_localRotation.y, v * DEGREES_TO_RAD)); - break; - + if (m_animation_mask[attrib]) return; - case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X: - setPreRotation(Vector3::Create(v * DEGREES_TO_RAD, m_preRotation.y, m_preRotation.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y: - setPreRotation(Vector3::Create(m_preRotation.x, v * DEGREES_TO_RAD, m_preRotation.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z: - setPreRotation(Vector3::Create(m_preRotation.x, m_preRotation.y, v * DEGREES_TO_RAD)); - break; - case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X: - setPostRotation(Vector3::Create(v * DEGREES_TO_RAD, m_postRotation.y, m_postRotation.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y: - setPostRotation(Vector3::Create(m_postRotation.x, v * DEGREES_TO_RAD, m_postRotation.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z: - setPostRotation(Vector3::Create(m_postRotation.x, m_postRotation.y, v * DEGREES_TO_RAD)); - break; - case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X: - setRotationPivot(Vector3::Create(v, m_rotationPivot.y, m_rotationPivot.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y: - setRotationPivot(Vector3::Create(m_rotationPivot.x, v, m_rotationPivot.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z: - setRotationPivot(Vector3::Create(m_rotationPivot.x, m_rotationPivot.y, v)); - break; - case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X: - setScalingPivot(Vector3::Create(v, m_scalingPivot.y, m_scalingPivot.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y: - setScalingPivot(Vector3::Create(m_scalingPivot.x, v, m_scalingPivot.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z: - setScalingPivot(Vector3::Create(m_scalingPivot.x, m_scalingPivot.y, v)); - break; - case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X: - setRotationOffset(Vector3::Create(v, m_rotationOffset.y, m_rotationOffset.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y: - setRotationOffset(Vector3::Create(m_rotationOffset.x, v, m_rotationOffset.z)); - break; - case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z: - setRotationOffset(Vector3::Create(m_rotationOffset.x, m_rotationOffset.y, v)); - break; - case KRENGINE_NODE_SCALE_OFFSET_X: - setScalingOffset(Vector3::Create(v, m_scalingOffset.y, m_scalingOffset.z)); - break; - case KRENGINE_NODE_SCALE_OFFSET_Y: - setScalingOffset(Vector3::Create(m_scalingOffset.x, v, m_scalingOffset.z)); - break; - case KRENGINE_NODE_SCALE_OFFSET_Z: - setScalingOffset(Vector3::Create(m_scalingOffset.x, m_scalingOffset.y, v)); - break; - case KRENGINE_NODE_ATTRIBUTE_NONE: - case KRENGINE_NODE_ATTRIBUTE_COUNT: - // Suppress warnings - break; - } + const float DEGREES_TO_RAD = (float)M_PI / 180.0f; + + //printf("%s - ", m_name.c_str()); + switch (attrib) { + case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X: + setLocalTranslation(Vector3::Create(v, m_localTranslation.y, m_localTranslation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y: + setLocalTranslation(Vector3::Create(m_localTranslation.x, v, m_localTranslation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z: + setLocalTranslation(Vector3::Create(m_localTranslation.x, m_localTranslation.y, v)); + break; + case KRENGINE_NODE_ATTRIBUTE_SCALE_X: + setLocalScale(Vector3::Create(v, m_localScale.y, m_localScale.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_SCALE_Y: + setLocalScale(Vector3::Create(m_localScale.x, v, m_localScale.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_SCALE_Z: + setLocalScale(Vector3::Create(m_localScale.x, m_localScale.y, v)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATE_X: + setLocalRotation(Vector3::Create(v * DEGREES_TO_RAD, m_localRotation.y, m_localRotation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATE_Y: + setLocalRotation(Vector3::Create(m_localRotation.x, v * DEGREES_TO_RAD, m_localRotation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATE_Z: + setLocalRotation(Vector3::Create(m_localRotation.x, m_localRotation.y, v * DEGREES_TO_RAD)); + break; + + + case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X: + setPreRotation(Vector3::Create(v * DEGREES_TO_RAD, m_preRotation.y, m_preRotation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y: + setPreRotation(Vector3::Create(m_preRotation.x, v * DEGREES_TO_RAD, m_preRotation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z: + setPreRotation(Vector3::Create(m_preRotation.x, m_preRotation.y, v * DEGREES_TO_RAD)); + break; + case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X: + setPostRotation(Vector3::Create(v * DEGREES_TO_RAD, m_postRotation.y, m_postRotation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y: + setPostRotation(Vector3::Create(m_postRotation.x, v * DEGREES_TO_RAD, m_postRotation.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z: + setPostRotation(Vector3::Create(m_postRotation.x, m_postRotation.y, v * DEGREES_TO_RAD)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X: + setRotationPivot(Vector3::Create(v, m_rotationPivot.y, m_rotationPivot.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y: + setRotationPivot(Vector3::Create(m_rotationPivot.x, v, m_rotationPivot.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z: + setRotationPivot(Vector3::Create(m_rotationPivot.x, m_rotationPivot.y, v)); + break; + case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X: + setScalingPivot(Vector3::Create(v, m_scalingPivot.y, m_scalingPivot.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y: + setScalingPivot(Vector3::Create(m_scalingPivot.x, v, m_scalingPivot.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z: + setScalingPivot(Vector3::Create(m_scalingPivot.x, m_scalingPivot.y, v)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X: + setRotationOffset(Vector3::Create(v, m_rotationOffset.y, m_rotationOffset.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y: + setRotationOffset(Vector3::Create(m_rotationOffset.x, v, m_rotationOffset.z)); + break; + case KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z: + setRotationOffset(Vector3::Create(m_rotationOffset.x, m_rotationOffset.y, v)); + break; + case KRENGINE_NODE_SCALE_OFFSET_X: + setScalingOffset(Vector3::Create(v, m_scalingOffset.y, m_scalingOffset.z)); + break; + case KRENGINE_NODE_SCALE_OFFSET_Y: + setScalingOffset(Vector3::Create(m_scalingOffset.x, v, m_scalingOffset.z)); + break; + case KRENGINE_NODE_SCALE_OFFSET_Z: + setScalingOffset(Vector3::Create(m_scalingOffset.x, m_scalingOffset.y, v)); + break; + case KRENGINE_NODE_ATTRIBUTE_NONE: + case KRENGINE_NODE_ATTRIBUTE_COUNT: + // Suppress warnings + break; + } } void KRNode::setAnimationEnabled(node_attribute_type attrib, bool enable) { - m_animation_mask[attrib] = !enable; + m_animation_mask[attrib] = !enable; } bool KRNode::getAnimationEnabled(node_attribute_type attrib) const { - return !m_animation_mask[attrib]; + return !m_animation_mask[attrib]; } void KRNode::removeFromOctreeNodes() { - for(std::set::iterator itr=m_octree_nodes.begin(); itr != m_octree_nodes.end(); itr++) { - KROctreeNode *octree_node = *itr; - octree_node->remove(this); - - // FINDME, TODO - This should be moved to the KROctree class - while(octree_node) { - octree_node->trim(); - if(octree_node->isEmpty()) { - octree_node = octree_node->getParent(); - } else { - octree_node = NULL; - } - } + for (std::set::iterator itr = m_octree_nodes.begin(); itr != m_octree_nodes.end(); itr++) { + KROctreeNode* octree_node = *itr; + octree_node->remove(this); + + // FINDME, TODO - This should be moved to the KROctree class + while (octree_node) { + octree_node->trim(); + if (octree_node->isEmpty()) { + octree_node = octree_node->getParent(); + } else { + octree_node = NULL; + } } - m_octree_nodes.clear(); + } + m_octree_nodes.clear(); } -void KRNode::addToOctreeNode(KROctreeNode *octree_node) +void KRNode::addToOctreeNode(KROctreeNode* octree_node) { - m_octree_nodes.insert(octree_node); + m_octree_nodes.insert(octree_node); } -void KRNode::updateLODVisibility(const KRViewport &viewport) +void KRNode::updateLODVisibility(const KRViewport& viewport) { - if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM) { - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - (*itr)->updateLODVisibility(viewport); - } + if (m_lod_visible >= LOD_VISIBILITY_PRESTREAM) { + for (std::set::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + (*itr)->updateLODVisibility(viewport); } + } } void KRNode::setLODVisibility(KRNode::LodVisibility lod_visibility) { - if(m_lod_visible != lod_visibility) { - if(m_lod_visible == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) { - getScene().notify_sceneGraphCreate(this); - } else if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM && lod_visibility == LOD_VISIBILITY_HIDDEN) { - getScene().notify_sceneGraphDelete(this); - } - - m_lod_visible = lod_visibility; - - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - (*itr)->setLODVisibility(lod_visibility); - } + if (m_lod_visible != lod_visibility) { + if (m_lod_visible == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) { + getScene().notify_sceneGraphCreate(this); + } else if (m_lod_visible >= LOD_VISIBILITY_PRESTREAM && lod_visibility == LOD_VISIBILITY_HIDDEN) { + getScene().notify_sceneGraphDelete(this); } + + m_lod_visible = lod_visibility; + + for (std::set::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + (*itr)->setLODVisibility(lod_visibility); + } + } } KRNode::LodVisibility KRNode::getLODVisibility() { - return m_lod_visible; + return m_lod_visible; } -const Vector3 KRNode::localToWorld(const Vector3 &local_point) +const Vector3 KRNode::localToWorld(const Vector3& local_point) { - return Matrix4::Dot(getModelMatrix(), local_point); + return Matrix4::Dot(getModelMatrix(), local_point); } -const Vector3 KRNode::worldToLocal(const Vector3 &world_point) +const Vector3 KRNode::worldToLocal(const Vector3& world_point) { - return Matrix4::Dot(getInverseModelMatrix(), world_point); + return Matrix4::Dot(getInverseModelMatrix(), world_point); } -void KRNode::addBehavior(KRBehavior *behavior) +void KRNode::addBehavior(KRBehavior* behavior) { - m_behaviors.insert(behavior); - behavior->__setNode(this); - getScene().notify_sceneGraphModify(this); + m_behaviors.insert(behavior); + behavior->__setNode(this); + getScene().notify_sceneGraphModify(this); } -std::set &KRNode::getBehaviors() +std::set& KRNode::getBehaviors() { - return m_behaviors; + return m_behaviors; } -kraken_stream_level KRNode::getStreamLevel(const KRViewport &viewport) +kraken_stream_level KRNode::getStreamLevel(const KRViewport& viewport) { - kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; - - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(viewport)); - } - - return stream_level; + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + + for (std::set::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(viewport)); + } + + return stream_level; } void KRNode::invalidateBounds() const { - m_boundsValid = false; - if(m_parentNode) { - m_parentNode->invalidateBounds(); - } + m_boundsValid = false; + if (m_parentNode) { + m_parentNode->invalidateBounds(); + } } diff --git a/kraken/KRNode.h b/kraken/KRNode.h index 403b246..14e017b 100755 --- a/kraken/KRNode.h +++ b/kraken/KRNode.h @@ -56,291 +56,295 @@ class KRPointLight; class KRSpotLight; class KRDirectionalLight; namespace tinyxml2 { - class XMLNode; - class XMLAttribute; +class XMLNode; +class XMLAttribute; } class KRNode : public KRContextObject { public: - enum RenderPass { - RENDER_PASS_FORWARD_OPAQUE, - RENDER_PASS_DEFERRED_GBUFFER, - RENDER_PASS_DEFERRED_LIGHTS, - RENDER_PASS_DEFERRED_OPAQUE, - RENDER_PASS_FORWARD_TRANSPARENT, - RENDER_PASS_PARTICLE_OCCLUSION, - RENDER_PASS_ADDITIVE_PARTICLES, - RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, - RENDER_PASS_GENERATE_SHADOWMAPS, - RENDER_PASS_SHADOWMAP, - RENDER_PASS_PRESTREAM - }; - - enum LodVisibility { - LOD_VISIBILITY_HIDDEN, - LOD_VISIBILITY_PRESTREAM, - LOD_VISIBILITY_VISIBLE - }; + enum RenderPass + { + RENDER_PASS_FORWARD_OPAQUE, + RENDER_PASS_DEFERRED_GBUFFER, + RENDER_PASS_DEFERRED_LIGHTS, + RENDER_PASS_DEFERRED_OPAQUE, + RENDER_PASS_FORWARD_TRANSPARENT, + RENDER_PASS_PARTICLE_OCCLUSION, + RENDER_PASS_ADDITIVE_PARTICLES, + RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, + RENDER_PASS_GENERATE_SHADOWMAPS, + RENDER_PASS_SHADOWMAP, + RENDER_PASS_PRESTREAM + }; - class RenderInfo { - public: - RenderInfo(VkCommandBuffer& cb) - : commandBuffer(cb) - { + enum LodVisibility + { + LOD_VISIBILITY_HIDDEN, + LOD_VISIBILITY_PRESTREAM, + LOD_VISIBILITY_VISIBLE + }; - } + class RenderInfo + { + public: + RenderInfo(VkCommandBuffer& cb) + : commandBuffer(cb) + { - RenderInfo(const RenderInfo&) = delete; - RenderInfo& operator=(const RenderInfo&) = delete; + } - VkCommandBuffer& commandBuffer; - KRCamera* camera; - KRSurface* surface; - std::vector point_lights; - std::vector directional_lights; - std::vector spot_lights; - KRViewport viewport; - RenderPass renderPass; - }; + RenderInfo(const RenderInfo&) = delete; + RenderInfo& operator=(const RenderInfo&) = delete; - static void InitNodeInfo(KrNodeInfo* nodeInfo); - - KRNode(KRScene &scene, std::string name); - virtual ~KRNode(); - - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); + VkCommandBuffer& commandBuffer; + KRCamera* camera; + KRSurface* surface; + std::vector point_lights; + std::vector directional_lights; + std::vector spot_lights; + KRViewport viewport; + RenderPass renderPass; + }; + + static void InitNodeInfo(KrNodeInfo* nodeInfo); + + KRNode(KRScene& scene, std::string name); + virtual ~KRNode(); + + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + + static KRNode* LoadXML(KRScene& scene, tinyxml2::XMLElement* e); + virtual void loadXML(tinyxml2::XMLElement* e); + + virtual std::string getElementName(); + const std::string& getName() const; + + void addChild(KRNode* child); + const std::set& getChildren(); + KRNode* getParent(); + + void setLocalTranslation(const Vector3& v, bool set_original = false); + void setLocalScale(const Vector3& v, bool set_original = false); + void setLocalRotation(const Vector3& v, bool set_original = false); + + + void setRotationOffset(const Vector3& v, bool set_original = false); + void setScalingOffset(const Vector3& v, bool set_original = false); + void setRotationPivot(const Vector3& v, bool set_original = false); + void setScalingPivot(const Vector3& v, bool set_original = false); + void setPreRotation(const Vector3& v, bool set_original = false); + void setPostRotation(const Vector3& v, bool set_original = false); + + const Vector3& getRotationOffset(); + const Vector3& getScalingOffset(); + const Vector3& getRotationPivot(); + const Vector3& getScalingPivot(); + const Vector3& getPreRotation(); + const Vector3& getPostRotation(); + + const Vector3& getInitialRotationOffset(); + const Vector3& getInitialScalingOffset(); + const Vector3& getInitialRotationPivot(); + const Vector3& getInitialScalingPivot(); + const Vector3& getInitialPreRotation(); + const Vector3& getInitialPostRotation(); + + + const Vector3& getLocalTranslation(); + const Vector3& getLocalScale(); + const Vector3& getLocalRotation(); + + const Vector3& getInitialLocalTranslation(); + const Vector3& getInitialLocalScale(); + const Vector3& getInitialLocalRotation(); + + const Vector3 getWorldTranslation(); + const Vector3 getWorldScale(); + const Quaternion getWorldRotation(); + + const Quaternion getBindPoseWorldRotation(); + const Quaternion getActivePoseWorldRotation(); + + const Vector3 localToWorld(const Vector3& local_point); + const Vector3 worldToLocal(const Vector3& world_point); + + void setWorldTranslation(const Vector3& v); + void setWorldScale(const Vector3& v); + void setWorldRotation(const Vector3& v); + + virtual AABB getBounds(); + void invalidateBounds() const; + const Matrix4& getModelMatrix(); + const Matrix4& getInverseModelMatrix(); + const Matrix4& getBindPoseMatrix(); + const Matrix4& getActivePoseMatrix(); + const Matrix4& getInverseBindPoseMatrix(); + + enum node_attribute_type + { + KRENGINE_NODE_ATTRIBUTE_NONE, + KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X, + KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y, + KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z, + KRENGINE_NODE_ATTRIBUTE_SCALE_X, + KRENGINE_NODE_ATTRIBUTE_SCALE_Y, + KRENGINE_NODE_ATTRIBUTE_SCALE_Z, + KRENGINE_NODE_ATTRIBUTE_ROTATE_X, + KRENGINE_NODE_ATTRIBUTE_ROTATE_Y, + 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); + + KRScene& getScene(); + + virtual void render(const RenderInfo& ri); + + virtual void physicsUpdate(float deltaTime); + virtual bool hasPhysics(); + + virtual void updateLODVisibility(const KRViewport& viewport); + LodVisibility getLODVisibility(); + + void setScaleCompensation(bool scale_compensation); + bool getScaleCompensation(); + void setAnimationEnabled(node_attribute_type attrib, bool enable); + bool getAnimationEnabled(node_attribute_type attrib) const; + + + virtual kraken_stream_level getStreamLevel(const KRViewport& viewport); + + virtual void setLODVisibility(LodVisibility lod_visibility); - static KRNode *LoadXML(KRScene &scene, tinyxml2::XMLElement *e); - virtual void loadXML(tinyxml2::XMLElement *e); - - virtual std::string getElementName(); - const std::string &getName() const; - - void addChild(KRNode *child); - const std::set &getChildren(); - KRNode *getParent(); - - void setLocalTranslation(const Vector3 &v, bool set_original = false); - void setLocalScale(const Vector3 &v, bool set_original = false); - void setLocalRotation(const Vector3 &v, bool set_original = false); - - - void setRotationOffset(const Vector3 &v, bool set_original = false); - void setScalingOffset(const Vector3 &v, bool set_original = false); - void setRotationPivot(const Vector3 &v, bool set_original = false); - void setScalingPivot(const Vector3 &v, bool set_original = false); - void setPreRotation(const Vector3 &v, bool set_original = false); - void setPostRotation(const Vector3 &v, bool set_original = false); - - const Vector3 &getRotationOffset(); - const Vector3 &getScalingOffset(); - const Vector3 &getRotationPivot(); - const Vector3 &getScalingPivot(); - const Vector3 &getPreRotation(); - const Vector3 &getPostRotation(); - - const Vector3 &getInitialRotationOffset(); - const Vector3 &getInitialScalingOffset(); - const Vector3 &getInitialRotationPivot(); - const Vector3 &getInitialScalingPivot(); - const Vector3 &getInitialPreRotation(); - const Vector3 &getInitialPostRotation(); - - - const Vector3 &getLocalTranslation(); - const Vector3 &getLocalScale(); - const Vector3 &getLocalRotation(); - - const Vector3 &getInitialLocalTranslation(); - const Vector3 &getInitialLocalScale(); - const Vector3 &getInitialLocalRotation(); - - const Vector3 getWorldTranslation(); - const Vector3 getWorldScale(); - const Quaternion getWorldRotation(); - - const Quaternion getBindPoseWorldRotation(); - const Quaternion getActivePoseWorldRotation(); - - const Vector3 localToWorld(const Vector3 &local_point); - const Vector3 worldToLocal(const Vector3 &world_point); - - void setWorldTranslation(const Vector3 &v); - void setWorldScale(const Vector3 &v); - void setWorldRotation(const Vector3 &v); - - virtual AABB getBounds(); - void invalidateBounds() const; - const Matrix4 &getModelMatrix(); - const Matrix4 &getInverseModelMatrix(); - const Matrix4 &getBindPoseMatrix(); - const Matrix4 &getActivePoseMatrix(); - const Matrix4 &getInverseBindPoseMatrix(); - - enum node_attribute_type { - KRENGINE_NODE_ATTRIBUTE_NONE, - KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X, - KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y, - KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z, - KRENGINE_NODE_ATTRIBUTE_SCALE_X, - KRENGINE_NODE_ATTRIBUTE_SCALE_Y, - KRENGINE_NODE_ATTRIBUTE_SCALE_Z, - KRENGINE_NODE_ATTRIBUTE_ROTATE_X, - KRENGINE_NODE_ATTRIBUTE_ROTATE_Y, - 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); - - KRScene &getScene(); - - virtual void render(const RenderInfo& ri); - - virtual void physicsUpdate(float deltaTime); - virtual bool hasPhysics(); - - virtual void updateLODVisibility(const KRViewport &viewport); - LodVisibility getLODVisibility(); - - void setScaleCompensation(bool scale_compensation); - bool getScaleCompensation(); - void setAnimationEnabled(node_attribute_type attrib, bool enable); - bool getAnimationEnabled(node_attribute_type attrib) const; - - - virtual kraken_stream_level getStreamLevel(const KRViewport &viewport); - - virtual void setLODVisibility(LodVisibility lod_visibility); - protected: - Vector3 m_localTranslation; - Vector3 m_localScale; - Vector3 m_localRotation; - - Vector3 m_rotationOffset; - Vector3 m_scalingOffset; - Vector3 m_rotationPivot; - Vector3 m_scalingPivot; - Vector3 m_preRotation; - Vector3 m_postRotation; - - Vector3 m_initialLocalTranslation; - Vector3 m_initialLocalScale; - Vector3 m_initialLocalRotation; - - Vector3 m_initialRotationOffset; - Vector3 m_initialScalingOffset; - Vector3 m_initialRotationPivot; - Vector3 m_initialScalingPivot; - Vector3 m_initialPreRotation; - Vector3 m_initialPostRotation; - - LodVisibility m_lod_visible; - - KRNode *m_parentNode; - std::set m_childNodes; - - bool m_animation_mask[KRENGINE_NODE_ATTRIBUTE_COUNT]; - + Vector3 m_localTranslation; + Vector3 m_localScale; + Vector3 m_localRotation; + + Vector3 m_rotationOffset; + Vector3 m_scalingOffset; + Vector3 m_rotationPivot; + Vector3 m_scalingPivot; + Vector3 m_preRotation; + Vector3 m_postRotation; + + Vector3 m_initialLocalTranslation; + Vector3 m_initialLocalScale; + Vector3 m_initialLocalRotation; + + Vector3 m_initialRotationOffset; + Vector3 m_initialScalingOffset; + Vector3 m_initialRotationPivot; + Vector3 m_initialScalingPivot; + Vector3 m_initialPreRotation; + Vector3 m_initialPostRotation; + + LodVisibility m_lod_visible; + + KRNode* m_parentNode; + std::set m_childNodes; + + bool m_animation_mask[KRENGINE_NODE_ATTRIBUTE_COUNT]; + private: - long m_lastRenderFrame; - void invalidateModelMatrix(); - void invalidateBindPoseMatrix(); - Matrix4 m_modelMatrix; - Matrix4 m_inverseModelMatrix; - Matrix4 m_bindPoseMatrix; - Matrix4 m_activePoseMatrix; - Matrix4 m_inverseBindPoseMatrix; - bool m_modelMatrixValid; - bool m_inverseModelMatrixValid; - bool m_bindPoseMatrixValid; - bool m_activePoseMatrixValid; - bool m_inverseBindPoseMatrixValid; - - mutable AABB m_bounds; - mutable bool m_boundsValid; - - std::string m_name; - - - - KRScene *m_pScene; - - std::set m_octree_nodes; - bool m_scale_compensation; - - std::set m_behaviors; - + long m_lastRenderFrame; + void invalidateModelMatrix(); + void invalidateBindPoseMatrix(); + Matrix4 m_modelMatrix; + Matrix4 m_inverseModelMatrix; + Matrix4 m_bindPoseMatrix; + Matrix4 m_activePoseMatrix; + Matrix4 m_inverseBindPoseMatrix; + bool m_modelMatrixValid; + bool m_inverseModelMatrixValid; + bool m_bindPoseMatrixValid; + bool m_activePoseMatrixValid; + bool m_inverseBindPoseMatrixValid; + + mutable AABB m_bounds; + mutable bool m_boundsValid; + + std::string m_name; + + + + KRScene* m_pScene; + + std::set m_octree_nodes; + bool m_scale_compensation; + + std::set m_behaviors; + public: - void addBehavior(KRBehavior *behavior); - std::set &getBehaviors(); - template T *getBehavior() - { - for(std::set::iterator itr=m_behaviors.begin(); itr != m_behaviors.end(); itr++) { - T *behavior = dynamic_cast(*itr); - if(behavior) { - return behavior; - } - } - return NULL; + void addBehavior(KRBehavior* behavior); + std::set& getBehaviors(); + template T* getBehavior() + { + for (std::set::iterator itr = m_behaviors.begin(); itr != m_behaviors.end(); itr++) { + T* behavior = dynamic_cast(*itr); + if (behavior) { + return behavior; + } } - void removeFromOctreeNodes(); - void addToOctreeNode(KROctreeNode *octree_node); - void childDeleted(KRNode *child_node); - - template T *find() - { - T *match = dynamic_cast(this); - if(match) { - return match; - } - - for(std::set::const_iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - match = (*itr)->find(); - if(match) { - return match; - } - } - - return NULL; + return NULL; + } + void removeFromOctreeNodes(); + void addToOctreeNode(KROctreeNode* octree_node); + void childDeleted(KRNode* child_node); + + template T* find() + { + T* match = dynamic_cast(this); + if (match) { + return match; } - - template T *find(const std::string &name) - { - T *match = dynamic_cast(this); - if(match) { - if(name.compare(match->getName()) == 0) { - return match; - } - } - - for(std::set::const_iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - match = (*itr)->find(name); - if(match) { - return match; - } - } - - return NULL; + + for (std::set::const_iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + match = (*itr)->find(); + if (match) { + return match; + } } + + return NULL; + } + + template T* find(const std::string& name) + { + T* match = dynamic_cast(this); + if (match) { + if (name.compare(match->getName()) == 0) { + return match; + } + } + + for (std::set::const_iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + match = (*itr)->find(name); + if (match) { + return match; + } + } + + return NULL; + } }; diff --git a/kraken/KROctree.cpp b/kraken/KROctree.cpp index 7c8879f..4cfc24c 100755 --- a/kraken/KROctree.cpp +++ b/kraken/KROctree.cpp @@ -36,144 +36,144 @@ KROctree::KROctree() { - m_pRootNode = NULL; + m_pRootNode = NULL; } KROctree::~KROctree() { - if(m_pRootNode) { - delete m_pRootNode; - } + if (m_pRootNode) { + delete m_pRootNode; + } } -void KROctree::add(KRNode *pNode) +void KROctree::add(KRNode* pNode) { - AABB nodeBounds = pNode->getBounds(); - if(nodeBounds == AABB::Zero()) { - // This item is not visible, don't add it to the octree or outer scene nodes - } else if(nodeBounds == AABB::Infinite()) { - // This item is infinitely large; we track it separately - m_outerSceneNodes.insert(pNode); - } else { - if(m_pRootNode == NULL) { - // First item inserted, create a node large enough to fit it - m_pRootNode = new KROctreeNode(NULL, nodeBounds); - m_pRootNode->add(pNode); + AABB nodeBounds = pNode->getBounds(); + if (nodeBounds == AABB::Zero()) { + // This item is not visible, don't add it to the octree or outer scene nodes + } else if (nodeBounds == AABB::Infinite()) { + // This item is infinitely large; we track it separately + m_outerSceneNodes.insert(pNode); + } else { + if (m_pRootNode == NULL) { + // First item inserted, create a node large enough to fit it + m_pRootNode = new KROctreeNode(NULL, nodeBounds); + m_pRootNode->add(pNode); + } else { + // Keep encapsulating the root node until the new root contains the inserted node + bool bInsideRoot = false; + while (!bInsideRoot) { + AABB rootBounds = m_pRootNode->getBounds(); + Vector3 rootSize = rootBounds.size(); + if (nodeBounds.min.x < rootBounds.min.x || nodeBounds.min.y < rootBounds.min.y || nodeBounds.min.z < rootBounds.min.z) { + m_pRootNode = new KROctreeNode(NULL, AABB::Create(rootBounds.min - rootSize, rootBounds.max), 7, m_pRootNode); + } else if (nodeBounds.max.x > rootBounds.max.x || nodeBounds.max.y > rootBounds.max.y || nodeBounds.max.z > rootBounds.max.z) { + m_pRootNode = new KROctreeNode(NULL, AABB::Create(rootBounds.min, rootBounds.max + rootSize), 0, m_pRootNode); } else { - // Keep encapsulating the root node until the new root contains the inserted node - bool bInsideRoot = false; - while(!bInsideRoot) { - AABB rootBounds = m_pRootNode->getBounds(); - Vector3 rootSize = rootBounds.size(); - if(nodeBounds.min.x < rootBounds.min.x || nodeBounds.min.y < rootBounds.min.y || nodeBounds.min.z < rootBounds.min.z) { - m_pRootNode = new KROctreeNode(NULL, AABB::Create(rootBounds.min - rootSize, rootBounds.max), 7, m_pRootNode); - } else if(nodeBounds.max.x > rootBounds.max.x || nodeBounds.max.y > rootBounds.max.y || nodeBounds.max.z > rootBounds.max.z) { - m_pRootNode = new KROctreeNode(NULL, AABB::Create(rootBounds.min, rootBounds.max + rootSize), 0, m_pRootNode); - } else { - bInsideRoot = true; - } - } - m_pRootNode->add(pNode); + bInsideRoot = true; } + } + m_pRootNode->add(pNode); } + } } -void KROctree::remove(KRNode *pNode) +void KROctree::remove(KRNode* pNode) { - if(!m_outerSceneNodes.erase(pNode)) { - if(m_pRootNode) { - pNode->removeFromOctreeNodes(); - } + if (!m_outerSceneNodes.erase(pNode)) { + if (m_pRootNode) { + pNode->removeFromOctreeNodes(); } - - shrink(); + } + + shrink(); } -void KROctree::update(KRNode *pNode) +void KROctree::update(KRNode* pNode) { - // TODO: This may be more efficient as an incremental operation rather than removing and re-adding the node - remove(pNode); - add(pNode); - shrink(); + // TODO: This may be more efficient as an incremental operation rather than removing and re-adding the node + remove(pNode); + add(pNode); + shrink(); } void KROctree::shrink() { - if(m_pRootNode) { - while(m_pRootNode->canShrinkRoot()) { - KROctreeNode *newRoot = m_pRootNode->stripChild(); - delete m_pRootNode; - m_pRootNode = newRoot; - if(m_pRootNode == NULL) return; - } + if (m_pRootNode) { + while (m_pRootNode->canShrinkRoot()) { + KROctreeNode* newRoot = m_pRootNode->stripChild(); + delete m_pRootNode; + m_pRootNode = newRoot; + if (m_pRootNode == NULL) return; } + } } -KROctreeNode *KROctree::getRootNode() +KROctreeNode* KROctree::getRootNode() { - return m_pRootNode; + return m_pRootNode; } -std::set &KROctree::getOuterSceneNodes() +std::set& KROctree::getOuterSceneNodes() { - return m_outerSceneNodes; + return m_outerSceneNodes; } -bool KROctree::lineCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo, unsigned int layer_mask) +bool KROctree::lineCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo, unsigned int layer_mask) { - bool hit_found = false; - std::vector outer_colliders; - - for(std::set::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) { - KRCollider *collider = dynamic_cast(*outer_nodes_itr); - if(collider) { - outer_colliders.push_back(collider); - } + bool hit_found = false; + std::vector outer_colliders; + + for (std::set::iterator outer_nodes_itr = m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) { + KRCollider* collider = dynamic_cast(*outer_nodes_itr); + if (collider) { + outer_colliders.push_back(collider); } - for(std::vector::iterator itr=outer_colliders.begin(); itr != outer_colliders.end(); itr++) { - if((*itr)->lineCast(v0, v1, hitinfo, layer_mask)) hit_found = true; - } - - if(m_pRootNode) { - if(m_pRootNode->lineCast(v0, v1, hitinfo, layer_mask)) hit_found = true; - } - return hit_found; + } + for (std::vector::iterator itr = outer_colliders.begin(); itr != outer_colliders.end(); itr++) { + if ((*itr)->lineCast(v0, v1, hitinfo, layer_mask)) hit_found = true; + } + + if (m_pRootNode) { + if (m_pRootNode->lineCast(v0, v1, hitinfo, layer_mask)) hit_found = true; + } + return hit_found; } -bool KROctree::rayCast(const Vector3 &v0, const Vector3 &dir, HitInfo &hitinfo, unsigned int layer_mask) +bool KROctree::rayCast(const Vector3& v0, const Vector3& dir, HitInfo& hitinfo, unsigned int layer_mask) { - bool hit_found = false; - for(std::set::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) { - KRCollider *collider = dynamic_cast(*outer_nodes_itr); - if(collider) { - if(collider->rayCast(v0, dir, hitinfo, layer_mask)) hit_found = true; - } + bool hit_found = false; + for (std::set::iterator outer_nodes_itr = m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) { + KRCollider* collider = dynamic_cast(*outer_nodes_itr); + if (collider) { + if (collider->rayCast(v0, dir, hitinfo, layer_mask)) hit_found = true; } - if(m_pRootNode) { - if(m_pRootNode->rayCast(v0, dir, hitinfo, layer_mask)) hit_found = true; - } - return hit_found; + } + if (m_pRootNode) { + if (m_pRootNode->rayCast(v0, dir, hitinfo, layer_mask)) hit_found = true; + } + return hit_found; } -bool KROctree::sphereCast(const Vector3 &v0, const Vector3 &v1, float radius, HitInfo &hitinfo, unsigned int layer_mask) +bool KROctree::sphereCast(const Vector3& v0, const Vector3& v1, float radius, HitInfo& hitinfo, unsigned int layer_mask) { - bool hit_found = false; - std::vector outer_colliders; - - for(std::set::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) { - KRCollider *collider = dynamic_cast(*outer_nodes_itr); - if(collider) { - outer_colliders.push_back(collider); - } + bool hit_found = false; + std::vector outer_colliders; + + for (std::set::iterator outer_nodes_itr = m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) { + KRCollider* collider = dynamic_cast(*outer_nodes_itr); + if (collider) { + outer_colliders.push_back(collider); } - for(std::vector::iterator itr=outer_colliders.begin(); itr != outer_colliders.end(); itr++) { - if((*itr)->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true; - } - - if(m_pRootNode) { - if(m_pRootNode->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true; - } - return hit_found; + } + for (std::vector::iterator itr = outer_colliders.begin(); itr != outer_colliders.end(); itr++) { + if ((*itr)->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true; + } + + if (m_pRootNode) { + if (m_pRootNode->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true; + } + return hit_found; } diff --git a/kraken/KROctree.h b/kraken/KROctree.h index 2520349..ca19725 100755 --- a/kraken/KROctree.h +++ b/kraken/KROctree.h @@ -36,25 +36,26 @@ class KRNode; -class KROctree { +class KROctree +{ public: - KROctree(); - ~KROctree(); + KROctree(); + ~KROctree(); - void add(KRNode *pNode); - void remove(KRNode *pNode); - void update(KRNode *pNode); + void add(KRNode* pNode); + void remove(KRNode* pNode); + void update(KRNode* pNode); - KROctreeNode *getRootNode(); - std::set &getOuterSceneNodes(); + KROctreeNode* getRootNode(); + std::set& getOuterSceneNodes(); - bool lineCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo, unsigned int layer_mask); - bool rayCast(const Vector3 &v0, const Vector3 &dir, HitInfo &hitinfo, unsigned int layer_mask); - bool sphereCast(const Vector3 &v0, const Vector3 &v1, float radius, HitInfo &hitinfo, unsigned int layer_mask); + bool lineCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo, unsigned int layer_mask); + bool rayCast(const Vector3& v0, const Vector3& dir, HitInfo& hitinfo, unsigned int layer_mask); + bool sphereCast(const Vector3& v0, const Vector3& v1, float radius, HitInfo& hitinfo, unsigned int layer_mask); private: - KROctreeNode *m_pRootNode; - std::set m_outerSceneNodes; + KROctreeNode* m_pRootNode; + std::set m_outerSceneNodes; - void shrink(); + void shrink(); }; diff --git a/kraken/KROctreeNode.cpp b/kraken/KROctreeNode.cpp index 76fbc3d..8f52fb5 100755 --- a/kraken/KROctreeNode.cpp +++ b/kraken/KROctreeNode.cpp @@ -33,281 +33,285 @@ #include "KRNode.h" #include "KRCollider.h" -KROctreeNode::KROctreeNode(KROctreeNode *parent, const AABB &bounds) : m_bounds(bounds) +KROctreeNode::KROctreeNode(KROctreeNode* parent, const AABB& bounds) : m_bounds(bounds) { - m_parent = parent; - - for(int i=0; i<8; i++) m_children[i] = NULL; - - m_occlusionQuery = 0; - m_occlusionTested = false; - m_activeQuery = false; + m_parent = parent; + + for (int i = 0; i < 8; i++) { + m_children[i] = NULL; + } + + m_occlusionQuery = 0; + m_occlusionTested = false; + m_activeQuery = false; } -KROctreeNode::KROctreeNode(KROctreeNode *parent, const AABB &bounds, int iChild, KROctreeNode *pChild) : m_bounds(bounds) +KROctreeNode::KROctreeNode(KROctreeNode* parent, const AABB& bounds, int iChild, KROctreeNode* pChild) : m_bounds(bounds) { - // This constructor is used when expanding the octree and replacing the root node with a new root that encapsulates it - m_parent = parent; - - for(int i=0; i<8; i++) m_children[i] = NULL; - m_children[iChild] = pChild; - pChild->m_parent = this; - - m_occlusionQuery = 0; - m_occlusionTested = false; - m_activeQuery = false; + // This constructor is used when expanding the octree and replacing the root node with a new root that encapsulates it + m_parent = parent; + + for (int i = 0; i < 8; i++) { + m_children[i] = NULL; + } + m_children[iChild] = pChild; + pChild->m_parent = this; + + m_occlusionQuery = 0; + m_occlusionTested = false; + m_activeQuery = false; } KROctreeNode::~KROctreeNode() { - for(int i=0; i<8; i++) { - if(m_children[i] != NULL) { - delete m_children[i]; - } + for (int i = 0; i < 8; i++) { + if (m_children[i] != NULL) { + delete m_children[i]; } + } - if(m_occlusionTested) { - GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery)); - } + if (m_occlusionTested) { + GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery)); + } } void KROctreeNode::beginOcclusionQuery() { - if(!m_occlusionTested){ - GLDEBUG(glGenQueriesEXT(1, &m_occlusionQuery)); + if (!m_occlusionTested) { + GLDEBUG(glGenQueriesEXT(1, &m_occlusionQuery)); #if TARGET_OS_IPHONE || defined(ANDROID) - GLDEBUG(glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, m_occlusionQuery)); + GLDEBUG(glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, m_occlusionQuery)); #else - GLDEBUG(glBeginQuery(GL_SAMPLES_PASSED, m_occlusionQuery)); + GLDEBUG(glBeginQuery(GL_SAMPLES_PASSED, m_occlusionQuery)); #endif - m_occlusionTested = true; - m_activeQuery = true; - } + m_occlusionTested = true; + m_activeQuery = true; + } } void KROctreeNode::endOcclusionQuery() { - if(m_activeQuery) { - // Only end a query if we started one + if (m_activeQuery) { + // Only end a query if we started one #if TARGET_OS_IPHONE || defined(ANDROID) - GLDEBUG(glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT)); + GLDEBUG(glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT)); #else - GLDEBUG(glEndQuery(GL_SAMPLES_PASSED)); + GLDEBUG(glEndQuery(GL_SAMPLES_PASSED)); #endif - } + } } AABB KROctreeNode::getBounds() { - return m_bounds; + return m_bounds; } -void KROctreeNode::add(KRNode *pNode) +void KROctreeNode::add(KRNode* pNode) { - int iChild = getChildIndex(pNode); - if(iChild == -1) { - m_sceneNodes.insert(pNode); - pNode->addToOctreeNode(this); - } else { - if(m_children[iChild] == NULL) { - m_children[iChild] = new KROctreeNode(this, getChildBounds(iChild)); - } - m_children[iChild]->add(pNode); + int iChild = getChildIndex(pNode); + if (iChild == -1) { + m_sceneNodes.insert(pNode); + pNode->addToOctreeNode(this); + } else { + if (m_children[iChild] == NULL) { + m_children[iChild] = new KROctreeNode(this, getChildBounds(iChild)); } + m_children[iChild]->add(pNode); + } } AABB KROctreeNode::getChildBounds(int iChild) { - Vector3 center = m_bounds.center(); - - return AABB::Create( - Vector3::Create( - (iChild & 1) == 0 ? m_bounds.min.x : center.x, - (iChild & 2) == 0 ? m_bounds.min.y : center.y, - (iChild & 4) == 0 ? m_bounds.min.z : center.z), - Vector3::Create( - (iChild & 1) == 0 ? center.x : m_bounds.max.x, - (iChild & 2) == 0 ? center.y : m_bounds.max.y, - (iChild & 4) == 0 ? center.z : m_bounds.max.z) - ); + Vector3 center = m_bounds.center(); + + return AABB::Create( + Vector3::Create( + (iChild & 1) == 0 ? m_bounds.min.x : center.x, + (iChild & 2) == 0 ? m_bounds.min.y : center.y, + (iChild & 4) == 0 ? m_bounds.min.z : center.z), + Vector3::Create( + (iChild & 1) == 0 ? center.x : m_bounds.max.x, + (iChild & 2) == 0 ? center.y : m_bounds.max.y, + (iChild & 4) == 0 ? center.z : m_bounds.max.z) + ); } -int KROctreeNode::getChildIndex(KRNode *pNode) -{ - for(int iChild=0; iChild < 8; iChild++) { - if(getChildBounds(iChild).contains(pNode->getBounds())) { - return iChild; - } +int KROctreeNode::getChildIndex(KRNode* pNode) +{ + for (int iChild = 0; iChild < 8; iChild++) { + if (getChildBounds(iChild).contains(pNode->getBounds())) { + return iChild; } - return -1; + } + return -1; } void KROctreeNode::trim() { - for(int iChild = 0; iChild < 8; iChild++) { - if(m_children[iChild]) { - if(m_children[iChild]->isEmpty()) { - delete m_children[iChild]; - m_children[iChild] = NULL; - } - } + for (int iChild = 0; iChild < 8; iChild++) { + if (m_children[iChild]) { + if (m_children[iChild]->isEmpty()) { + delete m_children[iChild]; + m_children[iChild] = NULL; + } } + } } -void KROctreeNode::remove(KRNode *pNode) +void KROctreeNode::remove(KRNode* pNode) { - m_sceneNodes.erase(pNode); + m_sceneNodes.erase(pNode); } -void KROctreeNode::update(KRNode *pNode) +void KROctreeNode::update(KRNode* pNode) { - + } bool KROctreeNode::isEmpty() const { - for(int i=0; i<8; i++) { - if(m_children[i]) { - return false; - } + for (int i = 0; i < 8; i++) { + if (m_children[i]) { + return false; } - return m_sceneNodes.empty(); + } + return m_sceneNodes.empty(); } bool KROctreeNode::canShrinkRoot() const { - int cChildren = 0; - for(int i=0; i<8; i++) { - if(m_children[i]) { - cChildren++; - } + int cChildren = 0; + for (int i = 0; i < 8; i++) { + if (m_children[i]) { + cChildren++; } - return cChildren <= 1 && m_sceneNodes.empty(); + } + return cChildren <= 1 && m_sceneNodes.empty(); } -KROctreeNode *KROctreeNode::stripChild() +KROctreeNode* KROctreeNode::stripChild() { - // Return the first found child and update its reference to NULL so that the destructor will not free it. This is used for shrinking the octree - // NOTE: The caller of this function will be responsible for freeing the child object. It is also possible to return a NULL - for(int i=0; i<8; i++) { - if(m_children[i]) { - KROctreeNode *child = m_children[i]; - child->m_parent = NULL; - m_children[i] = NULL; - return child; - } + // Return the first found child and update its reference to NULL so that the destructor will not free it. This is used for shrinking the octree + // NOTE: The caller of this function will be responsible for freeing the child object. It is also possible to return a NULL + for (int i = 0; i < 8; i++) { + if (m_children[i]) { + KROctreeNode* child = m_children[i]; + child->m_parent = NULL; + m_children[i] = NULL; + return child; } - return NULL; + } + return NULL; } -KROctreeNode *KROctreeNode::getParent() +KROctreeNode* KROctreeNode::getParent() { - return m_parent; + return m_parent; } -KROctreeNode **KROctreeNode::getChildren() +KROctreeNode** KROctreeNode::getChildren() { - return m_children; + return m_children; } -std::set &KROctreeNode::getSceneNodes() +std::set& KROctreeNode::getSceneNodes() { - return m_sceneNodes; + return m_sceneNodes; } -bool KROctreeNode::lineCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo, unsigned int layer_mask) +bool KROctreeNode::lineCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo, unsigned int layer_mask) { - bool hit_found = false; - if(hitinfo.didHit() && v1 != hitinfo.getPosition()) { - // Optimization: If we already have a hit, only search for hits that are closer - hit_found = lineCast(v0, hitinfo.getPosition(), hitinfo, layer_mask); - } else { - if(getBounds().intersectsLine(v0, v1)) { - for(std::set::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) { - KRCollider *collider = dynamic_cast(*nodes_itr); - if(collider) { - if(collider->lineCast(v0, v1, hitinfo, layer_mask)) hit_found = true; - } - } - - for(int i=0; i<8; i++) { - if(m_children[i]) { - if(m_children[i]->lineCast(v0, v1, hitinfo, layer_mask)) { - hit_found = true; - } - } - } + bool hit_found = false; + if (hitinfo.didHit() && v1 != hitinfo.getPosition()) { + // Optimization: If we already have a hit, only search for hits that are closer + hit_found = lineCast(v0, hitinfo.getPosition(), hitinfo, layer_mask); + } else { + if (getBounds().intersectsLine(v0, v1)) { + for (std::set::iterator nodes_itr = m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) { + KRCollider* collider = dynamic_cast(*nodes_itr); + if (collider) { + if (collider->lineCast(v0, v1, hitinfo, layer_mask)) hit_found = true; } + } + + for (int i = 0; i < 8; i++) { + if (m_children[i]) { + if (m_children[i]->lineCast(v0, v1, hitinfo, layer_mask)) { + hit_found = true; + } + } + } + } + } + + return hit_found; +} + +bool KROctreeNode::rayCast(const Vector3& v0, const Vector3& dir, HitInfo& hitinfo, unsigned int layer_mask) +{ + bool hit_found = false; + if (hitinfo.didHit()) { + // Optimization: If we already have a hit, only search for hits that are closer + hit_found = lineCast(v0, hitinfo.getPosition(), hitinfo, layer_mask); // Note: This is purposefully lineCast as opposed to RayCast + } else { + if (getBounds().intersectsRay(v0, dir)) { + for (std::set::iterator nodes_itr = m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) { + KRCollider* collider = dynamic_cast(*nodes_itr); + if (collider) { + if (collider->rayCast(v0, dir, hitinfo, layer_mask)) hit_found = true; + } + } + + for (int i = 0; i < 8; i++) { + if (m_children[i]) { + if (m_children[i]->rayCast(v0, dir, hitinfo, layer_mask)) { + hit_found = true; + } + } + } + } + } + + return hit_found; +} + +bool KROctreeNode::sphereCast(const Vector3& v0, const Vector3& v1, float radius, HitInfo& hitinfo, unsigned int layer_mask) +{ + bool hit_found = false; + /* + // FINDME, TODO - Adapt this optimization to work with sphereCasts + + if(hitinfo.didHit() && v1 != hitinfo.getPosition()) { + // Optimization: If we already have a hit, only search for hits that are closer + hit_found = sphereCast(v0, hitinfo.getPosition(), radius, hitinfo, layer_mask); + } else { + */ + + AABB swept_bounds = AABB::Create(Vector3::Create(KRMIN(v0.x, v1.x) - radius, KRMIN(v0.y, v1.y) - radius, KRMIN(v0.z, v1.z) - radius), Vector3::Create(KRMAX(v0.x, v1.x) + radius, KRMAX(v0.y, v1.y) + radius, KRMAX(v0.z, v1.z) + radius)); + // FINDME, TODO - Investigate AABB - swept sphere intersections or OBB - AABB intersections: "if(getBounds().intersectsSweptSphere(v0, v1, radius)) {" + if (getBounds().intersects(swept_bounds)) { + + for (std::set::iterator nodes_itr = m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) { + KRCollider* collider = dynamic_cast(*nodes_itr); + if (collider) { + if (collider->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true; + } } - return hit_found; -} - -bool KROctreeNode::rayCast(const Vector3 &v0, const Vector3 &dir, HitInfo &hitinfo, unsigned int layer_mask) -{ - bool hit_found = false; - if(hitinfo.didHit()) { - // Optimization: If we already have a hit, only search for hits that are closer - hit_found = lineCast(v0, hitinfo.getPosition(), hitinfo, layer_mask); // Note: This is purposefully lineCast as opposed to RayCast - } else { - if(getBounds().intersectsRay(v0, dir)) { - for(std::set::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) { - KRCollider *collider = dynamic_cast(*nodes_itr); - if(collider) { - if(collider->rayCast(v0, dir, hitinfo, layer_mask)) hit_found = true; - } - } - - for(int i=0; i<8; i++) { - if(m_children[i]) { - if(m_children[i]->rayCast(v0, dir, hitinfo, layer_mask)) { - hit_found = true; - } - } - } + for (int i = 0; i < 8; i++) { + if (m_children[i]) { + if (m_children[i]->sphereCast(v0, v1, radius, hitinfo, layer_mask)) { + hit_found = true; } + } } + } + // } - return hit_found; -} - -bool KROctreeNode::sphereCast(const Vector3 &v0, const Vector3 &v1, float radius, HitInfo &hitinfo, unsigned int layer_mask) -{ - bool hit_found = false; - /* - // FINDME, TODO - Adapt this optimization to work with sphereCasts - - if(hitinfo.didHit() && v1 != hitinfo.getPosition()) { - // Optimization: If we already have a hit, only search for hits that are closer - hit_found = sphereCast(v0, hitinfo.getPosition(), radius, hitinfo, layer_mask); - } else { - */ - - AABB swept_bounds = AABB::Create(Vector3::Create(KRMIN(v0.x, v1.x) - radius, KRMIN(v0.y, v1.y) - radius, KRMIN(v0.z, v1.z) - radius), Vector3::Create(KRMAX(v0.x, v1.x) + radius, KRMAX(v0.y, v1.y) + radius, KRMAX(v0.z, v1.z) + radius)); - // FINDME, TODO - Investigate AABB - swept sphere intersections or OBB - AABB intersections: "if(getBounds().intersectsSweptSphere(v0, v1, radius)) {" - if(getBounds().intersects(swept_bounds)) { - - for(std::set::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) { - KRCollider *collider = dynamic_cast(*nodes_itr); - if(collider) { - if(collider->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true; - } - } - - for(int i=0; i<8; i++) { - if(m_children[i]) { - if(m_children[i]->sphereCast(v0, v1, radius, hitinfo, layer_mask)) { - hit_found = true; - } - } - } - } - // } - - return hit_found; + return hit_found; } diff --git a/kraken/KROctreeNode.h b/kraken/KROctreeNode.h index 79c908c..ba92d94 100755 --- a/kraken/KROctreeNode.h +++ b/kraken/KROctreeNode.h @@ -36,49 +36,50 @@ class KRNode; -class KROctreeNode { +class KROctreeNode +{ public: - KROctreeNode(KROctreeNode *parent, const AABB &bounds); - KROctreeNode(KROctreeNode *parent, const AABB &bounds, int iChild, KROctreeNode *pChild); - ~KROctreeNode(); + KROctreeNode(KROctreeNode* parent, const AABB& bounds); + KROctreeNode(KROctreeNode* parent, const AABB& bounds, int iChild, KROctreeNode* pChild); + ~KROctreeNode(); - KROctreeNode **getChildren(); - std::set &getSceneNodes(); + KROctreeNode** getChildren(); + std::set& getSceneNodes(); - void add(KRNode *pNode); - void remove(KRNode *pNode); - void update(KRNode *pNode); + void add(KRNode* pNode); + void remove(KRNode* pNode); + void update(KRNode* pNode); - AABB getBounds(); + AABB getBounds(); - KROctreeNode *getParent(); - void setChildNode(int iChild, KROctreeNode *pChild); - int getChildIndex(KRNode *pNode); - AABB getChildBounds(int iChild); - void trim(); - bool isEmpty() const; + KROctreeNode* getParent(); + void setChildNode(int iChild, KROctreeNode* pChild); + int getChildIndex(KRNode* pNode); + AABB getChildBounds(int iChild); + void trim(); + bool isEmpty() const; - bool canShrinkRoot() const; - KROctreeNode *stripChild(); + bool canShrinkRoot() const; + KROctreeNode* stripChild(); - void beginOcclusionQuery(); - void endOcclusionQuery(); + void beginOcclusionQuery(); + void endOcclusionQuery(); - GLuint m_occlusionQuery; - bool m_occlusionTested; - bool m_activeQuery; + GLuint m_occlusionQuery; + bool m_occlusionTested; + bool m_activeQuery; - bool lineCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo, unsigned int layer_mask); - bool rayCast(const Vector3 &v0, const Vector3 &dir, HitInfo &hitinfo, unsigned int layer_mask); - bool sphereCast(const Vector3 &v0, const Vector3 &v1, float radius, HitInfo &hitinfo, unsigned int layer_mask); + bool lineCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo, unsigned int layer_mask); + bool rayCast(const Vector3& v0, const Vector3& dir, HitInfo& hitinfo, unsigned int layer_mask); + bool sphereCast(const Vector3& v0, const Vector3& v1, float radius, HitInfo& hitinfo, unsigned int layer_mask); private: - AABB m_bounds; + AABB m_bounds; - KROctreeNode *m_parent; - KROctreeNode *m_children[8]; + KROctreeNode* m_parent; + KROctreeNode* m_children[8]; - std::setm_sceneNodes; + std::setm_sceneNodes; }; diff --git a/kraken/KRParticleSystem.cpp b/kraken/KRParticleSystem.cpp index 71fa2c7..5712429 100755 --- a/kraken/KRParticleSystem.cpp +++ b/kraken/KRParticleSystem.cpp @@ -30,24 +30,24 @@ // #include "KRParticleSystem.h" -KRParticleSystem::KRParticleSystem(KRScene &scene, std::string name) : KRNode(scene, name) +KRParticleSystem::KRParticleSystem(KRScene& scene, std::string name) : KRNode(scene, name) { - + } KRParticleSystem::~KRParticleSystem() { - + } -void KRParticleSystem::loadXML(tinyxml2::XMLElement *e) +void KRParticleSystem::loadXML(tinyxml2::XMLElement* e) { - + } -tinyxml2::XMLElement *KRParticleSystem::saveXML( tinyxml2::XMLNode *parent) +tinyxml2::XMLElement* KRParticleSystem::saveXML(tinyxml2::XMLNode* parent) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - return e; + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + return e; } diff --git a/kraken/KRParticleSystem.h b/kraken/KRParticleSystem.h index c08b146..057311b 100755 --- a/kraken/KRParticleSystem.h +++ b/kraken/KRParticleSystem.h @@ -33,20 +33,21 @@ #include "KRNode.h" -class KRParticleSystem : public KRNode { +class KRParticleSystem : public KRNode +{ public: - virtual ~KRParticleSystem(); - - virtual std::string getElementName() = 0; - virtual void loadXML(tinyxml2::XMLElement *e); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - - virtual AABB getBounds() = 0; - - virtual void render(RenderInfo& ri) = 0; - + virtual ~KRParticleSystem(); + + virtual std::string getElementName() = 0; + virtual void loadXML(tinyxml2::XMLElement* e); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + + virtual AABB getBounds() = 0; + + virtual void render(RenderInfo& ri) = 0; + protected: - KRParticleSystem(KRScene &scene, std::string name); + KRParticleSystem(KRScene& scene, std::string name); private: - + }; diff --git a/kraken/KRParticleSystemNewtonian.cpp b/kraken/KRParticleSystemNewtonian.cpp index 3d43829..69c1cd7 100755 --- a/kraken/KRParticleSystemNewtonian.cpp +++ b/kraken/KRParticleSystemNewtonian.cpp @@ -35,81 +35,82 @@ #include "KRTexture.h" #include "KRContext.h" -KRParticleSystemNewtonian::KRParticleSystemNewtonian(KRScene &scene, std::string name) : KRParticleSystem(scene, name) +KRParticleSystemNewtonian::KRParticleSystemNewtonian(KRScene& scene, std::string name) : KRParticleSystem(scene, name) { - m_particlesAbsoluteTime = 0.0f; + m_particlesAbsoluteTime = 0.0f; } KRParticleSystemNewtonian::~KRParticleSystemNewtonian() { - + } std::string KRParticleSystemNewtonian::getElementName() { - return "newtonian_particles"; + return "newtonian_particles"; } -void KRParticleSystemNewtonian::loadXML(tinyxml2::XMLElement *e) +void KRParticleSystemNewtonian::loadXML(tinyxml2::XMLElement* e) { - KRParticleSystem::loadXML(e); + KRParticleSystem::loadXML(e); } -tinyxml2::XMLElement *KRParticleSystemNewtonian::saveXML( tinyxml2::XMLNode *parent) +tinyxml2::XMLElement* KRParticleSystemNewtonian::saveXML(tinyxml2::XMLNode* parent) { - tinyxml2::XMLElement *e = KRParticleSystem::saveXML(parent); - return e; + tinyxml2::XMLElement* e = KRParticleSystem::saveXML(parent); + return e; } AABB KRParticleSystemNewtonian::getBounds() { - return AABB::Create(-Vector3::One(), Vector3::One(), getModelMatrix()); + return AABB::Create(-Vector3::One(), Vector3::One(), getModelMatrix()); } void KRParticleSystemNewtonian::physicsUpdate(float deltaTime) { - KRParticleSystem::physicsUpdate(deltaTime); - m_particlesAbsoluteTime += deltaTime; + KRParticleSystem::physicsUpdate(deltaTime); + m_particlesAbsoluteTime += deltaTime; } bool KRParticleSystemNewtonian::hasPhysics() { - return true; + return true; } -void KRParticleSystemNewtonian::render(RenderInfo& ri) { - - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRNode::render(ri); - - if(ri.renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { - if(ri.viewport.visible(getBounds())) { - KRTexture *pParticleTexture = m_pContext->getTextureManager()->getTexture("flare"); - m_pContext->getTextureManager()->selectTexture(0, pParticleTexture, 0.0f, KRTexture::TEXTURE_USAGE_PARTICLE); - - int particle_count = 10000; - PipelineInfo info{}; - std::string shader_name("dust_particle"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAdditive; - info.cullMode = CullMode::kCullNone; - info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); - info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; +void KRParticleSystemNewtonian::render(RenderInfo& ri) +{ - KRPipeline *pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); - pParticleShader->setUniform(KRPipeline::Uniform::flare_size, 1.0f); - pParticleShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_RANDOM_PARTICLES, 1.0f); + KRNode::render(ri); - vkCmdDraw(ri.commandBuffer, particle_count * 3, 1, 0, 0); - } + if (ri.renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { + if (ri.viewport.visible(getBounds())) { + KRTexture* pParticleTexture = m_pContext->getTextureManager()->getTexture("flare"); + m_pContext->getTextureManager()->selectTexture(0, pParticleTexture, 0.0f, KRTexture::TEXTURE_USAGE_PARTICLE); + + int particle_count = 10000; + PipelineInfo info{}; + std::string shader_name("dust_particle"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.renderPass = ri.renderPass; + info.rasterMode = RasterMode::kAdditive; + info.cullMode = CullMode::kCullNone; + info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); + info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; + + KRPipeline* pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); + pParticleShader->setUniform(KRPipeline::Uniform::flare_size, 1.0f); + pParticleShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + + m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_RANDOM_PARTICLES, 1.0f); + + vkCmdDraw(ri.commandBuffer, particle_count * 3, 1, 0, 0); } + } } diff --git a/kraken/KRParticleSystemNewtonian.h b/kraken/KRParticleSystemNewtonian.h index e06235f..e75cf0b 100755 --- a/kraken/KRParticleSystemNewtonian.h +++ b/kraken/KRParticleSystemNewtonian.h @@ -33,23 +33,24 @@ #include "KRParticleSystem.h" -class KRParticleSystemNewtonian : public KRParticleSystem { +class KRParticleSystemNewtonian : public KRParticleSystem +{ public: - KRParticleSystemNewtonian(KRScene &scene, std::string name); - virtual ~KRParticleSystemNewtonian(); - - virtual std::string getElementName(); - virtual void loadXML(tinyxml2::XMLElement *e); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - - - virtual AABB getBounds(); - - virtual void render(RenderInfo& ri); - - - virtual void physicsUpdate(float deltaTime); - virtual bool hasPhysics(); + KRParticleSystemNewtonian(KRScene& scene, std::string name); + virtual ~KRParticleSystemNewtonian(); + + virtual std::string getElementName(); + virtual void loadXML(tinyxml2::XMLElement* e); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + + + virtual AABB getBounds(); + + virtual void render(RenderInfo& ri); + + + virtual void physicsUpdate(float deltaTime); + virtual bool hasPhysics(); private: - float m_particlesAbsoluteTime; + float m_particlesAbsoluteTime; }; diff --git a/kraken/KRPipeline.cpp b/kraken/KRPipeline.cpp index f58eadb..339318f 100644 --- a/kraken/KRPipeline.cpp +++ b/kraken/KRPipeline.cpp @@ -39,7 +39,7 @@ #include "KRRenderPass.h" -const char *KRPipeline::KRENGINE_UNIFORM_NAMES[] = { +const char* KRPipeline::KRENGINE_UNIFORM_NAMES[] = { "material_ambient", // Uniform::material_ambient "material_diffuse", // Uniform::material_diffuse "material_specular", // Uniform::material_specular @@ -168,35 +168,27 @@ KRPipeline::KRPipeline(KRContext& context, KRSurface& surface, const PipelineInf SpvReflectInterfaceVariable& input_var = *reflection->input_variables[i]; if (strcmp(input_var.name, "vertex_position") == 0) { attribute_locations[KRMesh::KRENGINE_ATTRIB_VERTEX] = input_var.location + 1; - } - else if (strcmp(input_var.name, "vertex_normal") == 0) { + } else if (strcmp(input_var.name, "vertex_normal") == 0) { attribute_locations[KRMesh::KRENGINE_ATTRIB_NORMAL] = input_var.location + 1; - } - else if (strcmp(input_var.name, "vertex_tangent") == 0) { + } else if (strcmp(input_var.name, "vertex_tangent") == 0) { attribute_locations[KRMesh::KRENGINE_ATTRIB_TANGENT] = input_var.location + 1; - } - else if (strcmp(input_var.name, "vertex_uv") == 0) { + } else if (strcmp(input_var.name, "vertex_uv") == 0) { attribute_locations[KRMesh::KRENGINE_ATTRIB_TEXUVA] = input_var.location + 1; - } - else if (strcmp(input_var.name, "vertex_lightmap_uv") == 0) { + } else if (strcmp(input_var.name, "vertex_lightmap_uv") == 0) { attribute_locations[KRMesh::KRENGINE_ATTRIB_TEXUVB] = input_var.location + 1; - } - else if (strcmp(input_var.name, "bone_indexes") == 0) { + } else if (strcmp(input_var.name, "bone_indexes") == 0) { attribute_locations[KRMesh::KRENGINE_ATTRIB_BONEINDEXES] = input_var.location + 1; - } - else if (strcmp(input_var.name, "bone_weights") == 0) { + } else if (strcmp(input_var.name, "bone_weights") == 0) { attribute_locations[KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS] = input_var.location + 1; } } initPushConstantStage(ShaderStages::vertex, reflection); - } - else if (shader->getSubExtension().compare("frag") == 0) { + } else if (shader->getSubExtension().compare("frag") == 0) { stageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; initPushConstantStage(ShaderStages::fragment, reflection); - } - else { + } else { // failed! TODO - Error handling } stageInfo.module = shaderModule; @@ -368,11 +360,11 @@ KRPipeline::KRPipeline(KRContext& context, KRSurface& surface, const PipelineInf switch (static_cast(iStage)) { case ShaderStages::vertex: - push_constant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - break; + push_constant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + break; case ShaderStages::fragment: - push_constant.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - break; + push_constant.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + break; case ShaderStages::geometry: push_constant.stageFlags = VK_SHADER_STAGE_GEOMETRY_BIT; break; @@ -380,7 +372,7 @@ KRPipeline::KRPipeline(KRContext& context, KRSurface& surface, const PipelineInf push_constant.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; break; } - + pushConstantsLayoutInfo.pPushConstantRanges = &push_constant; pushConstantsLayoutInfo.pushConstantRangeCount = 1; @@ -421,7 +413,7 @@ KRPipeline::KRPipeline(KRContext& context, KRSurface& surface, const PipelineInf } else { depthStencil.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; } - + depthStencil.depthBoundsTestEnable = VK_FALSE; depthStencil.minDepthBounds = 0.0f; depthStencil.maxDepthBounds = 1.0f; @@ -454,7 +446,8 @@ KRPipeline::KRPipeline(KRContext& context, KRSurface& surface, const PipelineInf } } -KRPipeline::~KRPipeline() { +KRPipeline::~KRPipeline() +{ if (m_graphicsPipeline) { // TODO: vkDestroyPipeline(device, m_graphicsPipeline, nullptr); } @@ -468,8 +461,8 @@ KRPipeline::~KRPipeline() { } - if(getContext().getPipelineManager()->m_active_pipeline == this) { - getContext().getPipelineManager()->m_active_pipeline = NULL; + if (getContext().getPipelineManager()->m_active_pipeline == this) { + getContext().getPipelineManager()->m_active_pipeline = NULL; } if (m_pushConstants[0].buffer) { delete m_pushConstants[0].buffer; @@ -492,8 +485,7 @@ void KRPipeline::initPushConstantStage(ShaderStages stage, const SpvReflectShade for (int iUniform = 0; iUniform < kUniformCount; iUniform++) { for (int iMember = 0; iMember < block.member_count; iMember++) { const SpvReflectBlockVariable& member = block.members[iMember]; - if (stricmp(KRENGINE_UNIFORM_NAMES[iUniform], member.name) == 0) - { + if (stricmp(KRENGINE_UNIFORM_NAMES[iUniform], member.name) == 0) { pushConstants.offset[iUniform] = member.offset; pushConstants.size[iUniform] = member.size; } @@ -535,7 +527,7 @@ void KRPipeline::setUniform(Uniform location, int value) } } -void KRPipeline::setUniform(Uniform location, const Vector2 &value) +void KRPipeline::setUniform(Uniform location, const Vector2& value) { for (PushConstantStageInfo& stageConstants : m_pushConstants) { if (stageConstants.size[static_cast(location)] == sizeof(value)) { @@ -544,7 +536,7 @@ void KRPipeline::setUniform(Uniform location, const Vector2 &value) } } } -void KRPipeline::setUniform(Uniform location, const Vector3 &value) +void KRPipeline::setUniform(Uniform location, const Vector3& value) { for (PushConstantStageInfo& stageConstants : m_pushConstants) { if (stageConstants.size[static_cast(location)] == sizeof(value)) { @@ -554,7 +546,7 @@ void KRPipeline::setUniform(Uniform location, const Vector3 &value) } } -void KRPipeline::setUniform(Uniform location, const Vector4 &value) +void KRPipeline::setUniform(Uniform location, const Vector4& value) { for (PushConstantStageInfo& stageConstants : m_pushConstants) { if (stageConstants.size[static_cast(location)] == sizeof(value)) { @@ -564,7 +556,7 @@ void KRPipeline::setUniform(Uniform location, const Vector4 &value) } } -void KRPipeline::setUniform(Uniform location, const Matrix4 &value) +void KRPipeline::setUniform(Uniform location, const Matrix4& value) { for (PushConstantStageInfo& stageConstants : m_pushConstants) { if (stageConstants.size[static_cast(location)] == sizeof(value)) { @@ -582,211 +574,212 @@ void KRPipeline::setUniform(Uniform location, const Matrix4* value, const size_t } } -bool KRPipeline::bind(VkCommandBuffer& commandBuffer, KRCamera &camera, const KRViewport &viewport, const Matrix4 &matModel, const std::vector *point_lights, const std::vector *directional_lights, const std::vector *spot_lights, const KRNode::RenderPass &renderPass) +bool KRPipeline::bind(VkCommandBuffer& commandBuffer, KRCamera& camera, const KRViewport& viewport, const Matrix4& matModel, const std::vector* point_lights, const std::vector* directional_lights, const std::vector* spot_lights, const KRNode::RenderPass& renderPass) { - setUniform(Uniform::absolute_time, getContext().getAbsoluteTime()); - - int light_directional_count = 0; - //int light_point_count = 0; - //int light_spot_count = 0; - // TODO - Need to support multiple lights and more light types in forward rendering - if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_DEFERRED_GBUFFER && renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE && renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS) { - - - if (directional_lights) { - for (std::vector::const_iterator light_itr = directional_lights->begin(); light_itr != directional_lights->end(); light_itr++) { - KRDirectionalLight* directional_light = (*light_itr); - if (light_directional_count == 0) { - int cShadowBuffers = directional_light->getShadowBufferCount(); - if (hasUniform(Uniform::shadowtexture1) && cShadowBuffers > 0) { - if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 3, directional_light->getShadowTextures()[0])) { - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - } + setUniform(Uniform::absolute_time, getContext().getAbsoluteTime()); - m_pContext->getTextureManager()->_setWrapModeS(3, GL_CLAMP_TO_EDGE); - m_pContext->getTextureManager()->_setWrapModeT(3, GL_CLAMP_TO_EDGE); + int light_directional_count = 0; + //int light_point_count = 0; + //int light_spot_count = 0; + // TODO - Need to support multiple lights and more light types in forward rendering + if (renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_DEFERRED_GBUFFER && renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE && renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS) { + + + if (directional_lights) { + for (std::vector::const_iterator light_itr = directional_lights->begin(); light_itr != directional_lights->end(); light_itr++) { + KRDirectionalLight* directional_light = (*light_itr); + if (light_directional_count == 0) { + int cShadowBuffers = directional_light->getShadowBufferCount(); + if (hasUniform(Uniform::shadowtexture1) && cShadowBuffers > 0) { + if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 3, directional_light->getShadowTextures()[0])) { + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); } - if (hasUniform(Uniform::shadowtexture2) && cShadowBuffers > 1 && camera.settings.m_cShadowBuffers > 1) { - if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 4, directional_light->getShadowTextures()[1])) { - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - } - m_pContext->getTextureManager()->_setWrapModeS(4, GL_CLAMP_TO_EDGE); - m_pContext->getTextureManager()->_setWrapModeT(4, GL_CLAMP_TO_EDGE); - } - - if (hasUniform(Uniform::shadowtexture3) && cShadowBuffers > 2 && camera.settings.m_cShadowBuffers > 2) { - if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 5, directional_light->getShadowTextures()[2])) { - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - } - m_pContext->getTextureManager()->_setWrapModeS(5, GL_CLAMP_TO_EDGE); - m_pContext->getTextureManager()->_setWrapModeT(5, GL_CLAMP_TO_EDGE); - } - - Matrix4 matBias; - matBias.translate(1.0, 1.0, 1.0); - matBias.scale(0.5); - for (int iShadow = 0; iShadow < cShadowBuffers; iShadow++) { - setUniform(static_cast(static_cast(Uniform::shadow_mvp1) + iShadow), matModel * directional_light->getShadowViewports()[iShadow].getViewProjectionMatrix() * matBias); - } - - if (hasUniform(Uniform::light_direction_model_space)) { - Matrix4 inverseModelMatrix = matModel; - inverseModelMatrix.invert(); - - // Bind the light direction vector - Vector3 lightDirObject = Matrix4::Dot(inverseModelMatrix, directional_light->getWorldLightDirection()); - lightDirObject.normalize(); - setUniform(Uniform::light_direction_model_space, lightDirObject); - } + m_pContext->getTextureManager()->_setWrapModeS(3, GL_CLAMP_TO_EDGE); + m_pContext->getTextureManager()->_setWrapModeT(3, GL_CLAMP_TO_EDGE); } - light_directional_count++; - } - } + if (hasUniform(Uniform::shadowtexture2) && cShadowBuffers > 1 && camera.settings.m_cShadowBuffers > 1) { + if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 4, directional_light->getShadowTextures()[1])) { + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + } + m_pContext->getTextureManager()->_setWrapModeS(4, GL_CLAMP_TO_EDGE); + m_pContext->getTextureManager()->_setWrapModeT(4, GL_CLAMP_TO_EDGE); + } - //light_point_count = point_lights.size(); - //light_spot_count = spot_lights.size(); - } + if (hasUniform(Uniform::shadowtexture3) && cShadowBuffers > 2 && camera.settings.m_cShadowBuffers > 2) { + if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 5, directional_light->getShadowTextures()[2])) { + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + } + m_pContext->getTextureManager()->_setWrapModeS(5, GL_CLAMP_TO_EDGE); + m_pContext->getTextureManager()->_setWrapModeT(5, GL_CLAMP_TO_EDGE); + } - if(hasUniform(Uniform::camerapos_model_space)) { - Matrix4 inverseModelMatrix = matModel; - inverseModelMatrix.invert(); - - if(hasUniform(Uniform::camerapos_model_space)) { - // Transform location of camera to object space for calculation of specular halfVec - Vector3 cameraPosObject = Matrix4::Dot(inverseModelMatrix, viewport.getCameraPosition()); - setUniform(Uniform::camerapos_model_space, cameraPosObject); - } - } - - if(hasUniform(Uniform::mvp) || hasUniform(KRPipeline::Uniform::invmvp)) { - // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram - Matrix4 mvpMatrix = matModel * viewport.getViewProjectionMatrix(); - setUniform(Uniform::mvp, mvpMatrix); - - if(hasUniform(KRPipeline::Uniform::invmvp)) { - setUniform(KRPipeline::Uniform::invmvp, Matrix4::Invert(mvpMatrix)); - } - } - - if(hasUniform(KRPipeline::Uniform::view_space_model_origin) || hasUniform(Uniform::model_view_inverse_transpose) || hasUniform(KRPipeline::Uniform::model_view)) { - Matrix4 matModelView = matModel * viewport.getViewMatrix(); - setUniform(Uniform::model_view, matModelView); - - - if(hasUniform(KRPipeline::Uniform::view_space_model_origin)) { - Vector3 view_space_model_origin = Matrix4::Dot(matModelView, Vector3::Zero()); // Origin point of model space is the light source position. No perspective, so no w divide required - setUniform(Uniform::view_space_model_origin, view_space_model_origin); - } - - if(hasUniform(Uniform::model_view_inverse_transpose)) { - Matrix4 matModelViewInverseTranspose = matModelView; - matModelViewInverseTranspose.transpose(); - matModelViewInverseTranspose.invert(); - setUniform(Uniform::model_view_inverse_transpose, matModelViewInverseTranspose); - } - } - - if(hasUniform(Uniform::model_inverse_transpose)) { - Matrix4 matModelInverseTranspose = matModel; - matModelInverseTranspose.transpose(); - matModelInverseTranspose.invert(); - setUniform(Uniform::model_inverse_transpose, matModelInverseTranspose); - } - - if(hasUniform(KRPipeline::Uniform::invp)) { - setUniform(Uniform::invp, viewport.getInverseProjectionMatrix()); - } - - if(hasUniform(KRPipeline::Uniform::invmvp_no_translate)) { - Matrix4 matInvMVPNoTranslate = matModel * viewport.getViewMatrix();; - // Remove the translation - matInvMVPNoTranslate.getPointer()[3] = 0; - matInvMVPNoTranslate.getPointer()[7] = 0; - matInvMVPNoTranslate.getPointer()[11] = 0; - matInvMVPNoTranslate.getPointer()[12] = 0; - matInvMVPNoTranslate.getPointer()[13] = 0; - matInvMVPNoTranslate.getPointer()[14] = 0; - matInvMVPNoTranslate.getPointer()[15] = 1.0; - matInvMVPNoTranslate = matInvMVPNoTranslate * viewport.getProjectionMatrix(); - matInvMVPNoTranslate.invert(); - setUniform(Uniform::invmvp_no_translate, matInvMVPNoTranslate); - } - - setUniform(Uniform::model_matrix, matModel); - if(hasUniform(Uniform::projection_matrix)) { - setUniform(Uniform::projection_matrix, viewport.getProjectionMatrix()); - } - - if(hasUniform(Uniform::viewport)) { - setUniform(Uniform::viewport, Vector4::Create( - (float)0.0, - (float)0.0, - (float)viewport.getSize().x, - (float)viewport.getSize().y - ) - ); - } - - if(hasUniform(Uniform::viewport_downsample)) { - setUniform(Uniform::viewport_downsample, camera.getDownsample()); - } - - // Fog parameters - setUniform(Uniform::fog_near, camera.settings.fog_near); - setUniform(Uniform::fog_far, camera.settings.fog_far); - setUniform(Uniform::fog_density, camera.settings.fog_density); - setUniform(Uniform::fog_color, camera.settings.fog_color); - - if(hasUniform(Uniform::fog_scale)) { - setUniform(Uniform::fog_scale, 1.0f / (camera.settings.fog_far - camera.settings.fog_near)); - } - if(hasUniform(Uniform::density_premultiplied_exponential)) { - setUniform(Uniform::density_premultiplied_exponential, -camera.settings.fog_density * 1.442695f); // -fog_density / log(2) - } - if(hasUniform(Uniform::density_premultiplied_squared)) { - setUniform(Uniform::density_premultiplied_squared, (float)(-camera.settings.fog_density * camera.settings.fog_density * 1.442695)); // -fog_density * fog_density / log(2) - } - - // Sets the diffuseTexture variable to the first texture unit - setUniform(Uniform::diffusetexture, 0); - - // Sets the specularTexture variable to the second texture unit - setUniform(Uniform::speculartexture, 1); - - // Sets the normalTexture variable to the third texture unit - setUniform(Uniform::normaltexture, 2); - - // Sets the shadowTexture variable to the fourth texture unit - setUniform(Uniform::shadowtexture1, 3); - setUniform(Uniform::shadowtexture2, 4); - setUniform(Uniform::shadowtexture3, 5); - setUniform(Uniform::reflectioncubetexture, 4); - setUniform(Uniform::lightmaptexture, 5); - setUniform(Uniform::gbuffer_frame, 6); - setUniform(Uniform::gbuffer_depth, 7); // Texture unit 7 is used for reading the depth buffer in gBuffer pass #2 and in post-processing pass - setUniform(Uniform::reflectiontexture, 7); // Texture unit 7 is used for the reflection map textures in gBuffer pass #3 and when using forward rendering - setUniform(Uniform::depth_frame, 0); - setUniform(Uniform::render_frame, 1); - setUniform(Uniform::volumetric_environment_frame, 2); + Matrix4 matBias; + matBias.translate(1.0, 1.0, 1.0); + matBias.scale(0.5); + for (int iShadow = 0; iShadow < cShadowBuffers; iShadow++) { + setUniform(static_cast(static_cast(Uniform::shadow_mvp1) + iShadow), matModel * directional_light->getShadowViewports()[iShadow].getViewProjectionMatrix() * matBias); + } - for (PushConstantStageInfo& pushConstants : m_pushConstants) { - if (pushConstants.buffer) { - vkCmdPushConstants(commandBuffer, pushConstants.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, pushConstants.bufferSize, pushConstants.buffer); + if (hasUniform(Uniform::light_direction_model_space)) { + Matrix4 inverseModelMatrix = matModel; + inverseModelMatrix.invert(); + + // Bind the light direction vector + Vector3 lightDirObject = Matrix4::Dot(inverseModelMatrix, directional_light->getWorldLightDirection()); + lightDirObject.normalize(); + setUniform(Uniform::light_direction_model_space, lightDirObject); + } + } + + light_directional_count++; } } - vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline); + //light_point_count = point_lights.size(); + //light_spot_count = spot_lights.size(); + } - return true; + if (hasUniform(Uniform::camerapos_model_space)) { + Matrix4 inverseModelMatrix = matModel; + inverseModelMatrix.invert(); + + if (hasUniform(Uniform::camerapos_model_space)) { + // Transform location of camera to object space for calculation of specular halfVec + Vector3 cameraPosObject = Matrix4::Dot(inverseModelMatrix, viewport.getCameraPosition()); + setUniform(Uniform::camerapos_model_space, cameraPosObject); + } + } + + if (hasUniform(Uniform::mvp) || hasUniform(KRPipeline::Uniform::invmvp)) { + // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram + Matrix4 mvpMatrix = matModel * viewport.getViewProjectionMatrix(); + setUniform(Uniform::mvp, mvpMatrix); + + if (hasUniform(KRPipeline::Uniform::invmvp)) { + setUniform(KRPipeline::Uniform::invmvp, Matrix4::Invert(mvpMatrix)); + } + } + + if (hasUniform(KRPipeline::Uniform::view_space_model_origin) || hasUniform(Uniform::model_view_inverse_transpose) || hasUniform(KRPipeline::Uniform::model_view)) { + Matrix4 matModelView = matModel * viewport.getViewMatrix(); + setUniform(Uniform::model_view, matModelView); + + + if (hasUniform(KRPipeline::Uniform::view_space_model_origin)) { + Vector3 view_space_model_origin = Matrix4::Dot(matModelView, Vector3::Zero()); // Origin point of model space is the light source position. No perspective, so no w divide required + setUniform(Uniform::view_space_model_origin, view_space_model_origin); + } + + if (hasUniform(Uniform::model_view_inverse_transpose)) { + Matrix4 matModelViewInverseTranspose = matModelView; + matModelViewInverseTranspose.transpose(); + matModelViewInverseTranspose.invert(); + setUniform(Uniform::model_view_inverse_transpose, matModelViewInverseTranspose); + } + } + + if (hasUniform(Uniform::model_inverse_transpose)) { + Matrix4 matModelInverseTranspose = matModel; + matModelInverseTranspose.transpose(); + matModelInverseTranspose.invert(); + setUniform(Uniform::model_inverse_transpose, matModelInverseTranspose); + } + + if (hasUniform(KRPipeline::Uniform::invp)) { + setUniform(Uniform::invp, viewport.getInverseProjectionMatrix()); + } + + if (hasUniform(KRPipeline::Uniform::invmvp_no_translate)) { + Matrix4 matInvMVPNoTranslate = matModel * viewport.getViewMatrix();; + // Remove the translation + matInvMVPNoTranslate.getPointer()[3] = 0; + matInvMVPNoTranslate.getPointer()[7] = 0; + matInvMVPNoTranslate.getPointer()[11] = 0; + matInvMVPNoTranslate.getPointer()[12] = 0; + matInvMVPNoTranslate.getPointer()[13] = 0; + matInvMVPNoTranslate.getPointer()[14] = 0; + matInvMVPNoTranslate.getPointer()[15] = 1.0; + matInvMVPNoTranslate = matInvMVPNoTranslate * viewport.getProjectionMatrix(); + matInvMVPNoTranslate.invert(); + setUniform(Uniform::invmvp_no_translate, matInvMVPNoTranslate); + } + + setUniform(Uniform::model_matrix, matModel); + if (hasUniform(Uniform::projection_matrix)) { + setUniform(Uniform::projection_matrix, viewport.getProjectionMatrix()); + } + + if (hasUniform(Uniform::viewport)) { + setUniform(Uniform::viewport, Vector4::Create( + (float)0.0, + (float)0.0, + (float)viewport.getSize().x, + (float)viewport.getSize().y + ) + ); + } + + if (hasUniform(Uniform::viewport_downsample)) { + setUniform(Uniform::viewport_downsample, camera.getDownsample()); + } + + // Fog parameters + setUniform(Uniform::fog_near, camera.settings.fog_near); + setUniform(Uniform::fog_far, camera.settings.fog_far); + setUniform(Uniform::fog_density, camera.settings.fog_density); + setUniform(Uniform::fog_color, camera.settings.fog_color); + + if (hasUniform(Uniform::fog_scale)) { + setUniform(Uniform::fog_scale, 1.0f / (camera.settings.fog_far - camera.settings.fog_near)); + } + if (hasUniform(Uniform::density_premultiplied_exponential)) { + setUniform(Uniform::density_premultiplied_exponential, -camera.settings.fog_density * 1.442695f); // -fog_density / log(2) + } + if (hasUniform(Uniform::density_premultiplied_squared)) { + setUniform(Uniform::density_premultiplied_squared, (float)(-camera.settings.fog_density * camera.settings.fog_density * 1.442695)); // -fog_density * fog_density / log(2) + } + + // Sets the diffuseTexture variable to the first texture unit + setUniform(Uniform::diffusetexture, 0); + + // Sets the specularTexture variable to the second texture unit + setUniform(Uniform::speculartexture, 1); + + // Sets the normalTexture variable to the third texture unit + setUniform(Uniform::normaltexture, 2); + + // Sets the shadowTexture variable to the fourth texture unit + setUniform(Uniform::shadowtexture1, 3); + setUniform(Uniform::shadowtexture2, 4); + setUniform(Uniform::shadowtexture3, 5); + setUniform(Uniform::reflectioncubetexture, 4); + setUniform(Uniform::lightmaptexture, 5); + setUniform(Uniform::gbuffer_frame, 6); + setUniform(Uniform::gbuffer_depth, 7); // Texture unit 7 is used for reading the depth buffer in gBuffer pass #2 and in post-processing pass + setUniform(Uniform::reflectiontexture, 7); // Texture unit 7 is used for the reflection map textures in gBuffer pass #3 and when using forward rendering + setUniform(Uniform::depth_frame, 0); + setUniform(Uniform::render_frame, 1); + setUniform(Uniform::volumetric_environment_frame, 2); + + for (PushConstantStageInfo& pushConstants : m_pushConstants) { + if (pushConstants.buffer) { + vkCmdPushConstants(commandBuffer, pushConstants.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, pushConstants.bufferSize, pushConstants.buffer); + } + } + + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline); + + return true; } -const char *KRPipeline::getKey() const { - return m_szKey; +const char* KRPipeline::getKey() const +{ + return m_szKey; } VkPipeline& KRPipeline::getPipeline() diff --git a/kraken/KRPipeline.h b/kraken/KRPipeline.h index 0df376a..ed385a4 100644 --- a/kraken/KRPipeline.h +++ b/kraken/KRPipeline.h @@ -45,14 +45,16 @@ class KRRenderPass; enum class ModelFormat : __uint8_t; struct SpvReflectShaderModule; -enum class CullMode : uint32_t { +enum class CullMode : uint32_t +{ kCullBack = 0, kCullFront, kCullNone }; // Note: RasterMode is likely to be refactored later to a bitfield -enum class RasterMode : uint32_t { +enum class RasterMode : uint32_t +{ kOpaque = 0, /* kOpaque is equivalent to: @@ -173,7 +175,8 @@ enum class RasterMode : uint32_t { */ }; -class PipelineInfo { +class PipelineInfo +{ public: const std::string* shader_name; KRCamera* pCamera; @@ -204,128 +207,130 @@ public: KRNode::RenderPass renderPass; }; -class KRPipeline : public KRContextObject { +class KRPipeline : public KRContextObject +{ public: - KRPipeline(KRContext& context, KRSurface& surface, const PipelineInfo& info, const char* szKey, const std::vector& shaders, uint32_t vertexAttributes, ModelFormat modelFormat); - virtual ~KRPipeline(); - const char *getKey() const; - - bool bind(VkCommandBuffer& commandBuffer, KRCamera &camera, const KRViewport &viewport, const Matrix4 &matModel, const std::vector *point_lights, const std::vector *directional_lights, const std::vector*spot_lights, const KRNode::RenderPass &renderPass); + KRPipeline(KRContext& context, KRSurface& surface, const PipelineInfo& info, const char* szKey, const std::vector& shaders, uint32_t vertexAttributes, ModelFormat modelFormat); + virtual ~KRPipeline(); + const char* getKey() const; - enum class Uniform : uint8_t { - material_ambient = 0, - material_diffuse, - material_specular, - material_reflection, - material_alpha, - material_shininess, - light_position, - light_direction_model_space, - light_direction_view_space, - light_color, - light_decay_start, - light_cutoff, - light_intensity, - flare_size, - view_space_model_origin, - mvp, - invp, - invmvp, - invmvp_no_translate, - model_view_inverse_transpose, - model_inverse_transpose, - model_view, - model_matrix, - projection_matrix, - camerapos_model_space, - viewport, - viewport_downsample, - diffusetexture, - speculartexture, - reflectioncubetexture, - reflectiontexture, - normaltexture, - diffusetexture_scale, - speculartexture_scale, - reflectiontexture_scale, - normaltexture_scale, - ambienttexture_scale, - diffusetexture_offset, - speculartexture_offset, - reflectiontexture_offset, - normaltexture_offset, - ambienttexture_offset, - shadow_mvp1, - shadow_mvp2, - shadow_mvp3, - shadowtexture1, - shadowtexture2, - shadowtexture3, - lightmaptexture, - gbuffer_frame, - gbuffer_depth, - depth_frame, - volumetric_environment_frame, - render_frame, - absolute_time, - fog_near, - fog_far, - fog_density, - fog_color, - fog_scale, - density_premultiplied_exponential, - density_premultiplied_squared, - slice_depth_scale, - particle_origin, - bone_transforms, - rim_color, - rim_power, - fade_color, - NUM_UNIFORMS - }; + bool bind(VkCommandBuffer& commandBuffer, KRCamera& camera, const KRViewport& viewport, const Matrix4& matModel, const std::vector* point_lights, const std::vector* directional_lights, const std::vector* spot_lights, const KRNode::RenderPass& renderPass); - static const size_t kUniformCount = static_cast(Uniform::NUM_UNIFORMS); + enum class Uniform : uint8_t + { + material_ambient = 0, + material_diffuse, + material_specular, + material_reflection, + material_alpha, + material_shininess, + light_position, + light_direction_model_space, + light_direction_view_space, + light_color, + light_decay_start, + light_cutoff, + light_intensity, + flare_size, + view_space_model_origin, + mvp, + invp, + invmvp, + invmvp_no_translate, + model_view_inverse_transpose, + model_inverse_transpose, + model_view, + model_matrix, + projection_matrix, + camerapos_model_space, + viewport, + viewport_downsample, + diffusetexture, + speculartexture, + reflectioncubetexture, + reflectiontexture, + normaltexture, + diffusetexture_scale, + speculartexture_scale, + reflectiontexture_scale, + normaltexture_scale, + ambienttexture_scale, + diffusetexture_offset, + speculartexture_offset, + reflectiontexture_offset, + normaltexture_offset, + ambienttexture_offset, + shadow_mvp1, + shadow_mvp2, + shadow_mvp3, + shadowtexture1, + shadowtexture2, + shadowtexture3, + lightmaptexture, + gbuffer_frame, + gbuffer_depth, + depth_frame, + volumetric_environment_frame, + render_frame, + absolute_time, + fog_near, + fog_far, + fog_density, + fog_color, + fog_scale, + density_premultiplied_exponential, + density_premultiplied_squared, + slice_depth_scale, + particle_origin, + bone_transforms, + rim_color, + rim_power, + fade_color, + NUM_UNIFORMS + }; - enum class ShaderStages : uint8_t - { - vertex = 0, - fragment, - geometry, - compute, - shaderStageCount - }; + static const size_t kUniformCount = static_cast(Uniform::NUM_UNIFORMS); - static const size_t kShaderStageCount = static_cast(ShaderStages::shaderStageCount); - - bool hasUniform(Uniform location) const; - void setUniform(Uniform location, float value); - void setUniform(Uniform location, int value); - void setUniform(Uniform location, const Vector2 &value); - void setUniform(Uniform location, const Vector3 &value); - void setUniform(Uniform location, const Vector4 &value); - void setUniform(Uniform location, const Matrix4 &value); - void setUniform(Uniform location, const Matrix4* value, const size_t count); + enum class ShaderStages : uint8_t + { + vertex = 0, + fragment, + geometry, + compute, + shaderStageCount + }; + + static const size_t kShaderStageCount = static_cast(ShaderStages::shaderStageCount); + + bool hasUniform(Uniform location) const; + void setUniform(Uniform location, float value); + void setUniform(Uniform location, int value); + void setUniform(Uniform location, const Vector2& value); + void setUniform(Uniform location, const Vector3& value); + void setUniform(Uniform location, const Vector4& value); + void setUniform(Uniform location, const Matrix4& value); + void setUniform(Uniform location, const Matrix4* value, const size_t count); + + VkPipeline& getPipeline(); - VkPipeline& getPipeline(); - private: - static const char* KRENGINE_UNIFORM_NAMES[]; + static const char* KRENGINE_UNIFORM_NAMES[]; - struct PushConstantStageInfo - { - int offset[kUniformCount]; - __uint8_t size[kUniformCount]; - uint8_t* buffer; - int bufferSize; - VkPipelineLayout layout; - }; - PushConstantStageInfo m_pushConstants[static_cast(ShaderStages::shaderStageCount)]; + struct PushConstantStageInfo + { + int offset[kUniformCount]; + __uint8_t size[kUniformCount]; + uint8_t* buffer; + int bufferSize; + VkPipelineLayout layout; + }; + PushConstantStageInfo m_pushConstants[static_cast(ShaderStages::shaderStageCount)]; - char m_szKey[256]; + char m_szKey[256]; - VkPipelineLayout m_pipelineLayout; - VkPipeline m_graphicsPipeline; + VkPipelineLayout m_pipelineLayout; + VkPipeline m_graphicsPipeline; - void initPushConstantStage(ShaderStages stage, const SpvReflectShaderModule* reflection); + void initPushConstantStage(ShaderStages stage, const SpvReflectShaderModule* reflection); }; diff --git a/kraken/KRPipelineManager.cpp b/kraken/KRPipelineManager.cpp index 1f9fc93..2bb3eb0 100644 --- a/kraken/KRPipelineManager.cpp +++ b/kraken/KRPipelineManager.cpp @@ -44,20 +44,21 @@ using namespace std; -KRPipelineManager::KRPipelineManager(KRContext &context) : KRContextObject(context) { - m_active_pipeline = NULL; +KRPipelineManager::KRPipelineManager(KRContext& context) : KRContextObject(context) +{ + m_active_pipeline = NULL; #ifndef ANDROID - bool success = glslang::InitializeProcess(); - if (success) { - printf("GLSLang Initialized.\n"); - } - else { - printf("Failed to initialize GLSLang.\n"); - } + bool success = glslang::InitializeProcess(); + if (success) { + printf("GLSLang Initialized.\n"); + } else { + printf("Failed to initialize GLSLang.\n"); + } #endif // ANDROID } -KRPipelineManager::~KRPipelineManager() { +KRPipelineManager::~KRPipelineManager() +{ #ifndef ANDROID glslang::FinalizeProcess(); #endif // ANDROID @@ -92,7 +93,7 @@ KRPipeline* KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInf /* // TODO - Vulkan Refactoring, merge with Vulkan version KRPipeline *KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInfo &info) { - + int iShadowQuality = 0; // FINDME - HACK - Placeholder code, need to iterate through lights and dynamically build shader @@ -103,7 +104,7 @@ KRPipeline *KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInf if (info.directional_lights) { light_directional_count = (int)info.directional_lights->size(); } - + if (info.point_lights) { light_point_count = (int)info.point_lights->size(); } @@ -115,13 +116,13 @@ KRPipeline *KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInf iShadowQuality = directional_light->getShadowBufferCount(); } } - + if(iShadowQuality > info.pCamera->settings.m_cShadowBuffers) { iShadowQuality = info.pCamera->settings.m_cShadowBuffers; } - + bool bFadeColorEnabled = info.pCamera->getFadeColor().w >= 0.0f; - + std::pair > key; key.first = *info.shader_name; key.second.push_back(light_directional_count); @@ -171,10 +172,10 @@ KRPipeline *KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInf key.second.push_back((int)(info.pCamera->settings.vignette_falloff * 1000.0f)); key.second.push_back(info.bRimColor); key.second.push_back(bFadeColorEnabled); - + KRPipeline *pPipeline = m_pipelines[key]; - - + + if(pPipeline == NULL) { if(m_pipelines.size() > KRContext::KRENGINE_MAX_PIPELINE_HANDLES) { // Keep the size of the pipeline cache reasonable @@ -183,7 +184,7 @@ KRPipeline *KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInf m_pipelines.erase(itr); KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Swapping pipelines...\n"); } - + stringstream stream; stream.precision(std::numeric_limits::digits10); @@ -194,37 +195,37 @@ KRPipeline *KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInf stream << "\n#define mediump"; stream << "\n#define highp"; #endif - + stream << "\n#define LIGHT_DIRECTIONAL_COUNT " << light_directional_count; stream << "\n#define LIGHT_POINT_COUNT " << light_point_count; stream << "\n#define LIGHT_SPOT_COUNT " << light_spot_count; stream << "\n#define BONE_COUNT " << info.bone_count; - + stream << "\n#define HAS_DIFFUSE_MAP " << (info.bDiffuseMap ? "1" : "0"); stream << "\n#define HAS_DIFFUSE_MAP_SCALE " << (info.bDiffuseMapScale ? "1" : "0"); stream << "\n#define HAS_DIFFUSE_MAP_OFFSET " << (info.bDiffuseMapOffset ? "1" : "0"); - + stream << "\n#define HAS_SPEC_MAP " << (info.bSpecMap ? "1" : "0"); stream << "\n#define HAS_SPEC_MAP_SCALE " << (info.bSpecMapScale ? "1" : "0"); stream << "\n#define HAS_SPEC_MAP_OFFSET " << (info.bSpecMapOffset ? "1" : "0"); - + stream << "\n#define HAS_NORMAL_MAP " << (info.bNormalMap ? "1" : "0"); stream << "\n#define HAS_NORMAL_MAP_SCALE " << (info.bNormalMapScale ? "1" : "0"); stream << "\n#define HAS_NORMAL_MAP_OFFSET " << (info.bNormalMapOffset ? "1" : "0"); - + stream << "\n#define HAS_REFLECTION_MAP " << (info.bReflectionMap ? "1" : "0"); stream << "\n#define HAS_REFLECTION_MAP_SCALE " << (info.bReflectionMapScale ? "1" : "0"); stream << "\n#define HAS_REFLECTION_MAP_OFFSET " << (info.bReflectionMapOffset ? "1" : "0"); - + stream << "\n#define HAS_LIGHT_MAP " << (info.bLightMap ? "1" : "0"); stream << "\n#define HAS_REFLECTION_CUBE_MAP " << (info.bReflectionCubeMap ? "1" : "0"); - + stream << "\n#define ALPHA_TEST " << (info.bAlphaTest ? "1" : "0"); stream << "\n#define ALPHA_BLEND " << ((info.rasterMode == RasterMode::kAlphaBlend || info.rasterMode == RasterMode::kAlphaBlendNoTest || info.rasterMode == RasterMode::kAdditive || info.rasterMode == RasterMode::kAdditiveNoTest) ? "1" : "0"); - + stream << "\n#define ENABLE_PER_PIXEL " << (info.pCamera->settings.bEnablePerPixel ? "1" : "0"); stream << "\n#define DEBUG_PSSM " << (info.pCamera->settings.bDebugPSSM ? "1" : "0"); stream << "\n#define SHADOW_QUALITY " << iShadowQuality; @@ -253,12 +254,12 @@ KRPipeline *KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInf stream << "\n#define ENABLE_FLASH " << (info.pCamera->settings.bEnableFlash ? "1" : "0"); stream << "\n#define ENABLE_VIGNETTE " << (info.pCamera->settings.bEnableVignette ? "1" : "0"); stream << "\n#define VOLUMETRIC_ENVIRONMENT_DOWNSAMPLED " << (info.pCamera->settings.volumetric_environment_enable && info.pCamera->settings.volumetric_environment_downsample != 0 ? "1" : "0"); - - + + stream.setf(ios::fixed,ios::floatfield); - + stream.precision(std::numeric_limits::digits10); - + stream << "\n#define DOF_DEPTH " << info.pCamera->settings.dof_depth; stream << "\n#define DOF_FALLOFF " << info.pCamera->settings.dof_falloff; stream << "\n#define FLASH_DEPTH " << info.pCamera->settings.flash_depth; @@ -266,26 +267,26 @@ KRPipeline *KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInf stream << "\n#define FLASH_INTENSITY " << info.pCamera->settings.flash_intensity; stream << "\n#define VIGNETTE_RADIUS " << info.pCamera->settings.vignette_radius; stream << "\n#define VIGNETTE_FALLOFF " << info.pCamera->settings.vignette_falloff; - + stream << "\n"; std::string options = stream.str(); KRSourceManager *sourceManager = m_pContext->getSourceManager(); KRSource *vertSource = sourceManager->get(info.shader_name->c_str(), "vert"); KRSource *fragSource = sourceManager->get(info.shader_name->c_str(), "frag"); - + if(vertSource == nullptr) { KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Vertex Shader Missing: %s", info.shader_name->c_str()); } if(fragSource == nullptr) { KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Fragment Shader Missing: %s", info.shader_name->c_str()); } - + Vector4 fade_color = info.pCamera->getFadeColor(); - + char szKey[256]; sprintf(szKey, "%i_%i_%i_%i_%i_%i_%i_%i_%i_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s_%i_%d_%d_%f_%f_%f_%f_%f_%f_%f_%f_%f_%f_%f", (int)info.rasterMode, (int)info.cullMode, (int)info.modelFormat, (int)info.vertexAttributes, light_directional_count, light_point_count, light_spot_count, info.bone_count, info.pCamera->settings.fog_type, info.pCamera->settings.bEnablePerPixel, info.bAlphaTest, info.bDiffuseMap, info.bNormalMap, info.bSpecMap, info.bReflectionMap, info.bReflectionCubeMap, info.pCamera->settings.bDebugPSSM, iShadowQuality, info.pCamera->settings.bEnableAmbient, info.pCamera->settings.bEnableDiffuse, info.pCamera->settings.bEnableSpecular, info.bLightMap, info.bDiffuseMapScale, info.bSpecMapScale, info.bReflectionMapScale, info.bNormalMapScale, info.bDiffuseMapOffset, info.bSpecMapOffset, info.bReflectionMapOffset, info.bNormalMapOffset, info.pCamera->settings.volumetric_environment_enable && info.pCamera->settings.volumetric_environment_downsample != 0, info.renderPass, info.shader_name->c_str(), info.pCamera->settings.dof_quality, info.pCamera->settings.bEnableFlash, info.pCamera->settings.bEnableVignette, info.pCamera->settings.dof_depth, info.pCamera->settings.dof_falloff, info.pCamera->settings.flash_depth, info.pCamera->settings.flash_falloff, info.pCamera->settings.flash_intensity, info.pCamera->settings.vignette_radius, info.pCamera->settings.vignette_falloff, fade_color.x, fade_color.y, fade_color.z, fade_color.w); - + pPipeline = new KRPipeline(getContext(), szKey, options, vertSource->getData()->getString(), fragSource->getData()->getString()); m_pipelines[key] = pPipeline; @@ -294,8 +295,9 @@ KRPipeline *KRPipelineManager::getPipeline(KRSurface& surface, const PipelineInf } */ -size_t KRPipelineManager::getPipelineHandlesUsed() { - return m_pipelines.size(); +size_t KRPipelineManager::getPipelineHandlesUsed() +{ + return m_pipelines.size(); } diff --git a/kraken/KRPipelineManager.h b/kraken/KRPipelineManager.h index 60df189..c4b0854 100644 --- a/kraken/KRPipelineManager.h +++ b/kraken/KRPipelineManager.h @@ -48,18 +48,19 @@ class KRPipeline; class PipelineInfo; class KRCamera; -class KRPipelineManager : public KRContextObject { +class KRPipelineManager : public KRContextObject +{ public: - KRPipelineManager(KRContext &context); - virtual ~KRPipelineManager(); - KRPipeline* get(const char* szKey); - - KRPipeline* getPipeline(KRSurface& surface, const PipelineInfo& info); + KRPipelineManager(KRContext& context); + virtual ~KRPipelineManager(); + KRPipeline* get(const char* szKey); - size_t getPipelineHandlesUsed(); - - KRPipeline *m_active_pipeline; + KRPipeline* getPipeline(KRSurface& surface, const PipelineInfo& info); + + size_t getPipelineHandlesUsed(); + + KRPipeline* m_active_pipeline; private: typedef std::map >, KRPipeline*> PipelineMap; diff --git a/kraken/KRPointLight.cpp b/kraken/KRPointLight.cpp index 3ccfffe..e9eeec3 100755 --- a/kraken/KRPointLight.cpp +++ b/kraken/KRPointLight.cpp @@ -42,199 +42,204 @@ void KRPointLight::InitNodeInfo(KrNodeInfo* nodeInfo) // No additional members } -KRPointLight::KRPointLight(KRScene &scene, std::string name) : KRLight(scene, name) +KRPointLight::KRPointLight(KRScene& scene, std::string name) : KRLight(scene, name) { - m_sphereVertices = NULL; - m_cVertices = 0; + m_sphereVertices = NULL; + m_cVertices = 0; } KRPointLight::~KRPointLight() { - if(m_sphereVertices) { - delete m_sphereVertices; - m_cVertices = 0; - } + if (m_sphereVertices) { + delete m_sphereVertices; + m_cVertices = 0; + } } -std::string KRPointLight::getElementName() { - return "point_light"; +std::string KRPointLight::getElementName() +{ + return "point_light"; } -AABB KRPointLight::getBounds() { - float influence_radius = m_decayStart - sqrt(m_intensity * 0.01f) / sqrt(KRLIGHT_MIN_INFLUENCE); - if(influence_radius < m_flareOcclusionSize) { - influence_radius = m_flareOcclusionSize; - } - return AABB::Create(Vector3::Create(-influence_radius), Vector3::Create(influence_radius), getModelMatrix()); +AABB KRPointLight::getBounds() +{ + float influence_radius = m_decayStart - sqrt(m_intensity * 0.01f) / sqrt(KRLIGHT_MIN_INFLUENCE); + if (influence_radius < m_flareOcclusionSize) { + influence_radius = m_flareOcclusionSize; + } + return AABB::Create(Vector3::Create(-influence_radius), Vector3::Create(influence_radius), getModelMatrix()); } void KRPointLight::render(RenderInfo& ri) { - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRLight::render(ri); - - bool bVisualize = ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && ri.camera->settings.bShowDeferred; - - if(ri.renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS || bVisualize) { - // Lights are rendered on the second pass of the deferred renderer - - std::vector this_light; - this_light.push_back(this); + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - Vector3 light_position = getLocalTranslation(); - - float influence_radius = m_decayStart - sqrt(m_intensity * 0.01f) / sqrt(KRLIGHT_MIN_INFLUENCE); - - Matrix4 sphereModelMatrix = Matrix4(); - sphereModelMatrix.scale(influence_radius); - sphereModelMatrix.translate(light_position.x, light_position.y, light_position.z); + KRLight::render(ri); - if(ri.viewport.visible(getBounds())) { // Cull out any lights not within the view frustrum + bool bVisualize = ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && ri.camera->settings.bShowDeferred; - Vector3 view_light_position = Matrix4::Dot(ri.viewport.getViewMatrix(), light_position); - - bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + ri.camera->settings.getPerspectiveNearZ()) * (influence_radius + ri.camera->settings.getPerspectiveNearZ()); - - std::string shader_name(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point")); - PipelineInfo info{}; - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &this_light; - info.renderPass = ri.renderPass; - if (bInsideLight) { - info.rasterMode = bVisualize ? RasterMode::kAdditiveNoTest : RasterMode::kAlphaBlendNoTest; - } - else { - info.rasterMode = bVisualize ? RasterMode::kAdditive : RasterMode::kAlphaBlend; - } - info.vertexAttributes = bInsideLight ? m_pContext->getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES.getVertexAttributes() : 1 << KRMesh::KRENGINE_ATTRIB_VERTEX; - info.modelFormat = bInsideLight ? ModelFormat::KRENGINE_MODEL_FORMAT_STRIP : ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; + if (ri.renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS || bVisualize) { + // Lights are rendered on the second pass of the deferred renderer - KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->setUniform(KRPipeline::Uniform::light_color, m_color); - pShader->setUniform(KRPipeline::Uniform::light_intensity, m_intensity * 0.01f); - pShader->setUniform(KRPipeline::Uniform::light_decay_start, getDecayStart()); - pShader->setUniform(KRPipeline::Uniform::light_cutoff, KRLIGHT_MIN_INFLUENCE); - pShader->setUniform(KRPipeline::Uniform::light_position, light_position); - pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &this_light, nullptr, nullptr, ri.renderPass); - - if(bInsideLight) { - // Render a full screen quad - m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES, 1.0f); - vkCmdDraw(ri.commandBuffer, 4, 1, 0, 0); - } else { - // Render sphere of light's influence - generateMesh(); - - GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, m_sphereVertices)); + std::vector this_light; + this_light.push_back(this); - vkCmdDraw(ri.commandBuffer, m_cVertices, 1, 0, 0); - } + Vector3 light_position = getLocalTranslation(); + + float influence_radius = m_decayStart - sqrt(m_intensity * 0.01f) / sqrt(KRLIGHT_MIN_INFLUENCE); + + Matrix4 sphereModelMatrix = Matrix4(); + sphereModelMatrix.scale(influence_radius); + sphereModelMatrix.translate(light_position.x, light_position.y, light_position.z); + + if (ri.viewport.visible(getBounds())) { // Cull out any lights not within the view frustrum + + Vector3 view_light_position = Matrix4::Dot(ri.viewport.getViewMatrix(), light_position); + + bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + ri.camera->settings.getPerspectiveNearZ()) * (influence_radius + ri.camera->settings.getPerspectiveNearZ()); + + std::string shader_name(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point")); + PipelineInfo info{}; + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &this_light; + info.renderPass = ri.renderPass; + if (bInsideLight) { + info.rasterMode = bVisualize ? RasterMode::kAdditiveNoTest : RasterMode::kAlphaBlendNoTest; + } else { + info.rasterMode = bVisualize ? RasterMode::kAdditive : RasterMode::kAlphaBlend; + } + info.vertexAttributes = bInsideLight ? m_pContext->getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES.getVertexAttributes() : 1 << KRMesh::KRENGINE_ATTRIB_VERTEX; + info.modelFormat = bInsideLight ? ModelFormat::KRENGINE_MODEL_FORMAT_STRIP : ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; + + KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + pShader->setUniform(KRPipeline::Uniform::light_color, m_color); + pShader->setUniform(KRPipeline::Uniform::light_intensity, m_intensity * 0.01f); + pShader->setUniform(KRPipeline::Uniform::light_decay_start, getDecayStart()); + pShader->setUniform(KRPipeline::Uniform::light_cutoff, KRLIGHT_MIN_INFLUENCE); + pShader->setUniform(KRPipeline::Uniform::light_position, light_position); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &this_light, nullptr, nullptr, ri.renderPass); + + if (bInsideLight) { + // Render a full screen quad + m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES, 1.0f); + vkCmdDraw(ri.commandBuffer, 4, 1, 0, 0); + } else { + // Render sphere of light's influence + generateMesh(); + + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, m_sphereVertices)); + + vkCmdDraw(ri.commandBuffer, m_cVertices, 1, 0, 0); + } - } } + } } -void KRPointLight::generateMesh() { - // Create a triangular facet approximation to a sphere - // Based on algorithm from Paul Bourke: http://paulbourke.net/miscellaneous/sphere_cylinder/ - - int iterations = 3; - int facet_count = (int)(pow(4, iterations) * 8); - - if(m_cVertices != facet_count * 3) { - if(m_sphereVertices) { - free(m_sphereVertices); - m_sphereVertices = NULL; - } - - m_cVertices = facet_count * 3; +void KRPointLight::generateMesh() +{ + // Create a triangular facet approximation to a sphere + // Based on algorithm from Paul Bourke: http://paulbourke.net/miscellaneous/sphere_cylinder/ - - class Facet3 { - public: - Facet3() { - - } - ~Facet3() { - - } - Vector3 p1; - Vector3 p2; - Vector3 p3; - }; - - std::vector f = std::vector(facet_count); - - int i,it; - float a; - Vector3 p[6] = { - Vector3::Create(0,0,1), - Vector3::Create(0,0,-1), - Vector3::Create(-1,-1,0), - Vector3::Create(1,-1,0), - Vector3::Create(1,1,0), - Vector3::Create(-1,1,0) - }; + int iterations = 3; + int facet_count = (int)(pow(4, iterations) * 8); - Vector3 pa,pb,pc; - int nt = 0,ntold; - - /* Create the level 0 object */ - a = 1.0f / sqrtf(2.0f); - for (i=0;i<6;i++) { - p[i].x *= a; - p[i].y *= a; - } - f[0].p1 = p[0]; f[0].p2 = p[3]; f[0].p3 = p[4]; - f[1].p1 = p[0]; f[1].p2 = p[4]; f[1].p3 = p[5]; - f[2].p1 = p[0]; f[2].p2 = p[5]; f[2].p3 = p[2]; - f[3].p1 = p[0]; f[3].p2 = p[2]; f[3].p3 = p[3]; - f[4].p1 = p[1]; f[4].p2 = p[4]; f[4].p3 = p[3]; - f[5].p1 = p[1]; f[5].p2 = p[5]; f[5].p3 = p[4]; - f[6].p1 = p[1]; f[6].p2 = p[2]; f[6].p3 = p[5]; - f[7].p1 = p[1]; f[7].p2 = p[3]; f[7].p3 = p[2]; - nt = 8; - - /* Bisect each edge and move to the surface of a unit sphere */ - for (it=0;it f = std::vector(facet_count); + + int i, it; + float a; + Vector3 p[6] = { + Vector3::Create(0,0,1), + Vector3::Create(0,0,-1), + Vector3::Create(-1,-1,0), + Vector3::Create(1,-1,0), + Vector3::Create(1,1,0), + Vector3::Create(-1,1,0) + }; + + Vector3 pa, pb, pc; + int nt = 0, ntold; + + /* Create the level 0 object */ + a = 1.0f / sqrtf(2.0f); + for (i = 0; i < 6; i++) { + p[i].x *= a; + p[i].y *= a; + } + f[0].p1 = p[0]; f[0].p2 = p[3]; f[0].p3 = p[4]; + f[1].p1 = p[0]; f[1].p2 = p[4]; f[1].p3 = p[5]; + f[2].p1 = p[0]; f[2].p2 = p[5]; f[2].p3 = p[2]; + f[3].p1 = p[0]; f[3].p2 = p[2]; f[3].p3 = p[3]; + f[4].p1 = p[1]; f[4].p2 = p[4]; f[4].p3 = p[3]; + f[5].p1 = p[1]; f[5].p2 = p[5]; f[5].p3 = p[4]; + f[6].p1 = p[1]; f[6].p2 = p[2]; f[6].p3 = p[5]; + f[7].p1 = p[1]; f[7].p2 = p[3]; f[7].p3 = p[2]; + nt = 8; + + /* Bisect each edge and move to the surface of a unit sphere */ + for (it = 0; it < iterations; it++) { + ntold = nt; + for (i = 0; i < ntold; i++) { + pa.x = (f[i].p1.x + f[i].p2.x) / 2; + pa.y = (f[i].p1.y + f[i].p2.y) / 2; + pa.z = (f[i].p1.z + f[i].p2.z) / 2; + pb.x = (f[i].p2.x + f[i].p3.x) / 2; + pb.y = (f[i].p2.y + f[i].p3.y) / 2; + pb.z = (f[i].p2.z + f[i].p3.z) / 2; + pc.x = (f[i].p3.x + f[i].p1.x) / 2; + pc.y = (f[i].p3.y + f[i].p1.y) / 2; + pc.z = (f[i].p3.z + f[i].p1.z) / 2; + pa.normalize(); + pb.normalize(); + pc.normalize(); + f[nt].p1 = f[i].p1; f[nt].p2 = pa; f[nt].p3 = pc; nt++; + f[nt].p1 = pa; f[nt].p2 = f[i].p2; f[nt].p3 = pb; nt++; + f[nt].p1 = pb; f[nt].p2 = f[i].p3; f[nt].p3 = pc; nt++; + f[i].p1 = pa; + f[i].p2 = pb; + f[i].p3 = pc; + } + } + + m_sphereVertices = (float*)malloc(sizeof(float) * m_cVertices * 3); + assert(m_sphereVertices != NULL); + float* pDest = m_sphereVertices; + for (int facet_index = 0; facet_index < facet_count; facet_index++) { + *pDest++ = f[facet_index].p1.x; + *pDest++ = f[facet_index].p1.y; + *pDest++ = f[facet_index].p1.z; + *pDest++ = f[facet_index].p2.x; + *pDest++ = f[facet_index].p2.y; + *pDest++ = f[facet_index].p2.z; + *pDest++ = f[facet_index].p3.x; + *pDest++ = f[facet_index].p3.y; + *pDest++ = f[facet_index].p3.z; + } + } } diff --git a/kraken/KRPointLight.h b/kraken/KRPointLight.h index 6fc7226..541e05f 100755 --- a/kraken/KRPointLight.h +++ b/kraken/KRPointLight.h @@ -33,21 +33,21 @@ #include "KRLight.h" -class KRPointLight : public KRLight { - +class KRPointLight : public KRLight +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); - KRPointLight(KRScene &scene, std::string name); - virtual ~KRPointLight(); - - virtual std::string getElementName(); - virtual AABB getBounds(); + static void InitNodeInfo(KrNodeInfo* nodeInfo); + KRPointLight(KRScene& scene, std::string name); + virtual ~KRPointLight(); + + virtual std::string getElementName(); + virtual AABB getBounds(); + + virtual void render(RenderInfo& ri); - virtual void render(RenderInfo& ri); - private: - void generateMesh(); - - float *m_sphereVertices; - int m_cVertices; + void generateMesh(); + + float* m_sphereVertices; + int m_cVertices; }; diff --git a/kraken/KRPresentationThread.cpp b/kraken/KRPresentationThread.cpp index 4aa19f6..a935baa 100644 --- a/kraken/KRPresentationThread.cpp +++ b/kraken/KRPresentationThread.cpp @@ -71,8 +71,7 @@ void KRPresentationThread::run() std::chrono::microseconds sleep_duration(15000); m_activeState = PresentThreadState::run; - while (m_requestedState != PresentThreadRequest::stop) - { + while (m_requestedState != PresentThreadRequest::stop) { switch (m_activeState) { case PresentThreadState::pause: case PresentThreadState::stop: @@ -103,7 +102,7 @@ void KRPresentationThread::renderFrame() unordered_map>& surfaces = m_pContext->getSurfaceManager()->getSurfaces(); KRSceneManager* sceneManager = m_pContext->getSceneManager(); - KRScene *scene = sceneManager->getFirstScene(); + KRScene* scene = sceneManager->getFirstScene(); for (auto surfaceItr = surfaces.begin(); surfaceItr != surfaces.end(); surfaceItr++) { KRSurface& surface = *(*surfaceItr).second; diff --git a/kraken/KRRenderPass.cpp b/kraken/KRRenderPass.cpp index f126a11..a61fd64 100644 --- a/kraken/KRRenderPass.cpp +++ b/kraken/KRRenderPass.cpp @@ -35,7 +35,7 @@ KRRenderPass::KRRenderPass(KRContext& context) : KRContextObject(context) - , m_renderPass(VK_NULL_HANDLE) + , m_renderPass(VK_NULL_HANDLE) { } @@ -45,7 +45,7 @@ KRRenderPass::~KRRenderPass() assert(m_renderPass == VK_NULL_HANDLE); } -void KRRenderPass::create(KRDevice &device, VkFormat swapChainImageFormat, VkFormat depthImageFormat, const RenderPassInfo& info) +void KRRenderPass::create(KRDevice& device, VkFormat swapChainImageFormat, VkFormat depthImageFormat, const RenderPassInfo& info) { if (m_renderPass) { return; @@ -110,7 +110,7 @@ void KRRenderPass::create(KRDevice &device, VkFormat swapChainImageFormat, VkFor } } -void KRRenderPass::destroy(KRDevice &device) +void KRRenderPass::destroy(KRDevice& device) { if (m_renderPass) { vkDestroyRenderPass(device.m_logicalDevice, m_renderPass, nullptr); diff --git a/kraken/KRRenderPass.h b/kraken/KRRenderPass.h index bc87456..193b58e 100644 --- a/kraken/KRRenderPass.h +++ b/kraken/KRRenderPass.h @@ -51,9 +51,9 @@ public: void create(KRDevice& device, VkFormat swapChainImageFormat, VkFormat depthImageFormat, const RenderPassInfo& info); void destroy(KRDevice& device); - void begin(VkCommandBuffer &commandBuffer, KRSurface& surface, const Vector4& clearColor); + void begin(VkCommandBuffer& commandBuffer, KRSurface& surface, const Vector4& clearColor); void end(VkCommandBuffer& commandBuffer); -// private: + // private: VkRenderPass m_renderPass; }; diff --git a/kraken/KRRenderSettings.cpp b/kraken/KRRenderSettings.cpp index 1ae4ae7..7ddfe52 100755 --- a/kraken/KRRenderSettings.cpp +++ b/kraken/KRRenderSettings.cpp @@ -33,195 +33,197 @@ KRRenderSettings::KRRenderSettings() { - siren_enable = true; - siren_enable_reverb = true; - siren_enable_hrtf = true; - siren_reverb_max_length = 2.0f; - - m_enable_realtime_occlusion = false; - bShowShadowBuffer = false; - bShowOctree = false; - bShowDeferred = false; - bEnablePerPixel = true; - bEnableDiffuseMap = true; - bEnableNormalMap = true; - bEnableSpecMap = true; - bEnableReflectionMap = true; - bEnableReflection = true; - bDebugPSSM = false; - bEnableAmbient = true; - bEnableDiffuse = true; - bEnableSpecular = true; - bEnableLightMap = true; - bEnableDeferredLighting = false; - max_anisotropy = 4.0f; - - ambient_intensity = Vector3::Zero(); - light_intensity = Vector3::One(); - - perspective_fov = 45.0f * D2R; - perspective_nearz = 0.3f; // was 0.05f - perspective_farz = 1000.0f; - - dof_quality = 0; - dof_depth = 0.05f; - dof_falloff = 0.05f; - - bEnableFlash = false; - flash_intensity = 1.0f; - flash_depth = 0.7f; - flash_falloff = 0.5f; - - - bEnableVignette = false; - vignette_radius = 0.4f; - vignette_falloff = 1.0f; - - - m_cShadowBuffers = 0; - - volumetric_environment_enable = false; - volumetric_environment_downsample = 2; - volumetric_environment_max_distance = 100.0f; - volumetric_environment_quality = (50.0f - 5.0f) / 495.0f; - volumetric_environment_intensity = 0.9f; - - - fog_near = 50.0f; - fog_far = 500.0f; - fog_density = 0.0005f; - fog_color = Vector3::Create(0.45f, 0.45f, 0.5f); - fog_type = 0; - - dust_particle_intensity = 0.25f; - dust_particle_enable = false; - - m_lodBias = 0.0f; - - debug_display = KRENGINE_DEBUG_DISPLAY_NONE; + siren_enable = true; + siren_enable_reverb = true; + siren_enable_hrtf = true; + siren_reverb_max_length = 2.0f; + + m_enable_realtime_occlusion = false; + bShowShadowBuffer = false; + bShowOctree = false; + bShowDeferred = false; + bEnablePerPixel = true; + bEnableDiffuseMap = true; + bEnableNormalMap = true; + bEnableSpecMap = true; + bEnableReflectionMap = true; + bEnableReflection = true; + bDebugPSSM = false; + bEnableAmbient = true; + bEnableDiffuse = true; + bEnableSpecular = true; + bEnableLightMap = true; + bEnableDeferredLighting = false; + max_anisotropy = 4.0f; + + ambient_intensity = Vector3::Zero(); + light_intensity = Vector3::One(); + + perspective_fov = 45.0f * D2R; + perspective_nearz = 0.3f; // was 0.05f + perspective_farz = 1000.0f; + + dof_quality = 0; + dof_depth = 0.05f; + dof_falloff = 0.05f; + + bEnableFlash = false; + flash_intensity = 1.0f; + flash_depth = 0.7f; + flash_falloff = 0.5f; + + + bEnableVignette = false; + vignette_radius = 0.4f; + vignette_falloff = 1.0f; + + + m_cShadowBuffers = 0; + + volumetric_environment_enable = false; + volumetric_environment_downsample = 2; + volumetric_environment_max_distance = 100.0f; + volumetric_environment_quality = (50.0f - 5.0f) / 495.0f; + volumetric_environment_intensity = 0.9f; + + + fog_near = 50.0f; + fog_far = 500.0f; + fog_density = 0.0005f; + fog_color = Vector3::Create(0.45f, 0.45f, 0.5f); + fog_type = 0; + + dust_particle_intensity = 0.25f; + dust_particle_enable = false; + + m_lodBias = 0.0f; + + debug_display = KRENGINE_DEBUG_DISPLAY_NONE; } KRRenderSettings::~KRRenderSettings() { - + } -KRRenderSettings& KRRenderSettings::operator=(const KRRenderSettings &s) +KRRenderSettings& KRRenderSettings::operator=(const KRRenderSettings& s) { - siren_enable = s.siren_enable; - siren_enable_reverb = s.siren_enable_reverb; - siren_enable_hrtf = s.siren_enable_hrtf; - siren_reverb_max_length = s.siren_reverb_max_length; - - bEnablePerPixel = s.bEnablePerPixel; - bEnableDiffuseMap = s.bEnableDiffuseMap; - bEnableNormalMap = s.bEnableNormalMap; - bEnableSpecMap = s.bEnableSpecMap; - bEnableReflectionMap = s.bEnableReflectionMap; - bEnableReflection=s.bEnableReflection; - bEnableLightMap=s.bEnableLightMap; - bDebugPSSM=s.bDebugPSSM; - bShowShadowBuffer=s.bShowShadowBuffer; - bShowOctree=s.bShowOctree; - bShowDeferred=s.bShowDeferred; - bEnableAmbient=s.bEnableAmbient; - bEnableDiffuse=s.bEnableDiffuse; - bEnableSpecular=s.bEnableSpecular; - bEnableDeferredLighting=s.bEnableDeferredLighting; - light_intensity=s.light_intensity; - ambient_intensity=s.ambient_intensity; - perspective_fov=s.perspective_fov; - - dof_quality=s.dof_quality; - dof_depth=s.dof_depth; - dof_falloff=s.dof_falloff; - bEnableFlash=s.bEnableFlash; - flash_intensity=s.flash_intensity; - flash_depth=s.flash_depth; - flash_falloff=s.flash_falloff; - - bEnableVignette=s.bEnableVignette; - vignette_radius=s.vignette_radius; - vignette_falloff=s.vignette_falloff; - - m_viewportSize=s.m_viewportSize; - - m_cShadowBuffers=s.m_cShadowBuffers; - - m_debug_text=s.m_debug_text; - - volumetric_environment_enable=s.volumetric_environment_enable; - volumetric_environment_downsample=s.volumetric_environment_downsample; - volumetric_environment_max_distance=s.volumetric_environment_max_distance; - volumetric_environment_quality=s.volumetric_environment_quality; - volumetric_environment_intensity=s.volumetric_environment_intensity; - - fog_near=s.fog_near; - fog_far=s.fog_far; - fog_density=s.fog_density; - fog_color=s.fog_color; - fog_type=s.fog_type; - - dust_particle_intensity=s.dust_particle_intensity; - dust_particle_enable=s.dust_particle_enable; - perspective_nearz=s.perspective_nearz; - perspective_farz=s.perspective_farz; - debug_display = s.debug_display; - - m_lodBias = s.m_lodBias; - m_enable_realtime_occlusion = s.m_enable_realtime_occlusion; - - max_anisotropy = s.max_anisotropy; - - return *this; + siren_enable = s.siren_enable; + siren_enable_reverb = s.siren_enable_reverb; + siren_enable_hrtf = s.siren_enable_hrtf; + siren_reverb_max_length = s.siren_reverb_max_length; + + bEnablePerPixel = s.bEnablePerPixel; + bEnableDiffuseMap = s.bEnableDiffuseMap; + bEnableNormalMap = s.bEnableNormalMap; + bEnableSpecMap = s.bEnableSpecMap; + bEnableReflectionMap = s.bEnableReflectionMap; + bEnableReflection = s.bEnableReflection; + bEnableLightMap = s.bEnableLightMap; + bDebugPSSM = s.bDebugPSSM; + bShowShadowBuffer = s.bShowShadowBuffer; + bShowOctree = s.bShowOctree; + bShowDeferred = s.bShowDeferred; + bEnableAmbient = s.bEnableAmbient; + bEnableDiffuse = s.bEnableDiffuse; + bEnableSpecular = s.bEnableSpecular; + bEnableDeferredLighting = s.bEnableDeferredLighting; + light_intensity = s.light_intensity; + ambient_intensity = s.ambient_intensity; + perspective_fov = s.perspective_fov; + + dof_quality = s.dof_quality; + dof_depth = s.dof_depth; + dof_falloff = s.dof_falloff; + bEnableFlash = s.bEnableFlash; + flash_intensity = s.flash_intensity; + flash_depth = s.flash_depth; + flash_falloff = s.flash_falloff; + + bEnableVignette = s.bEnableVignette; + vignette_radius = s.vignette_radius; + vignette_falloff = s.vignette_falloff; + + m_viewportSize = s.m_viewportSize; + + m_cShadowBuffers = s.m_cShadowBuffers; + + m_debug_text = s.m_debug_text; + + volumetric_environment_enable = s.volumetric_environment_enable; + volumetric_environment_downsample = s.volumetric_environment_downsample; + volumetric_environment_max_distance = s.volumetric_environment_max_distance; + volumetric_environment_quality = s.volumetric_environment_quality; + volumetric_environment_intensity = s.volumetric_environment_intensity; + + fog_near = s.fog_near; + fog_far = s.fog_far; + fog_density = s.fog_density; + fog_color = s.fog_color; + fog_type = s.fog_type; + + dust_particle_intensity = s.dust_particle_intensity; + dust_particle_enable = s.dust_particle_enable; + perspective_nearz = s.perspective_nearz; + perspective_farz = s.perspective_farz; + debug_display = s.debug_display; + + m_lodBias = s.m_lodBias; + m_enable_realtime_occlusion = s.m_enable_realtime_occlusion; + + max_anisotropy = s.max_anisotropy; + + return *this; } -const Vector2 &KRRenderSettings::getViewportSize() { - return m_viewportSize; +const Vector2& KRRenderSettings::getViewportSize() +{ + return m_viewportSize; } -void KRRenderSettings::setViewportSize(const Vector2 &size) { - m_viewportSize = size; +void KRRenderSettings::setViewportSize(const Vector2& size) +{ + m_viewportSize = size; } float KRRenderSettings::getPerspectiveNearZ() { - return perspective_nearz; + return perspective_nearz; } float KRRenderSettings::getPerspectiveFarZ() { - return perspective_farz; + return perspective_farz; } void KRRenderSettings::setPerspectiveNear(float v) { - if(perspective_nearz != v) { - perspective_nearz = v; - } + if (perspective_nearz != v) { + perspective_nearz = v; + } } void KRRenderSettings::setPerpsectiveFarZ(float v) { - if(perspective_farz != v) { - perspective_farz = v; - } + if (perspective_farz != v) { + perspective_farz = v; + } } float KRRenderSettings::getLODBias() { - return m_lodBias; + return m_lodBias; } void KRRenderSettings::setLODBias(float v) { - m_lodBias = v; + m_lodBias = v; } bool KRRenderSettings::getEnableRealtimeOcclusion() { - return m_enable_realtime_occlusion; + return m_enable_realtime_occlusion; } void KRRenderSettings::setEnableRealtimeOcclusion(bool enable) { - m_enable_realtime_occlusion = enable; + m_enable_realtime_occlusion = enable; } \ No newline at end of file diff --git a/kraken/KRRenderSettings.h b/kraken/KRRenderSettings.h index 61acd94..15d232a 100755 --- a/kraken/KRRenderSettings.h +++ b/kraken/KRRenderSettings.h @@ -33,104 +33,106 @@ #include "KREngine-common.h" -class KRRenderSettings { +class KRRenderSettings +{ public: - KRRenderSettings(); - ~KRRenderSettings(); - - // Overload assignment operator - KRRenderSettings& operator=(const KRRenderSettings &s); - - const Vector2 &getViewportSize(); - void setViewportSize(const Vector2 &size); - - float getPerspectiveNearZ(); - float getPerspectiveFarZ(); - void setPerspectiveNear(float v); - void setPerpsectiveFarZ(float v); - - float getLODBias(); - void setLODBias(float v); - - bool bEnablePerPixel; - bool bEnableDiffuseMap; - bool bEnableNormalMap; - bool bEnableSpecMap; - bool bEnableReflectionMap; - bool bEnableReflection; - bool bEnableLightMap; - bool bDebugPSSM; - bool bShowShadowBuffer; - bool bShowOctree; - bool bShowDeferred; - bool bEnableAmbient; - bool bEnableDiffuse; - bool bEnableSpecular; - bool bEnableDeferredLighting; - Vector3 light_intensity; - Vector3 ambient_intensity; - float perspective_fov; - - int dof_quality; - float dof_depth; - float dof_falloff; - bool bEnableFlash; - float flash_intensity; - float flash_depth; - float flash_falloff; - - bool bEnableVignette; - float vignette_radius; - float vignette_falloff; - - Vector2 m_viewportSize; - - int m_cShadowBuffers; - - std::string m_debug_text; - - bool volumetric_environment_enable; - int volumetric_environment_downsample; - float volumetric_environment_max_distance; - float volumetric_environment_quality; - float volumetric_environment_intensity; - - float fog_near; - float fog_far; - float fog_density; - Vector3 fog_color; - int fog_type; // 0 = no fog, 1 = linear, 2 = exponential, 3 = exponential squared - - float dust_particle_intensity; - bool dust_particle_enable; - float perspective_nearz; - float perspective_farz; - - enum debug_display_type{ - KRENGINE_DEBUG_DISPLAY_NONE = 0, - KRENGINE_DEBUG_DISPLAY_TIME, - KRENGINE_DEBUG_DISPLAY_MEMORY, - KRENGINE_DEBUG_DISPLAY_TEXTURES, - KRENGINE_DEBUG_DISPLAY_DRAW_CALLS, - KRENGINE_DEBUG_DISPLAY_OCTREE, - KRENGINE_DEBUG_DISPLAY_COLLIDERS, - KRENGINE_DEBUG_DISPLAY_BONES, - KRENGINE_DEBUG_DISPLAY_SIREN_REVERB_ZONES, - KRENGINE_DEBUG_DISPLAY_SIREN_AMBIENT_ZONES, - KRENGINE_DEBUG_DISPLAY_NUMBER - } debug_display; - - bool getEnableRealtimeOcclusion(); - void setEnableRealtimeOcclusion(bool enable); - - bool siren_enable; - bool siren_enable_reverb; - bool siren_enable_hrtf; - float siren_reverb_max_length; - - float max_anisotropy; + KRRenderSettings(); + ~KRRenderSettings(); + + // Overload assignment operator + KRRenderSettings& operator=(const KRRenderSettings& s); + + const Vector2& getViewportSize(); + void setViewportSize(const Vector2& size); + + float getPerspectiveNearZ(); + float getPerspectiveFarZ(); + void setPerspectiveNear(float v); + void setPerpsectiveFarZ(float v); + + float getLODBias(); + void setLODBias(float v); + + bool bEnablePerPixel; + bool bEnableDiffuseMap; + bool bEnableNormalMap; + bool bEnableSpecMap; + bool bEnableReflectionMap; + bool bEnableReflection; + bool bEnableLightMap; + bool bDebugPSSM; + bool bShowShadowBuffer; + bool bShowOctree; + bool bShowDeferred; + bool bEnableAmbient; + bool bEnableDiffuse; + bool bEnableSpecular; + bool bEnableDeferredLighting; + Vector3 light_intensity; + Vector3 ambient_intensity; + float perspective_fov; + + int dof_quality; + float dof_depth; + float dof_falloff; + bool bEnableFlash; + float flash_intensity; + float flash_depth; + float flash_falloff; + + bool bEnableVignette; + float vignette_radius; + float vignette_falloff; + + Vector2 m_viewportSize; + + int m_cShadowBuffers; + + std::string m_debug_text; + + bool volumetric_environment_enable; + int volumetric_environment_downsample; + float volumetric_environment_max_distance; + float volumetric_environment_quality; + float volumetric_environment_intensity; + + float fog_near; + float fog_far; + float fog_density; + Vector3 fog_color; + int fog_type; // 0 = no fog, 1 = linear, 2 = exponential, 3 = exponential squared + + float dust_particle_intensity; + bool dust_particle_enable; + float perspective_nearz; + float perspective_farz; + + enum debug_display_type + { + KRENGINE_DEBUG_DISPLAY_NONE = 0, + KRENGINE_DEBUG_DISPLAY_TIME, + KRENGINE_DEBUG_DISPLAY_MEMORY, + KRENGINE_DEBUG_DISPLAY_TEXTURES, + KRENGINE_DEBUG_DISPLAY_DRAW_CALLS, + KRENGINE_DEBUG_DISPLAY_OCTREE, + KRENGINE_DEBUG_DISPLAY_COLLIDERS, + KRENGINE_DEBUG_DISPLAY_BONES, + KRENGINE_DEBUG_DISPLAY_SIREN_REVERB_ZONES, + KRENGINE_DEBUG_DISPLAY_SIREN_AMBIENT_ZONES, + KRENGINE_DEBUG_DISPLAY_NUMBER + } debug_display; + + bool getEnableRealtimeOcclusion(); + void setEnableRealtimeOcclusion(bool enable); + + bool siren_enable; + bool siren_enable_reverb; + bool siren_enable_hrtf; + float siren_reverb_max_length; + + float max_anisotropy; private: - float m_lodBias; - bool m_enable_realtime_occlusion; + float m_lodBias; + bool m_enable_realtime_occlusion; }; diff --git a/kraken/KRResource+blend.cpp b/kraken/KRResource+blend.cpp index b2f9cbb..d2dc57b 100755 --- a/kraken/KRResource+blend.cpp +++ b/kraken/KRResource+blend.cpp @@ -36,131 +36,141 @@ #include "KRResource+blend.h" -KRScene* KRResource::LoadBlenderScene(KRContext &context, const std::string& path) { - KRScene *pScene = new KRScene(context, KRResource::GetFileBase(path)); - - KRDataBlock data; - - if(data.load(path)) { - //KRBlendFile blend_file = KRBlendFile(pFile); - } - - return pScene; +KRScene* KRResource::LoadBlenderScene(KRContext& context, const std::string& path) +{ + KRScene* pScene = new KRScene(context, KRResource::GetFileBase(path)); + + KRDataBlock data; + + if (data.load(path)) { + //KRBlendFile blend_file = KRBlendFile(pFile); + } + + return pScene; } -KRBlendFile::KRBlendFile(const void *pFile) { - unsigned char *scan = (unsigned char *)pFile; - readHeader(scan); - std::string block_code = ""; - while(block_code != "ENDB") { - Block b = Block(this, scan); - block_code = b.getCode(); - m_blocks.push_back(b); - - printf("Loaded block: %s - %i bytes\n", b.getCode().c_str(), b.getDataSize()); - } +KRBlendFile::KRBlendFile(const void* pFile) +{ + unsigned char* scan = (unsigned char*)pFile; + readHeader(scan); + std::string block_code = ""; + while (block_code != "ENDB") { + Block b = Block(this, scan); + block_code = b.getCode(); + m_blocks.push_back(b); + + printf("Loaded block: %s - %i bytes\n", b.getCode().c_str(), b.getDataSize()); + } } -void KRBlendFile::readHeader(unsigned char *&scan) { - if(strncmp((char *)scan, "BLENDER", 7) != 0) { - // TODO throw exception - } - scan += 7; - if(scan[0] == '_' && scan[1] == 'v') { - // 32-bit, little-endian - m_file_type = KRBLEND_LITTLEENDIAN_32BIT; - } else if(scan[0] == '_' && scan[1] == 'V') { - // 32-bit, bit-endian - m_file_type = KRBLEND_BIGENDIAN_32BIT; - } else if(scan[0] == '-' && scan[1] == 'v') { - // 64-bit, little-endian - m_file_type = KRBLEND_LITTLEENDIAN_64BIT; - } else if(scan[0] == '-' && scan[1] == 'V') { - // 64-bit, big-endian - m_file_type = KRBLEND_BIGENDIAN_64BIT; - } else { - // TODO - throw exception - } - scan += 5; // Skip and ignore version +void KRBlendFile::readHeader(unsigned char*& scan) +{ + if (strncmp((char*)scan, "BLENDER", 7) != 0) { + // TODO throw exception + } + scan += 7; + if (scan[0] == '_' && scan[1] == 'v') { + // 32-bit, little-endian + m_file_type = KRBLEND_LITTLEENDIAN_32BIT; + } else if (scan[0] == '_' && scan[1] == 'V') { + // 32-bit, bit-endian + m_file_type = KRBLEND_BIGENDIAN_32BIT; + } else if (scan[0] == '-' && scan[1] == 'v') { + // 64-bit, little-endian + m_file_type = KRBLEND_LITTLEENDIAN_64BIT; + } else if (scan[0] == '-' && scan[1] == 'V') { + // 64-bit, big-endian + m_file_type = KRBLEND_BIGENDIAN_64BIT; + } else { + // TODO - throw exception + } + scan += 5; // Skip and ignore version } -__int32_t KRBlendFile::readInt(unsigned char *&scan) { - __int32_t ret = 0; - // read a 32-bit integer and increment scan - - switch (m_file_type) { - case KRBLEND_BIGENDIAN_32BIT: - case KRBLEND_BIGENDIAN_64BIT: - ret = (__int32_t)scan[3] + (__int32_t)scan[2] * 0x100 + (__int32_t)scan[1] * 0x10000 + (__int32_t)scan[0] * 0x1000000; - break; - case KRBLEND_LITTLEENDIAN_32BIT: - case KRBLEND_LITTLEENDIAN_64BIT: - ret = (__int32_t)scan[0] + (__int32_t)scan[1] * 0x100 + (__int32_t)scan[2] * 0x10000 + (__int32_t)scan[3] * 0x1000000; - break; - } - +__int32_t KRBlendFile::readInt(unsigned char*& scan) +{ + __int32_t ret = 0; + // read a 32-bit integer and increment scan + + switch (m_file_type) { + case KRBLEND_BIGENDIAN_32BIT: + case KRBLEND_BIGENDIAN_64BIT: + ret = (__int32_t)scan[3] + (__int32_t)scan[2] * 0x100 + (__int32_t)scan[1] * 0x10000 + (__int32_t)scan[0] * 0x1000000; + break; + case KRBLEND_LITTLEENDIAN_32BIT: + case KRBLEND_LITTLEENDIAN_64BIT: + ret = (__int32_t)scan[0] + (__int32_t)scan[1] * 0x100 + (__int32_t)scan[2] * 0x10000 + (__int32_t)scan[3] * 0x1000000; + break; + } + + scan += 4; + return ret; +} + +__int64_t KRBlendFile::readPointer(unsigned char*& scan) +{ + __int64_t ret = 0; + // read a 32-bit integer and increment scan + switch (m_file_type) { + case KRBLEND_BIGENDIAN_32BIT: + ret = scan[3] + scan[2] * 0x100 + scan[1] * 0x10000 + scan[0] * 0x1000000; scan += 4; - return ret; + break; + case KRBLEND_LITTLEENDIAN_32BIT: + ret = scan[0] + scan[1] * 0x100 + scan[2] * 0x10000 + scan[3] * 0x1000000; + scan += 4; + break; + + case KRBLEND_BIGENDIAN_64BIT: + ret = scan[7] + scan[6] * 0x100 + scan[5] * 0x10000 + scan[4] * 0x1000000 + scan[3] * 0x100000000 + scan[2] * 0x10000000000 + scan[1] * 0x1000000000000 + scan[0] * 0x100000000000000; + scan += 8; + break; + case KRBLEND_LITTLEENDIAN_64BIT: + ret = scan[0] + scan[1] * 0x100 + scan[2] * 0x10000 + scan[3] * 0x1000000 + scan[4] * 0x100000000 + scan[5] * 0x10000000000 + scan[6] * 0x1000000000000 + scan[7] * 0x100000000000000; + scan += 8; + break; + } + + + return ret; } -__int64_t KRBlendFile::readPointer(unsigned char *&scan) { - __int64_t ret = 0; - // read a 32-bit integer and increment scan - switch (m_file_type) { - case KRBLEND_BIGENDIAN_32BIT: - ret = scan[3] + scan[2] * 0x100 + scan[1] * 0x10000 + scan[0] * 0x1000000; - scan += 4; - break; - case KRBLEND_LITTLEENDIAN_32BIT: - ret = scan[0] + scan[1] * 0x100 + scan[2] * 0x10000 + scan[3] * 0x1000000; - scan += 4; - break; - - case KRBLEND_BIGENDIAN_64BIT: - ret = scan[7] + scan[6] * 0x100 + scan[5] * 0x10000 + scan[4] * 0x1000000 + scan[3] * 0x100000000 + scan[2] * 0x10000000000 + scan[1] * 0x1000000000000 + scan[0] * 0x100000000000000; - scan += 8; - break; - case KRBLEND_LITTLEENDIAN_64BIT: - ret = scan[0] + scan[1] * 0x100 + scan[2] * 0x10000 + scan[3] * 0x1000000 + scan[4] * 0x100000000 + scan[5] * 0x10000000000 + scan[6] * 0x1000000000000 + scan[7] * 0x100000000000000; - scan += 8; - break; - } - - - return ret; -} +KRBlendFile::~KRBlendFile() +{ -KRBlendFile::~KRBlendFile() { - } -KRBlendFile::Block::Block(KRBlendFile *blendFile, unsigned char *&scan) { - scan += (__int64_t)scan % 4; // Scan forward until the next 4-byte boundary - char szBlock[5]; - szBlock[0] = *scan++; - szBlock[1] = *scan++; - szBlock[2] = *scan++; - szBlock[3] = *scan++; - szBlock[4] = '\0'; - m_code = szBlock; - m_dataSize = blendFile->readInt(scan); - m_prev_pointer = blendFile->readPointer(scan); - m_sdna_index = blendFile->readInt(scan); - m_structure_count = blendFile->readInt(scan); - m_data = scan; - scan += m_dataSize; +KRBlendFile::Block::Block(KRBlendFile* blendFile, unsigned char*& scan) +{ + scan += (__int64_t)scan % 4; // Scan forward until the next 4-byte boundary + char szBlock[5]; + szBlock[0] = *scan++; + szBlock[1] = *scan++; + szBlock[2] = *scan++; + szBlock[3] = *scan++; + szBlock[4] = '\0'; + m_code = szBlock; + m_dataSize = blendFile->readInt(scan); + m_prev_pointer = blendFile->readPointer(scan); + m_sdna_index = blendFile->readInt(scan); + m_structure_count = blendFile->readInt(scan); + m_data = scan; + scan += m_dataSize; } -KRBlendFile::Block::~Block() { - +KRBlendFile::Block::~Block() +{ + } -std::string KRBlendFile::Block::getCode() { - return m_code; +std::string KRBlendFile::Block::getCode() +{ + return m_code; } -int KRBlendFile::Block::getDataSize() { - return m_dataSize; +int KRBlendFile::Block::getDataSize() +{ + return m_dataSize; } diff --git a/kraken/KRResource+blend.h b/kraken/KRResource+blend.h index 9cff774..c673e91 100755 --- a/kraken/KRResource+blend.h +++ b/kraken/KRResource+blend.h @@ -31,38 +31,41 @@ #pragma once -class KRBlendFile { +class KRBlendFile +{ public: - KRBlendFile(const void *pFile); - ~KRBlendFile(); - - class Block { - public: - Block(KRBlendFile *blendFile, unsigned char *&scan); - ~Block(); - - std::string getCode(); - int getDataSize(); - private: - std::string m_code; - __int32_t m_dataSize; - __int32_t m_sdna_index; - __int32_t m_structure_count; - __int64_t m_prev_pointer; - unsigned char *m_data; - }; - + KRBlendFile(const void* pFile); + ~KRBlendFile(); + + class Block + { + public: + Block(KRBlendFile* blendFile, unsigned char*& scan); + ~Block(); + + std::string getCode(); + int getDataSize(); + private: + std::string m_code; + __int32_t m_dataSize; + __int32_t m_sdna_index; + __int32_t m_structure_count; + __int64_t m_prev_pointer; + unsigned char* m_data; + }; + private: - enum file_type { - KRBLEND_LITTLEENDIAN_32BIT, - KRBLEND_LITTLEENDIAN_64BIT, - KRBLEND_BIGENDIAN_32BIT, - KRBLEND_BIGENDIAN_64BIT - } m_file_type; - void readHeader(unsigned char *&scan); - - __int32_t readInt(unsigned char *&scan); - __int64_t readPointer(unsigned char *&scan); - - std::vector m_blocks; + enum file_type + { + KRBLEND_LITTLEENDIAN_32BIT, + KRBLEND_LITTLEENDIAN_64BIT, + KRBLEND_BIGENDIAN_32BIT, + KRBLEND_BIGENDIAN_64BIT + } m_file_type; + void readHeader(unsigned char*& scan); + + __int32_t readInt(unsigned char*& scan); + __int64_t readPointer(unsigned char*& scan); + + std::vector m_blocks; }; diff --git a/kraken/KRResource+fbx.cpp b/kraken/KRResource+fbx.cpp index 63276d0..7e7bb59 100755 --- a/kraken/KRResource+fbx.cpp +++ b/kraken/KRResource+fbx.cpp @@ -60,419 +60,412 @@ void InitializeSdkObjects(FbxManager*& pSdkManager, FbxScene*& pScene); void DestroySdkObjects(FbxManager* pSdkManager); bool LoadScene(FbxManager* pSdkManager, FbxDocument* pScene, const char* pFilename); -KRAnimation *LoadAnimation(KRContext &context, FbxAnimStack* pAnimStack); -KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurve); -KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLayer); -void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode); +KRAnimation* LoadAnimation(KRContext& context, FbxAnimStack* pAnimStack); +KRAnimationCurve* LoadAnimationCurve(KRContext& context, FbxAnimCurve* pAnimCurve); +KRAnimationLayer* LoadAnimationLayer(KRContext& context, FbxAnimLayer* pAnimLayer); +void LoadNode(FbxScene* pFbxScene, KRNode* parent_node, FbxGeometryConverter* pGeometryConverter, FbxNode* pNode); //void BakeNode(KFbxNode* pNode); -void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial); -void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxMesh* pMesh); -KRNode *LoadMesh(KRNode *parent_node, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode); -KRNode *LoadLight(KRNode *parent_node, FbxNode* pNode); -KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, FbxNode* pNode); -KRNode *LoadLocator(KRNode *parent_node, FbxScene* pScene, FbxNode* pNode); -KRNode *LoadCamera(KRNode *parent_node, FbxNode* pNode); -std::string GetFbxObjectName(FbxObject *obj); +void LoadMaterial(KRContext& context, FbxSurfaceMaterial* pMaterial); +void LoadMesh(KRContext& context, FbxScene* pFbxScene, FbxGeometryConverter* pGeometryConverter, FbxMesh* pMesh); +KRNode* LoadMesh(KRNode* parent_node, FbxScene* pFbxScene, FbxGeometryConverter* pGeometryConverter, FbxNode* pNode); +KRNode* LoadLight(KRNode* parent_node, FbxNode* pNode); +KRNode* LoadSkeleton(KRNode* parent_node, FbxScene* pScene, FbxNode* pNode); +KRNode* LoadLocator(KRNode* parent_node, FbxScene* pScene, FbxNode* pNode); +KRNode* LoadCamera(KRNode* parent_node, FbxNode* pNode); +std::string GetFbxObjectName(FbxObject* obj); const float KRAKEN_FBX_ANIMATION_FRAMERATE = 30.0f; // FINDME - This should be configurable -std::string GetFbxObjectName(FbxObject *obj) +std::string GetFbxObjectName(FbxObject* obj) { - bool is_locator = false; - FbxNode *node = FbxCast(obj); - if(node) { - FbxNodeAttribute::EType attribute_type = (node->GetNodeAttribute()->GetAttributeType()); - if(attribute_type == FbxNodeAttribute::eNull) { - FbxNull* pSourceNull = (FbxNull*) node->GetNodeAttribute(); - if(pSourceNull->Look.Get() == FbxNull::eCross ) { - is_locator = true; - } - } + bool is_locator = false; + FbxNode* node = FbxCast(obj); + if (node) { + FbxNodeAttribute::EType attribute_type = (node->GetNodeAttribute()->GetAttributeType()); + if (attribute_type == FbxNodeAttribute::eNull) { + FbxNull* pSourceNull = (FbxNull*)node->GetNodeAttribute(); + if (pSourceNull->Look.Get() == FbxNull::eCross) { + is_locator = true; + } } - - - // 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(is_locator) { - // We do not rename locators - return std::string(obj->GetName()); - } else if(strncmp(obj->GetName(), "so_", 3) == 0) { - // An so_ prefix indicates that this is a "Scriptable Object" that should not have the name decorated; - return obj->GetName(); - } else if(strcmp(obj->GetName(), "default_camera") == 0) { - // There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera - return "default_camera"; - } else { - std::stringstream st; - st << "fbx_"; - st << obj->GetUniqueID(); - if(strlen(obj->GetName()) != 0) { - st << "_"; - st << obj->GetName(); - } - return st.str(); + } + + + // 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 (is_locator) { + // We do not rename locators + return std::string(obj->GetName()); + } else if (strncmp(obj->GetName(), "so_", 3) == 0) { + // An so_ prefix indicates that this is a "Scriptable Object" that should not have the name decorated; + return obj->GetName(); + } else if (strcmp(obj->GetName(), "default_camera") == 0) { + // There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera + return "default_camera"; + } else { + std::stringstream st; + st << "fbx_"; + st << obj->GetUniqueID(); + if (strlen(obj->GetName()) != 0) { + st << "_"; + st << obj->GetName(); } + return st.str(); + } } -void KRResource::LoadFbx(KRContext &context, const std::string& path) +void KRResource::LoadFbx(KRContext& context, const std::string& path) { - KRScene *pScene = new KRScene(context, KRResource::GetFileBase(path)); - context.getSceneManager()->add(pScene); - - FbxManager* lSdkManager = NULL; - FbxScene* pFbxScene = NULL; - bool lResult; - FbxGeometryConverter *pGeometryConverter = NULL; - - // Prepare the FBX SDK. - InitializeSdkObjects(lSdkManager, pFbxScene); - - // Initialize Geometry Converter - pGeometryConverter = new FbxGeometryConverter(lSdkManager); - - // Load the scene. - lResult = LoadScene(lSdkManager, pFbxScene, path.c_str()); + KRScene* pScene = new KRScene(context, KRResource::GetFileBase(path)); + context.getSceneManager()->add(pScene); - // Triangulate the scene. - lResult = pGeometryConverter->Triangulate(pFbxScene, true); - - FbxNode* pNode = pFbxScene->GetRootNode(); - - // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====---- - /* - printf("Baking pivots...\n"); - - if(pNode) { - pNode->ResetPivotSetAndConvertAnimation(); - } - */ - - // ----====---- Import Animation Layers ----====---- - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "\nLoading animations..."); - int animation_count = pFbxScene->GetSrcObjectCount(); - for(int i = 0; i < animation_count; i++) { - FbxAnimStack *animation = pFbxScene->GetSrcObject(i); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Animation %i of %i: %s", i+1, animation_count, animation->GetName()); - KRAnimation *new_animation = LoadAnimation(context, animation); - if(new_animation) { - context.getAnimationManager()->addAnimation(new_animation); - } - } - - // ----====---- Import Animation Curves ----====---- - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "\nLoading animation curves..."); - int curve_count = pFbxScene->GetSrcObjectCount(); - for(int i=0; i < curve_count; i++) { - FbxAnimCurve *curve = pFbxScene->GetSrcObject(i); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Animation Curve %i of %i: %s", i+1, curve_count, curve->GetName()); - KRAnimationCurve *new_curve = LoadAnimationCurve(context, curve); + FbxManager* lSdkManager = NULL; + FbxScene* pFbxScene = NULL; + bool lResult; + FbxGeometryConverter* pGeometryConverter = NULL; - if(new_curve) { - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Adding a curve"); - context.getAnimationCurveManager()->addAnimationCurve(new_curve); - } + // Prepare the FBX SDK. + InitializeSdkObjects(lSdkManager, pFbxScene); + + // Initialize Geometry Converter + pGeometryConverter = new FbxGeometryConverter(lSdkManager); + + // Load the scene. + lResult = LoadScene(lSdkManager, pFbxScene, path.c_str()); + + // Triangulate the scene. + lResult = pGeometryConverter->Triangulate(pFbxScene, true); + + FbxNode* pNode = pFbxScene->GetRootNode(); + + // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====---- + /* + printf("Baking pivots...\n"); + + if(pNode) { + pNode->ResetPivotSetAndConvertAnimation(); + } + */ + + // ----====---- Import Animation Layers ----====---- + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "\nLoading animations..."); + int animation_count = pFbxScene->GetSrcObjectCount(); + for (int i = 0; i < animation_count; i++) { + FbxAnimStack* animation = pFbxScene->GetSrcObject(i); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Animation %i of %i: %s", i + 1, animation_count, animation->GetName()); + KRAnimation* new_animation = LoadAnimation(context, animation); + if (new_animation) { + context.getAnimationManager()->addAnimation(new_animation); } - - // ----====---- Import Materials ----====---- - int material_count = pFbxScene->GetSrcObjectCount(); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "\nLoading materials..."); - for(int i=0; i < material_count; i++) { - FbxSurfaceMaterial *material = pFbxScene->GetSrcObject(i); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Material %i of %i: %s", i+1, material_count, material->GetName()); - LoadMaterial(context, material); + } + + // ----====---- Import Animation Curves ----====---- + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "\nLoading animation curves..."); + int curve_count = pFbxScene->GetSrcObjectCount(); + for (int i = 0; i < curve_count; i++) { + FbxAnimCurve* curve = pFbxScene->GetSrcObject(i); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Animation Curve %i of %i: %s", i + 1, curve_count, curve->GetName()); + KRAnimationCurve* new_curve = LoadAnimationCurve(context, curve); + + if (new_curve) { + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Adding a curve"); + context.getAnimationCurveManager()->addAnimationCurve(new_curve); } - - // ----====---- Import Meshes ----====---- - int mesh_count = pFbxScene->GetSrcObjectCount(); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Loading meshes..."); - for(int i=0; i < mesh_count; i++) { - FbxMesh *mesh = pFbxScene->GetSrcObject(i); - - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Mesh %i of %i: %s", i+1, mesh_count, mesh->GetNode()->GetName()); - LoadMesh(context, pFbxScene, pGeometryConverter, mesh); + } + + // ----====---- Import Materials ----====---- + int material_count = pFbxScene->GetSrcObjectCount(); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "\nLoading materials..."); + for (int i = 0; i < material_count; i++) { + FbxSurfaceMaterial* material = pFbxScene->GetSrcObject(i); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Material %i of %i: %s", i + 1, material_count, material->GetName()); + LoadMaterial(context, material); + } + + // ----====---- Import Meshes ----====---- + int mesh_count = pFbxScene->GetSrcObjectCount(); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Loading meshes..."); + for (int i = 0; i < mesh_count; i++) { + FbxMesh* mesh = pFbxScene->GetSrcObject(i); + + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Mesh %i of %i: %s", i + 1, mesh_count, mesh->GetNode()->GetName()); + LoadMesh(context, pFbxScene, pGeometryConverter, mesh); + } + + // ----====---- Import Textures ----====---- + int texture_count = pFbxScene->GetSrcObjectCount(); + + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Loading textures..."); + for (int i = 0; i < texture_count; i++) { + FbxFileTexture* texture = pFbxScene->GetSrcObject(i); + const char* file_name = texture->GetFileName(); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Texture %i of %i: %s", i + 1, texture_count, (KRResource::GetFileBase(file_name) + "." + KRResource::GetFileExtension(file_name)).c_str()); + context.loadResource(file_name); + } + + // ----====---- Import Scene Graph Nodes ----====---- + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Loading scene graph..."); + if (pNode) { + for (int i = 0; i < pNode->GetChildCount(); i++) { + LoadNode(pFbxScene, pScene->getRootNode(), pGeometryConverter, pNode->GetChild(i)); } - - // ----====---- Import Textures ----====---- - int texture_count = pFbxScene->GetSrcObjectCount(); - - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Loading textures..."); - for(int i=0; i < texture_count; i++) { - FbxFileTexture *texture = pFbxScene->GetSrcObject(i); - const char *file_name = texture->GetFileName(); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Texture %i of %i: %s", i+1, texture_count, (KRResource::GetFileBase(file_name) + "." + KRResource::GetFileExtension(file_name)).c_str()); - context.loadResource(file_name); - } - - // ----====---- Import Scene Graph Nodes ----====---- - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Loading scene graph..."); - if(pNode) - { - for(int i = 0; i < pNode->GetChildCount(); i++) - { - LoadNode(pFbxScene, pScene->getRootNode(), pGeometryConverter, pNode->GetChild(i)); - } - } - - - - - DestroySdkObjects(lSdkManager); + } + + + + + DestroySdkObjects(lSdkManager); } void InitializeSdkObjects(FbxManager*& pSdkManager, FbxScene*& pScene) { - // The first thing to do is to create the FBX SDK manager which is the - // object allocator for almost all the classes in the SDK. - pSdkManager = FbxManager::Create(); - - if (!pSdkManager) - { - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Unable to create the FBX SDK manager"); - exit(0); - } - - // create an IOSettings object - FbxIOSettings * ios = FbxIOSettings::Create(pSdkManager, IOSROOT ); - pSdkManager->SetIOSettings(ios); - - // Load plugins from the executable directory - FbxString lPath = FbxGetApplicationDirectory(); + // The first thing to do is to create the FBX SDK manager which is the + // object allocator for almost all the classes in the SDK. + pSdkManager = FbxManager::Create(); + + if (!pSdkManager) { + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Unable to create the FBX SDK manager"); + exit(0); + } + + // create an IOSettings object + FbxIOSettings* ios = FbxIOSettings::Create(pSdkManager, IOSROOT); + pSdkManager->SetIOSettings(ios); + + // Load plugins from the executable directory + FbxString lPath = FbxGetApplicationDirectory(); #if defined(_WIN32) || defined(_WIN64) - FbxString lExtension = "dll"; + FbxString lExtension = "dll"; #elif TARGET_OS_MAC - FbxString lExtension = "dylib"; + FbxString lExtension = "dylib"; #elif TARGET_OS_UNIX - FbxString lExtension = "so"; + FbxString lExtension = "so"; #elif - #error Unsupported Platform +#error Unsupported Platform #endif - pSdkManager->LoadPluginsDirectory(lPath.Buffer(), lExtension.Buffer()); - - // Create the entity that will hold the scene. - pScene = FbxScene::Create(pSdkManager,""); + pSdkManager->LoadPluginsDirectory(lPath.Buffer(), lExtension.Buffer()); + + // Create the entity that will hold the scene. + pScene = FbxScene::Create(pSdkManager, ""); } void DestroySdkObjects(FbxManager* pSdkManager) { - // Delete the FBX SDK manager. All the objects that have been allocated - // using the FBX SDK manager and that haven't been explicitly destroyed - // are automatically destroyed at the same time. - if (pSdkManager) pSdkManager->Destroy(); - pSdkManager = NULL; + // Delete the FBX SDK manager. All the objects that have been allocated + // using the FBX SDK manager and that haven't been explicitly destroyed + // are automatically destroyed at the same time. + if (pSdkManager) pSdkManager->Destroy(); + pSdkManager = NULL; } bool LoadScene(FbxManager* pSdkManager, FbxDocument* pScene, const char* pFilename) { - int lFileMajor, lFileMinor, lFileRevision; - int lSDKMajor, lSDKMinor, lSDKRevision; - //int lFileFormat = -1; - int lAnimStackCount; - bool lStatus; - char lPassword[1024]; - - // Get the file version number generate by the FBX SDK. - FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision); - - // Create an importer. - FbxImporter* lImporter = FbxImporter::Create(pSdkManager,""); - - // Initialize the importer by providing a filename. - const bool lImportStatus = lImporter->Initialize(pFilename, -1, pSdkManager->GetIOSettings()); - lImporter->GetFileVersion(lFileMajor, lFileMinor, lFileRevision); - - if( !lImportStatus ) - { - FbxStatus &status = lImporter->GetStatus(); - - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Call to KFbxImporter::Initialize() failed.\nError returned: %s", status.GetErrorString()); - - - - if (status.GetCode() == FbxStatus::EStatusCode::eInvalidFileVersion) - { - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "FBX version number for this FBX SDK is %d.%d.%d", lSDKMajor, lSDKMinor, lSDKRevision); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "FBX version number for file %s is %d.%d.%d", pFilename, lFileMajor, lFileMinor, lFileRevision); - } - - return false; - } - - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "FBX version number for this FBX SDK is %d.%d.%d", lSDKMajor, lSDKMinor, lSDKRevision); - - if(!lImporter->IsFBX()) { - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "ERROR Unrecognized FBX File"); - return false; - } + int lFileMajor, lFileMinor, lFileRevision; + int lSDKMajor, lSDKMinor, lSDKRevision; + //int lFileFormat = -1; + int lAnimStackCount; + bool lStatus; + char lPassword[1024]; + + // Get the file version number generate by the FBX SDK. + FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision); + + // Create an importer. + FbxImporter* lImporter = FbxImporter::Create(pSdkManager, ""); + + // Initialize the importer by providing a filename. + const bool lImportStatus = lImporter->Initialize(pFilename, -1, pSdkManager->GetIOSettings()); + lImporter->GetFileVersion(lFileMajor, lFileMinor, lFileRevision); + + if (!lImportStatus) { + FbxStatus& status = lImporter->GetStatus(); + + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Call to KFbxImporter::Initialize() failed.\nError returned: %s", status.GetErrorString()); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "FBX version number for file %s is %d.%d.%d\n", pFilename, lFileMajor, lFileMinor, lFileRevision); - - // From this point, it is possible to access animation stack information without - // the expense of loading the entire file. - - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Animation Stack Information"); - - lAnimStackCount = lImporter->GetAnimStackCount(); - - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Number of Animation Stacks: %d", lAnimStackCount); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Current Animation Stack: \"%s\"", lImporter->GetActiveAnimStackName().Buffer()); - - - // Set the import states. By default, the import states are always set to - // true. The code below shows how to change these states. - IOS_REF.SetBoolProp(IMP_FBX_MATERIAL, true); - IOS_REF.SetBoolProp(IMP_FBX_TEXTURE, true); - IOS_REF.SetBoolProp(IMP_FBX_LINK, true); - IOS_REF.SetBoolProp(IMP_FBX_SHAPE, true); - IOS_REF.SetBoolProp(IMP_FBX_GOBO, true); - IOS_REF.SetBoolProp(IMP_FBX_ANIMATION, true); - IOS_REF.SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true); - - // Import the scene. + + if (status.GetCode() == FbxStatus::EStatusCode::eInvalidFileVersion) { + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "FBX version number for this FBX SDK is %d.%d.%d", lSDKMajor, lSDKMinor, lSDKRevision); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "FBX version number for file %s is %d.%d.%d", pFilename, lFileMajor, lFileMinor, lFileRevision); + } + + return false; + } + + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "FBX version number for this FBX SDK is %d.%d.%d", lSDKMajor, lSDKMinor, lSDKRevision); + + if (!lImporter->IsFBX()) { + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "ERROR Unrecognized FBX File"); + return false; + } + + + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "FBX version number for file %s is %d.%d.%d\n", pFilename, lFileMajor, lFileMinor, lFileRevision); + + // From this point, it is possible to access animation stack information without + // the expense of loading the entire file. + + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Animation Stack Information"); + + lAnimStackCount = lImporter->GetAnimStackCount(); + + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Number of Animation Stacks: %d", lAnimStackCount); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Current Animation Stack: \"%s\"", lImporter->GetActiveAnimStackName().Buffer()); + + + // Set the import states. By default, the import states are always set to + // true. The code below shows how to change these states. + IOS_REF.SetBoolProp(IMP_FBX_MATERIAL, true); + IOS_REF.SetBoolProp(IMP_FBX_TEXTURE, true); + IOS_REF.SetBoolProp(IMP_FBX_LINK, true); + IOS_REF.SetBoolProp(IMP_FBX_SHAPE, true); + IOS_REF.SetBoolProp(IMP_FBX_GOBO, true); + IOS_REF.SetBoolProp(IMP_FBX_ANIMATION, true); + IOS_REF.SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true); + + // Import the scene. + lStatus = lImporter->Import(pScene); + + if (lStatus == false && lImporter->GetStatus().GetCode() == FbxStatus::EStatusCode::ePasswordError) { + printf("Please enter password: "); + + lPassword[0] = '\0'; + + scanf("%s", lPassword); + FbxString lString(lPassword); + + IOS_REF.SetStringProp(IMP_FBX_PASSWORD, lString); + IOS_REF.SetBoolProp(IMP_FBX_PASSWORD_ENABLE, true); + lStatus = lImporter->Import(pScene); - - if(lStatus == false && lImporter->GetStatus().GetCode() == FbxStatus::EStatusCode::ePasswordError) - { - printf("Please enter password: "); - - lPassword[0] = '\0'; - - scanf("%s", lPassword); - FbxString lString(lPassword); - - IOS_REF.SetStringProp(IMP_FBX_PASSWORD, lString); - IOS_REF.SetBoolProp(IMP_FBX_PASSWORD_ENABLE, true); - - lStatus = lImporter->Import(pScene); - - if(lStatus == false && lImporter->GetStatus().GetCode() == FbxStatus::EStatusCode::ePasswordError) - { - printf("\nPassword is wrong, import aborted.\n"); - } - } - -// // ----====---- Start: Bake pivots into transforms, as Kraken doesn't support them directly ----====---- -// -// printf("Baking pivots...\n"); -// KFbxNode* pNode = ((KFbxScene*)pScene)->GetRootNode(); -//// BakeNode(pNode); -// -// for(i = 0; i < lAnimStackCount; i++) -// { -// KFbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); -// -// printf(" Animation: \"%s\"\n", lTakeInfo->mName.Buffer()); -// -// //pNode->ConvertPivotAnimationRecursive(lTakeInfo->mName.Buffer(), KFbxNode::eDestinationPivot, KRAKEN_FBX_ANIMATION_FRAMERATE); -// pNode->ResetPivotSetAndConvertAnimation(); -// -// } -//// pNode->ConvertPivotAnimationRecursive(NULL, KFbxNode::eDestinationPivot, KRAKEN_FBX_ANIMATION_FRAMERATE); -//// pNode->UpdatePropertiesFromPivotsAndLimits(); -// -// // ----====---- End: Bake pivots into transforms, as Kraken doesn't support them directly ----====---- -// // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====---- -// -// printf("Baking pivots...\n"); -// KFbxNode* pNode = ((KFbxScene*)pScene)->GetRootNode(); -// if(pNode) { -// pNode->ResetPivotSetAndConvertAnimation(); -// } - - // Destroy the importer. - lImporter->Destroy(); - - return lStatus; + if (lStatus == false && lImporter->GetStatus().GetCode() == FbxStatus::EStatusCode::ePasswordError) { + printf("\nPassword is wrong, import aborted.\n"); + } + } + + // // ----====---- Start: Bake pivots into transforms, as Kraken doesn't support them directly ----====---- + // + // printf("Baking pivots...\n"); + // KFbxNode* pNode = ((KFbxScene*)pScene)->GetRootNode(); + //// BakeNode(pNode); + // + // for(i = 0; i < lAnimStackCount; i++) + // { + // KFbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); + // + // printf(" Animation: \"%s\"\n", lTakeInfo->mName.Buffer()); + // + // //pNode->ConvertPivotAnimationRecursive(lTakeInfo->mName.Buffer(), KFbxNode::eDestinationPivot, KRAKEN_FBX_ANIMATION_FRAMERATE); + // pNode->ResetPivotSetAndConvertAnimation(); + // + // } + //// pNode->ConvertPivotAnimationRecursive(NULL, KFbxNode::eDestinationPivot, KRAKEN_FBX_ANIMATION_FRAMERATE); + //// pNode->UpdatePropertiesFromPivotsAndLimits(); + // + // // ----====---- End: Bake pivots into transforms, as Kraken doesn't support them directly ----====---- + + // // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====---- + // + // printf("Baking pivots...\n"); + // KFbxNode* pNode = ((KFbxScene*)pScene)->GetRootNode(); + // if(pNode) { + // pNode->ResetPivotSetAndConvertAnimation(); + // } + + // Destroy the importer. + lImporter->Destroy(); + + return lStatus; } -KRAnimation *LoadAnimation(KRContext &context, FbxAnimStack* pAnimStack) +KRAnimation* LoadAnimation(KRContext& context, FbxAnimStack* pAnimStack) { - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Loading animation: \"%s\"", pAnimStack->GetName()); - - KRAnimation *new_animation = new KRAnimation(context, pAnimStack->GetName()); - int cLayers = pAnimStack->GetMemberCount(); - new_animation->setDuration(pAnimStack->LocalStop.Get().GetSecondDouble()); - for(int iLayer=0; iLayer < cLayers; iLayer++) { - new_animation->addLayer(LoadAnimationLayer(context, pAnimStack->GetMember(iLayer))); - } - return new_animation; + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Loading animation: \"%s\"", pAnimStack->GetName()); + + KRAnimation* new_animation = new KRAnimation(context, pAnimStack->GetName()); + int cLayers = pAnimStack->GetMemberCount(); + new_animation->setDuration(pAnimStack->LocalStop.Get().GetSecondDouble()); + for (int iLayer = 0; iLayer < cLayers; iLayer++) { + new_animation->addLayer(LoadAnimationLayer(context, pAnimStack->GetMember(iLayer))); + } + return new_animation; } -KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurve) +KRAnimationCurve* LoadAnimationCurve(KRContext& context, FbxAnimCurve* pAnimCurve) { - std::string name = GetFbxObjectName(pAnimCurve); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Loading animation curve: \"%s\"", name.c_str()); - FbxTimeSpan time_span; - if(!pAnimCurve->GetTimeInterval(time_span)) { - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Failed to get time interval."); - return NULL; - } - - float dest_frame_rate = 30.0f; // FINDME, TODO - This needs to be dynamic - int frame_start = time_span.GetStart().GetSecondDouble() * dest_frame_rate; - int frame_count = (time_span.GetStop().GetSecondDouble() * dest_frame_rate) - frame_start; - - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " animation start %d and frame count %d", frame_start, frame_count); - - KRAnimationCurve *new_curve = new KRAnimationCurve(context, name); - new_curve->setFrameRate(dest_frame_rate); - new_curve->setFrameStart(frame_start); - new_curve->setFrameCount(frame_count); - - // Resample animation curve - int last_frame = 0; // Used by FBX sdk for faster keyframe searches - for(int frame_number=0; frame_number < frame_count; frame_number++) { - float frame_seconds = (frame_start + frame_number) / dest_frame_rate; - FbxTime frame_time; - frame_time.SetSecondDouble(frame_seconds); - float frame_value = pAnimCurve->Evaluate(frame_time, &last_frame); -// printf(" Frame %i / %i: %.6f\n", frame_number, frame_count, frame_value); - if (0 == frame_number) KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Value at starting key frame = %3.3f", frame_value); - new_curve->setValue(frame_number+frame_start, frame_value); - // BUG FIX Dec 2, 2013 .. changed frame_number to frame_number+frame_start - // setValue(frame_number, frame_value) clamps the frame_number range between frame_start : frame_start+frame_count - } + std::string name = GetFbxObjectName(pAnimCurve); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Loading animation curve: \"%s\"", name.c_str()); + FbxTimeSpan time_span; + if (!pAnimCurve->GetTimeInterval(time_span)) { + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Failed to get time interval."); + return NULL; + } - return new_curve; + float dest_frame_rate = 30.0f; // FINDME, TODO - This needs to be dynamic + int frame_start = time_span.GetStart().GetSecondDouble() * dest_frame_rate; + int frame_count = (time_span.GetStop().GetSecondDouble() * dest_frame_rate) - frame_start; + + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " animation start %d and frame count %d", frame_start, frame_count); + + KRAnimationCurve* new_curve = new KRAnimationCurve(context, name); + new_curve->setFrameRate(dest_frame_rate); + new_curve->setFrameStart(frame_start); + new_curve->setFrameCount(frame_count); + + // Resample animation curve + int last_frame = 0; // Used by FBX sdk for faster keyframe searches + for (int frame_number = 0; frame_number < frame_count; frame_number++) { + float frame_seconds = (frame_start + frame_number) / dest_frame_rate; + FbxTime frame_time; + frame_time.SetSecondDouble(frame_seconds); + float frame_value = pAnimCurve->Evaluate(frame_time, &last_frame); + // printf(" Frame %i / %i: %.6f\n", frame_number, frame_count, frame_value); + if (0 == frame_number) KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Value at starting key frame = %3.3f", frame_value); + new_curve->setValue(frame_number + frame_start, frame_value); + // BUG FIX Dec 2, 2013 .. changed frame_number to frame_number+frame_start + // setValue(frame_number, frame_value) clamps the frame_number range between frame_start : frame_start+frame_count + } + + return new_curve; } -KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLayer) +KRAnimationLayer* LoadAnimationLayer(KRContext& context, FbxAnimLayer* pAnimLayer) { - KRAnimationLayer *new_layer = new KRAnimationLayer(context); - new_layer->setName(pAnimLayer->GetName()); - new_layer->setWeight(pAnimLayer->Weight.Get() / 100.0f); - switch(pAnimLayer->BlendMode.Get()) { - case FbxAnimLayer::eBlendAdditive: - new_layer->setBlendMode(KRAnimationLayer::KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE); - break; - case FbxAnimLayer::eBlendOverride: - new_layer->setBlendMode(KRAnimationLayer::KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE); - break; - case FbxAnimLayer::eBlendOverridePassthrough: - new_layer->setBlendMode(KRAnimationLayer::KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH); - break; - } - switch(pAnimLayer->RotationAccumulationMode.Get()) { - case FbxAnimLayer::eRotationByLayer: - new_layer->setRotationAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER); - break; - case FbxAnimLayer::eRotationByChannel: - new_layer->setRotationAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL); - break; - } - switch(pAnimLayer->ScaleAccumulationMode.Get()) { - case FbxAnimLayer::eScaleAdditive: - new_layer->setScaleAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE); - break; - case FbxAnimLayer::eScaleMultiply: - new_layer->setScaleAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY); - break; - } - - return new_layer; + KRAnimationLayer* new_layer = new KRAnimationLayer(context); + new_layer->setName(pAnimLayer->GetName()); + new_layer->setWeight(pAnimLayer->Weight.Get() / 100.0f); + switch (pAnimLayer->BlendMode.Get()) { + case FbxAnimLayer::eBlendAdditive: + new_layer->setBlendMode(KRAnimationLayer::KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE); + break; + case FbxAnimLayer::eBlendOverride: + new_layer->setBlendMode(KRAnimationLayer::KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE); + break; + case FbxAnimLayer::eBlendOverridePassthrough: + new_layer->setBlendMode(KRAnimationLayer::KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH); + break; + } + switch (pAnimLayer->RotationAccumulationMode.Get()) { + case FbxAnimLayer::eRotationByLayer: + new_layer->setRotationAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER); + break; + case FbxAnimLayer::eRotationByChannel: + new_layer->setRotationAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL); + break; + } + switch (pAnimLayer->ScaleAccumulationMode.Get()) { + case FbxAnimLayer::eScaleAdditive: + new_layer->setScaleAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE); + break; + case FbxAnimLayer::eScaleMultiply: + new_layer->setScaleAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY); + break; + } + + return new_layer; } // //void BakeNode(KFbxNode *pNode) { @@ -600,804 +593,806 @@ KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLaye // } //} -void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode) { - FbxVector4 lTmpVector; - pNode->UpdatePropertiesFromPivotsAndLimits(); - - - FbxSystemUnit system_unit = pFbxScene->GetGlobalSettings().GetSystemUnit(); - - // Transform = T * Roff * Rp * Rpre * R * Rpost * inverse(Rp) * Soff * Sp * S * inverse(Sp) - - int node_has_n_points = 0; // this will be 3 if the node_frame_key_position is complete after the import animated properties loop - Vector3 node_key_frame_position = Vector3(0.0, 0.0, 0.0); - // ADDED 3, 2013 by Peter to store the key frame (start location) of an animation - // the x, y, z translation position of the animation will be extracted from the curves - // as they are added to the animation layer in the loop below .. - - // Import animated properties - int animation_count = pFbxScene->GetSrcObjectCount(); - for(int i = 0; i < animation_count; i++) { - // FbxAnimStack* pAnimStack = FbxCast(pFbxScene->GetSrcObject(FBX_TYPE(FbxAnimStack), i)); - FbxAnimStack* pAnimStack = pFbxScene->GetSrcObject(i); - KRAnimation *pAnimation = parent_node->getContext().getAnimationManager()->getAnimation(pAnimStack->GetName()); - if(pAnimation) { - int cLayers = pAnimStack->GetMemberCount(); - for(int iLayer=0; iLayer < cLayers; iLayer++) { - FbxAnimLayer *pFbxAnimLayer = pAnimStack->GetMember(iLayer); -// float weight = pFbxAnimLayer->Weight.Get(); - KRAnimationLayer *pAnimationLayer = pAnimation->getLayer(pFbxAnimLayer->GetName()); - - FbxAnimCurve *pAnimCurve = pNode->LclRotation.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_X); - pAnimationLayer->addAttribute(new_attribute); - } - - pAnimCurve = pNode->LclRotation.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_Y); - pAnimationLayer->addAttribute(new_attribute); - } - - pAnimCurve = pNode->LclRotation.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_Z); - pAnimationLayer->addAttribute(new_attribute); - } - - pAnimCurve = pNode->LclTranslation.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_TRANSLATE_X); - - KRAnimationCurve *curve = new_attribute->getCurve(); - node_key_frame_position.x = curve->getValue(curve->getFrameStart()); - node_has_n_points++; - // ADDED Dec 3, 2013 by Peter to extract start location key frame - - pAnimationLayer->addAttribute(new_attribute); - } - - pAnimCurve = pNode->LclTranslation.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_TRANSLATE_Y); - - KRAnimationCurve *curve = new_attribute->getCurve(); - node_key_frame_position.y = curve->getValue(curve->getFrameStart()); - node_has_n_points++; - // ADDED Dec 3, 2013 by Peter to extract start location key frame - - pAnimationLayer->addAttribute(new_attribute); - } - - pAnimCurve = pNode->LclTranslation.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_TRANSLATE_Z); - - KRAnimationCurve *curve = new_attribute->getCurve(); - node_key_frame_position.z = curve->getValue(curve->getFrameStart()); - node_has_n_points++; - // ADDED Dec 3, 2013 by Peter to extract start location key frame - - pAnimationLayer->addAttribute(new_attribute); - } - - pAnimCurve = pNode->LclScaling.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_X); - pAnimationLayer->addAttribute(new_attribute); - } - - pAnimCurve = pNode->LclScaling.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_Y); - pAnimationLayer->addAttribute(new_attribute); - } - - pAnimCurve = pNode->LclScaling.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_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); - } - } - } - } - - FbxDouble3 local_rotation = pNode->LclRotation.Get(); // pNode->GetGeometricRotation(KFbxNode::eSourcePivot); - 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(); - FbxDouble3 scaling_offset = pNode->ScalingOffset.Get(); - FbxDouble3 rotation_pivot = pNode->RotationPivot.Get(); - FbxDouble3 scaling_pivot = pNode->ScalingPivot.Get(); - FbxDouble3 geometric_rotation = pNode->GeometricRotation.Get(); - FbxDouble3 geometric_translation = pNode->GeometricTranslation.Get(); - FbxDouble3 geometric_scaling = pNode->GeometricScaling.Get(); - EFbxRotationOrder rotation_order = pNode->RotationOrder.Get(); - - - FbxVector4 lZero(0.0, 0.0, 0.0); - FbxVector4 lOne(1.0, 1.0, 1.0); - - warning((geometric_rotation == lZero), "Geometric Rotation not supported .. 3DSMax file??"); - warning((geometric_translation == lZero), "Geometric Rotation not supported .. 3DSMax file??"); - warning((geometric_scaling == lOne), "Geometric Rotation not supported .. 3DSMax file??"); - warning((rotation_order == eEulerXYZ), "Geometric Rotation not supported .. 3DSMax file??"); - - // FINDME - node_key_frame_position contains the key frame (start location) for an animation node - // node_has_n_points - // node_key_frame_position - if (3 == node_has_n_points) - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "key frame at %2.3f, %2.3f, %2.3f", - node_key_frame_position.x, - node_key_frame_position.y, - node_key_frame_position.z); - // - // The animation curve data is output to the KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_ X, Y, Z attribute targets - // The actor scripts 'move' command modifies the node's world translations using setWorldTranslation() - // - // QUESTION - where should we store the key frame within the node to make sure it is output into the KRBundle ?? - // do we store it as node_local or store it as the world translation? or somewhere else ?? - // +void LoadNode(FbxScene* pFbxScene, KRNode* parent_node, FbxGeometryConverter* pGeometryConverter, FbxNode* pNode) +{ + FbxVector4 lTmpVector; + pNode->UpdatePropertiesFromPivotsAndLimits(); - Vector3 node_translation = Vector3(local_translation[0], local_translation[1], local_translation[2]); // T * Roff * Rp - Vector3 node_rotation = Vector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI; - Vector3 node_scale = Vector3(local_scale[0], local_scale[1], local_scale[2]); - - Vector3 node_rotation_offset = Vector3(rotation_offset[0], rotation_offset[1], rotation_offset[2]); - Vector3 node_scaling_offset = Vector3(scaling_offset[0], scaling_offset[1], scaling_offset[2]); - Vector3 node_rotation_pivot = Vector3(rotation_pivot[0], rotation_pivot[1], rotation_pivot[2]); - Vector3 node_scaling_pivot = Vector3(scaling_pivot[0], scaling_pivot[1], scaling_pivot[2]); - Vector3 node_pre_rotation, node_post_rotation; - if(rotation_active) { - node_pre_rotation = Vector3(pre_rotation[0], pre_rotation[1], pre_rotation[2]) / 180.0 * M_PI; - node_post_rotation = Vector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI; - //&KRF HACK removing this line (above) to prevent the post rotation from corrupting the default light values; the FBX is importing a post rotation and setting it to -90 degrees - } else { - node_pre_rotation = Vector3::Zero(); - node_post_rotation = Vector3::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]); -// printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]); - - FbxNodeAttribute::EType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType()); - if(attribute_type == FbxNodeAttribute::eLODGroup) { - std::string name = GetFbxObjectName(pNode); - FbxLODGroup *fbx_lod_group = (FbxLODGroup*) pNode->GetNodeAttribute(); // FbxCast(pNode); - bool use_world_space_units = fbx_lod_group->WorldSpace.Get(); - float group_min_distance = 0.0f; - float group_max_distance = 0.0f; - if(fbx_lod_group->MinMaxDistance.Get()) { - group_min_distance = fbx_lod_group->MinDistance.Get(); - group_max_distance = fbx_lod_group->MaxDistance.Get(); - } - - KRLODSet *lod_set = new KRLODSet(parent_node->getScene(), name); - parent_node->addChild(lod_set); - - AABB reference_bounds; - // Create a lod_group node for each fbx child node - int child_count = pNode->GetChildCount(); - for(int i = 0; i < child_count; i++) - { - float min_distance = 0; - float max_distance = 0; // 0 for max_distance means infinity - FbxLODGroup::EDisplayLevel display_level; - fbx_lod_group->GetDisplayLevel(i, display_level); - switch(display_level) { - case FbxLODGroup::eUseLOD: - if(i > 0 ) { - FbxDistance d; - fbx_lod_group->GetThreshold(i - 1, d); - min_distance = d.valueAs(system_unit); - } - if(i < child_count - 1) { - FbxDistance d; - fbx_lod_group->GetThreshold(i, d); - max_distance = d.valueAs(system_unit); - } - break; - case FbxLODGroup::eShow: - // We leave min_distance and max_distance as 0's, which effectively makes the LOD group always visible - break; - case FbxLODGroup::eHide: - min_distance = -1; - max_distance = -1; - // LOD Groups with -1 for both min_distance and max_distance will never be displayed; import in case that the distance values are to be modified by scripting at runtime - break; - } - - if(group_min_distance != 0.0f && min_distance != -1) { - if(min_distance < group_min_distance) min_distance = group_min_distance; - } - if(group_max_distance != 0.0f && max_distance != -1) { - if(max_distance == 0.0f) { - max_distance = group_max_distance; - } else if(max_distance > group_max_distance) { - max_distance = group_max_distance; - } - } - KRLODGroup *new_node = new KRLODGroup(parent_node->getScene(), name + "_lodlevel" + boost::lexical_cast(i + 1)); - new_node->setMinDistance(min_distance); - new_node->setMaxDistance(max_distance); - new_node->setLocalRotation(node_rotation); - new_node->setLocalTranslation(node_translation); - new_node->setLocalScale(node_scale); - - - new_node->setRotationOffset(node_rotation_offset); - new_node->setScalingOffset(node_scaling_offset); - new_node->setRotationPivot(node_rotation_pivot); - new_node->setScalingPivot(node_scaling_pivot); - new_node->setPreRotation(node_pre_rotation); - new_node->setPostRotation(node_post_rotation); - - new_node->setUseWorldUnits(use_world_space_units); - lod_set->addChild(new_node); - - LoadNode(pFbxScene, new_node, pGeometryConverter, pNode->GetChild(i)); - - if(i == 0) { - // Calculate reference point using the bounding box center from the highest quality LOD level - reference_bounds = new_node->getBounds(); - } - - new_node->setReference(AABB(reference_bounds.min, reference_bounds.max, new_node->getInverseModelMatrix())); - } - } else { - KRNode *new_node = NULL; - switch(attribute_type) { - case FbxNodeAttribute::eMesh: - new_node = LoadMesh(parent_node, pFbxScene, pGeometryConverter, pNode); - break; - case FbxNodeAttribute::eLight: - new_node = LoadLight(parent_node, pNode); - break; - case FbxNodeAttribute::eSkeleton: - new_node = LoadSkeleton(parent_node, pFbxScene, pNode); - break; + FbxSystemUnit system_unit = pFbxScene->GetGlobalSettings().GetSystemUnit(); - case FbxNodeAttribute::eCamera: - new_node = LoadCamera(parent_node, pNode); - break; - default: - { - bool is_locator = false; - if(attribute_type == FbxNodeAttribute::eNull) { - FbxNull* pSourceNull = (FbxNull*) pNode->GetNodeAttribute(); - if(pSourceNull->Look.Get() == FbxNull::eCross ) { - is_locator = true; - } - } - - if(is_locator) { - new_node = LoadLocator(parent_node, pFbxScene, pNode); - } else { - if(pNode->GetChildCount() > 0) { - // Create an empty node, for inheritence of transforms - std::string name = GetFbxObjectName(pNode); - new_node = new KRNode(parent_node->getScene(), name); - } - } - } - break; + // Transform = T * Roff * Rp * Rpre * R * Rpost * inverse(Rp) * Soff * Sp * S * inverse(Sp) + + int node_has_n_points = 0; // this will be 3 if the node_frame_key_position is complete after the import animated properties loop + Vector3 node_key_frame_position = Vector3(0.0, 0.0, 0.0); + // ADDED 3, 2013 by Peter to store the key frame (start location) of an animation + // the x, y, z translation position of the animation will be extracted from the curves + // as they are added to the animation layer in the loop below .. + +// Import animated properties + int animation_count = pFbxScene->GetSrcObjectCount(); + for (int i = 0; i < animation_count; i++) { + // FbxAnimStack* pAnimStack = FbxCast(pFbxScene->GetSrcObject(FBX_TYPE(FbxAnimStack), i)); + FbxAnimStack* pAnimStack = pFbxScene->GetSrcObject(i); + KRAnimation* pAnimation = parent_node->getContext().getAnimationManager()->getAnimation(pAnimStack->GetName()); + if (pAnimation) { + int cLayers = pAnimStack->GetMemberCount(); + for (int iLayer = 0; iLayer < cLayers; iLayer++) { + FbxAnimLayer* pFbxAnimLayer = pAnimStack->GetMember(iLayer); + // float weight = pFbxAnimLayer->Weight.Get(); + KRAnimationLayer* pAnimationLayer = pAnimation->getLayer(pFbxAnimLayer->GetName()); + + FbxAnimCurve* pAnimCurve = pNode->LclRotation.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_X); + pAnimationLayer->addAttribute(new_attribute); } - - // this is a KRNode - if(new_node != NULL) { - new_node->setLocalRotation(node_rotation); - new_node->setLocalTranslation(node_translation); - new_node->setLocalScale(node_scale); - new_node->setRotationOffset(node_rotation_offset); - new_node->setScalingOffset(node_scaling_offset); - new_node->setRotationPivot(node_rotation_pivot); - new_node->setScalingPivot(node_scaling_pivot); - new_node->setPreRotation(node_pre_rotation); - new_node->setPostRotation(node_post_rotation); - parent_node->addChild(new_node); - - // Load child nodes - for(int i = 0; i < pNode->GetChildCount(); i++) - { - LoadNode(pFbxScene, new_node, pGeometryConverter, pNode->GetChild(i)); - } + + pAnimCurve = pNode->LclRotation.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_Y); + pAnimationLayer->addAttribute(new_attribute); } + + pAnimCurve = pNode->LclRotation.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_Z); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->LclTranslation.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_TRANSLATE_X); + + KRAnimationCurve* curve = new_attribute->getCurve(); + node_key_frame_position.x = curve->getValue(curve->getFrameStart()); + node_has_n_points++; + // ADDED Dec 3, 2013 by Peter to extract start location key frame + + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->LclTranslation.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_TRANSLATE_Y); + + KRAnimationCurve* curve = new_attribute->getCurve(); + node_key_frame_position.y = curve->getValue(curve->getFrameStart()); + node_has_n_points++; + // ADDED Dec 3, 2013 by Peter to extract start location key frame + + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->LclTranslation.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_TRANSLATE_Z); + + KRAnimationCurve* curve = new_attribute->getCurve(); + node_key_frame_position.z = curve->getValue(curve->getFrameStart()); + node_has_n_points++; + // ADDED Dec 3, 2013 by Peter to extract start location key frame + + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->LclScaling.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_X); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->LclScaling.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_Y); + pAnimationLayer->addAttribute(new_attribute); + } + + pAnimCurve = pNode->LclScaling.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_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); + } + } } + } + + FbxDouble3 local_rotation = pNode->LclRotation.Get(); // pNode->GetGeometricRotation(KFbxNode::eSourcePivot); + 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(); + FbxDouble3 scaling_offset = pNode->ScalingOffset.Get(); + FbxDouble3 rotation_pivot = pNode->RotationPivot.Get(); + FbxDouble3 scaling_pivot = pNode->ScalingPivot.Get(); + FbxDouble3 geometric_rotation = pNode->GeometricRotation.Get(); + FbxDouble3 geometric_translation = pNode->GeometricTranslation.Get(); + FbxDouble3 geometric_scaling = pNode->GeometricScaling.Get(); + EFbxRotationOrder rotation_order = pNode->RotationOrder.Get(); + + + FbxVector4 lZero(0.0, 0.0, 0.0); + FbxVector4 lOne(1.0, 1.0, 1.0); + + warning((geometric_rotation == lZero), "Geometric Rotation not supported .. 3DSMax file??"); + warning((geometric_translation == lZero), "Geometric Rotation not supported .. 3DSMax file??"); + warning((geometric_scaling == lOne), "Geometric Rotation not supported .. 3DSMax file??"); + warning((rotation_order == eEulerXYZ), "Geometric Rotation not supported .. 3DSMax file??"); + + // FINDME - node_key_frame_position contains the key frame (start location) for an animation node + // node_has_n_points + // node_key_frame_position + if (3 == node_has_n_points) + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "key frame at %2.3f, %2.3f, %2.3f", + node_key_frame_position.x, + node_key_frame_position.y, + node_key_frame_position.z); + // + // The animation curve data is output to the KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_ X, Y, Z attribute targets + // The actor scripts 'move' command modifies the node's world translations using setWorldTranslation() + // + // QUESTION - where should we store the key frame within the node to make sure it is output into the KRBundle ?? + // do we store it as node_local or store it as the world translation? or somewhere else ?? + // + + Vector3 node_translation = Vector3(local_translation[0], local_translation[1], local_translation[2]); // T * Roff * Rp + Vector3 node_rotation = Vector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI; + Vector3 node_scale = Vector3(local_scale[0], local_scale[1], local_scale[2]); + + Vector3 node_rotation_offset = Vector3(rotation_offset[0], rotation_offset[1], rotation_offset[2]); + Vector3 node_scaling_offset = Vector3(scaling_offset[0], scaling_offset[1], scaling_offset[2]); + Vector3 node_rotation_pivot = Vector3(rotation_pivot[0], rotation_pivot[1], rotation_pivot[2]); + Vector3 node_scaling_pivot = Vector3(scaling_pivot[0], scaling_pivot[1], scaling_pivot[2]); + Vector3 node_pre_rotation, node_post_rotation; + if (rotation_active) { + node_pre_rotation = Vector3(pre_rotation[0], pre_rotation[1], pre_rotation[2]) / 180.0 * M_PI; + node_post_rotation = Vector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI; + //&KRF HACK removing this line (above) to prevent the post rotation from corrupting the default light values; the FBX is importing a post rotation and setting it to -90 degrees + } else { + node_pre_rotation = Vector3::Zero(); + node_post_rotation = Vector3::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]); + // printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]); + + FbxNodeAttribute::EType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType()); + if (attribute_type == FbxNodeAttribute::eLODGroup) { + std::string name = GetFbxObjectName(pNode); + FbxLODGroup* fbx_lod_group = (FbxLODGroup*)pNode->GetNodeAttribute(); // FbxCast(pNode); + bool use_world_space_units = fbx_lod_group->WorldSpace.Get(); + float group_min_distance = 0.0f; + float group_max_distance = 0.0f; + if (fbx_lod_group->MinMaxDistance.Get()) { + group_min_distance = fbx_lod_group->MinDistance.Get(); + group_max_distance = fbx_lod_group->MaxDistance.Get(); + } + + KRLODSet* lod_set = new KRLODSet(parent_node->getScene(), name); + parent_node->addChild(lod_set); + + AABB reference_bounds; + // Create a lod_group node for each fbx child node + int child_count = pNode->GetChildCount(); + for (int i = 0; i < child_count; i++) { + float min_distance = 0; + float max_distance = 0; // 0 for max_distance means infinity + FbxLODGroup::EDisplayLevel display_level; + fbx_lod_group->GetDisplayLevel(i, display_level); + switch (display_level) { + case FbxLODGroup::eUseLOD: + if (i > 0) { + FbxDistance d; + fbx_lod_group->GetThreshold(i - 1, d); + min_distance = d.valueAs(system_unit); + } + if (i < child_count - 1) { + FbxDistance d; + fbx_lod_group->GetThreshold(i, d); + max_distance = d.valueAs(system_unit); + } + break; + case FbxLODGroup::eShow: + // We leave min_distance and max_distance as 0's, which effectively makes the LOD group always visible + break; + case FbxLODGroup::eHide: + min_distance = -1; + max_distance = -1; + // LOD Groups with -1 for both min_distance and max_distance will never be displayed; import in case that the distance values are to be modified by scripting at runtime + break; + } + + if (group_min_distance != 0.0f && min_distance != -1) { + if (min_distance < group_min_distance) min_distance = group_min_distance; + } + if (group_max_distance != 0.0f && max_distance != -1) { + if (max_distance == 0.0f) { + max_distance = group_max_distance; + } else if (max_distance > group_max_distance) { + max_distance = group_max_distance; + } + } + + KRLODGroup* new_node = new KRLODGroup(parent_node->getScene(), name + "_lodlevel" + boost::lexical_cast(i + 1)); + new_node->setMinDistance(min_distance); + new_node->setMaxDistance(max_distance); + new_node->setLocalRotation(node_rotation); + new_node->setLocalTranslation(node_translation); + new_node->setLocalScale(node_scale); + + + new_node->setRotationOffset(node_rotation_offset); + new_node->setScalingOffset(node_scaling_offset); + new_node->setRotationPivot(node_rotation_pivot); + new_node->setScalingPivot(node_scaling_pivot); + new_node->setPreRotation(node_pre_rotation); + new_node->setPostRotation(node_post_rotation); + + new_node->setUseWorldUnits(use_world_space_units); + lod_set->addChild(new_node); + + LoadNode(pFbxScene, new_node, pGeometryConverter, pNode->GetChild(i)); + + if (i == 0) { + // Calculate reference point using the bounding box center from the highest quality LOD level + reference_bounds = new_node->getBounds(); + } + + new_node->setReference(AABB(reference_bounds.min, reference_bounds.max, new_node->getInverseModelMatrix())); + } + } else { + KRNode* new_node = NULL; + switch (attribute_type) { + case FbxNodeAttribute::eMesh: + new_node = LoadMesh(parent_node, pFbxScene, pGeometryConverter, pNode); + break; + case FbxNodeAttribute::eLight: + new_node = LoadLight(parent_node, pNode); + break; + case FbxNodeAttribute::eSkeleton: + new_node = LoadSkeleton(parent_node, pFbxScene, pNode); + break; + + case FbxNodeAttribute::eCamera: + new_node = LoadCamera(parent_node, pNode); + break; + default: + { + bool is_locator = false; + if (attribute_type == FbxNodeAttribute::eNull) { + FbxNull* pSourceNull = (FbxNull*)pNode->GetNodeAttribute(); + if (pSourceNull->Look.Get() == FbxNull::eCross) { + is_locator = true; + } + } + + if (is_locator) { + new_node = LoadLocator(parent_node, pFbxScene, pNode); + } else { + if (pNode->GetChildCount() > 0) { + // Create an empty node, for inheritence of transforms + std::string name = GetFbxObjectName(pNode); + new_node = new KRNode(parent_node->getScene(), name); + } + } + } + break; + } + + // this is a KRNode + if (new_node != NULL) { + new_node->setLocalRotation(node_rotation); + new_node->setLocalTranslation(node_translation); + new_node->setLocalScale(node_scale); + new_node->setRotationOffset(node_rotation_offset); + new_node->setScalingOffset(node_scaling_offset); + new_node->setRotationPivot(node_rotation_pivot); + new_node->setScalingPivot(node_scaling_pivot); + new_node->setPreRotation(node_pre_rotation); + new_node->setPostRotation(node_post_rotation); + parent_node->addChild(new_node); + + // Load child nodes + for (int i = 0; i < pNode->GetChildCount(); i++) { + LoadNode(pFbxScene, new_node, pGeometryConverter, pNode->GetChild(i)); + } + } + } } -void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { - //printf(" %s: %i - %i\n", pMaterial->GetName(), mat_vertex_start, mat_vertex_count + mat_vertex_start - 1); - - // ----====---- Output Material File ----====---- - KRMaterial *new_material = new KRMaterial(context, pMaterial->GetName()); - - std::string name = pMaterial->GetName(); - if(boost::starts_with(name, "ab_reflect_")) { - new_material->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE); - size_t underscore_pos = name.find('_', 11); - new_material->setReflectionCube(name.substr(11, underscore_pos - 11)); - } else if(boost::starts_with(name, "reflect_")) { - size_t underscore_pos = name.find('_', 8); - new_material->setReflectionCube(name.substr(8, underscore_pos - 8)); - } else if(boost::starts_with(name, "at_")) { - new_material->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_TEST); - } else if(boost::starts_with(name, "ab_")) { - new_material->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE); - } else if(boost::starts_with(name, "ab2_")) { - new_material->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); - } +void LoadMaterial(KRContext& context, FbxSurfaceMaterial* pMaterial) +{ + //printf(" %s: %i - %i\n", pMaterial->GetName(), mat_vertex_start, mat_vertex_count + mat_vertex_start - 1); - FbxPropertyT lKFbxDouble3; - FbxPropertyT lKFbxDouble1; - - if (pMaterial->GetClassId().Is(FbxSurfacePhong::ClassId)) { - // We found a Phong material. - - // Ambient Color - lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Ambient; - new_material->setAmbient(Vector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); - - // Diffuse Color - lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Diffuse; - new_material->setDiffuse(Vector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); - - // Specular Color (unique to Phong materials) - lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Specular; - new_material->setSpecular(Vector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); - - // Emissive Color - //lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Emissive; - - /* - // Transparency - lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->TransparencyFactor; - new_material->setTransparency(1.0f - lKFbxDouble1.Get()); - */ - - // Shininess - lKFbxDouble1 =((FbxSurfacePhong *) pMaterial)->Shininess; - new_material->setShininess(lKFbxDouble1.Get()); - - /* - // Specular Factor - lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->SpecularFactor; - double specular_factor = lKFbxDouble1.Get(); - */ - - // Transparency Color - lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->TransparentColor; - new_material->setTransparency( 1.0f - (lKFbxDouble3.Get()[0] + lKFbxDouble3.Get()[1] + lKFbxDouble3.Get()[2]) / 3.0f); - - // Reflection factor - lKFbxDouble1 =((FbxSurfacePhong *) pMaterial)->ReflectionFactor; - - // Reflection color - //lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Reflection; - - // We modulate Relection color by reflection factor, as we only have one "reflection color" variable in Kraken - new_material->setReflection(Vector3(/*lKFbxDouble3.Get()[0] * */lKFbxDouble1.Get(), /*lKFbxDouble3.Get()[1] * */lKFbxDouble1.Get(), /*lKFbxDouble3.Get()[2] * */lKFbxDouble1.Get())); - - } else if(pMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId) ) { - // We found a Lambert material. - - // Ambient Color - lKFbxDouble3=((FbxSurfaceLambert *)pMaterial)->Ambient; - new_material->setAmbient(Vector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); - - // Diffuse Color - lKFbxDouble3 =((FbxSurfaceLambert *)pMaterial)->Diffuse; - new_material->setDiffuse(Vector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); - - // Emissive - //lKFbxDouble3 =((KFbxSurfaceLambert *)pMaterial)->Emissive; - /* - // Opacity - lKFbxDouble1 =((KFbxSurfaceLambert *)pMaterial)->TransparencyFactor; - new_material->setTransparency(1.0f - lKFbxDouble1.Get()); - */ - - // Transparency Color - lKFbxDouble3 =((FbxSurfaceLambert *) pMaterial)->TransparentColor; - new_material->setTransparency(1.0f - (lKFbxDouble3.Get()[0] + lKFbxDouble3.Get()[1] + lKFbxDouble3.Get()[2]) / 3.0f); - - } else { - KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Unable to convert material: %s", pMaterial->GetName()); + // ----====---- Output Material File ----====---- + KRMaterial* new_material = new KRMaterial(context, pMaterial->GetName()); + + std::string name = pMaterial->GetName(); + if (boost::starts_with(name, "ab_reflect_")) { + new_material->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE); + size_t underscore_pos = name.find('_', 11); + new_material->setReflectionCube(name.substr(11, underscore_pos - 11)); + } else if (boost::starts_with(name, "reflect_")) { + size_t underscore_pos = name.find('_', 8); + new_material->setReflectionCube(name.substr(8, underscore_pos - 8)); + } else if (boost::starts_with(name, "at_")) { + new_material->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_TEST); + } else if (boost::starts_with(name, "ab_")) { + new_material->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE); + } else if (boost::starts_with(name, "ab2_")) { + new_material->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); + } + + FbxPropertyT lKFbxDouble3; + FbxPropertyT lKFbxDouble1; + + if (pMaterial->GetClassId().Is(FbxSurfacePhong::ClassId)) { + // We found a Phong material. + + // Ambient Color + lKFbxDouble3 = ((FbxSurfacePhong*)pMaterial)->Ambient; + new_material->setAmbient(Vector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); + + // Diffuse Color + lKFbxDouble3 = ((FbxSurfacePhong*)pMaterial)->Diffuse; + new_material->setDiffuse(Vector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); + + // Specular Color (unique to Phong materials) + lKFbxDouble3 = ((FbxSurfacePhong*)pMaterial)->Specular; + new_material->setSpecular(Vector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); + + // Emissive Color + //lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Emissive; + + /* + // Transparency + lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->TransparencyFactor; + new_material->setTransparency(1.0f - lKFbxDouble1.Get()); + */ + + // Shininess + lKFbxDouble1 = ((FbxSurfacePhong*)pMaterial)->Shininess; + new_material->setShininess(lKFbxDouble1.Get()); + + /* + // Specular Factor + lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->SpecularFactor; + double specular_factor = lKFbxDouble1.Get(); + */ + + // Transparency Color + lKFbxDouble3 = ((FbxSurfacePhong*)pMaterial)->TransparentColor; + new_material->setTransparency(1.0f - (lKFbxDouble3.Get()[0] + lKFbxDouble3.Get()[1] + lKFbxDouble3.Get()[2]) / 3.0f); + + // Reflection factor + lKFbxDouble1 = ((FbxSurfacePhong*)pMaterial)->ReflectionFactor; + + // Reflection color + //lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Reflection; + + // We modulate Relection color by reflection factor, as we only have one "reflection color" variable in Kraken + new_material->setReflection(Vector3(/*lKFbxDouble3.Get()[0] * */lKFbxDouble1.Get(), /*lKFbxDouble3.Get()[1] * */lKFbxDouble1.Get(), /*lKFbxDouble3.Get()[2] * */lKFbxDouble1.Get())); + + } else if (pMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId)) { + // We found a Lambert material. + + // Ambient Color + lKFbxDouble3 = ((FbxSurfaceLambert*)pMaterial)->Ambient; + new_material->setAmbient(Vector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); + + // Diffuse Color + lKFbxDouble3 = ((FbxSurfaceLambert*)pMaterial)->Diffuse; + new_material->setDiffuse(Vector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2])); + + // Emissive + //lKFbxDouble3 =((KFbxSurfaceLambert *)pMaterial)->Emissive; + /* + // Opacity + lKFbxDouble1 =((KFbxSurfaceLambert *)pMaterial)->TransparencyFactor; + new_material->setTransparency(1.0f - lKFbxDouble1.Get()); + */ + + // Transparency Color + lKFbxDouble3 = ((FbxSurfaceLambert*)pMaterial)->TransparentColor; + new_material->setTransparency(1.0f - (lKFbxDouble3.Get()[0] + lKFbxDouble3.Get()[1] + lKFbxDouble3.Get()[2]) / 3.0f); + + } else { + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Unable to convert material: %s", pMaterial->GetName()); + } + + FbxProperty pProperty; + + // Diffuse Map Texture + pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse); + if (pProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxLayeredTexture::ClassId)) > 0) { + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Layered textures not supported."); + } + + int texture_count = pProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxTexture::ClassId)); + if (texture_count > 1) { + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Multiple diffuse textures not supported."); + } else if (texture_count == 1) { + FbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(FbxCriteria::ObjectType(FbxTexture::ClassId), 0)); + assert(!pTexture->GetSwapUV()); + assert(pTexture->GetCroppingTop() == 0); + assert(pTexture->GetCroppingLeft() == 0); + assert(pTexture->GetCroppingRight() == 0); + assert(pTexture->GetCroppingBottom() == 0); + assert(pTexture->GetWrapModeU() == FbxTexture::eRepeat); + assert(pTexture->GetWrapModeV() == FbxTexture::eRepeat); + assert(pTexture->GetRotationU() == 0.0f); + assert(pTexture->GetRotationV() == 0.0f); + assert(pTexture->GetRotationW() == 0.0f); + + FbxFileTexture* pFileTexture = FbxCast(pTexture); + if (pFileTexture) { + new_material->setDiffuseMap(KRResource::GetFileBase(pFileTexture->GetFileName()), Vector2(pTexture->GetScaleU(), pTexture->GetScaleV()), Vector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); } - - FbxProperty pProperty; - - // Diffuse Map Texture - pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse); - if(pProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxLayeredTexture::ClassId)) > 0) { - KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Layered textures not supported."); + } + + + // Specular Map Texture + pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sSpecular); + if (pProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxLayeredTexture::ClassId)) > 0) { + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Layered textures not supported."); + } + texture_count = pProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxTexture::ClassId)); + if (texture_count > 1) { + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Multiple specular textures not supported."); + } else if (texture_count == 1) { + FbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(FbxCriteria::ObjectType(FbxTexture::ClassId), 0)); + FbxFileTexture* pFileTexture = FbxCast(pTexture); + if (pFileTexture) { + new_material->setSpecularMap(KRResource::GetFileBase(pFileTexture->GetFileName()), Vector2(pTexture->GetScaleU(), pTexture->GetScaleV()), Vector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); } - - int texture_count = pProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxTexture::ClassId)); - if(texture_count > 1) { - KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Multiple diffuse textures not supported."); - } else if(texture_count == 1) { - FbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(FbxCriteria::ObjectType(FbxTexture::ClassId),0)); - assert(!pTexture->GetSwapUV()); - assert(pTexture->GetCroppingTop() == 0); - assert(pTexture->GetCroppingLeft() == 0); - assert(pTexture->GetCroppingRight() == 0); - assert(pTexture->GetCroppingBottom() == 0); - assert(pTexture->GetWrapModeU() == FbxTexture::eRepeat); - assert(pTexture->GetWrapModeV() == FbxTexture::eRepeat); - assert(pTexture->GetRotationU() == 0.0f); - assert(pTexture->GetRotationV() == 0.0f); - assert(pTexture->GetRotationW() == 0.0f); - - FbxFileTexture *pFileTexture = FbxCast(pTexture); - if(pFileTexture) { - new_material->setDiffuseMap(KRResource::GetFileBase(pFileTexture->GetFileName()), Vector2(pTexture->GetScaleU(), pTexture->GetScaleV()), Vector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); - } - } - - - // Specular Map Texture - pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sSpecular); - if(pProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxLayeredTexture::ClassId)) > 0) { - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Layered textures not supported."); - } - texture_count = pProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxTexture::ClassId)); - if(texture_count > 1) { - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Multiple specular textures not supported."); - } else if(texture_count == 1) { - FbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(FbxCriteria::ObjectType(FbxTexture::ClassId),0)); - FbxFileTexture *pFileTexture = FbxCast(pTexture); - if(pFileTexture) { - new_material->setSpecularMap(KRResource::GetFileBase(pFileTexture->GetFileName()), Vector2(pTexture->GetScaleU(), pTexture->GetScaleV()), Vector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); - } - } - - // Normal Map Texture - pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sNormalMap); - if(pProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxLayeredTexture::ClassId)) > 0) { - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Layered textures not supported."); - } - - - texture_count = pProperty.GetSrcObjectCount(); - if(texture_count > 1) { - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Multiple normal map textures not supported."); - } else if(texture_count == 1) { - FbxTexture* pTexture = pProperty.GetSrcObject(0); - FbxFileTexture *pFileTexture = FbxCast(pTexture); - if(pFileTexture) { - new_material->setNormalMap(KRResource::GetFileBase(pFileTexture->GetFileName()), Vector2(pTexture->GetScaleU(), pTexture->GetScaleV()), Vector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); - } - } - - // Only save unique materials - KRMaterial *found_material = context.getMaterialManager()->getMaterial(new_material->getName()); - if(found_material == NULL) { - context.getMaterialManager()->add(new_material); - } else { - delete new_material; + } + + // Normal Map Texture + pProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sNormalMap); + if (pProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxLayeredTexture::ClassId)) > 0) { + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Layered textures not supported."); + } + + + texture_count = pProperty.GetSrcObjectCount(); + if (texture_count > 1) { + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Multiple normal map textures not supported."); + } else if (texture_count == 1) { + FbxTexture* pTexture = pProperty.GetSrcObject(0); + FbxFileTexture* pFileTexture = FbxCast(pTexture); + if (pFileTexture) { + new_material->setNormalMap(KRResource::GetFileBase(pFileTexture->GetFileName()), Vector2(pTexture->GetScaleU(), pTexture->GetScaleV()), Vector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); } + } + + // Only save unique materials + KRMaterial* found_material = context.getMaterialManager()->getMaterial(new_material->getName()); + if (found_material == NULL) { + context.getMaterialManager()->add(new_material); + } else { + delete new_material; + } } -void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxMesh* pMesh) { - KRMesh::mesh_info mi; - mi.format = ModelFormat::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(); - FbxVector4* control_points = pMesh->GetControlPoints(); - - 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; iGetControlPointsCount(); + FbxVector4* control_points = pMesh->GetControlPoints(); + + 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; + control_point_weights[control_point].bone_indexes[i] = 0; + } + + } + + bool too_many_bone_weights = false; + + // Collect the top 4 bone weights per vertex ... + int skin_count = pMesh->GetDeformerCount(FbxDeformer::eSkin); + int target_bone_index = 0; + for (int skin_index = 0; skin_index < skin_count; skin_index++) { + FbxSkin* skin = (FbxSkin*)pMesh->GetDeformer(skin_index, FbxDeformer::eSkin); + int cluster_count = skin->GetClusterCount(); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Found skin with %i clusters.\n", cluster_count); + for (int cluster_index = 0; cluster_index < cluster_count; cluster_index++) { + FbxCluster* cluster = skin->GetCluster(cluster_index); + if (cluster->GetLinkMode() != FbxCluster::eNormalize) { + KRContext::Log(KRContext::LOG_LEVEL_WARNING, " Warning! link mode not supported."); + } + std::string bone_name = GetFbxObjectName(cluster->GetLink()); + mi.bone_names.push_back(bone_name); + + /* + FbxMatrix fbx_bind_pose_matrix; + Matrix4 bind_pose; + PoseList pose_list; + FbxArray pose_indices; + if(FbxPose::GetBindPoseContaining(pFbxScene, cluster->GetLink(), pose_list, pose_indices)) { + fbx_bind_pose_matrix = (*pose_list)[0].GetMatrix(pose_indices[0]); + bind_pose = Matrix4( + Vector3(fbx_bind_pose_matrix.GetColumn(0).mData), + Vector3(fbx_bind_pose_matrix.GetColumn(1).mData), + Vector3(fbx_bind_pose_matrix.GetColumn(2).mData), + Vector3(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(Matrix4( + Vector3(link_matrix.GetColumn(0).mData), + Vector3(link_matrix.GetColumn(1).mData), + Vector3(link_matrix.GetColumn(2).mData), + Vector3(link_matrix.GetColumn(3).mData) + )); + + int cluster_control_point_count = cluster->GetControlPointIndicesCount(); + 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; + } + weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = bone_weight; + weight_info.bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = target_bone_index; + for (int bone_index = KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 2; bone_index >= 0; bone_index--) { + if (bone_weight > weight_info.weights[bone_index]) { + weight_info.weights[bone_index + 1] = weight_info.weights[bone_index]; + weight_info.bone_indexes[bone_index + 1] = weight_info.bone_indexes[bone_index]; + weight_info.weights[bone_index] = bone_weight; + weight_info.bone_indexes[bone_index] = target_bone_index; + } + } + } else { + too_many_bone_weights = true; } - + } + target_bone_index++; } - - bool too_many_bone_weights = false; - - // Collect the top 4 bone weights per vertex ... - int skin_count = pMesh->GetDeformerCount(FbxDeformer::eSkin); - int target_bone_index = 0; - for(int skin_index=0; skin_indexGetDeformer(skin_index, FbxDeformer::eSkin); - int cluster_count = skin->GetClusterCount(); - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " Found skin with %i clusters.\n", cluster_count); - for(int cluster_index=0; cluster_index < cluster_count; cluster_index++) { - FbxCluster *cluster = skin->GetCluster(cluster_index); - if(cluster->GetLinkMode() != FbxCluster::eNormalize) { - KRContext::Log(KRContext::LOG_LEVEL_WARNING, " Warning! link mode not supported."); - } - std::string bone_name = GetFbxObjectName(cluster->GetLink()); - mi.bone_names.push_back(bone_name); - - /* - FbxMatrix fbx_bind_pose_matrix; - Matrix4 bind_pose; - PoseList pose_list; - FbxArray pose_indices; - if(FbxPose::GetBindPoseContaining(pFbxScene, cluster->GetLink(), pose_list, pose_indices)) { - fbx_bind_pose_matrix = (*pose_list)[0].GetMatrix(pose_indices[0]); - bind_pose = Matrix4( - Vector3(fbx_bind_pose_matrix.GetColumn(0).mData), - Vector3(fbx_bind_pose_matrix.GetColumn(1).mData), - Vector3(fbx_bind_pose_matrix.GetColumn(2).mData), - Vector3(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(Matrix4( - Vector3(link_matrix.GetColumn(0).mData), - Vector3(link_matrix.GetColumn(1).mData), - Vector3(link_matrix.GetColumn(2).mData), - Vector3(link_matrix.GetColumn(3).mData) - )); - - int cluster_control_point_count = cluster->GetControlPointIndicesCount(); - for(int cluster_control_point=0; cluster_control_pointGetControlPointIndices()[cluster_control_point]; - control_point_weight_info_t &weight_info = control_point_weights[control_point]; - float bone_weight = cluster->GetControlPointWeights()[cluster_control_point]; - if(bone_weight > weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1]) { - if(weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] != 0.0f) { - too_many_bone_weights = true; - } - weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = bone_weight; - weight_info.bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = target_bone_index; - for(int bone_index=KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 2; bone_index >=0; bone_index--) { - if(bone_weight > weight_info.weights[bone_index]) { - weight_info.weights[bone_index+1] = weight_info.weights[bone_index]; - weight_info.bone_indexes[bone_index+1] = weight_info.bone_indexes[bone_index]; - weight_info.weights[bone_index] = bone_weight; - weight_info.bone_indexes[bone_index] = target_bone_index; - } - } - } else { - too_many_bone_weights = true; - } - } - target_bone_index++; - } + } + + if (too_many_bone_weights) { + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Clipped bone weights to limit of %i per vertex (selecting largest weights and re-normalizing).", KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX); + } + // Normalize bone weights + 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_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]; + } + if (total_weights == 0.0f) total_weights = 1.0f; // Prevent any divisions by zero + for (int i = 0; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) { + weight_info.weights[i] = weight_info.weights[i] / total_weights; + } } - - if(too_many_bone_weights) { - KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Clipped bone weights to limit of %i per vertex (selecting largest weights and re-normalizing).", KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX); - } - // Normalize bone weights - 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_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]; - } - if(total_weights == 0.0f) total_weights = 1.0f; // Prevent any divisions by zero - for(int i=0; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX; i++) { - weight_info.weights[i] = weight_info.weights[i] / total_weights; - } - } - } - - pMesh->GenerateTangentsDataForAllUVSets(true); - - int polygon_count = pMesh->GetPolygonCount(); - int uv_count = pMesh->GetElementUVCount(); - int normal_count = pMesh->GetElementNormalCount(); - int tangent_count = pMesh->GetElementTangentCount(); - int elementmaterial_count = pMesh->GetElementMaterialCount(); - int material_count = pMesh->GetNode()->GetMaterialCount(); // FINDME, TODO - To support instancing, material names should be stored in the instance rather than the mesh - + } + + pMesh->GenerateTangentsDataForAllUVSets(true); + + int polygon_count = pMesh->GetPolygonCount(); + int uv_count = pMesh->GetElementUVCount(); + int normal_count = pMesh->GetElementNormalCount(); + int tangent_count = pMesh->GetElementTangentCount(); + int elementmaterial_count = pMesh->GetElementMaterialCount(); + int material_count = pMesh->GetNode()->GetMaterialCount(); // FINDME, TODO - To support instancing, material names should be stored in the instance rather than the mesh + // std::vector > bone_weights; // std::vector > bone_indexes; // @@ -1409,336 +1404,340 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe // std::vector submesh_lengths; // std::vector submesh_starts; // std::vector material_names; - - int dest_vertex_id = 0; - - bool need_tangents = false; - - for(int iMaterial=0; iMaterial < material_count; iMaterial++) { - FbxSurfaceMaterial *pMaterial = pMesh->GetNode()->GetMaterial(iMaterial); - - KRMaterial *material = context.getMaterialManager()->getMaterial(pMaterial->GetName()); - if(material) { - if(material->needsVertexTangents()) { - need_tangents = true; + + int dest_vertex_id = 0; + + bool need_tangents = false; + + for (int iMaterial = 0; iMaterial < material_count; iMaterial++) { + FbxSurfaceMaterial* pMaterial = pMesh->GetNode()->GetMaterial(iMaterial); + + KRMaterial* material = context.getMaterialManager()->getMaterial(pMaterial->GetName()); + if (material) { + if (material->needsVertexTangents()) { + need_tangents = true; + } + } + + int source_vertex_id = 0; + int mat_vertex_count = 0; + int mat_vertex_start = dest_vertex_id; + for (int iPolygon = 0; iPolygon < polygon_count; iPolygon++) { + int lPolygonSize = pMesh->GetPolygonSize(iPolygon); + if (lPolygonSize != 3) { + source_vertex_id += lPolygonSize; + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Poly with %i vertices found. Expecting only triangles.", lPolygonSize); + } else { + // ----====---- Read SubMesh / Material Mapping ----====---- + int iNewMaterial = -1; + for (int l = 0; l < elementmaterial_count; l++) { + FbxGeometryElementMaterial* leMat = pMesh->GetElementMaterial(l); + if (leMat) { + if (leMat->GetReferenceMode() == FbxGeometryElement::eIndex || leMat->GetReferenceMode() == FbxGeometryElement::eIndexToDirect) { + int new_id = leMat->GetIndexArray().GetAt(iPolygon); + if (new_id >= 0) { + iNewMaterial = new_id; + } } + } } - - int source_vertex_id = 0; - int mat_vertex_count = 0; - int mat_vertex_start = dest_vertex_id; - for(int iPolygon = 0; iPolygon < polygon_count; iPolygon++) { - int lPolygonSize = pMesh->GetPolygonSize(iPolygon); - if(lPolygonSize != 3) { - source_vertex_id += lPolygonSize; - KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Poly with %i vertices found. Expecting only triangles.", lPolygonSize); - } else { - // ----====---- Read SubMesh / Material Mapping ----====---- - int iNewMaterial = -1; - for (int l = 0; l < elementmaterial_count; l++) + + if (iMaterial == iNewMaterial) { + // ----====---- Read Vertex-level Attributes ----====---- + for (int iVertex = 0; iVertex < 3; iVertex++) { + // ----====---- Read Vertex Position ----====---- + int lControlPointIndex = pMesh->GetPolygonVertex(iPolygon, iVertex); + FbxVector4 v = control_points[lControlPointIndex]; + mi.vertices.push_back(Vector3(v[0], v[1], v[2])); + + if (mi.bone_names.size() > 0) { + control_point_weight_info_t& weight_info = control_point_weights[lControlPointIndex]; + std::vector vertex_bone_indexes; + std::vector vertex_bone_weights; + for (int i = 0; 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]); + } + mi.bone_indexes.push_back(vertex_bone_indexes); + mi.bone_weights.push_back(vertex_bone_weights); + } + + Vector2 new_uva = Vector2(0.0, 0.0); + Vector2 new_uvb = Vector2(0.0, 0.0); + + + // ----====---- Read UVs ----====---- + + FbxStringList uvNames; + pMesh->GetUVSetNames(uvNames); + if (uv_count >= 1) { + const char* setName = uvNames[0].Buffer(); + FbxVector2 uv; + bool unmapped = false; + if (pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { + if (!unmapped) { + new_uva = Vector2(uv[0], uv[1]); + } + } + mi.uva.push_back(new_uva); + } + + if (uv_count >= 2) { + const char* setName = uvNames[1].Buffer(); + FbxVector2 uv; + bool unmapped = false; + if (pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { + if (!unmapped) { + new_uvb = Vector2(uv[0], uv[1]); + } + } + mi.uvb.push_back(new_uvb); + } + + // ----====---- Read Normals ----====---- + + FbxVector4 new_normal; + if (pMesh->GetPolygonVertexNormal(iPolygon, iVertex, new_normal)) { + mi.normals.push_back(Vector3(new_normal[0], new_normal[1], new_normal[2])); + } + + /* + TODO - Tangent vectors imported from maya appear incorrectly... Only calculating them in Kraken for now + + // ----====---- Read Tangents ----====---- + if(need_tangents) { + for(int l = 0; l < tangent_count; ++l) { - FbxGeometryElementMaterial* leMat = pMesh->GetElementMaterial(l); - if(leMat) { - if (leMat->GetReferenceMode() == FbxGeometryElement::eIndex || leMat->GetReferenceMode() == FbxGeometryElement::eIndexToDirect) { - int new_id = leMat->GetIndexArray().GetAt(iPolygon); - if(new_id >= 0) { - iNewMaterial = new_id; - } - } - } - } - - if(iMaterial == iNewMaterial) { - // ----====---- Read Vertex-level Attributes ----====---- - for(int iVertex=0; iVertex<3; iVertex++) { - // ----====---- Read Vertex Position ----====---- - int lControlPointIndex = pMesh->GetPolygonVertex(iPolygon, iVertex); - FbxVector4 v = control_points[lControlPointIndex]; - mi.vertices.push_back(Vector3(v[0], v[1], v[2])); - - if(mi.bone_names.size() > 0) { - control_point_weight_info_t &weight_info = control_point_weights[lControlPointIndex]; - std::vector vertex_bone_indexes; - std::vector vertex_bone_weights; - for(int i=0; iGetUVSetNames(uvNames); - if(uv_count >= 1) { - const char *setName = uvNames[0].Buffer(); - FbxVector2 uv; - bool unmapped = false; - if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { - if(!unmapped) { - new_uva = Vector2(uv[0], uv[1]); - } - } - mi.uva.push_back(new_uva); - } - - if(uv_count >= 2) { - const char *setName = uvNames[1].Buffer(); - FbxVector2 uv; - bool unmapped = false; - if(pMesh->GetPolygonVertexUV(iPolygon, iVertex, setName, uv, unmapped)) { - if(!unmapped) { - new_uvb = Vector2(uv[0], uv[1]); - } - } - mi.uvb.push_back(new_uvb); - } - - // ----====---- Read Normals ----====---- - - FbxVector4 new_normal; - if(pMesh->GetPolygonVertexNormal(iPolygon, iVertex, new_normal)) { - mi.normals.push_back(Vector3(new_normal[0], new_normal[1], new_normal[2])); - } - - /* - TODO - Tangent vectors imported from maya appear incorrectly... Only calculating them in Kraken for now - - // ----====---- Read Tangents ----====---- - if(need_tangents) { - for(int l = 0; l < tangent_count; ++l) + FbxVector4 new_tangent; + FbxGeometryElementTangent* leTangent = pMesh->GetElementTangent(l); + + if(leTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) { + switch (leTangent->GetReferenceMode()) { + case FbxGeometryElement::eDirect: + new_tangent = leTangent->GetDirectArray().GetAt(lControlPointIndex); + break; + case FbxGeometryElement::eIndexToDirect: { - FbxVector4 new_tangent; - FbxGeometryElementTangent* leTangent = pMesh->GetElementTangent(l); - - if(leTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) { - switch (leTangent->GetReferenceMode()) { - case FbxGeometryElement::eDirect: - new_tangent = leTangent->GetDirectArray().GetAt(lControlPointIndex); - break; - case FbxGeometryElement::eIndexToDirect: - { - int id = leTangent->GetIndexArray().GetAt(lControlPointIndex); - new_tangent = leTangent->GetDirectArray().GetAt(id); - } - break; - default: - break; // other reference modes not shown here! - } - } - if(l == 0) { - mi.tangents.push_back(Vector3(new_tangent[0], new_tangent[1], new_tangent[2])); - } - + int id = leTangent->GetIndexArray().GetAt(lControlPointIndex); + new_tangent = leTangent->GetDirectArray().GetAt(id); } + break; + default: + break; // other reference modes not shown here! } - */ - - source_vertex_id++; - dest_vertex_id++; - mat_vertex_count++; } + if(l == 0) { + mi.tangents.push_back(Vector3(new_tangent[0], new_tangent[1], new_tangent[2])); + } + } } + */ + + source_vertex_id++; + dest_vertex_id++; + mat_vertex_count++; + } } - - - if(mat_vertex_count) { - // ----====---- Output last material / submesh details ----====---- - 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, pMesh->GetNode()->GetName()); - new_mesh->LoadData(mi, true, need_tangents); - - context.getMeshManager()->addModel(new_mesh); + + + if (mat_vertex_count) { + // ----====---- Output last material / submesh details ----====---- + 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, pMesh->GetNode()->GetName()); + new_mesh->LoadData(mi, true, need_tangents); + + context.getMeshManager()->addModel(new_mesh); } -KRNode *LoadMesh(KRNode *parent_node, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode) { - std::string name = GetFbxObjectName(pNode); - - FbxMesh* pSourceMesh = (FbxMesh*) pNode->GetNodeAttribute(); +KRNode* LoadMesh(KRNode* parent_node, FbxScene* pFbxScene, FbxGeometryConverter* pGeometryConverter, FbxNode* pNode) +{ + std::string name = GetFbxObjectName(pNode); - if(KRMesh::GetLODCoverage(pNode->GetName()) == 100) { - // If this is the full detail model, add an instance of it to the scene file - std::string light_map = pNode->GetName(); - light_map.append("_lightmap"); - - // FINDME, HACK - Until we have a GUI, we're using prefixes to select correct object type - const char *node_name = pNode->GetName(); - if(strncmp(node_name, "physics_collider_", strlen("physics_collider_")) == 0) { - return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), KRAKEN_COLLIDER_PHYSICS, 0.0f); - } else if(strncmp(node_name, "audio_collider_", strlen("audio_collider_")) == 0) { - return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), KRAKEN_COLLIDER_AUDIO, 1.0f); - } else if(strncmp(node_name, "collider", 8) == 0) { // 8 == strlen("collider") - // Colliders can have a prefix of collider_##_, where ## indicates the layer mask - // Colliders with a prefix of only collider_ will have a default layer mask of KRAKEN_COLLIDER_PHYSICS | KRAKEN_COLLIDER_AUDIO - - // Scan through the characters of the name until we no longer see digit characters (or see a '\0' indicating the end of the string) - unsigned int layer = 0; - const char *szNodeName = node_name + 8; // 8 == strlen("collider") - const char *source_char = szNodeName; - while(*source_char >= '0' && *source_char <= '9') { - layer = layer * 10 + (*source_char++ - '0'); - } - - if(layer == 0) { - // No layer mask number was found, use the default - layer = KRAKEN_COLLIDER_PHYSICS | KRAKEN_COLLIDER_AUDIO; - } - if(*source_char == '_') { - // Pattern has matched - return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), layer, 1.0f); - } else { - // This is just a normal node, which happened to be prefixed with "collider" but didn't have a number and underscore - return new KRModel(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), light_map, 0.0f, true, false); - } - } else { - return new KRModel(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), light_map, 0.0f, true, false); - } + FbxMesh* pSourceMesh = (FbxMesh*)pNode->GetNodeAttribute(); + + if (KRMesh::GetLODCoverage(pNode->GetName()) == 100) { + // If this is the full detail model, add an instance of it to the scene file + std::string light_map = pNode->GetName(); + light_map.append("_lightmap"); + + // FINDME, HACK - Until we have a GUI, we're using prefixes to select correct object type + const char* node_name = pNode->GetName(); + if (strncmp(node_name, "physics_collider_", strlen("physics_collider_")) == 0) { + return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), KRAKEN_COLLIDER_PHYSICS, 0.0f); + } else if (strncmp(node_name, "audio_collider_", strlen("audio_collider_")) == 0) { + return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), KRAKEN_COLLIDER_AUDIO, 1.0f); + } else if (strncmp(node_name, "collider", 8) == 0) { // 8 == strlen("collider") + // Colliders can have a prefix of collider_##_, where ## indicates the layer mask + // Colliders with a prefix of only collider_ will have a default layer mask of KRAKEN_COLLIDER_PHYSICS | KRAKEN_COLLIDER_AUDIO + + // Scan through the characters of the name until we no longer see digit characters (or see a '\0' indicating the end of the string) + unsigned int layer = 0; + const char* szNodeName = node_name + 8; // 8 == strlen("collider") + const char* source_char = szNodeName; + while (*source_char >= '0' && *source_char <= '9') { + layer = layer * 10 + (*source_char++ - '0'); + } + + if (layer == 0) { + // No layer mask number was found, use the default + layer = KRAKEN_COLLIDER_PHYSICS | KRAKEN_COLLIDER_AUDIO; + } + if (*source_char == '_') { + // Pattern has matched + return new KRCollider(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), layer, 1.0f); + } else { + // This is just a normal node, which happened to be prefixed with "collider" but didn't have a number and underscore + return new KRModel(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), light_map, 0.0f, true, false); + } } else { - return NULL; + return new KRModel(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), light_map, 0.0f, true, false); } - + } else { + return NULL; + } + } -KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { - std::string name = GetFbxObjectName(pNode); - KRBone *new_bone = new KRBone(parent_node->getScene(), name.c_str()); - - //static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray& pIndex); +KRNode* LoadSkeleton(KRNode* parent_node, FbxScene* pFbxScene, FbxNode* pNode) +{ + std::string name = GetFbxObjectName(pNode); + KRBone* new_bone = new KRBone(parent_node->getScene(), name.c_str()); + + //static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray& pIndex); // PoseList pose_list; // FbxArray pose_indices; // if(FbxPose::GetBindPoseContaining(pFbxScene, pNode, pose_list, pose_indices)) { // fprintf(stderr, "Found bind pose(s)!\n"); // } - - return new_bone; + + return new_bone; } -KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { - std::string name = GetFbxObjectName(pNode); - - KRLocator *new_locator = new KRLocator(parent_node->getScene(), name.c_str()); - - // Enumerate fbx properties so client code can convert locators into application-specific objects - FbxProperty fbx_property = pNode->GetFirstProperty(); - while(fbx_property.IsValid()) { - std::string property_name = fbx_property.GetNameAsCStr(); - std::transform(property_name.begin(), property_name.end(), property_name.begin(), ::tolower); - - boost::variant property_value = ""; - switch(fbx_property.GetPropertyDataType().GetType()) { - case eFbxInt: - new_locator->getUserAttributes()[property_name] = fbx_property.Get(); - break; - case eFbxDouble: - new_locator->getUserAttributes()[property_name] = fbx_property.Get(); - break; - case eFbxBool: - new_locator->getUserAttributes()[property_name] = fbx_property.Get(); - break; - case eFbxFloat: - new_locator->getUserAttributes()[property_name] = fbx_property.Get(); - break; - case eFbxString: - new_locator->getUserAttributes()[property_name] = std::string(fbx_property.Get().Buffer()); - break; - default: - { - // fprintf(stderr, "FBX property not imported due to unsupported data type: %s.%s\n", name.c_str(), property_name.c_str()); - } - break; - } - - fbx_property = pNode->GetNextProperty(fbx_property); +KRNode* LoadLocator(KRNode* parent_node, FbxScene* pFbxScene, FbxNode* pNode) +{ + std::string name = GetFbxObjectName(pNode); + + KRLocator* new_locator = new KRLocator(parent_node->getScene(), name.c_str()); + + // Enumerate fbx properties so client code can convert locators into application-specific objects + FbxProperty fbx_property = pNode->GetFirstProperty(); + while (fbx_property.IsValid()) { + std::string property_name = fbx_property.GetNameAsCStr(); + std::transform(property_name.begin(), property_name.end(), property_name.begin(), ::tolower); + + boost::variant property_value = ""; + switch (fbx_property.GetPropertyDataType().GetType()) { + case eFbxInt: + new_locator->getUserAttributes()[property_name] = fbx_property.Get(); + break; + case eFbxDouble: + new_locator->getUserAttributes()[property_name] = fbx_property.Get(); + break; + case eFbxBool: + new_locator->getUserAttributes()[property_name] = fbx_property.Get(); + break; + case eFbxFloat: + new_locator->getUserAttributes()[property_name] = fbx_property.Get(); + break; + case eFbxString: + new_locator->getUserAttributes()[property_name] = std::string(fbx_property.Get().Buffer()); + break; + default: + { + // fprintf(stderr, "FBX property not imported due to unsupported data type: %s.%s\n", name.c_str(), property_name.c_str()); } - - - //static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray& pIndex); - // PoseList pose_list; - // FbxArray pose_indices; - // if(FbxPose::GetBindPoseContaining(pFbxScene, pNode, pose_list, pose_indices)) { - // fprintf(stderr, "Found bind pose(s)!\n"); - // } - - return new_locator; + break; + } + + fbx_property = pNode->GetNextProperty(fbx_property); + } + + + //static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray& pIndex); + // PoseList pose_list; + // FbxArray pose_indices; + // if(FbxPose::GetBindPoseContaining(pFbxScene, pNode, pose_list, pose_indices)) { + // fprintf(stderr, "Found bind pose(s)!\n"); + // } + + return new_locator; } -KRNode *LoadCamera(KRNode *parent_node, FbxNode* pNode) { - FbxCamera *camera = (FbxCamera *)pNode->GetNodeAttribute(); - const char *szName = pNode->GetName(); - - KRCamera *new_camera = new KRCamera(parent_node->getScene(), szName); - return new_camera; +KRNode* LoadCamera(KRNode* parent_node, FbxNode* pNode) +{ + FbxCamera* camera = (FbxCamera*)pNode->GetNodeAttribute(); + const char* szName = pNode->GetName(); + + KRCamera* new_camera = new KRCamera(parent_node->getScene(), szName); + return new_camera; } -KRNode *LoadLight(KRNode *parent_node, FbxNode* pNode) { - const float PI = 3.14159265; - const float d2r = PI * 2 / 360; - - FbxLight* pLight = (FbxLight*) pNode->GetNodeAttribute(); - const char *szName = pNode->GetName(); - - FbxDouble3 light_color = pLight->Color.Get(); - FbxDouble light_intensity = pLight->Intensity.Get(); - FbxDouble light_hotspot = pLight->InnerAngle.Get(); // light inner cone angle (in degrees). Also know as the HotSpot - FbxDouble light_coneangle = pLight->OuterAngle.Get(); // light outer cone angle (in degrees). Also known as the Falloff - FbxLight::EDecayType light_decaytype = pLight->DecayType.Get(); // decay type - FbxDouble light_decaystart = pLight->DecayStart.Get(); // decay start distance - - +KRNode* LoadLight(KRNode* parent_node, FbxNode* pNode) +{ + const float PI = 3.14159265; + const float d2r = PI * 2 / 360; + + FbxLight* pLight = (FbxLight*)pNode->GetNodeAttribute(); + const char* szName = pNode->GetName(); + + FbxDouble3 light_color = pLight->Color.Get(); + FbxDouble light_intensity = pLight->Intensity.Get(); + FbxDouble light_hotspot = pLight->InnerAngle.Get(); // light inner cone angle (in degrees). Also know as the HotSpot + FbxDouble light_coneangle = pLight->OuterAngle.Get(); // light outer cone angle (in degrees). Also known as the Falloff + FbxLight::EDecayType light_decaytype = pLight->DecayType.Get(); // decay type + FbxDouble light_decaystart = pLight->DecayStart.Get(); // decay start distance + + // KFbxLight::eNONE - does not attenuate with distance // KFbxLight::eLINEAR - attenuation of 1/d // KFbxLight::eQUADRATIC - attenuation of 1/d^2 // KFbxLight::eCUBIC - attenuation of - - KRLight *new_light = NULL; - - switch(pLight->LightType.Get()) { - case FbxLight::ePoint: - { - KRPointLight *l = new KRPointLight(parent_node->getScene(), szName); - new_light = l; - - } - break; - case FbxLight::eDirectional: - { - KRDirectionalLight *l = new KRDirectionalLight(parent_node->getScene(), szName); - new_light = l; - } - break; - case FbxLight::eSpot: - { - KRSpotLight *l = new KRSpotLight(parent_node->getScene(), szName); - l->setInnerAngle(light_hotspot * d2r); - l->setOuterAngle(light_coneangle * d2r); - new_light = l; - } - break; - case FbxLight::eVolume: - case FbxLight::eArea: - // Not supported yet - break; - } - - if(new_light) { - new_light->setColor(Vector3(light_color[0], light_color[1], light_color[2])); - new_light->setIntensity(light_intensity); - new_light->setDecayStart(light_decaystart); - } - return new_light; - + + KRLight* new_light = NULL; + + switch (pLight->LightType.Get()) { + case FbxLight::ePoint: + { + KRPointLight* l = new KRPointLight(parent_node->getScene(), szName); + new_light = l; + + } + break; + case FbxLight::eDirectional: + { + KRDirectionalLight* l = new KRDirectionalLight(parent_node->getScene(), szName); + new_light = l; + } + break; + case FbxLight::eSpot: + { + KRSpotLight* l = new KRSpotLight(parent_node->getScene(), szName); + l->setInnerAngle(light_hotspot * d2r); + l->setOuterAngle(light_coneangle * d2r); + new_light = l; + } + break; + case FbxLight::eVolume: + case FbxLight::eArea: + // Not supported yet + break; + } + + if (new_light) { + new_light->setColor(Vector3(light_color[0], light_color[1], light_color[2])); + new_light->setIntensity(light_intensity); + new_light->setDecayStart(light_decaystart); + } + return new_light; + } diff --git a/kraken/KRResource+obj.cpp b/kraken/KRResource+obj.cpp index 81bebb4..ee72d62 100755 --- a/kraken/KRResource+obj.cpp +++ b/kraken/KRResource+obj.cpp @@ -34,313 +34,313 @@ #include "KRResource.h" #include "KRMesh.h" -KRMesh* KRResource::LoadObj(KRContext &context, const std::string& path) -{ - KRMesh *new_mesh = new KRMesh(context, KRResource::GetFileBase(path)); - - KRMesh::mesh_info mi; - - std::vector material_names_t; - - KRDataBlock data; - - char szSymbol[500][256]; - - int *pFaces = NULL; - - vector m_materials; - - if(data.load(path)) { - // -----=====----- Get counts -----=====----- - - int cVertexData = 0; - - - int cFaces = 1; - int cMaterialFaceStart = 1; - - char *pScan = (char *)data.getStart(); - char *pEnd = (char *)data.getEnd(); - while(pScan < pEnd) { - - // Scan through whitespace - while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t' || *pScan == '\r' || *pScan == '\n')) { - pScan++; - } - - if(*pScan == '#') { - // Line is a comment line - - // Scan to the end of the line - while(pScan < pEnd && *pScan != '\r' && *pScan != '\n') { - pScan++; - } - } else { - int cSymbols = 0; - while(pScan < pEnd && *pScan != '\n' && *pScan != '\r') { - - char *pDest = szSymbol[cSymbols++]; - while(pScan < pEnd && *pScan != ' ' && *pScan != '\n' && *pScan != '\r') { - *pDest++ = *pScan++; - } - *pDest = '\0'; - - // Scan through whitespace, but don't advance to next line - while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t')) { - pScan++; - } - } - - if(strcmp(szSymbol[0], "v") == 0) { - // Vertex (v) - } else if(strcmp(szSymbol[0], "vt") == 0) { - // Vertex Texture UV Coordinate (vt) - } else if(strcmp(szSymbol[0], "vn") == 0) { - // Vertex Normal (vn) - } else if(strcmp(szSymbol[0], "f") == 0) { - // Face (f) - int cFaceVertexes = (cSymbols - 3) * 3; // 3 vertexes per triangle. Triangles have 4 symbols. Quads have 5 symbols and generate two triangles. - cVertexData += cFaceVertexes; - cFaces += cFaceVertexes * 3 + 1; // Allocate space for count of vertices, Vertex Index, Texture Coordinate Index, and Normal Index - - } else if(strcmp(szSymbol[0], "usemtl") == 0) { - // Use Material (usemtl) - if(cMaterialFaceStart - cFaces > 0) { - cFaces++; - - } - material_names_t.push_back(std::string(szSymbol[1])); - } - - } +KRMesh* KRResource::LoadObj(KRContext& context, const std::string& path) +{ + KRMesh* new_mesh = new KRMesh(context, KRResource::GetFileBase(path)); + + KRMesh::mesh_info mi; + + std::vector material_names_t; + + KRDataBlock data; + + char szSymbol[500][256]; + + int* pFaces = NULL; + + vector m_materials; + + if (data.load(path)) { + // -----=====----- Get counts -----=====----- + + int cVertexData = 0; + + + int cFaces = 1; + int cMaterialFaceStart = 1; + + char* pScan = (char*)data.getStart(); + char* pEnd = (char*)data.getEnd(); + while (pScan < pEnd) { + + // Scan through whitespace + while (pScan < pEnd && (*pScan == ' ' || *pScan == '\t' || *pScan == '\r' || *pScan == '\n')) { + pScan++; + } + + if (*pScan == '#') { + // Line is a comment line + + // Scan to the end of the line + while (pScan < pEnd && *pScan != '\r' && *pScan != '\n') { + pScan++; } - - - // -----=====----- Populate vertexes and faces -----=====----- - - int *pFaces = (int *)malloc(sizeof(int) * (cFaces + 1)); - assert(pFaces != NULL); - - std::vector indexed_vertices; - std::vector indexed_uva; - std::vector indexed_normals; - - int *pFace = pFaces; - int *pMaterialFaces = pFace++; - *pMaterialFaces = 0; - - - - - // -------- - - pScan = (char *)data.getStart(); - while(pScan < pEnd) { - - // Scan through whitespace - while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t' || *pScan == '\r' || *pScan == '\n')) { - pScan++; - } - - if(*pScan == '#') { - // Line is a comment line - - // Scan to the end of the line - while(pScan < pEnd && *pScan != '\r' && *pScan != '\n') { - pScan++; - } - } else { - int cSymbols = 0; - while(pScan < pEnd && *pScan != '\n' && *pScan != '\r') { - - char *pDest = szSymbol[cSymbols++]; - while(pScan < pEnd && *pScan != ' ' && *pScan != '\n' && *pScan != '\r') { - *pDest++ = *pScan++; - } - *pDest = '\0'; - - // Scan through whitespace, but don't advance to next line - while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t')) { - pScan++; - } - } - - if(strcmp(szSymbol[0], "v") == 0) { - // Vertex (v) - float x, y, z; - char *pChar = szSymbol[1]; - x = strtof(pChar, &pChar); - pChar = szSymbol[2]; - y = strtof(pChar, &pChar); - pChar = szSymbol[3]; - z = strtof(pChar, &pChar); - indexed_vertices.push_back(Vector3::Create(x,y,z)); - } else if(strcmp(szSymbol[0], "vt") == 0) { - // Vertex Texture UV Coordinate (vt) - char *pChar = szSymbol[1]; - float u,v; - - u = strtof(pChar, &pChar); - pChar = szSymbol[2]; - v = strtof(pChar, &pChar); - indexed_uva.push_back(Vector2::Create(u,v)); - } else if(strcmp(szSymbol[0], "vn") == 0) { - // Vertex Normal (vn) - float x,y,z; - char *pChar = szSymbol[1]; - x = strtof(pChar, &pChar); - pChar = szSymbol[2]; - y = strtof(pChar, &pChar); - pChar = szSymbol[3]; - z = strtof(pChar, &pChar); - indexed_normals.push_back(Vector3::Create(x,y,z)); - } else if(strcmp(szSymbol[0], "f") == 0) { - // Face (f) - int cFaceVertices = cSymbols - 1; - - *pFace++ = cFaceVertices; - for(int iSymbol=1; iSymbol < cSymbols; iSymbol++) { - char *pChar = szSymbol[iSymbol]; - if(*pChar == '.' || (*pChar >= '0' && *pChar <= '9')) { - *pFace++ = strtol(pChar, &pChar, 10) - 1; // Vertex Index - - if(*pChar == '/') { - pChar++; - if(*pChar == '/') { - *pFace++ = -1; - } else { - *pFace++ = strtol(pChar, &pChar, 10) - 1; // Texture Coordinate Index - } - } else { - *pFace++ = -1; - } - - if(*pChar == '/') { - pChar++; - if(*pChar == '/') { - *pFace++ = -1; - } else { - *pFace++ = strtol(pChar, &pChar, 10) - 1; // Normal Index - } - } else { - *pFace++ = -1; - } - while(*pChar == '/') { - pChar++; - strtol(pChar, &pChar, 10); - } - } - } - - - } else if(strcmp(szSymbol[0], "usemtl") == 0) { - // Use Material (usemtl) - if(pFace - pMaterialFaces > 1) { - *pMaterialFaces = (int)(pFace - pMaterialFaces - 1); - pMaterialFaces = pFace++; - } - } - } + } else { + int cSymbols = 0; + while (pScan < pEnd && *pScan != '\n' && *pScan != '\r') { + + char* pDest = szSymbol[cSymbols++]; + while (pScan < pEnd && *pScan != ' ' && *pScan != '\n' && *pScan != '\r') { + *pDest++ = *pScan++; + } + *pDest = '\0'; + + // Scan through whitespace, but don't advance to next line + while (pScan < pEnd && (*pScan == ' ' || *pScan == '\t')) { + pScan++; + } } - - - *pMaterialFaces = (int)(pFace - pMaterialFaces - 1); - *pFace++ = 0; - - - int iVertex = 0; - - - std::vector::iterator material_itr = material_names_t.begin(); - KRMesh::pack_material *pMaterial = new KRMesh::pack_material(); + + if (strcmp(szSymbol[0], "v") == 0) { + // Vertex (v) + } else if (strcmp(szSymbol[0], "vt") == 0) { + // Vertex Texture UV Coordinate (vt) + } else if (strcmp(szSymbol[0], "vn") == 0) { + // Vertex Normal (vn) + } else if (strcmp(szSymbol[0], "f") == 0) { + // Face (f) + int cFaceVertexes = (cSymbols - 3) * 3; // 3 vertexes per triangle. Triangles have 4 symbols. Quads have 5 symbols and generate two triangles. + cVertexData += cFaceVertexes; + cFaces += cFaceVertexes * 3 + 1; // Allocate space for count of vertices, Vertex Index, Texture Coordinate Index, and Normal Index + + } else if (strcmp(szSymbol[0], "usemtl") == 0) { + // Use Material (usemtl) + if (cMaterialFaceStart - cFaces > 0) { + cFaces++; + + } + material_names_t.push_back(std::string(szSymbol[1])); + } + + } + } + + + // -----=====----- Populate vertexes and faces -----=====----- + + int* pFaces = (int*)malloc(sizeof(int) * (cFaces + 1)); + assert(pFaces != NULL); + + std::vector indexed_vertices; + std::vector indexed_uva; + std::vector indexed_normals; + + int* pFace = pFaces; + int* pMaterialFaces = pFace++; + *pMaterialFaces = 0; + + + + + // -------- + + pScan = (char*)data.getStart(); + while (pScan < pEnd) { + + // Scan through whitespace + while (pScan < pEnd && (*pScan == ' ' || *pScan == '\t' || *pScan == '\r' || *pScan == '\n')) { + pScan++; + } + + if (*pScan == '#') { + // Line is a comment line + + // Scan to the end of the line + while (pScan < pEnd && *pScan != '\r' && *pScan != '\n') { + pScan++; + } + } else { + int cSymbols = 0; + while (pScan < pEnd && *pScan != '\n' && *pScan != '\r') { + + char* pDest = szSymbol[cSymbols++]; + while (pScan < pEnd && *pScan != ' ' && *pScan != '\n' && *pScan != '\r') { + *pDest++ = *pScan++; + } + *pDest = '\0'; + + // Scan through whitespace, but don't advance to next line + while (pScan < pEnd && (*pScan == ' ' || *pScan == '\t')) { + pScan++; + } + } + + if (strcmp(szSymbol[0], "v") == 0) { + // Vertex (v) + float x, y, z; + char* pChar = szSymbol[1]; + x = strtof(pChar, &pChar); + pChar = szSymbol[2]; + y = strtof(pChar, &pChar); + pChar = szSymbol[3]; + z = strtof(pChar, &pChar); + indexed_vertices.push_back(Vector3::Create(x, y, z)); + } else if (strcmp(szSymbol[0], "vt") == 0) { + // Vertex Texture UV Coordinate (vt) + char* pChar = szSymbol[1]; + float u, v; + + u = strtof(pChar, &pChar); + pChar = szSymbol[2]; + v = strtof(pChar, &pChar); + indexed_uva.push_back(Vector2::Create(u, v)); + } else if (strcmp(szSymbol[0], "vn") == 0) { + // Vertex Normal (vn) + float x, y, z; + char* pChar = szSymbol[1]; + x = strtof(pChar, &pChar); + pChar = szSymbol[2]; + y = strtof(pChar, &pChar); + pChar = szSymbol[3]; + z = strtof(pChar, &pChar); + indexed_normals.push_back(Vector3::Create(x, y, z)); + } else if (strcmp(szSymbol[0], "f") == 0) { + // Face (f) + int cFaceVertices = cSymbols - 1; + + *pFace++ = cFaceVertices; + for (int iSymbol = 1; iSymbol < cSymbols; iSymbol++) { + char* pChar = szSymbol[iSymbol]; + if (*pChar == '.' || (*pChar >= '0' && *pChar <= '9')) { + *pFace++ = strtol(pChar, &pChar, 10) - 1; // Vertex Index + + if (*pChar == '/') { + pChar++; + if (*pChar == '/') { + *pFace++ = -1; + } else { + *pFace++ = strtol(pChar, &pChar, 10) - 1; // Texture Coordinate Index + } + } else { + *pFace++ = -1; + } + + if (*pChar == '/') { + pChar++; + if (*pChar == '/') { + *pFace++ = -1; + } else { + *pFace++ = strtol(pChar, &pChar, 10) - 1; // Normal Index + } + } else { + *pFace++ = -1; + } + while (*pChar == '/') { + pChar++; + strtol(pChar, &pChar, 10); + } + } + } + + + } else if (strcmp(szSymbol[0], "usemtl") == 0) { + // Use Material (usemtl) + if (pFace - pMaterialFaces > 1) { + *pMaterialFaces = (int)(pFace - pMaterialFaces - 1); + pMaterialFaces = pFace++; + } + } + } + } + + + *pMaterialFaces = (int)(pFace - pMaterialFaces - 1); + *pFace++ = 0; + + + int iVertex = 0; + + + std::vector::iterator material_itr = material_names_t.begin(); + KRMesh::pack_material* pMaterial = new KRMesh::pack_material(); + pMaterial->start_vertex = iVertex; + pMaterial->vertex_count = 0; + memset(pMaterial->szName, 0, 256); + if (material_itr < material_names_t.end()) { + strncpy(pMaterial->szName, (*material_itr++).c_str(), 256); + } + m_materials.push_back(pMaterial); + + + pFace = pFaces; + while (*pFace != 0 && iVertex < cVertexData) { + pMaterial->start_vertex = iVertex; + + int* pMaterialEndFace = pFace + *pFace; + ++pFace; + while (pFace < pMaterialEndFace && iVertex < cVertexData) { + int cFaceVertexes = *pFace; + Vector3 firstFaceVertex; + Vector3 prevFaceVertex; + Vector3 firstFaceNormal; + Vector3 prevFaceNormal; + Vector2 firstFaceUva; + Vector2 prevFaceUva; + for (int iFaceVertex = 0; iFaceVertex < cFaceVertexes; iFaceVertex++) { + if (iFaceVertex > 2) { + // 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; + + mi.vertices.push_back(firstFaceVertex); + mi.uva.push_back(firstFaceUva); + mi.normals.push_back(firstFaceNormal); + + mi.vertices.push_back(prevFaceVertex); + mi.uva.push_back(prevFaceUva); + mi.normals.push_back(prevFaceNormal); + } + Vector3 vertex = indexed_vertices[pFace[iFaceVertex * 3 + 1]]; + Vector2 new_uva; + if (pFace[iFaceVertex * 3 + 2] >= 0) { + new_uva = indexed_uva[pFace[iFaceVertex * 3 + 2]]; + } + Vector3 normal; + if (pFace[iFaceVertex * 3 + 3] >= 0) { + Vector3 normal = indexed_normals[pFace[iFaceVertex * 3 + 3]]; + } + + mi.vertices.push_back(vertex); + mi.uva.push_back(new_uva); + mi.normals.push_back(normal); + + if (iFaceVertex == 0) { + firstFaceVertex = vertex; + firstFaceUva = new_uva; + firstFaceNormal = normal; + } + prevFaceVertex = vertex; + prevFaceUva = new_uva; + prevFaceNormal = normal; + + iVertex++; + } + pFace += cFaceVertexes * 3 + 1; + } + pMaterial->vertex_count = iVertex - pMaterial->start_vertex; + if (*pFace != 0) { + pMaterial = new KRMesh::pack_material(); pMaterial->start_vertex = iVertex; pMaterial->vertex_count = 0; memset(pMaterial->szName, 0, 256); - if(material_itr < material_names_t.end()) { - strncpy(pMaterial->szName, (*material_itr++).c_str(), 256); + + if (material_itr < material_names_t.end()) { + strncpy(pMaterial->szName, (*material_itr++).c_str(), 256); } m_materials.push_back(pMaterial); - - - pFace = pFaces; - while(*pFace != 0 && iVertex < cVertexData) { - pMaterial->start_vertex = iVertex; - - int *pMaterialEndFace = pFace + *pFace; - ++pFace; - while(pFace < pMaterialEndFace && iVertex < cVertexData) { - int cFaceVertexes = *pFace; - Vector3 firstFaceVertex; - Vector3 prevFaceVertex; - Vector3 firstFaceNormal; - Vector3 prevFaceNormal; - Vector2 firstFaceUva; - Vector2 prevFaceUva; - for(int iFaceVertex=0; iFaceVertex < cFaceVertexes; iFaceVertex++) { - if(iFaceVertex > 2) { - // 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; - - mi.vertices.push_back(firstFaceVertex); - mi.uva.push_back(firstFaceUva); - mi.normals.push_back(firstFaceNormal); - - mi.vertices.push_back(prevFaceVertex); - mi.uva.push_back(prevFaceUva); - mi.normals.push_back(prevFaceNormal); - } - Vector3 vertex = indexed_vertices[pFace[iFaceVertex*3+1]]; - Vector2 new_uva; - if(pFace[iFaceVertex*3+2] >= 0) { - new_uva = indexed_uva[pFace[iFaceVertex*3+2]]; - } - Vector3 normal; - if(pFace[iFaceVertex*3+3] >= 0){ - Vector3 normal = indexed_normals[pFace[iFaceVertex*3+3]]; - } - - mi.vertices.push_back(vertex); - mi.uva.push_back(new_uva); - mi.normals.push_back(normal); - - if(iFaceVertex==0) { - firstFaceVertex = vertex; - firstFaceUva = new_uva; - firstFaceNormal = normal; - } - prevFaceVertex = vertex; - prevFaceUva = new_uva; - prevFaceNormal = normal; - - iVertex++; - } - pFace += cFaceVertexes * 3 + 1; - } - pMaterial->vertex_count = iVertex - pMaterial->start_vertex; - if(*pFace != 0) { - pMaterial = new KRMesh::pack_material(); - pMaterial->start_vertex = iVertex; - pMaterial->vertex_count = 0; - memset(pMaterial->szName, 0, 256); - - if(material_itr < material_names_t.end()) { - strncpy(pMaterial->szName, (*material_itr++).c_str(), 256); - } - m_materials.push_back(pMaterial); - } - } - - for(int iMaterial=0; iMaterial < m_materials.size(); iMaterial++) { - KRMesh::pack_material *pNewMaterial = m_materials[iMaterial]; - if(pNewMaterial->vertex_count > 0) { - 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 + } + } + + for (int iMaterial = 0; iMaterial < m_materials.size(); iMaterial++) { + KRMesh::pack_material* pNewMaterial = m_materials[iMaterial]; + if (pNewMaterial->vertex_count > 0) { + mi.material_names.push_back(std::string(pNewMaterial->szName)); + mi.submesh_starts.push_back(pNewMaterial->start_vertex); + mi.submesh_lengths.push_back(pNewMaterial->vertex_count); + } + delete pNewMaterial; + } + + // TODO: Bones not yet supported for OBJ // std::vector bone_names; // std::vector bone_bind_poses; // std::vector > bone_indexes; @@ -348,14 +348,14 @@ KRMesh* KRResource::LoadObj(KRContext &context, const std::string& path) // // std::vector<__uint16_t> vertex_indexes; // std::vector > vertex_index_bases; - - mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; - new_mesh->LoadData(mi, true, false); - } - - if(pFaces) { - free(pFaces); - } - - return new_mesh; + + mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; + new_mesh->LoadData(mi, true, false); + } + + if (pFaces) { + free(pFaces); + } + + return new_mesh; } diff --git a/kraken/KRResource.cpp b/kraken/KRResource.cpp index 255715a..de0f6a9 100755 --- a/kraken/KRResource.cpp +++ b/kraken/KRResource.cpp @@ -34,65 +34,67 @@ #include "KRBundle.h" #include "KRContext.h" -KRResource::KRResource(KRContext &context, std::string name) : KRContextObject(context) { - m_name = name; - context.addResource(this, name); +KRResource::KRResource(KRContext& context, std::string name) : KRContextObject(context) +{ + m_name = name; + context.addResource(this, name); } -KRResource::~KRResource() { +KRResource::~KRResource() +{ m_pContext->removeResource(this); } std::string KRResource::getName() { - return m_name; + return m_name; } std::string KRResource::GetFileExtension(const std::string& name) { - if(name.find_last_of(".") != std::string::npos) { - return name.substr(name.find_last_of(".")+1); - } else { - return ""; - } + if (name.find_last_of(".") != std::string::npos) { + return name.substr(name.find_last_of(".") + 1); + } else { + return ""; + } } std::string KRResource::GetFileBase(const std::string& name) { - std::string f = name; + std::string f = name; - // Normalize Windows Paths - std::replace(f.begin(), f.end(), '\\', '/'); + // Normalize Windows Paths + std::replace(f.begin(), f.end(), '\\', '/'); - // Strip off directory - if(f.find_last_of("/") != std::string::npos) { - f = f.substr(f.find_last_of("/") + 1); - } - - // Strip off extension - if(f.find_last_of(".") != std::string::npos) { - f = f.substr(0, f.find_last_of(".")); - } - - return f; + // Strip off directory + if (f.find_last_of("/") != std::string::npos) { + f = f.substr(f.find_last_of("/") + 1); + } + + // Strip off extension + if (f.find_last_of(".") != std::string::npos) { + f = f.substr(0, f.find_last_of(".")); + } + + return f; } std::string KRResource::GetFilePath(const std::string& name) { - if(name.find_last_of("/") != std::string::npos) { - return name.substr(0, name.find_last_of("/")); - } else { - return ""; - } + if (name.find_last_of("/") != std::string::npos) { + return name.substr(0, name.find_last_of("/")); + } else { + return ""; + } } bool KRResource::save(const std::string& path) { - KRDataBlock data; - if(save(data)) { - return data.save(path); - } else { - return false; - } + KRDataBlock data; + if (save(data)) { + return data.save(path); + } else { + return false; + } } KrResult KRResource::moveToBundle(KRBundle* bundle) diff --git a/kraken/KRResource.h b/kraken/KRResource.h index 7b6db7b..327562e 100755 --- a/kraken/KRResource.h +++ b/kraken/KRResource.h @@ -41,31 +41,31 @@ class KRMesh; class KRResource : public KRContextObject { public: - std::string getName(); - virtual std::string getExtension() = 0; - virtual bool save(const std::string& path); - virtual bool save(KRDataBlock &data) = 0; + std::string getName(); + virtual std::string getExtension() = 0; + virtual bool save(const std::string& path); + virtual bool save(KRDataBlock& data) = 0; - KrResult moveToBundle(KRBundle* bundle); - - static std::string GetFileExtension(const std::string& name); - static std::string GetFileBase(const std::string& name); - static std::string GetFilePath(const std::string& name); - - virtual ~KRResource(); - - static KRMesh* LoadObj(KRContext &context, const std::string& path); + KrResult moveToBundle(KRBundle* bundle); + + static std::string GetFileExtension(const std::string& name); + static std::string GetFileBase(const std::string& name); + static std::string GetFilePath(const std::string& name); + + virtual ~KRResource(); + + static KRMesh* LoadObj(KRContext& context, const std::string& path); #if !TARGET_OS_IPHONE -// static KRScene* LoadFbx(KRContext &context, const std::string& path); TODO, FINDME, HACK! - Uncomment - static KRScene* LoadBlenderScene(KRContext &context, const std::string& path); + // static KRScene* LoadFbx(KRContext &context, const std::string& path); TODO, FINDME, HACK! - Uncomment + static KRScene* LoadBlenderScene(KRContext& context, const std::string& path); #endif - + protected: - KRResource(KRContext &context, std::string name); - - + KRResource(KRContext& context, std::string name); + + private: - std::string m_name; - + std::string m_name; + }; diff --git a/kraken/KRResourceManager.cpp b/kraken/KRResourceManager.cpp index 64f0286..ff0783d 100644 --- a/kraken/KRResourceManager.cpp +++ b/kraken/KRResourceManager.cpp @@ -32,9 +32,9 @@ #include "KRResourceManager.h" #include "KREngine-common.h" -KRResourceManager::KRResourceManager(KRContext &context) : KRContextObject(context) +KRResourceManager::KRResourceManager(KRContext& context) : KRContextObject(context) { - + } KRResourceManager::~KRResourceManager() diff --git a/kraken/KRResourceManager.h b/kraken/KRResourceManager.h index d723858..5c5e39c 100644 --- a/kraken/KRResourceManager.h +++ b/kraken/KRResourceManager.h @@ -37,11 +37,12 @@ #include "KRContextObject.h" #include "KRDataBlock.h" -class KRResourceManager : public KRContextObject { +class KRResourceManager : public KRContextObject +{ public: - KRResourceManager(KRContext &context); - virtual ~KRResourceManager(); - - virtual KRResource* loadResource(const std::string &name, const std::string &extension, KRDataBlock *data) = 0; - virtual KRResource* getResource(const std::string &name, const std::string &extension) = 0; + KRResourceManager(KRContext& context); + virtual ~KRResourceManager(); + + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) = 0; + virtual KRResource* getResource(const std::string& name, const std::string& extension) = 0; }; diff --git a/kraken/KRReverbZone.cpp b/kraken/KRReverbZone.cpp index f0baa80..cad91d8 100755 --- a/kraken/KRReverbZone.cpp +++ b/kraken/KRReverbZone.cpp @@ -42,150 +42,150 @@ void KRReverbZone::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->reverb_zone.pZoneName = nullptr; } -KRReverbZone::KRReverbZone(KRScene &scene, std::string name) : KRNode(scene, name) +KRReverbZone::KRReverbZone(KRScene& scene, std::string name) : KRNode(scene, name) { - m_reverb = ""; - m_reverb_gain = 1.0f; - m_gradient_distance = 0.25f; - + m_reverb = ""; + m_reverb_gain = 1.0f; + m_gradient_distance = 0.25f; } KRReverbZone::~KRReverbZone() +{} + +std::string KRReverbZone::getElementName() { + return "reverb_zone"; } -std::string KRReverbZone::getElementName() { - return "reverb_zone"; +tinyxml2::XMLElement* KRReverbZone::saveXML(tinyxml2::XMLNode* parent) +{ + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + e->SetAttribute("zone", m_zone.c_str()); + e->SetAttribute("sample", m_reverb.c_str()); + e->SetAttribute("gain", m_reverb_gain); + e->SetAttribute("gradient", m_gradient_distance); + return e; } -tinyxml2::XMLElement *KRReverbZone::saveXML( tinyxml2::XMLNode *parent) +void KRReverbZone::loadXML(tinyxml2::XMLElement* e) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - e->SetAttribute("zone", m_zone.c_str()); - e->SetAttribute("sample", m_reverb.c_str()); - e->SetAttribute("gain", m_reverb_gain); - e->SetAttribute("gradient", m_gradient_distance); - return e; -} + KRNode::loadXML(e); -void KRReverbZone::loadXML(tinyxml2::XMLElement *e) -{ - KRNode::loadXML(e); - - m_zone = e->Attribute("zone"); - + m_zone = e->Attribute("zone"); + + m_gradient_distance = 0.25f; + if (e->QueryFloatAttribute("gradient", &m_gradient_distance) != tinyxml2::XML_SUCCESS) { m_gradient_distance = 0.25f; - if(e->QueryFloatAttribute("gradient", &m_gradient_distance) != tinyxml2::XML_SUCCESS) { - m_gradient_distance = 0.25f; - } - - m_reverb = e->Attribute("sample"); - + } + + m_reverb = e->Attribute("sample"); + + m_reverb_gain = 1.0f; + if (e->QueryFloatAttribute("gain", &m_reverb_gain) != tinyxml2::XML_SUCCESS) { m_reverb_gain = 1.0f; - if(e->QueryFloatAttribute("gain", &m_reverb_gain) != tinyxml2::XML_SUCCESS) { - m_reverb_gain = 1.0f; - } + } } std::string KRReverbZone::getReverb() { - return m_reverb; + return m_reverb; } -void KRReverbZone::setReverb(const std::string &reverb) +void KRReverbZone::setReverb(const std::string& reverb) { - m_reverb = reverb; + m_reverb = reverb; } float KRReverbZone::getReverbGain() { - return m_reverb_gain; + return m_reverb_gain; } void KRReverbZone::setReverbGain(float reverb_gain) { - m_reverb_gain = reverb_gain; + m_reverb_gain = reverb_gain; } std::string KRReverbZone::getZone() { - return m_zone; + return m_zone; } -void KRReverbZone::setZone(const std::string &zone) +void KRReverbZone::setZone(const std::string& zone) { - m_zone = zone; + m_zone = zone; } void KRReverbZone::render(RenderInfo& ri) { - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRNode::render(ri); - - bool bVisualize = ri.camera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_SIREN_REVERB_ZONES; - - if(ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) { - KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere"); - if (sphereModel) { - Matrix4 sphereModelMatrix = getModelMatrix(); - PipelineInfo info{}; - std::string shader_name("visualize_overlay"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAlphaBlend; - info.modelFormat = sphereModel->getModelFormat(); - info.vertexAttributes = sphereModel->getVertexAttributes(); + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + KRNode::render(ri); - pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + bool bVisualize = ri.camera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_SIREN_REVERB_ZONES; - sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); - } // sphereModel - } + if (ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) { + KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere"); + if (sphereModel) { + Matrix4 sphereModelMatrix = getModelMatrix(); + PipelineInfo info{}; + std::string shader_name("visualize_overlay"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.renderPass = ri.renderPass; + info.rasterMode = RasterMode::kAlphaBlend; + info.modelFormat = sphereModel->getModelFormat(); + info.vertexAttributes = sphereModel->getVertexAttributes(); + + KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, sphereModelMatrix, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + + sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f); + } // sphereModel + } } float KRReverbZone::getGradientDistance() { - return m_gradient_distance; + return m_gradient_distance; } void KRReverbZone::setGradientDistance(float gradient_distance) { - m_gradient_distance = gradient_distance; + m_gradient_distance = gradient_distance; } -AABB KRReverbZone::getBounds() { - // Reverb zones always have a -1, -1, -1 to 1, 1, 1 bounding box - return AABB::Create(-Vector3::One(), Vector3::One(), getModelMatrix()); -} - -float KRReverbZone::getContainment(const Vector3 &pos) +AABB KRReverbZone::getBounds() { - AABB bounds = getBounds(); - if(bounds.contains(pos)) { - Vector3 size = bounds.size(); - Vector3 diff = pos - bounds.center(); - diff = diff * 2.0f; - diff = Vector3::Create(diff.x / size.x, diff.y / size.y, diff.z / size.z); - float d = diff.magnitude(); - - if(m_gradient_distance <= 0.0f) { - // Avoid division by zero - d = d > 1.0f ? 0.0f : 1.0f; - } else { - d = (1.0f - d) / m_gradient_distance; - d = KRCLAMP(d, 0.0f, 1.0f); - } - return d; - + // Reverb zones always have a -1, -1, -1 to 1, 1, 1 bounding box + return AABB::Create(-Vector3::One(), Vector3::One(), getModelMatrix()); +} + +float KRReverbZone::getContainment(const Vector3& pos) +{ + AABB bounds = getBounds(); + if (bounds.contains(pos)) { + Vector3 size = bounds.size(); + Vector3 diff = pos - bounds.center(); + diff = diff * 2.0f; + diff = Vector3::Create(diff.x / size.x, diff.y / size.y, diff.z / size.z); + float d = diff.magnitude(); + + if (m_gradient_distance <= 0.0f) { + // Avoid division by zero + d = d > 1.0f ? 0.0f : 1.0f; } else { - return 0.0f; + d = (1.0f - d) / m_gradient_distance; + d = KRCLAMP(d, 0.0f, 1.0f); } + return d; + + } else { + return 0.0f; + } } \ No newline at end of file diff --git a/kraken/KRReverbZone.h b/kraken/KRReverbZone.h index e118369..24d871b 100755 --- a/kraken/KRReverbZone.h +++ b/kraken/KRReverbZone.h @@ -35,39 +35,40 @@ #include "KRNode.h" #include "KRTexture.h" -class KRReverbZone : public KRNode { +class KRReverbZone : public KRNode +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); + static void InitNodeInfo(KrNodeInfo* nodeInfo); + + KRReverbZone(KRScene& scene, std::string name); + virtual ~KRReverbZone(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + + void render(RenderInfo& ri); + + std::string getZone(); + void setZone(const std::string& zone); + + float getGradientDistance(); + void setGradientDistance(float gradient_distance); + + std::string getReverb(); + void setReverb(const std::string& reverb); + + float getReverbGain(); + void setReverbGain(float reverb_gain); + + virtual AABB getBounds(); + + float getContainment(const Vector3& pos); - KRReverbZone(KRScene &scene, std::string name); - virtual ~KRReverbZone(); - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - - void render(RenderInfo& ri); - - std::string getZone(); - void setZone(const std::string &zone); - - float getGradientDistance(); - void setGradientDistance(float gradient_distance); - - std::string getReverb(); - void setReverb(const std::string &reverb); - - float getReverbGain(); - void setReverbGain(float reverb_gain); - - virtual AABB getBounds(); - - float getContainment(const Vector3 &pos); - private: - std::string m_zone; - - float m_gradient_distance; - - std::string m_reverb; - float m_reverb_gain; + std::string m_zone; + + float m_gradient_distance; + + std::string m_reverb; + float m_reverb_gain; }; diff --git a/kraken/KRScene.cpp b/kraken/KRScene.cpp index 7ce9a76..466b127 100755 --- a/kraken/KRScene.cpp +++ b/kraken/KRScene.cpp @@ -42,548 +42,555 @@ const long KRENGINE_OCCLUSION_TEST_EXPIRY = 10; -KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) { - m_pFirstLight = NULL; - m_pRootNode = new KRNode(*this, "scene_root"); - notify_sceneGraphCreate(m_pRootNode); -} - -KRScene::~KRScene() { - delete m_pRootNode; - m_pRootNode = NULL; -} - -void KRScene::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& surface, float deltaTime) { - getContext().startFrame(deltaTime); - KRCamera *camera = find("default_camera"); - if(camera == NULL) { - // Add a default camera if none are present - camera = new KRCamera(*this, "default_camera"); - m_pRootNode->addChild(camera); - } - - // FINDME - This should be moved to de-couple Siren from the Rendering pipeline - getContext().getAudioManager()->setEnableAudio(camera->settings.siren_enable); - getContext().getAudioManager()->setEnableHRTF(camera->settings.siren_enable_hrtf); - getContext().getAudioManager()->setEnableReverb(camera->settings.siren_enable_reverb); - getContext().getAudioManager()->setReverbMaxLength(camera->settings.siren_reverb_max_length); - getContext().getTextureManager()->setMaxAnisotropy(camera->settings.max_anisotropy); - - camera->renderFrame(commandBuffer, surface); - getContext().endFrame(deltaTime); - physicsUpdate(deltaTime); -} - -std::set &KRScene::getAmbientZones() +KRScene::KRScene(KRContext& context, std::string name) : KRResource(context, name) { - // FINDME, TODO - To support large scenes with many reverb / ambient zones, this function should take a KRAABB and cull out any far away zones - return m_ambientZoneNodes; + m_pFirstLight = NULL; + m_pRootNode = new KRNode(*this, "scene_root"); + notify_sceneGraphCreate(m_pRootNode); } -std::set &KRScene::getReverbZones() +KRScene::~KRScene() { - // FINDME, TODO - To support large scenes with many reverb / ambient zones, this function should take a KRAABB and cull out any far away zones - return m_reverbZoneNodes; + delete m_pRootNode; + m_pRootNode = NULL; } -std::set &KRScene::getLocators() +void KRScene::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& surface, float deltaTime) { - return m_locatorNodes; + getContext().startFrame(deltaTime); + KRCamera* camera = find("default_camera"); + if (camera == NULL) { + // Add a default camera if none are present + camera = new KRCamera(*this, "default_camera"); + m_pRootNode->addChild(camera); + } + + // FINDME - This should be moved to de-couple Siren from the Rendering pipeline + getContext().getAudioManager()->setEnableAudio(camera->settings.siren_enable); + getContext().getAudioManager()->setEnableHRTF(camera->settings.siren_enable_hrtf); + getContext().getAudioManager()->setEnableReverb(camera->settings.siren_enable_reverb); + getContext().getAudioManager()->setReverbMaxLength(camera->settings.siren_reverb_max_length); + getContext().getTextureManager()->setMaxAnisotropy(camera->settings.max_anisotropy); + + camera->renderFrame(commandBuffer, surface); + getContext().endFrame(deltaTime); + physicsUpdate(deltaTime); } -std::set &KRScene::getLights() +std::set& KRScene::getAmbientZones() { - return m_lights; + // FINDME, TODO - To support large scenes with many reverb / ambient zones, this function should take a KRAABB and cull out any far away zones + return m_ambientZoneNodes; } -void KRScene::render(VkCommandBuffer& commandBuffer, KRSurface& surface, KRCamera *pCamera, unordered_map &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame) { - if(new_frame) { - // Expire cached occlusion test results. - // Cached "failed" results are expired on the next frame (marked with .second of -1) - // Cached "success" results are expired after KRENGINE_OCCLUSION_TEST_EXPIRY frames (marked with .second of the last frame - std::set expired_visible_bounds; - for(unordered_map::iterator visible_bounds_itr = visibleBounds.begin(); visible_bounds_itr != visibleBounds.end(); visible_bounds_itr++) { - if((*visible_bounds_itr).second == -1 || (*visible_bounds_itr).second + KRENGINE_OCCLUSION_TEST_EXPIRY < getContext().getCurrentFrame()) { - expired_visible_bounds.insert((*visible_bounds_itr).first); - } - } - for(std::set::iterator expired_visible_bounds_itr = expired_visible_bounds.begin(); expired_visible_bounds_itr != expired_visible_bounds.end(); expired_visible_bounds_itr++) { - visibleBounds.erase(*expired_visible_bounds_itr); - } - } - - if(getFirstLight() == NULL) { - addDefaultLights(); - } +std::set& KRScene::getReverbZones() +{ + // FINDME, TODO - To support large scenes with many reverb / ambient zones, this function should take a KRAABB and cull out any far away zones + return m_reverbZoneNodes; +} - KRNode::RenderInfo ri(commandBuffer); - ri.camera = pCamera; - ri.viewport = viewport; - ri.renderPass = renderPass; - - std::vector point_lights; - std::vectordirectional_lights; - std::vectorspot_lights; - - std::set outerNodes = std::set(m_nodeTree.getOuterSceneNodes()); // HACK - Copying the std::set as it is potentially modified as KRNode's update their bounds during the iteration. This is very expensive and will be eliminated in the future. - - // Get lights from outer nodes (directional lights, which have no bounds) - for(std::set::iterator itr=outerNodes.begin(); itr != outerNodes.end(); itr++) { - KRNode *node = (*itr); - KRPointLight *point_light = dynamic_cast(node); - if(point_light) { - point_lights.push_back(point_light); - } - KRDirectionalLight *directional_light = dynamic_cast(node); - if(directional_light) { - directional_lights.push_back(directional_light); - } - KRSpotLight *spot_light = dynamic_cast(node); - if(spot_light) { - spot_lights.push_back(spot_light); - } +std::set& KRScene::getLocators() +{ + return m_locatorNodes; +} + +std::set& KRScene::getLights() +{ + return m_lights; +} + +void KRScene::render(VkCommandBuffer& commandBuffer, KRSurface& surface, KRCamera* pCamera, unordered_map& visibleBounds, const KRViewport& viewport, KRNode::RenderPass renderPass, bool new_frame) +{ + if (new_frame) { + // Expire cached occlusion test results. + // Cached "failed" results are expired on the next frame (marked with .second of -1) + // Cached "success" results are expired after KRENGINE_OCCLUSION_TEST_EXPIRY frames (marked with .second of the last frame + std::set expired_visible_bounds; + for (unordered_map::iterator visible_bounds_itr = visibleBounds.begin(); visible_bounds_itr != visibleBounds.end(); visible_bounds_itr++) { + if ((*visible_bounds_itr).second == -1 || (*visible_bounds_itr).second + KRENGINE_OCCLUSION_TEST_EXPIRY < getContext().getCurrentFrame()) { + expired_visible_bounds.insert((*visible_bounds_itr).first); + } } - - // Render outer nodes - for(std::set::iterator itr=outerNodes.begin(); itr != outerNodes.end(); itr++) { - KRNode *node = (*itr); - node->render(ri); + for (std::set::iterator expired_visible_bounds_itr = expired_visible_bounds.begin(); expired_visible_bounds_itr != expired_visible_bounds.end(); expired_visible_bounds_itr++) { + visibleBounds.erase(*expired_visible_bounds_itr); } - - std::vector remainingOctrees; - std::vector remainingOctreesTestResults; - std::vector remainingOctreesTestResultsOnly; - if(m_nodeTree.getRootNode() != NULL) { - remainingOctrees.push_back(m_nodeTree.getRootNode()); + } + + if (getFirstLight() == NULL) { + addDefaultLights(); + } + + KRNode::RenderInfo ri(commandBuffer); + ri.camera = pCamera; + ri.viewport = viewport; + ri.renderPass = renderPass; + + std::vector point_lights; + std::vectordirectional_lights; + std::vectorspot_lights; + + std::set outerNodes = std::set(m_nodeTree.getOuterSceneNodes()); // HACK - Copying the std::set as it is potentially modified as KRNode's update their bounds during the iteration. This is very expensive and will be eliminated in the future. + + // Get lights from outer nodes (directional lights, which have no bounds) + for (std::set::iterator itr = outerNodes.begin(); itr != outerNodes.end(); itr++) { + KRNode* node = (*itr); + KRPointLight* point_light = dynamic_cast(node); + if (point_light) { + point_lights.push_back(point_light); } - - std::vector newRemainingOctrees; - std::vector newRemainingOctreesTestResults; - while((!remainingOctrees.empty() || !remainingOctreesTestResults.empty())) { - newRemainingOctrees.clear(); - newRemainingOctreesTestResults.clear(); - for(std::vector::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) { - render(ri, *octree_itr, visibleBounds, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false); - } - for(std::vector::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) { - render(ri, *octree_itr, visibleBounds, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, false); - } - remainingOctrees = newRemainingOctrees; - remainingOctreesTestResults = newRemainingOctreesTestResults; + KRDirectionalLight* directional_light = dynamic_cast(node); + if (directional_light) { + directional_lights.push_back(directional_light); } - + KRSpotLight* spot_light = dynamic_cast(node); + if (spot_light) { + spot_lights.push_back(spot_light); + } + } + + // Render outer nodes + for (std::set::iterator itr = outerNodes.begin(); itr != outerNodes.end(); itr++) { + KRNode* node = (*itr); + node->render(ri); + } + + std::vector remainingOctrees; + std::vector remainingOctreesTestResults; + std::vector remainingOctreesTestResultsOnly; + if (m_nodeTree.getRootNode() != NULL) { + remainingOctrees.push_back(m_nodeTree.getRootNode()); + } + + std::vector newRemainingOctrees; + std::vector newRemainingOctreesTestResults; + while ((!remainingOctrees.empty() || !remainingOctreesTestResults.empty())) { newRemainingOctrees.clear(); newRemainingOctreesTestResults.clear(); - for(std::vector::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) { - render(ri, *octree_itr, visibleBounds, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, true); + for (std::vector::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) { + render(ri, *octree_itr, visibleBounds, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false); } + for (std::vector::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) { + render(ri, *octree_itr, visibleBounds, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, false); + } + remainingOctrees = newRemainingOctrees; + remainingOctreesTestResults = newRemainingOctreesTestResults; + } + + newRemainingOctrees.clear(); + newRemainingOctreesTestResults.clear(); + for (std::vector::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) { + render(ri, *octree_itr, visibleBounds, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, true); + } } void KRScene::render(KRNode::RenderInfo& ri, KROctreeNode* pOctreeNode, unordered_map& visibleBounds, std::vector& remainingOctrees, std::vector& remainingOctreesTestResults, std::vector& remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly) -{ - if(pOctreeNode) { - - AABB octreeBounds = pOctreeNode->getBounds(); - - if(bOcclusionResultsPass) { - // ----====---- Occlusion results pass ----====---- - if(pOctreeNode->m_occlusionTested) { - GLuint params = 0; - GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms)); +{ + if (pOctreeNode) { - if(params) { - // Record the frame number that the test has passed on - visibleBounds[octreeBounds] = getContext().getCurrentFrame(); + AABB octreeBounds = pOctreeNode->getBounds(); - if(!bOcclusionTestResultsOnly) { - // Schedule a pass to perform the rendering - remainingOctrees.push_back(pOctreeNode); - } - } else { - // Record -1 to indicate that the visibility test had failed - visibleBounds[octreeBounds] = -1; - } + if (bOcclusionResultsPass) { + // ----====---- Occlusion results pass ----====---- + if (pOctreeNode->m_occlusionTested) { + GLuint params = 0; + GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms)); - GLDEBUG(glDeleteQueriesEXT(1, &pOctreeNode->m_occlusionQuery)); - pOctreeNode->m_occlusionTested = false; - pOctreeNode->m_occlusionQuery = 0; - } + if (params) { + // Record the frame number that the test has passed on + visibleBounds[octreeBounds] = getContext().getCurrentFrame(); + + if (!bOcclusionTestResultsOnly) { + // Schedule a pass to perform the rendering + remainingOctrees.push_back(pOctreeNode); + } } else { - bool in_viewport = false; - if(ri.renderPass == KRNode::RENDER_PASS_PRESTREAM) { - // When pre-streaming, objects are streamed in behind and in-front of the camera - AABB viewportExtents = AABB::Create(ri.viewport.getCameraPosition() - Vector3::Create(ri.camera->settings.getPerspectiveFarZ()), ri.viewport.getCameraPosition() + Vector3::Create(ri.camera->settings.getPerspectiveFarZ())); - in_viewport = octreeBounds.intersects(viewportExtents); + // Record -1 to indicate that the visibility test had failed + visibleBounds[octreeBounds] = -1; + } + + GLDEBUG(glDeleteQueriesEXT(1, &pOctreeNode->m_occlusionQuery)); + pOctreeNode->m_occlusionTested = false; + pOctreeNode->m_occlusionQuery = 0; + } + } else { + bool in_viewport = false; + if (ri.renderPass == KRNode::RENDER_PASS_PRESTREAM) { + // When pre-streaming, objects are streamed in behind and in-front of the camera + AABB viewportExtents = AABB::Create(ri.viewport.getCameraPosition() - Vector3::Create(ri.camera->settings.getPerspectiveFarZ()), ri.viewport.getCameraPosition() + Vector3::Create(ri.camera->settings.getPerspectiveFarZ())); + in_viewport = octreeBounds.intersects(viewportExtents); + } else { + in_viewport = ri.viewport.visible(pOctreeNode->getBounds()); + } + if (in_viewport) { + + // ----====---- Rendering and occlusion test pass ----====---- + bool bVisible = false; + bool bNeedOcclusionTest = true; + + if (!ri.camera->settings.getEnableRealtimeOcclusion()) { + bVisible = true; + bNeedOcclusionTest = false; + } + + if (!bVisible) { + // Assume bounding boxes are visible without occlusion test queries if the camera is inside the box. + // The near clipping plane of the camera is taken into consideration by expanding the match area + AABB cameraExtents = AABB::Create(ri.viewport.getCameraPosition() - Vector3::Create(ri.camera->settings.getPerspectiveNearZ()), ri.viewport.getCameraPosition() + Vector3::Create(ri.camera->settings.getPerspectiveNearZ())); + bVisible = octreeBounds.intersects(cameraExtents); + if (bVisible) { + // Record the frame number in which the camera was within the bounds + visibleBounds[octreeBounds] = getContext().getCurrentFrame(); + bNeedOcclusionTest = false; + } + } + + + if (!bVisible) { + // Check if a previous occlusion query has returned true, taking advantage of temporal consistency of visible elements from frame to frame + // If the previous frame rendered this octree, then attempt to render it in this frame without performing a pre-occlusion test + unordered_map::iterator match_itr = visibleBounds.find(octreeBounds); + if (match_itr != visibleBounds.end()) { + if ((*match_itr).second == -1) { + // We have already tested these bounds with a negative result + bNeedOcclusionTest = false; } else { - in_viewport = ri.viewport.visible(pOctreeNode->getBounds()); + bVisible = true; + + // We set bNeedOcclusionTest to false only when the previous occlusion test is old and we need to perform an occlusion test to record if this octree node was visible for the next frame + bNeedOcclusionTest = false; } - if(in_viewport) { + } - // ----====---- Rendering and occlusion test pass ----====---- - bool bVisible = false; - bool bNeedOcclusionTest = true; - - if(!ri.camera->settings.getEnableRealtimeOcclusion()) { - bVisible = true; - bNeedOcclusionTest = false; - } - - if(!bVisible) { - // Assume bounding boxes are visible without occlusion test queries if the camera is inside the box. - // The near clipping plane of the camera is taken into consideration by expanding the match area - AABB cameraExtents = AABB::Create(ri.viewport.getCameraPosition() - Vector3::Create(ri.camera->settings.getPerspectiveNearZ()), ri.viewport.getCameraPosition() + Vector3::Create(ri.camera->settings.getPerspectiveNearZ())); - bVisible = octreeBounds.intersects(cameraExtents); - if(bVisible) { - // Record the frame number in which the camera was within the bounds - visibleBounds[octreeBounds] = getContext().getCurrentFrame(); - bNeedOcclusionTest = false; - } - } - - - if(!bVisible) { - // Check if a previous occlusion query has returned true, taking advantage of temporal consistency of visible elements from frame to frame - // If the previous frame rendered this octree, then attempt to render it in this frame without performing a pre-occlusion test - unordered_map::iterator match_itr = visibleBounds.find(octreeBounds); - if(match_itr != visibleBounds.end()) { - if((*match_itr).second == -1) { - // We have already tested these bounds with a negative result - bNeedOcclusionTest = false; - } else { - bVisible = true; - - // We set bNeedOcclusionTest to false only when the previous occlusion test is old and we need to perform an occlusion test to record if this octree node was visible for the next frame - bNeedOcclusionTest = false; - } - } - - } - - if(!bVisible && bNeedOcclusionTest) { - // Optimization: If this is an empty octree node with only a single child node, then immediately try to render the child node without an occlusion test for this higher level, as it would be more expensive than the occlusion test for the child - if(pOctreeNode->getSceneNodes().empty()) { - int child_count = 0; - for(int i=0; i<8; i++) { - if(pOctreeNode->getChildren()[i] != NULL) child_count++; - } - if(child_count == 1) { - bVisible = true; - bNeedOcclusionTest = false; - } - } - } - - if(bNeedOcclusionTest) { - pOctreeNode->beginOcclusionQuery(); - - Matrix4 matModel = Matrix4(); - matModel.scale(octreeBounds.size() * 0.5f); - matModel.translate(octreeBounds.center()); - Matrix4 mvpmatrix = matModel * ri.viewport.getViewProjectionMatrix(); - - KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_3D_CUBE_VERTICES; - - getContext().getMeshManager()->bindVBO(ri.commandBuffer, &vertices, 1.0f); - - PipelineInfo info{}; - std::string shader_name("occlusion_test"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.renderPass = KRNode::RENDER_PASS_FORWARD_TRANSPARENT; - info.rasterMode = RasterMode::kAdditive; - info.vertexAttributes = vertices.getVertexAttributes(); - info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; - - KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pPipeline->bind(ri.commandBuffer, *info.pCamera, ri.viewport, matModel, info.point_lights, info.directional_lights, info.spot_lights, info.renderPass); - vkCmdDraw(ri.commandBuffer, 14, 1, 0, 0); - m_pContext->getMeshManager()->log_draw_call(ri.renderPass, "octree", "occlusion_test", 14); - - pOctreeNode->endOcclusionQuery(); - - if(bVisible) { - // Schedule a pass to get the result of the occlusion test only for future frames and passes, without rendering the model or recurring further - remainingOctreesTestResultsOnly.push_back(pOctreeNode); - } else { - // Schedule a pass to get the result of the occlusion test and continue recursion and rendering if test is true - remainingOctreesTestResults.push_back(pOctreeNode); - } - } - - if(bVisible) { - - // Add lights that influence this octree level and its children to the stack - int directional_light_count = 0; - int spot_light_count = 0; - int point_light_count = 0; - for(std::set::iterator itr=pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) { - KRNode *node = (*itr); - KRDirectionalLight *directional_light = dynamic_cast(node); - if(directional_light) { - ri.directional_lights.push_back(directional_light); - directional_light_count++; - } - KRSpotLight *spot_light = dynamic_cast(node); - if(spot_light) { - ri.spot_lights.push_back(spot_light); - spot_light_count++; - } - KRPointLight *point_light = dynamic_cast(node); - if(point_light) { - ri.point_lights.push_back(point_light); - point_light_count++; - } - } - - // Render objects that are at this octree level - for(std::set::iterator itr=pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) { - //assert(pOctreeNode->getBounds().contains((*itr)->getBounds())); // Sanity check - (*itr)->render(ri); - } - - // Render child octrees - const int *childOctreeOrder = ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || ri.renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES || ri.renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE ? ri.viewport.getBackToFrontOrder() : ri.viewport.getFrontToBackOrder(); - - for(int i=0; i<8; i++) { - render(ri, pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false); - } - - // Remove lights added at this octree level from the stack - while(directional_light_count--) { - ri.directional_lights.pop_back(); - } - while(spot_light_count--) { - ri.spot_lights.pop_back(); - } - while(point_light_count--) { - ri.point_lights.pop_back(); - } - } - } - } + + if (!bVisible && bNeedOcclusionTest) { + // Optimization: If this is an empty octree node with only a single child node, then immediately try to render the child node without an occlusion test for this higher level, as it would be more expensive than the occlusion test for the child + if (pOctreeNode->getSceneNodes().empty()) { + int child_count = 0; + for (int i = 0; i < 8; i++) { + if (pOctreeNode->getChildren()[i] != NULL) child_count++; + } + if (child_count == 1) { + bVisible = true; + bNeedOcclusionTest = false; + } + } + } + + if (bNeedOcclusionTest) { + pOctreeNode->beginOcclusionQuery(); + + Matrix4 matModel = Matrix4(); + matModel.scale(octreeBounds.size() * 0.5f); + matModel.translate(octreeBounds.center()); + Matrix4 mvpmatrix = matModel * ri.viewport.getViewProjectionMatrix(); + + KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_3D_CUBE_VERTICES; + + getContext().getMeshManager()->bindVBO(ri.commandBuffer, &vertices, 1.0f); + + PipelineInfo info{}; + std::string shader_name("occlusion_test"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.renderPass = KRNode::RENDER_PASS_FORWARD_TRANSPARENT; + info.rasterMode = RasterMode::kAdditive; + info.vertexAttributes = vertices.getVertexAttributes(); + info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; + + KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + pPipeline->bind(ri.commandBuffer, *info.pCamera, ri.viewport, matModel, info.point_lights, info.directional_lights, info.spot_lights, info.renderPass); + vkCmdDraw(ri.commandBuffer, 14, 1, 0, 0); + m_pContext->getMeshManager()->log_draw_call(ri.renderPass, "octree", "occlusion_test", 14); + + pOctreeNode->endOcclusionQuery(); + + if (bVisible) { + // Schedule a pass to get the result of the occlusion test only for future frames and passes, without rendering the model or recurring further + remainingOctreesTestResultsOnly.push_back(pOctreeNode); + } else { + // Schedule a pass to get the result of the occlusion test and continue recursion and rendering if test is true + remainingOctreesTestResults.push_back(pOctreeNode); + } + } + + if (bVisible) { + + // Add lights that influence this octree level and its children to the stack + int directional_light_count = 0; + int spot_light_count = 0; + int point_light_count = 0; + for (std::set::iterator itr = pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) { + KRNode* node = (*itr); + KRDirectionalLight* directional_light = dynamic_cast(node); + if (directional_light) { + ri.directional_lights.push_back(directional_light); + directional_light_count++; + } + KRSpotLight* spot_light = dynamic_cast(node); + if (spot_light) { + ri.spot_lights.push_back(spot_light); + spot_light_count++; + } + KRPointLight* point_light = dynamic_cast(node); + if (point_light) { + ri.point_lights.push_back(point_light); + point_light_count++; + } + } + + // Render objects that are at this octree level + for (std::set::iterator itr = pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) { + //assert(pOctreeNode->getBounds().contains((*itr)->getBounds())); // Sanity check + (*itr)->render(ri); + } + + // Render child octrees + const int* childOctreeOrder = ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || ri.renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES || ri.renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE ? ri.viewport.getBackToFrontOrder() : ri.viewport.getFrontToBackOrder(); + + for (int i = 0; i < 8; i++) { + render(ri, pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false); + } + + // Remove lights added at this octree level from the stack + while (directional_light_count--) { + ri.directional_lights.pop_back(); + } + while (spot_light_count--) { + ri.spot_lights.pop_back(); + } + while (point_light_count--) { + ri.point_lights.pop_back(); + } + } + } + } -// fprintf(stderr, "Octree culled: (%f, %f, %f) - (%f, %f, %f)\n", pOctreeNode->getBounds().min.x, pOctreeNode->getBounds().min.y, pOctreeNode->getBounds().min.z, pOctreeNode->getBounds().max.x, pOctreeNode->getBounds().max.y, pOctreeNode->getBounds().max.z); + } + // fprintf(stderr, "Octree culled: (%f, %f, %f) - (%f, %f, %f)\n", pOctreeNode->getBounds().min.x, pOctreeNode->getBounds().min.y, pOctreeNode->getBounds().min.z, pOctreeNode->getBounds().max.x, pOctreeNode->getBounds().max.y, pOctreeNode->getBounds().max.z); } -std::string KRScene::getExtension() { - return "krscene"; -} - -KRNode *KRScene::getRootNode() { - return m_pRootNode; -} - -bool KRScene::save(KRDataBlock &data) { - tinyxml2::XMLDocument doc; - tinyxml2::XMLElement *scene_node = doc.NewElement( "scene" ); - doc.InsertEndChild(scene_node); - m_pRootNode->saveXML(scene_node); - - tinyxml2::XMLPrinter p; - doc.Print(&p); - data.append((void *)p.CStr(), strlen(p.CStr())+1); - - return true; -} - -KRScene *KRScene::Load(KRContext &context, const std::string &name, KRDataBlock *data) +std::string KRScene::getExtension() { - std::string xml_string = data->getString(); - delete data; - tinyxml2::XMLDocument doc; - doc.Parse(xml_string.c_str()); - KRScene *new_scene = new KRScene(context, name); - - tinyxml2::XMLElement *scene_element = doc.RootElement(); - - KRNode *n = KRNode::LoadXML(*new_scene, scene_element->FirstChildElement()); - if(n) { - new_scene->getRootNode()->addChild(n); - } - - - return new_scene; + return "krscene"; +} + +KRNode* KRScene::getRootNode() +{ + return m_pRootNode; +} + +bool KRScene::save(KRDataBlock& data) +{ + tinyxml2::XMLDocument doc; + tinyxml2::XMLElement* scene_node = doc.NewElement("scene"); + doc.InsertEndChild(scene_node); + m_pRootNode->saveXML(scene_node); + + tinyxml2::XMLPrinter p; + doc.Print(&p); + data.append((void*)p.CStr(), strlen(p.CStr()) + 1); + + return true; +} + +KRScene* KRScene::Load(KRContext& context, const std::string& name, KRDataBlock* data) +{ + std::string xml_string = data->getString(); + delete data; + tinyxml2::XMLDocument doc; + doc.Parse(xml_string.c_str()); + KRScene* new_scene = new KRScene(context, name); + + tinyxml2::XMLElement* scene_element = doc.RootElement(); + + KRNode* n = KRNode::LoadXML(*new_scene, scene_element->FirstChildElement()); + if (n) { + new_scene->getRootNode()->addChild(n); + } + + + return new_scene; } -KRLight *KRScene::getFirstLight() +KRLight* KRScene::getFirstLight() { - if(m_pFirstLight == NULL) { - m_pFirstLight = find(); - } - return m_pFirstLight; + if (m_pFirstLight == NULL) { + m_pFirstLight = find(); + } + return m_pFirstLight; } -void KRScene::notify_sceneGraphCreate(KRNode *pNode) +void KRScene::notify_sceneGraphCreate(KRNode* pNode) { -// m_nodeTree.add(pNode); -// if(pNode->hasPhysics()) { -// m_physicsNodes.insert(pNode); -// } - m_newNodes.insert(pNode); + // m_nodeTree.add(pNode); + // if(pNode->hasPhysics()) { + // m_physicsNodes.insert(pNode); + // } + m_newNodes.insert(pNode); } -void KRScene::notify_sceneGraphModify(KRNode *pNode) +void KRScene::notify_sceneGraphModify(KRNode* pNode) { - // m_nodeTree.update(pNode); - m_modifiedNodes.insert(pNode); + // m_nodeTree.update(pNode); + m_modifiedNodes.insert(pNode); } -void KRScene::notify_sceneGraphDelete(KRNode *pNode) +void KRScene::notify_sceneGraphDelete(KRNode* pNode) { + m_nodeTree.remove(pNode); + m_physicsNodes.erase(pNode); + KRAmbientZone* AmbientZoneNode = dynamic_cast(pNode); + if (AmbientZoneNode) { + m_ambientZoneNodes.erase(AmbientZoneNode); + } + KRReverbZone* ReverbZoneNode = dynamic_cast(pNode); + if (ReverbZoneNode) { + m_reverbZoneNodes.erase(ReverbZoneNode); + } + KRLocator* locator = dynamic_cast(pNode); + if (locator) { + m_locatorNodes.erase(locator); + } + KRLight* light = dynamic_cast(pNode); + if (light) { + m_lights.erase(light); + } + m_modifiedNodes.erase(pNode); + if (!m_newNodes.erase(pNode)) { m_nodeTree.remove(pNode); - m_physicsNodes.erase(pNode); - KRAmbientZone *AmbientZoneNode = dynamic_cast(pNode); - if(AmbientZoneNode) { - m_ambientZoneNodes.erase(AmbientZoneNode); - } - KRReverbZone *ReverbZoneNode = dynamic_cast(pNode); - if(ReverbZoneNode) { - m_reverbZoneNodes.erase(ReverbZoneNode); - } - KRLocator *locator = dynamic_cast(pNode); - if(locator) { - m_locatorNodes.erase(locator); - } - KRLight *light = dynamic_cast(pNode); - if(light) { - m_lights.erase(light); - } - m_modifiedNodes.erase(pNode); - if(!m_newNodes.erase(pNode)) { - m_nodeTree.remove(pNode); - } + } } -void KRScene::updateOctree(const KRViewport &viewport) +void KRScene::updateOctree(const KRViewport& viewport) { - m_pRootNode->setLODVisibility(KRNode::LOD_VISIBILITY_VISIBLE); - m_pRootNode->updateLODVisibility(viewport); - - std::set newNodes = std::move(m_newNodes); - std::set modifiedNodes = std::move(m_modifiedNodes); - m_newNodes.clear(); - m_modifiedNodes.clear(); - - for(std::set::iterator itr=newNodes.begin(); itr != newNodes.end(); itr++) { - KRNode *node = *itr; - m_nodeTree.add(node); - if(node->hasPhysics()) { - m_physicsNodes.insert(node); - } - KRAmbientZone *ambientZoneNode = dynamic_cast(node); - if(ambientZoneNode) { - m_ambientZoneNodes.insert(ambientZoneNode); - } - KRReverbZone *reverbZoneNode = dynamic_cast(node); - if(reverbZoneNode) { - m_reverbZoneNodes.insert(reverbZoneNode); - } - KRLocator *locatorNode = dynamic_cast(node); - if(locatorNode) { - m_locatorNodes.insert(locatorNode); - } - KRLight *light = dynamic_cast(node); - if(light) { - m_lights.insert(light); - } + m_pRootNode->setLODVisibility(KRNode::LOD_VISIBILITY_VISIBLE); + m_pRootNode->updateLODVisibility(viewport); + + std::set newNodes = std::move(m_newNodes); + std::set modifiedNodes = std::move(m_modifiedNodes); + m_newNodes.clear(); + m_modifiedNodes.clear(); + + for (std::set::iterator itr = newNodes.begin(); itr != newNodes.end(); itr++) { + KRNode* node = *itr; + m_nodeTree.add(node); + if (node->hasPhysics()) { + m_physicsNodes.insert(node); } - for(std::set::iterator itr=modifiedNodes.begin(); itr != modifiedNodes.end(); itr++) { - KRNode *node = *itr; - if(node->getLODVisibility() >= KRNode::LOD_VISIBILITY_PRESTREAM) { - m_nodeTree.update(node); - } - if(node->hasPhysics()) { - m_physicsNodes.insert(node); - } else if(!node->hasPhysics()) { - m_physicsNodes.erase(node); - } + KRAmbientZone* ambientZoneNode = dynamic_cast(node); + if (ambientZoneNode) { + m_ambientZoneNodes.insert(ambientZoneNode); } + KRReverbZone* reverbZoneNode = dynamic_cast(node); + if (reverbZoneNode) { + m_reverbZoneNodes.insert(reverbZoneNode); + } + KRLocator* locatorNode = dynamic_cast(node); + if (locatorNode) { + m_locatorNodes.insert(locatorNode); + } + KRLight* light = dynamic_cast(node); + if (light) { + m_lights.insert(light); + } + } + for (std::set::iterator itr = modifiedNodes.begin(); itr != modifiedNodes.end(); itr++) { + KRNode* node = *itr; + if (node->getLODVisibility() >= KRNode::LOD_VISIBILITY_PRESTREAM) { + m_nodeTree.update(node); + } + if (node->hasPhysics()) { + m_physicsNodes.insert(node); + } else if (!node->hasPhysics()) { + m_physicsNodes.erase(node); + } + } } void KRScene::buildOctreeForTheFirstTime() { - std::set newNodes = std::move(m_newNodes); - m_newNodes.clear(); - for(std::set::iterator itr=newNodes.begin(); itr != newNodes.end(); itr++) { - KRNode *node = *itr; - m_nodeTree.add(node); - if(node->hasPhysics()) { - m_physicsNodes.insert(node); - } - KRAmbientZone *ambientZoneNode = dynamic_cast(node); - if(ambientZoneNode) { - m_ambientZoneNodes.insert(ambientZoneNode); - } - KRReverbZone *reverbZoneNode = dynamic_cast(node); - if(reverbZoneNode) { - m_reverbZoneNodes.insert(reverbZoneNode); - } - KRLocator *locatorNode = dynamic_cast(node); - if(locatorNode) { - m_locatorNodes.insert(locatorNode); - } - KRLight *light = dynamic_cast(node); - if(light) { - m_lights.insert(light); - } + std::set newNodes = std::move(m_newNodes); + m_newNodes.clear(); + for (std::set::iterator itr = newNodes.begin(); itr != newNodes.end(); itr++) { + KRNode* node = *itr; + m_nodeTree.add(node); + if (node->hasPhysics()) { + m_physicsNodes.insert(node); } + KRAmbientZone* ambientZoneNode = dynamic_cast(node); + if (ambientZoneNode) { + m_ambientZoneNodes.insert(ambientZoneNode); + } + KRReverbZone* reverbZoneNode = dynamic_cast(node); + if (reverbZoneNode) { + m_reverbZoneNodes.insert(reverbZoneNode); + } + KRLocator* locatorNode = dynamic_cast(node); + if (locatorNode) { + m_locatorNodes.insert(locatorNode); + } + KRLight* light = dynamic_cast(node); + if (light) { + m_lights.insert(light); + } + } } void KRScene::physicsUpdate(float deltaTime) { - for(std::set::iterator itr=m_physicsNodes.begin(); itr != m_physicsNodes.end(); itr++) { - (*itr)->physicsUpdate(deltaTime); - } + for (std::set::iterator itr = m_physicsNodes.begin(); itr != m_physicsNodes.end(); itr++) { + (*itr)->physicsUpdate(deltaTime); + } } void KRScene::addDefaultLights() { - KRDirectionalLight *light1 = new KRDirectionalLight(*this, "default_light1"); - - light1->setLocalRotation((Quaternion::Create(Vector3::Create(0.0f, (float)M_PI * 0.10f, 0.0f)) * Quaternion::Create(Vector3::Create(0.0f, 0.0f, (float)-M_PI * 0.15f))).eulerXYZ()); - m_pRootNode->addChild(light1); + KRDirectionalLight* light1 = new KRDirectionalLight(*this, "default_light1"); + + light1->setLocalRotation((Quaternion::Create(Vector3::Create(0.0f, (float)M_PI * 0.10f, 0.0f)) * Quaternion::Create(Vector3::Create(0.0f, 0.0f, (float)-M_PI * 0.15f))).eulerXYZ()); + m_pRootNode->addChild(light1); } AABB KRScene::getRootOctreeBounds() { - if(m_nodeTree.getRootNode()) { - return m_nodeTree.getRootNode()->getBounds(); - } else { - return AABB::Create(-Vector3::One(), Vector3::One()); - } + if (m_nodeTree.getRootNode()) { + return m_nodeTree.getRootNode()->getBounds(); + } else { + return AABB::Create(-Vector3::One(), Vector3::One()); + } } -bool KRScene::lineCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo, unsigned int layer_mask) +bool KRScene::lineCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo, unsigned int layer_mask) { - return m_nodeTree.lineCast(v0, v1, hitinfo, layer_mask); + return m_nodeTree.lineCast(v0, v1, hitinfo, layer_mask); } -bool KRScene::rayCast(const Vector3 &v0, const Vector3 &dir, HitInfo &hitinfo, unsigned int layer_mask) +bool KRScene::rayCast(const Vector3& v0, const Vector3& dir, HitInfo& hitinfo, unsigned int layer_mask) { - return m_nodeTree.rayCast(v0, dir, hitinfo, layer_mask); + return m_nodeTree.rayCast(v0, dir, hitinfo, layer_mask); } -bool KRScene::sphereCast(const Vector3 &v0, const Vector3 &v1, float radius, HitInfo &hitinfo, unsigned int layer_mask) +bool KRScene::sphereCast(const Vector3& v0, const Vector3& v1, float radius, HitInfo& hitinfo, unsigned int layer_mask) { - return m_nodeTree.sphereCast(v0, v1, radius, hitinfo, layer_mask); + return m_nodeTree.sphereCast(v0, v1, radius, hitinfo, layer_mask); } kraken_stream_level KRScene::getStreamLevel() { - kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; - - if(m_pRootNode) { - KRViewport viewport; // This isn't used when prime is false - stream_level = KRMIN(stream_level, m_pRootNode->getStreamLevel(viewport)); - } - - return stream_level; + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + + if (m_pRootNode) { + KRViewport viewport; // This isn't used when prime is false + stream_level = KRMIN(stream_level, m_pRootNode->getStreamLevel(viewport)); + } + + return stream_level; } diff --git a/kraken/KRScene.h b/kraken/KRScene.h index a410c65..a585937 100755 --- a/kraken/KRScene.h +++ b/kraken/KRScene.h @@ -48,77 +48,78 @@ class KRSurface; using std::vector; -class KRScene : public KRResource { +class KRScene : public KRResource +{ public: - KRScene(KRContext &context, std::string name); - virtual ~KRScene(); + KRScene(KRContext& context, std::string name); + virtual ~KRScene(); - virtual std::string getExtension(); - virtual bool save(KRDataBlock &data); + virtual std::string getExtension(); + virtual bool save(KRDataBlock& data); - static KRScene *Load(KRContext &context, const std::string &name, KRDataBlock *data); + static KRScene* Load(KRContext& context, const std::string& name, KRDataBlock* data); - KRNode *getRootNode(); - KRLight *getFirstLight(); + KRNode* getRootNode(); + KRLight* getFirstLight(); - kraken_stream_level getStreamLevel(); + kraken_stream_level getStreamLevel(); - bool lineCast(const Vector3 &v0, const Vector3 &v1, HitInfo &hitinfo, unsigned int layer_mask); - bool rayCast(const Vector3 &v0, const Vector3 &dir, HitInfo &hitinfo, unsigned int layer_mask); - bool sphereCast(const Vector3 &v0, const Vector3 &v1, float radius, HitInfo &hitinfo, unsigned int layer_mask); + bool lineCast(const Vector3& v0, const Vector3& v1, HitInfo& hitinfo, unsigned int layer_mask); + bool rayCast(const Vector3& v0, const Vector3& dir, HitInfo& hitinfo, unsigned int layer_mask); + bool sphereCast(const Vector3& v0, const Vector3& v1, float radius, HitInfo& hitinfo, unsigned int layer_mask); - void renderFrame(VkCommandBuffer& commandBuffer, KRSurface& surface, float deltaTime); - void render(VkCommandBuffer& commandBuffer, KRSurface& surface, KRCamera *pCamera, unordered_map &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame); - void render(KRNode::RenderInfo& ri, KROctreeNode *pOctreeNode, unordered_map &visibleBounds, std::vector &remainingOctrees, std::vector &remainingOctreesTestResults, std::vector &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly); + void renderFrame(VkCommandBuffer& commandBuffer, KRSurface& surface, float deltaTime); + void render(VkCommandBuffer& commandBuffer, KRSurface& surface, KRCamera* pCamera, unordered_map& visibleBounds, const KRViewport& viewport, KRNode::RenderPass renderPass, bool new_frame); + void render(KRNode::RenderInfo& ri, KROctreeNode* pOctreeNode, unordered_map& visibleBounds, std::vector& remainingOctrees, std::vector& remainingOctreesTestResults, std::vector& remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly); - void updateOctree(const KRViewport &viewport); - void buildOctreeForTheFirstTime(); + void updateOctree(const KRViewport& viewport); + void buildOctreeForTheFirstTime(); - void notify_sceneGraphCreate(KRNode *pNode); - void notify_sceneGraphDelete(KRNode *pNode); - void notify_sceneGraphModify(KRNode *pNode); + void notify_sceneGraphCreate(KRNode* pNode); + void notify_sceneGraphDelete(KRNode* pNode); + void notify_sceneGraphModify(KRNode* pNode); - void physicsUpdate(float deltaTime); - void addDefaultLights(); + void physicsUpdate(float deltaTime); + void addDefaultLights(); - AABB getRootOctreeBounds(); + AABB getRootOctreeBounds(); - std::set &getAmbientZones(); - std::set &getReverbZones(); - std::set &getLocators(); - std::set &getLights(); + std::set& getAmbientZones(); + std::set& getReverbZones(); + std::set& getLocators(); + std::set& getLights(); private: - KRNode *m_pRootNode; - KRLight *m_pFirstLight; + KRNode* m_pRootNode; + KRLight* m_pFirstLight; - std::set m_newNodes; - std::set m_modifiedNodes; + std::set m_newNodes; + std::set m_modifiedNodes; - std::set m_physicsNodes; - std::set m_ambientZoneNodes; - std::set m_reverbZoneNodes; - std::set m_locatorNodes; - std::set m_lights; + std::set m_physicsNodes; + std::set m_ambientZoneNodes; + std::set m_reverbZoneNodes; + std::set m_locatorNodes; + std::set m_lights; - KROctree m_nodeTree; + KROctree m_nodeTree; public: - template T *find() - { - if(m_pRootNode) return m_pRootNode->find(); - return NULL; - } + template T* find() + { + if (m_pRootNode) return m_pRootNode->find(); + return NULL; + } - template T *find(const std::string &name) - { - if(m_pRootNode) return m_pRootNode->find(name); - return NULL; - } + template T* find(const std::string& name) + { + if (m_pRootNode) return m_pRootNode->find(name); + return NULL; + } }; diff --git a/kraken/KRSceneManager.cpp b/kraken/KRSceneManager.cpp index cfe8613..706a4c3 100755 --- a/kraken/KRSceneManager.cpp +++ b/kraken/KRSceneManager.cpp @@ -32,14 +32,15 @@ #include "KRSceneManager.h" #include "KRScene.h" -KRSceneManager::KRSceneManager(KRContext &context) : KRResourceManager(context){ -} +KRSceneManager::KRSceneManager(KRContext& context) : KRResourceManager(context) +{} -KRSceneManager::~KRSceneManager() { - for(unordered_map::iterator itr = m_scenes.begin(); itr != m_scenes.end(); ++itr){ - delete (*itr).second; - } - m_scenes.clear(); +KRSceneManager::~KRSceneManager() +{ + for (unordered_map::iterator itr = m_scenes.begin(); itr != m_scenes.end(); ++itr) { + delete (*itr).second; + } + m_scenes.clear(); } KRResource* KRSceneManager::loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) @@ -58,15 +59,16 @@ KRResource* KRSceneManager::getResource(const std::string& name, const std::stri return nullptr; } -KRScene *KRSceneManager::loadScene(const std::string &name, KRDataBlock *data) { - std::lock_guard lock(m_mutex); - std::string lowerName = name; - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - - KRScene *pScene = KRScene::Load(*m_pContext, name, data); - m_scenes[lowerName] = pScene; - return pScene; +KRScene* KRSceneManager::loadScene(const std::string& name, KRDataBlock* data) +{ + std::lock_guard lock(m_mutex); + std::string lowerName = name; + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + + KRScene* pScene = KRScene::Load(*m_pContext, name, data); + m_scenes[lowerName] = pScene; + return pScene; } @@ -78,40 +80,43 @@ KRScene* KRSceneManager::createScene(const std::string& name) return pScene; } -void KRSceneManager::add(KRScene *scene) +void KRSceneManager::add(KRScene* scene) { std::lock_guard lock(m_mutex); - std::string lowerName = scene->getName(); - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - m_scenes[lowerName] = scene; + std::string lowerName = scene->getName(); + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + m_scenes[lowerName] = scene; } -KRScene *KRSceneManager::getScene(const std::string &name) { +KRScene* KRSceneManager::getScene(const std::string& name) +{ std::lock_guard lock(m_mutex); - std::string lowerName = name; - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - - static unordered_map::iterator scene_itr = m_scenes.find(lowerName); - if(scene_itr != m_scenes.end()) { - return (*scene_itr).second; - } else { - return NULL; - } + std::string lowerName = name; + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + + static unordered_map::iterator scene_itr = m_scenes.find(lowerName); + if (scene_itr != m_scenes.end()) { + return (*scene_itr).second; + } else { + return NULL; + } } -KRScene *KRSceneManager::getFirstScene() { - std::lock_guard lock(m_mutex); - unordered_map::iterator scene_itr = m_scenes.begin(); - if(scene_itr != m_scenes.end()) { - return (*scene_itr).second; - } else { - return NULL; - } +KRScene* KRSceneManager::getFirstScene() +{ + std::lock_guard lock(m_mutex); + unordered_map::iterator scene_itr = m_scenes.begin(); + if (scene_itr != m_scenes.end()) { + return (*scene_itr).second; + } else { + return NULL; + } } -unordered_map &KRSceneManager::getScenes() { - return m_scenes; +unordered_map& KRSceneManager::getScenes() +{ + return m_scenes; } diff --git a/kraken/KRSceneManager.h b/kraken/KRSceneManager.h index d5ba7b3..f007eca 100755 --- a/kraken/KRSceneManager.h +++ b/kraken/KRSceneManager.h @@ -39,29 +39,29 @@ class KRScene; - -class KRSceneManager : public KRResourceManager { +class KRSceneManager : public KRResourceManager +{ public: - KRSceneManager(KRContext &context); - virtual ~KRSceneManager(); - - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; + KRSceneManager(KRContext& context); + virtual ~KRSceneManager(); - KRScene* createScene(const std::string& name); + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - void add(KRScene *scene); - KRScene *loadScene(const std::string &name, KRDataBlock *data); + KRScene* createScene(const std::string& name); + + void add(KRScene* scene); + KRScene* loadScene(const std::string& name, KRDataBlock* data); + + KRScene* getScene(const std::string& name); + KRScene* getFirstScene(); + + std::vector getSceneNames(); + unordered_map& getScenes(); - KRScene *getScene(const std::string &name); - KRScene *getFirstScene(); - - std::vector getSceneNames(); - unordered_map &getScenes(); - private: - unordered_map m_scenes; - std::mutex m_mutex; - + unordered_map m_scenes; + std::mutex m_mutex; + }; diff --git a/kraken/KRShader.cpp b/kraken/KRShader.cpp index e658de8..8511f2f 100644 --- a/kraken/KRShader.cpp +++ b/kraken/KRShader.cpp @@ -32,33 +32,33 @@ #include "KRShader.h" #include "spirv_reflect.h" -KRShader::KRShader(KRContext &context, std::string name, std::string extension) : KRResource(context, name) +KRShader::KRShader(KRContext& context, std::string name, std::string extension) : KRResource(context, name) { - m_pData = new KRDataBlock(); - m_extension = extension; - m_subExtension = KRResource::GetFileExtension(name); - m_reflectionValid = false; + m_pData = new KRDataBlock(); + m_extension = extension; + m_subExtension = KRResource::GetFileExtension(name); + m_reflectionValid = false; - getReflection(); + getReflection(); } -KRShader::KRShader(KRContext &context, std::string name, std::string extension, KRDataBlock *data) : KRResource(context, name) +KRShader::KRShader(KRContext& context, std::string name, std::string extension, KRDataBlock* data) : KRResource(context, name) { - m_pData = data; - m_extension = extension; - m_subExtension = KRResource::GetFileExtension(name); - m_reflectionValid = false; + m_pData = data; + m_extension = extension; + m_subExtension = KRResource::GetFileExtension(name); + m_reflectionValid = false; } KRShader::~KRShader() { - freeReflection(); - delete m_pData; + freeReflection(); + delete m_pData; } std::string KRShader::getExtension() { - return m_extension; + return m_extension; } std::string& KRShader::getSubExtension() @@ -66,15 +66,15 @@ std::string& KRShader::getSubExtension() return m_subExtension; } -bool KRShader::save(KRDataBlock &data) +bool KRShader::save(KRDataBlock& data) { - data.append(*m_pData); - return true; + data.append(*m_pData); + return true; } -KRDataBlock *KRShader::getData() +KRDataBlock* KRShader::getData() { - return m_pData; + return m_pData; } bool KRShader::createShaderModule(VkDevice& device, VkShaderModule& module) @@ -85,10 +85,10 @@ bool KRShader::createShaderModule(VkDevice& device, VkShaderModule& module) createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; createInfo.codeSize = m_pData->getSize(); createInfo.pCode = reinterpret_cast(m_pData->getStart()); - + VkResult result = vkCreateShaderModule(device, &createInfo, nullptr, &module); - - if(result != VK_SUCCESS) { + + if (result != VK_SUCCESS) { success = false; } m_pData->unlock(); diff --git a/kraken/KRShader.h b/kraken/KRShader.h index b6022c7..bdbe2ec 100644 --- a/kraken/KRShader.h +++ b/kraken/KRShader.h @@ -37,31 +37,31 @@ #include "KRResource.h" #include "spirv_reflect.h" -class KRShader : public KRResource { - +class KRShader : public KRResource +{ public: - KRShader(KRContext &context, std::string name, std::string extension); - KRShader(KRContext &context, std::string name, std::string extension, KRDataBlock *data); - virtual ~KRShader(); - - virtual std::string getExtension(); - std::string& getSubExtension(); + KRShader(KRContext& context, std::string name, std::string extension); + KRShader(KRContext& context, std::string name, std::string extension, KRDataBlock* data); + virtual ~KRShader(); + + virtual std::string getExtension(); + std::string& getSubExtension(); + + bool createShaderModule(VkDevice& device, VkShaderModule& module); + + virtual bool save(KRDataBlock& data); + + KRDataBlock* getData(); + const SpvReflectShaderModule* getReflection(); - bool createShaderModule(VkDevice& device, VkShaderModule& module); - - virtual bool save(KRDataBlock &data); - - KRDataBlock *getData(); - const SpvReflectShaderModule* getReflection(); - private: - - std::string m_extension; - std::string m_subExtension; - KRDataBlock *m_pData; - SpvReflectShaderModule m_reflection; - bool m_reflectionValid; - void parseReflection(); - void freeReflection(); + std::string m_extension; + std::string m_subExtension; + KRDataBlock* m_pData; + SpvReflectShaderModule m_reflection; + bool m_reflectionValid; + + void parseReflection(); + void freeReflection(); }; diff --git a/kraken/KRShaderManager.cpp b/kraken/KRShaderManager.cpp index 37db9ba..2fb29dd 100644 --- a/kraken/KRShaderManager.cpp +++ b/kraken/KRShaderManager.cpp @@ -36,22 +36,22 @@ #include "KRUnknownManager.h" #include "KRUnknown.h" -KRShaderManager::KRShaderManager(KRContext &context) : KRResourceManager(context) +KRShaderManager::KRShaderManager(KRContext& context) : KRResourceManager(context) , m_initializedGlslang(false) { - + } KRShaderManager::~KRShaderManager() { - for(unordered_map >::iterator extension_itr = m_shaders.begin(); extension_itr != m_shaders.end(); extension_itr++) { - for(unordered_map::iterator name_itr=(*extension_itr).second.begin(); name_itr != (*extension_itr).second.end(); name_itr++) { - delete (*name_itr).second; - } - } - if (m_initializedGlslang) { - glslang::FinalizeProcess(); + for (unordered_map >::iterator extension_itr = m_shaders.begin(); extension_itr != m_shaders.end(); extension_itr++) { + for (unordered_map::iterator name_itr = (*extension_itr).second.begin(); name_itr != (*extension_itr).second.end(); name_itr++) { + delete (*name_itr).second; } + } + if (m_initializedGlslang) { + glslang::FinalizeProcess(); + } } KRResource* KRShaderManager::loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) @@ -69,58 +69,58 @@ KRResource* KRShaderManager::getResource(const std::string& name, const std::str return nullptr; } -unordered_map > &KRShaderManager::getShaders() +unordered_map >& KRShaderManager::getShaders() { - return m_shaders; + return m_shaders; } -void KRShaderManager::add(KRShader *shader) +void KRShaderManager::add(KRShader* shader) { - std::string lower_name = shader->getName(); - std::string lower_extension = shader->getExtension(); - - std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); - std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); - - unordered_map >::iterator extension_itr = m_shaders.find(lower_extension); - if(extension_itr == m_shaders.end()) { - m_shaders[lower_extension] = unordered_map(); - extension_itr = m_shaders.find(lower_extension); - } - - unordered_map::iterator name_itr = (*extension_itr).second.find(lower_name); - if(name_itr != (*extension_itr).second.end()) { - delete (*name_itr).second; - (*name_itr).second = shader; - } else { - (*extension_itr).second[lower_name] = shader; - } + std::string lower_name = shader->getName(); + std::string lower_extension = shader->getExtension(); + + std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); + std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); + + unordered_map >::iterator extension_itr = m_shaders.find(lower_extension); + if (extension_itr == m_shaders.end()) { + m_shaders[lower_extension] = unordered_map(); + extension_itr = m_shaders.find(lower_extension); + } + + unordered_map::iterator name_itr = (*extension_itr).second.find(lower_name); + if (name_itr != (*extension_itr).second.end()) { + delete (*name_itr).second; + (*name_itr).second = shader; + } else { + (*extension_itr).second[lower_name] = shader; + } } -KRShader *KRShaderManager::load(const std::string &name, const std::string &extension, KRDataBlock *data) +KRShader* KRShaderManager::load(const std::string& name, const std::string& extension, KRDataBlock* data) { - KRShader *shader = new KRShader(getContext(), name, extension, data); - if(shader) add(shader); - return shader; + KRShader* shader = new KRShader(getContext(), name, extension, data); + if (shader) add(shader); + return shader; } -KRShader *KRShaderManager::get(const std::string &name, const std::string &extension) +KRShader* KRShaderManager::get(const std::string& name, const std::string& extension) { - std::string lower_name = name; - std::string lower_extension = extension; - - std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); - std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); - - return m_shaders[lower_extension][lower_name]; + std::string lower_name = name; + std::string lower_extension = extension; + + std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); + std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); + + return m_shaders[lower_extension][lower_name]; } -const unordered_map &KRShaderManager::get(const std::string &extension) +const unordered_map& KRShaderManager::get(const std::string& extension) { - std::string lower_extension = extension; - std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); - return m_shaders[lower_extension]; + std::string lower_extension = extension; + std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); + return m_shaders[lower_extension]; } // From glslang/StandAlone/ResourceLimits.cpp @@ -278,16 +278,16 @@ bool KRShaderManager::compileAll(KRBundle* outputBundle, KRUnknown* logResource) std::string fragSourceName; auto parse_shader = [&](KRSource* source, glslang::TShader& shader, const char** sourceText, int* sourceLen, const char** sourceNameStr, std::string& sourceName) { - if(source == nullptr) { + if (source == nullptr) { return; } sourceName = source->getName() + "." + source->getExtension(); - sourceText[0] = (char *)source->getData()->getStart(); + sourceText[0] = (char*)source->getData()->getStart(); sourceLen[0] = source->getData()->getSize(); sourceNameStr[0] = sourceName.c_str(); shader.setStringsWithLengthsAndNames(sourceText, sourceLen, sourceNameStr, 1); //shader.setStrings(&sourceStr, 1); - + if (shader.parse(&resources, defaultVersion, false, messages)) { program.addShader(&shader); } else { @@ -302,7 +302,7 @@ bool KRShaderManager::compileAll(KRBundle* outputBundle, KRUnknown* logResource) parse_shader(vertSource, vertShader, vertSourceText, vertSourceLen, vertSourceNameStr, vertSourceName); parse_shader(fragSource, fragShader, fragSourceText, fragSourceLen, fragSourceNameStr, fragSourceName); - + if (!program.link(messages)) { const char* log = program.getInfoLog(); if (log[0] != '\0') { @@ -327,8 +327,7 @@ bool KRShaderManager::compileAll(KRBundle* outputBundle, KRUnknown* logResource) } std::string shader_name; - switch (stage) - { + switch (stage) { case EShLangVertex: shader_name = vertSourceName; break; @@ -348,7 +347,7 @@ bool KRShaderManager::compileAll(KRBundle* outputBundle, KRUnknown* logResource) } } } - + if (vertSource) { vertSource->getData()->unlock(); } diff --git a/kraken/KRShaderManager.h b/kraken/KRShaderManager.h index 32b4880..5339b6e 100644 --- a/kraken/KRShaderManager.h +++ b/kraken/KRShaderManager.h @@ -41,26 +41,27 @@ class KRUnknown; -class KRShaderManager : public KRResourceManager { +class KRShaderManager : public KRResourceManager +{ public: - KRShaderManager(KRContext &context); - virtual ~KRShaderManager(); + KRShaderManager(KRContext& context); + virtual ~KRShaderManager(); - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - - void add(KRShader *shader); - - KRShader *load(const std::string &name, const std::string &extension, KRDataBlock *data); - KRShader *get(const std::string &name, const std::string &extension); + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - bool compileAll(KRBundle* outputBundle, KRUnknown* logResource); + void add(KRShader* shader); + + KRShader* load(const std::string& name, const std::string& extension, KRDataBlock* data); + KRShader* get(const std::string& name, const std::string& extension); + + bool compileAll(KRBundle* outputBundle, KRUnknown* logResource); + + const unordered_map& get(const std::string& extension); + + unordered_map >& getShaders(); - const unordered_map &get(const std::string &extension); - - unordered_map > &getShaders(); - private: - unordered_map > m_shaders; - bool m_initializedGlslang; + unordered_map > m_shaders; + bool m_initializedGlslang; }; diff --git a/kraken/KRSource.cpp b/kraken/KRSource.cpp index 2edc531..b94a93c 100644 --- a/kraken/KRSource.cpp +++ b/kraken/KRSource.cpp @@ -31,35 +31,35 @@ #include "KRSource.h" -KRSource::KRSource(KRContext &context, std::string name, std::string extension) : KRResource(context, name) +KRSource::KRSource(KRContext& context, std::string name, std::string extension) : KRResource(context, name) { - m_pData = new KRDataBlock(); - m_extension = extension; + m_pData = new KRDataBlock(); + m_extension = extension; } -KRSource::KRSource(KRContext &context, std::string name, std::string extension, KRDataBlock *data) : KRResource(context, name) +KRSource::KRSource(KRContext& context, std::string name, std::string extension, KRDataBlock* data) : KRResource(context, name) { - m_pData = data; - m_extension = extension; + m_pData = data; + m_extension = extension; } KRSource::~KRSource() { - delete m_pData; + delete m_pData; } std::string KRSource::getExtension() { - return m_extension; + return m_extension; } -bool KRSource::save(KRDataBlock &data) +bool KRSource::save(KRDataBlock& data) { - data.append(*m_pData); - return true; + data.append(*m_pData); + return true; } -KRDataBlock *KRSource::getData() +KRDataBlock* KRSource::getData() { - return m_pData; + return m_pData; } diff --git a/kraken/KRSource.h b/kraken/KRSource.h index 7c7910d..52e6c00 100644 --- a/kraken/KRSource.h +++ b/kraken/KRSource.h @@ -36,21 +36,22 @@ #include "KRDataBlock.h" #include "KRResource.h" -class KRSource : public KRResource { - +class KRSource : public KRResource +{ + public: - KRSource(KRContext &context, std::string name, std::string extension); - KRSource(KRContext &context, std::string name, std::string extension, KRDataBlock *data); - virtual ~KRSource(); - - virtual std::string getExtension(); - - virtual bool save(KRDataBlock &data); - - KRDataBlock *getData(); + KRSource(KRContext& context, std::string name, std::string extension); + KRSource(KRContext& context, std::string name, std::string extension, KRDataBlock* data); + virtual ~KRSource(); + + virtual std::string getExtension(); + + virtual bool save(KRDataBlock& data); + + KRDataBlock* getData(); private: - - std::string m_extension; - KRDataBlock *m_pData; + + std::string m_extension; + KRDataBlock* m_pData; }; diff --git a/kraken/KRSourceManager.cpp b/kraken/KRSourceManager.cpp index f3ff14f..9d38ba2 100644 --- a/kraken/KRSourceManager.cpp +++ b/kraken/KRSourceManager.cpp @@ -32,46 +32,46 @@ #include "KRSourceManager.h" #include "KREngine-common.h" -KRSourceManager::KRSourceManager(KRContext &context) : KRResourceManager(context) +KRSourceManager::KRSourceManager(KRContext& context) : KRResourceManager(context) { - + } KRSourceManager::~KRSourceManager() { - for(unordered_map >::iterator extension_itr = m_sources.begin(); extension_itr != m_sources.end(); extension_itr++) { - for(unordered_map::iterator name_itr=(*extension_itr).second.begin(); name_itr != (*extension_itr).second.end(); name_itr++) { - delete (*name_itr).second; - } + for (unordered_map >::iterator extension_itr = m_sources.begin(); extension_itr != m_sources.end(); extension_itr++) { + for (unordered_map::iterator name_itr = (*extension_itr).second.begin(); name_itr != (*extension_itr).second.end(); name_itr++) { + delete (*name_itr).second; } + } } -unordered_map > &KRSourceManager::getSources() +unordered_map >& KRSourceManager::getSources() { - return m_sources; + return m_sources; } -void KRSourceManager::add(KRSource *source) +void KRSourceManager::add(KRSource* source) { - std::string lower_name = source->getName(); - std::string lower_extension = source->getExtension(); - - std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); - std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); - - unordered_map >::iterator extension_itr = m_sources.find(lower_extension); - if(extension_itr == m_sources.end()) { - m_sources[lower_extension] = unordered_map(); - extension_itr = m_sources.find(lower_extension); - } - - unordered_map::iterator name_itr = (*extension_itr).second.find(lower_name); - if(name_itr != (*extension_itr).second.end()) { - delete (*name_itr).second; - (*name_itr).second = source; - } else { - (*extension_itr).second[lower_name] = source; - } + std::string lower_name = source->getName(); + std::string lower_extension = source->getExtension(); + + std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); + std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); + + unordered_map >::iterator extension_itr = m_sources.find(lower_extension); + if (extension_itr == m_sources.end()) { + m_sources[lower_extension] = unordered_map(); + extension_itr = m_sources.find(lower_extension); + } + + unordered_map::iterator name_itr = (*extension_itr).second.find(lower_name); + if (name_itr != (*extension_itr).second.end()) { + delete (*name_itr).second; + (*name_itr).second = source; + } else { + (*extension_itr).second[lower_name] = source; + } } KRResource* KRSourceManager::loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) @@ -120,29 +120,29 @@ KRResource* KRSourceManager::getResource(const std::string& name, const std::str return nullptr; } -KRSource *KRSourceManager::load(const std::string &name, const std::string &extension, KRDataBlock *data) +KRSource* KRSourceManager::load(const std::string& name, const std::string& extension, KRDataBlock* data) { - KRSource *source = new KRSource(getContext(), name, extension, data); - if(source) add(source); - return source; + KRSource* source = new KRSource(getContext(), name, extension, data); + if (source) add(source); + return source; } -KRSource *KRSourceManager::get(const std::string &name, const std::string &extension) +KRSource* KRSourceManager::get(const std::string& name, const std::string& extension) { - std::string lower_name = name; - std::string lower_extension = extension; - - std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); - std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); - - return m_sources[lower_extension][lower_name]; + std::string lower_name = name; + std::string lower_extension = extension; + + std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); + std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); + + return m_sources[lower_extension][lower_name]; } -const unordered_map &KRSourceManager::get(const std::string &extension) +const unordered_map& KRSourceManager::get(const std::string& extension) { - std::string lower_extension = extension; - std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); - return m_sources[lower_extension]; + std::string lower_extension = extension; + std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); + return m_sources[lower_extension]; } diff --git a/kraken/KRSourceManager.h b/kraken/KRSourceManager.h index f1ee532..f3765d1 100644 --- a/kraken/KRSourceManager.h +++ b/kraken/KRSourceManager.h @@ -38,23 +38,24 @@ #include "KRContextObject.h" #include "KRDataBlock.h" -class KRSourceManager : public KRResourceManager { +class KRSourceManager : public KRResourceManager +{ public: - KRSourceManager(KRContext &context); - virtual ~KRSourceManager(); + KRSourceManager(KRContext& context); + virtual ~KRSourceManager(); - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - - void add(KRSource *source); - - KRSource *load(const std::string &name, const std::string &extension, KRDataBlock *data); - KRSource *get(const std::string &name, const std::string &extension); + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; + + void add(KRSource* source); + + KRSource* load(const std::string& name, const std::string& extension, KRDataBlock* data); + KRSource* get(const std::string& name, const std::string& extension); + + const unordered_map& get(const std::string& extension); + + unordered_map >& getSources(); - const unordered_map &get(const std::string &extension); - - unordered_map > &getSources(); - private: - unordered_map > m_sources; + unordered_map > m_sources; }; diff --git a/kraken/KRSpotLight.cpp b/kraken/KRSpotLight.cpp index 0d1abe7..8845a91 100755 --- a/kraken/KRSpotLight.cpp +++ b/kraken/KRSpotLight.cpp @@ -40,7 +40,7 @@ void KRSpotLight::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->light.spot.outer_angle = M_PI_2; } -KRSpotLight::KRSpotLight(KRScene &scene, std::string name) : KRLight(scene, name) +KRSpotLight::KRSpotLight(KRScene& scene, std::string name) : KRLight(scene, name) { m_innerAngle = M_PI_4; m_outerAngle = M_PI_2; @@ -48,47 +48,54 @@ KRSpotLight::KRSpotLight(KRScene &scene, std::string name) : KRLight(scene, name KRSpotLight::~KRSpotLight() { - + } -std::string KRSpotLight::getElementName() { - return "spot_light"; -} - -tinyxml2::XMLElement *KRSpotLight::saveXML( tinyxml2::XMLNode *parent) +std::string KRSpotLight::getElementName() { - tinyxml2::XMLElement *e = KRLight::saveXML(parent); - e->SetAttribute("inner_angle", m_innerAngle); - e->SetAttribute("outer_angle", m_outerAngle); - return e; + return "spot_light"; } -void KRSpotLight::loadXML(tinyxml2::XMLElement *e) { - KRLight::loadXML(e); - - e->QueryFloatAttribute("inner_angle", &m_innerAngle); - e->QueryFloatAttribute("outer_angle", &m_outerAngle); +tinyxml2::XMLElement* KRSpotLight::saveXML(tinyxml2::XMLNode* parent) +{ + tinyxml2::XMLElement* e = KRLight::saveXML(parent); + e->SetAttribute("inner_angle", m_innerAngle); + e->SetAttribute("outer_angle", m_outerAngle); + return e; } -float KRSpotLight::getInnerAngle() { - return m_innerAngle; -} -float KRSpotLight::getOuterAngle() { - return m_outerAngle; -} -void KRSpotLight::setInnerAngle(float innerAngle) { - m_innerAngle = innerAngle; -} -void KRSpotLight::setOuterAngle(float outerAngle) { - m_outerAngle = outerAngle; +void KRSpotLight::loadXML(tinyxml2::XMLElement* e) +{ + KRLight::loadXML(e); + + e->QueryFloatAttribute("inner_angle", &m_innerAngle); + e->QueryFloatAttribute("outer_angle", &m_outerAngle); } -AABB KRSpotLight::getBounds() { - float influence_radius = m_decayStart - sqrt(m_intensity * 0.01f) / sqrt(KRLIGHT_MIN_INFLUENCE); - if(influence_radius < m_flareOcclusionSize) { - influence_radius = m_flareOcclusionSize; - } - return AABB::Create(Vector3::Create(-influence_radius), Vector3::Create(influence_radius), getModelMatrix()); +float KRSpotLight::getInnerAngle() +{ + return m_innerAngle; +} +float KRSpotLight::getOuterAngle() +{ + return m_outerAngle; +} +void KRSpotLight::setInnerAngle(float innerAngle) +{ + m_innerAngle = innerAngle; +} +void KRSpotLight::setOuterAngle(float outerAngle) +{ + m_outerAngle = outerAngle; +} + +AABB KRSpotLight::getBounds() +{ + float influence_radius = m_decayStart - sqrt(m_intensity * 0.01f) / sqrt(KRLIGHT_MIN_INFLUENCE); + if (influence_radius < m_flareOcclusionSize) { + influence_radius = m_flareOcclusionSize; + } + return AABB::Create(Vector3::Create(-influence_radius), Vector3::Create(influence_radius), getModelMatrix()); } diff --git a/kraken/KRSpotLight.h b/kraken/KRSpotLight.h index 54d43c2..7817585 100755 --- a/kraken/KRSpotLight.h +++ b/kraken/KRSpotLight.h @@ -33,24 +33,25 @@ #include "KRLight.h" -class KRSpotLight : public KRLight { +class KRSpotLight : public KRLight +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); + static void InitNodeInfo(KrNodeInfo* nodeInfo); + + KRSpotLight(KRScene& scene, std::string name); + virtual ~KRSpotLight(); + + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + virtual AABB getBounds(); + + float getInnerAngle(); + float getOuterAngle(); + void setInnerAngle(float innerAngle); + void setOuterAngle(float outerAngle); - KRSpotLight(KRScene &scene, std::string name); - virtual ~KRSpotLight(); - - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - virtual AABB getBounds(); - - float getInnerAngle(); - float getOuterAngle(); - void setInnerAngle(float innerAngle); - void setOuterAngle(float outerAngle); - private: - float m_innerAngle; // Inner angle of the cone, in radians. Inside this radius, the light will be at full brightness - float m_outerAngle; // Outer angle of the cone, in radians. Outside this radius, the light will be completely attenuated + float m_innerAngle; // Inner angle of the cone, in radians. Inside this radius, the light will be at full brightness + float m_outerAngle; // Outer angle of the cone, in radians. Outside this radius, the light will be completely attenuated }; diff --git a/kraken/KRSprite.cpp b/kraken/KRSprite.cpp index 4ba49cd..069c50b 100755 --- a/kraken/KRSprite.cpp +++ b/kraken/KRSprite.cpp @@ -51,120 +51,124 @@ void KRSprite::InitNodeInfo(KrNodeInfo* nodeInfo) nodeInfo->sprite.texture = -1; } -KRSprite::KRSprite(KRScene &scene, std::string name) : KRNode(scene, name) +KRSprite::KRSprite(KRScene& scene, std::string name) : KRNode(scene, name) { - m_spriteTexture = ""; - m_pSpriteTexture = NULL; - m_spriteAlpha = 1.0f; + m_spriteTexture = ""; + m_pSpriteTexture = NULL; + m_spriteAlpha = 1.0f; } KRSprite::~KRSprite() +{} + +std::string KRSprite::getElementName() { + return "sprite"; } -std::string KRSprite::getElementName() { - return "sprite"; -} - -tinyxml2::XMLElement *KRSprite::saveXML( tinyxml2::XMLNode *parent) +tinyxml2::XMLElement* KRSprite::saveXML(tinyxml2::XMLNode* parent) { - tinyxml2::XMLElement *e = KRNode::saveXML(parent); - e->SetAttribute("sprite_texture", m_spriteTexture.c_str()); - e->SetAttribute("sprite_alpha", m_spriteAlpha); - return e; + tinyxml2::XMLElement* e = KRNode::saveXML(parent); + e->SetAttribute("sprite_texture", m_spriteTexture.c_str()); + e->SetAttribute("sprite_alpha", m_spriteAlpha); + return e; } -void KRSprite::loadXML(tinyxml2::XMLElement *e) { - KRNode::loadXML(e); +void KRSprite::loadXML(tinyxml2::XMLElement* e) +{ + KRNode::loadXML(e); - if(e->QueryFloatAttribute("sprite_alpha", &m_spriteAlpha) != tinyxml2::XML_SUCCESS) { - m_spriteAlpha = 1.0f; - } - - const char *szSpriteTexture = e->Attribute("sprite_texture"); - if(szSpriteTexture) { - m_spriteTexture = szSpriteTexture; - } else { - m_spriteTexture = ""; - } - m_pSpriteTexture = NULL; + if (e->QueryFloatAttribute("sprite_alpha", &m_spriteAlpha) != tinyxml2::XML_SUCCESS) { + m_spriteAlpha = 1.0f; + } + + const char* szSpriteTexture = e->Attribute("sprite_texture"); + if (szSpriteTexture) { + m_spriteTexture = szSpriteTexture; + } else { + m_spriteTexture = ""; + } + m_pSpriteTexture = NULL; } -void KRSprite::setSpriteTexture(std::string sprite_texture) { - m_spriteTexture = sprite_texture; - m_pSpriteTexture = NULL; +void KRSprite::setSpriteTexture(std::string sprite_texture) +{ + m_spriteTexture = sprite_texture; + m_pSpriteTexture = NULL; } void KRSprite::setSpriteAlpha(float alpha) { - m_spriteAlpha = alpha; + m_spriteAlpha = alpha; } float KRSprite::getSpriteAlpha() const { - return m_spriteAlpha; + return m_spriteAlpha; } -AABB KRSprite::getBounds() { - return AABB::Create(-Vector3::One() * 0.5f, Vector3::One() * 0.5f, getModelMatrix()); +AABB KRSprite::getBounds() +{ + return AABB::Create(-Vector3::One() * 0.5f, Vector3::One() * 0.5f, getModelMatrix()); } -void KRSprite::render(RenderInfo& ri) { - - if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM && ri.renderPass == KRNode::RENDER_PASS_PRESTREAM) { - // Pre-stream sprites, even if the alpha is zero - if(m_spriteTexture.size() && m_pSpriteTexture == NULL) { - if(!m_pSpriteTexture && m_spriteTexture.size()) { - m_pSpriteTexture = getContext().getTextureManager()->getTexture(m_spriteTexture); - } - } - - if(m_pSpriteTexture) { - m_pSpriteTexture->resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_SPRITE); - } +void KRSprite::render(RenderInfo& ri) +{ + + if (m_lod_visible >= LOD_VISIBILITY_PRESTREAM && ri.renderPass == KRNode::RENDER_PASS_PRESTREAM) { + // Pre-stream sprites, even if the alpha is zero + if (m_spriteTexture.size() && m_pSpriteTexture == NULL) { + if (!m_pSpriteTexture && m_spriteTexture.size()) { + m_pSpriteTexture = getContext().getTextureManager()->getTexture(m_spriteTexture); + } } - - if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; - - KRNode::render(ri); - - - if(ri.renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { - if(m_spriteTexture.size() && m_spriteAlpha > 0.0f) { - - if(!m_pSpriteTexture && m_spriteTexture.size()) { - m_pSpriteTexture = getContext().getTextureManager()->getTexture(m_spriteTexture); - } - - if(m_pSpriteTexture) { - // TODO - Sprites are currently additive only. Need to expose this and allow for multiple blending modes - - KRMeshManager::KRVBOData& vertices = m_pContext->getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES; - - // Render light sprite on transparency pass - PipelineInfo info{}; - std::string shader_name("sprite"); - info.shader_name = &shader_name; - info.pCamera = ri.camera; - info.point_lights = &ri.point_lights; - info.directional_lights = &ri.directional_lights; - info.spot_lights = &ri.spot_lights; - info.renderPass = ri.renderPass; - info.rasterMode = RasterMode::kAdditive; - info.cullMode = CullMode::kCullNone; - info.vertexAttributes = vertices.getVertexAttributes(); - info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; - - KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->setUniform(KRPipeline::Uniform::material_alpha, m_spriteAlpha); - pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); - - m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture, 0.0f, KRTexture::TEXTURE_USAGE_SPRITE); - m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &vertices, 1.0f); - vkCmdDraw(ri.commandBuffer, 4, 1, 0, 0); - } - } + if (m_pSpriteTexture) { + m_pSpriteTexture->resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_SPRITE); } + } + + if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + + KRNode::render(ri); + + + if (ri.renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { + if (m_spriteTexture.size() && m_spriteAlpha > 0.0f) { + + + if (!m_pSpriteTexture && m_spriteTexture.size()) { + m_pSpriteTexture = getContext().getTextureManager()->getTexture(m_spriteTexture); + } + + if (m_pSpriteTexture) { + // TODO - Sprites are currently additive only. Need to expose this and allow for multiple blending modes + + KRMeshManager::KRVBOData& vertices = m_pContext->getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES; + + // Render light sprite on transparency pass + PipelineInfo info{}; + std::string shader_name("sprite"); + info.shader_name = &shader_name; + info.pCamera = ri.camera; + info.point_lights = &ri.point_lights; + info.directional_lights = &ri.directional_lights; + info.spot_lights = &ri.spot_lights; + info.renderPass = ri.renderPass; + info.rasterMode = RasterMode::kAdditive; + info.cullMode = CullMode::kCullNone; + info.vertexAttributes = vertices.getVertexAttributes(); + info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP; + + KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); + pShader->setUniform(KRPipeline::Uniform::material_alpha, m_spriteAlpha); + pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass); + + m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture, 0.0f, KRTexture::TEXTURE_USAGE_SPRITE); + m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &vertices, 1.0f); + vkCmdDraw(ri.commandBuffer, 4, 1, 0, 0); + } + } + } } diff --git a/kraken/KRSprite.h b/kraken/KRSprite.h index e002c72..52da3c1 100755 --- a/kraken/KRSprite.h +++ b/kraken/KRSprite.h @@ -35,28 +35,29 @@ #include "KRNode.h" #include "KRTexture.h" -class KRSprite : public KRNode { +class KRSprite : public KRNode +{ public: - static void InitNodeInfo(KrNodeInfo* nodeInfo); + static void InitNodeInfo(KrNodeInfo* nodeInfo); + + KRSprite(KRScene& scene, std::string name); + + virtual ~KRSprite(); + virtual std::string getElementName(); + virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); + virtual void loadXML(tinyxml2::XMLElement* e); + + void setSpriteTexture(std::string sprite_texture); + void setSpriteAlpha(float alpha); + float getSpriteAlpha() const; + + virtual void render(RenderInfo& ri); + + virtual AABB getBounds(); - KRSprite(KRScene &scene, std::string name); - - virtual ~KRSprite(); - virtual std::string getElementName(); - virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); - virtual void loadXML(tinyxml2::XMLElement *e); - - void setSpriteTexture(std::string sprite_texture); - void setSpriteAlpha(float alpha); - float getSpriteAlpha() const; - - virtual void render(RenderInfo& ri); - - virtual AABB getBounds(); - protected: - - std::string m_spriteTexture; - KRTexture *m_pSpriteTexture; - float m_spriteAlpha; + + std::string m_spriteTexture; + KRTexture* m_pSpriteTexture; + float m_spriteAlpha; }; diff --git a/kraken/KRStreamerThread.cpp b/kraken/KRStreamerThread.cpp index 80f2672..f5a93ff 100644 --- a/kraken/KRStreamerThread.cpp +++ b/kraken/KRStreamerThread.cpp @@ -37,19 +37,19 @@ #include -KRStreamerThread::KRStreamerThread(KRContext &context) : m_context(context) +KRStreamerThread::KRStreamerThread(KRContext& context) : m_context(context) { - m_running = false; - m_stop = false; + m_running = false; + m_stop = false; } void KRStreamerThread::start() { - if(!m_running) { - m_running = true; - - m_thread = std::thread(&KRStreamerThread::run, this); - } + if (!m_running) { + m_running = true; + + m_thread = std::thread(&KRStreamerThread::run, this); + } } void KRStreamerThread::stop() @@ -70,18 +70,17 @@ void KRStreamerThread::run() { #if defined(ANDROID) - // TODO - Set thread names on Android + // TODO - Set thread names on Android #elif defined(_WIN32) || defined(_WIN64) - // TODO - Set thread names on windows + // TODO - Set thread names on windows #else - pthread_setname_np("Kraken - Streamer"); + pthread_setname_np("Kraken - Streamer"); #endif - std::chrono::microseconds sleep_duration( 15000 ); + std::chrono::microseconds sleep_duration(15000); - while(!m_stop) - { - m_context.doStreaming(); - std::this_thread::sleep_for( sleep_duration ); - } + while (!m_stop) { + m_context.doStreaming(); + std::this_thread::sleep_for(sleep_duration); + } } diff --git a/kraken/KRStreamerThread.h b/kraken/KRStreamerThread.h index e97e2b6..f59fab0 100755 --- a/kraken/KRStreamerThread.h +++ b/kraken/KRStreamerThread.h @@ -41,18 +41,18 @@ class KRContext; class KRStreamerThread { public: - KRStreamerThread(KRContext &context); - ~KRStreamerThread(); - - void start(); - void stop(); - + KRStreamerThread(KRContext& context); + ~KRStreamerThread(); + + void start(); + void stop(); + private: - KRContext &m_context; - - std::thread m_thread; - std::atomic m_stop; - std::atomic m_running; - - void run(); + KRContext& m_context; + + std::thread m_thread; + std::atomic m_stop; + std::atomic m_running; + + void run(); }; diff --git a/kraken/KRSurface.cpp b/kraken/KRSurface.cpp index 901bb5b..f3aa8db 100644 --- a/kraken/KRSurface.cpp +++ b/kraken/KRSurface.cpp @@ -110,12 +110,12 @@ void KRSurface::destroy() vkDestroySemaphore(device->m_logicalDevice, m_renderFinishedSemaphore, nullptr); m_renderFinishedSemaphore = VK_NULL_HANDLE; } - + if (device && m_imageAvailableSemaphore != VK_NULL_HANDLE) { vkDestroySemaphore(device->m_logicalDevice, m_imageAvailableSemaphore, nullptr); m_imageAvailableSemaphore = VK_NULL_HANDLE; } - + if (m_surface != VK_NULL_HANDLE) { vkDestroySurfaceKHR(m_pContext->getDeviceManager()->getVulkanInstance(), m_surface, nullptr); m_surface = VK_NULL_HANDLE; @@ -124,12 +124,12 @@ void KRSurface::destroy() KrResult KRSurface::createSwapChain() { - + std::unique_ptr& device = m_pContext->getDeviceManager()->getDevice(m_deviceHandle); KrResult res = KR_SUCCESS; VkSurfaceFormatKHR selectedSurfaceFormat{}; - res =device->selectSurfaceFormat(m_surface, selectedSurfaceFormat); + res = device->selectSurfaceFormat(m_surface, selectedSurfaceFormat); if (res != KR_SUCCESS) return res; VkFormat depthImageFormat = VK_FORMAT_UNDEFINED; @@ -161,7 +161,7 @@ KrResult KRSurface::createSwapChain() info.clearDepth = true; info.keepDepth = false; m_forwardOpaquePass->create(*device, selectedSurfaceFormat.format, depthImageFormat, info); - + info.clearDepth = true; info.keepDepth = true; m_deferredGBufferPass->create(*device, selectedSurfaceFormat.format, depthImageFormat, info); diff --git a/kraken/KRSurface.h b/kraken/KRSurface.h index d8838c7..9bff556 100644 --- a/kraken/KRSurface.h +++ b/kraken/KRSurface.h @@ -70,7 +70,7 @@ public: #endif KrDeviceHandle m_deviceHandle; VkSurfaceKHR m_surface; - + VkSemaphore m_imageAvailableSemaphore; VkSemaphore m_renderFinishedSemaphore; diff --git a/kraken/KRSurfaceManager.cpp b/kraken/KRSurfaceManager.cpp index 2d812b4..8ace487 100644 --- a/kraken/KRSurfaceManager.cpp +++ b/kraken/KRSurfaceManager.cpp @@ -35,8 +35,7 @@ KRSurfaceManager::KRSurfaceManager(KRContext& context) : KRContextObject(context) , m_topSurfaceHandle(0) -{ -} +{} KRSurfaceManager::~KRSurfaceManager() { diff --git a/kraken/KRSwapchain.cpp b/kraken/KRSwapchain.cpp index 595e47f..ca36ff8 100644 --- a/kraken/KRSwapchain.cpp +++ b/kraken/KRSwapchain.cpp @@ -85,8 +85,7 @@ KrResult KRSwapchain::create(KRDevice& device, VkSurfaceKHR& surface, VkSurfaceF swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; swapChainCreateInfo.queueFamilyIndexCount = 0; swapChainCreateInfo.pQueueFamilyIndices = nullptr; - } - else { + } else { swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; swapChainCreateInfo.queueFamilyIndexCount = 2; swapChainCreateInfo.pQueueFamilyIndices = queueFamilyIndices; diff --git a/kraken/KRTexture.cpp b/kraken/KRTexture.cpp index 173fd86..180c66f 100755 --- a/kraken/KRTexture.cpp +++ b/kraken/KRTexture.cpp @@ -35,22 +35,22 @@ #include "KRContext.h" #include "KRTextureManager.h" -KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, name) +KRTexture::KRTexture(KRContext& context, std::string name) : KRResource(context, name) { - m_current_lod_max_dim = 0; - m_new_lod_max_dim = 0; - m_textureMemUsed = 0; - m_newTextureMemUsed = 0; - m_last_frame_used = 0; - m_last_frame_max_lod_coverage = 0.0f; - m_last_frame_usage = TEXTURE_USAGE_NONE; - m_handle_lock.clear(); - m_haveNewHandles = false; + m_current_lod_max_dim = 0; + m_new_lod_max_dim = 0; + m_textureMemUsed = 0; + m_newTextureMemUsed = 0; + m_last_frame_used = 0; + m_last_frame_max_lod_coverage = 0.0f; + m_last_frame_usage = TEXTURE_USAGE_NONE; + m_handle_lock.clear(); + m_haveNewHandles = false; } KRTexture::~KRTexture() { - releaseHandles(); + releaseHandles(); } void KRTexture::TextureHandle::destroy(KRDeviceManager* deviceManager) @@ -87,177 +87,188 @@ void KRTexture::destroyNewHandles() m_newTextureMemUsed = 0; } -void KRTexture::releaseHandles() { - long mem_size = getMemSize(); - - while(m_handle_lock.test_and_set()); // Spin lock - - destroyNewHandles(); - destroyHandles(); +void KRTexture::releaseHandles() +{ + long mem_size = getMemSize(); - m_current_lod_max_dim = 0; - m_new_lod_max_dim = 0; - - m_handle_lock.clear(); - - getContext().getTextureManager()->memoryChanged(-mem_size); + while (m_handle_lock.test_and_set()); // Spin lock + + destroyNewHandles(); + destroyHandles(); + + m_current_lod_max_dim = 0; + m_new_lod_max_dim = 0; + + m_handle_lock.clear(); + + getContext().getTextureManager()->memoryChanged(-mem_size); } -long KRTexture::getMemSize() { - return m_textureMemUsed + m_newTextureMemUsed; // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory +long KRTexture::getMemSize() +{ + return m_textureMemUsed + m_newTextureMemUsed; // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory } -long KRTexture::getReferencedMemSize() { - // Return the amount of memory used by other textures referenced by this texture (for cube maps and animated textures) - return 0; +long KRTexture::getReferencedMemSize() +{ + // Return the amount of memory used by other textures referenced by this texture (for cube maps and animated textures) + return 0; } void KRTexture::resize(int max_dim) { - while(m_handle_lock.test_and_set()) {}; // Spin lock + while (m_handle_lock.test_and_set()) { + }; // Spin lock - if(!m_haveNewHandles) { - if(max_dim > 0) { - int target_dim = max_dim; - if(target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim; + if (!m_haveNewHandles) { + if (max_dim > 0) { + int target_dim = max_dim; + if (target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim; - if(m_new_lod_max_dim != target_dim || m_handles.empty()) { - assert(m_newTextureMemUsed == 0); - m_newTextureMemUsed = getMemRequiredForSize(target_dim); - - getContext().getTextureManager()->memoryChanged(m_newTextureMemUsed); - getContext().getTextureManager()->addMemoryTransferredThisFrame(m_newTextureMemUsed); - - if (createGPUTexture(target_dim)) { - m_new_lod_max_dim = target_dim; - } else { - getContext().getTextureManager()->memoryChanged(-m_newTextureMemUsed); - m_newTextureMemUsed = 0; - assert(false); // Failed to create the texture - } - } + if (m_new_lod_max_dim != target_dim || m_handles.empty()) { + assert(m_newTextureMemUsed == 0); + m_newTextureMemUsed = getMemRequiredForSize(target_dim); + + getContext().getTextureManager()->memoryChanged(m_newTextureMemUsed); + getContext().getTextureManager()->addMemoryTransferredThisFrame(m_newTextureMemUsed); + + if (createGPUTexture(target_dim)) { + m_new_lod_max_dim = target_dim; + } else { + getContext().getTextureManager()->memoryChanged(-m_newTextureMemUsed); + m_newTextureMemUsed = 0; + assert(false); // Failed to create the texture } + } } - - m_handle_lock.clear(); + } + + m_handle_lock.clear(); } -GLuint KRTexture::getHandle() { - // assert(false); // TODO - Vulkan refactoring required - resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_NONE); // TODO - Pass through getHandle() arguements to replace extraneous resetPoolExpiry calls? - return 0; +GLuint KRTexture::getHandle() +{ + // assert(false); // TODO - Vulkan refactoring required + resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_NONE); // TODO - Pass through getHandle() arguements to replace extraneous resetPoolExpiry calls? + return 0; } void KRTexture::resetPoolExpiry(float lodCoverage, KRTexture::texture_usage_t textureUsage) { - long current_frame = getContext().getCurrentFrame(); - if(current_frame != m_last_frame_used) { - m_last_frame_used = current_frame; - m_last_frame_max_lod_coverage = 0.0f; - m_last_frame_usage = TEXTURE_USAGE_NONE; - - getContext().getTextureManager()->primeTexture(this); - } - m_last_frame_max_lod_coverage = KRMAX(lodCoverage, m_last_frame_max_lod_coverage); - m_last_frame_usage = static_cast(static_cast(m_last_frame_usage) | static_cast(textureUsage)); + long current_frame = getContext().getCurrentFrame(); + if (current_frame != m_last_frame_used) { + m_last_frame_used = current_frame; + m_last_frame_max_lod_coverage = 0.0f; + m_last_frame_usage = TEXTURE_USAGE_NONE; + + getContext().getTextureManager()->primeTexture(this); + } + m_last_frame_max_lod_coverage = KRMAX(lodCoverage, m_last_frame_max_lod_coverage); + m_last_frame_usage = static_cast(static_cast(m_last_frame_usage) | static_cast(textureUsage)); } kraken_stream_level KRTexture::getStreamLevel(KRTexture::texture_usage_t textureUsage) { - if(m_current_lod_max_dim == 0) { - return kraken_stream_level::STREAM_LEVEL_OUT; - } else if(m_current_lod_max_dim == KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, (int)m_max_lod_max_dim)) { - return kraken_stream_level::STREAM_LEVEL_IN_HQ; - } else if(m_current_lod_max_dim >= KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, (int)m_min_lod_max_dim)) { - return kraken_stream_level::STREAM_LEVEL_IN_LQ; - } else { - return kraken_stream_level::STREAM_LEVEL_OUT; - } + if (m_current_lod_max_dim == 0) { + return kraken_stream_level::STREAM_LEVEL_OUT; + } else if (m_current_lod_max_dim == KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, (int)m_max_lod_max_dim)) { + return kraken_stream_level::STREAM_LEVEL_IN_HQ; + } else if (m_current_lod_max_dim >= KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, (int)m_min_lod_max_dim)) { + return kraken_stream_level::STREAM_LEVEL_IN_LQ; + } else { + return kraken_stream_level::STREAM_LEVEL_OUT; + } } float KRTexture::getStreamPriority() { - long current_frame = getContext().getCurrentFrame(); - if(current_frame > m_last_frame_used + 5) { - return 1.0f - KRCLAMP((float)(current_frame - m_last_frame_used) / 60.0f, 0.0f, 1.0f); - } else { - float priority = 100.0f; - if(m_last_frame_usage & (TEXTURE_USAGE_UI | TEXTURE_USAGE_SHADOW_DEPTH)) { - priority += 10000000.0f; - } - if(m_last_frame_usage & (TEXTURE_USAGE_SKY_CUBE | TEXTURE_USAGE_PARTICLE | TEXTURE_USAGE_SPRITE | TEXTURE_USAGE_LIGHT_FLARE)) { - priority += 1000000.0f; - } - if(m_last_frame_usage & (TEXTURE_USAGE_DIFFUSE_MAP | TEXTURE_USAGE_AMBIENT_MAP | TEXTURE_USAGE_SPECULAR_MAP | TEXTURE_USAGE_NORMAL_MAP | TEXTURE_USAGE_REFLECTION_MAP)) { - priority += 100000.0f; - } - if(m_last_frame_usage & (TEXTURE_USAGE_LIGHT_MAP)) { - priority += 100000.0f; - } - if(m_last_frame_usage & (TEXTURE_USAGE_REFECTION_CUBE)) { - priority += 100000.0f; - } - priority += m_last_frame_max_lod_coverage * 10.0f; - return priority; + long current_frame = getContext().getCurrentFrame(); + if (current_frame > m_last_frame_used + 5) { + return 1.0f - KRCLAMP((float)(current_frame - m_last_frame_used) / 60.0f, 0.0f, 1.0f); + } else { + float priority = 100.0f; + if (m_last_frame_usage & (TEXTURE_USAGE_UI | TEXTURE_USAGE_SHADOW_DEPTH)) { + priority += 10000000.0f; } + if (m_last_frame_usage & (TEXTURE_USAGE_SKY_CUBE | TEXTURE_USAGE_PARTICLE | TEXTURE_USAGE_SPRITE | TEXTURE_USAGE_LIGHT_FLARE)) { + priority += 1000000.0f; + } + if (m_last_frame_usage & (TEXTURE_USAGE_DIFFUSE_MAP | TEXTURE_USAGE_AMBIENT_MAP | TEXTURE_USAGE_SPECULAR_MAP | TEXTURE_USAGE_NORMAL_MAP | TEXTURE_USAGE_REFLECTION_MAP)) { + priority += 100000.0f; + } + if (m_last_frame_usage & (TEXTURE_USAGE_LIGHT_MAP)) { + priority += 100000.0f; + } + if (m_last_frame_usage & (TEXTURE_USAGE_REFECTION_CUBE)) { + priority += 100000.0f; + } + priority += m_last_frame_max_lod_coverage * 10.0f; + return priority; + } } float KRTexture::getLastFrameLodCoverage() const { - return m_last_frame_max_lod_coverage; + return m_last_frame_max_lod_coverage; } long KRTexture::getLastFrameUsed() { - return m_last_frame_used; + return m_last_frame_used; } bool KRTexture::isAnimated() { - return false; + return false; } -KRTexture *KRTexture::compress(bool premultiply_alpha) +KRTexture* KRTexture::compress(bool premultiply_alpha) { - return NULL; + return NULL; } -int KRTexture::getCurrentLodMaxDim() { - return m_current_lod_max_dim; +int KRTexture::getCurrentLodMaxDim() +{ + return m_current_lod_max_dim; } -int KRTexture::getNewLodMaxDim() { - return m_new_lod_max_dim; +int KRTexture::getNewLodMaxDim() +{ + return m_new_lod_max_dim; } -int KRTexture::getMaxMipMap() { - return m_max_lod_max_dim; +int KRTexture::getMaxMipMap() +{ + return m_max_lod_max_dim; } -int KRTexture::getMinMipMap() { - return m_min_lod_max_dim; +int KRTexture::getMinMipMap() +{ + return m_min_lod_max_dim; } -bool KRTexture::hasMipmaps() { - return m_max_lod_max_dim != m_min_lod_max_dim; +bool KRTexture::hasMipmaps() +{ + return m_max_lod_max_dim != m_min_lod_max_dim; } -void KRTexture::bind(GLuint texture_unit) { - +void KRTexture::bind(GLuint texture_unit) +{ + } void KRTexture::_swapHandles() { - //while(m_handle_lock.test_and_set()); // Spin lock - if(!m_handle_lock.test_and_set()) { - if(m_haveNewHandles) { - destroyHandles(); - m_handles.swap(m_newHandles); - m_textureMemUsed = (long)m_newTextureMemUsed; - m_newTextureMemUsed = 0; - m_current_lod_max_dim = m_new_lod_max_dim; - m_haveNewHandles = false; - } - m_handle_lock.clear(); + //while(m_handle_lock.test_and_set()); // Spin lock + if (!m_handle_lock.test_and_set()) { + if (m_haveNewHandles) { + destroyHandles(); + m_handles.swap(m_newHandles); + m_textureMemUsed = (long)m_newTextureMemUsed; + m_newTextureMemUsed = 0; + m_current_lod_max_dim = m_new_lod_max_dim; + m_haveNewHandles = false; } + m_handle_lock.clear(); + } } diff --git a/kraken/KRTexture.h b/kraken/KRTexture.h index b80c32b..b936d5f 100755 --- a/kraken/KRTexture.h +++ b/kraken/KRTexture.h @@ -39,87 +39,90 @@ class KRDataBlock; class KRCamera; class KRDeviceManager; -class KRTexture : public KRResource { +class KRTexture : public KRResource +{ public: - KRTexture(KRContext &context, std::string name); - virtual ~KRTexture(); + KRTexture(KRContext& context, std::string name); + virtual ~KRTexture(); - virtual void bind(GLuint texture_unit); - void releaseHandles(); - long getMemSize(); - virtual long getReferencedMemSize(); - - virtual long getMemRequiredForSize(int max_dim) = 0; - virtual void resize(int max_dim); - - long getLastFrameUsed(); - - typedef enum { - TEXTURE_USAGE_NONE = 0x00, - TEXTURE_USAGE_UI = 0x01, - TEXTURE_USAGE_SKY_CUBE = 0x02, - TEXTURE_USAGE_LIGHT_MAP = 0x04, - TEXTURE_USAGE_DIFFUSE_MAP = 0x08, - TEXTURE_USAGE_AMBIENT_MAP = 0x10, - TEXTURE_USAGE_SPECULAR_MAP = 0x20, - TEXTURE_USAGE_NORMAL_MAP = 0x40, - TEXTURE_USAGE_REFLECTION_MAP = 0x80, - TEXTURE_USAGE_REFECTION_CUBE = 0x100, - TEXTURE_USAGE_LIGHT_FLARE = 0x200, - TEXTURE_USAGE_SHADOW_DEPTH = 0x400, - TEXTURE_USAGE_PARTICLE = 0x800, - TEXTURE_USAGE_SPRITE = 0x1000 - } texture_usage_t; - - float getStreamPriority(); - - virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); - virtual bool isAnimated(); - - virtual KRTexture *compress(bool premultiply_alpha = false); - int getCurrentLodMaxDim(); - int getNewLodMaxDim(); // For use by streamer only - int getMaxMipMap(); - int getMinMipMap(); - bool hasMipmaps(); + virtual void bind(GLuint texture_unit); + void releaseHandles(); + long getMemSize(); + virtual long getReferencedMemSize(); + + virtual long getMemRequiredForSize(int max_dim) = 0; + virtual void resize(int max_dim); + + long getLastFrameUsed(); + + typedef enum + { + TEXTURE_USAGE_NONE = 0x00, + TEXTURE_USAGE_UI = 0x01, + TEXTURE_USAGE_SKY_CUBE = 0x02, + TEXTURE_USAGE_LIGHT_MAP = 0x04, + TEXTURE_USAGE_DIFFUSE_MAP = 0x08, + TEXTURE_USAGE_AMBIENT_MAP = 0x10, + TEXTURE_USAGE_SPECULAR_MAP = 0x20, + TEXTURE_USAGE_NORMAL_MAP = 0x40, + TEXTURE_USAGE_REFLECTION_MAP = 0x80, + TEXTURE_USAGE_REFECTION_CUBE = 0x100, + TEXTURE_USAGE_LIGHT_FLARE = 0x200, + TEXTURE_USAGE_SHADOW_DEPTH = 0x400, + TEXTURE_USAGE_PARTICLE = 0x800, + TEXTURE_USAGE_SPRITE = 0x1000 + } texture_usage_t; + + float getStreamPriority(); + + virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); + virtual bool isAnimated(); + + virtual KRTexture* compress(bool premultiply_alpha = false); + int getCurrentLodMaxDim(); + int getNewLodMaxDim(); // For use by streamer only + int getMaxMipMap(); + int getMinMipMap(); + bool hasMipmaps(); + + kraken_stream_level getStreamLevel(KRTexture::texture_usage_t textureUsage); + float getLastFrameLodCoverage() const; + + void _swapHandles(); - kraken_stream_level getStreamLevel(KRTexture::texture_usage_t textureUsage); - float getLastFrameLodCoverage() const; - - void _swapHandles(); - protected: - virtual bool createGPUTexture(int lod_max_dim) = 0; - GLuint getHandle(); - void destroyHandles(); - void destroyNewHandles(); - - struct TextureHandle { - VkImage image; - VkImageView fullImageView; - KrDeviceHandle device; - VmaAllocation allocation; + virtual bool createGPUTexture(int lod_max_dim) = 0; + GLuint getHandle(); + void destroyHandles(); + void destroyNewHandles(); - void destroy(KRDeviceManager* deviceManager); - }; + struct TextureHandle + { + VkImage image; + VkImageView fullImageView; + KrDeviceHandle device; + VmaAllocation allocation; - std::vector m_handles; - std::vector m_newHandles; - std::atomic_bool m_haveNewHandles; + void destroy(KRDeviceManager* deviceManager); + }; + + std::vector m_handles; + std::vector m_newHandles; + std::atomic_bool m_haveNewHandles; + + std::atomic_flag m_handle_lock; + + int m_current_lod_max_dim; + int m_new_lod_max_dim; + + uint32_t m_max_lod_max_dim; + uint32_t m_min_lod_max_dim; + + long m_last_frame_used; + float m_last_frame_max_lod_coverage; + texture_usage_t m_last_frame_usage; - std::atomic_flag m_handle_lock; - - int m_current_lod_max_dim; - int m_new_lod_max_dim; - - uint32_t m_max_lod_max_dim; - uint32_t m_min_lod_max_dim; - - long m_last_frame_used; - float m_last_frame_max_lod_coverage; - texture_usage_t m_last_frame_usage; - private: - std::atomic m_textureMemUsed; - std::atomic m_newTextureMemUsed; + std::atomic m_textureMemUsed; + std::atomic m_newTextureMemUsed; }; diff --git a/kraken/KRTexture2D.cpp b/kraken/KRTexture2D.cpp index 53797d2..8be5a77 100755 --- a/kraken/KRTexture2D.cpp +++ b/kraken/KRTexture2D.cpp @@ -33,102 +33,107 @@ #include "KRTexture2D.h" #include "KRTextureManager.h" -KRTexture2D::KRTexture2D(KRContext &context, KRDataBlock *data, std::string name) : KRTexture(context, name) { - m_pData = data; -} - -KRTexture2D::~KRTexture2D() { - delete m_pData; +KRTexture2D::KRTexture2D(KRContext& context, KRDataBlock* data, std::string name) : KRTexture(context, name) +{ + m_pData = data; } -bool KRTexture2D::createGPUTexture(int lod_max_dim) { - if (m_haveNewHandles) { - return true; - } - - bool success = true; - int prev_lod_max_dim = m_new_lod_max_dim; - m_new_lod_max_dim = 0; +KRTexture2D::~KRTexture2D() +{ + delete m_pData; +} - KRDeviceManager* deviceManager = getContext().getDeviceManager(); +bool KRTexture2D::createGPUTexture(int lod_max_dim) +{ + if (m_haveNewHandles) { + return true; + } - for (auto deviceItr = deviceManager->getDevices().begin(); deviceItr != deviceManager->getDevices().end(); deviceItr++) { - KRDevice& device = *(*deviceItr).second; - KrDeviceHandle deviceHandle = (*deviceItr).first; - VmaAllocator allocator = device.getAllocator(); - KRTexture::TextureHandle& texture = m_newHandles.emplace_back(); - texture.device = deviceHandle; - texture.allocation = VK_NULL_HANDLE; - texture.image = VK_NULL_HANDLE; + bool success = true; + int prev_lod_max_dim = m_new_lod_max_dim; + m_new_lod_max_dim = 0; - if (!device.createImage(getDimensions(), 0, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &texture.image, &texture.allocation + KRDeviceManager* deviceManager = getContext().getDeviceManager(); + + for (auto deviceItr = deviceManager->getDevices().begin(); deviceItr != deviceManager->getDevices().end(); deviceItr++) { + KRDevice& device = *(*deviceItr).second; + KrDeviceHandle deviceHandle = (*deviceItr).first; + VmaAllocator allocator = device.getAllocator(); + KRTexture::TextureHandle& texture = m_newHandles.emplace_back(); + texture.device = deviceHandle; + texture.allocation = VK_NULL_HANDLE; + texture.image = VK_NULL_HANDLE; + + if (!device.createImage(getDimensions(), 0, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &texture.image, &texture.allocation #if KRENGINE_DEBUG_GPU_LABELS , getName().c_str() #endif )) { - success = false; - break; - } - - VkImageViewCreateInfo viewInfo{}; - viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewInfo.image = texture.image; - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewInfo.format = VK_FORMAT_R8G8B8A8_SRGB; - viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - viewInfo.subresourceRange.baseMipLevel = 0; - viewInfo.subresourceRange.levelCount = 1; - viewInfo.subresourceRange.baseArrayLayer = 0; - viewInfo.subresourceRange.layerCount = 1; - VkResult res = vkCreateImageView(device.m_logicalDevice, &viewInfo, nullptr, &texture.fullImageView); - if(res != VK_SUCCESS) { - success = false; - break; - } - - if (!uploadTexture(device, texture.image, lod_max_dim, m_new_lod_max_dim)) { - success = false; - break; - } + success = false; + break; } - if (success) { - m_new_lod_max_dim = prev_lod_max_dim; - m_haveNewHandles = true; - } else { - destroyNewHandles(); + VkImageViewCreateInfo viewInfo{}; + viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + viewInfo.image = texture.image; + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.format = VK_FORMAT_R8G8B8A8_SRGB; + viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + viewInfo.subresourceRange.baseMipLevel = 0; + viewInfo.subresourceRange.levelCount = 1; + viewInfo.subresourceRange.baseArrayLayer = 0; + viewInfo.subresourceRange.layerCount = 1; + VkResult res = vkCreateImageView(device.m_logicalDevice, &viewInfo, nullptr, &texture.fullImageView); + if (res != VK_SUCCESS) { + success = false; + break; } - - return success; + + if (!uploadTexture(device, texture.image, lod_max_dim, m_new_lod_max_dim)) { + success = false; + break; + } + } + + if (success) { + m_new_lod_max_dim = prev_lod_max_dim; + m_haveNewHandles = true; + } else { + destroyNewHandles(); + } + + return success; } -void KRTexture2D::bind(GLuint texture_unit) { - KRTexture::bind(texture_unit); - GLuint handle = getHandle(); - - if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, texture_unit, handle)) { - if(handle) { - // TODO - These texture parameters should be assigned by the material or texture parameters - m_pContext->getTextureManager()->_setWrapModeS(texture_unit, GL_REPEAT); - m_pContext->getTextureManager()->_setWrapModeT(texture_unit, GL_REPEAT); - } +void KRTexture2D::bind(GLuint texture_unit) +{ + KRTexture::bind(texture_unit); + GLuint handle = getHandle(); + + if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, texture_unit, handle)) { + if (handle) { + // TODO - These texture parameters should be assigned by the material or texture parameters + m_pContext->getTextureManager()->_setWrapModeS(texture_unit, GL_REPEAT); + m_pContext->getTextureManager()->_setWrapModeT(texture_unit, GL_REPEAT); } + } } bool KRTexture2D::save(const std::string& path) { - if(m_pData) { - return m_pData->save(path); - } else { - return false; - } + if (m_pData) { + return m_pData->save(path); + } else { + return false; + } } -bool KRTexture2D::save(KRDataBlock &data) { - if(m_pData) { - data.append(*m_pData); - return true; - } else { - return false; - } +bool KRTexture2D::save(KRDataBlock& data) +{ + if (m_pData) { + data.append(*m_pData); + return true; + } else { + return false; + } } diff --git a/kraken/KRTexture2D.h b/kraken/KRTexture2D.h index a57aec5..2779ee9 100755 --- a/kraken/KRTexture2D.h +++ b/kraken/KRTexture2D.h @@ -40,19 +40,20 @@ using std::list; class KRDevice; -class KRTexture2D : public KRTexture { +class KRTexture2D : public KRTexture +{ public: - KRTexture2D(KRContext &context, KRDataBlock *data, std::string name); - virtual ~KRTexture2D(); - virtual bool save(const std::string& path); - virtual bool save(KRDataBlock &data); - - virtual bool uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int ¤t_lod_max_dim, bool compress = false, bool premultiply_alpha = false) = 0; - virtual void bind(GLuint texture_unit); - virtual Vector2i getDimensions() const = 0; - + KRTexture2D(KRContext& context, KRDataBlock* data, std::string name); + virtual ~KRTexture2D(); + virtual bool save(const std::string& path); + virtual bool save(KRDataBlock& data); + + virtual bool uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int& current_lod_max_dim, bool compress = false, bool premultiply_alpha = false) = 0; + virtual void bind(GLuint texture_unit); + virtual Vector2i getDimensions() const = 0; + protected: - KRDataBlock *m_pData; - - bool createGPUTexture(int lod_max_dim) override; + KRDataBlock* m_pData; + + bool createGPUTexture(int lod_max_dim) override; }; diff --git a/kraken/KRTextureAnimated.cpp b/kraken/KRTextureAnimated.cpp index b5b132c..ae2ab74 100755 --- a/kraken/KRTextureAnimated.cpp +++ b/kraken/KRTextureAnimated.cpp @@ -34,45 +34,45 @@ #include "KRTexture2D.h" #include "KRContext.h" -KRTextureAnimated::KRTextureAnimated(KRContext &context, std::string name) : KRTexture(context, name) +KRTextureAnimated::KRTextureAnimated(KRContext& context, std::string name) : KRTexture(context, name) { - // Format of name: - // animate:texturebasename,xx,yy - // Where - texturebasename is a prefix for the other textures - // - xx is the number of frames - // - yy is the framerate - - // TODO - Add error handling for mal-formatted animated texture formats - size_t first_comma_pos = name.find(","); - size_t second_comma_pos = name.find(",", first_comma_pos + 1); - - - m_texture_base_name = name.substr(8, first_comma_pos - 8); - m_frame_count = atoi(name.substr(first_comma_pos+1, second_comma_pos - first_comma_pos -1).c_str()); - m_frame_rate = (float)atof(name.substr(second_comma_pos+1).c_str()); - - m_max_lod_max_dim = 2048; - m_min_lod_max_dim = 64; - - for(int i=0; igetMaxMipMap() < (int)m_max_lod_max_dim) m_max_lod_max_dim = frame_texture->getMaxMipMap(); - if(frame_texture->getMinMipMap() > (int)m_min_lod_max_dim) m_min_lod_max_dim = frame_texture->getMinMipMap(); - } + // Format of name: + // animate:texturebasename,xx,yy + // Where - texturebasename is a prefix for the other textures + // - xx is the number of frames + // - yy is the framerate + + // TODO - Add error handling for mal-formatted animated texture formats + size_t first_comma_pos = name.find(","); + size_t second_comma_pos = name.find(",", first_comma_pos + 1); + + + m_texture_base_name = name.substr(8, first_comma_pos - 8); + m_frame_count = atoi(name.substr(first_comma_pos + 1, second_comma_pos - first_comma_pos - 1).c_str()); + m_frame_rate = (float)atof(name.substr(second_comma_pos + 1).c_str()); + + m_max_lod_max_dim = 2048; + m_min_lod_max_dim = 64; + + for (int i = 0; i < m_frame_count; i++) { + KRTexture2D* frame_texture = textureForFrame(i); + if (frame_texture) { + if (frame_texture->getMaxMipMap() < (int)m_max_lod_max_dim) m_max_lod_max_dim = frame_texture->getMaxMipMap(); + if (frame_texture->getMinMipMap() > (int)m_min_lod_max_dim) m_min_lod_max_dim = frame_texture->getMinMipMap(); } + } } std::string KRTextureAnimated::textureNameForFrame(int frame) { - char szFrameNumber[10]; - sprintf(szFrameNumber, "%i", frame); - return m_texture_base_name + szFrameNumber; + char szFrameNumber[10]; + sprintf(szFrameNumber, "%i", frame); + return m_texture_base_name + szFrameNumber; } -KRTexture2D *KRTextureAnimated::textureForFrame(int frame) +KRTexture2D* KRTextureAnimated::textureForFrame(int frame) { - return (KRTexture2D *)getContext().getTextureManager()->getTexture(textureNameForFrame(frame)); + return (KRTexture2D*)getContext().getTextureManager()->getTexture(textureNameForFrame(frame)); } KRTextureAnimated::~KRTextureAnimated() @@ -82,70 +82,70 @@ KRTextureAnimated::~KRTextureAnimated() bool KRTextureAnimated::createGPUTexture(int lod_max_dim) { - return true; + return true; } long KRTextureAnimated::getMemRequiredForSize(int max_dim) { - return 0; // Memory is allocated by individual frame textures + return 0; // Memory is allocated by individual frame textures } void KRTextureAnimated::resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage) { - KRTexture::resetPoolExpiry(lodCoverage, textureUsage); - for(int i=0; iresetPoolExpiry(lodCoverage, textureUsage); // Ensure that frames of animated textures do not expire from the texture pool prematurely, as they are referenced indirectly - } + KRTexture::resetPoolExpiry(lodCoverage, textureUsage); + for (int i = 0; i < m_frame_count; i++) { + KRTexture2D* frame_texture = textureForFrame(i); + if (frame_texture) { + frame_texture->resetPoolExpiry(lodCoverage, textureUsage); // Ensure that frames of animated textures do not expire from the texture pool prematurely, as they are referenced indirectly } + } } void KRTextureAnimated::bind(GLuint texture_unit) { - resetPoolExpiry(0.0f, TEXTURE_USAGE_NONE); // TODO - Need to set parameters here for streaming priority? - KRTexture::bind(texture_unit); - int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate, (float)m_frame_count)); - KRTexture2D *frame_texture = textureForFrame(frame_number); - if(frame_texture) { - frame_texture->bind(texture_unit); - } + resetPoolExpiry(0.0f, TEXTURE_USAGE_NONE); // TODO - Need to set parameters here for streaming priority? + KRTexture::bind(texture_unit); + int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate, (float)m_frame_count)); + KRTexture2D* frame_texture = textureForFrame(frame_number); + if (frame_texture) { + frame_texture->bind(texture_unit); + } } long KRTextureAnimated::getReferencedMemSize() { - long referenced_mem = 0; - for(int i=0; igetMemSize(); - } + long referenced_mem = 0; + for (int i = 0; i < m_frame_count; i++) { + KRTexture2D* frame_texture = textureForFrame(i); + if (frame_texture) { + referenced_mem += frame_texture->getMemSize(); } - return referenced_mem; + } + return referenced_mem; } bool KRTextureAnimated::isAnimated() { - return true; + return true; } std::string KRTextureAnimated::getExtension() { - return ""; // Animated textures are just references; there are no files to output + return ""; // Animated textures are just references; there are no files to output } -bool KRTextureAnimated::save(const std::string &path) +bool KRTextureAnimated::save(const std::string& path) { - return true; // Animated textures are just references; there are no files to output + return true; // Animated textures are just references; there are no files to output } -bool KRTextureAnimated::save(KRDataBlock &data) +bool KRTextureAnimated::save(KRDataBlock& data) { - return true; // Animated textures are just references; there are no files to output + return true; // Animated textures are just references; there are no files to output } void KRTextureAnimated::resize(int max_dim) { - // Purposely not calling the superclass method + // Purposely not calling the superclass method } \ No newline at end of file diff --git a/kraken/KRTextureAnimated.h b/kraken/KRTextureAnimated.h index aa3f3a7..7a68db5 100755 --- a/kraken/KRTextureAnimated.h +++ b/kraken/KRTextureAnimated.h @@ -34,30 +34,31 @@ #include "KRTexture.h" #include "KRTexture2D.h" -class KRTextureAnimated : public KRTexture { +class KRTextureAnimated : public KRTexture +{ public: - KRTextureAnimated(KRContext &context, std::string name); - virtual ~KRTextureAnimated(); - virtual std::string getExtension(); - virtual bool save(const std::string& path); - virtual bool save(KRDataBlock &data); - - virtual void bind(GLuint texture_unit); - virtual long getMemRequiredForSize(int max_dim); - virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); - - virtual long getReferencedMemSize(); - - virtual bool isAnimated(); - virtual void resize(int max_dim); - + KRTextureAnimated(KRContext& context, std::string name); + virtual ~KRTextureAnimated(); + virtual std::string getExtension(); + virtual bool save(const std::string& path); + virtual bool save(KRDataBlock& data); + + virtual void bind(GLuint texture_unit); + virtual long getMemRequiredForSize(int max_dim); + virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); + + virtual long getReferencedMemSize(); + + virtual bool isAnimated(); + virtual void resize(int max_dim); + private: - bool createGPUTexture(int lod_max_dim) override; - - float m_frame_rate; - int m_frame_count; - - std::string m_texture_base_name; - std::string textureNameForFrame(int frame); - KRTexture2D *textureForFrame(int frame); + bool createGPUTexture(int lod_max_dim) override; + + float m_frame_rate; + int m_frame_count; + + std::string m_texture_base_name; + std::string textureNameForFrame(int frame); + KRTexture2D* textureForFrame(int frame); }; diff --git a/kraken/KRTextureCube.cpp b/kraken/KRTextureCube.cpp index 9ee59df..f67418c 100755 --- a/kraken/KRTextureCube.cpp +++ b/kraken/KRTextureCube.cpp @@ -33,116 +33,115 @@ #include "KRTexture2D.h" #include "KRContext.h" -KRTextureCube::KRTextureCube(KRContext &context, std::string name) : KRTexture(context, name) +KRTextureCube::KRTextureCube(KRContext& context, std::string name) : KRTexture(context, name) { - - m_max_lod_max_dim = 2048; - m_min_lod_max_dim = 64; - - for(int i=0; i<6; i++) { - m_textures[i] = NULL; - std::string faceName = getName() + SUFFIXES[i]; - m_textures[i] = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); - if(m_textures[i]) { - if(m_textures[i]->getMaxMipMap() < (int)m_max_lod_max_dim) m_max_lod_max_dim = m_textures[i]->getMaxMipMap(); - if(m_textures[i]->getMinMipMap() > (int)m_min_lod_max_dim) m_min_lod_max_dim = m_textures[i]->getMinMipMap(); - } else { - assert(false); - } + + m_max_lod_max_dim = 2048; + m_min_lod_max_dim = 64; + + for (int i = 0; i < 6; i++) { + m_textures[i] = NULL; + std::string faceName = getName() + SUFFIXES[i]; + m_textures[i] = (KRTexture2D*)getContext().getTextureManager()->getTexture(faceName); + if (m_textures[i]) { + if (m_textures[i]->getMaxMipMap() < (int)m_max_lod_max_dim) m_max_lod_max_dim = m_textures[i]->getMaxMipMap(); + if (m_textures[i]->getMinMipMap() > (int)m_min_lod_max_dim) m_min_lod_max_dim = m_textures[i]->getMinMipMap(); + } else { + assert(false); } + } } KRTextureCube::~KRTextureCube() -{ -} +{} bool KRTextureCube::createGPUTexture(int lod_max_dim) { - assert(!m_haveNewHandles); // Only allow one resize per frame - - bool success = true; + assert(!m_haveNewHandles); // Only allow one resize per frame - int prev_lod_max_dim = m_new_lod_max_dim; - m_new_lod_max_dim = 0; - bool bMipMaps = false; + bool success = true; - Vector2i dimensions = Vector2i::Zero(); + int prev_lod_max_dim = m_new_lod_max_dim; + m_new_lod_max_dim = 0; + bool bMipMaps = false; - for (int i = 0; i < 6; i++) { - if (!m_textures[i]) { + Vector2i dimensions = Vector2i::Zero(); + + for (int i = 0; i < 6; i++) { + if (!m_textures[i]) { + success = false; + } else { + KRTexture2D& tex = *m_textures[i]; + Vector2i texDimensions = tex.getDimensions(); + if (dimensions.x == 0) { + dimensions = texDimensions; + } else if (dimensions != texDimensions) { success = false; - } else { - KRTexture2D& tex = *m_textures[i]; - Vector2i texDimensions = tex.getDimensions(); - if (dimensions.x == 0) { - dimensions = texDimensions; - } else if (dimensions != texDimensions) { - success = false; - } - if (tex.hasMipmaps()) { - bMipMaps = true; - } + } + if (tex.hasMipmaps()) { + bMipMaps = true; } } - if (!success) { - // Not all face images were loaded, or they have - // mismatched dimensions - // TODO - Perhaps we should have multiple error result codes. - return false; - } - - KRDeviceManager* deviceManager = getContext().getDeviceManager(); + } + if (!success) { + // Not all face images were loaded, or they have + // mismatched dimensions + // TODO - Perhaps we should have multiple error result codes. + return false; + } - for (auto deviceItr = deviceManager->getDevices().begin(); deviceItr != deviceManager->getDevices().end(); deviceItr++) { - KRDevice& device = *(*deviceItr).second; - KrDeviceHandle deviceHandle = (*deviceItr).first; - VmaAllocator allocator = device.getAllocator(); - KRTexture::TextureHandle& texture = m_newHandles.emplace_back(); - texture.device = deviceHandle; - texture.allocation = VK_NULL_HANDLE; - texture.image = VK_NULL_HANDLE; + KRDeviceManager* deviceManager = getContext().getDeviceManager(); - if (!device.createImage(dimensions, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &texture.image, &texture.allocation + for (auto deviceItr = deviceManager->getDevices().begin(); deviceItr != deviceManager->getDevices().end(); deviceItr++) { + KRDevice& device = *(*deviceItr).second; + KrDeviceHandle deviceHandle = (*deviceItr).first; + VmaAllocator allocator = device.getAllocator(); + KRTexture::TextureHandle& texture = m_newHandles.emplace_back(); + texture.device = deviceHandle; + texture.allocation = VK_NULL_HANDLE; + texture.image = VK_NULL_HANDLE; + + if (!device.createImage(dimensions, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &texture.image, &texture.allocation #if KRENGINE_DEBUG_GPU_LABELS - , getName().c_str() + , getName().c_str() #endif )) { - success = false; - break; - } - - for (int i = 0; i < 6; i++) { - std::string faceName = getName() + SUFFIXES[i]; - if (m_textures[i]) { - /* TODO - Vulkan refactoring... - incorporate TARGETS[i], - */ - m_textures[i]->uploadTexture(device, texture.image, lod_max_dim, m_new_lod_max_dim); - } - } - } - if (success) { - m_haveNewHandles = true; - } else { - destroyHandles(); - m_new_lod_max_dim = prev_lod_max_dim; + success = false; + break; } - return success; + for (int i = 0; i < 6; i++) { + std::string faceName = getName() + SUFFIXES[i]; + if (m_textures[i]) { + /* TODO - Vulkan refactoring... + incorporate TARGETS[i], + */ + m_textures[i]->uploadTexture(device, texture.image, lod_max_dim, m_new_lod_max_dim); + } + } + } + if (success) { + m_haveNewHandles = true; + } else { + destroyHandles(); + m_new_lod_max_dim = prev_lod_max_dim; + } + + return success; } long KRTextureCube::getMemRequiredForSize(int max_dim) { - int target_dim = max_dim; - if(target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim; - - long memoryRequired = 0; - for(int i=0; i<6; i++) { - if(m_textures[i]) { - memoryRequired += m_textures[i]->getMemRequiredForSize(target_dim); - } + int target_dim = max_dim; + if (target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim; + + long memoryRequired = 0; + for (int i = 0; i < 6; i++) { + if (m_textures[i]) { + memoryRequired += m_textures[i]->getMemRequiredForSize(target_dim); } - return memoryRequired; + } + return memoryRequired; } /* @@ -159,27 +158,27 @@ void KRTextureCube::resetPoolExpiry(float lodCoverage, texture_usage_t textureUs void KRTextureCube::bind(GLuint texture_unit) { - KRTexture::bind(texture_unit); - GLuint handle = getHandle(); - if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_CUBE_MAP, texture_unit, handle)) { - if(handle) { - GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - } + KRTexture::bind(texture_unit); + GLuint handle = getHandle(); + if (m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_CUBE_MAP, texture_unit, handle)) { + if (handle) { + GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); } + } } std::string KRTextureCube::getExtension() { - return ""; // Cube maps are just references; there are no files to output + return ""; // Cube maps are just references; there are no files to output } -bool KRTextureCube::save(const std::string &path) +bool KRTextureCube::save(const std::string& path) { - return true; // Cube maps are just references; there are no files to output + return true; // Cube maps are just references; there are no files to output } -bool KRTextureCube::save(KRDataBlock &data) +bool KRTextureCube::save(KRDataBlock& data) { - return true; // Cube maps are just references; there are no files to output + return true; // Cube maps are just references; there are no files to output } diff --git a/kraken/KRTextureCube.h b/kraken/KRTextureCube.h index e9adeaf..d92e2b5 100755 --- a/kraken/KRTextureCube.h +++ b/kraken/KRTextureCube.h @@ -35,38 +35,39 @@ class KRTexture2D; -class KRTextureCube : public KRTexture { +class KRTextureCube : public KRTexture +{ public: - KRTextureCube(KRContext &context, std::string name); - virtual ~KRTextureCube(); - virtual std::string getExtension(); - virtual bool save(const std::string& path); - virtual bool save(KRDataBlock &data); - - virtual void bind(GLuint texture_unit); - virtual long getMemRequiredForSize(int max_dim); -// virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); - + KRTextureCube(KRContext& context, std::string name); + virtual ~KRTextureCube(); + virtual std::string getExtension(); + virtual bool save(const std::string& path); + virtual bool save(KRDataBlock& data); + + virtual void bind(GLuint texture_unit); + virtual long getMemRequiredForSize(int max_dim); + // virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); + private: - bool createGPUTexture(int lod_max_dim) override; - - const GLenum TARGETS[6] = { - GL_TEXTURE_CUBE_MAP_POSITIVE_X, - GL_TEXTURE_CUBE_MAP_NEGATIVE_X, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - }; - - const char *SUFFIXES[6] = { - "_positive_x", - "_negative_x", - "_positive_y", - "_negative_y", - "_positive_z", - "_negative_z" - }; - - KRTexture2D *m_textures[6]; + bool createGPUTexture(int lod_max_dim) override; + + const GLenum TARGETS[6] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + }; + + const char* SUFFIXES[6] = { + "_positive_x", + "_negative_x", + "_positive_y", + "_negative_y", + "_positive_z", + "_negative_z" + }; + + KRTexture2D* m_textures[6]; }; diff --git a/kraken/KRTextureKTX.cpp b/kraken/KRTextureKTX.cpp index e490d93..bdb43de 100755 --- a/kraken/KRTextureKTX.cpp +++ b/kraken/KRTextureKTX.cpp @@ -38,89 +38,91 @@ __uint8_t _KTXFileIdentifier[12] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }; -KRTextureKTX::KRTextureKTX(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) { - m_pData->copy(&m_header, 0, sizeof(KTXHeader)); - if(memcmp(_KTXFileIdentifier, m_header.identifier, 12) != 0) { - assert(false); // Header not recognized - } - if(m_header.endianness != 0x04030201) { - assert(false); // Endianness not (yet) supported - } - if(m_header.pixelDepth != 0) { - assert(false); // 3d textures not (yet) supported - } - if(m_header.numberOfArrayElements != 0) { - assert(false); // Array textures not (yet) supported - } - if(m_header.numberOfFaces != 1) { - assert(false); // Cube-map textures are only supported as a file for each separate face (for now) - } - - uint32_t blockStart = sizeof(KTXHeader) + m_header.bytesOfKeyValueData; - uint32_t width = m_header.pixelWidth, height = m_header.pixelHeight; - - for(int mipmap_level=0; mipmap_level < (int)KRMAX(m_header.numberOfMipmapLevels, 1); mipmap_level++) { - uint32_t blockLength; - data->copy(&blockLength, blockStart, 4); - blockStart += 4; - - m_blocks.push_back(m_pData->getSubBlock(blockStart, blockLength)); - - blockStart += blockLength; - blockStart = KRALIGN(blockStart); - - width = width >> 1; - if(width < 1) { - width = 1; - } - height = height >> 1; - if(height < 1) { - height = 1; - } - } - - m_max_lod_max_dim = KRMAX(m_header.pixelWidth, m_header.pixelHeight); - m_min_lod_max_dim = KRMAX(width, height); -} - -KRTextureKTX::KRTextureKTX(KRContext &context, std::string name, GLenum internal_format, GLenum base_internal_format, int width, int height, const std::list &blocks) : KRTexture2D(context, new KRDataBlock(), name) +KRTextureKTX::KRTextureKTX(KRContext& context, KRDataBlock* data, std::string name) : KRTexture2D(context, data, name) { - memcpy(m_header.identifier, _KTXFileIdentifier, 12); - m_header.endianness = 0x04030201; - m_header.glType = 0; - m_header.glTypeSize = 1; - m_header.glFormat = 0; - m_header.glInternalFormat = internal_format; - m_header.glBaseInternalFormat = base_internal_format; - m_header.pixelWidth = width; - m_header.pixelHeight = height; - m_header.pixelDepth = 0; - m_header.numberOfArrayElements = 0; - m_header.numberOfFaces = 1; - m_header.numberOfMipmapLevels = (__uint32_t)blocks.size(); - m_header.bytesOfKeyValueData = 0; - - m_pData->append(&m_header, sizeof(m_header)); - for(auto block_itr = blocks.begin(); block_itr != blocks.end(); block_itr++) { - KRDataBlock *source_block = *block_itr; - __uint32_t block_size = (__uint32_t)source_block->getSize(); - m_pData->append(&block_size, 4); - m_pData->append(*source_block); - m_blocks.push_back(m_pData->getSubBlock((int)m_pData->getSize() - (int)block_size, (int)block_size)); - size_t alignment_padding_size = KRALIGN(m_pData->getSize()) - m_pData->getSize(); - __uint8_t alignment_padding[4] = {0, 0, 0, 0}; - if(alignment_padding_size > 0) { - m_pData->append(&alignment_padding, alignment_padding_size); - } + m_pData->copy(&m_header, 0, sizeof(KTXHeader)); + if (memcmp(_KTXFileIdentifier, m_header.identifier, 12) != 0) { + assert(false); // Header not recognized + } + if (m_header.endianness != 0x04030201) { + assert(false); // Endianness not (yet) supported + } + if (m_header.pixelDepth != 0) { + assert(false); // 3d textures not (yet) supported + } + if (m_header.numberOfArrayElements != 0) { + assert(false); // Array textures not (yet) supported + } + if (m_header.numberOfFaces != 1) { + assert(false); // Cube-map textures are only supported as a file for each separate face (for now) + } + + uint32_t blockStart = sizeof(KTXHeader) + m_header.bytesOfKeyValueData; + uint32_t width = m_header.pixelWidth, height = m_header.pixelHeight; + + for (int mipmap_level = 0; mipmap_level < (int)KRMAX(m_header.numberOfMipmapLevels, 1); mipmap_level++) { + uint32_t blockLength; + data->copy(&blockLength, blockStart, 4); + blockStart += 4; + + m_blocks.push_back(m_pData->getSubBlock(blockStart, blockLength)); + + blockStart += blockLength; + blockStart = KRALIGN(blockStart); + + width = width >> 1; + if (width < 1) { + width = 1; } + height = height >> 1; + if (height < 1) { + height = 1; + } + } + + m_max_lod_max_dim = KRMAX(m_header.pixelWidth, m_header.pixelHeight); + m_min_lod_max_dim = KRMAX(width, height); } -KRTextureKTX::~KRTextureKTX() { - for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { - KRDataBlock *block = *itr; - delete block; +KRTextureKTX::KRTextureKTX(KRContext& context, std::string name, GLenum internal_format, GLenum base_internal_format, int width, int height, const std::list& blocks) : KRTexture2D(context, new KRDataBlock(), name) +{ + memcpy(m_header.identifier, _KTXFileIdentifier, 12); + m_header.endianness = 0x04030201; + m_header.glType = 0; + m_header.glTypeSize = 1; + m_header.glFormat = 0; + m_header.glInternalFormat = internal_format; + m_header.glBaseInternalFormat = base_internal_format; + m_header.pixelWidth = width; + m_header.pixelHeight = height; + m_header.pixelDepth = 0; + m_header.numberOfArrayElements = 0; + m_header.numberOfFaces = 1; + m_header.numberOfMipmapLevels = (__uint32_t)blocks.size(); + m_header.bytesOfKeyValueData = 0; + + m_pData->append(&m_header, sizeof(m_header)); + for (auto block_itr = blocks.begin(); block_itr != blocks.end(); block_itr++) { + KRDataBlock* source_block = *block_itr; + __uint32_t block_size = (__uint32_t)source_block->getSize(); + m_pData->append(&block_size, 4); + m_pData->append(*source_block); + m_blocks.push_back(m_pData->getSubBlock((int)m_pData->getSize() - (int)block_size, (int)block_size)); + size_t alignment_padding_size = KRALIGN(m_pData->getSize()) - m_pData->getSize(); + __uint8_t alignment_padding[4] = { 0, 0, 0, 0 }; + if (alignment_padding_size > 0) { + m_pData->append(&alignment_padding, alignment_padding_size); } - m_blocks.clear(); + } +} + +KRTextureKTX::~KRTextureKTX() +{ + for (std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { + KRDataBlock* block = *itr; + delete block; + } + m_blocks.clear(); } Vector2i KRTextureKTX::getDimensions() const @@ -130,104 +132,104 @@ Vector2i KRTextureKTX::getDimensions() const long KRTextureKTX::getMemRequiredForSize(int max_dim) { - int target_dim = max_dim; - if(target_dim < (int)m_min_lod_max_dim) target_dim = target_dim; - - // Determine how much memory will be consumed - - int width = m_header.pixelWidth; - int height = m_header.pixelHeight; - long memoryRequired = 0; - - for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { - KRDataBlock *block = *itr; - if(width <= target_dim && height <= target_dim) { - memoryRequired += (long)block->getSize(); - } - - width = width >> 1; - if(width < 1) { - width = 1; - } - height = height >> 1; - if(height < 1) { - height = 1; - } - } - - return memoryRequired; + int target_dim = max_dim; + if (target_dim < (int)m_min_lod_max_dim) target_dim = target_dim; + + // Determine how much memory will be consumed + + int width = m_header.pixelWidth; + int height = m_header.pixelHeight; + long memoryRequired = 0; + + for (std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { + KRDataBlock* block = *itr; + if (width <= target_dim && height <= target_dim) { + memoryRequired += (long)block->getSize(); + } + + width = width >> 1; + if (width < 1) { + width = 1; + } + height = height >> 1; + if (height < 1) { + height = 1; + } + } + + return memoryRequired; } -bool KRTextureKTX::uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int ¤t_lod_max_dim, bool compress, bool premultiply_alpha) +bool KRTextureKTX::uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int& current_lod_max_dim, bool compress, bool premultiply_alpha) { - int target_dim = lod_max_dim; - if(target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim; - - if(m_blocks.size() == 0) { - return false; + int target_dim = lod_max_dim; + if (target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim; + + if (m_blocks.size() == 0) { + return false; + } + + // Determine how much memory will be consumed + int width = m_header.pixelWidth; + int height = m_header.pixelHeight; + long memoryRequired = 0; + long memoryTransferred = 0; + + + // Upload texture data + int destination_level = 0; + int source_level = 0; + for (std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { + KRDataBlock* block = *itr; + if (width <= target_dim && height <= target_dim) { + + if (width > current_lod_max_dim) { + current_lod_max_dim = width; + } + if (height > current_lod_max_dim) { + current_lod_max_dim = height; + } + + block->lock(); + /* + * TODO - Vulkan Refactoring + GLDEBUG(glCompressedTexImage2D(target, destination_level, (GLenum)m_header.glInternalFormat, width, height, 0, (GLsizei)block->getSize(), block->getStart())); + */ + + block->unlock(); + memoryTransferred += (long)block->getSize(); // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE + memoryRequired += (long)block->getSize(); + // + // err = glGetError(); + // if (err != GL_NO_ERROR) { + // assert(false); + // return false; + // } + // + + destination_level++; } - - // Determine how much memory will be consumed - int width = m_header.pixelWidth; - int height = m_header.pixelHeight; - long memoryRequired = 0; - long memoryTransferred = 0; - - // Upload texture data - int destination_level=0; - int source_level = 0; - for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { - KRDataBlock *block = *itr; - if(width <= target_dim && height <= target_dim) { - - if(width > current_lod_max_dim) { - current_lod_max_dim = width; - } - if(height > current_lod_max_dim) { - current_lod_max_dim = height; - } + if (width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) { + source_level++; + } - block->lock(); - /* - * TODO - Vulkan Refactoring - GLDEBUG(glCompressedTexImage2D(target, destination_level, (GLenum)m_header.glInternalFormat, width, height, 0, (GLsizei)block->getSize(), block->getStart())); - */ + width = width >> 1; + if (width < 1) { + width = 1; + } + height = height >> 1; + if (height < 1) { + height = 1; + } + } + + return true; - block->unlock(); - memoryTransferred += (long)block->getSize(); // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE - memoryRequired += (long)block->getSize(); - // - // err = glGetError(); - // if (err != GL_NO_ERROR) { - // assert(false); - // return false; - // } - // - - destination_level++; - } - - if(width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) { - source_level++; - } - - width = width >> 1; - if(width < 1) { - width = 1; - } - height = height >> 1; - if(height < 1) { - height = 1; - } - } - - return true; - } std::string KRTextureKTX::getExtension() { - return "ktx"; + return "ktx"; } diff --git a/kraken/KRTextureKTX.h b/kraken/KRTextureKTX.h index c7dd6a8..df400cf 100755 --- a/kraken/KRTextureKTX.h +++ b/kraken/KRTextureKTX.h @@ -36,37 +36,37 @@ class KRTextureKTX : public KRTexture2D { public: - KRTextureKTX(KRContext &context, KRDataBlock *data, std::string name); - KRTextureKTX(KRContext &context, std::string name, GLenum internal_format, GLenum base_internal_format, int width, int height, const std::list &blocks); - virtual ~KRTextureKTX(); - virtual std::string getExtension(); - - bool uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int& current_lod_max_dim, bool compress = false, bool premultiply_alpha = false) override; - - virtual long getMemRequiredForSize(int max_dim); - virtual Vector2i getDimensions() const override; - + KRTextureKTX(KRContext& context, KRDataBlock* data, std::string name); + KRTextureKTX(KRContext& context, std::string name, GLenum internal_format, GLenum base_internal_format, int width, int height, const std::list& blocks); + virtual ~KRTextureKTX(); + virtual std::string getExtension(); + + bool uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int& current_lod_max_dim, bool compress = false, bool premultiply_alpha = false) override; + + virtual long getMemRequiredForSize(int max_dim); + virtual Vector2i getDimensions() const override; + protected: - - std::list m_blocks; - - typedef struct _KTXHeader - { - __uint8_t identifier[12]; - __uint32_t endianness; - __uint32_t glType; - __uint32_t glTypeSize; - __uint32_t glFormat; - __uint32_t glInternalFormat; - __uint32_t glBaseInternalFormat; - __uint32_t pixelWidth; - __uint32_t pixelHeight; - __uint32_t pixelDepth; - __uint32_t numberOfArrayElements; - __uint32_t numberOfFaces; - __uint32_t numberOfMipmapLevels; - __uint32_t bytesOfKeyValueData; - } KTXHeader; - - KTXHeader m_header; + + std::list m_blocks; + + typedef struct _KTXHeader + { + __uint8_t identifier[12]; + __uint32_t endianness; + __uint32_t glType; + __uint32_t glTypeSize; + __uint32_t glFormat; + __uint32_t glInternalFormat; + __uint32_t glBaseInternalFormat; + __uint32_t pixelWidth; + __uint32_t pixelHeight; + __uint32_t pixelDepth; + __uint32_t numberOfArrayElements; + __uint32_t numberOfFaces; + __uint32_t numberOfMipmapLevels; + __uint32_t bytesOfKeyValueData; + } KTXHeader; + + KTXHeader m_header; }; diff --git a/kraken/KRTextureManager.cpp b/kraken/KRTextureManager.cpp index 40c8433..93ff3f7 100755 --- a/kraken/KRTextureManager.cpp +++ b/kraken/KRTextureManager.cpp @@ -40,17 +40,18 @@ #include "KRTextureAnimated.h" #include "KRContext.h" -KRTextureManager::KRTextureManager(KRContext &context) : KRResourceManager(context) { - m_textureMemUsed = 0; +KRTextureManager::KRTextureManager(KRContext& context) : KRResourceManager(context) +{ + m_textureMemUsed = 0; - for(int iTexture=0; iTextureloadTexture(name.c_str(), extension.c_str(), data); } else if(extension.compare("ktx") == 0) { resource = m_pTextureManager->loadTexture(name.c_str(), extension.c_str(), data); } else if(extension.compare("tga") == 0) { - + */ if (extension.compare("pvr") == 0 || extension.compare("ktx") == 0 || @@ -147,361 +149,367 @@ KRResource* KRTextureManager::getResource(const std::string& name, const std::st return nullptr; } -KRTexture *KRTextureManager::loadTexture(const char *szName, const char *szExtension, KRDataBlock *data) { - KRTexture *pTexture = NULL; - - std::string lowerName = szName; - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - - std::string lowerExtension = szExtension; - std::transform(lowerExtension.begin(), lowerExtension.end(), - lowerExtension.begin(), ::tolower); +KRTexture* KRTextureManager::loadTexture(const char* szName, const char* szExtension, KRDataBlock* data) +{ + KRTexture* pTexture = NULL; - - if(strcmp(szExtension, "pvr") == 0) { - pTexture = new KRTexturePVR(getContext(), data, szName); - } else if(strcmp(szExtension, "tga") == 0) { - pTexture = new KRTextureTGA(getContext(), data, szName); - } else if(strcmp(szExtension, "ktx") == 0) { - pTexture = new KRTextureKTX(getContext(), data, szName); - } - - if(pTexture) { - m_textures[lowerName] = pTexture; - } - return pTexture; + std::string lowerName = szName; + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + + std::string lowerExtension = szExtension; + std::transform(lowerExtension.begin(), lowerExtension.end(), + lowerExtension.begin(), ::tolower); + + + if (strcmp(szExtension, "pvr") == 0) { + pTexture = new KRTexturePVR(getContext(), data, szName); + } else if (strcmp(szExtension, "tga") == 0) { + pTexture = new KRTextureTGA(getContext(), data, szName); + } else if (strcmp(szExtension, "ktx") == 0) { + pTexture = new KRTextureKTX(getContext(), data, szName); + } + + if (pTexture) { + m_textures[lowerName] = pTexture; + } + return pTexture; } -KRTexture *KRTextureManager::getTextureCube(const char *szName) { - std::string lowerName = szName; - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - - unordered_map::iterator itr = m_textures.find(lowerName); - if(itr == m_textures.end()) { - - // Defer resolving the texture cube until its referenced textures are ready - const char *SUFFIXES[6] = { - "_positive_x", - "_negative_x", - "_positive_y", - "_negative_y", - "_positive_z", - "_negative_z" - }; - bool found_all = true; - for(int i=0; i<6; i++) { - std::string faceName = lowerName + SUFFIXES[i]; - KRTexture *faceTexture = dynamic_cast(getContext().getTextureManager()->getTexture(faceName)); - if(faceTexture == NULL) { - found_all = false; - } - } - - if(found_all) { - KRTextureCube *pTexture = new KRTextureCube(getContext(), lowerName); - - m_textures[lowerName] = pTexture; - return pTexture; - } else { - return NULL; - } +KRTexture* KRTextureManager::getTextureCube(const char* szName) +{ + std::string lowerName = szName; + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + + unordered_map::iterator itr = m_textures.find(lowerName); + if (itr == m_textures.end()) { + + // Defer resolving the texture cube until its referenced textures are ready + const char* SUFFIXES[6] = { + "_positive_x", + "_negative_x", + "_positive_y", + "_negative_y", + "_positive_z", + "_negative_z" + }; + bool found_all = true; + for (int i = 0; i < 6; i++) { + std::string faceName = lowerName + SUFFIXES[i]; + KRTexture* faceTexture = dynamic_cast(getContext().getTextureManager()->getTexture(faceName)); + if (faceTexture == NULL) { + found_all = false; + } + } + + if (found_all) { + KRTextureCube* pTexture = new KRTextureCube(getContext(), lowerName); + + m_textures[lowerName] = pTexture; + return pTexture; } else { - return (*itr).second; + return NULL; } + } else { + return (*itr).second; + } } -KRTexture *KRTextureManager::getTexture(const std::string &name) { - - std::string lowerName = name; - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - - unordered_map::iterator itr = m_textures.find(lowerName); - if(itr == m_textures.end()) { - if(lowerName.length() <= 8) { - return NULL; - } else if(lowerName.compare(0, 8, "animate:", 0, 8) == 0) { - // This is an animated texture, create KRTextureAnimated's on-demand - KRTextureAnimated *pTexture = new KRTextureAnimated(getContext(), lowerName); - m_textures[lowerName] = pTexture; - return pTexture; - } else { - // Not found - // fprintf(stderr, "ERROR: Texture not found: %s\n", name.c_str()); - return NULL; - } +KRTexture* KRTextureManager::getTexture(const std::string& name) +{ + + std::string lowerName = name; + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + + unordered_map::iterator itr = m_textures.find(lowerName); + if (itr == m_textures.end()) { + if (lowerName.length() <= 8) { + return NULL; + } else if (lowerName.compare(0, 8, "animate:", 0, 8) == 0) { + // This is an animated texture, create KRTextureAnimated's on-demand + KRTextureAnimated* pTexture = new KRTextureAnimated(getContext(), lowerName); + m_textures[lowerName] = pTexture; + return pTexture; } else { - return (*itr).second; + // Not found + // fprintf(stderr, "ERROR: Texture not found: %s\n", name.c_str()); + return NULL; } + } else { + return (*itr).second; + } } -void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture, float lod_coverage, KRTexture::texture_usage_t textureUsage) { - bool is_animated = false; - if(pTexture) { - pTexture->resetPoolExpiry(lod_coverage, textureUsage); - if(pTexture->isAnimated()) is_animated = true; - } - - if(m_boundTextures[iTextureUnit] != pTexture || is_animated) { - - if(pTexture != NULL) { - _setActiveTexture(iTextureUnit); - pTexture->bind(iTextureUnit); - } else { - selectTexture(GL_TEXTURE_2D, iTextureUnit, 0); - } - m_boundTextures[iTextureUnit] = pTexture; +void KRTextureManager::selectTexture(int iTextureUnit, KRTexture* pTexture, float lod_coverage, KRTexture::texture_usage_t textureUsage) +{ + bool is_animated = false; + if (pTexture) { + pTexture->resetPoolExpiry(lod_coverage, textureUsage); + if (pTexture->isAnimated()) is_animated = true; + } + + if (m_boundTextures[iTextureUnit] != pTexture || is_animated) { + + if (pTexture != NULL) { + _setActiveTexture(iTextureUnit); + pTexture->bind(iTextureUnit); + } else { + selectTexture(GL_TEXTURE_2D, iTextureUnit, 0); } + m_boundTextures[iTextureUnit] = pTexture; + } } bool KRTextureManager::selectTexture(GLenum target, int iTextureUnit, int iTextureHandle) { - if(m_boundTextureHandles[iTextureUnit] != iTextureHandle) { - m_boundTextureHandles[iTextureUnit] = iTextureHandle; - _setActiveTexture(iTextureUnit); - glBindTexture(target, iTextureHandle); - return true; - } else { - return false; - } + if (m_boundTextureHandles[iTextureUnit] != iTextureHandle) { + m_boundTextureHandles[iTextureUnit] = iTextureHandle; + _setActiveTexture(iTextureUnit); + glBindTexture(target, iTextureHandle); + return true; + } else { + return false; + } } -long KRTextureManager::getMemUsed() { - return m_textureMemUsed; +long KRTextureManager::getMemUsed() +{ + return m_textureMemUsed; } -long KRTextureManager::getMemActive() { - long mem_active = 0; - for(std::set::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { - KRTexture *activeTexture = *itr; - mem_active += activeTexture->getMemSize(); - } - - return mem_active; +long KRTextureManager::getMemActive() +{ + long mem_active = 0; + for (std::set::iterator itr = m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { + KRTexture* activeTexture = *itr; + mem_active += activeTexture->getMemSize(); + } + + return mem_active; } void KRTextureManager::startFrame(float deltaTime) { - _clearGLState(); - - // TODO - Implement proper double-buffering to reduce copy operations - m_streamerFenceMutex.lock(); - - if(m_streamerComplete) { - assert(m_activeTextures_streamer_copy.size() == 0); // The streamer should have emptied this if it really did complete - - const long KRENGINE_TEXTURE_EXPIRY_FRAMES = 10; - - std::set expiredTextures; - for(std::set::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { - KRTexture *activeTexture = *itr; - activeTexture->_swapHandles(); - if(activeTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) { - // Expire textures that haven't been used in a long time - expiredTextures.insert(activeTexture); - activeTexture->releaseHandles(); - } else { - float priority = activeTexture->getStreamPriority(); - m_activeTextures_streamer_copy.push_back(std::pair(priority, activeTexture)); - } - } - for(std::set::iterator itr=expiredTextures.begin(); itr != expiredTextures.end(); itr++) { - m_activeTextures.erase(*itr); - } - - if(m_activeTextures_streamer_copy.size() > 0) { - m_streamerComplete = false; - } + _clearGLState(); + + // TODO - Implement proper double-buffering to reduce copy operations + m_streamerFenceMutex.lock(); + + if (m_streamerComplete) { + assert(m_activeTextures_streamer_copy.size() == 0); // The streamer should have emptied this if it really did complete + + const long KRENGINE_TEXTURE_EXPIRY_FRAMES = 10; + + std::set expiredTextures; + for (std::set::iterator itr = m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { + KRTexture* activeTexture = *itr; + activeTexture->_swapHandles(); + if (activeTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) { + // Expire textures that haven't been used in a long time + expiredTextures.insert(activeTexture); + activeTexture->releaseHandles(); + } else { + float priority = activeTexture->getStreamPriority(); + m_activeTextures_streamer_copy.push_back(std::pair(priority, activeTexture)); + } + } + for (std::set::iterator itr = expiredTextures.begin(); itr != expiredTextures.end(); itr++) { + m_activeTextures.erase(*itr); } - m_streamerFenceMutex.unlock(); - - m_memoryTransferredThisFrame = 0; + if (m_activeTextures_streamer_copy.size() > 0) { + m_streamerComplete = false; + } + } + + m_streamerFenceMutex.unlock(); + + m_memoryTransferredThisFrame = 0; } void KRTextureManager::endFrame(float deltaTime) { - for(int iTexture=0; iTexture < KRENGINE_MAX_TEXTURE_UNITS; iTexture++) { - if(m_boundTextures[iTexture]) { - m_boundTextures[iTexture]->resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_NONE); // Even if the same texture is bound, ensure that they don't expire from the texture pool while in use - } + for (int iTexture = 0; iTexture < KRENGINE_MAX_TEXTURE_UNITS; iTexture++) { + if (m_boundTextures[iTexture]) { + m_boundTextures[iTexture]->resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_NONE); // Even if the same texture is bound, ensure that they don't expire from the texture pool while in use } + } } -void KRTextureManager::doStreaming(long &memoryRemaining, long &memoryRemainingThisFrame) +void KRTextureManager::doStreaming(long& memoryRemaining, long& memoryRemainingThisFrame) { - - // TODO - Implement proper double-buffering to reduce copy operations + + // TODO - Implement proper double-buffering to reduce copy operations + m_streamerFenceMutex.lock(); + m_activeTextures_streamer = std::move(m_activeTextures_streamer_copy); + m_streamerFenceMutex.unlock(); + + if (m_activeTextures_streamer.size() > 0) { + balanceTextureMemory(memoryRemaining, memoryRemainingThisFrame); + m_streamerFenceMutex.lock(); - m_activeTextures_streamer = std::move(m_activeTextures_streamer_copy); + m_streamerComplete = true; m_streamerFenceMutex.unlock(); - - if(m_activeTextures_streamer.size() > 0) { - balanceTextureMemory(memoryRemaining, memoryRemainingThisFrame); - - m_streamerFenceMutex.lock(); - m_streamerComplete = true; - m_streamerFenceMutex.unlock(); - } else { - memoryRemaining -= getMemUsed(); - } + } else { + memoryRemaining -= getMemUsed(); + } } -void KRTextureManager::balanceTextureMemory(long &memoryRemaining, long &memoryRemainingThisFrame) +void KRTextureManager::balanceTextureMemory(long& memoryRemaining, long& memoryRemainingThisFrame) { - // Balance texture memory by reducing and increasing the maximum mip-map level of both active and inactive textures - // Favour performance over maximum texture resolution when memory is insufficient for textures at full resolution. - - /* - NEW ALGORITHM: - - Textures are assigned a “weight” by tuneable criteria: - - Area of screen coverage taken by objects containing material (more accurate and generic than distance) - - Type of texture (separate weight for normal, diffuse, spec maps) - - Last used time (to keep textures loaded for recently seen objects that are outside of the view frustum) - Those factors combine together to give a “weight”, which represents a proportion relative to all other textures weights - Mipmap levels are stripped off of each texture until they occupy the amount of memory they should proportionally have - This is in contrast to the global ceiling of texture resolution that slowly drops until the textures fit - - */ + // Balance texture memory by reducing and increasing the maximum mip-map level of both active and inactive textures + // Favour performance over maximum texture resolution when memory is insufficient for textures at full resolution. - // --------------- - - //long MAX_STREAM_TIME = 66; - //long startTime = getContext().getAbsoluteTimeMilliseconds(); - - std::sort(m_activeTextures_streamer.begin(), m_activeTextures_streamer.end(), std::greater>()); - - for(auto itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) { - KRTexture *texture = (*itr).second; - int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap()); - long minLodMem = texture->getMemRequiredForSize(min_mip_level); - memoryRemaining -= minLodMem; - - if(memoryRemainingThisFrame > minLodMem && texture->getNewLodMaxDim() < min_mip_level) { - memoryRemainingThisFrame -= minLodMem; - texture->resize(min_mip_level); - } - } - - //long minMipTime = getContext().getAbsoluteTimeMilliseconds() - startTime; - - std::vector mipPercents = {75, 75, 50, 50, 50}; - int mip_drop = -1; - auto mip_itr = mipPercents.begin(); - long memoryRemainingThisMip = 0; + /* + NEW ALGORITHM: - for(auto itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) { - if(memoryRemainingThisMip <= 0) { - if(mip_itr == mipPercents.end()) { - break; - } else { - memoryRemainingThisMip = memoryRemaining / 100L * (long)(*mip_itr); - mip_drop++; - mip_itr++; - } - } - - KRTexture *texture = (*itr).second; - int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap()); - int max_mip_level = KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, texture->getMaxMipMap()); - int target_mip_level = (max_mip_level >> mip_drop); - long targetMem = texture->getMemRequiredForSize(target_mip_level); - long additionalMemRequired = targetMem - texture->getMemRequiredForSize(min_mip_level); - memoryRemainingThisMip -= additionalMemRequired; - memoryRemaining -= additionalMemRequired; - if(memoryRemainingThisMip > 0 && memoryRemainingThisFrame > targetMem) { - int current_mip_level = texture->getNewLodMaxDim(); - if(current_mip_level == (target_mip_level >> 1) || target_mip_level < current_mip_level) { - memoryRemainingThisFrame -= targetMem; - texture->resize(target_mip_level); - } else if(current_mip_level == (target_mip_level >> 2)) { - memoryRemainingThisFrame -= texture->getMemRequiredForSize(target_mip_level >> 1); - texture->resize(target_mip_level >> 1); - } else if(current_mip_level < (target_mip_level >> 2)) { - memoryRemainingThisFrame -= texture->getMemRequiredForSize(target_mip_level >> 2); - texture->resize(target_mip_level >> 2); - } - } - - //if(getContext().getAbsoluteTimeMilliseconds() - startTime > MAX_STREAM_TIME) { - // return; // Bail out early if we spend too long - //} + Textures are assigned a “weight” by tuneable criteria: + - Area of screen coverage taken by objects containing material (more accurate and generic than distance) + - Type of texture (separate weight for normal, diffuse, spec maps) + - Last used time (to keep textures loaded for recently seen objects that are outside of the view frustum) + Those factors combine together to give a “weight”, which represents a proportion relative to all other textures weights + Mipmap levels are stripped off of each texture until they occupy the amount of memory they should proportionally have + This is in contrast to the global ceiling of texture resolution that slowly drops until the textures fit + + */ + + // --------------- + + //long MAX_STREAM_TIME = 66; + //long startTime = getContext().getAbsoluteTimeMilliseconds(); + + std::sort(m_activeTextures_streamer.begin(), m_activeTextures_streamer.end(), std::greater>()); + + for (auto itr = m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) { + KRTexture* texture = (*itr).second; + int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap()); + long minLodMem = texture->getMemRequiredForSize(min_mip_level); + memoryRemaining -= minLodMem; + + if (memoryRemainingThisFrame > minLodMem && texture->getNewLodMaxDim() < min_mip_level) { + memoryRemainingThisFrame -= minLodMem; + texture->resize(min_mip_level); } - - //long streamerTime = getContext().getAbsoluteTimeMilliseconds() - startTime; - //fprintf(stderr, "%i / %i\n", (int)minMipTime, (int)streamerTime); + } + + //long minMipTime = getContext().getAbsoluteTimeMilliseconds() - startTime; + + std::vector mipPercents = { 75, 75, 50, 50, 50 }; + int mip_drop = -1; + auto mip_itr = mipPercents.begin(); + long memoryRemainingThisMip = 0; + + for (auto itr = m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) { + if (memoryRemainingThisMip <= 0) { + if (mip_itr == mipPercents.end()) { + break; + } else { + memoryRemainingThisMip = memoryRemaining / 100L * (long)(*mip_itr); + mip_drop++; + mip_itr++; + } + } + + KRTexture* texture = (*itr).second; + int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap()); + int max_mip_level = KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, texture->getMaxMipMap()); + int target_mip_level = (max_mip_level >> mip_drop); + long targetMem = texture->getMemRequiredForSize(target_mip_level); + long additionalMemRequired = targetMem - texture->getMemRequiredForSize(min_mip_level); + memoryRemainingThisMip -= additionalMemRequired; + memoryRemaining -= additionalMemRequired; + if (memoryRemainingThisMip > 0 && memoryRemainingThisFrame > targetMem) { + int current_mip_level = texture->getNewLodMaxDim(); + if (current_mip_level == (target_mip_level >> 1) || target_mip_level < current_mip_level) { + memoryRemainingThisFrame -= targetMem; + texture->resize(target_mip_level); + } else if (current_mip_level == (target_mip_level >> 2)) { + memoryRemainingThisFrame -= texture->getMemRequiredForSize(target_mip_level >> 1); + texture->resize(target_mip_level >> 1); + } else if (current_mip_level < (target_mip_level >> 2)) { + memoryRemainingThisFrame -= texture->getMemRequiredForSize(target_mip_level >> 2); + texture->resize(target_mip_level >> 2); + } + } + + //if(getContext().getAbsoluteTimeMilliseconds() - startTime > MAX_STREAM_TIME) { + // return; // Bail out early if we spend too long + //} + } + + //long streamerTime = getContext().getAbsoluteTimeMilliseconds() - startTime; + //fprintf(stderr, "%i / %i\n", (int)minMipTime, (int)streamerTime); } long KRTextureManager::getMemoryTransferedThisFrame() { - return m_memoryTransferredThisFrame; + return m_memoryTransferredThisFrame; } void KRTextureManager::addMemoryTransferredThisFrame(long memoryTransferred) { - m_memoryTransferredThisFrame += memoryTransferred; + m_memoryTransferredThisFrame += memoryTransferred; } void KRTextureManager::memoryChanged(long memoryDelta) { - m_textureMemUsed += memoryDelta; - //fprintf(stderr, "Texture Memory: %ld / %i\n", (long)m_textureMemUsed, KRContext::KRENGINE_GPU_MEM_MAX); + m_textureMemUsed += memoryDelta; + //fprintf(stderr, "Texture Memory: %ld / %i\n", (long)m_textureMemUsed, KRContext::KRENGINE_GPU_MEM_MAX); } -unordered_map &KRTextureManager::getTextures() +unordered_map& KRTextureManager::getTextures() { - return m_textures; + return m_textures; } void KRTextureManager::compress(bool premultiply_alpha) { - std::vector textures_to_remove; - std::vector textures_to_add; - - for(unordered_map::iterator itr=m_textures.begin(); itr != m_textures.end(); itr++) { - KRTexture *texture = (*itr).second; - KRTexture *compressed_texture = texture->compress(premultiply_alpha); - if(compressed_texture) { - textures_to_remove.push_back(texture); - textures_to_add.push_back(compressed_texture); - } else { - assert(false); - } - } - - for(std::vector::iterator itr = textures_to_remove.begin(); itr != textures_to_remove.end(); itr++) { - KRTexture *texture = *itr; - std::string lowerName = texture->getName(); - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - m_textures.erase(lowerName); - delete texture; - } - - for(std::vector::iterator itr = textures_to_add.begin(); itr != textures_to_add.end(); itr++) { - KRTexture *texture = *itr; - std::string lowerName = texture->getName(); - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - m_textures[lowerName] = texture; + std::vector textures_to_remove; + std::vector textures_to_add; + + for (unordered_map::iterator itr = m_textures.begin(); itr != m_textures.end(); itr++) { + KRTexture* texture = (*itr).second; + KRTexture* compressed_texture = texture->compress(premultiply_alpha); + if (compressed_texture) { + textures_to_remove.push_back(texture); + textures_to_add.push_back(compressed_texture); + } else { + assert(false); } + } + + for (std::vector::iterator itr = textures_to_remove.begin(); itr != textures_to_remove.end(); itr++) { + KRTexture* texture = *itr; + std::string lowerName = texture->getName(); + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + m_textures.erase(lowerName); + delete texture; + } + + for (std::vector::iterator itr = textures_to_add.begin(); itr != textures_to_add.end(); itr++) { + KRTexture* texture = *itr; + std::string lowerName = texture->getName(); + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + m_textures[lowerName] = texture; + } } -std::set &KRTextureManager::getActiveTextures() +std::set& KRTextureManager::getActiveTextures() { - return m_activeTextures; + return m_activeTextures; } -void KRTextureManager::primeTexture(KRTexture *texture) +void KRTextureManager::primeTexture(KRTexture* texture) { - if(m_activeTextures.find(texture) == m_activeTextures.end()) { - m_activeTextures.insert(texture); - } + if (m_activeTextures.find(texture) == m_activeTextures.end()) { + m_activeTextures.insert(texture); + } } diff --git a/kraken/KRTextureManager.h b/kraken/KRTextureManager.h index 7fc3f99..7a37ee5 100755 --- a/kraken/KRTextureManager.h +++ b/kraken/KRTextureManager.h @@ -42,72 +42,73 @@ #include "KRContext.h" #include "KRStreamerThread.h" -class KRTextureManager : public KRResourceManager { +class KRTextureManager : public KRResourceManager +{ public: - KRTextureManager(KRContext &context); - virtual ~KRTextureManager(); - void destroy(); + KRTextureManager(KRContext& context); + virtual ~KRTextureManager(); + void destroy(); + + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; + + void selectTexture(int iTextureUnit, KRTexture* pTexture, float lod_coverage, KRTexture::texture_usage_t textureUsage); + bool selectTexture(GLenum target, int iTextureUnit, int iTextureHandle); + + KRTexture* loadTexture(const char* szName, const char* szExtension, KRDataBlock* data); + KRTexture* getTextureCube(const char* szName); + KRTexture* getTexture(const std::string& name); + + long getMemUsed(); + long getMemActive(); + + long getMemoryTransferedThisFrame(); + void addMemoryTransferredThisFrame(long memoryTransferred); + + void memoryChanged(long memoryDelta); + + void startFrame(float deltaTime); + void endFrame(float deltaTime); + + unordered_map& getTextures(); + + void compress(bool premultiply_alpha = false); + + std::set& getActiveTextures(); + + void _setActiveTexture(int i); + void _setWrapModeS(GLuint i, GLuint wrap_mode); + void _setWrapModeT(GLuint i, GLuint wrap_mode); + + void _clearGLState(); + void setMaxAnisotropy(float max_anisotropy); + + void doStreaming(long& memoryRemaining, long& memoryRemainingThisFrame); + void primeTexture(KRTexture* texture); - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - - void selectTexture(int iTextureUnit, KRTexture *pTexture, float lod_coverage, KRTexture::texture_usage_t textureUsage); - bool selectTexture(GLenum target, int iTextureUnit, int iTextureHandle); - - KRTexture *loadTexture(const char *szName, const char *szExtension, KRDataBlock *data); - KRTexture *getTextureCube(const char *szName); - KRTexture *getTexture(const std::string &name); - - long getMemUsed(); - long getMemActive(); - - long getMemoryTransferedThisFrame(); - void addMemoryTransferredThisFrame(long memoryTransferred); - - void memoryChanged(long memoryDelta); - - void startFrame(float deltaTime); - void endFrame(float deltaTime); - - unordered_map &getTextures(); - - void compress(bool premultiply_alpha = false); - - std::set &getActiveTextures(); - - void _setActiveTexture(int i); - void _setWrapModeS(GLuint i, GLuint wrap_mode); - void _setWrapModeT(GLuint i, GLuint wrap_mode); - - void _clearGLState(); - void setMaxAnisotropy(float max_anisotropy); - - void doStreaming(long &memoryRemaining, long &memoryRemainingThisFrame); - void primeTexture(KRTexture *texture); - private: - int m_iActiveTexture; - - long m_memoryTransferredThisFrame; - - unordered_map m_textures; - - KRTexture *m_boundTextures[KRENGINE_MAX_TEXTURE_UNITS]; - int m_boundTextureHandles[KRENGINE_MAX_TEXTURE_UNITS]; - GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS]; - GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS]; - float m_maxAnisotropy; - - - std::set m_activeTextures; - - std::vector > m_activeTextures_streamer; - std::vector > m_activeTextures_streamer_copy; - bool m_streamerComplete; - - std::atomic m_textureMemUsed; - - void balanceTextureMemory(long &memoryRemaining, long &memoryRemainingThisFrame); - - std::mutex m_streamerFenceMutex; + int m_iActiveTexture; + + long m_memoryTransferredThisFrame; + + unordered_map m_textures; + + KRTexture* m_boundTextures[KRENGINE_MAX_TEXTURE_UNITS]; + int m_boundTextureHandles[KRENGINE_MAX_TEXTURE_UNITS]; + GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS]; + GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS]; + float m_maxAnisotropy; + + + std::set m_activeTextures; + + std::vector > m_activeTextures_streamer; + std::vector > m_activeTextures_streamer_copy; + bool m_streamerComplete; + + std::atomic m_textureMemUsed; + + void balanceTextureMemory(long& memoryRemaining, long& memoryRemainingThisFrame); + + std::mutex m_streamerFenceMutex; }; diff --git a/kraken/KRTexturePVR.cpp b/kraken/KRTexturePVR.cpp index c477305..070f8a3 100755 --- a/kraken/KRTexturePVR.cpp +++ b/kraken/KRTexturePVR.cpp @@ -41,107 +41,109 @@ static char gPVRTexIdentifier[5] = "PVR!"; enum { - kPVRTextureFlagTypePVRTC_2 = 24, - kPVRTextureFlagTypePVRTC_4 + kPVRTextureFlagTypePVRTC_2 = 24, + kPVRTextureFlagTypePVRTC_4 }; typedef struct _PVRTexHeader { - uint32_t headerLength; - uint32_t height; - uint32_t width; - uint32_t numMipmaps; - uint32_t flags; - uint32_t dataLength; - uint32_t bpp; - uint32_t bitmaskRed; - uint32_t bitmaskGreen; - uint32_t bitmaskBlue; - uint32_t bitmaskAlpha; - uint32_t pvrTag; - uint32_t numSurfs; + uint32_t headerLength; + uint32_t height; + uint32_t width; + uint32_t numMipmaps; + uint32_t flags; + uint32_t dataLength; + uint32_t bpp; + uint32_t bitmaskRed; + uint32_t bitmaskGreen; + uint32_t bitmaskBlue; + uint32_t bitmaskAlpha; + uint32_t pvrTag; + uint32_t numSurfs; } PVRTexHeader; -KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) { +KRTexturePVR::KRTexturePVR(KRContext& context, KRDataBlock* data, std::string name) : KRTexture2D(context, data, name) +{ #if TARGET_OS_IPHONE - - PVRTexHeader header; - m_pData->copy(&header, 0, sizeof(PVRTexHeader)); - - uint32_t formatFlags = header.flags & PVR_TEXTURE_FLAG_TYPE_MASK; + + PVRTexHeader header; + m_pData->copy(&header, 0, sizeof(PVRTexHeader)); + + uint32_t formatFlags = header.flags & PVR_TEXTURE_FLAG_TYPE_MASK; + if (formatFlags == kPVRTextureFlagTypePVRTC_4) { + m_internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + } else if (formatFlags == kPVRTextureFlagTypePVRTC_2) { + m_internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + } else { + assert(false); + } + + uint32_t pvrTag = header.pvrTag; + if (gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) || + gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) || + gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) || + gPVRTexIdentifier[3] != ((pvrTag >> 24) & 0xff)) { + assert(false); + } + + m_iWidth = header.width; // Note: call __builtin_bswap32 when needed to switch endianness + m_iHeight = header.height; + m_bHasAlpha = header.bitmaskAlpha; + + uint32_t dataStart = sizeof(PVRTexHeader); + uint32_t dataLength = header.dataLength, dataOffset = 0, dataSize = 0; + uint32_t width = m_iWidth, height = m_iHeight, bpp = 4; + uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0; + + // Calculate the data size for each texture level and respect the minimum number of blocks + while (dataOffset < dataLength) { if (formatFlags == kPVRTextureFlagTypePVRTC_4) { - m_internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; - } else if(formatFlags == kPVRTextureFlagTypePVRTC_2) { - m_internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + blockSize = 4 * 4; // Pixel by pixel block size for 4bpp + widthBlocks = width / 4; + heightBlocks = height / 4; + bpp = 4; } else { - assert(false); + blockSize = 8 * 4; // Pixel by pixel block size for 2bpp + widthBlocks = width / 8; + heightBlocks = height / 4; + bpp = 2; } - - uint32_t pvrTag = header.pvrTag; - if (gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) || - gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) || - gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) || - gPVRTexIdentifier[3] != ((pvrTag >> 24) & 0xff)) { - assert(false); + + // Clamp to minimum number of blocks + if (widthBlocks < 2) { + widthBlocks = 2; } - - m_iWidth = header.width; // Note: call __builtin_bswap32 when needed to switch endianness - m_iHeight = header.height; - m_bHasAlpha = header.bitmaskAlpha; - - uint32_t dataStart = sizeof(PVRTexHeader); - uint32_t dataLength = header.dataLength, dataOffset = 0, dataSize = 0; - uint32_t width = m_iWidth, height = m_iHeight, bpp = 4; - uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0; - - // Calculate the data size for each texture level and respect the minimum number of blocks - while(dataOffset < dataLength) { - if (formatFlags == kPVRTextureFlagTypePVRTC_4) { - blockSize = 4 * 4; // Pixel by pixel block size for 4bpp - widthBlocks = width / 4; - heightBlocks = height / 4; - bpp = 4; - } else { - blockSize = 8 * 4; // Pixel by pixel block size for 2bpp - widthBlocks = width / 8; - heightBlocks = height / 4; - bpp = 2; - } - - // Clamp to minimum number of blocks - if (widthBlocks < 2) { - widthBlocks = 2; - } - if (heightBlocks < 2) { - heightBlocks = 2; - } - dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8); - - m_blocks.push_back(m_pData->getSubBlock(dataStart + dataOffset, dataSize)); - - dataOffset += dataSize; - - width = width >> 1; - if(width < 1) { - width = 1; - } - height = height >> 1; - if(height < 1) { - height = 1; - } + if (heightBlocks < 2) { + heightBlocks = 2; } - - m_max_lod_max_dim = m_iWidth > m_iHeight ? m_iWidth : m_iHeight; - m_min_lod_max_dim = width > height ? width : height; + dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8); + + m_blocks.push_back(m_pData->getSubBlock(dataStart + dataOffset, dataSize)); + + dataOffset += dataSize; + + width = width >> 1; + if (width < 1) { + width = 1; + } + height = height >> 1; + if (height < 1) { + height = 1; + } + } + + m_max_lod_max_dim = m_iWidth > m_iHeight ? m_iWidth : m_iHeight; + m_min_lod_max_dim = width > height ? width : height; #endif } -KRTexturePVR::~KRTexturePVR() { - for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { - KRDataBlock *block = *itr; - delete block; - } - m_blocks.clear(); +KRTexturePVR::~KRTexturePVR() +{ + for (std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { + KRDataBlock* block = *itr; + delete block; + } + m_blocks.clear(); } Vector2i KRTexturePVR::getDimensions() const @@ -151,101 +153,101 @@ Vector2i KRTexturePVR::getDimensions() const long KRTexturePVR::getMemRequiredForSize(int max_dim) { - int target_dim = max_dim; - if(target_dim < (int)m_min_lod_max_dim) target_dim = target_dim; - - // Determine how much memory will be consumed - int width = m_iWidth; - int height = m_iHeight; - long memoryRequired = 0; - - for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { - KRDataBlock *block = *itr; - if(width <= target_dim && height <= target_dim) { - memoryRequired += (long)block->getSize(); - } - - width = width >> 1; - if(width < 1) { - width = 1; - } - height = height >> 1; - if(height < 1) { - height = 1; - } - } - - return memoryRequired; + int target_dim = max_dim; + if (target_dim < (int)m_min_lod_max_dim) target_dim = target_dim; + + // Determine how much memory will be consumed + int width = m_iWidth; + int height = m_iHeight; + long memoryRequired = 0; + + for (std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { + KRDataBlock* block = *itr; + if (width <= target_dim && height <= target_dim) { + memoryRequired += (long)block->getSize(); + } + + width = width >> 1; + if (width < 1) { + width = 1; + } + height = height >> 1; + if (height < 1) { + height = 1; + } + } + + return memoryRequired; } -bool KRTexturePVR::uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int ¤t_lod_max_dim, bool compress, bool premultiply_alpha) -{ - int target_dim = lod_max_dim; - if(target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim; - - if(m_blocks.size() == 0) { - return false; +bool KRTexturePVR::uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int& current_lod_max_dim, bool compress, bool premultiply_alpha) +{ + int target_dim = lod_max_dim; + if (target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim; + + if (m_blocks.size() == 0) { + return false; + } + + // Determine how much memory will be consumed + int width = m_iWidth; + int height = m_iHeight; + long memoryRequired = 0; + long memoryTransferred = 0; + + // Upload texture data + int destination_level = 0; + int source_level = 0; + for (std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { + KRDataBlock* block = *itr; + if (width <= target_dim && height <= target_dim) { + + if (width > current_lod_max_dim) { + current_lod_max_dim = width; + } + if (height > current_lod_max_dim) { + current_lod_max_dim = height; + } + + block->lock(); + /* + * TODO - Vulkan Refactoring + GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, (GLsizei)block->getSize(), block->getStart())); + */ + block->unlock(); + memoryTransferred += (long)block->getSize(); // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE + memoryRequired += (long)block->getSize(); + // + // err = glGetError(); + // if (err != GL_NO_ERROR) { + // assert(false); + // return false; + // } + // + + destination_level++; } - - // Determine how much memory will be consumed - int width = m_iWidth; - int height = m_iHeight; - long memoryRequired = 0; - long memoryTransferred = 0; - - // Upload texture data - int destination_level=0; - int source_level = 0; - for(std::list::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { - KRDataBlock *block = *itr; - if(width <= target_dim && height <= target_dim) { - if(width > current_lod_max_dim) { - current_lod_max_dim = width; - } - if(height > current_lod_max_dim) { - current_lod_max_dim = height; - } + if (width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) { + source_level++; + } + + width = width >> 1; + if (width < 1) { + width = 1; + } + height = height >> 1; + if (height < 1) { + height = 1; + } + } + + return true; - block->lock(); - /* - * TODO - Vulkan Refactoring - GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, (GLsizei)block->getSize(), block->getStart())); - */ - block->unlock(); - memoryTransferred += (long)block->getSize(); // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE - memoryRequired += (long)block->getSize(); -// -// err = glGetError(); -// if (err != GL_NO_ERROR) { -// assert(false); -// return false; -// } -// - - destination_level++; - } - - if(width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) { - source_level++; - } - - width = width >> 1; - if(width < 1) { - width = 1; - } - height = height >> 1; - if(height < 1) { - height = 1; - } - } - - return true; - } std::string KRTexturePVR::getExtension() { - return "pvr"; + return "pvr"; } diff --git a/kraken/KRTexturePVR.h b/kraken/KRTexturePVR.h index f781781..ecf2f0f 100755 --- a/kraken/KRTexturePVR.h +++ b/kraken/KRTexturePVR.h @@ -36,21 +36,21 @@ class KRTexturePVR : public KRTexture2D { public: - KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name); - virtual ~KRTexturePVR(); - virtual std::string getExtension(); - - bool uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int& current_lod_max_dim, bool compress = false, bool premultiply_alpha = false) override; - - virtual long getMemRequiredForSize(int max_dim); - virtual Vector2i getDimensions() const override; - + KRTexturePVR(KRContext& context, KRDataBlock* data, std::string name); + virtual ~KRTexturePVR(); + virtual std::string getExtension(); + + bool uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int& current_lod_max_dim, bool compress = false, bool premultiply_alpha = false) override; + + virtual long getMemRequiredForSize(int max_dim); + virtual Vector2i getDimensions() const override; + protected: - - uint32_t m_iWidth; - uint32_t m_iHeight; - GLenum m_internalFormat; - bool m_bHasAlpha; - - std::list m_blocks; + + uint32_t m_iWidth; + uint32_t m_iHeight; + GLenum m_internalFormat; + bool m_bHasAlpha; + + std::list m_blocks; }; diff --git a/kraken/KRTextureTGA.cpp b/kraken/KRTextureTGA.cpp index fd91dd1..d2c4ed3 100755 --- a/kraken/KRTextureTGA.cpp +++ b/kraken/KRTextureTGA.cpp @@ -35,23 +35,25 @@ #if defined(_WIN32) || defined(_WIN64) #pragma pack(1) -typedef struct { - char idlength; - char colourmaptype; - char imagetype; - short int colourmaporigin; - short int colourmaplength; - char colourmapdepth; - short int x_origin; - short int y_origin; - short width; - short height; - char bitsperpixel; - char imagedescriptor; +typedef struct +{ + char idlength; + char colourmaptype; + char imagetype; + short int colourmaporigin; + short int colourmaplength; + char colourmapdepth; + short int x_origin; + short int y_origin; + short width; + short height; + char bitsperpixel; + char imagedescriptor; } TGA_HEADER; #pragma pack() #else -typedef struct { +typedef struct +{ char idlength; char colourmaptype; char imagetype; @@ -68,346 +70,346 @@ typedef struct { #endif -KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) +KRTextureTGA::KRTextureTGA(KRContext& context, KRDataBlock* data, std::string name) : KRTexture2D(context, data, name) { - data->lock(); - TGA_HEADER *pHeader = (TGA_HEADER *)data->getStart(); - - m_dimensions.x = pHeader->width; - m_dimensions.y = pHeader->height; - m_max_lod_max_dim = pHeader->width > pHeader->height ? pHeader->width : pHeader->height; - m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for TGA images - switch(pHeader->imagetype) { - case 2: // rgb - case 10: // rgb + rle - switch(pHeader->bitsperpixel) { - case 24: - { - m_imageSize = pHeader->width * pHeader->height * 4; - } - break; - case 32: - { - m_imageSize = pHeader->width * pHeader->height * 4; - } - break; - - default: - { - assert(false); - } - break; - } - break; - default: - { - assert(false); - break; - } + data->lock(); + TGA_HEADER* pHeader = (TGA_HEADER*)data->getStart(); + + m_dimensions.x = pHeader->width; + m_dimensions.y = pHeader->height; + m_max_lod_max_dim = pHeader->width > pHeader->height ? pHeader->width : pHeader->height; + m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for TGA images + switch (pHeader->imagetype) { + case 2: // rgb + case 10: // rgb + rle + switch (pHeader->bitsperpixel) { + case 24: + { + m_imageSize = pHeader->width * pHeader->height * 4; } - - data->unlock(); + break; + case 32: + { + m_imageSize = pHeader->width * pHeader->height * 4; + } + break; + + default: + { + assert(false); + } + break; + } + break; + default: + { + assert(false); + break; + } + } + + data->unlock(); } KRTextureTGA::~KRTextureTGA() { - + } -bool KRTextureTGA::uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int ¤t_lod_max_dim, bool compress, bool premultiply_alpha) +bool KRTextureTGA::uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int& current_lod_max_dim, bool compress, bool premultiply_alpha) { - // TODO - Vulkan Refactoring - Perhaps it would be more efficient to reformat the color channels during the copy to the staging buffer. + // TODO - Vulkan Refactoring - Perhaps it would be more efficient to reformat the color channels during the copy to the staging buffer. - m_pData->lock(); - TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart(); - unsigned char *pData = (unsigned char *)pHeader + (long)pHeader->idlength + (long)pHeader->colourmaplength * (long)pHeader->colourmaptype + sizeof(TGA_HEADER); - - /* - * TODO - Vulkan refactoring to support compressing textures on load - GLenum internal_format = GL_RGBA; - if(compress) { - internal_format = pHeader->bitsperpixel == 24 ? GL_COMPRESSED_RGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - } - */ - - if(pHeader->colourmaptype != 0) { - m_pData->unlock(); - return false; // Mapped colors not supported - } + m_pData->lock(); + TGA_HEADER* pHeader = (TGA_HEADER*)m_pData->getStart(); + unsigned char* pData = (unsigned char*)pHeader + (long)pHeader->idlength + (long)pHeader->colourmaplength * (long)pHeader->colourmaptype + sizeof(TGA_HEADER); - Vector2i dimensions = { pHeader->width, pHeader->height }; - - switch(pHeader->imagetype) { - case 2: // rgb - switch(pHeader->bitsperpixel) { - case 24: - { - unsigned char *converted_image = (unsigned char *)malloc(pHeader->width * pHeader->height * 4); - unsigned char *pSource = pData; - unsigned char *pDest = converted_image; - unsigned char *pEnd = pData + pHeader->height * pHeader->width * 3; - while(pSource < pEnd) { - *pDest++ = pSource[2]; - *pDest++ = pSource[1]; - *pDest++ = pSource[0]; - *pDest++ = 0xff; - pSource += 3; - } - assert(pSource <= m_pData->getEnd()); - device.streamUpload((void *)converted_image, pDest - converted_image, dimensions, image); - free(converted_image); - - current_lod_max_dim = m_max_lod_max_dim; - } - break; - case 32: - { - if(premultiply_alpha) { - unsigned char *converted_image = (unsigned char *)malloc(pHeader->width * pHeader->height * 4); - - unsigned char *pSource = pData; - unsigned char *pDest = converted_image; - unsigned char *pEnd = pData + pHeader->height * pHeader->width * 3; - while(pSource < pEnd) { - *pDest++ = (__uint32_t)pSource[2] * (__uint32_t)pSource[3] / 0xff; - *pDest++ = (__uint32_t)pSource[1] * (__uint32_t)pSource[3] / 0xff; - *pDest++ = (__uint32_t)pSource[0] * (__uint32_t)pSource[3] / 0xff; - *pDest++ = pSource[3]; - pSource += 4; - } - assert(pSource <= m_pData->getEnd()); - device.streamUpload((void*)converted_image, pDest - converted_image, dimensions, image); - free(converted_image); - } else { - unsigned char *converted_image = (unsigned char *)malloc(pHeader->width * pHeader->height * 4); - - unsigned char *pSource = pData; - unsigned char *pDest = converted_image; - unsigned char *pEnd = pData + pHeader->height * pHeader->width * 3; - while(pSource < pEnd) { - *pDest++ = (__uint32_t)pSource[2]; - *pDest++ = (__uint32_t)pSource[1]; - *pDest++ = (__uint32_t)pSource[0]; - *pDest++ = pSource[3]; - pSource += 4; - } - assert(pSource <= m_pData->getEnd()); - device.streamUpload((void*)converted_image, pDest - converted_image, dimensions, image); - free(converted_image); - } - - current_lod_max_dim = m_max_lod_max_dim; - } - break; - default: - m_pData->unlock(); - return false; // 16-bit images not yet supported - } - break; - case 10: // rgb + rle - switch(pHeader->bitsperpixel) { - case 32: - { - unsigned char *converted_image = (unsigned char *)malloc(pHeader->width * pHeader->height * 4); - unsigned char *pSource = pData; - unsigned char *pDest = converted_image; - unsigned char *pEnd = converted_image + pHeader->height * pHeader->width * 4; - if(premultiply_alpha) { - while(pDest < pEnd) { - int count = (*pSource & 0x7f) + 1; - if(*pSource & 0x80) { - // RLE Packet - pSource++; - while(count--) { - *pDest++ = (__uint32_t)pSource[2] * (__uint32_t)pSource[3] / 0xff; - *pDest++ = (__uint32_t)pSource[1] * (__uint32_t)pSource[3] / 0xff; - *pDest++ = (__uint32_t)pSource[0] * (__uint32_t)pSource[3] / 0xff; - *pDest++ = pSource[3]; - } - pSource += 4; - } else { - // RAW Packet - pSource++; - while(count--) { - *pDest++ = (__uint32_t)pSource[2] * (__uint32_t)pSource[3] / 0xff; - *pDest++ = (__uint32_t)pSource[1] * (__uint32_t)pSource[3] / 0xff; - *pDest++ = (__uint32_t)pSource[0] * (__uint32_t)pSource[3] / 0xff; - *pDest++ = pSource[3]; - pSource += 4; - } - } - } - assert(pSource <= m_pData->getEnd()); - assert(pDest == pEnd); - } else { - while(pDest < pEnd) { - int count = (*pSource & 0x7f) + 1; - if(*pSource & 0x80) { - // RLE Packet - pSource++; - while(count--) { - *pDest++ = pSource[2]; - *pDest++ = pSource[1]; - *pDest++ = pSource[0]; - *pDest++ = pSource[3]; - } - pSource += 4; - } else { - // RAW Packet - pSource++; - while(count--) { - *pDest++ = pSource[2]; - *pDest++ = pSource[1]; - *pDest++ = pSource[0]; - *pDest++ = pSource[3]; - pSource += 4; - } - } - } - assert(pSource <= m_pData->getEnd()); - assert(pDest == pEnd); - } - device.streamUpload((void*)converted_image, pDest - converted_image, dimensions, image); - free(converted_image); - current_lod_max_dim = m_max_lod_max_dim; - } - break; - case 24: - { - unsigned char *converted_image = (unsigned char *)malloc(pHeader->width * pHeader->height * 4); - unsigned char *pSource = pData; - unsigned char *pDest = converted_image; - unsigned char *pEnd = converted_image + pHeader->height * pHeader->width * 4; - while(pDest < pEnd) { - int count = (*pSource & 0x7f) + 1; - if(*pSource & 0x80) { - // RLE Packet - pSource++; - while(count--) { - *pDest++ = pSource[2]; - *pDest++ = pSource[1]; - *pDest++ = pSource[0]; - *pDest++ = 0xff; - } - pSource += 3; - } else { - // RAW Packet - pSource++; - while(count--) { - *pDest++ = pSource[2]; - *pDest++ = pSource[1]; - *pDest++ = pSource[0]; - *pDest++ = 0xff; - pSource += 3; - } - } - } - assert(pSource <= m_pData->getEnd()); - assert(pDest == pEnd); - device.streamUpload((void*)converted_image, pDest - converted_image, dimensions, image); - free(converted_image); - current_lod_max_dim = m_max_lod_max_dim; - } - break; - default: - m_pData->unlock(); - return false; // 16-bit images not yet supported - } - break; - default: - m_pData->unlock(); - return false; // Image type not yet supported - } + /* + * TODO - Vulkan refactoring to support compressing textures on load + GLenum internal_format = GL_RGBA; + if(compress) { + internal_format = pHeader->bitsperpixel == 24 ? GL_COMPRESSED_RGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + } + */ + if (pHeader->colourmaptype != 0) { m_pData->unlock(); - return true; + return false; // Mapped colors not supported + } + + Vector2i dimensions = { pHeader->width, pHeader->height }; + + switch (pHeader->imagetype) { + case 2: // rgb + switch (pHeader->bitsperpixel) { + case 24: + { + unsigned char* converted_image = (unsigned char*)malloc(pHeader->width * pHeader->height * 4); + unsigned char* pSource = pData; + unsigned char* pDest = converted_image; + unsigned char* pEnd = pData + pHeader->height * pHeader->width * 3; + while (pSource < pEnd) { + *pDest++ = pSource[2]; + *pDest++ = pSource[1]; + *pDest++ = pSource[0]; + *pDest++ = 0xff; + pSource += 3; + } + assert(pSource <= m_pData->getEnd()); + device.streamUpload((void*)converted_image, pDest - converted_image, dimensions, image); + free(converted_image); + + current_lod_max_dim = m_max_lod_max_dim; + } + break; + case 32: + { + if (premultiply_alpha) { + unsigned char* converted_image = (unsigned char*)malloc(pHeader->width * pHeader->height * 4); + + unsigned char* pSource = pData; + unsigned char* pDest = converted_image; + unsigned char* pEnd = pData + pHeader->height * pHeader->width * 3; + while (pSource < pEnd) { + *pDest++ = (__uint32_t)pSource[2] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[1] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[0] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = pSource[3]; + pSource += 4; + } + assert(pSource <= m_pData->getEnd()); + device.streamUpload((void*)converted_image, pDest - converted_image, dimensions, image); + free(converted_image); + } else { + unsigned char* converted_image = (unsigned char*)malloc(pHeader->width * pHeader->height * 4); + + unsigned char* pSource = pData; + unsigned char* pDest = converted_image; + unsigned char* pEnd = pData + pHeader->height * pHeader->width * 3; + while (pSource < pEnd) { + *pDest++ = (__uint32_t)pSource[2]; + *pDest++ = (__uint32_t)pSource[1]; + *pDest++ = (__uint32_t)pSource[0]; + *pDest++ = pSource[3]; + pSource += 4; + } + assert(pSource <= m_pData->getEnd()); + device.streamUpload((void*)converted_image, pDest - converted_image, dimensions, image); + free(converted_image); + } + + current_lod_max_dim = m_max_lod_max_dim; + } + break; + default: + m_pData->unlock(); + return false; // 16-bit images not yet supported + } + break; + case 10: // rgb + rle + switch (pHeader->bitsperpixel) { + case 32: + { + unsigned char* converted_image = (unsigned char*)malloc(pHeader->width * pHeader->height * 4); + unsigned char* pSource = pData; + unsigned char* pDest = converted_image; + unsigned char* pEnd = converted_image + pHeader->height * pHeader->width * 4; + if (premultiply_alpha) { + while (pDest < pEnd) { + int count = (*pSource & 0x7f) + 1; + if (*pSource & 0x80) { + // RLE Packet + pSource++; + while (count--) { + *pDest++ = (__uint32_t)pSource[2] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[1] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[0] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = pSource[3]; + } + pSource += 4; + } else { + // RAW Packet + pSource++; + while (count--) { + *pDest++ = (__uint32_t)pSource[2] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[1] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[0] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = pSource[3]; + pSource += 4; + } + } + } + assert(pSource <= m_pData->getEnd()); + assert(pDest == pEnd); + } else { + while (pDest < pEnd) { + int count = (*pSource & 0x7f) + 1; + if (*pSource & 0x80) { + // RLE Packet + pSource++; + while (count--) { + *pDest++ = pSource[2]; + *pDest++ = pSource[1]; + *pDest++ = pSource[0]; + *pDest++ = pSource[3]; + } + pSource += 4; + } else { + // RAW Packet + pSource++; + while (count--) { + *pDest++ = pSource[2]; + *pDest++ = pSource[1]; + *pDest++ = pSource[0]; + *pDest++ = pSource[3]; + pSource += 4; + } + } + } + assert(pSource <= m_pData->getEnd()); + assert(pDest == pEnd); + } + device.streamUpload((void*)converted_image, pDest - converted_image, dimensions, image); + free(converted_image); + current_lod_max_dim = m_max_lod_max_dim; + } + break; + case 24: + { + unsigned char* converted_image = (unsigned char*)malloc(pHeader->width * pHeader->height * 4); + unsigned char* pSource = pData; + unsigned char* pDest = converted_image; + unsigned char* pEnd = converted_image + pHeader->height * pHeader->width * 4; + while (pDest < pEnd) { + int count = (*pSource & 0x7f) + 1; + if (*pSource & 0x80) { + // RLE Packet + pSource++; + while (count--) { + *pDest++ = pSource[2]; + *pDest++ = pSource[1]; + *pDest++ = pSource[0]; + *pDest++ = 0xff; + } + pSource += 3; + } else { + // RAW Packet + pSource++; + while (count--) { + *pDest++ = pSource[2]; + *pDest++ = pSource[1]; + *pDest++ = pSource[0]; + *pDest++ = 0xff; + pSource += 3; + } + } + } + assert(pSource <= m_pData->getEnd()); + assert(pDest == pEnd); + device.streamUpload((void*)converted_image, pDest - converted_image, dimensions, image); + free(converted_image); + current_lod_max_dim = m_max_lod_max_dim; + } + break; + default: + m_pData->unlock(); + return false; // 16-bit images not yet supported + } + break; + default: + m_pData->unlock(); + return false; // Image type not yet supported + } + + m_pData->unlock(); + return true; } #if !TARGET_OS_IPHONE && !defined(ANDROID) -KRTexture *KRTextureTGA::compress(bool premultiply_alpha) +KRTexture* KRTextureTGA::compress(bool premultiply_alpha) { - // TODO - Vulkan refactoring... - assert(false); - return nullptr; - /* - * TODO - Vulkan refactoring... + // TODO - Vulkan refactoring... + assert(false); + return nullptr; + /* + * TODO - Vulkan refactoring... - m_pData->lock(); - - std::list blocks; - - getContext().getTextureManager()->_setActiveTexture(0); - - GLuint compressed_handle = 0; - GLDEBUG(glGenTextures(1, &compressed_handle)); - - GLDEBUG(glBindTexture(GL_TEXTURE_2D, compressed_handle)); - - int current_max_dim = 0; - if(!uploadTexture(m_max_lod_max_dim, current_max_dim, true, premultiply_alpha)) { - assert(false); // Failed to upload the texture - } - GLDEBUG(glGenerateMipmap(GL_TEXTURE_2D)); - - GLint width = 0, height = 0, internal_format, base_internal_format; + m_pData->lock(); + + std::list blocks; + + getContext().getTextureManager()->_setActiveTexture(0); + + GLuint compressed_handle = 0; + GLDEBUG(glGenTextures(1, &compressed_handle)); + + GLDEBUG(glBindTexture(GL_TEXTURE_2D, compressed_handle)); + + int current_max_dim = 0; + if(!uploadTexture(m_max_lod_max_dim, current_max_dim, true, premultiply_alpha)) { + assert(false); // Failed to upload the texture + } + GLDEBUG(glGenerateMipmap(GL_TEXTURE_2D)); + + GLint width = 0, height = 0, internal_format, base_internal_format; - GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width)); - GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height)); - GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format)); - - switch(internal_format) - { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - base_internal_format = GL_BGRA; - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - base_internal_format = GL_BGRA; - break; - default: - assert(false); // Not yet supported - break; - } - - GLuint lod_level = 0; - GLint compressed_size = 0; - int lod_width = width; - while(lod_width > 1) { - GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, lod_level, GL_TEXTURE_WIDTH, &lod_width)); - GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, lod_level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed_size)); - KRDataBlock *new_block = new KRDataBlock(); - new_block->expand(compressed_size); - new_block->lock(); - GLDEBUG(glGetCompressedTexImage(GL_TEXTURE_2D, lod_level, new_block->getStart())); - new_block->unlock(); - blocks.push_back(new_block); - - lod_level++; - } - assert(lod_width == 1); - - GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); - getContext().getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - GLDEBUG(glDeleteTextures(1, &compressed_handle)); - - KRTextureKTX *new_texture = new KRTextureKTX(getContext(), getName(), internal_format, base_internal_format, width, height, blocks); - - m_pData->unlock(); - - for(auto block_itr = blocks.begin(); block_itr != blocks.end(); block_itr++) { - KRDataBlock *block = *block_itr; - delete block; - } - - return new_texture; - */ + GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width)); + GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height)); + GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format)); + + switch(internal_format) + { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + base_internal_format = GL_BGRA; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + base_internal_format = GL_BGRA; + break; + default: + assert(false); // Not yet supported + break; + } + + GLuint lod_level = 0; + GLint compressed_size = 0; + int lod_width = width; + while(lod_width > 1) { + GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, lod_level, GL_TEXTURE_WIDTH, &lod_width)); + GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, lod_level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed_size)); + KRDataBlock *new_block = new KRDataBlock(); + new_block->expand(compressed_size); + new_block->lock(); + GLDEBUG(glGetCompressedTexImage(GL_TEXTURE_2D, lod_level, new_block->getStart())); + new_block->unlock(); + blocks.push_back(new_block); + + lod_level++; + } + assert(lod_width == 1); + + GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); + getContext().getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); + GLDEBUG(glDeleteTextures(1, &compressed_handle)); + + KRTextureKTX *new_texture = new KRTextureKTX(getContext(), getName(), internal_format, base_internal_format, width, height, blocks); + + m_pData->unlock(); + + for(auto block_itr = blocks.begin(); block_itr != blocks.end(); block_itr++) { + KRDataBlock *block = *block_itr; + delete block; + } + + return new_texture; + */ } #endif long KRTextureTGA::getMemRequiredForSize(int max_dim) { - return m_imageSize; + return m_imageSize; } Vector2i KRTextureTGA::getDimensions() const @@ -417,5 +419,5 @@ Vector2i KRTextureTGA::getDimensions() const std::string KRTextureTGA::getExtension() { - return "tga"; + return "tga"; } diff --git a/kraken/KRTextureTGA.h b/kraken/KRTextureTGA.h index d692984..def7891 100755 --- a/kraken/KRTextureTGA.h +++ b/kraken/KRTextureTGA.h @@ -36,19 +36,19 @@ class KRTextureTGA : public KRTexture2D { public: - KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name); - virtual ~KRTextureTGA(); - virtual std::string getExtension(); - - bool uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int& current_lod_max_dim, bool compress = false, bool premultiply_alpha = false) override; - + KRTextureTGA(KRContext& context, KRDataBlock* data, std::string name); + virtual ~KRTextureTGA(); + virtual std::string getExtension(); + + bool uploadTexture(KRDevice& device, VkImage& image, int lod_max_dim, int& current_lod_max_dim, bool compress = false, bool premultiply_alpha = false) override; + #if !TARGET_OS_IPHONE && !defined(ANDROID) - virtual KRTexture *compress(bool premultiply_alpha = false); + virtual KRTexture* compress(bool premultiply_alpha = false); #endif - - virtual long getMemRequiredForSize(int max_dim); - virtual Vector2i getDimensions() const override; + + virtual long getMemRequiredForSize(int max_dim); + virtual Vector2i getDimensions() const override; private: - long m_imageSize; - Vector2i m_dimensions; + long m_imageSize; + Vector2i m_dimensions; }; diff --git a/kraken/KRUnknown.cpp b/kraken/KRUnknown.cpp index af95f02..2441208 100755 --- a/kraken/KRUnknown.cpp +++ b/kraken/KRUnknown.cpp @@ -31,35 +31,35 @@ #include "KRUnknown.h" -KRUnknown::KRUnknown(KRContext &context, std::string name, std::string extension) : KRResource(context, name) +KRUnknown::KRUnknown(KRContext& context, std::string name, std::string extension) : KRResource(context, name) { - m_pData = new KRDataBlock(); - m_extension = extension; + m_pData = new KRDataBlock(); + m_extension = extension; } -KRUnknown::KRUnknown(KRContext &context, std::string name, std::string extension, KRDataBlock *data) : KRResource(context, name) +KRUnknown::KRUnknown(KRContext& context, std::string name, std::string extension, KRDataBlock* data) : KRResource(context, name) { - m_pData = data; - m_extension = extension; + m_pData = data; + m_extension = extension; } KRUnknown::~KRUnknown() { - delete m_pData; + delete m_pData; } std::string KRUnknown::getExtension() { - return m_extension; + return m_extension; } -bool KRUnknown::save(KRDataBlock &data) +bool KRUnknown::save(KRDataBlock& data) { - data.append(*m_pData); - return true; + data.append(*m_pData); + return true; } -KRDataBlock *KRUnknown::getData() +KRDataBlock* KRUnknown::getData() { - return m_pData; + return m_pData; } diff --git a/kraken/KRUnknown.h b/kraken/KRUnknown.h index 1f477b9..ba21a7d 100755 --- a/kraken/KRUnknown.h +++ b/kraken/KRUnknown.h @@ -36,21 +36,22 @@ #include "KRDataBlock.h" #include "KRResource.h" -class KRUnknown : public KRResource { - +class KRUnknown : public KRResource +{ + public: - KRUnknown(KRContext &context, std::string name, std::string extension); - KRUnknown(KRContext &context, std::string name, std::string extension, KRDataBlock *data); - virtual ~KRUnknown(); - - virtual std::string getExtension(); - - virtual bool save(KRDataBlock &data); - - KRDataBlock *getData(); + KRUnknown(KRContext& context, std::string name, std::string extension); + KRUnknown(KRContext& context, std::string name, std::string extension, KRDataBlock* data); + virtual ~KRUnknown(); + + virtual std::string getExtension(); + + virtual bool save(KRDataBlock& data); + + KRDataBlock* getData(); private: - - std::string m_extension; - KRDataBlock *m_pData; + + std::string m_extension; + KRDataBlock* m_pData; }; diff --git a/kraken/KRUnknownManager.cpp b/kraken/KRUnknownManager.cpp index c6b2678..fc8a0ba 100755 --- a/kraken/KRUnknownManager.cpp +++ b/kraken/KRUnknownManager.cpp @@ -32,46 +32,46 @@ #include "KRUnknownManager.h" #include "KREngine-common.h" -KRUnknownManager::KRUnknownManager(KRContext &context) : KRResourceManager(context) +KRUnknownManager::KRUnknownManager(KRContext& context) : KRResourceManager(context) { - + } KRUnknownManager::~KRUnknownManager() { - for(unordered_map >::iterator extension_itr = m_unknowns.begin(); extension_itr != m_unknowns.end(); extension_itr++) { - for(unordered_map::iterator name_itr=(*extension_itr).second.begin(); name_itr != (*extension_itr).second.end(); name_itr++) { - delete (*name_itr).second; - } + for (unordered_map >::iterator extension_itr = m_unknowns.begin(); extension_itr != m_unknowns.end(); extension_itr++) { + for (unordered_map::iterator name_itr = (*extension_itr).second.begin(); name_itr != (*extension_itr).second.end(); name_itr++) { + delete (*name_itr).second; } + } } -unordered_map > &KRUnknownManager::getUnknowns() +unordered_map >& KRUnknownManager::getUnknowns() { - return m_unknowns; + return m_unknowns; } -void KRUnknownManager::add(KRUnknown *unknown) +void KRUnknownManager::add(KRUnknown* unknown) { - std::string lower_name = unknown->getName(); - std::string lower_extension = unknown->getExtension(); - - std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); - std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); - - unordered_map >::iterator extension_itr = m_unknowns.find(lower_extension); - if(extension_itr == m_unknowns.end()) { - m_unknowns[lower_extension] = unordered_map(); - extension_itr = m_unknowns.find(lower_extension); - } - - unordered_map::iterator name_itr = (*extension_itr).second.find(lower_name); - if(name_itr != (*extension_itr).second.end()) { - delete (*name_itr).second; - (*name_itr).second = unknown; - } else { - (*extension_itr).second[lower_name] = unknown; - } + std::string lower_name = unknown->getName(); + std::string lower_extension = unknown->getExtension(); + + std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); + std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); + + unordered_map >::iterator extension_itr = m_unknowns.find(lower_extension); + if (extension_itr == m_unknowns.end()) { + m_unknowns[lower_extension] = unordered_map(); + extension_itr = m_unknowns.find(lower_extension); + } + + unordered_map::iterator name_itr = (*extension_itr).second.find(lower_name); + if (name_itr != (*extension_itr).second.end()) { + delete (*name_itr).second; + (*name_itr).second = unknown; + } else { + (*extension_itr).second[lower_name] = unknown; + } } @@ -87,29 +87,29 @@ KRResource* KRUnknownManager::getResource(const std::string& name, const std::st return get(name, extension); } -KRUnknown *KRUnknownManager::load(const std::string &name, const std::string &extension, KRDataBlock *data) +KRUnknown* KRUnknownManager::load(const std::string& name, const std::string& extension, KRDataBlock* data) { - KRUnknown *unknown = new KRUnknown(getContext(), name, extension, data); - if(unknown) add(unknown); - return unknown; + KRUnknown* unknown = new KRUnknown(getContext(), name, extension, data); + if (unknown) add(unknown); + return unknown; } -KRUnknown *KRUnknownManager::get(const std::string &name, const std::string &extension) +KRUnknown* KRUnknownManager::get(const std::string& name, const std::string& extension) { - std::string lower_name = name; - std::string lower_extension = extension; - - std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); - std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); - - return m_unknowns[lower_extension][lower_name]; + std::string lower_name = name; + std::string lower_extension = extension; + + std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); + std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); + + return m_unknowns[lower_extension][lower_name]; } -const unordered_map &KRUnknownManager::get(const std::string &extension) +const unordered_map& KRUnknownManager::get(const std::string& extension) { - std::string lower_extension = extension; - std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); - return m_unknowns[lower_extension]; + std::string lower_extension = extension; + std::transform(lower_extension.begin(), lower_extension.end(), lower_extension.begin(), ::tolower); + return m_unknowns[lower_extension]; } diff --git a/kraken/KRUnknownManager.h b/kraken/KRUnknownManager.h index d6589fa..b81c53f 100755 --- a/kraken/KRUnknownManager.h +++ b/kraken/KRUnknownManager.h @@ -39,24 +39,25 @@ #include "KRContextObject.h" #include "KRDataBlock.h" -class KRUnknownManager : public KRResourceManager { +class KRUnknownManager : public KRResourceManager +{ public: - KRUnknownManager(KRContext &context); - virtual ~KRUnknownManager(); + KRUnknownManager(KRContext& context); + virtual ~KRUnknownManager(); - virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; - virtual KRResource* getResource(const std::string& name, const std::string& extension) override; - - void add(KRUnknown *unknown); - - KRUnknown *load(const std::string &name, const std::string &extension, KRDataBlock *data); - KRUnknown *get(const std::string &name, const std::string &extension); - + virtual KRResource* loadResource(const std::string& name, const std::string& extension, KRDataBlock* data) override; + virtual KRResource* getResource(const std::string& name, const std::string& extension) override; + + void add(KRUnknown* unknown); + + KRUnknown* load(const std::string& name, const std::string& extension, KRDataBlock* data); + KRUnknown* get(const std::string& name, const std::string& extension); + + + const unordered_map& get(const std::string& extension); + + unordered_map >& getUnknowns(); - const unordered_map &get(const std::string &extension); - - unordered_map > &getUnknowns(); - private: - unordered_map > m_unknowns; + unordered_map > m_unknowns; }; diff --git a/kraken/KRViewport.cpp b/kraken/KRViewport.cpp index 74b6f13..e8a5e11 100755 --- a/kraken/KRViewport.cpp +++ b/kraken/KRViewport.cpp @@ -36,248 +36,249 @@ KRViewport::KRViewport() { - m_size = Vector2::One(); - m_matProjection = Matrix4(); - m_matView = Matrix4(); - m_lodBias = 0.0f; - calculateDerivedValues(); + m_size = Vector2::One(); + m_matProjection = Matrix4(); + m_matView = Matrix4(); + m_lodBias = 0.0f; + calculateDerivedValues(); } -KRViewport::KRViewport(const Vector2 &size, const Matrix4 &matView, const Matrix4 &matProjection) +KRViewport::KRViewport(const Vector2& size, const Matrix4& matView, const Matrix4& matProjection) { - m_size = size; - m_matView = matView; - m_matProjection = matProjection; - calculateDerivedValues(); + m_size = size; + m_matView = matView; + m_matProjection = matProjection; + calculateDerivedValues(); } -KRViewport& KRViewport::operator=(const KRViewport &v) { - if(this != &v) { // Prevent self-assignment. - m_size = v.m_size; - m_matProjection = v.m_matProjection; - m_matView = v.m_matView; - m_lodBias = v.m_lodBias; - - calculateDerivedValues(); - } - return *this; +KRViewport& KRViewport::operator=(const KRViewport& v) +{ + if (this != &v) { // Prevent self-assignment. + m_size = v.m_size; + m_matProjection = v.m_matProjection; + m_matView = v.m_matView; + m_lodBias = v.m_lodBias; + + calculateDerivedValues(); + } + return *this; } KRViewport::~KRViewport() { - + } -const Vector2 &KRViewport::getSize() const +const Vector2& KRViewport::getSize() const { - return m_size; + return m_size; } -const Matrix4 &KRViewport::getViewMatrix() const +const Matrix4& KRViewport::getViewMatrix() const { - return m_matView; + return m_matView; } -const Matrix4 &KRViewport::getProjectionMatrix() const +const Matrix4& KRViewport::getProjectionMatrix() const { - return m_matProjection; + return m_matProjection; } -void KRViewport::setSize(const Vector2 &size) +void KRViewport::setSize(const Vector2& size) { - m_size = size; + m_size = size; } -void KRViewport::setViewMatrix(const Matrix4 &matView) +void KRViewport::setViewMatrix(const Matrix4& matView) { - m_matView = matView; - calculateDerivedValues(); + m_matView = matView; + calculateDerivedValues(); } -void KRViewport::setProjectionMatrix(const Matrix4 &matProjection) +void KRViewport::setProjectionMatrix(const Matrix4& matProjection) { - m_matProjection = matProjection; - calculateDerivedValues(); + m_matProjection = matProjection; + calculateDerivedValues(); } -const Matrix4 &KRViewport::KRViewport::getViewProjectionMatrix() const +const Matrix4& KRViewport::KRViewport::getViewProjectionMatrix() const { - return m_matViewProjection; + return m_matViewProjection; } -const Matrix4 &KRViewport::getInverseViewMatrix() const +const Matrix4& KRViewport::getInverseViewMatrix() const { - return m_matInverseView; + return m_matInverseView; } -const Matrix4 &KRViewport::getInverseProjectionMatrix() const +const Matrix4& KRViewport::getInverseProjectionMatrix() const { - return m_matInverseProjection; + return m_matInverseProjection; } -const Vector3 &KRViewport::getCameraDirection() const +const Vector3& KRViewport::getCameraDirection() const { - return m_cameraDirection; + return m_cameraDirection; } -const Vector3 &KRViewport::getCameraPosition() const +const Vector3& KRViewport::getCameraPosition() const { - return m_cameraPosition; + return m_cameraPosition; } -const int *KRViewport::getFrontToBackOrder() const +const int* KRViewport::getFrontToBackOrder() const { - return &m_frontToBackOrder[0]; + return &m_frontToBackOrder[0]; } -const int *KRViewport::getBackToFrontOrder() const +const int* KRViewport::getBackToFrontOrder() const { - return &m_backToFrontOrder[0]; + return &m_backToFrontOrder[0]; } void KRViewport::calculateDerivedValues() { - m_matViewProjection = m_matView * m_matProjection; - m_matInverseView = Matrix4::Invert(m_matView); - m_matInverseProjection = Matrix4::Invert(m_matProjection); - m_cameraPosition = Matrix4::Dot(m_matInverseView, Vector3::Zero()); - m_cameraDirection = Matrix4::Dot(m_matInverseView, Vector3::Create(0.0, 0.0, 1.0)) - Matrix4::Dot(m_matInverseView, Vector3::Create(0.0, 0.0, 0.0)); + m_matViewProjection = m_matView * m_matProjection; + m_matInverseView = Matrix4::Invert(m_matView); + m_matInverseProjection = Matrix4::Invert(m_matProjection); + m_cameraPosition = Matrix4::Dot(m_matInverseView, Vector3::Zero()); + m_cameraDirection = Matrix4::Dot(m_matInverseView, Vector3::Create(0.0, 0.0, 1.0)) - Matrix4::Dot(m_matInverseView, Vector3::Create(0.0, 0.0, 0.0)); - for(int i=0; i<8; i++) { - m_frontToBackOrder[i] = i; - } - - if(m_cameraDirection.x > 0.0) { - KRENGINE_SWAP_INT(m_frontToBackOrder[0], m_frontToBackOrder[1]); - KRENGINE_SWAP_INT(m_frontToBackOrder[2], m_frontToBackOrder[3]); - KRENGINE_SWAP_INT(m_frontToBackOrder[4], m_frontToBackOrder[5]); - KRENGINE_SWAP_INT(m_frontToBackOrder[6], m_frontToBackOrder[7]); - } - - if(m_cameraDirection.y > 0.0) { - KRENGINE_SWAP_INT(m_frontToBackOrder[0], m_frontToBackOrder[2]); - KRENGINE_SWAP_INT(m_frontToBackOrder[1], m_frontToBackOrder[3]); - KRENGINE_SWAP_INT(m_frontToBackOrder[4], m_frontToBackOrder[6]); - KRENGINE_SWAP_INT(m_frontToBackOrder[5], m_frontToBackOrder[7]); - } - - if(m_cameraDirection.z > 0.0) { - KRENGINE_SWAP_INT(m_frontToBackOrder[0], m_frontToBackOrder[4]); - KRENGINE_SWAP_INT(m_frontToBackOrder[1], m_frontToBackOrder[5]); - KRENGINE_SWAP_INT(m_frontToBackOrder[2], m_frontToBackOrder[6]); - KRENGINE_SWAP_INT(m_frontToBackOrder[3], m_frontToBackOrder[7]); - } - - for(int i=0; i<8; i++) { - m_backToFrontOrder[i] = m_frontToBackOrder[7-i]; - } + for (int i = 0; i < 8; i++) { + m_frontToBackOrder[i] = i; + } + + if (m_cameraDirection.x > 0.0) { + KRENGINE_SWAP_INT(m_frontToBackOrder[0], m_frontToBackOrder[1]); + KRENGINE_SWAP_INT(m_frontToBackOrder[2], m_frontToBackOrder[3]); + KRENGINE_SWAP_INT(m_frontToBackOrder[4], m_frontToBackOrder[5]); + KRENGINE_SWAP_INT(m_frontToBackOrder[6], m_frontToBackOrder[7]); + } + + if (m_cameraDirection.y > 0.0) { + KRENGINE_SWAP_INT(m_frontToBackOrder[0], m_frontToBackOrder[2]); + KRENGINE_SWAP_INT(m_frontToBackOrder[1], m_frontToBackOrder[3]); + KRENGINE_SWAP_INT(m_frontToBackOrder[4], m_frontToBackOrder[6]); + KRENGINE_SWAP_INT(m_frontToBackOrder[5], m_frontToBackOrder[7]); + } + + if (m_cameraDirection.z > 0.0) { + KRENGINE_SWAP_INT(m_frontToBackOrder[0], m_frontToBackOrder[4]); + KRENGINE_SWAP_INT(m_frontToBackOrder[1], m_frontToBackOrder[5]); + KRENGINE_SWAP_INT(m_frontToBackOrder[2], m_frontToBackOrder[6]); + KRENGINE_SWAP_INT(m_frontToBackOrder[3], m_frontToBackOrder[7]); + } + + for (int i = 0; i < 8; i++) { + m_backToFrontOrder[i] = m_frontToBackOrder[7 - i]; + } } -unordered_map &KRViewport::getVisibleBounds() +unordered_map& KRViewport::getVisibleBounds() { - return m_visibleBounds; + return m_visibleBounds; } float KRViewport::getLODBias() const { - return m_lodBias; + return m_lodBias; } void KRViewport::setLODBias(float lod_bias) { - m_lodBias = lod_bias; + m_lodBias = lod_bias; } -float KRViewport::coverage(const AABB &b) const +float KRViewport::coverage(const AABB& b) const { - if(!visible(b)) { - return 0.0f; // Culled out by view frustrum - } else { - Vector3 nearest_point = b.nearestPoint(getCameraPosition()); - float distance = (nearest_point - getCameraPosition()).magnitude(); - - Vector3 v = Matrix4::DotWDiv(m_matProjection, getCameraPosition() + getCameraDirection() * distance); - - float screen_depth = distance / 1000.0f; - - return KRCLAMP(1.0f - screen_depth, 0.01f, 1.0f); - - /* - - Vector2 screen_min; - Vector2 screen_max; - // Loop through all corners and transform them to screen space - for(int i=0; i<8; i++) { - Vector3 screen_pos = Matrix4::DotWDiv(m_matViewProjection, Vector3(i & 1 ? b.min.x : b.max.x, i & 2 ? b.min.y : b.max.y, i & 4 ? b.min.z : b.max.z)); - if(i==0) { - screen_min = screen_pos.xy(); - screen_max = screen_pos.xy(); - } else { - if(screen_pos.x < screen_min.x) screen_min.x = screen_pos.x; - if(screen_pos.y < screen_min.y) screen_min.y = screen_pos.y; - if(screen_pos.x > screen_max.x) screen_max.x = screen_pos.x; - if(screen_pos.y > screen_max.y) screen_max.y = screen_pos.y; - } + if (!visible(b)) { + return 0.0f; // Culled out by view frustrum + } else { + Vector3 nearest_point = b.nearestPoint(getCameraPosition()); + float distance = (nearest_point - getCameraPosition()).magnitude(); + + Vector3 v = Matrix4::DotWDiv(m_matProjection, getCameraPosition() + getCameraDirection() * distance); + + float screen_depth = distance / 1000.0f; + + return KRCLAMP(1.0f - screen_depth, 0.01f, 1.0f); + + /* + + Vector2 screen_min; + Vector2 screen_max; + // Loop through all corners and transform them to screen space + for(int i=0; i<8; i++) { + Vector3 screen_pos = Matrix4::DotWDiv(m_matViewProjection, Vector3(i & 1 ? b.min.x : b.max.x, i & 2 ? b.min.y : b.max.y, i & 4 ? b.min.z : b.max.z)); + if(i==0) { + screen_min = screen_pos.xy(); + screen_max = screen_pos.xy(); + } else { + if(screen_pos.x < screen_min.x) screen_min.x = screen_pos.x; + if(screen_pos.y < screen_min.y) screen_min.y = screen_pos.y; + if(screen_pos.x > screen_max.x) screen_max.x = screen_pos.x; + if(screen_pos.y > screen_max.y) screen_max.y = screen_pos.y; } - - screen_min.x = KRCLAMP(screen_min.x, 0.0f, 1.0f); - screen_min.y = KRCLAMP(screen_min.y, 0.0f, 1.0f); - screen_max.x = KRCLAMP(screen_max.x, 0.0f, 1.0f); - screen_max.y = KRCLAMP(screen_max.y, 0.0f, 1.0f); - - float c = (screen_max.x - screen_min.x) * (screen_max.y - screen_min.y); - return KRCLAMP(c, 0.01f, 1.0f); - */ } + + screen_min.x = KRCLAMP(screen_min.x, 0.0f, 1.0f); + screen_min.y = KRCLAMP(screen_min.y, 0.0f, 1.0f); + screen_max.x = KRCLAMP(screen_max.x, 0.0f, 1.0f); + screen_max.y = KRCLAMP(screen_max.y, 0.0f, 1.0f); + + float c = (screen_max.x - screen_min.x) * (screen_max.y - screen_min.y); + return KRCLAMP(c, 0.01f, 1.0f); + */ + } } -bool KRViewport::visible(const AABB &b) const +bool KRViewport::visible(const AABB& b) const { - // test if bounding box would be within the visible range of the clip space transformed by matViewProjection - // This is used for view frustrum culling - - int outside_count[6] = {0, 0, 0, 0, 0, 0}; - - for(int iCorner=0; iCorner<8; iCorner++) { - Vector4 sourceCornerVertex = Vector4::Create( - (iCorner & 1) == 0 ? b.min.x : b.max.x, - (iCorner & 2) == 0 ? b.min.y : b.max.y, - (iCorner & 4) == 0 ? b.min.z : b.max.z, 1.0f); - - Vector4 cornerVertex = Matrix4::Dot4(m_matViewProjection, sourceCornerVertex); - - if(cornerVertex.x < -cornerVertex.w) { - outside_count[0]++; - } - if(cornerVertex.y < -cornerVertex.w) { - outside_count[1]++; - } - if(cornerVertex.z < -cornerVertex.w) { - outside_count[2]++; - } - if(cornerVertex.x > cornerVertex.w) { - outside_count[3]++; - } - if(cornerVertex.y > cornerVertex.w) { - outside_count[4]++; - } - if(cornerVertex.z > cornerVertex.w) { - outside_count[5]++; - } + // test if bounding box would be within the visible range of the clip space transformed by matViewProjection + // This is used for view frustrum culling + + int outside_count[6] = { 0, 0, 0, 0, 0, 0 }; + + for (int iCorner = 0; iCorner < 8; iCorner++) { + Vector4 sourceCornerVertex = Vector4::Create( + (iCorner & 1) == 0 ? b.min.x : b.max.x, + (iCorner & 2) == 0 ? b.min.y : b.max.y, + (iCorner & 4) == 0 ? b.min.z : b.max.z, 1.0f); + + Vector4 cornerVertex = Matrix4::Dot4(m_matViewProjection, sourceCornerVertex); + + if (cornerVertex.x < -cornerVertex.w) { + outside_count[0]++; } - - bool is_visible = true; - for(int iFace=0; iFace < 6; iFace++) { - if(outside_count[iFace] == 8) { - is_visible = false; - } + if (cornerVertex.y < -cornerVertex.w) { + outside_count[1]++; } - - return is_visible; + if (cornerVertex.z < -cornerVertex.w) { + outside_count[2]++; + } + if (cornerVertex.x > cornerVertex.w) { + outside_count[3]++; + } + if (cornerVertex.y > cornerVertex.w) { + outside_count[4]++; + } + if (cornerVertex.z > cornerVertex.w) { + outside_count[5]++; + } + } + + bool is_visible = true; + for (int iFace = 0; iFace < 6; iFace++) { + if (outside_count[iFace] == 8) { + is_visible = false; + } + } + + return is_visible; } diff --git a/kraken/KRViewport.h b/kraken/KRViewport.h index e7c94a7..573ba8d 100755 --- a/kraken/KRViewport.h +++ b/kraken/KRViewport.h @@ -37,57 +37,58 @@ class KRLight; -class KRViewport { +class KRViewport +{ public: - KRViewport(); - KRViewport(const Vector2 &size, const Matrix4 &matView, const Matrix4 &matProjection); - ~KRViewport(); - - const Vector2 &getSize() const; - const Matrix4 &getViewMatrix() const; - const Matrix4 &getProjectionMatrix() const; - const Matrix4 &getViewProjectionMatrix() const; - const Matrix4 &getInverseViewMatrix() const; - const Matrix4 &getInverseProjectionMatrix() const; - const Vector3 &getCameraDirection() const; - const Vector3 &getCameraPosition() const; - const int *getFrontToBackOrder() const; - const int *getBackToFrontOrder() const; - void setSize(const Vector2 &size); - void setViewMatrix(const Matrix4 &matView); - void setProjectionMatrix(const Matrix4 &matProjection); - float getLODBias() const; - void setLODBias(float lod_bias); - - // Overload assignment operator - KRViewport& operator=(const KRViewport &v); - - unordered_map &getVisibleBounds(); - - const std::set &getVisibleLights(); - void setVisibleLights(const std::set visibleLights); - - bool visible(const AABB &b) const; - float coverage(const AABB &b) const; - + KRViewport(); + KRViewport(const Vector2& size, const Matrix4& matView, const Matrix4& matProjection); + ~KRViewport(); + + const Vector2& getSize() const; + const Matrix4& getViewMatrix() const; + const Matrix4& getProjectionMatrix() const; + const Matrix4& getViewProjectionMatrix() const; + const Matrix4& getInverseViewMatrix() const; + const Matrix4& getInverseProjectionMatrix() const; + const Vector3& getCameraDirection() const; + const Vector3& getCameraPosition() const; + const int* getFrontToBackOrder() const; + const int* getBackToFrontOrder() const; + void setSize(const Vector2& size); + void setViewMatrix(const Matrix4& matView); + void setProjectionMatrix(const Matrix4& matProjection); + float getLODBias() const; + void setLODBias(float lod_bias); + + // Overload assignment operator + KRViewport& operator=(const KRViewport& v); + + unordered_map& getVisibleBounds(); + + const std::set& getVisibleLights(); + void setVisibleLights(const std::set visibleLights); + + bool visible(const AABB& b) const; + float coverage(const AABB& b) const; + private: - Vector2 m_size; - Matrix4 m_matView; - Matrix4 m_matProjection; - - float m_lodBias; - - // Derived values - Matrix4 m_matViewProjection; - Matrix4 m_matInverseView; - Matrix4 m_matInverseProjection; - Vector3 m_cameraDirection; - Vector3 m_cameraPosition; - - int m_frontToBackOrder[8]; - int m_backToFrontOrder[8]; - - void calculateDerivedValues(); - - unordered_map m_visibleBounds; // AABB's that output fragments in the last frame + Vector2 m_size; + Matrix4 m_matView; + Matrix4 m_matProjection; + + float m_lodBias; + + // Derived values + Matrix4 m_matViewProjection; + Matrix4 m_matInverseView; + Matrix4 m_matInverseProjection; + Vector3 m_cameraDirection; + Vector3 m_cameraPosition; + + int m_frontToBackOrder[8]; + int m_backToFrontOrder[8]; + + void calculateDerivedValues(); + + unordered_map m_visibleBounds; // AABB's that output fragments in the last frame }; diff --git a/kraken/public/context.h b/kraken/public/context.h index b780e8c..75daf16 100644 --- a/kraken/public/context.h +++ b/kraken/public/context.h @@ -35,7 +35,7 @@ namespace kraken { class Context { -class impl; + class impl; public: static Context* Get(); bool loadResource(const char* szPath); diff --git a/kraken/public/kraken.h b/kraken/public/kraken.h index be23db5..27c8317 100644 --- a/kraken/public/kraken.h +++ b/kraken/public/kraken.h @@ -35,7 +35,8 @@ #define KR_NULL_HANDLE 0 -typedef enum { +typedef enum +{ KR_SUCCESS = 0, KR_ERROR_NOT_INITIALIZED, KR_ERROR_NOT_IMPLEMENTED, @@ -56,14 +57,15 @@ typedef enum { KR_RESULT_MAX_ENUM = 0x7FFFFFFF } KrResult; -typedef enum { - KR_STRUCTURE_TYPE_INITIALIZE = 0, +typedef enum +{ + KR_STRUCTURE_TYPE_INITIALIZE = 0, KR_STRUCTURE_TYPE_SHUTDOWN, KR_STRUCTURE_TYPE_CREATE_WINDOW_SURFACE, KR_STRUCTURE_TYPE_DELETE_WINDOW_SURFACE, - KR_STRUCTURE_TYPE_LOAD_RESOURCE = 0x00010000, + KR_STRUCTURE_TYPE_LOAD_RESOURCE = 0x00010000, KR_STRUCTURE_TYPE_UNLOAD_RESOURCE, KR_STRUCTURE_TYPE_GET_RESOURCE_DATA, KR_STRUCTURE_TYPE_SAVE_RESOURCE, @@ -74,9 +76,9 @@ typedef enum { KR_STRUCTURE_TYPE_COMPILE_ALL_SHADERS, - KR_STRUCTURE_TYPE_CREATE_SCENE = 0x00020000, + KR_STRUCTURE_TYPE_CREATE_SCENE = 0x00020000, - KR_STRUCTURE_TYPE_FIND_NODE_BY_NAME = 0x00030000, + KR_STRUCTURE_TYPE_FIND_NODE_BY_NAME = 0x00030000, KR_STRUCTURE_TYPE_FIND_ADJACENT_NODES, KR_STRUCTURE_TYPE_DELETE_NODE, KR_STRUCTURE_TYPE_DELETE_NODE_CHILDREN, @@ -88,7 +90,7 @@ typedef enum { KR_STRUCTURE_TYPE_SET_NODE_LOCAL_TRANSFORM, KR_STRUCTURE_TYPE_SET_NODE_WORLD_TRANSFORM, - KR_STRUCTURE_TYPE_NODE = 0x10000000, + KR_STRUCTURE_TYPE_NODE = 0x10000000, KR_STRUCTURE_TYPE_NODE_CAMERA, KR_STRUCTURE_TYPE_NODE_LOD_SET, KR_STRUCTURE_TYPE_NODE_LOD_GROUP, @@ -104,20 +106,22 @@ typedef enum { KR_STRUCTURE_TYPE_NODE_AMBIENT_ZONE, KR_STRUCTURE_TYPE_NODE_REVERB_ZONE, KR_STRUCTURE_TYPE_NODE_MAX_ENUM, - - KR_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF + + KR_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } KrStructureType; typedef int KrResourceMapIndex; typedef int KrSceneNodeMapIndex; typedef int KrSurfaceMapIndex; -typedef struct { +typedef struct +{ KrStructureType sType; size_t resourceMapSize; } KrInitializeInfo; -typedef struct { +typedef struct +{ KrStructureType sType; KrSurfaceMapIndex surfaceHandle; #if defined(_WIN32) || defined(_WIN64) @@ -125,28 +129,33 @@ typedef struct { #endif } KrCreateWindowSurfaceInfo; -typedef struct { +typedef struct +{ KrStructureType sType; KrSurfaceMapIndex surfaceHandle; } KrDeleteWindowSurfaceInfo; -typedef struct { +typedef struct +{ KrStructureType sType; const char* pResourcePath; KrResourceMapIndex resourceHandle; } KrLoadResourceInfo; -typedef struct { +typedef struct +{ KrStructureType sType; KrResourceMapIndex resourceHandle; } KrUnloadResourceInfo; -typedef struct { +typedef struct +{ KrStructureType sType; KrResourceMapIndex resourceHandle; } KrGetResourceDataInfo; -typedef struct { +typedef struct +{ KrResult result; void* data; size_t length; @@ -154,48 +163,56 @@ typedef struct { typedef void (*KrGetResourceDataCallback)(const KrGetResourceDataResult&); -typedef struct { +typedef struct +{ KrStructureType sType; const char* pResourceName; KrResourceMapIndex resourceHandle; } KrMapResourceInfo; -typedef struct { +typedef struct +{ KrStructureType sType; KrResourceMapIndex resourceHandle; } KrUnmapResourceInfo; -typedef struct { +typedef struct +{ KrStructureType sType; const char* pResourcePath; KrResourceMapIndex resourceHandle; } KrSaveResourceInfo; -typedef struct { +typedef struct +{ KrStructureType sType; const char* pBundleName; KrResourceMapIndex resourceHandle; } KrCreateBundleInfo; -typedef struct { +typedef struct +{ KrStructureType sType; KrResourceMapIndex resourceHandle; KrResourceMapIndex bundleHandle; } KrMoveToBundleInfo; -typedef struct { +typedef struct +{ KrStructureType sType; KrResourceMapIndex bundleHandle; KrResourceMapIndex logHandle; } KrCompileAllShadersInfo; -typedef struct { +typedef struct +{ KrStructureType sType; const char* pSceneName; KrResourceMapIndex resourceHandle; } KrCreateSceneInfo; -typedef struct { +typedef struct +{ KrStructureType sType; const char* pName; kraken::Vector3 translate; @@ -207,20 +224,25 @@ typedef struct { kraken::Vector3 scale_offset; kraken::Vector3 rotate_pivot; kraken::Vector3 scale_pivot; - union { - struct { + union + { + struct + { // KR_STRUCTURE_TYPE_NODE // No additional members } node; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_CAMERA KrResourceMapIndex skybox_texture; } camera; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_LOD_SET // No additional members } lod_set; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_LOD_GROUP float min_distance; float max_distance; @@ -228,7 +250,8 @@ typedef struct { kraken::Vector3 reference_max; bool use_world_units; } lod_group; - struct { + struct + { kraken::Vector3 color; float intensity; float decay_start; @@ -240,26 +263,31 @@ typedef struct { float dust_particle_density; float dust_particle_size; float dust_particle_intensity; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_POINT_LIGHT // No additional members } point; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_DIRECTIONAL_LIGHT // No additional members } directional; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_SPOT_LIGHT float inner_angle; float outer_angle; } spot; } light; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_SPRITE KrResourceMapIndex texture; float alpha; } sprite; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_MODEL float lod_min_coverage; bool receives_shadow; @@ -269,21 +297,25 @@ typedef struct { KrResourceMapIndex mesh; KrResourceMapIndex light_map_texture; } model; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_COLLIDER KrResourceMapIndex mesh; uint64_t layer_mask; float audio_occlusion; } collider; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_BONE // No additional members } bone; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_LOCATOR // No additional members } locator; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_AUDIO_SOURCE KrResourceMapIndex sample; float gain; @@ -296,14 +328,16 @@ typedef struct { bool enable_obstruction; bool enable_occlusion; } audio_source; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_AMBIENT_ZONE char* pZoneName; float gradient; float gain; KrResourceMapIndex sample; } ambient_zone; - struct { + struct + { // KR_STRUCTURE_TYPE_NODE_REVERB_ZONE char* pZoneName; float gradient; @@ -387,7 +421,8 @@ typedef struct KrNodeInfo node; } KrUpdateNodeInfo; -typedef struct { +typedef struct +{ KrStructureType sType; KrResourceMapIndex sceneHandle; KrSceneNodeMapIndex nodeHandle; @@ -396,7 +431,8 @@ typedef struct { kraken::Vector3 rotate; } KrSetNodeLocalTransformInfo; -typedef struct { +typedef struct +{ KrStructureType sType; KrResourceMapIndex sceneHandle; KrSceneNodeMapIndex nodeHandle; diff --git a/tests/smoke/hello_cube/main_win.cpp b/tests/smoke/hello_cube/main_win.cpp index 03bd495..10ff5b8 100644 --- a/tests/smoke/hello_cube/main_win.cpp +++ b/tests/smoke/hello_cube/main_win.cpp @@ -65,8 +65,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine init_info.resourceMapSize = 1024; KrResult res = KrInitialize(&init_info); if (res != KR_SUCCESS) { - // printf("Failed to initialize Kraken!\n"); - return 1; + // printf("Failed to initialize Kraken!\n"); + return 1; } KrLoadResourceInfo load_resource_info = {}; @@ -75,9 +75,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine load_resource_info.pResourcePath = "kraken_cube.krbundle"; res = KrLoadResource(&load_resource_info); if (res != KR_SUCCESS) { - //printf("Failed to load resource: %s\n", arg); - KrShutdown(); - return 1; + //printf("Failed to load resource: %s\n", arg); + KrShutdown(); + return 1; } KrCreateWindowSurfaceInfo create_surface_info = {}; @@ -96,7 +96,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine while (GetMessage(&msg, NULL, 0, 0) > 0) { DispatchMessage(&msg); } - + // KrShutdown will delete the window surfaces for us; however, we // include this here for code coverage in tests. @@ -118,8 +118,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) - { + switch (message) { case WM_CLOSE: PostQuitMessage(0); break; diff --git a/tools/convert/main.cpp b/tools/convert/main.cpp index ed3fc97..5205b5a 100644 --- a/tools/convert/main.cpp +++ b/tools/convert/main.cpp @@ -39,13 +39,14 @@ using namespace kraken; -enum ResourceMapping { +enum ResourceMapping +{ output_bundle = 0, loaded_resource = 1, shader_compile_log = 2, }; -int main( int argc, char *argv[] ) +int main(int argc, char* argv[]) { bool failed = false; printf("Kraken Convert\n"); @@ -86,7 +87,7 @@ int main( int argc, char *argv[] ) char command = '\0'; for (int i = 1; i < argc && !failed; i++) { - char *arg = argv[i]; + char* arg = argv[i]; if (arg[0] == '-') { if (command != '\0') { // The last command is expecting a parameter, not another command. @@ -126,14 +127,14 @@ int main( int argc, char *argv[] ) // Process commands that receive arguments switch (command) { - case 'i': - input_list_file = arg; - command = '\0'; - continue; - case 'o': - output_bundle = arg; - command = '\0'; - continue; + case 'i': + input_list_file = arg; + command = '\0'; + continue; + case 'o': + output_bundle = arg; + command = '\0'; + continue; } input_files.push_back(arg); @@ -200,7 +201,7 @@ int main( int argc, char *argv[] ) } else { // result.data will be a null terminated string if (result.data != nullptr && result.length > 0) { - printf("Shader compile log:\n%s\n", static_cast(result.data)); + printf("Shader compile log:\n%s\n", static_cast(result.data)); } } });