lod_group nodes now have a reference point attribute, enabling use of lod_groups containing objects with a centre that is not at the pivot point of the lod_group node.
Numerous small bug fixes.
This commit is contained in:
@@ -279,3 +279,14 @@ bool KRAABB::intersectsRay(const KRVector3 &v1, const KRVector3 &dir) const
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KRAABB::encapsulate(const KRAABB & b)
|
||||||
|
{
|
||||||
|
if(b.min.x < min.x) min.x = b.min.x;
|
||||||
|
if(b.min.y < min.y) min.y = b.min.y;
|
||||||
|
if(b.min.z < min.z) min.z = b.min.z;
|
||||||
|
|
||||||
|
if(b.max.x > max.x) max.x = b.max.x;
|
||||||
|
if(b.max.y > max.y) max.y = b.max.y;
|
||||||
|
if(b.max.z > max.z) max.z = b.max.z;
|
||||||
|
}
|
||||||
@@ -34,6 +34,7 @@ public:
|
|||||||
bool visible(const KRMat4 &matViewProjection) const;
|
bool visible(const KRMat4 &matViewProjection) const;
|
||||||
bool intersectsLine(const KRVector3 &v1, const KRVector3 &v2) const;
|
bool intersectsLine(const KRVector3 &v1, const KRVector3 &v2) const;
|
||||||
bool intersectsRay(const KRVector3 &v1, const KRVector3 &dir) const;
|
bool intersectsRay(const KRVector3 &v1, const KRVector3 &dir) const;
|
||||||
|
void encapsulate(const KRAABB & b);
|
||||||
|
|
||||||
KRAABB& operator =(const KRAABB& b);
|
KRAABB& operator =(const KRAABB& b);
|
||||||
bool operator ==(const KRAABB& b) const;
|
bool operator ==(const KRAABB& b) const;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ KRLODGroup::KRLODGroup(KRScene &scene, std::string name) : KRNode(scene, name)
|
|||||||
{
|
{
|
||||||
m_min_distance = 0.0f;
|
m_min_distance = 0.0f;
|
||||||
m_max_distance = 0.0f;
|
m_max_distance = 0.0f;
|
||||||
|
m_referencePoint = KRVector3::Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
KRLODGroup::~KRLODGroup()
|
KRLODGroup::~KRLODGroup()
|
||||||
@@ -28,6 +29,10 @@ tinyxml2::XMLElement *KRLODGroup::saveXML( tinyxml2::XMLNode *parent)
|
|||||||
tinyxml2::XMLElement *e = KRNode::saveXML(parent);
|
tinyxml2::XMLElement *e = KRNode::saveXML(parent);
|
||||||
e->SetAttribute("min_distance", m_min_distance);
|
e->SetAttribute("min_distance", m_min_distance);
|
||||||
e->SetAttribute("max_distance", m_max_distance);
|
e->SetAttribute("max_distance", m_max_distance);
|
||||||
|
|
||||||
|
e->SetAttribute("reference_x", m_referencePoint.x);
|
||||||
|
e->SetAttribute("reference_y", m_referencePoint.y);
|
||||||
|
e->SetAttribute("reference_z", m_referencePoint.z);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,13 +49,49 @@ void KRLODGroup::loadXML(tinyxml2::XMLElement *e)
|
|||||||
if(e->QueryFloatAttribute("max_distance", &m_max_distance) != tinyxml2::XML_SUCCESS) {
|
if(e->QueryFloatAttribute("max_distance", &m_max_distance) != tinyxml2::XML_SUCCESS) {
|
||||||
m_max_distance = 0.0f;
|
m_max_distance = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float x=0.0f, y=0.0f, z=0.0f;
|
||||||
|
if(e->QueryFloatAttribute("reference_x", &x) != tinyxml2::XML_SUCCESS) {
|
||||||
|
x = 0.0f;
|
||||||
|
}
|
||||||
|
if(e->QueryFloatAttribute("reference_y", &y) != tinyxml2::XML_SUCCESS) {
|
||||||
|
y = 0.0f;
|
||||||
|
}
|
||||||
|
if(e->QueryFloatAttribute("reference_z", &z) != tinyxml2::XML_SUCCESS) {
|
||||||
|
z = 0.0f;
|
||||||
|
}
|
||||||
|
m_referencePoint = KRVector3(x,y,z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const KRVector3 KRLODGroup::getReferencePoint()
|
||||||
|
{
|
||||||
|
return m_referencePoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KRLODGroup::setReferencePoint(const KRVector3 &referencePoint)
|
||||||
|
{
|
||||||
|
m_referencePoint = referencePoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
const KRVector3 KRLODGroup::getWorldReferencePoint()
|
||||||
|
{
|
||||||
|
return localToWorld(m_referencePoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KRLODGroup::getLODVisibility(const KRViewport &viewport)
|
bool KRLODGroup::getLODVisibility(const KRViewport &viewport)
|
||||||
{
|
{
|
||||||
// Compare square distances as sqrt is expensive
|
if(m_min_distance == 0 && m_max_distance == 0) {
|
||||||
float sqr_distance = (viewport.getCameraPosition() - getWorldTranslation()).sqrMagnitude();
|
return true;
|
||||||
return ((sqr_distance >= m_min_distance * m_min_distance || m_min_distance == 0) && (sqr_distance < m_max_distance * m_max_distance || m_max_distance == 0));
|
} else {
|
||||||
|
// return (m_max_distance == 0); // FINDME, HACK - Test code to enable only the lowest LOD group
|
||||||
|
float lod_bias = 1.0f;
|
||||||
|
|
||||||
|
// Compare square distances as sqrt is expensive
|
||||||
|
float sqr_distance = (viewport.getCameraPosition() - getWorldReferencePoint()).sqrMagnitude() * (lod_bias * lod_bias);
|
||||||
|
return ((sqr_distance >= m_min_distance * m_min_distance || m_min_distance == 0) && (sqr_distance < m_max_distance * m_max_distance || m_max_distance == 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRLODGroup::updateLODVisibility(const KRViewport &viewport)
|
void KRLODGroup::updateLODVisibility(const KRViewport &viewport)
|
||||||
|
|||||||
@@ -28,10 +28,16 @@ public:
|
|||||||
void setMinDistance(float min_distance);
|
void setMinDistance(float min_distance);
|
||||||
void setMaxDistance(float max_distance);
|
void setMaxDistance(float max_distance);
|
||||||
|
|
||||||
|
const KRVector3 getReferencePoint();
|
||||||
|
void setReferencePoint(const KRVector3 &referencePoint);
|
||||||
|
|
||||||
|
const KRVector3 getWorldReferencePoint();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool getLODVisibility(const KRViewport &viewport);
|
bool getLODVisibility(const KRViewport &viewport);
|
||||||
float m_min_distance;
|
float m_min_distance;
|
||||||
float m_max_distance;
|
float m_max_distance;
|
||||||
|
KRVector3 m_referencePoint; // Point of reference, used for distance calculation. Usually set to the bounding box center
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -64,19 +64,17 @@ KRMeshManager::~KRMeshManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KRMesh *KRMeshManager::loadModel(const char *szName, KRDataBlock *pData) {
|
KRMesh *KRMeshManager::loadModel(const char *szName, KRDataBlock *pData) {
|
||||||
|
KRMesh *pModel = new KRMesh(*m_pContext, szName, pData);
|
||||||
std::string lowerName = szName;
|
|
||||||
std::transform(lowerName.begin(), lowerName.end(),
|
|
||||||
lowerName.begin(), ::tolower);
|
|
||||||
|
|
||||||
|
|
||||||
KRMesh *pModel = new KRMesh(*m_pContext, lowerName, pData);
|
|
||||||
addModel(pModel);
|
addModel(pModel);
|
||||||
return pModel;
|
return pModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRMeshManager::addModel(KRMesh *model) {
|
void KRMeshManager::addModel(KRMesh *model) {
|
||||||
m_models.insert(std::pair<std::string, KRMesh *>(model->getLODBaseName(), 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<KRMesh *> KRMeshManager::getModel(const char *szName) {
|
std::vector<KRMesh *> KRMeshManager::getModel(const char *szName) {
|
||||||
@@ -101,7 +99,7 @@ std::vector<KRMesh *> KRMeshManager::getModel(const char *szName) {
|
|||||||
return matching_models;
|
return matching_models;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::multimap<std::string, KRMesh *> KRMeshManager::getModels() {
|
std::multimap<std::string, KRMesh *> &KRMeshManager::getModels() {
|
||||||
return m_models;
|
return m_models;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public:
|
|||||||
void addModel(KRMesh *model);
|
void addModel(KRMesh *model);
|
||||||
|
|
||||||
std::vector<std::string> getModelNames();
|
std::vector<std::string> getModelNames();
|
||||||
std::multimap<std::string, KRMesh *> getModels();
|
std::multimap<std::string, KRMesh *> &getModels();
|
||||||
|
|
||||||
|
|
||||||
void bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights, bool static_vbo);
|
void bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights, bool static_vbo);
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ const KRVector3 &KRNode::getInitialLocalRotation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const KRVector3 KRNode::getWorldTranslation() {
|
const KRVector3 KRNode::getWorldTranslation() {
|
||||||
return KRMat4::Dot(getModelMatrix(), KRVector3::Zero());
|
return localToWorld(KRVector3::Zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
const KRVector3 KRNode::getWorldScale() {
|
const KRVector3 KRNode::getWorldScale() {
|
||||||
@@ -278,7 +278,20 @@ KRScene &KRNode::getScene() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KRAABB KRNode::getBounds() {
|
KRAABB KRNode::getBounds() {
|
||||||
return KRAABB::Infinite();
|
KRAABB bounds = KRAABB::Infinite();
|
||||||
|
|
||||||
|
bool first_child = true;
|
||||||
|
for(std::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) {
|
||||||
|
KRNode *child = (*itr);
|
||||||
|
if(first_child) {
|
||||||
|
first_child = false;
|
||||||
|
bounds = child->getBounds();
|
||||||
|
} else {
|
||||||
|
bounds.encapsulate(child->getBounds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRNode::invalidateModelMatrix()
|
void KRNode::invalidateModelMatrix()
|
||||||
@@ -475,3 +488,13 @@ bool KRNode::lodIsVisible()
|
|||||||
{
|
{
|
||||||
return m_lod_visible;
|
return m_lod_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const KRVector3 KRNode::localToWorld(const KRVector3 &local_point)
|
||||||
|
{
|
||||||
|
return KRMat4::Dot(getModelMatrix(), local_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
const KRVector3 KRNode::worldToLocal(const KRVector3 &world_point)
|
||||||
|
{
|
||||||
|
return KRMat4::Dot(getInverseModelMatrix(), world_point);
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ public:
|
|||||||
const KRVector3 getWorldScale();
|
const KRVector3 getWorldScale();
|
||||||
const KRVector3 getWorldRotation();
|
const KRVector3 getWorldRotation();
|
||||||
|
|
||||||
|
const KRVector3 localToWorld(const KRVector3 &local_point);
|
||||||
|
const KRVector3 worldToLocal(const KRVector3 &world_point);
|
||||||
|
|
||||||
void setWorldTranslation(const KRVector3 &v);
|
void setWorldTranslation(const KRVector3 &v);
|
||||||
void setWorldScale(const KRVector3 &v);
|
void setWorldScale(const KRVector3 &v);
|
||||||
void setWorldRotation(const KRVector3 &v);
|
void setWorldRotation(const KRVector3 &v);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ KRRenderSettings::KRRenderSettings()
|
|||||||
bEnableSpecular = true;
|
bEnableSpecular = true;
|
||||||
bEnableLightMap = true;
|
bEnableLightMap = true;
|
||||||
bDebugSuperShiny = false;
|
bDebugSuperShiny = false;
|
||||||
bEnableDeferredLighting = true;
|
bEnableDeferredLighting = false;
|
||||||
|
|
||||||
ambient_intensity = KRVector3::Zero();
|
ambient_intensity = KRVector3::Zero();
|
||||||
light_intensity = KRVector3::One();
|
light_intensity = KRVector3::One();
|
||||||
|
|||||||
@@ -95,17 +95,7 @@ std::vector<KRResource *> KRResource::LoadFbx(KRContext &context, const std::str
|
|||||||
if(pNode) {
|
if(pNode) {
|
||||||
pNode->ResetPivotSetAndConvertAnimation();
|
pNode->ResetPivotSetAndConvertAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----====---- Import Scene Graph Nodes ----====----
|
|
||||||
printf("\nLoading scene graph...\n");
|
|
||||||
if(pNode)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < pNode->GetChildCount(); i++)
|
|
||||||
{
|
|
||||||
LoadNode(pFbxScene, pScene->getRootNode(), resources, pGeometryConverter, pNode->GetChild(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----====---- Import Animation Layers ----====----
|
// ----====---- Import Animation Layers ----====----
|
||||||
printf("\nLoading animations...\n");
|
printf("\nLoading animations...\n");
|
||||||
int animation_count = pFbxScene->GetSrcObjectCount<FbxAnimStack>();
|
int animation_count = pFbxScene->GetSrcObjectCount<FbxAnimStack>();
|
||||||
@@ -162,10 +152,24 @@ std::vector<KRResource *> KRResource::LoadFbx(KRContext &context, const std::str
|
|||||||
context.loadResource(file_name);
|
context.loadResource(file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----====---- Import Scene Graph Nodes ----====----
|
||||||
|
printf("\nLoading scene graph...\n");
|
||||||
|
if(pNode)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < pNode->GetChildCount(); i++)
|
||||||
|
{
|
||||||
|
LoadNode(pFbxScene, pScene->getRootNode(), resources, pGeometryConverter, pNode->GetChild(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(std::map<std::string, KRTexture *>::iterator texture_itr = context.getTextureManager()->getTextures().begin(); texture_itr != context.getTextureManager()->getTextures().end(); texture_itr++) {
|
for(std::map<std::string, KRTexture *>::iterator texture_itr = context.getTextureManager()->getTextures().begin(); texture_itr != context.getTextureManager()->getTextures().end(); texture_itr++) {
|
||||||
resources.push_back((*texture_itr).second);
|
resources.push_back((*texture_itr).second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(std::map<std::string, KRMesh *>::iterator mesh_itr = context.getModelManager()->getModels().begin(); mesh_itr != context.getModelManager()->getModels().end(); mesh_itr++) {
|
||||||
|
resources.push_back((*mesh_itr).second);
|
||||||
|
}
|
||||||
|
|
||||||
DestroySdkObjects(lSdkManager);
|
DestroySdkObjects(lSdkManager);
|
||||||
|
|
||||||
// Compress textures to PVR format
|
// Compress textures to PVR format
|
||||||
@@ -727,7 +731,6 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vector<KRResource
|
|||||||
// printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]);
|
// printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]);
|
||||||
// printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]);
|
// printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]);
|
||||||
|
|
||||||
|
|
||||||
KFbxNodeAttribute::EType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType());
|
KFbxNodeAttribute::EType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType());
|
||||||
if(attribute_type == KFbxNodeAttribute::eLODGroup) {
|
if(attribute_type == KFbxNodeAttribute::eLODGroup) {
|
||||||
std::string name = GetFbxObjectName(pNode);
|
std::string name = GetFbxObjectName(pNode);
|
||||||
@@ -741,6 +744,8 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vector<KRResource
|
|||||||
group_min_distance = fbx_lod_group->MinDistance.Get();
|
group_min_distance = fbx_lod_group->MinDistance.Get();
|
||||||
group_max_distance = fbx_lod_group->MinDistance.Get();
|
group_max_distance = fbx_lod_group->MinDistance.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KRVector3 reference_point;
|
||||||
// Create a lod_group node for each fbx child node
|
// Create a lod_group node for each fbx child node
|
||||||
int child_count = pNode->GetChildCount();
|
int child_count = pNode->GetChildCount();
|
||||||
for(int i = 0; i < child_count; i++)
|
for(int i = 0; i < child_count; i++)
|
||||||
@@ -792,6 +797,13 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vector<KRResource
|
|||||||
parent_node->addChild(new_node);
|
parent_node->addChild(new_node);
|
||||||
|
|
||||||
LoadNode(pFbxScene, new_node, resources, pGeometryConverter, pNode->GetChild(i));
|
LoadNode(pFbxScene, new_node, resources, pGeometryConverter, pNode->GetChild(i));
|
||||||
|
|
||||||
|
if(i == 0) {
|
||||||
|
// Calculate reference point using the bounding box center from the highest quality LOD level
|
||||||
|
reference_point = new_node->getBounds().center();
|
||||||
|
}
|
||||||
|
|
||||||
|
new_node->setReferencePoint(new_node->worldToLocal(reference_point));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
KRNode *new_node = NULL;
|
KRNode *new_node = NULL;
|
||||||
@@ -1279,7 +1291,8 @@ void LoadMesh(KRContext &context, std::vector<KRResource *> &resources, FbxGeome
|
|||||||
|
|
||||||
KRMesh *new_mesh = new KRMesh(context, pSourceMesh->GetNode()->GetName());
|
KRMesh *new_mesh = new KRMesh(context, pSourceMesh->GetNode()->GetName());
|
||||||
new_mesh->LoadData(vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights,KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES);
|
new_mesh->LoadData(vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights,KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES);
|
||||||
resources.push_back(new_mesh);
|
|
||||||
|
context.getModelManager()->addModel(new_mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) {
|
KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) {
|
||||||
|
|||||||
@@ -489,3 +489,4 @@ bool KRScene::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hiti
|
|||||||
{
|
{
|
||||||
return m_nodeTree.rayCast(v0, dir, hitinfo, layer_mask);
|
return m_nodeTree.rayCast(v0, dir, hitinfo, layer_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user