//! ---|> [State] State::stateResult_t EnvironmentState::doEnableState(FrameContext & context, Node * /*node*/, const RenderParam & rp) { if (rp.getFlag(NO_GEOMETRY)) return State::STATE_SKIPPED; if (!environment.isNull()) { // extract rotation of the camera Geometry::SRT camRotationSrt = context.getRenderingContext().getMatrix_worldToCamera()._toSRT(); camRotationSrt.setTranslation(Geometry::Vec3(0,0,0)); camRotationSrt.setScale(1.0); // render the environment node as seen standing at the origin (0,0,0) but looking in the camera's direction. context.getRenderingContext().pushMatrix_modelToCamera(); context.getRenderingContext().setMatrix_modelToCamera(Geometry::Matrix4x4(camRotationSrt)); context.getRenderingContext().multMatrix_modelToCamera(Geometry::Matrix4x4f(Geometry::SRT(Geometry::Vec3f(0,0,0), context.getWorldFrontVector(), context.getWorldUpVector()))); context.displayNode(environment.get(), rp); context.getRenderingContext().popMatrix_modelToCamera(); } return State::STATE_OK; }
void ParticleBillboardRenderer::operator()(ParticleSystemNode * psys, FrameContext & context, const RenderParam & rp) { if(rp.getFlag(NO_GEOMETRY)) { return; } const auto & worldToCamera = context.getRenderingContext().getMatrix_worldToCamera(); const auto cameraToWorld = worldToCamera.inverse(); const auto halfRight = cameraToWorld.transformDirection(context.getWorldRightVector() * 0.5f); const auto halfUp = cameraToWorld.transformDirection(context.getWorldUpVector() * 0.5f); // 2. just update position for each particle and render // render particles const uint32_t count = psys->getParticleCount(); Rendering::VertexDescription vertexDesc; const Rendering::VertexAttribute & posAttrib = vertexDesc.appendPosition3D(); const Rendering::VertexAttribute & colorAttrib = vertexDesc.appendColorRGBAByte(); const Rendering::VertexAttribute & texCoordAttrib = vertexDesc.appendTexCoord(); // The usage of a cache for the mesh has been tested. Reusing a preallocated mesh is not faster. Util::Reference<Rendering::Mesh> mesh = new Rendering::Mesh(vertexDesc, 4 * count, 6 * count); mesh->setDataStrategy(Rendering::SimpleMeshDataStrategy::getPureLocalStrategy()); Rendering::MeshIndexData & indexData = mesh->openIndexData(); Rendering::MeshVertexData & vertexData = mesh->openVertexData(); Util::Reference<Rendering::PositionAttributeAccessor> positionAccessor = Rendering::PositionAttributeAccessor::create(vertexData, posAttrib.getNameId()); Util::Reference<Rendering::ColorAttributeAccessor> colorAccessor = Rendering::ColorAttributeAccessor::create(vertexData, colorAttrib.getNameId()); Util::Reference<Rendering::TexCoordAttributeAccessor> texCoordAccessor = Rendering::TexCoordAttributeAccessor::create(vertexData, texCoordAttrib.getNameId()); uint32_t * indices = indexData.data(); uint_fast32_t index = 0; for(const auto & p : psys->getParticles()) { const Geometry::Vec3f upOffset = halfUp * p.size.getHeight(); const Geometry::Vec3f rightOffset = halfRight * p.size.getWidth(); colorAccessor->setColor(index + 0, p.color); texCoordAccessor->setCoordinate(index + 0, Geometry::Vec2f(0.0f, 0.0f)); positionAccessor->setPosition(index + 0, p.position + upOffset - rightOffset); colorAccessor->setColor(index + 1, p.color); texCoordAccessor->setCoordinate(index + 1, Geometry::Vec2f(0.0f, 1.0f)); positionAccessor->setPosition(index + 1, p.position - upOffset - rightOffset); colorAccessor->setColor(index + 2, p.color); texCoordAccessor->setCoordinate(index + 2, Geometry::Vec2f(1.0f, 1.0f)); positionAccessor->setPosition(index + 2, p.position - upOffset + rightOffset); colorAccessor->setColor(index + 3, p.color); texCoordAccessor->setCoordinate(index + 3, Geometry::Vec2f(1.0f, 0.0f)); positionAccessor->setPosition(index + 3, p.position + upOffset + rightOffset); *indices++ = index + 0; *indices++ = index + 1; *indices++ = index + 3; *indices++ = index + 1; *indices++ = index + 2; *indices++ = index + 3; index += 4; } indexData.markAsChanged(); indexData.updateIndexRange(); vertexData.markAsChanged(); vertexData.updateBoundingBox(); context.displayMesh(mesh.get()); }