Auto format C++ source

This commit is contained in:
2022-08-08 01:07:26 -07:00
parent c5a640e22d
commit 7433d54c16
155 changed files with 17259 additions and 16879 deletions

View File

@@ -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;
if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(ri);
KRNode::render(ri);
bool bVisualize = ri.camera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_SIREN_AMBIENT_ZONES;
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 (ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) {
KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere");
if (sphereModel) {
Matrix4 sphereModelMatrix = getModelMatrix();
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();
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);
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
}
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;
} else {
return 0.0f;
}
// 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 {
d = (1.0f - d) / m_gradient_distance;
d = KRCLAMP(d, 0.0f, 1.0f);
}
return d;
} else {
return 0.0f;
}
}

View File

@@ -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);
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);
void render(RenderInfo& ri);
std::string getZone();
void setZone(const std::string &zone);
std::string getZone();
void setZone(const std::string& zone);
float getGradientDistance();
void setGradientDistance(float gradient_distance);
float getGradientDistance();
void setGradientDistance(float gradient_distance);
std::string getAmbient();
void setAmbient(const std::string &ambient);
std::string getAmbient();
void setAmbient(const std::string& ambient);
float getAmbientGain();
void setAmbientGain(float ambient_gain);
float getAmbientGain();
void setAmbientGain(float ambient_gain);
virtual AABB getBounds();
virtual AABB getBounds();
float getContainment(const Vector3 &pos);
float getContainment(const Vector3& pos);
private:
std::string m_zone;
std::string m_zone;
float m_gradient_distance;
float m_gradient_distance;
std::string m_ambient;
float m_ambient_gain;
std::string m_ambient;
float m_ambient_gain;
};

View File

@@ -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<std::string, KRAnimationLayer *>::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr){
delete (*itr).second;
}
for (unordered_map<std::string, KRAnimationLayer*>::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<std::string, KRAnimationLayer *>::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();
m_layers[layer->getName()] = layer;
}
tinyxml2::XMLDocument doc;
doc.Parse(xml_string.c_str());
KRAnimation *new_animation = new KRAnimation(context, name);
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);
tinyxml2::XMLElement *animation_node = doc.RootElement();
for (unordered_map<std::string, KRAnimationLayer*>::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr) {
(*itr).second->saveXML(animation_node);
}
if(animation_node->QueryFloatAttribute("duration", &new_animation->m_duration) != tinyxml2::XML_SUCCESS) {
new_animation->m_duration = 0.0f; // Default value
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(animation_node->QueryFloatAttribute("start_time", &new_animation->m_start_time) != tinyxml2::XML_SUCCESS) {
new_animation->m_start_time = 0.0f; // Default value
}
if (new_animation->m_auto_play) {
new_animation->m_playing = true;
}
if(animation_node->QueryBoolAttribute("loop", &new_animation->m_loop) != tinyxml2::XML_SUCCESS) {
new_animation->m_loop = false; // Default value
}
// KRNode *n = KRNode::LoadXML(*new_scene, scene_element->FirstChildElement());
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;
delete data;
return new_animation;
}
unordered_map<std::string, KRAnimationLayer *> &KRAnimation::getLayers()
unordered_map<std::string, KRAnimationLayer*>& 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<std::string, KRAnimationLayer *>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer *layer = (*layer_itr).second;
for(std::vector<KRAnimationAttribute *>::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<std::string, KRAnimationLayer*>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer* layer = (*layer_itr).second;
for (std::vector<KRAnimationAttribute*>::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<std::string, KRAnimationLayer *>::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<KRAnimationAttribute *>::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) {
KRAnimationAttribute *attribute = *attribute_itr;
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<std::string, KRAnimationLayer*>::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<KRAnimationAttribute*>::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.
// 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
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 };
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();
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);
}
}
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);
}
}
getContext().getAnimationManager()->addAnimation(new_animation);
return new_animation;
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;
}
void KRAnimation::deleteCurves()
{
for(unordered_map<std::string, KRAnimationLayer *>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer *layer = (*layer_itr).second;
for(std::vector<KRAnimationAttribute *>::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) {
KRAnimationAttribute *attribute = *attribute_itr;
attribute->deleteCurve();
}
for (unordered_map<std::string, KRAnimationLayer*>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer* layer = (*layer_itr).second;
for (std::vector<KRAnimationAttribute*>::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<std::string, KRAnimationLayer *>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer *layer = (*layer_itr).second;
for(std::vector<KRAnimationAttribute *>::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<std::string, KRAnimationLayer*>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer* layer = (*layer_itr).second;
for (std::vector<KRAnimationAttribute*>::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<std::string, KRAnimationLayer *>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer *layer = (*layer_itr).second;
for(std::vector<KRAnimationAttribute *>::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<std::string, KRAnimationLayer*>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer* layer = (*layer_itr).second;
for (std::vector<KRAnimationAttribute*>::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();
}
}
}
}

View File

@@ -38,47 +38,48 @@
#include "KRAnimationLayer.h"
class KRAnimation : public KRResource {
class KRAnimation : public KRResource
{
public:
KRAnimation(KRContext &context, std::string name);
virtual ~KRAnimation();
KRAnimation(KRContext& context, std::string name);
virtual ~KRAnimation();
virtual std::string getExtension();
virtual bool save(KRDataBlock &data);
virtual std::string getExtension();
virtual bool save(KRDataBlock& data);
static KRAnimation *Load(KRContext &context, const std::string &name, KRDataBlock *data);
static KRAnimation* Load(KRContext& context, const std::string& name, KRDataBlock* data);
void addLayer(KRAnimationLayer *layer);
unordered_map<std::string, KRAnimationLayer *> &getLayers();
KRAnimationLayer *getLayer(const char *szName);
bool getAutoPlay() const;
void setAutoPlay(bool auto_play);
bool getLooping() const;
void setLooping(bool looping);
void Play();
void Stop();
void update(float deltaTime);
float getTime();
void setTime(float time);
float getDuration();
void setDuration(float duration);
float getStartTime();
void setStartTime(float start_time);
bool isPlaying();
void addLayer(KRAnimationLayer* layer);
unordered_map<std::string, KRAnimationLayer*>& getLayers();
KRAnimationLayer* getLayer(const char* szName);
bool getAutoPlay() const;
void setAutoPlay(bool auto_play);
bool getLooping() const;
void setLooping(bool looping);
void Play();
void Stop();
void update(float deltaTime);
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();
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();
void _lockData();
void _unlockData();
private:
unordered_map<std::string, KRAnimationLayer *> 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<std::string, KRAnimationLayer*> m_layers;
bool m_auto_play;
bool m_loop;
bool m_playing;
float m_local_time;
float m_duration;
float m_start_time;
};

View File

@@ -35,11 +35,11 @@
#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()
@@ -47,237 +47,237 @@ 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;
}
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;
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<KRNode>(m_target_name); // FINDME, HACK! - This won't work with multiple scenes in a context; we should move the animations out of KRAnimationManager and attach them to the parent nodes of the animated KRNode's
}
if(m_target == NULL) {
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<KRNode>(m_target_name); // FINDME, HACK! - This won't work with multiple scenes in a context; we should move the animations out of KRAnimationManager and attach them to the parent nodes of the animated KRNode's
}
if (m_target == NULL) {
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;
}
}

View File

@@ -36,33 +36,34 @@
#include "KRNode.h"
#include "KRAnimationCurve.h"
class KRAnimationAttribute : public KRContextObject {
class KRAnimationAttribute : public KRContextObject
{
public:
KRAnimationAttribute(KRContext &context);
~KRAnimationAttribute();
KRAnimationAttribute(KRContext& context);
~KRAnimationAttribute();
tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
void loadXML(tinyxml2::XMLElement *e);
tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent);
void loadXML(tinyxml2::XMLElement* e);
std::string getCurveName() const;
void setCurveName(const std::string &curve_name);
std::string getCurveName() const;
void setCurveName(const std::string& curve_name);
std::string getTargetName() const;
void setTargetName(const std::string &target_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::node_attribute_type getTargetAttribute() const;
void setTargetAttribute(KRNode::node_attribute_type target_attribute);
KRNode *getTarget();
KRAnimationCurve *getCurve();
KRNode* getTarget();
KRAnimationCurve* getCurve();
void deleteCurve();
void deleteCurve();
private:
std::string m_target_name;
std::string m_curve_name;
KRNode::node_attribute_type m_node_attribute;
std::string m_target_name;
std::string m_curve_name;
KRNode::node_attribute_type m_node_attribute;
KRNode *m_target;
KRAnimationCurve *m_curve;
KRNode* m_target;
KRAnimationCurve* m_curve;
};

View File

@@ -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();
m_pData->lock();
int frame_count = ((animation_curve_header*)m_pData->getStart())->frame_count;
m_pData->unlock();
return frame_count;
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);
m_pData->lock();
float first_value = getValue(start_frame);
bool change_found = false;
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;
}
// 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);
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();
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();
// 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;
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();
}

View File

@@ -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();
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);
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);
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);
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);
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);
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();
void _lockData();
void _unlockData();
private:
KRDataBlock *m_pData;
KRDataBlock* m_pData;
typedef struct {
char szTag[16];
float frame_rate;
int32_t frame_start;
int32_t frame_count;
} animation_curve_header;
typedef struct
{
char szTag[16];
float frame_rate;
int32_t frame_start;
int32_t frame_count;
} animation_curve_header;
};

View File

@@ -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<std::string, KRAnimationCurve *>::iterator itr = m_animationCurves.begin(); itr != m_animationCurves.end(); ++itr){
delete (*itr).second;
}
KRAnimationCurveManager::~KRAnimationCurveManager()
{
for (unordered_map<std::string, KRAnimationCurve*>::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<std::string, KRAnimationCurve *>::iterator itr = m_animationCurves.find(name);
if(itr == m_animationCurves.end()) {
return NULL; // Not found
} else {
return (*itr).second;
}
}
unordered_map<std::string, KRAnimationCurve *> &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<std::string, KRAnimationCurve*>::iterator itr = m_animationCurves.find(name);
if (itr == m_animationCurves.end()) {
return NULL; // Not found
} else {
return (*itr).second;
}
}
unordered_map<std::string, KRAnimationCurve*>& 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;
}

View File

@@ -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<std::string, KRAnimationCurve *> &getAnimationCurves();
KRAnimationCurve* loadAnimationCurve(const std::string& name, KRDataBlock* data);
KRAnimationCurve* getAnimationCurve(const std::string& name);
void addAnimationCurve(KRAnimationCurve* new_animation_curve);
unordered_map<std::string, KRAnimationCurve*>& getAnimationCurves();
void deleteAnimationCurve(KRAnimationCurve *curve);
void deleteAnimationCurve(KRAnimationCurve* curve);
private:
unordered_map<std::string, KRAnimationCurve *> m_animationCurves;
unordered_map<std::string, KRAnimationCurve*> m_animationCurves;
};

View File

@@ -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<KRAnimationAttribute *>::iterator itr = m_attributes.begin(); itr != m_attributes.end(); ++itr){
delete (*itr);
}
for (std::vector<KRAnimationAttribute*>::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);
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_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_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;
}
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<KRAnimationAttribute *>::iterator itr = m_attributes.begin(); itr != m_attributes.end(); ++itr){
(*itr)->saveXML(n);
}
for (std::vector<KRAnimationAttribute*>::iterator itr = m_attributes.begin(); itr != m_attributes.end(); ++itr) {
(*itr)->saveXML(n);
}
return e;
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
}
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* 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* 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
}
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);
}
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<KRAnimationAttribute *> &KRAnimationLayer::getAttributes()
std::vector<KRAnimationAttribute*>& KRAnimationLayer::getAttributes()
{
return m_attributes;
return m_attributes;
}

View File

@@ -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();
KRAnimationLayer(KRContext& context);
~KRAnimationLayer();
tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
void loadXML(tinyxml2::XMLElement *e);
tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent);
void loadXML(tinyxml2::XMLElement* e);
std::string getName() const;
void setName(const std::string &name);
std::string getName() const;
void setName(const std::string& name);
float getWeight() const;
void setWeight(float weight);
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;
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);
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;
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);
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;
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);
scale_accumulation_mode_t getScaleAccumulationMode() const;
void setScaleAccumulationMode(const scale_accumulation_mode_t& scale_accumulation_mode);
void addAttribute(KRAnimationAttribute *attribute);
std::vector<KRAnimationAttribute *> &getAttributes();
void addAttribute(KRAnimationAttribute* attribute);
std::vector<KRAnimationAttribute*>& 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::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<KRAnimationAttribute *> m_attributes;
std::vector<KRAnimationAttribute*> m_attributes;
};

View File

