Merge branch 'Instancing'
This commit is contained in:
26
data/shaders/instanced_grass.vert
Normal file
26
data/shaders/instanced_grass.vert
Normal file
@@ -0,0 +1,26 @@
|
||||
uniform vec3 windDir;
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
uniform mat4 InverseViewMatrix;
|
||||
|
||||
in vec3 Origin;
|
||||
in vec3 Orientation;
|
||||
|
||||
in vec3 Position;
|
||||
in vec3 Normal;
|
||||
in vec2 Texcoord;
|
||||
in vec4 Color;
|
||||
|
||||
out vec3 nor;
|
||||
out vec2 uv;
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation);
|
||||
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation);
|
||||
|
||||
void main()
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin + windDir * Color.r, Orientation);
|
||||
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin + windDir * Color.r, Orientation) * InverseViewMatrix);
|
||||
gl_Position = ViewProjectionMatrix * ModelMatrix * vec4(Position, 1.);
|
||||
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
|
||||
uv = Texcoord;
|
||||
}
|
||||
24
data/shaders/instanced_object_pass.vert
Normal file
24
data/shaders/instanced_object_pass.vert
Normal file
@@ -0,0 +1,24 @@
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
uniform mat4 InverseViewMatrix;
|
||||
|
||||
in vec3 Origin;
|
||||
in vec3 Orientation;
|
||||
|
||||
in vec3 Position;
|
||||
in vec3 Normal;
|
||||
in vec2 Texcoord;
|
||||
|
||||
out vec3 nor;
|
||||
out vec2 uv;
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation);
|
||||
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation);
|
||||
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation) * InverseViewMatrix);
|
||||
gl_Position = ViewProjectionMatrix * ModelMatrix * vec4(Position, 1.);
|
||||
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
|
||||
uv = Texcoord;
|
||||
}
|
||||
36
data/shaders/utils/getworldmatrix.vert
Normal file
36
data/shaders/utils/getworldmatrix.vert
Normal file
@@ -0,0 +1,36 @@
|
||||
mat4 getMatrixFromRotation(vec3 rotation)
|
||||
{
|
||||
|
||||
// from irrlicht
|
||||
float cr = cos( rotation.z );
|
||||
float sr = sin( rotation.z );
|
||||
float cp = cos( rotation.x );
|
||||
float sp = sin( rotation.x );
|
||||
float cy = cos( rotation.y );
|
||||
float sy = sin( rotation.y );
|
||||
|
||||
float srsp = sr*sp;
|
||||
float crsp = cr*sp;
|
||||
|
||||
return mat4(
|
||||
vec4(cp * cy, srsp * cy - cr * sy, crsp * cy + sr * sy, 0.),
|
||||
vec4(cp * sy, srsp * sy + cr * cy, crsp * sy - sr * cy, 0.),
|
||||
vec4(-sp, sr * cp, cr * cp, 0.),
|
||||
vec4(0., 0., 0., 1.));
|
||||
}
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation)
|
||||
{
|
||||
mat4 result = getMatrixFromRotation(rotation);
|
||||
// translation
|
||||
result[3].xyz += translation;
|
||||
return result;
|
||||
}
|
||||
|
||||
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation)
|
||||
{
|
||||
mat4 result = transpose(getMatrixFromRotation(rotation));
|
||||
// FIXME: it's wrong but the fourth column is not used
|
||||
result[3].xyz -= translation;
|
||||
return result;
|
||||
}
|
||||
@@ -63,6 +63,7 @@ src/graphics/slip_stream.cpp
|
||||
src/graphics/stars.cpp
|
||||
src/graphics/stkanimatedmesh.cpp
|
||||
src/graphics/stkbillboard.cpp
|
||||
src/graphics/stkinstancedscenenode.cpp
|
||||
src/graphics/stkmesh.cpp
|
||||
src/graphics/stkmeshscenenode.cpp
|
||||
src/graphics/sun.cpp
|
||||
@@ -304,7 +305,7 @@ src/tracks/check_manager.cpp
|
||||
src/tracks/check_sphere.cpp
|
||||
src/tracks/check_structure.cpp
|
||||
src/tracks/graph_node.cpp
|
||||
src/tracks/lod_node_loader.cpp
|
||||
src/tracks/model_definition_loader.cpp
|
||||
src/tracks/quad.cpp
|
||||
src/tracks/quad_graph.cpp
|
||||
src/tracks/quad_set.cpp
|
||||
@@ -399,6 +400,7 @@ src/graphics/slip_stream.hpp
|
||||
src/graphics/stars.hpp
|
||||
src/graphics/stkanimatedmesh.hpp
|
||||
src/graphics/stkbillboard.hpp
|
||||
src/graphics/stkinstancedscenenode.hpp
|
||||
src/graphics/stkmesh.hpp
|
||||
src/graphics/stkmeshscenenode.hpp
|
||||
src/graphics/sun.hpp
|
||||
@@ -646,7 +648,7 @@ src/tracks/check_manager.hpp
|
||||
src/tracks/check_sphere.hpp
|
||||
src/tracks/check_structure.hpp
|
||||
src/tracks/graph_node.hpp
|
||||
src/tracks/lod_node_loader.hpp
|
||||
src/tracks/model_definition_loader.hpp
|
||||
src/tracks/quad.hpp
|
||||
src/tracks/quad_graph.hpp
|
||||
src/tracks/quad_set.hpp
|
||||
|
||||
@@ -46,6 +46,7 @@ PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
|
||||
PFNGLBLENDEQUATIONPROC glBlendEquation;
|
||||
PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
|
||||
PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
|
||||
PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
|
||||
PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
@@ -183,6 +184,7 @@ void initGL()
|
||||
glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation");
|
||||
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor");
|
||||
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced");
|
||||
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsInstanced");
|
||||
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers");
|
||||
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glGenVertexArrays");
|
||||
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)IRR_OGL_LOAD_EXTENSION("glBindVertexArray");
|
||||
|
||||
@@ -64,6 +64,7 @@ extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
|
||||
extern PFNGLBLENDEQUATIONPROC glBlendEquation;
|
||||
extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
|
||||
extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
|
||||
extern PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
|
||||
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/shadow_importance.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "graphics/stkinstancedscenenode.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "items/item.hpp"
|
||||
@@ -50,6 +51,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
STKInstancedSceneNode *InstancedBox = 0;
|
||||
|
||||
void IrrDriver::renderGLSL(float dt)
|
||||
{
|
||||
World *world = World::getWorld(); // Never NULL.
|
||||
@@ -203,7 +206,6 @@ void IrrDriver::renderGLSL(float dt)
|
||||
irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
|
||||
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||
irr_driver->genProjViewMatrix();
|
||||
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
// Todo : reenable glow and shadows
|
||||
@@ -245,7 +247,6 @@ void IrrDriver::renderGLSL(float dt)
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
m_scene_manager->drawAll(m_renderpass);
|
||||
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
if (World::getWorld()->getTrack()->isFogEnabled())
|
||||
|
||||
@@ -318,7 +318,11 @@ void Shaders::loadShaders()
|
||||
MeshShader::NormalMapShader::init();
|
||||
MeshShader::ObjectPass1Shader::init();
|
||||
MeshShader::ObjectRefPass1Shader::init();
|
||||
MeshShader::InstancedObjectPass1Shader::init();
|
||||
MeshShader::InstancedGrassPass1Shader::init();
|
||||
MeshShader::ObjectPass2Shader::init();
|
||||
MeshShader::InstancedObjectPass2Shader::init();
|
||||
MeshShader::InstancedGrassPass2Shader::init();
|
||||
MeshShader::DetailledObjectPass2Shader::init();
|
||||
MeshShader::ObjectRimLimitShader::init();
|
||||
MeshShader::UntexturedObjectShader::init();
|
||||
@@ -501,6 +505,72 @@ namespace MeshShader
|
||||
glUniform1i(uniform_normalMap, TU_normalMap);
|
||||
}
|
||||
|
||||
GLuint InstancedObjectPass1Shader::Program;
|
||||
GLuint InstancedObjectPass1Shader::attrib_position;
|
||||
GLuint InstancedObjectPass1Shader::attrib_normal;
|
||||
GLuint InstancedObjectPass1Shader::attrib_origin;
|
||||
GLuint InstancedObjectPass1Shader::uniform_MP;
|
||||
GLuint InstancedObjectPass1Shader::uniform_VM;
|
||||
|
||||
void InstancedObjectPass1Shader::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass1.frag").c_str());
|
||||
attrib_origin = glGetAttribLocation(Program, "Origin");
|
||||
attrib_position = glGetAttribLocation(Program, "Position");
|
||||
attrib_normal = glGetAttribLocation(Program, "Normal");
|
||||
uniform_MP = glGetUniformLocation(Program, "ViewProjectionMatrix");
|
||||
uniform_VM = glGetUniformLocation(Program, "InverseViewMatrix");
|
||||
}
|
||||
|
||||
void InstancedObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ViewMatrix)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_MP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_VM, 1, GL_FALSE, ViewMatrix.pointer());
|
||||
}
|
||||
|
||||
GLuint InstancedGrassPass1Shader::Program;
|
||||
GLuint InstancedGrassPass1Shader::attrib_position;
|
||||
GLuint InstancedGrassPass1Shader::attrib_normal;
|
||||
GLuint InstancedGrassPass1Shader::attrib_origin;
|
||||
GLuint InstancedGrassPass1Shader::attrib_orientation;
|
||||
GLuint InstancedGrassPass1Shader::attrib_texcoord;
|
||||
GLuint InstancedGrassPass1Shader::attrib_color;
|
||||
GLuint InstancedGrassPass1Shader::uniform_MP;
|
||||
GLuint InstancedGrassPass1Shader::uniform_IVM;
|
||||
GLuint InstancedGrassPass1Shader::uniform_windDir;
|
||||
GLuint InstancedGrassPass1Shader::uniform_tex;
|
||||
|
||||
void InstancedGrassPass1Shader::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str());
|
||||
attrib_origin = glGetAttribLocation(Program, "Origin");
|
||||
attrib_orientation = glGetAttribLocation(Program, "Orientation");
|
||||
attrib_position = glGetAttribLocation(Program, "Position");
|
||||
attrib_normal = glGetAttribLocation(Program, "Normal");
|
||||
attrib_color = glGetAttribLocation(Program, "Color");
|
||||
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
||||
uniform_MP = glGetUniformLocation(Program, "ViewProjectionMatrix");
|
||||
uniform_IVM = glGetUniformLocation(Program, "InverseViewMatrix");
|
||||
uniform_windDir = glGetUniformLocation(Program, "windDir");
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
}
|
||||
|
||||
void InstancedGrassPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &InverseViewMatrix, const core::vector3df &windDir, unsigned TU_tex)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_MP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_IVM, 1, GL_FALSE, InverseViewMatrix.pointer());
|
||||
glUniform3f(uniform_windDir, windDir.X, windDir.Y, windDir.Z);
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
|
||||
// Solid Lit pass shaders
|
||||
|
||||
GLuint ObjectPass2Shader::Program;
|
||||
@@ -547,6 +617,53 @@ namespace MeshShader
|
||||
glUniform3f(uniform_ambient, s.r, s.g, s.b);
|
||||
}
|
||||
|
||||
GLuint InstancedObjectPass2Shader::Program;
|
||||
GLuint InstancedObjectPass2Shader::attrib_position;
|
||||
GLuint InstancedObjectPass2Shader::attrib_texcoord;
|
||||
GLuint InstancedObjectPass2Shader::attrib_origin;
|
||||
GLuint InstancedObjectPass2Shader::uniform_VP;
|
||||
GLuint InstancedObjectPass2Shader::uniform_TM;
|
||||
GLuint InstancedObjectPass2Shader::uniform_screen;
|
||||
GLuint InstancedObjectPass2Shader::uniform_ambient;
|
||||
GLuint InstancedObjectPass2Shader::TU_Albedo;
|
||||
|
||||
void InstancedObjectPass2Shader::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass2.frag").c_str());
|
||||
attrib_position = glGetAttribLocation(Program, "Position");
|
||||
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
||||
attrib_origin = glGetAttribLocation(Program, "Origin");
|
||||
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix");
|
||||
uniform_TM = glGetUniformLocation(Program, "TextureMatrix");
|
||||
GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo");
|
||||
GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap");
|
||||
GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap");
|
||||
GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO");
|
||||
uniform_screen = glGetUniformLocation(Program, "screen");
|
||||
uniform_ambient = glGetUniformLocation(Program, "ambient");
|
||||
TU_Albedo = 3;
|
||||
|
||||
glUseProgram(Program);
|
||||
glUniform1i(uniform_DiffuseMap, 0);
|
||||
glUniform1i(uniform_SpecularMap, 1);
|
||||
glUniform1i(uniform_SSAO, 2);
|
||||
glUniform1i(uniform_Albedo, TU_Albedo);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void InstancedObjectPass2Shader::setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_VP, 1, GL_FALSE, ViewProjectionMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer());
|
||||
glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight();
|
||||
glUniform3f(uniform_ambient, s.r, s.g, s.b);
|
||||
}
|
||||
|
||||
GLuint DetailledObjectPass2Shader::Program;
|
||||
GLuint DetailledObjectPass2Shader::attrib_position;
|
||||
GLuint DetailledObjectPass2Shader::attrib_texcoord;
|
||||
@@ -798,6 +915,57 @@ namespace MeshShader
|
||||
glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z);
|
||||
}
|
||||
|
||||
GLuint InstancedGrassPass2Shader::Program;
|
||||
GLuint InstancedGrassPass2Shader::attrib_position;
|
||||
GLuint InstancedGrassPass2Shader::attrib_texcoord;
|
||||
GLuint InstancedGrassPass2Shader::attrib_color;
|
||||
GLuint InstancedGrassPass2Shader::attrib_origin;
|
||||
GLuint InstancedGrassPass2Shader::attrib_orientation;
|
||||
GLuint InstancedGrassPass2Shader::uniform_VP;
|
||||
GLuint InstancedGrassPass2Shader::uniform_screen;
|
||||
GLuint InstancedGrassPass2Shader::uniform_ambient;
|
||||
GLuint InstancedGrassPass2Shader::uniform_windDir;
|
||||
GLuint InstancedGrassPass2Shader::TU_Albedo;
|
||||
|
||||
void InstancedGrassPass2Shader::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass2.frag").c_str());
|
||||
attrib_position = glGetAttribLocation(Program, "Position");
|
||||
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
||||
attrib_color = glGetAttribLocation(Program, "Color");
|
||||
attrib_origin = glGetAttribLocation(Program, "Origin");
|
||||
attrib_orientation = glGetAttribLocation(Program, "Orientation");
|
||||
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix");
|
||||
GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo");
|
||||
GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap");
|
||||
GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap");
|
||||
GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO");
|
||||
uniform_screen = glGetUniformLocation(Program, "screen");
|
||||
uniform_ambient = glGetUniformLocation(Program, "ambient");
|
||||
uniform_windDir = glGetUniformLocation(Program, "windDir");
|
||||
TU_Albedo = 3;
|
||||
|
||||
glUseProgram(Program);
|
||||
glUniform1i(uniform_DiffuseMap, 0);
|
||||
glUniform1i(uniform_SpecularMap, 1);
|
||||
glUniform1i(uniform_SSAO, 2);
|
||||
glUniform1i(uniform_Albedo, TU_Albedo);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void InstancedGrassPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_VP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
||||
glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight();
|
||||
glUniform3f(uniform_ambient, s.r, s.g, s.b);
|
||||
glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z);
|
||||
}
|
||||
|
||||
GLuint SphereMapShader::Program;
|
||||
GLuint SphereMapShader::attrib_position;
|
||||
GLuint SphereMapShader::attrib_normal;
|
||||
|
||||
@@ -77,6 +77,28 @@ public:
|
||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap);
|
||||
};
|
||||
|
||||
class InstancedObjectPass1Shader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint attrib_position, attrib_normal, attrib_origin;
|
||||
static GLuint uniform_MP, uniform_VM;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &ViewMatrix);
|
||||
};
|
||||
|
||||
class InstancedGrassPass1Shader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint attrib_position, attrib_normal, attrib_origin, attrib_orientation, attrib_color, attrib_texcoord;
|
||||
static GLuint uniform_MP, uniform_IVM, uniform_windDir, uniform_tex;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &InverseViewMatrix, const core::vector3df &windDir, unsigned TU_tex);
|
||||
};
|
||||
|
||||
class ObjectPass2Shader
|
||||
{
|
||||
public:
|
||||
@@ -89,6 +111,18 @@ public:
|
||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix);
|
||||
};
|
||||
|
||||
class InstancedObjectPass2Shader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint attrib_position, attrib_texcoord, attrib_origin;
|
||||
static GLuint uniform_VP, uniform_TM, uniform_screen, uniform_ambient;
|
||||
static GLuint TU_Albedo;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix);
|
||||
};
|
||||
|
||||
class DetailledObjectPass2Shader
|
||||
{
|
||||
public:
|
||||
@@ -160,6 +194,18 @@ public:
|
||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection);
|
||||
};
|
||||
|
||||
class InstancedGrassPass2Shader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint attrib_position, attrib_texcoord, attrib_color, attrib_origin, attrib_orientation;
|
||||
static GLuint uniform_VP, uniform_TM, uniform_screen, uniform_ambient, uniform_windDir;
|
||||
static GLuint TU_Albedo;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::vector3df &windDirection);
|
||||
};
|
||||
|
||||
class SphereMapShader
|
||||
{
|
||||
public:
|
||||
|
||||
244
src/graphics/stkinstancedscenenode.cpp
Normal file
244
src/graphics/stkinstancedscenenode.cpp
Normal file
@@ -0,0 +1,244 @@
|
||||
#include "stkinstancedscenenode.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
|
||||
STKInstancedSceneNode::STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position,
|
||||
const irr::core::vector3df& rotation,
|
||||
const irr::core::vector3df& scale) :
|
||||
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
|
||||
{
|
||||
createGLMeshes();
|
||||
setAutomaticCulling(0);
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::cleanGL()
|
||||
{
|
||||
for (u32 i = 0; i < GLmeshes.size(); ++i)
|
||||
{
|
||||
GLMesh mesh = GLmeshes[i];
|
||||
if (!mesh.vertex_buffer)
|
||||
continue;
|
||||
if (mesh.vao_first_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_first_pass));
|
||||
if (mesh.vao_second_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_second_pass));
|
||||
if (mesh.vao_glow_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_glow_pass));
|
||||
if (mesh.vao_displace_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_displace_pass));
|
||||
if (mesh.vao_displace_mask_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_displace_mask_pass));
|
||||
if (mesh.vao_shadow_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_shadow_pass));
|
||||
glDeleteBuffers(1, &(mesh.vertex_buffer));
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
}
|
||||
glDeleteBuffers(1, &instances_vbo);
|
||||
}
|
||||
|
||||
STKInstancedSceneNode::~STKInstancedSceneNode()
|
||||
{
|
||||
cleanGL();
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::createGLMeshes()
|
||||
{
|
||||
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
GLmeshes.push_back(allocateMeshBuffer(mb));
|
||||
}
|
||||
isMaterialInitialized = false;
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat)
|
||||
{
|
||||
switch (GeoMat)
|
||||
{
|
||||
case FPSM_DEFAULT:
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::InstancedObjectPass1Shader::attrib_position, -1, -1, MeshShader::InstancedObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
glGenBuffers(1, &instances_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_origin);
|
||||
glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
|
||||
glVertexAttribDivisor(MeshShader::InstancedObjectPass1Shader::attrib_origin, 1);
|
||||
break;
|
||||
case FPSM_GRASS:
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::InstancedGrassPass1Shader::attrib_position, MeshShader::InstancedGrassPass1Shader::attrib_texcoord, -1, MeshShader::InstancedGrassPass1Shader::attrib_normal, -1, -1, MeshShader::InstancedGrassPass1Shader::attrib_color, mesh.Stride);
|
||||
glGenBuffers(1, &instances_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(MeshShader::InstancedGrassPass1Shader::attrib_origin);
|
||||
glVertexAttribPointer(MeshShader::InstancedGrassPass1Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), 0);
|
||||
glVertexAttribDivisor(MeshShader::InstancedGrassPass1Shader::attrib_origin, 1);
|
||||
glVertexAttribPointer(MeshShader::InstancedGrassPass1Shader::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(MeshShader::InstancedGrassPass1Shader::attrib_orientation, 1);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch (ShadedMat)
|
||||
{
|
||||
case SM_DEFAULT:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::InstancedObjectPass2Shader::attrib_position, MeshShader::InstancedObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
|
||||
glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_origin);
|
||||
glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), 0);
|
||||
glVertexAttribDivisor(MeshShader::InstancedObjectPass2Shader::attrib_origin, 1);
|
||||
break;
|
||||
case SM_GRASS:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::InstancedGrassPass2Shader::attrib_position, MeshShader::InstancedGrassPass2Shader::attrib_texcoord, -1, -1, -1, -1, MeshShader::InstancedGrassPass2Shader::attrib_color, mesh.Stride);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
|
||||
glEnableVertexAttribArray(MeshShader::InstancedGrassPass2Shader::attrib_origin);
|
||||
glVertexAttribPointer(MeshShader::InstancedGrassPass2Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), 0);
|
||||
glVertexAttribDivisor(MeshShader::InstancedGrassPass2Shader::attrib_origin, 1);
|
||||
glVertexAttribPointer(MeshShader::InstancedGrassPass2Shader::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid*) (3 * sizeof(float)));
|
||||
glVertexAttribDivisor(MeshShader::InstancedGrassPass2Shader::attrib_orientation, 1);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::setFirstTimeMaterial()
|
||||
{
|
||||
if (isMaterialInitialized)
|
||||
return;
|
||||
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type);
|
||||
ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures);
|
||||
initinstancedvaostate(mesh, GeometricType, ShadedType);
|
||||
if (mesh.vao_first_pass)
|
||||
GeometricMesh[GeometricType].push_back(&mesh);
|
||||
if (mesh.vao_second_pass)
|
||||
ShadedMesh[ShadedType].push_back(&mesh);
|
||||
}
|
||||
isMaterialInitialized = true;
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::addInstance(const core::vector3df &origin, const core::vector3df &orientation)
|
||||
{
|
||||
instance_pos.push_back(origin.X);
|
||||
instance_pos.push_back(origin.Y);
|
||||
instance_pos.push_back(origin.Z);
|
||||
instance_pos.push_back(orientation.X);
|
||||
instance_pos.push_back(orientation.Y);
|
||||
instance_pos.push_back(orientation.Z);
|
||||
}
|
||||
|
||||
static void drawFSPMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, size_t instance_count)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
core::matrix4 InverseViewMatrix;
|
||||
irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW).getInverse(InverseViewMatrix);
|
||||
|
||||
MeshShader::InstancedObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, InverseViewMatrix);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
||||
}
|
||||
|
||||
static void drawFSPMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDir, size_t instance_count)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
core::matrix4 InverseViewMatrix;
|
||||
irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW).getInverse(InverseViewMatrix);
|
||||
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
MeshShader::InstancedGrassPass1Shader::setUniforms(ModelViewProjectionMatrix, InverseViewMatrix, windDir, 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
||||
}
|
||||
|
||||
static void drawSMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, size_t instance_count)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
setTexture(MeshShader::InstancedObjectPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
|
||||
MeshShader::InstancedObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, core::matrix4::EM4CONST_IDENTITY);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
||||
}
|
||||
|
||||
static void drawSMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDir, size_t instance_count)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
setTexture(MeshShader::InstancedGrassPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
|
||||
MeshShader::InstancedGrassPass2Shader::setUniforms(ModelViewProjectionMatrix, windDir);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::render()
|
||||
{
|
||||
setFirstTimeMaterial();
|
||||
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
|
||||
{
|
||||
ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION);
|
||||
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
||||
|
||||
if (!GeometricMesh[FPSM_DEFAULT].empty())
|
||||
glUseProgram(MeshShader::InstancedObjectPass1Shader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
|
||||
drawFSPMDefault(*GeometricMesh[FPSM_DEFAULT][i], ModelViewProjectionMatrix, instance_pos.size() / 3);
|
||||
|
||||
windDir = getWind();
|
||||
if (!GeometricMesh[FPSM_GRASS].empty())
|
||||
glUseProgram(MeshShader::InstancedGrassPass1Shader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_GRASS].size(); i++)
|
||||
drawFSPMGrass(*GeometricMesh[FPSM_GRASS][i], ModelViewProjectionMatrix, windDir, instance_pos.size() / 3);
|
||||
return;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SOLID_LIT_PASS)
|
||||
{
|
||||
if (!ShadedMesh[SM_DEFAULT].empty())
|
||||
glUseProgram(MeshShader::InstancedObjectPass2Shader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[FPSM_DEFAULT].size(); i++)
|
||||
drawSMDefault(*ShadedMesh[FPSM_DEFAULT][i], ModelViewProjectionMatrix, instance_pos.size() / 3);
|
||||
|
||||
if (!ShadedMesh[SM_GRASS].empty())
|
||||
glUseProgram(MeshShader::InstancedGrassPass2Shader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_GRASS].size(); i++)
|
||||
drawSMGrass(*ShadedMesh[SM_GRASS][i], ModelViewProjectionMatrix, windDir, instance_pos.size() / 3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
31
src/graphics/stkinstancedscenenode.hpp
Normal file
31
src/graphics/stkinstancedscenenode.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef STKINSTANCEDSCENENODE_HPP
|
||||
#define STKINSTANCEDSCENENODE_HPP
|
||||
|
||||
#include "stkmesh.hpp"
|
||||
|
||||
class STKInstancedSceneNode : public irr::scene::CMeshSceneNode
|
||||
{
|
||||
protected:
|
||||
std::vector<GLMesh *> GeometricMesh[FPSM_COUNT];
|
||||
std::vector<GLMesh *> ShadedMesh[SM_COUNT];
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
std::vector<float> instance_pos;
|
||||
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
|
||||
GLuint instances_vbo;
|
||||
void createGLMeshes();
|
||||
bool isMaterialInitialized;
|
||||
void setFirstTimeMaterial();
|
||||
void initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat);
|
||||
void cleanGL();
|
||||
core::vector3df windDir;
|
||||
public:
|
||||
STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
|
||||
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));
|
||||
~STKInstancedSceneNode();
|
||||
virtual void render();
|
||||
void addInstance(const core::vector3df &origin, const core::vector3df &orientation);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -102,7 +102,6 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t
|
||||
glVertexAttribPointer(attrib_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (GLvoid*)24);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx);
|
||||
glBindVertexArray(0);
|
||||
return vao;
|
||||
}
|
||||
|
||||
@@ -206,6 +205,16 @@ void computeTIMV(core::matrix4 &TransposeInverseModelView)
|
||||
TransposeInverseModelView = TransposeInverseModelView.getTransposed();
|
||||
}
|
||||
|
||||
core::vector3df getWind()
|
||||
{
|
||||
const core::vector3df pos = irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD).getTranslation();
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS);
|
||||
float m_speed = gsp->getSpeed(), m_amplitude = gsp->getAmplitude();
|
||||
|
||||
return m_speed * vector3df(1., 0., 0.) * cos(time);
|
||||
}
|
||||
|
||||
void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
|
||||
@@ -64,6 +64,8 @@ void computeMVP(core::matrix4 &ModelViewProjectionMatrix);
|
||||
void computeTIMV(core::matrix4 &TransposeInverseModelView);
|
||||
bool isObject(video::E_MATERIAL_TYPE type);
|
||||
|
||||
core::vector3df getWind();
|
||||
|
||||
// Pass 1 shader (ie shaders that outputs normals and depth)
|
||||
void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView);
|
||||
void drawNormalPass(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView);
|
||||
|
||||
@@ -10,22 +10,6 @@
|
||||
#include "graphics/camera.hpp"
|
||||
#include "modes/world.hpp"
|
||||
|
||||
static
|
||||
core::vector3df getWind()
|
||||
{
|
||||
const core::vector3df pos = irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD).getTranslation();
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS);
|
||||
float m_speed = gsp->getSpeed(), m_amplitude = gsp->getAmplitude();
|
||||
|
||||
float strength = (pos.X + pos.Y + pos.Z) * 1.2f + time * m_speed;
|
||||
strength = noise2d(strength / 10.0f) * m_amplitude * 5;
|
||||
// * 5 is to work with the existing amplitude values.
|
||||
|
||||
// Pre-multiply on the cpu
|
||||
return irr_driver->getWind() * strength;
|
||||
}
|
||||
|
||||
STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position,
|
||||
const irr::core::vector3df& rotation,
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "tracks/lod_node_loader.hpp"
|
||||
#include "tracks/model_definition_loader.hpp"
|
||||
using namespace irr;
|
||||
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/lod_node.hpp"
|
||||
#include "graphics/stkinstancedscenenode.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
|
||||
@@ -29,14 +30,14 @@ using namespace irr;
|
||||
#include <IMeshManipulator.h>
|
||||
#include <algorithm>
|
||||
|
||||
LodNodeLoader::LodNodeLoader(Track* track)
|
||||
ModelDefinitionLoader::ModelDefinitionLoader(Track* track)
|
||||
{
|
||||
m_track = track;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void LodNodeLoader::addLODModelDefinition(const XMLNode* xml)
|
||||
void ModelDefinitionLoader::addModelDefinition(const XMLNode* xml)
|
||||
{
|
||||
float lod_distance = -1.0f;
|
||||
xml->get("lod_distance", &lod_distance);
|
||||
@@ -50,35 +51,24 @@ void LodNodeLoader::addLODModelDefinition(const XMLNode* xml)
|
||||
std::string model_name;
|
||||
xml->get("model", &model_name);
|
||||
|
||||
m_lod_groups[lodgroup].push_back(LodModel(xml, (int)lod_distance, model_name, tangent));
|
||||
m_lod_groups[lodgroup].push_back(ModelDefinition(xml, (int)lod_distance, model_name, tangent));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
LODNode* LodNodeLoader::instanciate(const XMLNode* node, scene::ISceneNode* parent)
|
||||
//Track* track, std::vector<irr::scene::IMesh*>& cache)
|
||||
LODNode* ModelDefinitionLoader::instanciateAsLOD(const XMLNode* node, scene::ISceneNode* parent)
|
||||
{
|
||||
scene::ISceneManager* sm = irr_driver->getSceneManager();
|
||||
|
||||
std::string groupname = "";
|
||||
node->get("lod_group", &groupname);
|
||||
|
||||
std::vector< LodModel >& group = m_lod_groups[groupname];
|
||||
|
||||
//core::vector3df xyz(0,0,0);
|
||||
//node->get("xyz", &xyz);
|
||||
//core::vector3df hpr(0,0,0);
|
||||
//node->get("hpr", &hpr);
|
||||
//core::vector3df scale(1.0f, 1.0f, 1.0f);
|
||||
//node->get("scale", &scale);
|
||||
std::vector< ModelDefinition >& group = m_lod_groups[groupname];
|
||||
|
||||
if (group.size() > 0)
|
||||
{
|
||||
scene::ISceneNode* actual_parent = (parent == NULL ? sm->getRootSceneNode() : parent);
|
||||
LODNode* lod_node = new LODNode(groupname, actual_parent, sm);
|
||||
//lod_node->setPosition(xyz);
|
||||
//lod_node->setRotation(hpr);
|
||||
//lod_node->setScale(scale);
|
||||
lod_node->updateAbsolutePosition();
|
||||
for (unsigned int m=0; m<group.size(); m++)
|
||||
{
|
||||
@@ -119,14 +109,37 @@ LODNode* LodNodeLoader::instanciate(const XMLNode* node, scene::ISceneNode* pare
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("LodNodeLoader", "LOD group '%s' is empty", groupname.c_str());
|
||||
Log::warn("ModelDefinitionLoader", "LOD group '%s' is empty", groupname.c_str());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void LodNodeLoader::clear()
|
||||
void ModelDefinitionLoader::instanciate(const irr::core::vector3df& position,
|
||||
const irr::core::vector3df& rotation,
|
||||
const std::string& name)
|
||||
{
|
||||
if (m_instancing_nodes.find(name) == m_instancing_nodes.end())
|
||||
{
|
||||
if (m_lod_groups.find(name) == m_lod_groups.end())
|
||||
{
|
||||
Log::warn("Instancing", "Cannot find instancing model <%s>", name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
scene::IMesh* mesh = irr_driver->getMesh(m_lod_groups[name][0].m_model_file);
|
||||
m_instancing_nodes[name] = new STKInstancedSceneNode(mesh,
|
||||
irr_driver->getSceneManager()->getRootSceneNode(), irr_driver->getSceneManager(), -1);
|
||||
m_track->addNode(m_instancing_nodes[name]);
|
||||
}
|
||||
|
||||
m_instancing_nodes[name]->addInstance(position, rotation);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ModelDefinitionLoader::clear()
|
||||
{
|
||||
m_lod_groups.clear();
|
||||
}
|
||||
@@ -21,10 +21,12 @@
|
||||
|
||||
class LODNode;
|
||||
class Track;
|
||||
class STKInstancedSceneNode;
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <irrlicht.h>
|
||||
#include "io/xml_node.hpp"
|
||||
|
||||
namespace irr
|
||||
@@ -36,23 +38,24 @@ namespace irr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct LodModel
|
||||
struct ModelDefinition
|
||||
{
|
||||
std::string m_model_file;
|
||||
bool m_tangent;
|
||||
const XMLNode* m_xml;
|
||||
|
||||
/** For LOD */
|
||||
int m_distance;
|
||||
|
||||
/** Constructor to allow storing this in STL containers */
|
||||
LodModel()
|
||||
ModelDefinition()
|
||||
{
|
||||
m_tangent = false;
|
||||
m_distance = 0;
|
||||
m_xml = NULL;
|
||||
}
|
||||
|
||||
LodModel(const XMLNode* xml, int distance, std::string& model, bool tangent)
|
||||
ModelDefinition(const XMLNode* xml, int distance, std::string& model, bool tangent)
|
||||
{
|
||||
m_model_file = model;
|
||||
m_tangent = tangent;
|
||||
@@ -60,29 +63,32 @@ struct LodModel
|
||||
m_distance = distance;
|
||||
}
|
||||
|
||||
~LodModel()
|
||||
~ModelDefinition()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** Utility class to load level-of-detail nodes
|
||||
/** Utility class to load level-of-detail nodes and instaincing nodes
|
||||
* \ingroup tracks
|
||||
*/
|
||||
class LodNodeLoader
|
||||
class ModelDefinitionLoader
|
||||
{
|
||||
private:
|
||||
std::map< std::string, std::vector< LodModel > > m_lod_groups;
|
||||
std::map< std::string, std::vector< ModelDefinition > > m_lod_groups;
|
||||
std::map< std::string, STKInstancedSceneNode* > m_instancing_nodes;
|
||||
Track* m_track;
|
||||
|
||||
public:
|
||||
LodNodeLoader(Track* track);
|
||||
ModelDefinitionLoader(Track* track);
|
||||
|
||||
void addLODModelDefinition(const XMLNode* xml);
|
||||
LODNode* instanciate(const XMLNode* xml_node, scene::ISceneNode* parent);
|
||||
//Track* track, std::vector<irr::scene::IMesh*>& cache);
|
||||
void addModelDefinition(const XMLNode* xml);
|
||||
LODNode* instanciateAsLOD(const XMLNode* xml_node, scene::ISceneNode* parent);
|
||||
void instanciate(const core::vector3df& position,
|
||||
const irr::core::vector3df& rotation,
|
||||
const std::string& name);
|
||||
|
||||
void clear();
|
||||
|
||||
}; // LodNodeLoader
|
||||
}; // ModelDefinitionLoader
|
||||
|
||||
#endif // HEADER_LOD_NODE_LOADER_HPP
|
||||
@@ -52,7 +52,7 @@
|
||||
#include "race/race_manager.hpp"
|
||||
#include "tracks/bezier_curve.hpp"
|
||||
#include "tracks/check_manager.hpp"
|
||||
#include "tracks/lod_node_loader.hpp"
|
||||
#include "tracks/model_definition_loader.hpp"
|
||||
#include "tracks/track_manager.hpp"
|
||||
#include "tracks/quad_graph.hpp"
|
||||
#include "tracks/quad_set.hpp"
|
||||
@@ -880,7 +880,7 @@ bool Track::loadMainTrack(const XMLNode &root)
|
||||
m_aabb_max.setY(m_aabb_max.getY()+30.0f);
|
||||
World::getWorld()->getPhysics()->init(m_aabb_min, m_aabb_max);
|
||||
|
||||
LodNodeLoader lodLoader(this);
|
||||
ModelDefinitionLoader lodLoader(this);
|
||||
|
||||
// Load LOD groups
|
||||
const XMLNode *lod_xml_node = root.getNode("lod");
|
||||
@@ -891,7 +891,21 @@ bool Track::loadMainTrack(const XMLNode &root)
|
||||
const XMLNode* lod_group_xml = lod_xml_node->getNode(i);
|
||||
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
|
||||
{
|
||||
lodLoader.addLODModelDefinition(lod_group_xml->getNode(j));
|
||||
lodLoader.addModelDefinition(lod_group_xml->getNode(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load instancing models (for the moment they are loaded the same way as LOD to simplify implementation)
|
||||
const XMLNode *instancing_xml_node = root.getNode("instancing");
|
||||
if (instancing_xml_node != NULL)
|
||||
{
|
||||
for (unsigned int i = 0; i < instancing_xml_node->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode* lod_group_xml = instancing_xml_node->getNode(i);
|
||||
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
|
||||
{
|
||||
lodLoader.addModelDefinition(lod_group_xml->getNode(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1075,7 +1089,7 @@ bool Track::loadMainTrack(const XMLNode &root)
|
||||
}
|
||||
else if (lod_instance)
|
||||
{
|
||||
LODNode* node = lodLoader.instanciate(n, NULL);
|
||||
LODNode* node = lodLoader.instanciateAsLOD(n, NULL);
|
||||
if (node != NULL)
|
||||
{
|
||||
node->setPosition(xyz);
|
||||
@@ -1524,7 +1538,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
loadMainTrack(*root);
|
||||
unsigned int main_track_count = m_all_nodes.size();
|
||||
|
||||
LodNodeLoader lod_loader(this);
|
||||
ModelDefinitionLoader model_def_loader(this);
|
||||
|
||||
// Load LOD groups
|
||||
const XMLNode *lod_xml_node = root->getNode("lod");
|
||||
@@ -1535,13 +1549,27 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
const XMLNode* lod_group_xml = lod_xml_node->getNode(i);
|
||||
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
|
||||
{
|
||||
lod_loader.addLODModelDefinition(lod_group_xml->getNode(j));
|
||||
model_def_loader.addModelDefinition(lod_group_xml->getNode(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load instancing models (for the moment they are loaded the same way as LOD to simplify implementation)
|
||||
const XMLNode *instancing_xml_node = root->getNode("instancing");
|
||||
if (instancing_xml_node != NULL)
|
||||
{
|
||||
for (unsigned int i = 0; i < instancing_xml_node->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode* lod_group_xml = instancing_xml_node->getNode(i);
|
||||
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
|
||||
{
|
||||
model_def_loader.addModelDefinition(lod_group_xml->getNode(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, XMLNode*> library_nodes;
|
||||
loadObjects(root, path, lod_loader, true, NULL, library_nodes);
|
||||
loadObjects(root, path, model_def_loader, true, NULL, library_nodes);
|
||||
|
||||
// Cleanup library nodes
|
||||
for (std::map<std::string, XMLNode*>::iterator it = library_nodes.begin();
|
||||
@@ -1709,7 +1737,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoader& lod_loader,
|
||||
void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& model_def_loader,
|
||||
bool create_lod_definitions, scene::ISceneNode* parent,
|
||||
std::map<std::string, XMLNode*>& library_nodes)
|
||||
{
|
||||
@@ -1725,7 +1753,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa
|
||||
if (name == "track" || name == "default-start") continue;
|
||||
if (name == "object")
|
||||
{
|
||||
m_track_object_manager->add(*node, parent, lod_loader);
|
||||
m_track_object_manager->add(*node, parent, model_def_loader);
|
||||
}
|
||||
else if (name == "library")
|
||||
{
|
||||
@@ -1770,7 +1798,21 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa
|
||||
const XMLNode* lod_group_xml = lod_xml_node->getNode(i);
|
||||
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
|
||||
{
|
||||
lod_loader.addLODModelDefinition(lod_group_xml->getNode(j));
|
||||
model_def_loader.addModelDefinition(lod_group_xml->getNode(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load instancing definitions
|
||||
const XMLNode *instancing_xml_node = libroot->getNode("instancing");
|
||||
if (instancing_xml_node != NULL)
|
||||
{
|
||||
for (unsigned int i = 0; i < instancing_xml_node->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode* instancing_group_xml = instancing_xml_node->getNode(i);
|
||||
for (unsigned int j = 0; j < instancing_group_xml->getNumNodes(); j++)
|
||||
{
|
||||
model_def_loader.addModelDefinition(instancing_group_xml->getNode(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1786,7 +1828,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa
|
||||
parent->setRotation(hpr);
|
||||
parent->setScale(scale);
|
||||
parent->updateAbsolutePosition();
|
||||
loadObjects(libroot, lib_path, lod_loader, create_lod_definitions, parent, library_nodes);
|
||||
loadObjects(libroot, lib_path, model_def_loader, create_lod_definitions, parent, library_nodes);
|
||||
}
|
||||
else if (name == "water")
|
||||
{
|
||||
@@ -1830,7 +1872,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa
|
||||
{
|
||||
if (UserConfigParams::m_graphical_effects)
|
||||
{
|
||||
m_track_object_manager->add(*node, parent, lod_loader);
|
||||
m_track_object_manager->add(*node, parent, model_def_loader);
|
||||
}
|
||||
}
|
||||
else if (name == "sky-dome" || name == "sky-box" || name == "sky-color")
|
||||
@@ -1843,7 +1885,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa
|
||||
}
|
||||
else if (name == "light")
|
||||
{
|
||||
m_track_object_manager->add(*node, parent, lod_loader);
|
||||
m_track_object_manager->add(*node, parent, model_def_loader);
|
||||
}
|
||||
else if (name == "weather")
|
||||
{
|
||||
@@ -1883,6 +1925,10 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa
|
||||
{
|
||||
// handled above
|
||||
}
|
||||
else if (name == "instancing")
|
||||
{
|
||||
// handled above
|
||||
}
|
||||
else if (name == "subtitles")
|
||||
{
|
||||
std::vector<XMLNode*> subtitles;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace irr
|
||||
namespace scene { class IMesh; class ILightSceneNode; }
|
||||
}
|
||||
using namespace irr;
|
||||
class LodNodeLoader;
|
||||
class ModelDefinitionLoader;
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
@@ -401,7 +401,7 @@ private:
|
||||
std::vector<MusicInformation*>& m_music );
|
||||
void loadCurves(const XMLNode &node);
|
||||
void handleSky(const XMLNode &root, const std::string &filename);
|
||||
void loadObjects(const XMLNode* root, const std::string& path, LodNodeLoader& lod_loader,
|
||||
void loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& lod_loader,
|
||||
bool create_lod_definitions, scene::ISceneNode* parent,
|
||||
std::map<std::string, XMLNode*>& library_nodes);
|
||||
|
||||
@@ -606,6 +606,7 @@ public:
|
||||
bool hasGodRays() const { return m_godrays; }
|
||||
bool hasShadows() const { return m_shadows; }
|
||||
|
||||
void addNode(scene::ISceneNode* node) { m_all_nodes.push_back(node); }
|
||||
|
||||
float getDisplacementSpeed() const { return m_displacement_speed; }
|
||||
float getCausticsSpeed() const { return m_caustics_speed; }
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
* \param lod_node Lod node (defaults to NULL).
|
||||
*/
|
||||
TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent,
|
||||
LodNodeLoader& lod_loader)
|
||||
ModelDefinitionLoader& model_def_loader)
|
||||
{
|
||||
init(xml_node, parent, lod_loader);
|
||||
init(xml_node, parent, model_def_loader);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -80,7 +80,7 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr,
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
|
||||
LodNodeLoader& lod_loader)
|
||||
ModelDefinitionLoader& model_def_loader)
|
||||
{
|
||||
m_init_xyz = core::vector3df(0,0,0);
|
||||
m_init_hpr = core::vector3df(0,0,0);
|
||||
@@ -103,6 +103,9 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
|
||||
bool lod_instance = false;
|
||||
xml_node.get("lod_instance", &lod_instance);
|
||||
|
||||
bool instancing = false;
|
||||
xml_node.get("instancing", &instancing);
|
||||
|
||||
m_soccer_ball = false;
|
||||
xml_node.get("soccer_ball", &m_soccer_ball);
|
||||
|
||||
@@ -156,11 +159,18 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
|
||||
{
|
||||
scene::ISceneNode *glownode = NULL;
|
||||
|
||||
if (lod_instance)
|
||||
if (instancing)
|
||||
{
|
||||
m_type = "lod";
|
||||
TrackObjectPresentationInstancing* instancing_node =
|
||||
new TrackObjectPresentationInstancing(xml_node, parent, model_def_loader);
|
||||
m_presentation = instancing_node;
|
||||
}
|
||||
else if (lod_instance)
|
||||
{
|
||||
m_type = "lod";
|
||||
TrackObjectPresentationLOD* lod_node =
|
||||
new TrackObjectPresentationLOD(xml_node, parent, lod_loader);
|
||||
new TrackObjectPresentationLOD(xml_node, parent, model_def_loader);
|
||||
m_presentation = lod_node;
|
||||
|
||||
glownode = ((LODNode*)lod_node->getNode())->getAllNodes()[0];
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
class XMLNode;
|
||||
class ThreeDAnimation;
|
||||
class LodNodeLoader;
|
||||
class ModelDefinitionLoader;
|
||||
|
||||
/**
|
||||
* \ingroup tracks
|
||||
@@ -82,10 +82,10 @@ protected:
|
||||
|
||||
ThreeDAnimation* m_animator;
|
||||
|
||||
void init(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader);
|
||||
void init(const XMLNode &xml_node, scene::ISceneNode* parent, ModelDefinitionLoader& model_def_loader);
|
||||
|
||||
public:
|
||||
TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader);
|
||||
TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, ModelDefinitionLoader& model_def_loader);
|
||||
|
||||
TrackObject(const core::vector3df& xyz,
|
||||
const core::vector3df& hpr,
|
||||
|
||||
@@ -49,11 +49,11 @@ TrackObjectManager::~TrackObjectManager()
|
||||
* in a separate section that's read before everything and remove all this
|
||||
* crap
|
||||
*/
|
||||
void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader)
|
||||
void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent, ModelDefinitionLoader& model_def_loader)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_all_objects.push_back(new TrackObject(xml_node, parent, lod_loader));
|
||||
m_all_objects.push_back(new TrackObject(xml_node, parent, model_def_loader));
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@ protected:
|
||||
public:
|
||||
TrackObjectManager();
|
||||
~TrackObjectManager();
|
||||
void add(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader);
|
||||
void add(const XMLNode &xml_node, scene::ISceneNode* parent, ModelDefinitionLoader& model_def_loader);
|
||||
void update(float dt);
|
||||
void handleExplosion(const Vec3 &pos, const PhysicalObject *mp,
|
||||
bool secondary_hits=true);
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "modes/world.hpp"
|
||||
#include "states_screens/dialogs/race_paused_dialog.hpp"
|
||||
#include "states_screens/dialogs/tutorial_message_dialog.hpp"
|
||||
#include "tracks/lod_node_loader.hpp"
|
||||
#include "tracks/model_definition_loader.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
|
||||
#include <ISceneManager.h>
|
||||
@@ -138,10 +138,10 @@ TrackObjectPresentationEmpty::~TrackObjectPresentationEmpty()
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node,
|
||||
scene::ISceneNode* parent, LodNodeLoader& lod_loader) :
|
||||
scene::ISceneNode* parent, ModelDefinitionLoader& model_def_loader) :
|
||||
TrackObjectPresentationSceneNode(xml_node)
|
||||
{
|
||||
m_node = lod_loader.instanciate(&xml_node, parent);
|
||||
m_node = model_def_loader.instanciateAsLOD(&xml_node, parent);
|
||||
if (m_node == NULL) throw std::runtime_error("Cannot load LOD node");
|
||||
m_node->setPosition(m_init_xyz);
|
||||
m_node->setRotation(m_init_hpr);
|
||||
@@ -156,6 +156,27 @@ TrackObjectPresentationLOD::~TrackObjectPresentationLOD()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TrackObjectPresentationInstancing::TrackObjectPresentationInstancing(const XMLNode& xml_node,
|
||||
scene::ISceneNode* parent,
|
||||
ModelDefinitionLoader& model_def_loader) : TrackObjectPresentationSceneNode(xml_node)
|
||||
{
|
||||
std::string instancing_model;
|
||||
xml_node.get("instancing_model", &instancing_model);
|
||||
|
||||
m_node = irr_driver->getSceneManager()->addEmptySceneNode(parent);
|
||||
m_node->setPosition(m_init_xyz);
|
||||
m_node->setRotation(m_init_hpr);
|
||||
m_node->setScale(m_init_scale);
|
||||
m_node->updateAbsolutePosition();
|
||||
model_def_loader.instanciate(m_node->getAbsolutePosition(), m_init_hpr, instancing_model);
|
||||
}
|
||||
|
||||
TrackObjectPresentationInstancing::~TrackObjectPresentationInstancing()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node,
|
||||
bool enabled, scene::ISceneNode* parent) :
|
||||
TrackObjectPresentationSceneNode(xml_node)
|
||||
|
||||
@@ -40,7 +40,7 @@ class SFXBase;
|
||||
class ParticleEmitter;
|
||||
class PhysicalObject;
|
||||
class ThreeDAnimation;
|
||||
class LodNodeLoader;
|
||||
class ModelDefinitionLoader;
|
||||
|
||||
/**
|
||||
* \ingroup tracks
|
||||
@@ -152,10 +152,20 @@ public:
|
||||
|
||||
TrackObjectPresentationLOD(const XMLNode& xml_node,
|
||||
scene::ISceneNode* parent,
|
||||
LodNodeLoader& lod_loader);
|
||||
ModelDefinitionLoader& model_def_loader);
|
||||
virtual ~TrackObjectPresentationLOD();
|
||||
};
|
||||
|
||||
class TrackObjectPresentationInstancing : public TrackObjectPresentationSceneNode
|
||||
{
|
||||
public:
|
||||
|
||||
TrackObjectPresentationInstancing(const XMLNode& xml_node,
|
||||
scene::ISceneNode* parent,
|
||||
ModelDefinitionLoader& model_def_loader);
|
||||
virtual ~TrackObjectPresentationInstancing();
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup tracks
|
||||
* A track object representation that consists of a mesh scene node.
|
||||
|
||||
Reference in New Issue
Block a user