Auto format C++ source
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
1256
kraken/KRCamera.cpp
1256
kraken/KRCamera.cpp
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -37,43 +37,46 @@
|
||||
|
||||
#include "KREngine-common.h"
|
||||
|
||||
typedef enum KREngineParameterType {KRENGINE_PARAMETER_INT, KRENGINE_PARAMETER_FLOAT, KRENGINE_PARAMETER_BOOL} KREngineParameterType;
|
||||
typedef enum KREngineParameterType
|
||||
{
|
||||
KRENGINE_PARAMETER_INT, KRENGINE_PARAMETER_FLOAT, KRENGINE_PARAMETER_BOOL
|
||||
} KREngineParameterType;
|
||||
|
||||
namespace kraken {
|
||||
void set_parameter(const std::string ¶meter_name, float parameter_value);
|
||||
void set_debug_text(const std::string &print_text);
|
||||
void set_parameter(const std::string& parameter_name, float parameter_value);
|
||||
void set_debug_text(const std::string& print_text);
|
||||
};
|
||||
|
||||
#ifdef __OBJC__
|
||||
|
||||
@interface KREngine : NSObject
|
||||
|
||||
+ (KREngine *)sharedInstance;
|
||||
+ (KREngine*)sharedInstance;
|
||||
|
||||
@property(nonatomic, readonly) NSDictionary *parameter_names;
|
||||
@property(nonatomic, assign) KRContext *context;
|
||||
@property(nonatomic, retain) NSString *debug_text;
|
||||
@property(nonatomic, assign, readonly) KRRenderSettings *settings;
|
||||
@property(nonatomic, readonly) NSDictionary* parameter_names;
|
||||
@property(nonatomic, assign) KRContext* context;
|
||||
@property(nonatomic, retain) NSString* debug_text;
|
||||
@property(nonatomic, assign, readonly) KRRenderSettings* settings;
|
||||
|
||||
- (id)init;
|
||||
- (BOOL)loadResource:(NSString *)path;
|
||||
-(id)init;
|
||||
-(BOOL)loadResource:(NSString*)path;
|
||||
|
||||
// Parameter enumeration interface
|
||||
-(int)getParameterCount;
|
||||
-(NSString *)getParameterNameWithIndex: (int)i;
|
||||
-(NSString *)getParameterLabelWithIndex: (int)i;
|
||||
-(NSString*)getParameterNameWithIndex: (int)i;
|
||||
-(NSString*)getParameterLabelWithIndex: (int)i;
|
||||
-(KREngineParameterType)getParameterTypeWithIndex: (int)i;
|
||||
-(float)getParameterMinWithIndex: (int)i;
|
||||
-(float)getParameterMaxWithIndex: (int)i;
|
||||
-(float)getParameterValueWithIndex: (int)i;
|
||||
-(void)setParameterValueWithIndex: (int)i Value: (float)v;
|
||||
-(void)setParameterValueWithName: (NSString *)name Value: (float)v;
|
||||
-(int)getParameterIndexWithName: (NSString *)name;
|
||||
-(void)setParameterValueWithIndex: (int)i Value : (float)v;
|
||||
-(void)setParameterValueWithName: (NSString*)name Value : (float)v;
|
||||
-(int)getParameterIndexWithName: (NSString*)name;
|
||||
|
||||
- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime AndWidth: (int)width AndHeight: (int)height AndDefaultFBO: (GLint)defaultFBO;
|
||||
-(void)renderScene: (KRScene*)pScene WithDeltaTime : (float)deltaTime AndWidth : (int)width AndHeight : (int)height AndDefaultFBO : (GLint)defaultFBO;
|
||||
//- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime;
|
||||
- (void)setNearZ: (float)dNearZ;
|
||||
- (void)setFarZ: (float)dFarZ;
|
||||
-(void)setNearZ: (float)dNearZ;
|
||||
-(void)setFarZ: (float)dFarZ;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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, ¶ms));
|
||||
GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery));
|
||||
|
||||
if(params) {
|
||||
|
||||
if(!m_pFlareTexture && m_flareTexture.size()) {
|
||||
m_pFlareTexture = getContext().getTextureManager()->getTexture(m_flareTexture);
|
||||
}
|
||||
|
||||
if(m_pFlareTexture) {
|
||||
KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES;
|
||||
|
||||
// Render light flare on transparency pass
|
||||
PipelineInfo info{};
|
||||
std::string shader_name("flare");
|
||||
info.shader_name = &shader_name;
|
||||
info.pCamera = ri.camera;
|
||||
info.point_lights = &ri.point_lights;
|
||||
info.directional_lights = &ri.directional_lights;
|
||||
info.spot_lights = &ri.spot_lights;
|
||||
info.renderPass = ri.renderPass;
|
||||
info.rasterMode = RasterMode::kAdditiveNoTest;
|
||||
info.cullMode = CullMode::kCullNone;
|
||||
info.vertexAttributes = vertices.getVertexAttributes();
|
||||
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
|
||||
|
||||
|
||||
KRPipeline *pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info);
|
||||
pShader->setUniform(KRPipeline::Uniform::material_alpha, 1.0f);
|
||||
pShader->setUniform(KRPipeline::Uniform::flare_size, m_flareSize);
|
||||
pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass);
|
||||
|
||||
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, ¶ms));
|
||||
GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery));
|
||||
|
||||
if (params) {
|
||||
|
||||
if (!m_pFlareTexture && m_flareTexture.size()) {
|
||||
m_pFlareTexture = getContext().getTextureManager()->getTexture(m_flareTexture);
|
||||
}
|
||||
|
||||
if (m_pFlareTexture) {
|
||||
KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES;
|
||||
|
||||
// Render light flare on transparency pass
|
||||
PipelineInfo info{};
|
||||
std::string shader_name("flare");
|
||||
info.shader_name = &shader_name;
|
||||
info.pCamera = ri.camera;
|
||||
info.point_lights = &ri.point_lights;
|
||||
info.directional_lights = &ri.directional_lights;
|
||||
info.spot_lights = &ri.spot_lights;
|
||||
info.renderPass = ri.renderPass;
|
||||
info.rasterMode = RasterMode::kAdditiveNoTest;
|
||||
info.cullMode = CullMode::kCullNone;
|
||||
info.vertexAttributes = vertices.getVertexAttributes();
|
||||
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
|
||||
|
||||
|
||||
KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info);
|
||||
pShader->setUniform(KRPipeline::Uniform::material_alpha, 1.0f);
|
||||
pShader->setUniform(KRPipeline::Uniform::flare_size, m_flareSize);
|
||||
pShader->bind(ri.commandBuffer, *ri.camera, ri.viewport, getModelMatrix(), &ri.point_lights, &ri.directional_lights, &ri.spot_lights, ri.renderPass);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
2576
kraken/KRMesh.cpp
2576
kraken/KRMesh.cpp
File diff suppressed because it is too large
Load Diff
347
kraken/KRMesh.h
347
kraken/KRMesh.h
@@ -65,230 +65,241 @@ enum class ModelFormat : __uint8_t
|
||||
KRENGINE_MODEL_FORMAT_INDEXED_STRIP
|
||||
};
|
||||
|
||||
class KRMesh : public KRResource {
|
||||
class KRMesh : public KRResource
|
||||
{
|
||||
|
||||
public:
|
||||
static void parseName(const std::string& name, std::string& lodBaseName, int& lodCoverage);
|
||||
static void parseName(const std::string& name, std::string& lodBaseName, int& lodCoverage);
|
||||
|
||||
KRMesh(KRContext &context, std::string name, KRDataBlock *data);
|
||||
KRMesh(KRContext &context, std::string name);
|
||||
virtual ~KRMesh();
|
||||
KRMesh(KRContext& context, std::string name, KRDataBlock* data);
|
||||
KRMesh(KRContext& context, std::string name);
|
||||
virtual ~KRMesh();
|
||||
|
||||
kraken_stream_level getStreamLevel();
|
||||
void preStream(float lodCoverage);
|
||||
kraken_stream_level getStreamLevel();
|
||||
void preStream(float lodCoverage);
|
||||
|
||||
bool hasTransparency();
|
||||
bool hasTransparency();
|
||||
|
||||
typedef enum {
|
||||
KRENGINE_ATTRIB_VERTEX = 0,
|
||||
KRENGINE_ATTRIB_NORMAL,
|
||||
KRENGINE_ATTRIB_TANGENT,
|
||||
KRENGINE_ATTRIB_TEXUVA,
|
||||
KRENGINE_ATTRIB_TEXUVB,
|
||||
KRENGINE_ATTRIB_BONEINDEXES,
|
||||
KRENGINE_ATTRIB_BONEWEIGHTS,
|
||||
KRENGINE_ATTRIB_VERTEX_SHORT,
|
||||
KRENGINE_ATTRIB_NORMAL_SHORT,
|
||||
KRENGINE_ATTRIB_TANGENT_SHORT,
|
||||
KRENGINE_ATTRIB_TEXUVA_SHORT,
|
||||
KRENGINE_ATTRIB_TEXUVB_SHORT,
|
||||
KRENGINE_NUM_ATTRIBUTES
|
||||
} vertex_attrib_t;
|
||||
typedef enum
|
||||
{
|
||||
KRENGINE_ATTRIB_VERTEX = 0,
|
||||
KRENGINE_ATTRIB_NORMAL,
|
||||
KRENGINE_ATTRIB_TANGENT,
|
||||
KRENGINE_ATTRIB_TEXUVA,
|
||||
KRENGINE_ATTRIB_TEXUVB,
|
||||
KRENGINE_ATTRIB_BONEINDEXES,
|
||||
KRENGINE_ATTRIB_BONEWEIGHTS,
|
||||
KRENGINE_ATTRIB_VERTEX_SHORT,
|
||||
KRENGINE_ATTRIB_NORMAL_SHORT,
|
||||
KRENGINE_ATTRIB_TANGENT_SHORT,
|
||||
KRENGINE_ATTRIB_TEXUVA_SHORT,
|
||||
KRENGINE_ATTRIB_TEXUVB_SHORT,
|
||||
KRENGINE_NUM_ATTRIBUTES
|
||||
} vertex_attrib_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
ModelFormat format;
|
||||
std::vector<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);
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
1579
kraken/KRNode.cpp
1579
kraken/KRNode.cpp
File diff suppressed because it is too large
Load Diff
452
kraken/KRNode.h
452
kraken/KRNode.h
@@ -56,291 +56,295 @@ class KRPointLight;
|
||||
class KRSpotLight;
|
||||
class KRDirectionalLight;
|
||||
namespace tinyxml2 {
|
||||
class XMLNode;
|
||||
class XMLAttribute;
|
||||
class XMLNode;
|
||||
class XMLAttribute;
|
||||
}
|
||||
|
||||
class KRNode : public KRContextObject
|
||||
{
|
||||
public:
|
||||
enum RenderPass {
|
||||
RENDER_PASS_FORWARD_OPAQUE,
|
||||
RENDER_PASS_DEFERRED_GBUFFER,
|
||||
RENDER_PASS_DEFERRED_LIGHTS,
|
||||
RENDER_PASS_DEFERRED_OPAQUE,
|
||||
RENDER_PASS_FORWARD_TRANSPARENT,
|
||||
RENDER_PASS_PARTICLE_OCCLUSION,
|
||||
RENDER_PASS_ADDITIVE_PARTICLES,
|
||||
RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE,
|
||||
RENDER_PASS_GENERATE_SHADOWMAPS,
|
||||
RENDER_PASS_SHADOWMAP,
|
||||
RENDER_PASS_PRESTREAM
|
||||
};
|
||||
enum 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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user