@@ -32,48 +32,49 @@
#include "KRAnimationManager.h"
#include "KRAnimation.h"
KRAnimationManager::KRAnimationManager(KRContext &context) : KRResourceManager(context)
KRAnimationManager::KRAnimationManager(KRContext& context) : KRResourceManager(context)
{
}
KRAnimationManager::~KRAnimationManager() {
for(std::set<KRAnimation *>::iterator itr = m_activeAnimations.begin(); itr != m_activeAnimations.end(); itr++) {
KRAnimation *animation = *itr;
animation->_unlockData();
}
KRAnimationManager::~KRAnimationManager()
{
for (std::set<KRAnimation*>::iterator itr = m_activeAnimations.begin(); itr != m_activeAnimations.end(); itr++) {
KRAnimation* animation = *itr;
animation->_unlockData();
}
for(unordered_map<std::string, KRAnimation *>::iterator itr = m_animations.begin(); itr != m_animations.end(); ++itr){
delete (*itr).second;
}
for (unordered_map<std::string, KRAnimation*>::iterator itr = m_animations.begin(); itr != m_animations.end(); ++itr) {
delete (*itr).second;
}
}
void KRAnimationManager::startFrame(float deltaTime)
{
for(std::set<KRAnimation *>::iterator itr = m_animationsToUpdate.begin(); itr != m_animationsToUpdate.end(); itr++) {
KRAnimation *animation = *itr;
std::set<KRAnimation *>::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();
}
}
for (std::set<KRAnimation*>::iterator itr = m_animationsToUpdate.begin(); itr != m_animationsToUpdate.end(); itr++) {
KRAnimation* animation = *itr;
std::set<KRAnimation*>::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();
m_animationsToUpdate.clear();
for(std::set<KRAnimation *>::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<KRAnimation*>::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)
@@ -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<std::string, KRAnimation *> &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<std::string, KRAnimation*>& 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;
}

View File

@@ -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;
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<std::string, KRAnimation *> &getAnimations();
void deleteAnimation(KRAnimation *animation, bool delete_curves);
KRAnimation* loadAnimation(const char* szName, KRDataBlock* data);
KRAnimation* getAnimation(const char* szName);
void addAnimation(KRAnimation* new_animation);
unordered_map<std::string, KRAnimation*>& getAnimations();
void deleteAnimation(KRAnimation* animation, bool delete_curves);
void startFrame(float deltaTime);
void endFrame(float deltaTime);
void startFrame(float deltaTime);
void endFrame(float deltaTime);
void updateActiveAnimations(KRAnimation *animation);
void updateActiveAnimations(KRAnimation* animation);
private:
unordered_map<std::string, KRAnimation *> m_animations;
set<KRAnimation *> m_activeAnimations;
set<KRAnimation *> m_animationsToUpdate;
unordered_map<std::string, KRAnimation*> m_animations;
set<KRAnimation*> m_activeAnimations;
set<KRAnimation*> m_animationsToUpdate;
};

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -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;
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<std::string, KRAudioSample *> &getSounds();
unordered_map<std::string, KRAudioSample*>& getSounds();
void add(KRAudioSample *Sound);
void add(KRAudioSample* Sound);
KRAudioSample *load(const std::string &name, const std::string &extension, KRDataBlock *data);
KRAudioSample *get(const std::string &name);
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();
// 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);
// 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();
void makeCurrentContext();
KRDataBlock *getBufferData(int size);
void recycleBufferData(KRDataBlock *data);
KRDataBlock* getBufferData(int size);
void recycleBufferData(KRDataBlock* data);
void activateAudioSource(KRAudioSource *audioSource);
void deactivateAudioSource(KRAudioSource *audioSource);
void activateAudioSource(KRAudioSource* audioSource);
void deactivateAudioSource(KRAudioSource* audioSource);
__int64_t getAudioFrame();
__int64_t getAudioFrame();
KRAudioBuffer *getBuffer(KRAudioSample &audio_sample, int buffer_index);
KRAudioBuffer* getBuffer(KRAudioSample& audio_sample, int buffer_index);
static void mute(bool onNotOff);
void goToSleep();
static void mute(bool onNotOff);
void goToSleep();
void startFrame(float deltaTime);
void startFrame(float deltaTime);
bool getEnableAudio();
void setEnableAudio(bool enable);
bool getEnableAudio();
void setEnableAudio(bool enable);
bool getEnableHRTF();
void setEnableHRTF(bool enable);
bool getEnableHRTF();
void setEnableHRTF(bool enable);
bool getEnableReverb();
void setEnableReverb(bool enable);
bool getEnableReverb();
void setEnableReverb(bool enable);
float getReverbMaxLength();
void setReverbMaxLength(float max_length);
float getReverbMaxLength();
void setReverbMaxLength(float max_length);
void _registerOpenAudioSample(KRAudioSample *audioSample);
void _registerCloseAudioSample(KRAudioSample *audioSample);
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;
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
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;
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;
Vector3 m_listener_position;
Vector3 m_listener_forward;
Vector3 m_listener_up;
unordered_map<std::string, KRAudioSample *> m_sounds;
unordered_map<std::string, KRAudioSample*> m_sounds;
std::vector<KRDataBlock *> m_bufferPoolIdle;
std::vector<KRDataBlock*> m_bufferPoolIdle;
std::vector<KRAudioBuffer *> m_bufferCache;
std::vector<KRAudioBuffer*> m_bufferCache;
std::set<KRAudioSource *> m_activeAudioSources;
std::set<KRAudioSource*> m_activeAudioSources;
std::set<KRAudioSample *> m_openAudioSamples;
std::set<KRAudioSample*> m_openAudioSamples;
void initAudio();
void initHRTF();
void initAudio();
void initHRTF();
void cleanupAudio();
void cleanupAudio();
bool m_initialized;
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
__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;
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];
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_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* 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();
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<Vector2> m_hrtf_sample_locations;
float *m_hrtf_data;
unordered_map<Vector2, KRDSP::SplitComplex> m_hrtf_spectral[2];
std::vector<Vector2> m_hrtf_sample_locations;
float* m_hrtf_data;
unordered_map<Vector2, KRDSP::SplitComplex> 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);
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<std::string, siren_ambient_zone_weight_info> m_ambient_zone_weights;
float m_ambient_zone_total_weight = 0.0f; // For normalizing zone weights
unordered_map<std::string, siren_ambient_zone_weight_info> m_ambient_zone_weights;
float m_ambient_zone_total_weight = 0.0f; // For normalizing zone weights
unordered_map<std::string, siren_reverb_zone_weight_info> m_reverb_zone_weights;
float m_reverb_zone_total_weight = 0.0f; // For normalizing zone weights
unordered_map<std::string, siren_reverb_zone_weight_info> m_reverb_zone_weights;
float m_reverb_zone_total_weight = 0.0f; // For normalizing zone weights
std::mutex m_mutex;
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<Vector2, std::pair<KRAudioSource *, std::pair<float, float> > > 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<Vector2, std::pair<KRAudioSource*, std::pair<float, float> > > 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
};

View File

@@ -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_totalFrames = 0;
m_bytesPerFrame = 0;
m_frameRate = 0;
m_bufferCount = 0;
m_last_frame_used = 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_totalFrames = 0;
m_bytesPerFrame = 0;
m_frameRate = 0;
m_bufferCount = 0;
m_last_frame_used = 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();
loadInfo();
int c = KRMIN(channel, m_channelsPerFrame - 1);
int c = KRMIN(channel, m_channelsPerFrame - 1);
if(frame_offset < 0) {
return 0.0f; // Past the beginning of the recording
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();
loadInfo();
m_last_frame_used = (int)getContext().getAudioManager()->getAudioFrame();
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);
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) {
// 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
//
// 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;
// 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);
// ---- 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);
// ---- 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);
// ---- 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);
// ---- 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;
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)
int maxFramesPerBuffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / m_bytesPerFrame;
m_bufferCount = (m_totalFrames + maxFramesPerBuffer - 1) / maxFramesPerBuffer; // CEIL(_totalFrames / maxFramesPerBuffer)
m_channelsPerFrame = outputFormat.mChannelsPerFrame;
m_channelsPerFrame = outputFormat.mChannelsPerFrame;
getContext().getAudioManager()->_registerOpenAudioSample(this);
}
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_fileRef) {
ExtAudioFileDispose(m_fileRef);
m_fileRef = NULL;
}
if(m_audio_file_id) {
AudioFileClose(m_audio_file_id);
m_audio_file_id = 0;
}
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;
// 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);
// 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);
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);
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;
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();
}
}

View File

@@ -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();
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 std::string getExtension();
virtual bool save(KRDataBlock &data);
virtual bool save(KRDataBlock& data);
float getDuration();
KRAudioBuffer *getBuffer(int index);
int getBufferCount();
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);
// 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();
void _endFrame();
private:
__int64_t m_last_frame_used;
__int64_t m_last_frame_used;
std::string m_extension;
KRDataBlock *m_pData;
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;
int m_bufferCount;
__int64_t m_totalFrames;
int m_frameRate;
int m_bytesPerFrame;
int m_channelsPerFrame;
__int64_t m_totalFrames;
int m_frameRate;
int m_bytesPerFrame;
int m_channelsPerFrame;
void openFile();
void closeFile();
void loadInfo();
void openFile();
void closeFile();
void loadInfo();
static void PopulateBuffer(KRAudioSample *sound, int index, void *data);
static void PopulateBuffer(KRAudioSample* sound, int index, void* data);
};

View File

@@ -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_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_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_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");
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;
}
float gain = 1.0f;
if(e->QueryFloatAttribute("gain", &gain) != tinyxml2::XML_SUCCESS) {
gain = 1.0f;
}
setGain(gain);
void KRAudioSource::loadXML(tinyxml2::XMLElement* e)
{
m_audio_sample_name = e->Attribute("sample");
float pitch = 1.0f;
if(e->QueryFloatAttribute("pitch", &pitch) != tinyxml2::XML_SUCCESS) {
pitch = 1.0f;
}
setPitch(m_pitch);
float gain = 1.0f;
if (e->QueryFloatAttribute("gain", &gain) != tinyxml2::XML_SUCCESS) {
gain = 1.0f;
}
setGain(gain);
bool looping = false;
if(e->QueryBoolAttribute("looping", &looping) != tinyxml2::XML_SUCCESS) {
looping = false;
}
setLooping(looping);
float pitch = 1.0f;
if (e->QueryFloatAttribute("pitch", &pitch) != tinyxml2::XML_SUCCESS) {
pitch = 1.0f;
}
setPitch(m_pitch);
bool is3d = true;
if(e->QueryBoolAttribute("is3d", &is3d) != tinyxml2::XML_SUCCESS) {
is3d = true;
}
setIs3D(is3d);
bool looping = false;
if (e->QueryBoolAttribute("looping", &looping) != tinyxml2::XML_SUCCESS) {
looping = false;
}
setLooping(looping);
float reference_distance = 1.0f;
if(e->QueryFloatAttribute("reference_distance", &reference_distance) != tinyxml2::XML_SUCCESS) {
reference_distance = 1.0f;
}
setReferenceDistance(reference_distance);
bool is3d = true;
if (e->QueryBoolAttribute("is3d", &is3d) != tinyxml2::XML_SUCCESS) {
is3d = true;
}
setIs3D(is3d);
float reverb = 0.0f;
if(e->QueryFloatAttribute("reverb", &reverb) != tinyxml2::XML_SUCCESS) {
reverb = 0.0f;
}
setReverb(reverb);
float reference_distance = 1.0f;
if (e->QueryFloatAttribute("reference_distance", &reference_distance) != tinyxml2::XML_SUCCESS) {
reference_distance = 1.0f;
}
setReferenceDistance(reference_distance);
float rolloff_factor = 2.0f;
if(e->QueryFloatAttribute("rolloff_factor", &rolloff_factor) != tinyxml2::XML_SUCCESS) {
rolloff_factor = 2.0f;
}
setRolloffFactor(rolloff_factor);
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;
if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(ri);
KRNode::render(ri);
bool bVisualize = false;
bool bVisualize = false;
if(ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) {
KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere");
if (sphereModel) {
Matrix4 sphereModelMatrix = getModelMatrix();
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();
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);
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()
}
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);
KRNode::physicsUpdate(deltaTime);
KRAudioManager *audioManager = getContext().getAudioManager();
audioManager->activateAudioSource(this);
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
// 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;
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.
// 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);
}
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.
// 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;
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;
m_currentBufferFrame += frame_count;
KRAudioBuffer *buffer = getBuffer();
while(buffer != NULL && m_currentBufferFrame >= buffer->getFrameCount()) {
m_currentBufferFrame -= buffer->getFrameCount();
advanceBuffer();
buffer = getBuffer();
}
KRAudioBuffer* buffer = getBuffer();
while (buffer != NULL && m_currentBufferFrame >= buffer->getFrameCount()) {
m_currentBufferFrame -= buffer->getFrameCount();
advanceBuffer();
buffer = getBuffer();
}
if(buffer == NULL) {
m_currentBufferFrame = 0;
stop();
}
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.
// 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;
}
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.
// Gets the audio playback position with units of floating point seconds.
return getAudioFrame() / 44100.0f;
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);
}
}

View File

@@ -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);
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);
void render(RenderInfo& ri);
// ---- Audio Playback Controls ----
// ---- 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();
// 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();
// 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 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();
// 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);
// 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();
// 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);
// 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();
// 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);
// 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 ----
// ---- End: Audio Playback Controls ----
void setSample(const std::string &sound_name);
std::string getSample();
void setSample(const std::string& sound_name);
std::string getSample();
KRAudioSample *getAudioSample();
KRAudioSample* getAudioSample();
float getGain();
void setGain(float gain);
float getGain();
void setGain(float gain);
float getPitch();
void setPitch(float pitch);
float getPitch();
void setPitch(float pitch);
bool getIs3D();
void setIs3D(bool is3D);
bool getIs3D();
void setIs3D(bool is3D);
// 3d only properties:
float getReverb();
void setReverb(float reverb);
// 3d only properties:
float getReverb();
void setReverb(float reverb);
float getReferenceDistance();
void setReferenceDistance(float reference_distance);
float getReferenceDistance();
void setReferenceDistance(float reference_distance);
float getRolloffFactor();
void setRolloffFactor(float rolloff_factor);
float getRolloffFactor();
void setRolloffFactor(float rolloff_factor);
bool getEnableOcclusion();
void setEnableOcclusion(bool enable_occlusion);
bool getEnableOcclusion();
void setEnableOcclusion(bool enable_occlusion);
bool getEnableObstruction();
void setEnableObstruction(bool enable_obstruction);
bool getEnableObstruction();
void setEnableObstruction(bool enable_obstruction);
// ---- Siren Audio Engine Interface ----
// ---- Siren Audio Engine Interface ----
void advanceFrames(int frame_count);
KRAudioBuffer *getBuffer();
int getBufferFrame();
void advanceFrames(int frame_count);
KRAudioBuffer* getBuffer();
int getBufferFrame();
void sample(int frame_count, int channel, float *buffer, float gain);
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();
__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;
std::string m_audio_sample_name;
KRAudioSample *m_audioFile;
unsigned int m_sourceID;
float m_gain;
float m_pitch;
bool m_looping;
std::queue<KRAudioBuffer *> m_audioBuffers;
int m_nextBufferIndex;
bool m_playing;
bool m_is3d;
bool m_isPrimed;
KRAudioSample* m_audioFile;
unsigned int m_sourceID;
float m_gain;
float m_pitch;
bool m_looping;
std::queue<KRAudioBuffer*> m_audioBuffers;
int m_nextBufferIndex;
bool m_playing;
bool m_is3d;
bool m_isPrimed;
void prime();
void queueBuffer();
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;
// 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;
};

