Port slipstream to SP
This commit is contained in:
parent
17c337284e
commit
3a24d0ed1f
@ -20,10 +20,12 @@
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/stk_mesh_scene_node.hpp"
|
||||
#include "graphics/stk_tex_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "graphics/sp/sp_mesh.hpp"
|
||||
#include "graphics/sp/sp_mesh_node.hpp"
|
||||
#include "graphics/sp/sp_uniform_assigner.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
@ -32,10 +34,7 @@
|
||||
#include "modes/world.hpp"
|
||||
#include "tracks/quad.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
|
||||
#include <SMesh.h>
|
||||
#include <SMeshBuffer.h>
|
||||
#include <IMeshSceneNode.h>
|
||||
#include "utils/mini_glm.hpp"
|
||||
|
||||
/** Creates the slip stream object using a moving texture.
|
||||
* \param kart Pointer to the kart to which the slip stream
|
||||
@ -43,30 +42,27 @@
|
||||
*/
|
||||
SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
|
||||
{
|
||||
Material *material = material_manager->getMaterial("slipstream.png");
|
||||
|
||||
createMesh(material);
|
||||
m_node = irr_driver->addMesh(m_mesh, "splistream");
|
||||
|
||||
scene::IMeshBuffer* buffer = m_mesh->getMeshBuffer(0);
|
||||
material->setMaterialProperties(&buffer->getMaterial(), buffer);
|
||||
m_node = NULL;
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
STKMeshSceneNode* stk_node = dynamic_cast<STKMeshSceneNode*>(m_node);
|
||||
if (stk_node != NULL)
|
||||
stk_node->setReloadEachFrame(true);
|
||||
m_mesh->drop();
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
Material* material =
|
||||
material_manager->getMaterialSPM("slipstream.png", "");
|
||||
SP::SPMesh* mesh = createMesh(material);
|
||||
m_node = irr_driver->addMesh(mesh, "slipstream");
|
||||
mesh->drop();
|
||||
std::string debug_name = m_kart->getIdent()+" (slip-stream)";
|
||||
m_node->setName(debug_name.c_str());
|
||||
m_node->setPosition(core::vector3df(0, 0 * 0.25f + 2.5f,
|
||||
m_kart->getKartLength()));
|
||||
m_node->setVisible(false);
|
||||
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(m_node);
|
||||
assert(spmn);
|
||||
spmn->setTextureMatrix(0, getSPTM());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
std::string debug_name = m_kart->getIdent()+" (slip-stream)";
|
||||
m_node->setName(debug_name.c_str());
|
||||
#endif
|
||||
m_node->setPosition(core::vector3df(0,
|
||||
0*0.25f+2.5,
|
||||
m_kart->getKartLength()) );
|
||||
m_node->setVisible(false);
|
||||
setTextureMatrix(&(m_node->getMaterial(0).getTextureMatrix(0)));
|
||||
m_slipstream_time = 0.0f;
|
||||
|
||||
float length = m_kart->getKartProperties()->getSlipstreamLength();
|
||||
@ -80,43 +76,28 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
|
||||
p[2]=Vec3( ew*0.5f, 0, -kl*0.5f-length);
|
||||
p[3]=Vec3( kw*0.5f, 0, -kl*0.5f );
|
||||
m_slipstream_quad = new Quad(p[0], p[1], p[2], p[3]);
|
||||
if(UserConfigParams::m_slipstream_debug)
|
||||
{
|
||||
video::SMaterial material;
|
||||
material.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||
material.setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||
material.setFlag(video::EMF_LIGHTING, false);
|
||||
|
||||
m_debug_mesh = irr_driver->createQuadMesh(&material, true);
|
||||
scene::IMeshBuffer *buffer = m_debug_mesh->getMeshBuffer(0);
|
||||
assert(buffer->getVertexType()==video::EVT_STANDARD);
|
||||
irr::video::S3DVertex* vertices
|
||||
= (video::S3DVertex*)buffer->getVertices();
|
||||
video::SColor red(128, 255, 0, 0);
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
vertices[i].Pos = p[i].toIrrVector();
|
||||
vertices[i].Color = red;
|
||||
vertices[i].TCoords = core::vector2df(0, 0);
|
||||
}
|
||||
video::SMaterial &mat = buffer->getMaterial();
|
||||
// Meshes need a texture, otherwise stk crashes.
|
||||
#ifndef SERVER_ONLY
|
||||
video::ITexture *red_texture = STKTexManager::getInstance()->getUnicolorTexture(red);
|
||||
mat.setTexture(0, red_texture);
|
||||
#endif
|
||||
|
||||
buffer->recalculateBoundingBox();
|
||||
m_mesh->setBoundingBox(buffer->getBoundingBox());
|
||||
m_debug_node = irr_driver->addMesh(m_debug_mesh, "splistream_debug", m_kart->getNode());
|
||||
m_debug_node->grab();
|
||||
}
|
||||
else
|
||||
if (UserConfigParams::m_slipstream_debug)
|
||||
{
|
||||
m_debug_mesh = NULL;
|
||||
m_debug_node = NULL;
|
||||
m_debug_dc = std::make_shared<SP::SPDynamicDrawCall>
|
||||
(scene::EPT_TRIANGLE_STRIP, SP::getSPShader("additive"),
|
||||
material_manager->getSPMaterial("additive"));
|
||||
m_debug_dc->getVerticesVector().resize(4);
|
||||
video::S3DVertexSkinnedMesh* v =
|
||||
m_debug_dc->getVerticesVector().data();
|
||||
video::SColor red(128, 255, 0, 0);
|
||||
unsigned idx[] = { 0, 3, 1, 2 };
|
||||
for (unsigned i; i < 4; i++)
|
||||
{
|
||||
v[i].m_position = p[idx[i]].toIrrVector();
|
||||
v[i].m_normal = 0x1FF << 10;
|
||||
v[i].m_color = red;
|
||||
}
|
||||
m_debug_dc->recalculateBoundingBox();
|
||||
m_debug_dc->setParent(m_kart->getNode());
|
||||
SP::addDynamicDrawCall(m_debug_dc);
|
||||
}
|
||||
|
||||
#endif
|
||||
} // SlipStream
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -124,11 +105,13 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
|
||||
*/
|
||||
SlipStream::~SlipStream()
|
||||
{
|
||||
irr_driver->removeNode(m_node);
|
||||
if(m_debug_node)
|
||||
if (m_node)
|
||||
{
|
||||
m_debug_node->drop();
|
||||
m_debug_mesh->drop();
|
||||
irr_driver->removeNode(m_node);
|
||||
}
|
||||
if (m_debug_dc)
|
||||
{
|
||||
m_debug_dc->removeFromSP();
|
||||
}
|
||||
delete m_slipstream_quad;
|
||||
|
||||
@ -152,8 +135,10 @@ void SlipStream::reset()
|
||||
* texture coordniates.
|
||||
* \param material The material to use.
|
||||
*/
|
||||
void SlipStream::createMesh(Material* material)
|
||||
SP::SPMesh* SlipStream::createMesh(Material* material)
|
||||
{
|
||||
SP::SPMesh* spm = NULL;
|
||||
#ifndef SERVER_ONLY
|
||||
// All radius, starting with the one closest to the kart (and
|
||||
// widest) to the one furthest away. A 0 indicates the end of the list
|
||||
float radius[] = {1.5f, 1.0f, 0.5f, 0.0f};
|
||||
@ -196,25 +181,37 @@ void SlipStream::createMesh(Material* material)
|
||||
const unsigned int first_segment = 0;
|
||||
const unsigned int last_segment = 14;
|
||||
const float f = 2*M_PI/float(num_segments);
|
||||
scene::SMeshBuffer *buffer = new scene::SMeshBuffer();
|
||||
buffer->getMaterial().TextureLayer[0].Texture = material->getTexture();
|
||||
SP::SPMeshBuffer* buffer = new SP::SPMeshBuffer();
|
||||
|
||||
static_cast<SP::SPPerObjectUniform*>(buffer)->addAssignerFunction
|
||||
("custom_alpha", [this](SP::SPUniformAssigner* ua)->void
|
||||
{
|
||||
// In sp shader it's assigned reverse by 1.0 - custom_alpha
|
||||
ua->setValue(1.0f - m_slipstream_time);
|
||||
});
|
||||
|
||||
std::vector<uint16_t> indices;
|
||||
std::vector<video::S3DVertexSkinnedMesh> vertices;
|
||||
for(unsigned int j=0; j<num_circles; j++)
|
||||
{
|
||||
float curr_distance = distance[j]-distance[0];
|
||||
// Create the vertices for each of the circle
|
||||
for(unsigned int i=first_segment; i<=last_segment; i++)
|
||||
{
|
||||
video::S3DVertex v;
|
||||
video::S3DVertexSkinnedMesh v;
|
||||
// Offset every 2nd circle by one half segment to increase
|
||||
// the number of planes so it looks better.
|
||||
v.Pos.X = sin((i+(j%2)*0.5f)*f)*radius[j];
|
||||
v.Pos.Y = -cos((i+(j%2)*0.5f)*f)*radius[j];
|
||||
v.Pos.Z = distance[j];
|
||||
v.Color = video::SColor(alphas[j], alphas[j], alphas[j], alphas[j]);
|
||||
v.TCoords.X = curr_distance/m_length;
|
||||
v.TCoords.Y = (float)(i-first_segment)/(last_segment-first_segment)
|
||||
+ (j%2)*(.5f/num_segments);
|
||||
buffer->Vertices.push_back(v);
|
||||
v.m_position.X = sin((i+(j%2)*0.5f)*f)*radius[j];
|
||||
v.m_position.Y = -cos((i+(j%2)*0.5f)*f)*radius[j];
|
||||
v.m_position.Z = distance[j];
|
||||
// Enable texture matrix and dummy normal for visualization
|
||||
v.m_normal = 0x1FF << 10 | 1 << 30;
|
||||
v.m_color = video::SColor(alphas[j], 255, 255, 255);
|
||||
v.m_all_uvs[0] = MiniGLM::toFloat16(curr_distance/m_length);
|
||||
v.m_all_uvs[1] = MiniGLM::toFloat16(
|
||||
(float)(i-first_segment)/(last_segment-first_segment)
|
||||
+ (j%2)*(.5f/num_segments));
|
||||
vertices.push_back(v);
|
||||
} // for i<num_segments
|
||||
} // while radius[num_circles]!=0
|
||||
|
||||
@ -225,32 +222,23 @@ void SlipStream::createMesh(Material* material)
|
||||
{
|
||||
for(unsigned int i=first_segment; i<last_segment; i++)
|
||||
{
|
||||
buffer->Indices.push_back( j *diff_segments+i );
|
||||
buffer->Indices.push_back((j+1)*diff_segments+i );
|
||||
buffer->Indices.push_back( j *diff_segments+i+1);
|
||||
buffer->Indices.push_back( j *diff_segments+i+1);
|
||||
buffer->Indices.push_back((j+1)*diff_segments+i );
|
||||
buffer->Indices.push_back((j+1)*diff_segments+i+1);
|
||||
indices.push_back(uint16_t( j *diff_segments+i ));
|
||||
indices.push_back(uint16_t((j+1)*diff_segments+i ));
|
||||
indices.push_back(uint16_t( j *diff_segments+i+1));
|
||||
indices.push_back(uint16_t( j *diff_segments+i+1));
|
||||
indices.push_back(uint16_t((j+1)*diff_segments+i ));
|
||||
indices.push_back(uint16_t((j+1)*diff_segments+i+1));
|
||||
}
|
||||
} // for j<num_circles-1
|
||||
buffer->setSPMVertices(vertices);
|
||||
buffer->setIndices(indices);
|
||||
buffer->setSTKMaterial(material);
|
||||
|
||||
material->setMaterialProperties(&buffer->getMaterial(), buffer);
|
||||
#ifndef SERVER_ONLY
|
||||
if (!CVS->isGLSL())
|
||||
spm = new SP::SPMesh();
|
||||
spm->addSPMeshBuffer(buffer);
|
||||
spm->updateBoundingBox();
|
||||
#endif
|
||||
{
|
||||
buffer->Material.setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||
buffer->Material.setFlag(video::EMF_COLOR_MATERIAL, true);
|
||||
buffer->Material.ColorMaterial = video::ECM_DIFFUSE_AND_AMBIENT;
|
||||
//buffer->Material.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||
}
|
||||
|
||||
scene::SMesh *mesh = new scene::SMesh();
|
||||
mesh->addMeshBuffer(buffer);
|
||||
mesh->recalculateBoundingBox();
|
||||
|
||||
buffer->drop();
|
||||
m_mesh = mesh;
|
||||
return spm;
|
||||
} // createMesh
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -261,9 +249,12 @@ void SlipStream::createMesh(Material* material)
|
||||
*/
|
||||
void SlipStream::setIntensity(float f, const AbstractKart *kart)
|
||||
{
|
||||
if(!kart)
|
||||
if (!kart || !m_node)
|
||||
{
|
||||
m_node->setVisible(false);
|
||||
if (m_node)
|
||||
{
|
||||
m_node->setVisible(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -285,24 +276,6 @@ void SlipStream::setIntensity(float f, const AbstractKart *kart)
|
||||
m_node->setVisible(f!=0);
|
||||
MovingTexture::setSpeed(f, 0);
|
||||
|
||||
|
||||
int c = (int)(f*255);
|
||||
if (c > 255) c = 255;
|
||||
|
||||
/*const unsigned int bcount = m_node->getMesh()->getMeshBufferCount();
|
||||
for (unsigned int b=0; b<bcount; b++)
|
||||
{
|
||||
scene::IMeshBuffer* mb = m_node->getMesh()->getMeshBuffer(b);
|
||||
irr::video::S3DVertex* vertices = (video::S3DVertex*)mb->getVertices();
|
||||
for (unsigned int i=0; i<mb->getVertexCount(); i++)
|
||||
{
|
||||
const int color = (int)(c*(vertices[i].Color.getAlpha()/255.0f));
|
||||
vertices[i].Color.setRed( color );
|
||||
vertices[i].Color.setGreen( color );
|
||||
vertices[i].Color.setBlue( color );
|
||||
}
|
||||
}*/
|
||||
|
||||
return;
|
||||
// For debugging: make the slip stream effect visible all the time
|
||||
m_node->setVisible(true);
|
||||
@ -349,14 +322,18 @@ void SlipStream::updateSlipstreamPower()
|
||||
*/
|
||||
void SlipStream::setDebugColor(const video::SColor &color)
|
||||
{
|
||||
if(!UserConfigParams::m_slipstream_debug) return;
|
||||
// FIXME: Does not work anymore - the colour is changed, but
|
||||
// visually there is no change.
|
||||
scene::IMeshBuffer *buffer = m_debug_mesh->getMeshBuffer(0);
|
||||
irr::video::S3DVertex* vertices =
|
||||
(video::S3DVertex*)buffer->getVertices();
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
vertices[i].Color=color;
|
||||
if (!m_debug_dc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
video::S3DVertexSkinnedMesh* v = m_debug_dc->getVerticesVector().data();
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
{
|
||||
v[i].m_color = color;
|
||||
}
|
||||
m_debug_dc->setUpdateOffset(0);
|
||||
|
||||
} // setDebugColor
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -23,12 +23,19 @@
|
||||
namespace irr
|
||||
{
|
||||
namespace video { class SMaterial; class SColor; }
|
||||
namespace scene { class ISceneNode; class IMesh; class IMesh; }
|
||||
namespace scene { class ISceneNode; }
|
||||
}
|
||||
using namespace irr;
|
||||
|
||||
namespace SP
|
||||
{
|
||||
class SPDynamicDrawCall;
|
||||
class SPMesh;
|
||||
}
|
||||
|
||||
#include "graphics/moving_texture.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include <memory>
|
||||
|
||||
class AbstractKart;
|
||||
class Quad;
|
||||
@ -46,14 +53,8 @@ private:
|
||||
/** The scene node. */
|
||||
scene::ISceneNode *m_node;
|
||||
|
||||
/** The actual mesh. */
|
||||
scene::IMesh *m_mesh;
|
||||
|
||||
/** For debugging: display where slipstream works. */
|
||||
scene::ISceneNode *m_debug_node;
|
||||
|
||||
/** For debugging: a simple quad to display where slipstream works. */
|
||||
scene::IMesh *m_debug_mesh;
|
||||
std::shared_ptr<SP::SPDynamicDrawCall> m_debug_dc;
|
||||
|
||||
/** The length of the slipstream cylinder. This is used to scale
|
||||
* the actual scene node correctly. */
|
||||
@ -73,7 +74,7 @@ private:
|
||||
** overtake the right kart. */
|
||||
AbstractKart* m_target_kart;
|
||||
|
||||
void createMesh(Material* material);
|
||||
SP::SPMesh* createMesh(Material* material);
|
||||
void setDebugColor(const video::SColor &color);
|
||||
public:
|
||||
SlipStream (AbstractKart* kart);
|
||||
|
@ -1685,6 +1685,22 @@ void drawNormal()
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < g_final_draw_calls[5].size(); i++)
|
||||
{
|
||||
auto& p = g_final_draw_calls[5][i];
|
||||
for (unsigned j = 0; j < p.second.size(); j++)
|
||||
{
|
||||
for (unsigned k = 0; k < p.second[j].second.size(); k++)
|
||||
{
|
||||
// Make sure tangents and joints are not drawn undefined
|
||||
glVertexAttrib4f(5, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glVertexAttribI4i(6, 0, 0, 0, 0);
|
||||
glVertexAttrib4f(7, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
p.second[j].second[k].first->draw(DCT_TRANSPARENT,
|
||||
-1/*material_id*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
nv->unuse();
|
||||
#endif
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "graphics/sp/sp_mesh_buffer.hpp"
|
||||
|
||||
#include <IMeshBuffer.h>
|
||||
#include <ISceneNode.h>
|
||||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
@ -30,7 +31,6 @@
|
||||
#include <vector>
|
||||
|
||||
using namespace irr;
|
||||
using namespace scene;
|
||||
|
||||
class Material;
|
||||
|
||||
@ -38,7 +38,6 @@ namespace SP
|
||||
{
|
||||
class SPShader;
|
||||
|
||||
|
||||
class SPDynamicDrawCall : public SPMeshBuffer
|
||||
{
|
||||
private:
|
||||
@ -46,13 +45,15 @@ private:
|
||||
|
||||
SPShader* m_shader;
|
||||
|
||||
scene::ISceneNode* m_parent = NULL;
|
||||
|
||||
core::vector2df m_texture_trans;
|
||||
|
||||
scene::E_PRIMITIVE_TYPE m_primitive_type;
|
||||
|
||||
unsigned m_gl_vbo_size = 4;
|
||||
|
||||
int m_update_offset = -1;
|
||||
int m_update_offset = 0;
|
||||
|
||||
bool m_visible = true;
|
||||
|
||||
@ -85,10 +86,10 @@ public:
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (m_texture_trans.X != 0.0f || m_texture_trans.Y != 0.0f ||
|
||||
m_update_trans)
|
||||
m_update_trans || m_parent != NULL)
|
||||
{
|
||||
m_update_trans = false;
|
||||
SPInstancedData id = SPInstancedData(m_trans,
|
||||
SPInstancedData id = SPInstancedData(getAbsoluteTransformation(),
|
||||
m_texture_trans.X, m_texture_trans.Y, 0.0f, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_ibo);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, 32, &id);
|
||||
@ -139,7 +140,15 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
void setVisible(bool val) { m_visible = val; }
|
||||
// ------------------------------------------------------------------------
|
||||
const core::matrix4& getAbsoluteTransformation() const { return m_trans; }
|
||||
core::matrix4 getAbsoluteTransformation() const
|
||||
{
|
||||
core::matrix4 trans = m_trans;
|
||||
if (m_parent != NULL)
|
||||
{
|
||||
trans = m_parent->getAbsoluteTransformation() * trans;
|
||||
}
|
||||
return trans;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void removeFromSP() { m_removing = true; }
|
||||
// ------------------------------------------------------------------------
|
||||
@ -147,7 +156,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
bool notReadyFromDrawing() const { return m_vertices.size() < 3; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setAbsoluteTransformation(core::matrix4& mat)
|
||||
void setTransformation(const core::matrix4& mat)
|
||||
{
|
||||
m_trans = mat;
|
||||
m_update_trans = true;
|
||||
@ -176,6 +185,8 @@ public:
|
||||
m_trans.setScale(scale);
|
||||
m_update_trans = true;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void setParent(scene::ISceneNode* parent) { m_parent = parent; }
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user