//----------------------------------------------------------------------------- void KartModel::attachHat() { m_hat_node = NULL; if(m_hat_name.size()>0) { scene::IBoneSceneNode *bone = m_animated_node->getJointNode("Head"); if(!bone) bone = m_animated_node->getJointNode("head"); if(bone) { // Till we have all models fixed, accept Head and head as bone name scene::IMesh *hat_mesh = irr_driver->getAnimatedMesh( file_manager->getAsset(FileManager::MODEL, m_hat_name)); m_hat_node = irr_driver->addMesh(hat_mesh, "hat"); bone->addChild(m_hat_node); m_animated_node->setCurrentFrame((float)m_animation_frame[AF_STRAIGHT]); m_animated_node->OnAnimate(0); bone->updateAbsolutePosition(); // With the hat node attached to the head bone, we have to // reverse the transformation of the bone, so that the hat // is still properly placed. Esp. the hat offset needs // to be rotated. const core::matrix4 mat = bone->getAbsoluteTransformation(); core::matrix4 inv; mat.getInverse(inv); core::vector3df rotated_offset; inv.rotateVect(rotated_offset, m_hat_offset); m_hat_node->setPosition(rotated_offset); m_hat_node->setScale(inv.getScale()); m_hat_node->setRotation(inv.getRotationDegrees()); } // if bone } // if(m_hat_name) } // attachHat
void computeTIMV(core::matrix4 &TransposeInverseModelView) { TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); TransposeInverseModelView.makeInverse(); TransposeInverseModelView = TransposeInverseModelView.getTransposed(); }
void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3df &rh_extend, GLuint shr, GLuint shg, GLuint shb) { core::matrix4 InvRHMatrix; RHMatrix.getInverse(InvRHMatrix); glDisable(GL_DEPTH_TEST); glUseProgram(FullScreenShader::GlobalIlluminationReconstructionShader::Program); glBindVertexArray(FullScreenShader::GlobalIlluminationReconstructionShader::vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_3D, shr); { glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_3D, shg); { glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_3D, shb); { glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } setTexture(3, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST); setTexture(4, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST); FullScreenShader::GlobalIlluminationReconstructionShader::setUniforms(RHMatrix, InvRHMatrix, rh_extend, 3, 4, 0, 1, 2); glDrawArrays(GL_TRIANGLES, 0, 3); }
/** Given a matrix transform and a set of points returns an orthogonal projection matrix that maps coordinates of transformed points between -1 and 1. * \param transform a transform matrix. * \param pointsInside a vector of point in 3d space. */ core::matrix4 getTighestFitOrthoProj(const core::matrix4 &transform, const std::vector<vector3df> &pointsInside) { float xmin = std::numeric_limits<float>::infinity(); float xmax = -std::numeric_limits<float>::infinity(); float ymin = std::numeric_limits<float>::infinity(); float ymax = -std::numeric_limits<float>::infinity(); float zmin = std::numeric_limits<float>::infinity(); float zmax = -std::numeric_limits<float>::infinity(); for (unsigned i = 0; i < pointsInside.size(); i++) { vector3df TransformedVector; transform.transformVect(TransformedVector, pointsInside[i]); xmin = MIN2(xmin, TransformedVector.X); xmax = MAX2(xmax, TransformedVector.X); ymin = MIN2(ymin, TransformedVector.Y); ymax = MAX2(ymax, TransformedVector.Y); zmin = MIN2(zmin, TransformedVector.Z); zmax = MAX2(zmax, TransformedVector.Z); } float left = xmin; float right = xmax; float up = ymin; float down = ymax; core::matrix4 tmp_matrix; // Prevent Matrix without extend if (left == right || up == down) return tmp_matrix; tmp_matrix.buildProjectionMatrixOrthoLH(left, right, down, up, 30, zmax); return tmp_matrix; }
void GLMaterial::setParameterImpl(ShaderParameter* parameter, const core::matrix4& m) { GLShaderParameter* glParam = static_cast<GLShaderParameter*>(parameter); if (glParam != nullptr) { glUniformMatrix4fv(glParam->ParameterID, 1, GL_TRUE/*GL_FALSE*/, m.get()); } }
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const core::matrix4 &mat, Args... arg) { #ifndef GL_FALSE #define GL_FALSE 0 #endif glUniformMatrix4fvWraper(uniforms[N], 1, GL_FALSE, mat.pointer()); setUniformsHelper<N + 1>(uniforms, arg...); }
void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3df &rh_extend, GLuint shr, GLuint shg, GLuint shb) { core::matrix4 InvRHMatrix; RHMatrix.getInverse(InvRHMatrix); glDisable(GL_DEPTH_TEST); FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->SetTextureUnits(createVector<GLuint>( irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), shr, shg, shb)); DrawFullScreenEffect<FullScreenShader::GlobalIlluminationReconstructionShader>(RHMatrix, InvRHMatrix, rh_extend); }
void interpolate_matrix(const core::matrix4 &a, const core::matrix4 &b, f32 alpha, core::matrix4 &dest) { // I think the reason I interpolate position and rotation separately (rather than using matrix.interpolate) // is for slerp. dest.setTranslation( core::lerp(a.getTranslation(), b.getTranslation(), alpha) ); dest.setRotationDegrees( interpolate_rotation(a.getRotationDegrees(),b.getRotationDegrees(),alpha) ); }
void genProjViewMatrix() { m_ProjViewMatrix = m_ProjMatrix * m_ViewMatrix; m_InvProjViewMatrix = m_ProjViewMatrix; m_InvProjViewMatrix.makeInverse(); }
void setProjMatrix(core::matrix4 matrix) { m_ProjMatrix = matrix; matrix.getInverse(m_InvProjMatrix); }
// ------------------------------------------------------------------------ void setViewMatrix(core::matrix4 matrix) { m_ViewMatrix = matrix; matrix.getInverse(m_InvViewMatrix); }
void BuildCylinder( core::array<video::S3DVertex>& vertexArray, core::array<u16>& indexArray, core::aabbox3d<f32>& boundingBox, f32 height, f32 startRadius, f32 endRadius, s32 radialSegments, const core::matrix4& transform, f32 startTCoordY = 0.0f, f32 endTCoordY = 1.0f, video::SColor startColor = video::SColor(255,255,255,255), video::SColor endColor = video::SColor(255,255,255,255) ) { u16 vertexIndex = vertexArray.size(); s32 radialVertices = radialSegments + 1; // We want one additional vertex to make the texture wraps correctly // Place bottom cap for ( s32 i=0; i<radialVertices; i++ ) { f32 angle = 2.0f * core::PI * i / (f32)( radialSegments ); core::vector3df dir; dir.X = cos(angle); dir.Z = sin(angle); core::vector3df pos; core::vector3df normal = dir; pos = dir * startRadius; // Place bottom vertex transform.transformVect( pos ); transform.rotateVect( normal ); core::vector2df tcoord; tcoord.X = (f32)( i ) / (f32)( radialSegments ); tcoord.Y = startTCoordY; vertexArray.push_back( video::S3DVertex( pos, normal, startColor, tcoord ) ); boundingBox.addInternalPoint( pos ); } // Place top cap and indices for ( s32 i=0; i<radialVertices; i++ ) { f32 angle = 2.0f * core::PI * i / (f32)( radialSegments ); core::vector3df dir; dir.X = cos(angle); dir.Z = sin(angle); core::vector3df normal = dir; core::vector3df pos = dir * endRadius; pos.Y = height; transform.transformVect( pos ); transform.rotateVect( normal ); core::vector2df tcoord; tcoord.X = (f32)( i ) / (f32)( radialSegments ); tcoord.Y = endTCoordY; vertexArray.push_back( video::S3DVertex( pos, normal, endColor, tcoord ) ); boundingBox.addInternalPoint(pos); // Add indices if ( i != radialVertices-1 ) { s32 i2 = (i+1)%radialVertices; // Place the indices indexArray.push_back ( vertexIndex + i ); indexArray.push_back ( vertexIndex + radialVertices + i ); indexArray.push_back ( vertexIndex + i2 ); indexArray.push_back ( vertexIndex + radialVertices + i ); indexArray.push_back ( vertexIndex + radialVertices + i2 ); indexArray.push_back ( vertexIndex + i2 ); } } }
// ---------------------------------------------------------------------------- void STKParticle::stimulateNormal(float dt, unsigned int active_count, std::vector<CPUParticle>* out) { const core::matrix4 cur_matrix = AbsoluteTransformation; core::vector3df previous_frame_position, current_frame_position, previous_frame_direction, current_frame_direction; for (unsigned i = 0; i < m_max_count; i++) { core::vector3df new_particle_position; core::vector3df new_particle_direction; float new_size = 0.0f; float new_lifetime = 0.0f; const core::vector3df particle_position = m_particles_generating[i].m_position; const float lifetime = m_particles_generating[i].m_lifetime; const core::vector3df particle_direction = m_particles_generating[i].m_direction; const float size = m_particles_generating[i].m_size; const core::vector3df particle_position_initial = m_initial_particles[i].m_position; const float lifetime_initial = m_initial_particles[i].m_lifetime; const core::vector3df particle_direction_initial = m_initial_particles[i].m_direction; const float size_initial = m_initial_particles[i].m_size; float updated_lifetime = lifetime + (dt / lifetime_initial); if (updated_lifetime > 1.0f) { if (i < active_count) { float dt_from_last_frame = glslFract(updated_lifetime) * lifetime_initial; float coeff = dt_from_last_frame / dt; m_previous_frame_matrix.transformVect(previous_frame_position, particle_position_initial); cur_matrix.transformVect(current_frame_position, particle_position_initial); core::vector3df updated_position = previous_frame_position .getInterpolated(current_frame_position, coeff); m_previous_frame_matrix.rotateVect(previous_frame_direction, particle_direction_initial); cur_matrix.rotateVect(current_frame_direction, particle_direction_initial); core::vector3df updated_direction = previous_frame_direction .getInterpolated(current_frame_direction, coeff); // + (current_frame_position - previous_frame_position) / dt; // To be accurate, emitter speed should be added. // But the simple formula // ( (current_frame_position - previous_frame_position) / dt ) // with a constant speed between 2 frames creates visual // artifacts when the framerate is low, and a more accurate // formula would need more complex computations. new_particle_position = updated_position + dt_from_last_frame * updated_direction; new_particle_direction = updated_direction; new_lifetime = glslFract(updated_lifetime); new_size = glslMix(size_initial, size_initial * m_size_increase_factor, glslFract(updated_lifetime)); } else { new_lifetime = glslFract(updated_lifetime); new_size = 0.0f; } } else { new_particle_position = particle_position + particle_direction * dt; new_particle_direction = particle_direction; new_lifetime = updated_lifetime; new_size = (size == 0.0f) ? 0.0f : glslMix(size_initial, size_initial * m_size_increase_factor, updated_lifetime); } m_particles_generating[i].m_position = new_particle_position; m_particles_generating[i].m_lifetime = new_lifetime; m_particles_generating[i].m_direction = new_particle_direction; m_particles_generating[i].m_size = new_size; if (out != NULL) { if (m_flips || new_size != 0.0f) { if (new_size != 0.0f) { Buffer->BoundingBox.addInternalPoint (new_particle_position); } out->emplace_back(new_particle_position, m_color_from, m_color_to, new_lifetime, new_size); } } } } // stimulateNormal
// ---------------------------------------------------------------------------- void STKParticle::stimulateHeightMap(float dt, unsigned int active_count, std::vector<CPUParticle>* out) { assert(m_hm != NULL); const core::matrix4 cur_matrix = AbsoluteTransformation; for (unsigned i = 0; i < m_max_count; i++) { core::vector3df new_particle_position; core::vector3df new_particle_direction; float new_size = 0.0f; float new_lifetime = 0.0f; const core::vector3df particle_position = m_particles_generating[i].m_position; const float lifetime = m_particles_generating[i].m_lifetime; const core::vector3df particle_direction = m_particles_generating[i].m_direction; const core::vector3df particle_position_initial = m_initial_particles[i].m_position; const float lifetime_initial = m_initial_particles[i].m_lifetime; const core::vector3df particle_direction_initial = m_initial_particles[i].m_direction; const float size_initial = m_initial_particles[i].m_size; bool reset = false; const int px = core::clamp((int)(256.0f * (particle_position.X - m_hm->m_x) / m_hm->m_x_len), 0, 255); const int py = core::clamp((int)(256.0f * (particle_position.Z - m_hm->m_z) / m_hm->m_z_len), 0, 255); const float h = particle_position.Y - m_hm->m_array[px][py]; reset = h < 0.0f; core::vector3df initial_position, initial_new_position; cur_matrix.transformVect(initial_position, particle_position_initial); cur_matrix.transformVect(initial_new_position, particle_position_initial + particle_direction_initial); core::vector3df adjusted_initial_direction = initial_new_position - initial_position; float adjusted_lifetime = lifetime + (dt / lifetime_initial); reset = reset || adjusted_lifetime > 1.0f; reset = reset || lifetime < 0.0f; new_particle_position = !reset ? (particle_position + particle_direction * dt) : initial_position; new_lifetime = !reset ? adjusted_lifetime : 0.0f; new_particle_direction = !reset ? particle_direction : adjusted_initial_direction; new_size = !reset ? glslMix(size_initial, size_initial * m_size_increase_factor, adjusted_lifetime) : 0.0f; m_particles_generating[i].m_position = new_particle_position; m_particles_generating[i].m_lifetime = new_lifetime; m_particles_generating[i].m_direction = new_particle_direction; m_particles_generating[i].m_size = new_size; if (out != NULL) { if (m_flips || new_size != 0.0f) { if (new_size != 0.0f) { Buffer->BoundingBox.addInternalPoint (new_particle_position); } out->emplace_back(new_particle_position, m_color_from, m_color_to, new_lifetime, new_size); } } } } // stimulateHeightMap