View File

@@ -36,7 +36,7 @@ KRBehaviorFactoryFunctionMap m_factoryFunctions;
KRBehavior::KRBehavior()
{
__node = NULL;
__node = NULL;
}
KRBehavior::~KRBehavior()
@@ -46,44 +46,44 @@ 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<std::string, std::string> attributes;
for(const tinyxml2::XMLAttribute *attribute = e->FirstAttribute(); attribute != NULL; attribute = attribute->Next()) {
attributes[attribute->Name()] = attribute->Value();
}
std::map<std::string, std::string> 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);
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);
}

View File

@@ -46,25 +46,25 @@ namespace tinyxml2 {
class XMLElement;
} // namespace tinyxml2
typedef KRBehavior *(*KRBehaviorFactoryFunction)(std::map<std::string, std::string> attributes);
typedef KRBehavior* (*KRBehaviorFactoryFunction)(std::map<std::string, std::string> attributes);
typedef std::map<std::string, KRBehaviorFactoryFunction> 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;
};

View File

@@ -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;
if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(ri);
KRNode::render(ri);
bool bVisualize = ri.camera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_BONES;
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();
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();
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);
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
}
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;
}

View File

@@ -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();
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);
void render(RenderInfo& ri);
void setBindPose(const Matrix4 &pose);
const Matrix4 &getBindPose();
void setBindPose(const Matrix4& pose);
const Matrix4& getBindPose();
private:
Matrix4 m_bind_pose;
Matrix4 m_bind_pose;
};

View File

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

View File

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

View File

@@ -33,21 +33,23 @@
#include "KRBundle.h"
KRBundleManager::KRBundleManager(KRContext &context) : KRResourceManager(context) {
KRBundleManager::KRBundleManager(KRContext& context) : KRResourceManager(context)
{
}
KRBundleManager::~KRBundleManager() {
for(unordered_map<std::string, KRBundle *>::iterator itr = m_bundles.begin(); itr != m_bundles.end(); ++itr){
delete (*itr).second;
}
m_bundles.clear();
KRBundleManager::~KRBundleManager()
{
for (unordered_map<std::string, KRBundle*>::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<std::string, KRBundle *> KRBundleManager::getBundles() {
return m_bundles;
KRBundle* KRBundleManager::getBundle(const char* szName)
{
return m_bundles[szName];
}
unordered_map<std::string, KRBundle*> KRBundleManager::getBundles()
{
return m_bundles;
}

View File

@@ -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;
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);
KRBundle* loadBundle(const char* szName, KRDataBlock* pData);
KRBundle* getBundle(const char* szName);
KRBundle* createBundle(const char* szName);
std::vector<std::string> getBundleNames();
unordered_map<std::string, KRBundle *> getBundles();
std::vector<std::string> getBundleNames();
unordered_map<std::string, KRBundle*> getBundles();
private:
unordered_map<std::string, KRBundle *> m_bundles;
unordered_map<std::string, KRBundle*> m_bundles;
};

File diff suppressed because it is too large Load Diff

View File

@@ -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);
void renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeSurface);
KRRenderSettings settings;
KRRenderSettings settings;
const KRViewport &getViewport() const;
const KRViewport& getViewport() const;
virtual std::string getElementName();
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
virtual void loadXML(tinyxml2::XMLElement *e);
virtual std::string getElementName();
virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent);
virtual void loadXML(tinyxml2::XMLElement* e);
std::string getDebugText();
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 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 setFadeColor(const Vector4& fade_color);
Vector4 getFadeColor();
void setSkyBox(const std::string &skyBox);
const std::string getSkyBox() const;
void setSkyBox(const std::string& skyBox);
const std::string getSkyBox() const;
private:
void createBuffers(GLint renderBufferWidth, GLint renderBufferHeight);
void createBuffers(GLint renderBufferWidth, GLint renderBufferHeight);
GLint volumetricBufferWidth, volumetricBufferHeight;
GLint volumetricBufferWidth, volumetricBufferHeight;
GLuint compositeFramebuffer, compositeDepthTexture, compositeColorTexture;
GLuint lightAccumulationBuffer, lightAccumulationTexture;
GLuint compositeFramebuffer, compositeDepthTexture, compositeColorTexture;
GLuint lightAccumulationBuffer, lightAccumulationTexture;
GLuint volumetricLightAccumulationBuffer, volumetricLightAccumulationTexture;
GLuint volumetricLightAccumulationBuffer, volumetricLightAccumulationTexture;
void renderPost(VkCommandBuffer& commandBuffer, KRSurface& surface);
void renderPost(VkCommandBuffer& commandBuffer, KRSurface& surface);
void destroyBuffers();
void destroyBuffers();
KRTexture *m_pSkyBoxTexture;
std::string m_skyBox;
KRViewport m_viewport;
KRTexture* m_pSkyBoxTexture;
std::string m_skyBox;
KRViewport m_viewport;
float m_particlesAbsoluteTime;
float m_particlesAbsoluteTime;
Vector2 m_downsample;
Vector2 m_downsample;
Vector4 m_fade_color;
Vector4 m_fade_color;
typedef struct {
float x;
float y;
float z;
float u;
float v;
} DebugTextVertexData;
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;
KRDataBlock m_debug_text_vertices;
KRMeshManager::KRVBOData m_debug_text_vbo_data;
// std::string getDebugText();
// std::string getDebugText();
uint64_t m_last_frame_start;
int m_frame_times[KRAKEN_FPS_AVERAGE_FRAME_COUNT];
int m_frame_times_filled;
uint64_t m_last_frame_start;
int m_frame_times[KRAKEN_FPS_AVERAGE_FRAME_COUNT];
int m_frame_times_filled;
};

View File

@@ -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 (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 (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;
if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(ri);
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) {
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");
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();
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);
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);
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);
m_model->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "visualize_overlay", 1.0f);
GL_POP_GROUP_MARKER;
}
GL_POP_GROUP_MARKER;
}
}
}

View File

@@ -46,37 +46,38 @@
#include "KRMesh.h"
#include "KRTexture.h"
class KRCollider : public KRNode {
class KRCollider : public KRNode
{
public:
static void InitNodeInfo(KrNodeInfo* nodeInfo);
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();
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();
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);
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);
unsigned int getLayerMask();
void setLayerMask(unsigned int layer_mask);
float getAudioOcclusion();
void setAudioOcclusion(float audio_occlusion);
float getAudioOcclusion();
void setAudioOcclusion(float audio_occlusion);
void render(RenderInfo& ri);
void render(RenderInfo& ri);
private:
KRMesh* m_model;
std::string m_model_name;
KRMesh* m_model;
std::string m_model_name;
unsigned int m_layer_mask;
float m_audio_occlusion;
unsigned int m_layer_mask;
float m_audio_occlusion;
void loadModel();
void loadModel();
};

View File

