Add GEVulkanDrawCall
This commit is contained in:
parent
5853d618a6
commit
44b2468003
@ -23,9 +23,10 @@ endif()
|
||||
|
||||
set(GE_SOURCES
|
||||
src/gl.c
|
||||
src/ge_culling_tool.cpp
|
||||
src/ge_dx9_texture.cpp
|
||||
src/ge_main.cpp
|
||||
src/ge_texture.cpp
|
||||
src/ge_dx9_texture.cpp
|
||||
src/ge_vma.cpp
|
||||
src/ge_vulkan_2d_renderer.cpp
|
||||
src/ge_vulkan_animated_mesh_scene_node.cpp
|
||||
@ -33,6 +34,7 @@ set(GE_SOURCES
|
||||
src/ge_vulkan_command_loader.cpp
|
||||
src/ge_vulkan_depth_texture.cpp
|
||||
src/ge_vulkan_driver.cpp
|
||||
src/ge_vulkan_draw_call.cpp
|
||||
src/ge_vulkan_dynamic_buffer.cpp
|
||||
src/ge_vulkan_features.cpp
|
||||
src/ge_vulkan_mesh_cache.cpp
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define HEADER_GE_MAIN_HPP
|
||||
|
||||
#include <IVideoDriver.h>
|
||||
#include <matrix4.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
@ -21,6 +22,7 @@ const std::string& getShaderFolder();
|
||||
GEConfig* getGEConfig();
|
||||
void deinit();
|
||||
uint64_t getMonoTimeMs();
|
||||
void mathPlaneFrustumf(float* out, const irr::core::matrix4& pvm);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2,13 +2,19 @@
|
||||
#define HEADER_GE_VULKAN_SCENE_MANAGER_HPP
|
||||
|
||||
#include "../source/Irrlicht/CSceneManager.h"
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
namespace GE
|
||||
{
|
||||
class GEVulkanCameraSceneNode;
|
||||
class GEVulkanDrawCall;
|
||||
|
||||
class GEVulkanSceneManager : public irr::scene::CSceneManager
|
||||
{
|
||||
private:
|
||||
std::map<GEVulkanCameraSceneNode*, std::unique_ptr<GEVulkanDrawCall> > m_draw_calls;
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
GEVulkanSceneManager(irr::video::IVideoDriver* driver,
|
||||
@ -38,6 +44,15 @@ public:
|
||||
const irr::core::vector3df& rotation = irr::core::vector3df(0, 0, 0),
|
||||
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f),
|
||||
bool alsoAddIfMeshPointerZero = false);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void drawAll(irr::u32 flags = 0xFFFFFFFF);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual irr::u32 registerNodeForRendering(irr::scene::ISceneNode* node,
|
||||
irr::scene::E_SCENE_NODE_RENDER_PASS pass = irr::scene::ESNRP_AUTOMATIC);
|
||||
// ------------------------------------------------------------------------
|
||||
void addDrawCall(GEVulkanCameraSceneNode* cam);
|
||||
// ------------------------------------------------------------------------
|
||||
void removeDrawCall(GEVulkanCameraSceneNode* cam);
|
||||
}; // GEVulkanSceneManager
|
||||
|
||||
}
|
||||
|
59
lib/graphics_engine/src/ge_culling_tool.cpp
Normal file
59
lib/graphics_engine/src/ge_culling_tool.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "ge_culling_tool.hpp"
|
||||
|
||||
#include "ge_main.hpp"
|
||||
#include "ge_spm_buffer.hpp"
|
||||
#include "ge_vulkan_camera_scene_node.hpp"
|
||||
|
||||
#include "ISceneNode.h"
|
||||
|
||||
namespace GE
|
||||
{
|
||||
// ----------------------------------------------------------------------------
|
||||
void GECullingTool::init(GEVulkanCameraSceneNode* cam)
|
||||
{
|
||||
mathPlaneFrustumf(&m_frustum[0].X, cam->getPVM());
|
||||
m_cam_bbox = cam->getViewFrustum()->getBoundingBox();
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool GECullingTool::isCulled(GESPMBuffer* buffer,
|
||||
irr::scene::ISceneNode* node)
|
||||
{
|
||||
using namespace irr;
|
||||
using namespace core;
|
||||
aabbox3df bb = buffer->getBoundingBox();
|
||||
node->getAbsoluteTransformation().transformBoxEx(bb);
|
||||
|
||||
if (!m_cam_bbox.intersectsWithBox(bb))
|
||||
return true;
|
||||
|
||||
quaternion edges[8] =
|
||||
{
|
||||
quaternion(bb.MinEdge.X, bb.MinEdge.Y, bb.MinEdge.Z, 1.0f),
|
||||
quaternion(bb.MaxEdge.X, bb.MinEdge.Y, bb.MinEdge.Z, 1.0f),
|
||||
quaternion(bb.MinEdge.X, bb.MaxEdge.Y, bb.MinEdge.Z, 1.0f),
|
||||
quaternion(bb.MaxEdge.X, bb.MaxEdge.Y, bb.MinEdge.Z, 1.0f),
|
||||
quaternion(bb.MinEdge.X, bb.MinEdge.Y, bb.MaxEdge.Z, 1.0f),
|
||||
quaternion(bb.MaxEdge.X, bb.MinEdge.Y, bb.MaxEdge.Z, 1.0f),
|
||||
quaternion(bb.MinEdge.X, bb.MaxEdge.Y, bb.MaxEdge.Z, 1.0f),
|
||||
quaternion(bb.MaxEdge.X, bb.MaxEdge.Y, bb.MaxEdge.Z, 1.0f)
|
||||
};
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
bool culled = true;
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
if (m_frustum[i].dotProduct(edges[j]) >= 0.0)
|
||||
{
|
||||
culled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (culled)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} // isCulled
|
||||
|
||||
}
|
33
lib/graphics_engine/src/ge_culling_tool.hpp
Normal file
33
lib/graphics_engine/src/ge_culling_tool.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef HEADER_GE_CULLING_TOOL_HPP
|
||||
#define HEADER_GE_CULLING_TOOL_HPP
|
||||
|
||||
#include "aabbox3d.h"
|
||||
#include "quaternion.h"
|
||||
#include "matrix4.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene { class ISceneNode; }
|
||||
}
|
||||
|
||||
namespace GE
|
||||
{
|
||||
class GESPMBuffer;
|
||||
class GEVulkanCameraSceneNode;
|
||||
|
||||
class GECullingTool
|
||||
{
|
||||
private:
|
||||
irr::core::quaternion m_frustum[6];
|
||||
|
||||
irr::core::aabbox3df m_cam_bbox;
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
void init(GEVulkanCameraSceneNode* cam);
|
||||
// ------------------------------------------------------------------------
|
||||
bool isCulled(GESPMBuffer* buffer, irr::scene::ISceneNode* node);
|
||||
}; // GECullingTool
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -53,4 +53,61 @@ uint64_t getMonoTimeMs()
|
||||
return value.count();
|
||||
}
|
||||
|
||||
void mathPlaneNormf(float *p)
|
||||
{
|
||||
float f = 1.0f / sqrtf(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]);
|
||||
p[0] *= f;
|
||||
p[1] *= f;
|
||||
p[2] *= f;
|
||||
p[3] *= f;
|
||||
}
|
||||
|
||||
void mathPlaneFrustumf(float* out, const irr::core::matrix4& pvm)
|
||||
{
|
||||
// return 6 planes, 24 floats
|
||||
const float* m = pvm.pointer();
|
||||
|
||||
// near
|
||||
out[0] = m[3] + m[2];
|
||||
out[1] = m[7] + m[6];
|
||||
out[2] = m[11] + m[10];
|
||||
out[3] = m[15] + m[14];
|
||||
mathPlaneNormf(&out[0]);
|
||||
|
||||
// right
|
||||
out[4] = m[3] - m[0];
|
||||
out[4 + 1] = m[7] - m[4];
|
||||
out[4 + 2] = m[11] - m[8];
|
||||
out[4 + 3] = m[15] - m[12];
|
||||
mathPlaneNormf(&out[4]);
|
||||
|
||||
// left
|
||||
out[2 * 4] = m[3] + m[0];
|
||||
out[2 * 4 + 1] = m[7] + m[4];
|
||||
out[2 * 4 + 2] = m[11] + m[8];
|
||||
out[2 * 4 + 3] = m[15] + m[12];
|
||||
mathPlaneNormf(&out[2 * 4]);
|
||||
|
||||
// bottom
|
||||
out[3 * 4] = m[3] + m[1];
|
||||
out[3 * 4 + 1] = m[7] + m[5];
|
||||
out[3 * 4 + 2] = m[11] + m[9];
|
||||
out[3 * 4 + 3] = m[15] + m[13];
|
||||
mathPlaneNormf(&out[3 * 4]);
|
||||
|
||||
// top
|
||||
out[4 * 4] = m[3] - m[1];
|
||||
out[4 * 4 + 1] = m[7] - m[5];
|
||||
out[4 * 4 + 2] = m[11] - m[9];
|
||||
out[4 * 4 + 3] = m[15] - m[13];
|
||||
mathPlaneNormf(&out[4 * 4]);
|
||||
|
||||
// far
|
||||
out[5 * 4] = m[3] - m[2];
|
||||
out[5 * 4 + 1] = m[7] - m[6];
|
||||
out[5 * 4 + 2] = m[11] - m[10];
|
||||
out[5 * 4 + 3] = m[15] - m[14];
|
||||
mathPlaneNormf(&out[5 * 4]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "ge_main.hpp"
|
||||
#include "ge_vulkan_driver.hpp"
|
||||
#include "ge_vulkan_dynamic_buffer.hpp"
|
||||
#include "ge_vulkan_scene_manager.hpp"
|
||||
|
||||
namespace GE
|
||||
{
|
||||
@ -16,12 +17,14 @@ GEVulkanCameraSceneNode::GEVulkanCameraSceneNode(irr::scene::ISceneNode* parent,
|
||||
{
|
||||
m_buffer = new GEVulkanDynamicBuffer(GVDBT_GPU_RAM,
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(GEVulkanCameraUBO));
|
||||
static_cast<GEVulkanSceneManager*>(SceneManager)->addDrawCall(this);
|
||||
} // GEVulkanCameraSceneNode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
GEVulkanCameraSceneNode::~GEVulkanCameraSceneNode()
|
||||
{
|
||||
delete m_buffer;
|
||||
static_cast<GEVulkanSceneManager*>(SceneManager)->removeDrawCall(this);
|
||||
} // ~GEVulkanCameraSceneNode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -51,4 +54,12 @@ void GEVulkanCameraSceneNode::render()
|
||||
m_ubo_data.m_projection_view_matrix = mat;
|
||||
} // render
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
irr::core::matrix4 GEVulkanCameraSceneNode::getPVM() const
|
||||
{
|
||||
// Use the original unedited matrix for culling
|
||||
return ViewArea.getTransform(irr::video::ETS_PROJECTION) *
|
||||
ViewArea.getTransform(irr::video::ETS_VIEW);
|
||||
} // getPVM
|
||||
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ public:
|
||||
{ m_viewport = area; }
|
||||
// ------------------------------------------------------------------------
|
||||
const irr::core::rect<irr::s32>& getViewPort() const { return m_viewport; }
|
||||
// ------------------------------------------------------------------------
|
||||
irr::core::matrix4 getPVM() const;
|
||||
}; // GEVulkanCameraSceneNode
|
||||
|
||||
}
|
||||
|
87
lib/graphics_engine/src/ge_vulkan_draw_call.cpp
Normal file
87
lib/graphics_engine/src/ge_vulkan_draw_call.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include "ge_vulkan_draw_call.hpp"
|
||||
|
||||
#include "ge_culling_tool.hpp"
|
||||
#include "ge_spm_buffer.hpp"
|
||||
#include "ge_vulkan_animated_mesh_scene_node.hpp"
|
||||
#include "ge_vulkan_camera_scene_node.hpp"
|
||||
#include "ge_vulkan_mesh_scene_node.hpp"
|
||||
|
||||
namespace GE
|
||||
{
|
||||
// ----------------------------------------------------------------------------
|
||||
GEVulkanDrawCall::GEVulkanDrawCall()
|
||||
{
|
||||
m_culling_tool = new GECullingTool;
|
||||
} // GEVulkanDrawCall
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
GEVulkanDrawCall::~GEVulkanDrawCall()
|
||||
{
|
||||
delete m_culling_tool;
|
||||
} // ~GEVulkanDrawCall
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDrawCall::addNode(irr::scene::ISceneNode* node)
|
||||
{
|
||||
irr::scene::IMesh* mesh;
|
||||
if (node->getType() == irr::scene::ESNT_ANIMATED_MESH)
|
||||
{
|
||||
mesh = static_cast<
|
||||
GEVulkanAnimatedMeshSceneNode*>(node)->getMesh();
|
||||
}
|
||||
else if (node->getType() == irr::scene::ESNT_MESH)
|
||||
{
|
||||
mesh = static_cast<irr::scene::IMeshSceneNode*>(node)->getMesh();
|
||||
for (unsigned i = 0; i < mesh->getMeshBufferCount(); i++)
|
||||
{
|
||||
irr::scene::IMeshBuffer* b = mesh->getMeshBuffer(i);
|
||||
if (b->getVertexType() != irr::video::EVT_SKINNED_MESH)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < mesh->getMeshBufferCount(); i++)
|
||||
{
|
||||
GESPMBuffer* buffer = static_cast<GESPMBuffer*>(
|
||||
mesh->getMeshBuffer(i));
|
||||
if (m_culling_tool->isCulled(buffer, node))
|
||||
continue;
|
||||
m_visible_nodes[buffer].push_back(node);
|
||||
}
|
||||
} // addNode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDrawCall::generate()
|
||||
{
|
||||
unsigned accumulated_instance = 0;
|
||||
for (auto& p : m_visible_nodes)
|
||||
{
|
||||
unsigned visible_count = p.second.size();
|
||||
if (visible_count != 0)
|
||||
{
|
||||
for (auto* node : p.second)
|
||||
m_visible_trans.push_back(node->getAbsoluteTransformation());
|
||||
VkDrawIndexedIndirectCommand cmd;
|
||||
cmd.indexCount = p.first->getIndexCount();
|
||||
cmd.instanceCount = visible_count;
|
||||
cmd.firstIndex = p.first->getIBOOffset();
|
||||
cmd.vertexOffset = p.first->getVBOOffset();
|
||||
cmd.firstInstance = accumulated_instance;
|
||||
accumulated_instance += visible_count;
|
||||
m_cmds.push_back(cmd);
|
||||
}
|
||||
}
|
||||
} // generate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDrawCall::prepare(GEVulkanCameraSceneNode* cam)
|
||||
{
|
||||
m_visible_nodes.clear();
|
||||
m_cmds.clear();
|
||||
m_visible_trans.clear();
|
||||
m_culling_tool->init(cam);
|
||||
} // prepare
|
||||
|
||||
}
|
47
lib/graphics_engine/src/ge_vulkan_draw_call.hpp
Normal file
47
lib/graphics_engine/src/ge_vulkan_draw_call.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef HEADER_GE_VULKAN_DRAW_CALL_HPP
|
||||
#define HEADER_GE_VULKAN_DRAW_CALL_HPP
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "vulkan_wrapper.h"
|
||||
|
||||
#include "matrix4.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene { class ISceneNode; }
|
||||
}
|
||||
|
||||
namespace GE
|
||||
{
|
||||
class GECullingTool;
|
||||
class GESPMBuffer;
|
||||
class GEVulkanCameraSceneNode;
|
||||
|
||||
class GEVulkanDrawCall
|
||||
{
|
||||
private:
|
||||
std::unordered_map<GESPMBuffer*, std::vector<irr::scene::ISceneNode*> > m_visible_nodes;
|
||||
|
||||
GECullingTool* m_culling_tool;
|
||||
|
||||
std::vector<VkDrawIndexedIndirectCommand> m_cmds;
|
||||
|
||||
std::vector<irr::core::matrix4> m_visible_trans;
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
GEVulkanDrawCall();
|
||||
// ------------------------------------------------------------------------
|
||||
~GEVulkanDrawCall();
|
||||
// ------------------------------------------------------------------------
|
||||
void addNode(irr::scene::ISceneNode* node);
|
||||
// ------------------------------------------------------------------------
|
||||
void prepare(GEVulkanCameraSceneNode* cam);
|
||||
// ------------------------------------------------------------------------
|
||||
void generate();
|
||||
}; // GEVulkanDrawCall
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,8 +1,11 @@
|
||||
#include "ge_vulkan_scene_manager.hpp"
|
||||
|
||||
#include "../source/Irrlicht/os.h"
|
||||
|
||||
#include "ge_spm.hpp"
|
||||
#include "ge_vulkan_animated_mesh_scene_node.hpp"
|
||||
#include "ge_vulkan_camera_scene_node.hpp"
|
||||
#include "ge_vulkan_draw_call.hpp"
|
||||
#include "ge_vulkan_mesh_cache.hpp"
|
||||
#include "ge_vulkan_mesh_scene_node.hpp"
|
||||
|
||||
@ -77,9 +80,23 @@ irr::scene::IMeshSceneNode* GEVulkanSceneManager::addMeshSceneNode(
|
||||
const irr::core::vector3df& scale,
|
||||
bool alsoAddIfMeshPointerZero)
|
||||
{
|
||||
if (!alsoAddIfMeshPointerZero && (!mesh || !dynamic_cast<GESPM*>(mesh)))
|
||||
if (!alsoAddIfMeshPointerZero && !mesh)
|
||||
return NULL;
|
||||
|
||||
if (mesh)
|
||||
{
|
||||
for (unsigned i = 0; i < mesh->getMeshBufferCount(); i++)
|
||||
{
|
||||
irr::scene::IMeshBuffer* b = mesh->getMeshBuffer(i);
|
||||
if (b->getVertexType() != irr::video::EVT_SKINNED_MESH)
|
||||
{
|
||||
return irr::scene::CSceneManager::addMeshSceneNode(
|
||||
mesh, parent, id, position, rotation, scale,
|
||||
alsoAddIfMeshPointerZero);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!parent)
|
||||
parent = this;
|
||||
|
||||
@ -90,4 +107,61 @@ irr::scene::IMeshSceneNode* GEVulkanSceneManager::addMeshSceneNode(
|
||||
return node;
|
||||
} // addMeshSceneNode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanSceneManager::drawAll(irr::u32 flags)
|
||||
{
|
||||
static_cast<GEVulkanMeshCache*>(getMeshCache())->updateCache();
|
||||
GEVulkanCameraSceneNode* cam = NULL;
|
||||
if (getActiveCamera())
|
||||
{
|
||||
cam = static_cast<
|
||||
GEVulkanCameraSceneNode*>(getActiveCamera());
|
||||
}
|
||||
OnAnimate(os::Timer::getTime());
|
||||
if (cam)
|
||||
{
|
||||
cam->render();
|
||||
auto it = m_draw_calls.find(cam);
|
||||
if (it == m_draw_calls.end())
|
||||
return;
|
||||
|
||||
it->second->prepare(cam);
|
||||
OnRegisterSceneNode();
|
||||
it->second->generate();
|
||||
}
|
||||
} // drawAll
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
irr::u32 GEVulkanSceneManager::registerNodeForRendering(
|
||||
irr::scene::ISceneNode* node,
|
||||
irr::scene::E_SCENE_NODE_RENDER_PASS pass)
|
||||
{
|
||||
if (!getActiveCamera())
|
||||
return 0;
|
||||
|
||||
GEVulkanCameraSceneNode* cam = static_cast<
|
||||
GEVulkanCameraSceneNode*>(getActiveCamera());
|
||||
|
||||
if ((node->getType() == irr::scene::ESNT_ANIMATED_MESH &&
|
||||
pass != irr::scene::ESNRP_SOLID) ||
|
||||
(node->getType() == irr::scene::ESNT_MESH &&
|
||||
pass != irr::scene::ESNRP_SOLID))
|
||||
return 0;
|
||||
|
||||
m_draw_calls.at(cam)->addNode(node);
|
||||
return 1;
|
||||
} // registerNodeForRendering
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanSceneManager::addDrawCall(GEVulkanCameraSceneNode* cam)
|
||||
{
|
||||
m_draw_calls[cam] = std::unique_ptr<GEVulkanDrawCall>(new GEVulkanDrawCall);
|
||||
} // addDrawCall
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanSceneManager::removeDrawCall(GEVulkanCameraSceneNode* cam)
|
||||
{
|
||||
m_draw_calls.erase(cam);
|
||||
} // removeDrawCall
|
||||
|
||||
}
|
||||
|
@ -57,6 +57,9 @@
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include <ge_main.hpp>
|
||||
using namespace GE;
|
||||
|
||||
namespace SP
|
||||
{
|
||||
|
||||
@ -641,64 +644,6 @@ SPShader* getNormalVisualizer()
|
||||
return g_normal_visualizer;
|
||||
} // getNormalVisualizer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
inline void mathPlaneNormf(float *p)
|
||||
{
|
||||
float f = 1.0f / sqrtf(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]);
|
||||
p[0] *= f;
|
||||
p[1] *= f;
|
||||
p[2] *= f;
|
||||
p[3] *= f;
|
||||
} // mathPlaneNormf
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
inline void mathPlaneFrustumf(float* out, const core::matrix4& pvm)
|
||||
{
|
||||
// return 6 planes, 24 floats
|
||||
const float* m = pvm.pointer();
|
||||
|
||||
// near
|
||||
out[0] = m[3] + m[2];
|
||||
out[1] = m[7] + m[6];
|
||||
out[2] = m[11] + m[10];
|
||||
out[3] = m[15] + m[14];
|
||||
mathPlaneNormf(&out[0]);
|
||||
|
||||
// right
|
||||
out[4] = m[3] - m[0];
|
||||
out[4 + 1] = m[7] - m[4];
|
||||
out[4 + 2] = m[11] - m[8];
|
||||
out[4 + 3] = m[15] - m[12];
|
||||
mathPlaneNormf(&out[4]);
|
||||
|
||||
// left
|
||||
out[2 * 4] = m[3] + m[0];
|
||||
out[2 * 4 + 1] = m[7] + m[4];
|
||||
out[2 * 4 + 2] = m[11] + m[8];
|
||||
out[2 * 4 + 3] = m[15] + m[12];
|
||||
mathPlaneNormf(&out[2 * 4]);
|
||||
|
||||
// bottom
|
||||
out[3 * 4] = m[3] + m[1];
|
||||
out[3 * 4 + 1] = m[7] + m[5];
|
||||
out[3 * 4 + 2] = m[11] + m[9];
|
||||
out[3 * 4 + 3] = m[15] + m[13];
|
||||
mathPlaneNormf(&out[3 * 4]);
|
||||
|
||||
// top
|
||||
out[4 * 4] = m[3] - m[1];
|
||||
out[4 * 4 + 1] = m[7] - m[5];
|
||||
out[4 * 4 + 2] = m[11] - m[9];
|
||||
out[4 * 4 + 3] = m[15] - m[13];
|
||||
mathPlaneNormf(&out[4 * 4]);
|
||||
|
||||
// far
|
||||
out[5 * 4] = m[3] - m[2];
|
||||
out[5 * 4 + 1] = m[7] - m[6];
|
||||
out[5 * 4 + 2] = m[11] - m[10];
|
||||
out[5 * 4 + 3] = m[15] - m[14];
|
||||
mathPlaneNormf(&out[5 * 4]);
|
||||
} // mathPlaneFrustumf
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
inline core::vector3df getCorner(const core::aabbox3df& bbox, unsigned n)
|
||||
|
Loading…
x
Reference in New Issue
Block a user