1#include <Engine/Data/DrawPrimitives.hpp>
3#include <Core/Geometry/MeshPrimitives.hpp>
4#include <Core/Geometry/StandardAttribNames.hpp>
5#include <Core/Utils/Color.hpp>
7#include <Engine/Data/Mesh.hpp>
8#include <Engine/Data/ShaderConfigFactory.hpp>
9#include <Engine/Rendering/RenderObject.hpp>
10#include <Engine/Rendering/RenderTechnique.hpp>
12#include <Core/Containers/MakeShared.hpp>
13#include <Engine/Data/PlainMaterial.hpp>
21using namespace Core::Geometry;
25namespace DrawPrimitives {
36 const AttribArrayDisplayablePtr& mesh ) {
38 auto builder = Rendering::EngineRenderTechniques::getDefaultTechnique(
"Plain" );
39 builder.second( rt,
false );
41 roMaterial->setColoredByVertexAttrib( mesh->getAttribArrayGeometry().hasAttrib(
42 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) ) );
47 ro->setMaterial( roMaterial );
53 Geometry::LineMesh geom;
54 geom.
setVertices( { ( point + ( scale * Core::Vector3::UnitX() ) ),
55 ( point - ( scale * Core::Vector3::UnitX() ) ),
56 ( point + ( scale * Core::Vector3::UnitY() ) ),
57 ( point - ( scale * Core::Vector3::UnitY() ) ),
58 ( point + ( scale * Core::Vector3::UnitZ() ) ),
59 ( point - ( scale * Core::Vector3::UnitZ() ) ) } );
60 geom.
setIndices( { { 0, 1 }, { 2, 3 }, { 4, 5 } } );
62 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ),
63 Core::Vector4Array { geom.
vertices().size(), color } );
70 Geometry::LineMesh geom;
74 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ),
75 Core::Vector4Array { geom.
vertices().size(), color } );
82 Core::Vector3 end = start + v;
88 const Scalar arrowFract = 0.1f;
90 Geometry::LineMesh geom;
93 start + ( ( 1.f - arrowFract ) * v ) + ( ( arrowFract * l ) * a ),
94 start + ( ( 1.f - arrowFract ) * v ) - ( ( arrowFract * l ) * a ) } );
95 geom.
setIndices( { { 0, 1 }, { 1, 2 }, { 1, 3 } } );
97 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ),
98 Core::Vector4Array { geom.
vertices().size(), color } );
104 Geometry::LineMesh geom;
105 Core::Vector3 end = ray.pointAt( len );
109 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ),
110 Core::Vector4Array { geom.
vertices().size(), color } );
115 const Core::Vector3& b,
116 const Core::Vector3& c,
120 Geometry::TriangleMesh geom;
124 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ),
125 Core::Vector4Array { geom.
vertices().size(), color } );
129 Geometry::LineMesh geom;
131 geom.
setIndices( { { 0, 1 }, { 1, 2 }, { 2, 0 } } );
133 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ),
134 Core::Vector4Array { geom.
vertices().size(), color } );
141 const Core::Vector3& x,
142 const Core::Vector3& y,
145 Core::Vector3Array vertices( quads * 2 + 2 );
153 for ( uint i = 0; i < quads; ++i ) {
155 vertices[2 * i + 2] = B;
156 vertices[2 * i + 3] = B + x;
157 indices[2 * i + 2] = 2 * i + 2;
158 indices[2 * i + 3] = 2 * i + 3;
161 Core::Vector4Array colors( vertices.size(), color );
163 MeshPtr mesh(
new Mesh(
"Quad Strip Primitive", Mesh::RM_TRIANGLE_STRIP ) );
164 mesh->loadGeometry( vertices, indices );
165 mesh->getCoreGeometry().addAttrib(
166 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ), colors );
171 const Core::Vector3& normal,
175 CORE_ASSERT( segments >= 2,
"Cannot draw a circle with less than 3 points" );
177 Geometry::LineMesh geom;
179 Core::Vector3Array vertices( segments + 1 );
180 Geometry::LineMesh::IndexContainerType indices;
181 indices.resize( segments );
183 Core::Vector3 xPlane, yPlane;
188 Scalar thetaInc( Core::Math::PiMul2 / Scalar( segments ) );
190 vertices[0] = center + radius * (
std::cos( theta ) * xPlane +
std::sin( theta ) * yPlane );
193 for ( uint i = 1; i <= segments; ++i ) {
194 vertices[i] = center + radius * (
std::cos( theta ) * xPlane +
std::sin( theta ) * yPlane );
195 indices[i - 1] = { i - 1, i };
202 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ),
203 Core::Vector4Array { geom.
vertices().size(), color } );
209 const Core::Vector3& normal,
215 Geometry::LineMesh geom;
216 Core::Vector3Array vertices( segments + 1 );
217 Geometry::LineMesh::IndexContainerType indices;
218 indices.resize( segments );
220 Core::Vector3 xPlane, yPlane;
225 Scalar thetaInc( 2 * angle / Scalar( segments ) );
227 vertices[0] = center + radius * (
std::cos( theta ) * xPlane +
std::sin( theta ) * yPlane );
230 for ( uint i = 1; i <= segments; ++i ) {
231 vertices[i] = center + radius * (
std::cos( theta ) * xPlane +
std::sin( theta ) * yPlane );
232 indices[i - 1] = { i - 1, i };
240 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ),
241 Core::Vector4Array { geom.
vertices().size(), color } );
247 auto geom = makeGeodesicSphere( radius, 4, color );
248 auto handle = geom.getAttribHandle<TriangleMesh::Point>(
249 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_POSITION ) );
250 auto& vertices = geom.getAttrib<TriangleMesh::Point>( handle );
251 auto& data = vertices.getDataWithLock();
253 std::for_each( data.begin(), data.end(), [center]( Core::Vector3& v ) { v += center; } );
262 bool generateTexCoord ) {
263 auto geom = makeParametricSphere<32, 32>( radius, color, generateTexCoord );
264 auto handle = geom.getAttribHandle<TriangleMesh::Point>(
265 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_POSITION ) );
266 auto& vertices = geom.getAttrib<TriangleMesh::Point>( handle );
267 auto& data = vertices.getDataWithLock();
269 std::for_each( data.begin(), data.end(), [center]( Core::Vector3& v ) { v += center; } );
276 const Core::Vector3& p2,
279 const Scalar l = ( p2 - p1 ).norm();
281 TriangleMesh geom = makeCapsule( l, radius, 32, color );
286 const Core::Vector3 trans = 0.5f * ( p2 + p1 );
287 Core::Quaternion rot =
288 Core::Quaternion::FromTwoVectors( Core::Vector3 { 0, 0, l / 2 }, 0.5f * ( p1 - p2 ) );
290 Core::Transform t = Core::Transform::Identity();
292 t.pretranslate( trans );
293 Matrix3 normalMatrix = t.linear().inverse().transpose();
296 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::VERTEX_POSITION ) );
297 auto& vertAttrib = geom.
getAttrib<TriangleMesh::Point>( vertHandle );
298 auto& vertData = vertAttrib.getDataWithLock();
299 std::for_each( vertData.begin(), vertData.end(), [t]( Core::Vector3& v ) { v = t * v; } );
303 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::VERTEX_NORMAL ) );
304 auto& normalAttrib = geom.
getAttrib<TriangleMesh::Point>( normalHandle );
305 auto& normalData = normalAttrib.getDataWithLock();
306 std::for_each( normalData.begin(), normalData.end(), [normalMatrix]( Core::Vector3& n ) {
307 n = normalMatrix * n;
309 normalAttrib.unlock();
315 const Core::Vector3& normal,
319 CORE_ASSERT( segments > 2,
"Cannot draw a circle with less than 3 points" );
321 uint seg = segments + 1;
322 Core::Vector3Array vertices( seg );
325 Core::Vector3 xPlane, yPlane;
330 Scalar thetaInc( Core::Math::PiMul2 / Scalar( segments ) );
333 vertices[0] = center;
335 for ( uint i = 1; i < seg; ++i ) {
336 vertices[i] = center + radius * (
std::cos( theta ) * xPlane +
std::sin( theta ) * yPlane );
343 Core::Vector4Array colors( vertices.size(), color );
345 MeshPtr mesh(
new Mesh(
"Disk Primitive", Mesh::RM_TRIANGLE_FAN ) );
346 mesh->loadGeometry( vertices, indices );
347 mesh->getCoreGeometry().addAttrib(
348 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ), colors );
354 const Core::Vector3& normal,
360 Core::Vector3 n = normal.normalized();
364 Core::Vector3 end = point + n;
368 const Scalar arrowFract = 0.1f;
370 Geometry::LineMesh geom;
372 Core::Vector3Array vertices = {
375 point + ( ( 1.f - arrowFract ) * n ) + ( ( arrowFract * scale ) * a ),
376 point + ( ( 1.f - arrowFract ) * n ) - ( ( arrowFract * scale ) * a ),
378 point + ( scale * a ),
379 point + ( scale * b ),
380 point - ( scale * a ),
381 point - ( scale * b ),
395 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ),
396 Core::Vector4Array { geom.
vertices().size(), color } );
404 Core::Vector3 pos = frameFromEntity.translation();
405 Core::Vector3 x = frameFromEntity.linear() * Core::Vector3::UnitX();
406 Core::Vector3 y = frameFromEntity.linear() * Core::Vector3::UnitY();
407 Core::Vector3 z = frameFromEntity.linear() * Core::Vector3::UnitZ();
409 Core::Vector3Array vertices = {
410 pos, pos + scale * x, pos, pos + scale * y, pos, pos + scale * z };
412 Core::Vector4Array colors = {
413 Core::Utils::Color::Red(),
414 Core::Utils::Color::Red(),
415 Core::Utils::Color::Green(),
416 Core::Utils::Color::Green(),
417 Core::Utils::Color::Blue(),
418 Core::Utils::Color::Blue(),
422 MeshPtr mesh(
new Mesh(
"Frame Primitive", Mesh::RM_LINES ) );
424 mesh->loadGeometry( vertices, indices );
425 mesh->getCoreGeometry().addAttrib(
426 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ), colors );
432 const Core::Vector3& x,
433 const Core::Vector3& y,
438 CORE_ASSERT( res > 1,
"Grid has to be at least a 2x2 grid." );
439 Core::Vector3Array vertices;
442 const Scalar halfWidth { ( cellSize * res ) / 2.f };
443 const Core::Vector3 deltaPosX { cellSize * x };
444 const Core::Vector3 startPosX { center - halfWidth * x };
445 const Core::Vector3 endPosX { center + halfWidth * x };
446 const Core::Vector3 deltaPosY { cellSize * y };
447 const Core::Vector3 startPosY { center - halfWidth * y };
448 const Core::Vector3 endPosY { center + halfWidth * y };
449 Core::Vector3 currentPosX { startPosX };
450 for ( uint i = 0; i < res + 1; ++i ) {
451 vertices.push_back( startPosY + currentPosX );
452 vertices.push_back( endPosY + currentPosX );
453 indices.
push_back( uint( vertices.size() ) - 2 );
454 indices.
push_back( uint( vertices.size() ) - 1 );
455 currentPosX += deltaPosX;
458 Core::Vector3 currentPosY = startPosY;
459 for ( uint i = 0; i < res + 1; ++i ) {
460 vertices.push_back( startPosX + currentPosY );
461 vertices.push_back( endPosX + currentPosY );
462 indices.
push_back( uint( vertices.size() ) - 2 );
463 indices.
push_back( uint( vertices.size() ) - 1 );
464 currentPosY += deltaPosY;
467 Core::Vector4Array colors( vertices.size(), color );
469 MeshPtr mesh(
new Mesh(
"GridPrimitive", Mesh::RM_LINES ) );
470 mesh->loadGeometry( vertices, indices );
471 mesh->getCoreGeometry().addAttrib(
472 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ), colors );
478 Core::Vector3Array vertices( 8 );
480 for ( uint i = 0; i < 8; ++i ) {
481 vertices[i] = aabb.corner(
static_cast<Core::Aabb::CornerType
>( i ) );
485 0, 1, 1, 3, 3, 2, 2, 0,
486 0, 4, 1, 5, 2, 6, 3, 7,
487 4, 5, 5, 7, 7, 6, 6, 4,
490 Core::Vector4Array colors( vertices.size(), color );
492 MeshPtr mesh(
new Mesh(
"AABB Primitive", Mesh::RM_LINES ) );
493 mesh->loadGeometry( vertices, indices );
494 mesh->getCoreGeometry().addAttrib(
495 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ), colors );
501 Core::Vector3Array vertices( 8 );
503 for ( uint i = 0; i < 8; ++i ) {
508 0, 1, 1, 3, 3, 2, 2, 0,
509 4, 5, 5, 7, 7, 6, 6, 4,
510 0, 4, 1, 5, 2, 6, 3, 7,
513 Core::Vector4Array colors( vertices.size(), color );
515 MeshPtr mesh(
new Mesh(
"OBB Primitive", Mesh::RM_LINES ) );
516 mesh->loadGeometry( vertices, indices );
517 mesh->getCoreGeometry().addAttrib(
518 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ), colors );
527 Core::Vector3Array vertices;
528 vertices.reserve( pointCount );
531 indices.
reserve( pointCount * 2 - 2 );
533 Scalar dt = Scalar( 1 ) / Scalar( pointCount - 1 );
534 for ( uint i = 0; i < pointCount; ++i ) {
536 vertices.push_back( spline.
f( t ) );
539 for ( uint i = 0; i < pointCount - 1; ++i ) {
544 Core::Vector4Array colors( vertices.size(), color );
546 MeshPtr mesh(
new Mesh(
"Spline Primitive", Mesh::RM_LINES ) );
547 mesh->loadGeometry( vertices, indices );
548 mesh->getCoreGeometry().addAttrib(
549 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ), colors );
558 auto r = ( vertices.size() % 3 );
560 for ( ; r < 3; ++r ) {
561 indices.
push_back( vertices.size() - 1 );
564 MeshPtr mesh(
new Mesh(
"Line Strip Primitive", Mesh::RM_LINE_STRIP ) );
565 mesh->loadGeometry( vertices, indices );
566 if ( colors.size() > 0 ) {
567 mesh->getCoreGeometry().addAttrib(
568 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ),
Utils::AttribHandle< T > getAttribHandle(const std::string &name) const
void setVertices(PointAttribHandle::Container &&vertices)
Set vertices.
const PointAttribHandle::Container & vertices() const
Access the vertices positions.
Utils::AttribHandle< T > addAttrib(const std::string &name)
Utils::Attrib< T > & getAttrib(const Utils::AttribHandle< T > &h)
void setIndices(IndexContainerType &&indices)
An oriented bounding box.
Eigen::Matrix< Scalar, 3, 1 > worldCorner(int i) const
Returns the position of the ith corner of the OBB ( world space )
Handling spline curves of arbitrary dimensions.
Mesh, own a Core::Geometry::TriangleMesh.
static RenderObject * createRenderObject(const std::string &name, Scene::Component *comp, const RenderObjectType &type, std::shared_ptr< Data::Displayable > mesh, const RenderTechnique &techniqueConfig=RenderTechnique::createDefaultRenderTechnique())
void setParametersProvider(std::shared_ptr< Data::ShaderParameterProvider > provider, Core::Utils::Index pass=Core::Utils::Index(-1))
A component is an element that can be updated by a system. It is also linked to some other components...
void getOrthogonalVectors(const Vector3 &fx, Eigen::Ref< Vector3 > fy, Eigen::Ref< Vector3 > fz)
std::shared_ptr< T > make_shared(Args &&... args)
MeshPtr Capsule(const Core::Vector3 &p1, const Core::Vector3 &p2, Scalar radius, const Core::Utils::Color &color)
Displays a capsule computed with given endpoints and radius.
LineMeshPtr Line(const Core::Vector3 &a, const Core::Vector3 &b, const Core::Utils::Color &color)
Displays given line.
LineMeshPtr CircleArc(const Core::Vector3 ¢er, const Core::Vector3 &normal, Scalar radius, Scalar angle, uint segments, const Core::Utils::Color &color)
MeshPtr ParametricSphere(const Core::Vector3 ¢er, Scalar radius, const Core::Utils::Color &color, bool generateTexCoord)
MeshPtr Disk(const Core::Vector3 ¢er, const Core::Vector3 &normal, Scalar radius, uint segments, const Core::Utils::Color &color)
AttribArrayDisplayablePtr Triangle(const Core::Vector3 &a, const Core::Vector3 &b, const Core::Vector3 &c, const Core::Utils::Color &color, bool fill)
MeshPtr AABB(const Core::Aabb &aabb, const Core::Utils::Color &color)
Display a wireframe AABB.
MeshPtr Frame(const Core::Transform &frameFromEntity, Scalar scale)
LineMeshPtr Vector(const Core::Vector3 &start, const Core::Vector3 &v, const Core::Utils::Color &color)
Displays given vector shown as an arrow originating from 'start'.
MeshPtr Grid(const Core::Vector3 ¢er, const Core::Vector3 &x, const Core::Vector3 &y, const Core::Utils::Color &color, Scalar cellSize, uint res)
MeshPtr LineStrip(const Core::Vector3Array &vertices, const Core::Vector4Array &colors)
Display a line strip.
LineMeshPtr Normal(const Core::Vector3 &point, const Core::Vector3 &normal, const Core::Utils::Color &color, Scalar scale)
MeshPtr Sphere(const Core::Vector3 ¢er, Scalar radius, const Core::Utils::Color &color)
Displays geodesic sphere computed with given center and radius.
LineMeshPtr Circle(const Core::Vector3 ¢er, const Core::Vector3 &normal, Scalar radius, uint segments, const Core::Utils::Color &color)
LineMeshPtr Point(const Core::Vector3 &point, const Core::Utils::Color &color, Scalar scale)
Displays given point shown as the crossing of 3 lines of length 'scale'.
Rendering::RenderObject * Primitive(Scene::Component *component, const MeshPtr &mesh)
MeshPtr OBB(const Obb &obb, const Core::Utils::Color &color)
Display a wireframe OBB.
MeshPtr QuadStrip(const Core::Vector3 &a, const Core::Vector3 &x, const Core::Vector3 &y, uint quads, const Core::Utils::Color &color)
Displays a strip of n quads, starting at A and with directions X and Y.
@ Debug
"Debug" render objects are drawn like any other object (not lit though)
hepler function to manage enum as underlying types in VariableSet
T dynamic_pointer_cast(T... args)