@@ -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<KRPresentationThread>(*this);
m_streamerThread = std::make_unique<KRStreamerThread>(*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<KRPresentationThread>(*this);
m_streamerThread = std::make_unique<KRStreamerThread>(*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_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<KRBundleManager>(*this);
m_pPipelineManager = std::make_unique<KRPipelineManager>(*this);
m_pTextureManager = std::make_unique<KRTextureManager>(*this);
m_pMaterialManager = std::make_unique<KRMaterialManager>(*this, m_pTextureManager.get(), m_pPipelineManager.get());
m_pMeshManager = std::make_unique<KRMeshManager>(*this);
m_pMeshManager->init();
m_pSceneManager = std::make_unique<KRSceneManager>(*this);
m_pAnimationManager = std::make_unique<KRAnimationManager>(*this);
m_pAnimationCurveManager = std::make_unique<KRAnimationCurveManager>(*this);
m_pSoundManager = std::make_unique<KRAudioManager>(*this);
m_pUnknownManager = std::make_unique<KRUnknownManager>(*this);
m_pShaderManager = std::make_unique<KRShaderManager>(*this);
m_pSourceManager = std::make_unique<KRSourceManager>(*this);
m_deviceManager = std::make_unique<KRDeviceManager>(*this);
m_surfaceManager = std::make_unique<KRSurfaceManager>(*this);
m_streamingEnabled = true;
m_pBundleManager = std::make_unique<KRBundleManager>(*this);
m_pPipelineManager = std::make_unique<KRPipelineManager>(*this);
m_pTextureManager = std::make_unique<KRTextureManager>(*this);
m_pMaterialManager = std::make_unique<KRMaterialManager>(*this, m_pTextureManager.get(), m_pPipelineManager.get());
m_pMeshManager = std::make_unique<KRMeshManager>(*this);
m_pMeshManager->init();
m_pSceneManager = std::make_unique<KRSceneManager>(*this);
m_pAnimationManager = std::make_unique<KRAnimationManager>(*this);
m_pAnimationCurveManager = std::make_unique<KRAnimationCurveManager>(*this);
m_pSoundManager = std::make_unique<KRAudioManager>(*this);
m_pUnknownManager = std::make_unique<KRUnknownManager>(*this);
m_pShaderManager = std::make_unique<KRShaderManager>(*this);
m_pSourceManager = std::make_unique<KRSourceManager>(*this);
m_deviceManager = std::make_unique<KRDeviceManager>(*this);
m_surfaceManager = std::make_unique<KRSurfaceManager>(*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_deviceManager->initialize();
m_presentationThread->start();
m_streamerThread->start();
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);
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");
}
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_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<KRResource *> KRContext::getResources()
KRUnknownManager* KRContext::getUnknownManager()
{
std::vector<KRResource *> resources;
return m_pUnknownManager.get();
}
std::vector<KRResource*> KRContext::getResources()
{
std::vector<KRResource*> resources;
for(unordered_map<std::string, KRScene *>::iterator itr = m_pSceneManager->getScenes().begin(); itr != m_pSceneManager->getScenes().end(); itr++) {
resources.push_back((*itr).second);
}
for(unordered_map<std::string, KRTexture *>::iterator itr = m_pTextureManager->getTextures().begin(); itr != m_pTextureManager->getTextures().end(); itr++) {
resources.push_back((*itr).second);
}
for(unordered_map<std::string, KRMaterial *>::iterator itr = m_pMaterialManager->getMaterials().begin(); itr != m_pMaterialManager->getMaterials().end(); itr++) {
resources.push_back((*itr).second);
}
for(unordered_multimap<std::string, KRMesh *>::iterator itr = m_pMeshManager->getModels().begin(); itr != m_pMeshManager->getModels().end(); itr++) {
resources.push_back((*itr).second);
}
for(unordered_map<std::string, KRAnimation *>::iterator itr = m_pAnimationManager->getAnimations().begin(); itr != m_pAnimationManager->getAnimations().end(); itr++) {
resources.push_back((*itr).second);
}
for(unordered_map<std::string, KRAnimationCurve *>::iterator itr = m_pAnimationCurveManager->getAnimationCurves().begin(); itr != m_pAnimationCurveManager->getAnimationCurves().end(); itr++) {
resources.push_back((*itr).second);
}
for(unordered_map<std::string, KRAudioSample *>::iterator itr = m_pSoundManager->getSounds().begin(); itr != m_pSoundManager->getSounds().end(); itr++) {
resources.push_back((*itr).second);
}
for (unordered_map<std::string, KRScene*>::iterator itr = m_pSceneManager->getScenes().begin(); itr != m_pSceneManager->getScenes().end(); itr++) {
resources.push_back((*itr).second);
}
for (unordered_map<std::string, KRTexture*>::iterator itr = m_pTextureManager->getTextures().begin(); itr != m_pTextureManager->getTextures().end(); itr++) {
resources.push_back((*itr).second);
}
for (unordered_map<std::string, KRMaterial*>::iterator itr = m_pMaterialManager->getMaterials().begin(); itr != m_pMaterialManager->getMaterials().end(); itr++) {
resources.push_back((*itr).second);
}
for (unordered_multimap<std::string, KRMesh*>::iterator itr = m_pMeshManager->getModels().begin(); itr != m_pMeshManager->getModels().end(); itr++) {
resources.push_back((*itr).second);
}
for (unordered_map<std::string, KRAnimation*>::iterator itr = m_pAnimationManager->getAnimations().begin(); itr != m_pAnimationManager->getAnimations().end(); itr++) {
resources.push_back((*itr).second);
}
for (unordered_map<std::string, KRAnimationCurve*>::iterator itr = m_pAnimationCurveManager->getAnimationCurves().begin(); itr != m_pAnimationCurveManager->getAnimationCurves().end(); itr++) {
resources.push_back((*itr).second);
}
for (unordered_map<std::string, KRAudioSample*>::iterator itr = m_pSoundManager->getSounds().begin(); itr != m_pSoundManager->getSounds().end(); itr++) {
resources.push_back((*itr).second);
}
unordered_map<std::string, unordered_map<std::string, KRSource *> > sources = m_pSourceManager->getSources();
for(unordered_map<std::string, unordered_map<std::string, KRSource *> >::iterator itr = sources.begin(); itr != sources.end(); itr++) {
for(unordered_map<std::string, KRSource *>::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) {
resources.push_back((*itr2).second);
}
unordered_map<std::string, unordered_map<std::string, KRSource*> > sources = m_pSourceManager->getSources();
for (unordered_map<std::string, unordered_map<std::string, KRSource*> >::iterator itr = sources.begin(); itr != sources.end(); itr++) {
for (unordered_map<std::string, KRSource*>::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) {
resources.push_back((*itr2).second);
}
}
unordered_map<std::string, unordered_map<std::string, KRShader *> > shaders = m_pShaderManager->getShaders();
for(unordered_map<std::string, unordered_map<std::string, KRShader *> >::iterator itr = shaders.begin(); itr != shaders.end(); itr++) {
for(unordered_map<std::string, KRShader *>::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) {
resources.push_back((*itr2).second);
}
unordered_map<std::string, unordered_map<std::string, KRShader*> > shaders = m_pShaderManager->getShaders();
for (unordered_map<std::string, unordered_map<std::string, KRShader*> >::iterator itr = shaders.begin(); itr != shaders.end(); itr++) {
for (unordered_map<std::string, KRShader*>::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) {
resources.push_back((*itr2).second);
}
}
unordered_map<std::string, unordered_map<std::string, KRUnknown *> > unknowns = m_pUnknownManager->getUnknowns();
for(unordered_map<std::string, unordered_map<std::string, KRUnknown *> >::iterator itr = unknowns.begin(); itr != unknowns.end(); itr++) {
for(unordered_map<std::string, KRUnknown *>::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) {
resources.push_back((*itr2).second);
}
unordered_map<std::string, unordered_map<std::string, KRUnknown*> > unknowns = m_pUnknownManager->getUnknowns();
for (unordered_map<std::string, unordered_map<std::string, KRUnknown*> >::iterator itr = unknowns.begin(); itr != unknowns.end(); itr++) {
for (unordered_map<std::string, KRUnknown*>::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) {
resources.push_back((*itr2).second);
}
}
return resources;
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;
KRResource* resource = nullptr;
// fprintf(stderr, "KRContext::loadResource - Loading: %s\n", file_name.c_str());
// 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 (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)
@@ -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::milliseconds>(
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;
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;
}
free_memory = (vm_stat.free_count + vm_stat.inactive_count) * pagesize;
}
}
#endif

View File

@@ -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;
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();
KRContext(const KrInitializeInfo* initializeInfo);
~KRContext();
KrResult createWindowSurface(const KrCreateWindowSurfaceInfo* createWindowSurfaceInfo);
KrResult deleteWindowSurface(const KrDeleteWindowSurfaceInfo* deleteWindowSurfaceInfo);
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 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 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);
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);
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();
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);
void startFrame(float deltaTime);
void endFrame(float deltaTime);
long getCurrentFrame() const;
long getLastFullyStreamedFrame() const;
float getAbsoluteTime() const;
long getCurrentFrame() const;
long getLastFullyStreamedFrame() const;
float getAbsoluteTime() const;
long getAbsoluteTimeMilliseconds();
long getAbsoluteTimeMilliseconds();
std::vector<KRResource *> getResources();
std::vector<KRResource*> 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 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);
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, ...);
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();
void doStreaming();
void receivedMemoryWarning();
static std::mutex g_SurfaceInfoMutex;
static std::mutex g_DeviceInfoMutex;
static std::mutex g_SurfaceInfoMutex;
static std::mutex g_DeviceInfoMutex;
void addResource(KRResource* resource, const std::string& name);
void removeResource(KRResource* resource);
void addResource(KRResource* resource, const std::string& name);
void removeResource(KRResource* resource);
private:
std::unique_ptr<KRBundleManager> m_pBundleManager;
std::unique_ptr<KRSceneManager> m_pSceneManager;
std::unique_ptr<KRTextureManager> m_pTextureManager;
std::unique_ptr<KRMaterialManager> m_pMaterialManager;
std::unique_ptr<KRPipelineManager> m_pPipelineManager;
std::unique_ptr<KRMeshManager> m_pMeshManager;
std::unique_ptr<KRAnimationManager> m_pAnimationManager;
std::unique_ptr<KRAnimationCurveManager> m_pAnimationCurveManager;
std::unique_ptr<KRAudioManager> m_pSoundManager;
std::unique_ptr<KRUnknownManager> m_pUnknownManager;
std::unique_ptr<KRShaderManager> m_pShaderManager;
std::unique_ptr<KRSourceManager> m_pSourceManager;
std::unique_ptr<KRDeviceManager> m_deviceManager;
std::unique_ptr<KRSurfaceManager> m_surfaceManager;
std::unique_ptr<KRBundleManager> m_pBundleManager;
std::unique_ptr<KRSceneManager> m_pSceneManager;
std::unique_ptr<KRTextureManager> m_pTextureManager;
std::unique_ptr<KRMaterialManager> m_pMaterialManager;
std::unique_ptr<KRPipelineManager> m_pPipelineManager;
std::unique_ptr<KRMeshManager> m_pMeshManager;
std::unique_ptr<KRAnimationManager> m_pAnimationManager;
std::unique_ptr<KRAnimationCurveManager> m_pAnimationCurveManager;
std::unique_ptr<KRAudioManager> m_pSoundManager;
std::unique_ptr<KRUnknownManager> m_pUnknownManager;
std::unique_ptr<KRShaderManager> m_pShaderManager;
std::unique_ptr<KRSourceManager> m_pSourceManager;
std::unique_ptr<KRDeviceManager> m_deviceManager;
std::unique_ptr<KRSurfaceManager> m_surfaceManager;
KRResource** m_resourceMap;
size_t m_resourceMapSize;
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;
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<bool> m_streamingEnabled;
// m_streamingEnabled is set to true once all managers are loaded
std::atomic<bool> m_streamingEnabled;
static log_callback *s_log_callback;
static void *s_log_callback_user_data;
static log_callback* s_log_callback;
static void* s_log_callback_user_data;
unordered_multimap<std::string, KRResource*> m_resources;
unordered_multimap<std::string, KRResource*> m_resources;
std::unique_ptr<KRStreamerThread> m_streamerThread;
std::unique_ptr<KRPresentationThread> m_presentationThread;
std::unique_ptr<KRStreamerThread> m_streamerThread;
std::unique_ptr<KRPresentationThread> m_presentationThread;
unordered_map<KrSurfaceMapIndex, KrSurfaceHandle> m_surfaceHandleMap;
unordered_map<KrSurfaceMapIndex, KrSurfaceHandle> m_surfaceHandleMap;
};

View File

@@ -31,9 +31,9 @@
#include "KRContextObject.h"
KRContextObject::KRContextObject(KRContext &context)
KRContextObject::KRContextObject(KRContext& context)
{
m_pContext = &context;
m_pContext = &context;
}
KRContextObject::~KRContextObject()
@@ -41,7 +41,7 @@ KRContextObject::~KRContextObject()
}
KRContext &KRContextObject::getContext() const
KRContext& KRContextObject::getContext() const
{
return *m_pContext;
return *m_pContext;
}

View File

@@ -33,13 +33,14 @@
class KRContext;
class KRContextObject {
class KRContextObject
{
public:
KRContextObject(KRContext &context);
~KRContextObject();
KRContextObject(KRContext& context);
~KRContextObject();
KRContext &getContext() const;
KRContext& getContext() const;
protected:
KRContext *m_pContext;
KRContext* m_pContext;
};

View File

@@ -39,53 +39,56 @@ namespace KRDSP {
#define KRDSP_APPLE_VDSP
#include <Accelerate/Accelerate.h>
#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

View File

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

View File

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

View File

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

View File

@@ -39,90 +39,91 @@
#define KRENGINE_MIN_MMAP 32768
class KRDataBlock {
class KRDataBlock
{
public:
KRDataBlock();
KRDataBlock(void *data, size_t size);
~KRDataBlock();
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);
// 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);
// 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);
// 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);
// 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(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 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);
// 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);
// 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();
// 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 start of the data block
void* getStart();
// Return a pointer to the one byte after the end of the data block
void *getEnd();
// 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;
// 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();
// Get the contents as a string
std::string getString();
// Copy the entire data block to the destination pointer
void copy(void *dest);
// 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);
// 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();
// 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();
// 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;
void* m_data;
size_t m_data_size;
size_t m_data_offset;
// For memory mapped objects:
// 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;
std::string m_fileName;
KRDataBlock* m_fileOwnerDataBlock;
void* m_mmapData;
// For malloc'ed objects:
bool m_bMalloced;
// For malloc'ed objects:
bool m_bMalloced;
// Lock refcount
int m_lockCount;
// Lock refcount
int m_lockCount;
// Read-only allocation
bool m_bReadOnly;
// Read-only allocation
bool m_bReadOnly;
// Assert if not locked
void assertLocked();
// Assert if not locked
void assertLocked();
};

View File

@@ -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) {

View File

@@ -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<VkCommandBuffer> m_transferCommandBuffers;
VmaAllocator m_allocator;
struct StagingBufferInfo {
struct StagingBufferInfo
{
VkBuffer buffer;
VmaAllocation allocation;
size_t size;

View File

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

View File

@@ -43,7 +43,7 @@ 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)
{
}
@@ -53,117 +53,122 @@ 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) {
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...
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}};
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;
*/
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);
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 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
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 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;
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");
}
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;
return 1;
}
void KRDirectionalLight::render(RenderInfo& ri) {
void KRDirectionalLight::render(RenderInfo& ri)
{
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRLight::render(ri);
KRLight::render(ri);
if(ri.renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) {
// Lights are rendered on the second pass of the deferred renderer
if (ri.renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) {
// Lights are rendered on the second pass of the deferred renderer
std::vector<KRDirectionalLight *> this_light;
this_light.push_back(this);
std::vector<KRDirectionalLight*> this_light;
this_light.push_back(this);
Matrix4 matModelViewInverseTranspose = ri.viewport.getViewMatrix() * getModelMatrix();
matModelViewInverseTranspose.transpose();
matModelViewInverseTranspose.invert();
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();
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;
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;
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;
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);
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);
}
// 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();
}

View File

@@ -33,24 +33,25 @@
#include "KRLight.h"
class KRDirectionalLight : public KRLight {
class KRDirectionalLight : public KRLight
{
public:
static void InitNodeInfo(KrNodeInfo* nodeInfo);
static void InitNodeInfo(KrNodeInfo* nodeInfo);
KRDirectionalLight(KRScene &scene, std::string name);
virtual ~KRDirectionalLight();
KRDirectionalLight(KRScene& scene, std::string name);
virtual ~KRDirectionalLight();
virtual std::string getElementName();
Vector3 getLocalLightDirection();
Vector3 getWorldLightDirection();
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);
};

View File

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

View File

@@ -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 &parameter_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

View File

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

View File

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

View File

@@ -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;
}
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);
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);
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);
sqr_distance = (local_camera_position - local_reference_point).sqrMagnitude() * (lod_bias * lod_bias);
// Compare using squared distances as sqrt is expensive
float sqr_distance;
float sqr_prestream_distance;
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?
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;
}
}
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;
}

View File

@@ -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);
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);
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;
const AABB& getReference() const;
void setReference(const AABB& reference);
void setUseWorldUnits(bool use_world_units);
bool getUseWorldUnits() const;
LodVisibility calcLODVisibility(const KRViewport &viewport);
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;
};

View File

@@ -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;
*/
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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup *lod_group = dynamic_cast<KRLODGroup *>(*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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup *lod_group = dynamic_cast<KRLODGroup *>(*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);
// Upgrade and downgrade LOD groups as needed
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup* lod_group = dynamic_cast<KRLODGroup*>(*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<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup* lod_group = dynamic_cast<KRLODGroup*>(*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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup *lod_group = dynamic_cast<KRLODGroup *>(*itr);
assert(lod_group != NULL);
if(lod_group->calcLODVisibility(viewport) == LOD_VISIBILITY_VISIBLE) {
new_active_lod_group = lod_group;
}
// Upgrade and downgrade LOD groups as needed
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup* lod_group = dynamic_cast<KRLODGroup*>(*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;
}
if (new_active_lod_group) {
return new_active_lod_group->getStreamLevel(viewport);
} else {
return kraken_stream_level::STREAM_LEVEL_IN_HQ;
}
}

View File

@@ -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);
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 updateLODVisibility(const KRViewport& viewport);
virtual void setLODVisibility(LodVisibility lod_visibility);
virtual void setLODVisibility(LodVisibility lod_visibility);
virtual kraken_stream_level getStreamLevel(const KRViewport &viewport);
virtual kraken_stream_level getStreamLevel(const KRViewport& viewport);
};

View File

@@ -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;
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;
}
// 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);
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("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("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_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->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("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;
}
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;
if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(ri);
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_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.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"?
if (ri.viewport.visible(getBounds()) || true) { // FINDME, HACK need to remove "|| true"?
float particle_range = 600.0f;
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;
}
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<KRDirectionalLight *> this_directional_light;
std::vector<KRSpotLight *> this_spot_light;
std::vector<KRPointLight *> this_point_light;
KRDirectionalLight *directional_light = dynamic_cast<KRDirectionalLight *>(this);
KRSpotLight *spot_light = dynamic_cast<KRSpotLight *>(this);
KRPointLight *point_light = dynamic_cast<KRPointLight *>(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);
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);
}
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;
}
}
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());
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<KRDirectionalLight *> this_directional_light;
std::vector<KRSpotLight *> this_spot_light;
std::vector<KRPointLight *> this_point_light;
KRDirectionalLight *directional_light = dynamic_cast<KRDirectionalLight *>(this);
KRSpotLight *spot_light = dynamic_cast<KRSpotLight *>(this);
KRPointLight *point_light = dynamic_cast<KRPointLight *>(this);
if(directional_light) {
this_directional_light.push_back(directional_light);
std::vector<KRDirectionalLight*> this_directional_light;
std::vector<KRSpotLight*> this_spot_light;
std::vector<KRPointLight*> this_point_light;
KRDirectionalLight* directional_light = dynamic_cast<KRDirectionalLight*>(this);
KRSpotLight* spot_light = dynamic_cast<KRSpotLight*>(this);
KRPointLight* point_light = dynamic_cast<KRPointLight*>(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* pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info);
KRPipeline *pFogShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info);
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);
int slice_count = (int)(ri.camera->settings.volumetric_environment_quality * 495.0) + 5;
m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_RANDOM_PARTICLES, 1.0f);
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;
vkCmdDraw(ri.commandBuffer, particle_count * 3, 1, 0, 0);
}
}
}
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_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<KRDirectionalLight*> this_directional_light;
std::vector<KRSpotLight*> this_spot_light;
std::vector<KRPointLight*> this_point_light;
KRDirectionalLight* directional_light = dynamic_cast<KRDirectionalLight*>(this);
KRSpotLight* spot_light = dynamic_cast<KRSpotLight*>(this);
KRPointLight* point_light = dynamic_cast<KRPointLight*>(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);
}
if(ri.renderPass == KRNode::RENDER_PASS_PARTICLE_OCCLUSION) {
if(m_flareTexture.size() && m_flareSize > 0.0f) {
KRMesh* sphereModel = getContext().getMeshManager()->getMaxLODModel("__sphere");
if (sphereModel) {
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;
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();
}
KRPipeline* pFogShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info);
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();
int slice_count = (int)(ri.camera->settings.volumetric_environment_quality * 495.0) + 5;
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);
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;
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
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);
sphereModel->renderNoMaterials(ri.commandBuffer, ri.renderPass, getName(), "occlusion_test", 1.0f);
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, &params));
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);
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);
}
}
}
}
}
}
}
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, &params));
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);
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 (shadowFramebuffer[iShadow]) {
GLDEBUG(glDeleteFramebuffers(1, shadowFramebuffer + iShadow));
shadowFramebuffer[iShadow] = 0;
}
}
if(!shadowDepthTexture[iShadow]) {
shadowValid[iShadow] = false;
// Allocate newly required buffers
for (int iShadow = 0; iShadow < cBuffers; iShadow++) {
Vector2 viewportSize = m_shadowViewports[iShadow].getSize();
GLDEBUG(glGenFramebuffers(1, shadowFramebuffer + iShadow));
GLDEBUG(glGenTextures(1, shadowDepthTexture + iShadow));
// ===== Create offscreen shadow framebuffer object =====
if (!shadowDepthTexture[iShadow]) {
shadowValid[iShadow] = false;
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow]));
GLDEBUG(glGenFramebuffers(1, shadowFramebuffer + iShadow));
GLDEBUG(glGenTextures(1, shadowDepthTexture + iShadow));
// ===== Create offscreen shadow framebuffer object =====
// ----- 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);
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(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(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;
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(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(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(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(glViewport(1, 1, (GLsizei)m_shadowViewports[iShadow].getSize().x - 2, (GLsizei)m_shadowViewports[iShadow].getSize().y - 2));
GLDEBUG(glClearDepthf(1.0f));
GLDEBUG(glClearDepthf(1.0f));
GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT));
GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT));
GLDEBUG(glDisable(GL_DITHER));
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);
// 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);
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);
}
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;
}

View File

@@ -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);
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);
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 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();
void setFlareTexture(std::string flare_texture);
void setFlareSize(float flare_size);
void setFlareOcclusionSize(float occlusion_size);
void deleteBuffers();
virtual void render(RenderInfo& ri);
virtual void render(RenderInfo& ri);
int getShadowBufferCount();
GLuint *getShadowTextures();
KRViewport *getShadowViewports();
int getShadowBufferCount();
GLuint* getShadowTextures();
KRViewport* getShadowViewports();
protected:
KRLight(KRScene &scene, std::string name);
KRLight(KRScene& scene, std::string name);
float m_intensity;
float m_decayStart;
Vector3 m_color;
float m_intensity;
float m_decayStart;
Vector3 m_color;
std::string m_flareTexture;
KRTexture *m_pFlareTexture;
float m_flareSize;
float m_flareOcclusionSize;
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;
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
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];
// 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();
void allocateShadowBuffers(int cBuffers);
void invalidateShadowBuffers();
virtual int configureShadowBufferViewports(const KRViewport &viewport);
void renderShadowBuffers(RenderInfo& ri);
virtual int configureShadowBufferViewports(const KRViewport& viewport);
void renderShadowBuffers(RenderInfo& ri);
};

View File

@@ -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* KRLocator::saveXML(tinyxml2::XMLNode* parent)
{
tinyxml2::XMLElement *e = KRNode::saveXML(parent);
tinyxml2::XMLElement* e = KRNode::saveXML(parent);
return e;
return e;
}
void KRLocator::loadXML(tinyxml2::XMLElement *e)
void KRLocator::loadXML(tinyxml2::XMLElement* e)
{
KRNode::loadXML(e);
KRNode::loadXML(e);
}
unordered_map<std::string, int> &KRLocator::getUserIntAttributes()
unordered_map<std::string, int>& KRLocator::getUserIntAttributes()
{
return m_userIntAttributes;
return m_userIntAttributes;
}
unordered_map<std::string, double> &KRLocator::getUserDoubleAttributes()
unordered_map<std::string, double>& KRLocator::getUserDoubleAttributes()
{
return m_userDoubleAttributes;
return m_userDoubleAttributes;
}
unordered_map<std::string, bool> &KRLocator::getUserBoolAttributes()
unordered_map<std::string, bool>& KRLocator::getUserBoolAttributes()
{
return m_userBoolAttributes;
return m_userBoolAttributes;
}
unordered_map<std::string, std::string> &KRLocator::getUserStringAttributes()
unordered_map<std::string, std::string>& KRLocator::getUserStringAttributes()
{
return m_userStringAttributes;
return m_userStringAttributes;
}

View File

@@ -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<std::string, int> &getUserIntAttributes();
unordered_map<std::string, double> &getUserDoubleAttributes();
unordered_map<std::string, bool> &getUserBoolAttributes();
unordered_map<std::string, std::string> &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<std::string, int>& getUserIntAttributes();
unordered_map<std::string, double>& getUserDoubleAttributes();
unordered_map<std::string, bool>& getUserBoolAttributes();
unordered_map<std::string, std::string>& getUserStringAttributes();
private:
unordered_map<std::string, int> m_userIntAttributes;
unordered_map<std::string, double> m_userDoubleAttributes;
unordered_map<std::string, bool> m_userBoolAttributes;
unordered_map<std::string, std::string> m_userStringAttributes;
unordered_map<std::string, int> m_userIntAttributes;
unordered_map<std::string, double> m_userDoubleAttributes;
unordered_map<std::string, bool> m_userBoolAttributes;
unordered_map<std::string, std::string> m_userStringAttributes;
};

View File

@@ -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<long double>::digits10);
stream.setf(std::ios::fixed,std::ios::floatfield);
bool KRMaterial::save(KRDataBlock& data)
{
std::stringstream stream;
stream.precision(std::numeric_limits<long double>::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 << "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());
stream << "\n";
data.append(stream.str());
return true;
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();
getTextures();
if(m_pAmbientMap) {
m_pAmbientMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_AMBIENT_MAP);
}
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_pDiffuseMap) {
m_pDiffuseMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP);
}
if(m_pNormalMap) {
m_pNormalMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_NORMAL_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_pSpecularMap) {
m_pSpecularMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP);
}
if(m_pReflectionMap) {
m_pReflectionMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_REFLECTION_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);
}
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;
kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ;
getTextures();
getTextures();
if(m_pAmbientMap) {
stream_level = KRMIN(stream_level, m_pAmbientMap->getStreamLevel(KRTexture::TEXTURE_USAGE_AMBIENT_MAP));
}
if (m_pAmbientMap) {
stream_level = KRMIN(stream_level, m_pAmbientMap->getStreamLevel(KRTexture::TEXTURE_USAGE_AMBIENT_MAP));
}
if(m_pDiffuseMap) {
stream_level = KRMIN(stream_level, m_pDiffuseMap->getStreamLevel(KRTexture::TEXTURE_USAGE_DIFFUSE_MAP));
}
if (m_pDiffuseMap) {
stream_level = KRMIN(stream_level, m_pDiffuseMap->getStreamLevel(KRTexture::TEXTURE_USAGE_DIFFUSE_MAP));
}
if(m_pNormalMap) {
stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(KRTexture::TEXTURE_USAGE_NORMAL_MAP));
}
if (m_pNormalMap) {
stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(KRTexture::TEXTURE_USAGE_NORMAL_MAP));
}
if(m_pSpecularMap) {
stream_level = KRMIN(stream_level, m_pSpecularMap->getStreamLevel(KRTexture::TEXTURE_USAGE_SPECULAR_MAP));
}
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_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));
}
if (m_pReflectionCube) {
stream_level = KRMIN(stream_level, m_pReflectionCube->getStreamLevel(KRTexture::TEXTURE_USAGE_REFECTION_CUBE));
}
return stream_level;
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<KRBone *> &bones, const std::vector<Matrix4> &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<KRBone*>& bones, const std::vector<Matrix4>& bind_poses, const Matrix4& matModel, KRTexture* pLightMap, const Vector3& rim_color, float rim_power, float lod_coverage)
{
bool bLightMap = pLightMap && ri.camera->settings.bEnableLightMap;
bool bLightMap = pLightMap && ri.camera->settings.bEnableLightMap;
getTextures();
getTextures();
Vector2 default_scale = Vector2::One();
Vector2 default_offset = Vector2::Zero();
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);
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);
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);
// Rim highlighting parameters
pShader->setUniform(KRPipeline::Uniform::rim_color, rim_color);
pShader->setUniform(KRPipeline::Uniform::rim_power, rim_power);
// 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];
// 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);
// 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());
}
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];
}
}
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 (pShader->hasUniform(KRPipeline::Uniform::bone_transforms)) {
pShader->setUniform(KRPipeline::Uniform::bone_transforms, (Matrix4*)bone_mats, bones.size());
}
}
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_ambient, m_ambientColor + ri.camera->settings.ambient_intensity);
pShader->setUniform(KRPipeline::Uniform::material_alpha, m_tr);
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(bDiffuseMap) {
m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap, lod_coverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP);
}
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);
}
if(bSpecMap) {
m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap, lod_coverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP);
}
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);
if(bNormalMap) {
m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap, lod_coverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP);
}
pShader->setUniform(KRPipeline::Uniform::material_alpha, m_tr);
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 (bDiffuseMap) {
m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap, lod_coverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP);
}
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);
}
if (bSpecMap) {
m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap, lod_coverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP);
}
pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, matModel, &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass);
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;
}

View File

@@ -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;
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();
KRMaterial(KRContext& context, const char* szName);
virtual ~KRMaterial();
virtual std::string getExtension();
virtual bool save(KRDataBlock &data);
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();
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;
bool isTransparent();
const std::string& getName() const;
void bind(const KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector<KRBone*>& bones, const std::vector<Matrix4>& bind_poses, const Matrix4& matModel, KRTexture* pLightMap, const Vector3& rim_color, float rim_power, float lod_coverage = 0.0f);
void bind(const KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector<KRBone*>& bones, const std::vector<Matrix4>& bind_poses, const Matrix4& matModel, KRTexture* pLightMap, const Vector3& rim_color, float rim_power, float lod_coverage = 0.0f);
bool needsVertexTangents();
bool needsVertexTangents();
kraken_stream_level getStreamLevel();
void preStream(float lodCoverage);
kraken_stream_level getStreamLevel();
void preStream(float lodCoverage);
private:
std::string m_name;
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;
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;
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
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_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
float m_tr; // Transparency
float m_ns; // Shininess
alpha_mode_type m_alpha_mode;
alpha_mode_type m_alpha_mode;
void getTextures();
void getTextures();
};

View File

@@ -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<std::string, KRMaterial *> &KRMaterialManager::getMaterials()
unordered_map<std::string, KRMaterial*>& 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);
KRMaterial* KRMaterialManager::getMaterial(const std::string& name)
{
std::string lowerName = name;
std::transform(lowerName.begin(), lowerName.end(),
lowerName.begin(), ::tolower);
unordered_map<std::string, KRMaterial *>::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;
unordered_map<std::string, KRMaterial*>::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++;
}
}
*pDest = '\0';
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';
}
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;
}

View File

@@ -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;
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);
KRMaterial* load(const char* szName, KRDataBlock* data);
void add(KRMaterial* new_material);
KRMaterial* getMaterial(const std::string& name);
unordered_map<std::string, KRMaterial *> &getMaterials();
unordered_map<std::string, KRMaterial*>& getMaterials();
private:
unordered_map<std::string, KRMaterial *> m_materials;
KRTextureManager *m_pTextureManager;
KRPipelineManager *m_pPipelineManager;
unordered_map<std::string, KRMaterial*> m_materials;
KRTextureManager* m_pTextureManager;
KRPipelineManager* m_pPipelineManager;
};

File diff suppressed because it is too large Load Diff

View File

@@ -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<Vector3> vertices;
std::vector<__uint16_t> vertex_indexes;
std::vector<std::pair<int, int> > vertex_index_bases;
std::vector<Vector2> uva;
std::vector<Vector2> uvb;
std::vector<Vector3> normals;
std::vector<Vector3> tangents;
std::vector<int> submesh_starts;
std::vector<int> submesh_lengths;
std::vector<std::string> material_names;
std::vector<std::string> bone_names;
std::vector<std::vector<int> > bone_indexes;
std::vector<Matrix4> bone_bind_poses;
std::vector<std::vector<float> > bone_weights;
} mesh_info;
typedef struct
{
ModelFormat format;
std::vector<Vector3> vertices;
std::vector<__uint16_t> vertex_indexes;
std::vector<std::pair<int, int> > vertex_index_bases;
std::vector<Vector2> uva;
std::vector<Vector2> uvb;
std::vector<Vector3> normals;
std::vector<Vector3> tangents;
std::vector<int> submesh_starts;
std::vector<int> submesh_lengths;
std::vector<std::string> material_names;
std::vector<std::string> bone_names;
std::vector<std::vector<int> > bone_indexes;
std::vector<Matrix4> bone_bind_poses;
std::vector<std::vector<float> > bone_weights;
} mesh_info;
void render(const KRNode::RenderInfo& ri, const std::string &object_name, const Matrix4 &matModel, KRTexture *pLightMap, const std::vector<KRBone *> &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<KRBone*>& 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<KRDataBlock *> vertex_data_blocks;
vector<KRDataBlock *> index_data_blocks;
vector<KRMeshManager::KRVBOData *> 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<KRDataBlock*> vertex_data_blocks;
vector<KRDataBlock*> index_data_blocks;
vector<KRMeshManager::KRVBOData*> 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 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 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;
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);
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);
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);
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);
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<KRMaterial *> m_materials;
set<KRMaterial *> 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<KRMaterial*> m_materials;
set<KRMaterial*> 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<Submesh *> m_submeshes;
int m_vertex_attribute_offset[KRENGINE_NUM_ATTRIBUTES];
int m_vertex_size;
void updateAttributeOffsets();
vector<Submesh*> 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);
};

View File

@@ -32,35 +32,35 @@
#include "KRMeshCube.h"
KRMeshCube::KRMeshCube(KRContext &context) : KRMesh(context, "__cube")
KRMeshCube::KRMeshCube(KRContext& context) : KRMesh(context, "__cube")
{
m_constant = true;
m_constant = true;
KRMesh::mesh_info mi;
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.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;
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);
LoadData(mi, true, true);
}
KRMeshCube::~KRMeshCube()

View File

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

View File

@@ -50,69 +50,71 @@ KRMeshManager::KRMeshManager(KRContext& context)
}
void KRMeshManager::init() {
addModel(new KRMeshCube(*m_pContext));
addModel(new KRMeshQuad(*m_pContext));
addModel(new KRMeshSphere(*m_pContext));
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
};
// ---- 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_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
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]"
, "Cube Mesh [built-in]"
#endif
);
);
initRandomParticles();
initVolumetricLightingVertexes();
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();
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
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]"
, "Square Mesh [built-in]"
#endif
);
);
}
KRMeshManager::~KRMeshManager() {
for(unordered_multimap<std::string, KRMesh *>::iterator itr = m_models.begin(); itr != m_models.end(); ++itr){
delete (*itr).second;
}
m_models.clear();
KRMeshManager::~KRMeshManager()
{
for (unordered_multimap<std::string, KRMesh*>::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);
void KRMeshManager::addModel(KRMesh* model)
{
std::string lowerName = model->getLODBaseName();
std::transform(lowerName.begin(), lowerName.end(),
lowerName.begin(), ::tolower);
m_models.insert(std::pair<std::string, KRMesh *>(lowerName, model));
m_models.insert(std::pair<std::string, KRMesh*>(lowerName, model));
}
KRMesh* KRMeshManager::getMaxLODModel(const char* szName) {
KRMesh* KRMeshManager::getMaxLODModel(const char* szName)
{
std::vector<KRMesh*> models = getModel(szName);
// models are always in order of highest LOD first
if (models.size()) {
@@ -161,111 +166,113 @@ KRMesh* KRMeshManager::getMaxLODModel(const char* szName) {
return nullptr;
}
std::vector<KRMesh *> KRMeshManager::getModel(const char *szName) {
std::string lowerName = szName;
std::transform(lowerName.begin(), lowerName.end(),
lowerName.begin(), ::tolower);
std::vector<KRMesh *> matching_models;
std::pair<unordered_multimap<std::string, KRMesh *>::iterator, unordered_multimap<std::string, KRMesh *>::iterator> range = m_models.equal_range(lowerName);
for(unordered_multimap<std::string, KRMesh *>::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<std::string, KRMesh *> &KRMeshManager::getModels() {
return m_models;
}
void KRMeshManager::bindVBO(VkCommandBuffer& commandBuffer, KRVBOData *vbo_data, float lodCoverage)
std::vector<KRMesh*> KRMeshManager::getModel(const char* szName)
{
vbo_data->resetPoolExpiry(lodCoverage);
std::string lowerName = szName;
std::transform(lowerName.begin(), lowerName.end(),
lowerName.begin(), ::tolower);
bool vbo_changed = false;
if(m_currentVBO == NULL) {
vbo_changed = true;
} else if(m_currentVBO->m_data != vbo_data->m_data) {
vbo_changed = true;
std::vector<KRMesh*> matching_models;
std::pair<unordered_multimap<std::string, KRMesh*>::iterator, unordered_multimap<std::string, KRMesh*>::iterator> range = m_models.equal_range(lowerName);
for (unordered_multimap<std::string, KRMesh*>::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<std::string, KRMesh*>& 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;
}
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);
}
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<KRVBOData*> 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<float>::max();
m_activeVBOs_streamer_copy.push_back(std::pair<float, KRVBOData*>(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<float, KRVBOData*>(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<KRVBOData *> 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<float>::max();
m_activeVBOs_streamer_copy.push_back(std::pair<float, KRVBOData*>(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<float, KRVBOData *>(priority, activeVBO));
}
}
for(std::set<KRVBOData *>::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<KRVBOData*>::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();
}
@@ -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::pair<float, KRVBOData *>>());
std::sort(m_activeVBOs_streamer.begin(), m_activeVBOs_streamer.end(), std::greater<std::pair<float, KRVBOData*>>());
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<KRDataBlock *, KRVBOData *>::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<KRDataBlock*, KRVBOData*>::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++;
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++;
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++;
}
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();
}
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();
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
// 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));
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++;
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.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();
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::draw_call_info> 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_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_last_frame_used = 0;
m_last_frame_max_lod_coverage = 0.0f;
memset(m_allocations, 0, sizeof(AllocationInfo) * KRENGINE_MAX_GPU_COUNT);
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_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_size = m_data->getSize();
if (m_index_data != NULL) {
m_size += m_index_data->getSize();
}
if (t == KRVBOData::CONSTANT) {
m_manager->primeVBO(this);
}
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;
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;
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 debug_label[KRENGINE_DEBUG_GPU_LABEL_MAX_LEN];
char* type_label = "";
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);
}
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_is_vbo_loaded = true;
m_manager->m_vboMemUsed += getSize();
m_manager->m_memoryTransferredThisFrame += getSize();
m_manager->m_vboMemUsed += getSize();
m_manager->m_memoryTransferredThisFrame += getSize();
if(m_type != STREAMING) {
_swapHandles();
}
if (m_type != STREAMING) {
_swapHandles();
}
}
void KRMeshManager::KRVBOData::unload()
@@ -630,8 +637,8 @@ 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;
@@ -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;
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);
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;
}
}

View File

@@ -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;
static const int KRENGINE_MAX_VOLUMETRIC_PLANES = 500;
static const int KRENGINE_MAX_RANDOM_PARTICLES = 150000;
KRMeshManager(KRContext &context);
void init();
virtual ~KRMeshManager();
KRMeshManager(KRContext& context);
void init();
virtual ~KRMeshManager();
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;
void startFrame(float deltaTime);
void endFrame(float deltaTime);
void startFrame(float deltaTime);
void endFrame(float deltaTime);
KRMesh *loadModel(const char *szName, KRDataBlock *pData);
std::vector<KRMesh *> getModel(const char *szName);
KRMesh* KRMeshManager::getMaxLODModel(const char* szName);
void addModel(KRMesh *model);
KRMesh* loadModel(const char* szName, KRDataBlock* pData);
std::vector<KRMesh*> getModel(const char* szName);
KRMesh* KRMeshManager::getMaxLODModel(const char* szName);
void addModel(KRMesh* model);
std::vector<std::string> getModelNames();
unordered_multimap<std::string, KRMesh *> &getModels();
std::vector<std::string> getModelNames();
unordered_multimap<std::string, KRMesh*>& getModels();
class KRVBOData {
class KRVBOData
{
public:
public:
typedef enum {
STREAMING,
// STREAMING data is loaded asynchronously, with transfer queues in the streamer thread.
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.
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;
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
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();
);
~KRVBOData();
KRDataBlock *m_data;
KRDataBlock *m_index_data;
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);
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;
// Disable copy constructors
KRVBOData(const KRVBOData& o) = delete;
KRVBOData& operator=(const KRVBOData& o) = delete;
long getSize() { return (long)m_size; }
long getSize()
{
return (long)m_size;
}
void resetPoolExpiry(float lodCoverage);
long getLastFrameUsed() { return m_last_frame_used; }
void resetPoolExpiry(float lodCoverage);
long getLastFrameUsed()
{
return m_last_frame_used;
}
vbo_type getType() { return m_type; }
vbo_type getType()
{
return m_type;
}
float getStreamPriority();
float getStreamPriority();
void _swapHandles();
void _swapHandles();
VkBuffer& getVertexBuffer();
VkBuffer& getIndexBuffer();
uint32_t getVertexAttributes();
VkBuffer& getVertexBuffer();
VkBuffer& getIndexBuffer();
uint32_t getVertexAttributes();
private:
KRMeshManager *m_manager;
int m_vertex_attrib_flags;
long m_size;
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;
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;
typedef struct
{
KrDeviceHandle device;
VkBuffer vertex_buffer;
VmaAllocation vertex_allocation;
VkBuffer index_buffer;
VmaAllocation index_allocation;
} AllocationInfo;
AllocationInfo m_allocations[KRENGINE_MAX_GPU_COUNT];
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();
void bindVBO(VkCommandBuffer& commandBuffer, KRVBOData* vbo_data, float lodCoverage);
long getMemUsed();
long getMemActive();
typedef struct {
Vector3 vertex;
Vector2 uva;
} RandomParticleVertexData;
typedef struct
{
Vector3 vertex;
Vector2 uva;
} RandomParticleVertexData;
typedef struct {
Vector3 vertex;
} VolumetricLightingVertexData;
typedef struct
{
Vector3 vertex;
} VolumetricLightingVertexData;
long getMemoryTransferedThisFrame();
long getMemoryTransferedThisFrame();
size_t getActiveVBOCount();
size_t getActiveVBOCount();
struct draw_call_info {
KRNode::RenderPass pass;
char object_name[256];
char material_name[256];
int vertex_count;
};
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<draw_call_info> getDrawCalls();
void log_draw_call(KRNode::RenderPass pass, const std::string& object_name, const std::string& material_name, int vertex_count);
std::vector<draw_call_info> 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;
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;
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<std::string, KRMesh *> m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model
unordered_multimap<std::string, KRMesh*> 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;
long m_vboMemUsed;
KRVBOData* m_currentVBO;
unordered_map<KRDataBlock *, KRVBOData *> m_vbosActive;
std::vector<std::pair<float, KRVBOData *> > m_activeVBOs_streamer;
std::vector<std::pair<float, KRVBOData *> > m_activeVBOs_streamer_copy;
unordered_map<KRDataBlock*, KRVBOData*> m_vbosActive;
std::vector<std::pair<float, KRVBOData*> > m_activeVBOs_streamer;
std::vector<std::pair<float, KRVBOData*> > m_activeVBOs_streamer_copy;
KRDataBlock m_randomParticleVertexData;
KRDataBlock m_volumetricLightingVertexData;
KRDataBlock m_randomParticleVertexData;
KRDataBlock m_volumetricLightingVertexData;
long m_memoryTransferredThisFrame;
long m_memoryTransferredThisFrame;
std::vector<draw_call_info> m_draw_calls;
bool m_draw_call_logging_enabled;
bool m_draw_call_log_used;
std::vector<draw_call_info> m_draw_calls;
bool m_draw_call_logging_enabled;
bool m_draw_call_log_used;
std::mutex m_streamerFenceMutex;
bool m_streamerComplete;
std::mutex m_streamerFenceMutex;
bool m_streamerComplete;
void balanceVBOMemory(long &memoryRemaining, long &memoryRemainingThisFrame);
void balanceVBOMemory(long& memoryRemaining, long& memoryRemainingThisFrame);
void primeVBO(KRVBOData *vbo_data);
void primeVBO(KRVBOData* vbo_data);
void initRandomParticles();
void initVolumetricLightingVertexes();
void initRandomParticles();
void initVolumetricLightingVertexes();
};

View File

@@ -32,29 +32,29 @@
#include "KRMeshQuad.h"
KRMeshQuad::KRMeshQuad(KRContext &context) : KRMesh(context, "__quad")
KRMeshQuad::KRMeshQuad(KRContext& context) : KRMesh(context, "__quad")
{
m_constant = true;
m_constant = true;
KRMesh::mesh_info mi;
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.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.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;
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);
LoadData(mi, true, true);
}
KRMeshQuad::~KRMeshQuad()

View File

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

View File

@@ -32,94 +32,94 @@
#include "KRMeshSphere.h"
KRMeshSphere::KRMeshSphere(KRContext &context) : KRMesh(context, "__sphere")
KRMeshSphere::KRMeshSphere(KRContext& context) : KRMesh(context, "__sphere")
{
m_constant = true;
m_constant = true;
KRMesh::mesh_info mi;
KRMesh::mesh_info mi;
// Create a triangular facet approximation to a sphere
// Based on algorithm from Paul Bourke: http://paulbourke.net/miscellaneous/sphere_cylinder/
// 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);
int iterations = 3;
int facet_count = (int)(pow(4, iterations) * 8.0f);
std::vector<Triangle3> f = std::vector<Triangle3>(facet_count);
std::vector<Triangle3> f = std::vector<Triangle3>(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 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;
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;
/* 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;
}
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]);
}
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.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;
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()));
}
// 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);
LoadData(mi, true, true);
}
KRMeshSphere::~KRMeshSphere()

View File

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

View File

@@ -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<KRMesh *> 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<KRMesh *, std::vector<KRBone *> > bones;
if(models.size() > 0) {
bool all_bones_found = true;
for(std::vector<KRMesh *>::iterator model_itr = models.begin(); model_itr != models.end(); model_itr++) {
KRMesh *model = *model_itr;
std::vector<KRBone *> model_bones;
int bone_count = model->getBoneCount();
for(int bone_index=0; bone_index < bone_count; bone_index++) {
KRBone *matching_bone = dynamic_cast<KRBone *>(getScene().getRootNode()->find<KRNode>(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<KRMesh *>::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<KRMesh*> 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<KRMesh*, std::vector<KRBone*> > bones;
if (models.size() > 0) {
bool all_bones_found = true;
for (std::vector<KRMesh*>::iterator model_itr = models.begin(); model_itr != models.end(); model_itr++) {
KRMesh* model = *model_itr;
std::vector<KRBone*> model_bones;
int bone_count = model->getBoneCount();
for (int bone_index = 0; bone_index < bone_count; bone_index++) {
KRBone* matching_bone = dynamic_cast<KRBone*>(getScene().getRootNode()->find<KRNode>(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<KRMesh*>::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();
}
}

View File

@@ -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();
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 std::string getElementName();
virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent);
virtual void render(KRNode::RenderInfo& ri);
virtual void render(KRNode::RenderInfo& ri);
virtual AABB getBounds();
virtual AABB getBounds();
void setRimColor(const Vector3 &rim_color);
void setRimPower(float rim_power);
Vector3 getRimColor();
float getRimPower();
void setRimColor(const Vector3& rim_color);
void setRimPower(float rim_power);
Vector3 getRimColor();
float getRimPower();
void setLightMap(const std::string &name);
std::string getLightMap();
void setLightMap(const std::string& name);
std::string getLightMap();
virtual kraken_stream_level getStreamLevel(const KRViewport &viewport);
virtual kraken_stream_level getStreamLevel(const KRViewport& viewport);
private:
void preStream(const KRViewport &viewport);
void preStream(const KRViewport& viewport);
std::vector<KRMesh *> m_models;
unordered_map<KRMesh *, std::vector<KRBone *> > m_bones; // Outer std::map connects model to set of bones
KRTexture *m_pLightMap;
std::string m_lightMap;
std::string m_model_name;
std::vector<KRMesh*> m_models;
unordered_map<KRMesh*, std::vector<KRBone*> > 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();
float m_min_lod_coverage;
void loadModel();
bool m_receivesShadow;
bool m_faces_camera;
bool m_receivesShadow;
bool m_faces_camera;
Matrix4 m_boundsCachedMat;
AABB m_boundsCached;
Matrix4 m_boundsCachedMat;
AABB m_boundsCached;
Vector3 m_rim_color;
float m_rim_power;
Vector3 m_rim_color;
float m_rim_power;
};

File diff suppressed because it is too large Load Diff

View File

@@ -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 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 LodVisibility
{
LOD_VISIBILITY_HIDDEN,
LOD_VISIBILITY_PRESTREAM,
LOD_VISIBILITY_VISIBLE
};
class RenderInfo {
public:
RenderInfo(VkCommandBuffer& cb)
: commandBuffer(cb)
{
class RenderInfo
{
public:
RenderInfo(VkCommandBuffer& cb)
: commandBuffer(cb)
{
}
}
RenderInfo(const RenderInfo&) = delete;
RenderInfo& operator=(const RenderInfo&) = delete;
RenderInfo(const RenderInfo&) = delete;
RenderInfo& operator=(const RenderInfo&) = delete;
VkCommandBuffer& commandBuffer;
KRCamera* camera;
KRSurface* surface;
std::vector<KRPointLight*> point_lights;
std::vector<KRDirectionalLight*> directional_lights;
std::vector<KRSpotLight*> spot_lights;
KRViewport viewport;
RenderPass renderPass;
};
VkCommandBuffer& commandBuffer;
KRCamera* camera;
KRSurface* surface;
std::vector<KRPointLight*> point_lights;
std::vector<KRDirectionalLight*> directional_lights;
std::vector<KRSpotLight*> spot_lights;
KRViewport viewport;
RenderPass renderPass;
};
static void InitNodeInfo(KrNodeInfo* nodeInfo);
static void InitNodeInfo(KrNodeInfo* nodeInfo);
KRNode(KRScene &scene, std::string name);
virtual ~KRNode();
KRNode(KRScene& scene, std::string name);
virtual ~KRNode();
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent);
static KRNode *LoadXML(KRScene &scene, tinyxml2::XMLElement *e);
virtual void loadXML(tinyxml2::XMLElement *e);
static KRNode* LoadXML(KRScene& scene, tinyxml2::XMLElement* e);
virtual void loadXML(tinyxml2::XMLElement* e);
virtual std::string getElementName();
const std::string &getName() const;
virtual std::string getElementName();
const std::string& getName() const;
void addChild(KRNode *child);
const std::set<KRNode *> &getChildren();
KRNode *getParent();
void addChild(KRNode* child);
const std::set<KRNode*>& 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 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);
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& 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& 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& getLocalTranslation();
const Vector3& getLocalScale();
const Vector3& getLocalRotation();
const Vector3 &getInitialLocalTranslation();
const Vector3 &getInitialLocalScale();
const Vector3 &getInitialLocalRotation();
const Vector3& getInitialLocalTranslation();
const Vector3& getInitialLocalScale();
const Vector3& getInitialLocalRotation();
const Vector3 getWorldTranslation();
const Vector3 getWorldScale();
const Quaternion getWorldRotation();
const Vector3 getWorldTranslation();
const Vector3 getWorldScale();
const Quaternion getWorldRotation();
const Quaternion getBindPoseWorldRotation();
const Quaternion getActivePoseWorldRotation();
const Quaternion getBindPoseWorldRotation();
const Quaternion getActivePoseWorldRotation();
const Vector3 localToWorld(const Vector3 &local_point);
const Vector3 worldToLocal(const Vector3 &world_point);
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);
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();
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
};
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);
void SetAttribute(node_attribute_type attrib, float v);
KRScene &getScene();
KRScene& getScene();
virtual void render(const RenderInfo& ri);
virtual void render(const RenderInfo& ri);
virtual void physicsUpdate(float deltaTime);
virtual bool hasPhysics();
virtual void physicsUpdate(float deltaTime);
virtual bool hasPhysics();
virtual void updateLODVisibility(const KRViewport &viewport);
LodVisibility getLODVisibility();
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;
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 kraken_stream_level getStreamLevel(const KRViewport& viewport);
virtual void setLODVisibility(LodVisibility lod_visibility);
virtual void setLODVisibility(LodVisibility lod_visibility);
protected:
Vector3 m_localTranslation;
Vector3 m_localScale;
Vector3 m_localRotation;
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_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_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;
Vector3 m_initialRotationOffset;
Vector3 m_initialScalingOffset;
Vector3 m_initialRotationPivot;
Vector3 m_initialScalingPivot;
Vector3 m_initialPreRotation;
Vector3 m_initialPostRotation;
LodVisibility m_lod_visible;
LodVisibility m_lod_visible;
KRNode *m_parentNode;
std::set<KRNode *> m_childNodes;
KRNode* m_parentNode;
std::set<KRNode*> m_childNodes;
bool m_animation_mask[KRENGINE_NODE_ATTRIBUTE_COUNT];
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;
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;
mutable AABB m_bounds;
mutable bool m_boundsValid;
std::string m_name;
std::string m_name;
KRScene *m_pScene;
KRScene* m_pScene;
std::set<KROctreeNode *> m_octree_nodes;
bool m_scale_compensation;
std::set<KROctreeNode*> m_octree_nodes;
bool m_scale_compensation;
std::set<KRBehavior *> m_behaviors;
std::set<KRBehavior*> m_behaviors;
public:
void addBehavior(KRBehavior *behavior);
std::set<KRBehavior *> &getBehaviors();
template <class T> T *getBehavior()
{
for(std::set<KRBehavior *>::iterator itr=m_behaviors.begin(); itr != m_behaviors.end(); itr++) {
T *behavior = dynamic_cast<T *>(*itr);
if(behavior) {
return behavior;
}
}
return NULL;
void addBehavior(KRBehavior* behavior);
std::set<KRBehavior*>& getBehaviors();
template <class T> T* getBehavior()
{
for (std::set<KRBehavior*>::iterator itr = m_behaviors.begin(); itr != m_behaviors.end(); itr++) {
T* behavior = dynamic_cast<T*>(*itr);
if (behavior) {
return behavior;
}
}
void removeFromOctreeNodes();
void addToOctreeNode(KROctreeNode *octree_node);
void childDeleted(KRNode *child_node);
return NULL;
}
void removeFromOctreeNodes();
void addToOctreeNode(KROctreeNode* octree_node);
void childDeleted(KRNode* child_node);
template <class T> T *find()
{
T *match = dynamic_cast<T *>(this);
if(match) {
return match;
}
for(std::set<KRNode *>::const_iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
match = (*itr)->find<T>();
if(match) {
return match;
}
}
return NULL;
template <class T> T* find()
{
T* match = dynamic_cast<T*>(this);
if (match) {
return match;
}
template <class T> T *find(const std::string &name)
{
T *match = dynamic_cast<T *>(this);
if(match) {
if(name.compare(match->getName()) == 0) {
return match;
}
}
for(std::set<KRNode *>::const_iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
match = (*itr)->find<T>(name);
if(match) {
return match;
}
}
return NULL;
for (std::set<KRNode*>::const_iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
match = (*itr)->find<T>();
if (match) {
return match;
}
}
return NULL;
}
template <class T> T* find(const std::string& name)
{
T* match = dynamic_cast<T*>(this);
if (match) {
if (name.compare(match->getName()) == 0) {
return match;
}
}
for (std::set<KRNode*>::const_iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
match = (*itr)->find<T>(name);
if (match) {
return match;
}
}
return NULL;
}
};

View File

@@ -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);
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 {
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);
// 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<KRNode *> &KROctree::getOuterSceneNodes()
std::set<KRNode*>& 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<KRCollider *> outer_colliders;
bool hit_found = false;
std::vector<KRCollider*> outer_colliders;
for(std::set<KRNode *>::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*outer_nodes_itr);
if(collider) {
outer_colliders.push_back(collider);
}
}
for(std::vector<KRCollider *>::iterator itr=outer_colliders.begin(); itr != outer_colliders.end(); itr++) {
if((*itr)->lineCast(v0, v1, hitinfo, layer_mask)) hit_found = true;
for (std::set<KRNode*>::iterator outer_nodes_itr = m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) {
KRCollider* collider = dynamic_cast<KRCollider*>(*outer_nodes_itr);
if (collider) {
outer_colliders.push_back(collider);
}
}
for (std::vector<KRCollider*>::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;
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<KRNode *>::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*outer_nodes_itr);
if(collider) {
if(collider->rayCast(v0, dir, hitinfo, layer_mask)) hit_found = true;
}
bool hit_found = false;
for (std::set<KRNode*>::iterator outer_nodes_itr = m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) {
KRCollider* collider = dynamic_cast<KRCollider*>(*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<KRCollider *> outer_colliders;
bool hit_found = false;
std::vector<KRCollider*> outer_colliders;
for(std::set<KRNode *>::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*outer_nodes_itr);
if(collider) {
outer_colliders.push_back(collider);
}
}
for(std::vector<KRCollider *>::iterator itr=outer_colliders.begin(); itr != outer_colliders.end(); itr++) {
if((*itr)->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true;
for (std::set<KRNode*>::iterator outer_nodes_itr = m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) {
KRCollider* collider = dynamic_cast<KRCollider*>(*outer_nodes_itr);
if (collider) {
outer_colliders.push_back(collider);
}
}
for (std::vector<KRCollider*>::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;
if (m_pRootNode) {
if (m_pRootNode->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true;
}
return hit_found;
}

View File

@@ -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<KRNode *> &getOuterSceneNodes();
KROctreeNode* getRootNode();
std::set<KRNode*>& 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<KRNode *> m_outerSceneNodes;
KROctreeNode* m_pRootNode;
std::set<KRNode*> m_outerSceneNodes;
void shrink();
void shrink();
};

View File

@@ -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;
m_parent = parent;
for(int i=0; i<8; i++) m_children[i] = NULL;
for (int i = 0; i < 8; i++) {
m_children[i] = NULL;
}
m_occlusionQuery = 0;
m_occlusionTested = false;
m_activeQuery = false;
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;
// 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;
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;
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();
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)
);
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)
int KROctreeNode::getChildIndex(KRNode* pNode)
{
for(int iChild=0; iChild < 8; iChild++) {
if(getChildBounds(iChild).contains(pNode->getBounds())) {
return iChild;
}
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<KRNode *> &KROctreeNode::getSceneNodes()
std::set<KRNode*>& 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<KRNode *>::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*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<KRNode*>::iterator nodes_itr = m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) {
KRCollider* collider = dynamic_cast<KRCollider*>(*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<KRNode*>::iterator nodes_itr = m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) {
KRCollider* collider = dynamic_cast<KRCollider*>(*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<KRNode*>::iterator nodes_itr = m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) {
KRCollider* collider = dynamic_cast<KRCollider*>(*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<KRNode *>::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*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<KRNode *>::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*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;
}

View File

@@ -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<KRNode *> &getSceneNodes();
KROctreeNode** getChildren();
std::set<KRNode*>& 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::set<KRNode *>m_sceneNodes;
std::set<KRNode*>m_sceneNodes;
};

View File

@@ -30,7 +30,7 @@
//
#include "KRParticleSystem.h"
KRParticleSystem::KRParticleSystem(KRScene &scene, std::string name) : KRNode(scene, name)
KRParticleSystem::KRParticleSystem(KRScene& scene, std::string name) : KRNode(scene, name)
{
}
@@ -40,14 +40,14 @@ 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;
}

View File

@@ -33,20 +33,21 @@
#include "KRNode.h"
class KRParticleSystem : public KRNode {
class KRParticleSystem : public KRNode
{
public:
virtual ~KRParticleSystem();
virtual ~KRParticleSystem();
virtual std::string getElementName() = 0;
virtual void loadXML(tinyxml2::XMLElement *e);
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
virtual std::string getElementName() = 0;
virtual void loadXML(tinyxml2::XMLElement* e);
virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent);
virtual AABB getBounds() = 0;
virtual AABB getBounds() = 0;
virtual void render(RenderInfo& ri) = 0;
virtual void render(RenderInfo& ri) = 0;
protected:
KRParticleSystem(KRScene &scene, std::string name);
KRParticleSystem(KRScene& scene, std::string name);
private:
};

View File

@@ -35,9 +35,9 @@
#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()
@@ -47,69 +47,70 @@ 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) {
void KRParticleSystemNewtonian::render(RenderInfo& ri)
{
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRNode::render(ri);
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);
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;
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);
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);
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);
}
vkCmdDraw(ri.commandBuffer, particle_count * 3, 1, 0, 0);
}
}
}

View File

@@ -33,23 +33,24 @@
#include "KRParticleSystem.h"
class KRParticleSystemNewtonian : public KRParticleSystem {
class KRParticleSystemNewtonian : public KRParticleSystem
{
public:
KRParticleSystemNewtonian(KRScene &scene, std::string name);
virtual ~KRParticleSystemNewtonian();
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 std::string getElementName();
virtual void loadXML(tinyxml2::XMLElement* e);
virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent);
virtual AABB getBounds();
virtual AABB getBounds();
virtual void render(RenderInfo& ri);
virtual void render(RenderInfo& ri);
virtual void physicsUpdate(float deltaTime);
virtual bool hasPhysics();
virtual void physicsUpdate(float deltaTime);
virtual bool hasPhysics();
private:
float m_particlesAbsoluteTime;
float m_particlesAbsoluteTime;
};

View File

@@ -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<ShaderStages>(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;
@@ -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<size_t>(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<size_t>(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<size_t>(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<size_t>(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<KRPointLight *> *point_lights, const std::vector<KRDirectionalLight *> *directional_lights, const std::vector<KRSpotLight *> *spot_lights, const KRNode::RenderPass &renderPass)
bool KRPipeline::bind(VkCommandBuffer& commandBuffer, KRCamera& camera, const KRViewport& viewport, const Matrix4& matModel, const std::vector<KRPointLight*>* point_lights, const std::vector<KRDirectionalLight*>* directional_lights, const std::vector<KRSpotLight*>* spot_lights, const KRNode::RenderPass& renderPass)
{
setUniform(Uniform::absolute_time, getContext().getAbsoluteTime());
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) {
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<KRDirectionalLight*>::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));
}
m_pContext->getTextureManager()->_setWrapModeS(3, GL_CLAMP_TO_EDGE);
m_pContext->getTextureManager()->_setWrapModeT(3, GL_CLAMP_TO_EDGE);
if (directional_lights) {
for (std::vector<KRDirectionalLight*>::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<Uniform>(static_cast<int>(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();
Matrix4 matBias;
matBias.translate(1.0, 1.0, 1.0);
matBias.scale(0.5);
for (int iShadow = 0; iShadow < cShadowBuffers; iShadow++) {
setUniform(static_cast<Uniform>(static_cast<int>(Uniform::shadow_mvp1) + iShadow), matModel * directional_light->getShadowViewports()[iShadow].getViewProjectionMatrix() * matBias);
}
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::light_direction_model_space)) {
Matrix4 inverseModelMatrix = matModel;
inverseModelMatrix.invert();
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);
// Bind the light direction vector
Vector3 lightDirObject = Matrix4::Dot(inverseModelMatrix, directional_light->getWorldLightDirection());
lightDirObject.normalize();
setUniform(Uniform::light_direction_model_space, lightDirObject);
}
}
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);
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()

View File

@@ -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<KRShader*>& shaders, uint32_t vertexAttributes, ModelFormat modelFormat);
virtual ~KRPipeline();
const char *getKey() const;
KRPipeline(KRContext& context, KRSurface& surface, const PipelineInfo& info, const char* szKey, const std::vector<KRShader*>& 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<KRPointLight *> *point_lights, const std::vector<KRDirectionalLight *> *directional_lights, const std::vector<KRSpotLight *>*spot_lights, const KRNode::RenderPass &renderPass);
bool bind(VkCommandBuffer& commandBuffer, KRCamera& camera, const KRViewport& viewport, const Matrix4& matModel, const std::vector<KRPointLight*>* point_lights, const std::vector<KRDirectionalLight*>* directional_lights, const std::vector<KRSpotLight*>* spot_lights, const KRNode::RenderPass& renderPass);
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 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
};
static const size_t kUniformCount = static_cast<size_t>(Uniform::NUM_UNIFORMS);
static const size_t kUniformCount = static_cast<size_t>(Uniform::NUM_UNIFORMS);
enum class ShaderStages : uint8_t
{
vertex = 0,
fragment,
geometry,
compute,
shaderStageCount
};
enum class ShaderStages : uint8_t
{
vertex = 0,
fragment,
geometry,
compute,
shaderStageCount
};
static const size_t kShaderStageCount = static_cast<size_t>(ShaderStages::shaderStageCount);
static const size_t kShaderStageCount = static_cast<size_t>(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);
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<size_t>(ShaderStages::shaderStageCount)];
struct PushConstantStageInfo
{
int offset[kUniformCount];
__uint8_t size[kUniformCount];
uint8_t* buffer;
int bufferSize;
VkPipelineLayout layout;
};
PushConstantStageInfo m_pushConstants[static_cast<size_t>(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);
};

View File

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

View File

@@ -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);
KRPipelineManager(KRContext& context);
virtual ~KRPipelineManager();
KRPipeline* get(const char* szKey);
KRPipeline* getPipeline(KRSurface& surface, const PipelineInfo& info);
KRPipeline* getPipeline(KRSurface& surface, const PipelineInfo& info);
size_t getPipelineHandlesUsed();
size_t getPipelineHandlesUsed();
KRPipeline *m_active_pipeline;
KRPipeline* m_active_pipeline;
private:
typedef std::map<std::pair<std::string, std::vector<int> >, KRPipeline*> PipelineMap;

View File

@@ -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;
if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
KRLight::render(ri);
KRLight::render(ri);
bool bVisualize = ri.renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && ri.camera->settings.bShowDeferred;
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
if (ri.renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS || bVisualize) {
// Lights are rendered on the second pass of the deferred renderer
std::vector<KRPointLight *> this_light;
this_light.push_back(this);
std::vector<KRPointLight*> this_light;
this_light.push_back(this);
Vector3 light_position = getLocalTranslation();
Vector3 light_position = getLocalTranslation();
float influence_radius = m_decayStart - sqrt(m_intensity * 0.01f) / sqrt(KRLIGHT_MIN_INFLUENCE);
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);
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
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);
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());
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;
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);
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();
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));
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, m_sphereVertices));
vkCmdDraw(ri.commandBuffer, m_cVertices, 1, 0, 0);
}
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/
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);
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;
class Facet3 {
public:
Facet3() {
}
~Facet3() {
}
Vector3 p1;
Vector3 p2;
Vector3 p3;
};
std::vector<Facet3> f = std::vector<Facet3>(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;
}
if (m_cVertices != facet_count * 3) {
if (m_sphereVertices) {
free(m_sphereVertices);
m_sphereVertices = NULL;
}
m_cVertices = facet_count * 3;
class Facet3
{
public:
Facet3()
{
}
~Facet3()
{
}
Vector3 p1;
Vector3 p2;
Vector3 p3;
};
std::vector<Facet3> f = std::vector<Facet3>(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;
}
}
}

View File

@@ -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();
static void InitNodeInfo(KrNodeInfo* nodeInfo);
KRPointLight(KRScene& scene, std::string name);
virtual ~KRPointLight();
virtual std::string getElementName();
virtual AABB getBounds();
virtual std::string getElementName();
virtual AABB getBounds();
virtual void render(RenderInfo& ri);
virtual void render(RenderInfo& ri);
private:
void generateMesh();
void generateMesh();
float *m_sphereVertices;
int m_cVertices;
float* m_sphereVertices;
int m_cVertices;
};

View File

@@ -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<KrSurfaceHandle, std::unique_ptr<KRSurface>>& 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;

View File

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

View File

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

View File

@@ -33,72 +33,72 @@
KRRenderSettings::KRRenderSettings()
{
siren_enable = true;
siren_enable_reverb = true;
siren_enable_hrtf = true;
siren_reverb_max_length = 2.0f;
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;
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();
ambient_intensity = Vector3::Zero();
light_intensity = Vector3::One();
perspective_fov = 45.0f * D2R;
perspective_nearz = 0.3f; // was 0.05f
perspective_farz = 1000.0f;
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;
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;
bEnableFlash = false;
flash_intensity = 1.0f;
flash_depth = 0.7f;
flash_falloff = 0.5f;
bEnableVignette = false;
vignette_radius = 0.4f;
vignette_falloff = 1.0f;
bEnableVignette = false;
vignette_radius = 0.4f;
vignette_falloff = 1.0f;
m_cShadowBuffers = 0;
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;
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;
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;
dust_particle_intensity = 0.25f;
dust_particle_enable = false;
m_lodBias = 0.0f;
m_lodBias = 0.0f;
debug_display = KRENGINE_DEBUG_DISPLAY_NONE;
debug_display = KRENGINE_DEBUG_DISPLAY_NONE;
}
KRRenderSettings::~KRRenderSettings()
@@ -106,122 +106,124 @@ 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;
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;
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;
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;
bEnableVignette = s.bEnableVignette;
vignette_radius = s.vignette_radius;
vignette_falloff = s.vignette_falloff;
m_viewportSize=s.m_viewportSize;
m_viewportSize = s.m_viewportSize;
m_cShadowBuffers=s.m_cShadowBuffers;
m_cShadowBuffers = s.m_cShadowBuffers;
m_debug_text=s.m_debug_text;
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;
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;
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;
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;
m_lodBias = s.m_lodBias;
m_enable_realtime_occlusion = s.m_enable_realtime_occlusion;
max_anisotropy = s.max_anisotropy;
max_anisotropy = s.max_anisotropy;
return *this;
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;
}

View File

@@ -33,104 +33,106 @@
#include "KREngine-common.h"
class KRRenderSettings {
class KRRenderSettings
{
public:
KRRenderSettings();
~KRRenderSettings();
KRRenderSettings();
~KRRenderSettings();
// Overload assignment operator
KRRenderSettings& operator=(const KRRenderSettings &s);
// Overload assignment operator
KRRenderSettings& operator=(const KRRenderSettings& s);
const Vector2 &getViewportSize();
void setViewportSize(const Vector2 &size);
const Vector2& getViewportSize();
void setViewportSize(const Vector2& size);
float getPerspectiveNearZ();
float getPerspectiveFarZ();
void setPerspectiveNear(float v);
void setPerpsectiveFarZ(float v);
float getPerspectiveNearZ();
float getPerspectiveFarZ();
void setPerspectiveNear(float v);
void setPerpsectiveFarZ(float v);
float getLODBias();
void setLODBias(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;
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;
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;
bool bEnableVignette;
float vignette_radius;
float vignette_falloff;
Vector2 m_viewportSize;
Vector2 m_viewportSize;
int m_cShadowBuffers;
int m_cShadowBuffers;
std::string m_debug_text;
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;
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 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;
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;
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 getEnableRealtimeOcclusion();
void setEnableRealtimeOcclusion(bool enable);
bool siren_enable;
bool siren_enable_reverb;
bool siren_enable_hrtf;
float siren_reverb_max_length;
bool siren_enable;
bool siren_enable_reverb;
bool siren_enable_hrtf;
float siren_reverb_max_length;
float max_anisotropy;
float max_anisotropy;
private:
float m_lodBias;
bool m_enable_realtime_occlusion;
float m_lodBias;
bool m_enable_realtime_occlusion;
};

View File

@@ -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));
KRScene* KRResource::LoadBlenderScene(KRContext& context, const std::string& path)
{
KRScene* pScene = new KRScene(context, KRResource::GetFileBase(path));
KRDataBlock data;
KRDataBlock data;
if(data.load(path)) {
//KRBlendFile blend_file = KRBlendFile(pFile);
}
if (data.load(path)) {
//KRBlendFile blend_file = KRBlendFile(pFile);
}
return pScene;
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);
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());
}
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
__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;
}
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;
}

View File

@@ -31,38 +31,41 @@
#pragma once
class KRBlendFile {
class KRBlendFile
{
public:
KRBlendFile(const void *pFile);
~KRBlendFile();
KRBlendFile(const void* pFile);
~KRBlendFile();
class Block {
public:
Block(KRBlendFile *blendFile, unsigned char *&scan);
~Block();
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;
};
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);
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);
__int32_t readInt(unsigned char*& scan);
__int64_t readPointer(unsigned char*& scan);
std::vector<Block> m_blocks;
std::vector<Block> m_blocks;
};

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More