The Vish Visualization Shell 0.3
Vish
AnemoneBoundingVolume.cpp

Draw the bounding box of some VObject, if that one provides the respective information as an interface.

Draw the bounding box of some VObject, if that one provides the respective information as an interface.This example demonstrates uses Render Anemone objects to perform the actual rendering. A Render Anemone is an Vish object to encapsulate rendering operations, see Wizt::Anemone for detailed documentation and the BoundingVolume.cpp example, which demonstrates drawing a Bounding Volume using raw OpenGL, without the Anemone object.

See also
SeagrassBoundingVolume.cpp for an advanced version involving MemCore Cache Management of Limited Resources management through the Seagrass class.
#include <ocean/plankton/VPipeline.hpp>
#include <ocean/GLvish/VGLRenderObject.hpp>
#include <eagle/PhysicalSpace.hpp>
#include <eagle/GL/EagleGL.hpp>
#include <ocean/GLvish/BoundingBox.hpp>
#include <ocean/GLvish/GLFonts.hpp>
#include <ocean/Anemonia/FloatOrigin.hpp>
using namespace Wizt;
using namespace Eagle;
#define MY_URL "http://vish.fiberbundle.net/doc/AnemoneBoundingVolume_8cpp-example.html"
namespace
{
class BoundingBoxRenderer : public VGLRenderObject , public FloatOrigin
{
public:
TypedSlot<double> Thickness,
FontSize,
inDescriptionSize;
// TypedSlot<GLFontManager> MyFonts;
in<Color> inColor;
in<string> inDescription;
BoundingBoxRenderer(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
: VGLRenderObject(name, RenderCategory::DEFAULT_OBJECT, VP)
, myData( this, "source", VBoundingBox() )
, Thickness(this, "thickness", 1.5, nullptr, 2)
, FontSize(this, "fontsize", 1.0, nullptr, 3)
, inDescriptionSize(this, "textsize", 0.01, nullptr, 3)
, inColor(this, "color", {0.5, 0.7, 0.6, 1.0}, 1)
, inDescription(this, "description", {}, new VCreationPreferences( VValueTrait<string>::OneLine() ), 3)
{
FontSize.setProperty("max",10.0);
inDescriptionSize.setProperty("max",10.0);
Thickness.setProperty("max",10.0);
}
bool update(VRequest&Context, double precision) override;
bool renderGL(VGLRenderContext&Context) const override;
static string createChildname(const string&parent_name)
{
return "BoundingVolumeOf" + parent_name;
}
};
bool BoundingBoxRenderer::update(VRequest&Context, double precision)
{
myData << Context >> BBox;
if (!BBox)
{
resetBBox( Context );
return setStatusError(Context, "No Bounding box");
}
setBoundingBall(Context, BBox);
return setStatusInfo(Context, "Bounding box" + String( BBox ) );
}
class FontTentacle : public Anemone::SpecializedTentacle<Anemone::DisplayLists>
{
public:
string text;
double FontScale;
FontTentacle(const string&txt,
const Eagle::PhysicalSpace::point&thePosition,
double theFontScale,
: text(txt)
, Position( thePosition )
, FontScale ( theFontScale )
, myFont( theFont )
{
myFont->setSize(2);
}
bool activate(const Anemone&) override
{
float llx, lly, llz, urx, ury, urz;
glPushMatrix();
glTranslate( Position );
myFont->getBBox( text.c_str(), llx, lly, llz, urx, ury, urz);
glTranslatef( -FontScale*(urx-llx)/2, -(ury-lly), 0);
glScalef(FontScale, FontScale, FontScale );
myFont->render(text.c_str() );
glPopMatrix();
return true;
}
bool deactivate(const Anemone&) override
{
return true;
}
};
bool BoundingBoxRenderer::renderGL(VGLRenderContext&Context) const
{
myData << Context >> IB;
if (!IB)
return true;
using namespace Eagle::PhysicalSpace;
point P0 = IB->center(),
P1 = IB->center();
if (BB)
{
P0 = BB->mincoord();
P1 = BB->maxcoord();
}
else
{
for(int i=0; i<P0.SIZE; i++)
{
P0[i] -= IB->radius();
P1[i] += IB->radius();
}
}
Eagle::tvector3 TranslationVector;
auto T = getCoordinateTranslation(Context, TranslationVector);
P0 -= TranslationVector;
P1 -= TranslationVector;
auto diag = P1 - P0;
double d = norm(diag);
double DescriptionSize = 0.0;
inDescriptionSize << Context >> DescriptionSize;
#if 1
double FontScale = 1.0;
FontSize << Context >> FontScale;
if (FontScale>0.0)
{
if (DescriptionSize<=0.0) DescriptionSize = FontScale;
RefPtr<Anemone> FontAnemone = new Anemone();
if (auto MyFont = Context.getFont() )
{
if (MyFont)
{
MyFont->setSize(2);
{
float front_emission[4] = { 0.3, 0.2, 0.1, 0.0 };
float front_ambient[4] = { 0.2, 0.2, 0.2, 0.0 };
float front_diffuse[4] = { 0.95, 0.95, 0.8, 0.0 };
float front_specular[4] = { 0.6, 0.6, 0.6, 0.0 };
glMaterialfv(GL_FRONT, GL_EMISSION, front_emission);
glMaterialfv(GL_FRONT, GL_AMBIENT, front_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, front_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, front_specular);
glMaterialf(GL_FRONT, GL_SHININESS, 16.0);
glColor4fv(front_diffuse);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glDisable( GL_TEXTURE_2D);
glEnable( GL_DEPTH_TEST);
glDisable( GL_BLEND);
}
glEnable( GL_NORMALIZE );
{
char coords0[2048];
sprintf(coords0,"(%lg,%lg,%lg)", P0[0], P0[1], P0[2] );
Ref<FontTentacle> TextAtP0( coords0, P0, FontScale, MyFont);
FontAnemone->insert( TextAtP0 );
}
{
char coords1[2048];
sprintf(coords1,"(%lg,%lg,%lg)", P1[0], P1[1], P1[2] );
Ref<FontTentacle> TextAtP1( coords1, P1, FontScale, MyFont);
FontAnemone->insert( TextAtP1 );
}
FontAnemone->wave();
}
else
puts("font not found");
}
else
puts("no font manager");
}
#endif
string Description;
inDescription << Context >> Description;
!Description.empty() &&
(MyFont = Context.getFont() ) )
{
MyFont->setSize(2);
{ float front_emission[4] = { 0.3, 0.2, 0.1, 0.0 };
float front_ambient[4] = { 0.2, 0.2, 0.2, 0.0 };
float front_diffuse[4] = { 0.95, 0.95, 0.8, 0.0 };
float front_specular[4] = { 0.6, 0.6, 0.6, 0.0 };
glMaterialfv(GL_FRONT, GL_EMISSION, front_emission);
glMaterialfv(GL_FRONT, GL_AMBIENT, front_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, front_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, front_specular);
glMaterialf(GL_FRONT, GL_SHININESS, 16.0);
glColor4fv(front_diffuse);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glDisable( GL_TEXTURE_2D);
glEnable( GL_DEPTH_TEST);
glDisable( GL_BLEND);
}
glEnable( GL_NORMALIZE );
Ref<Anemone> FontAnemone;
Ref<FontTentacle> myText( Description, P0 + diag * 0.5,
DescriptionSize*d, MyFont);
FontAnemone->insert( myText );
FontAnemone->wave();
}
// printf("BBOX: %lg,%lg,%lg <-> %lg,%lg,%lg\n",
// P0[0], P0[1], P0[2],
// P1[0], P1[1], P1[2] );
double width = 20;
Thickness << Context >> width;
if (width<0.01) width=0.01;
point P000 ( P0.x(), P0.y(), P0.z() ),
P001 ( P0.x(), P0.y(), P1.z() ),
P010 ( P0.x(), P1.y(), P0.z() ),
P011 ( P0.x(), P1.y(), P1.z() ),
P100 ( P1.x(), P0.y(), P0.z() ),
P101 ( P1.x(), P0.y(), P1.z() ),
P110 ( P1.x(), P1.y(), P0.z() ),
P111 ( P1.x(), P1.y(), P1.z() );
/*
This code is inspired by
http://www.bluevoid.com/opengl/sig00/advanced00/notes/node290.html
*/
glLineWidth(width);
glEnable(GL_LINE_SMOOTH);
glDisable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
Color BBColor = {0.5, 0.7, 0.6, 1.0};
inColor << Context >> BBColor;
glColor3d( BBColor[0], BBColor[1], BBColor[2] );
RefPtr<Anemone> BBoxAnemone = new Anemone();
{
MemVector<point> BoxVertices(24);
BoxVertices[ 0] = P000; BoxVertices[ 1] = P010;
BoxVertices[ 2] = P010; BoxVertices[ 3] = P011;
BoxVertices[ 4] = P011; BoxVertices[ 5] = P001;
BoxVertices[ 6] = P001; BoxVertices[ 7] = P000;
BoxVertices[ 8] = P100; BoxVertices[ 9] = P110;
BoxVertices[10] = P110; BoxVertices[11] = P111;
BoxVertices[12] = P111; BoxVertices[13] = P101;
BoxVertices[14] = P101; BoxVertices[15] = P100;
BoxVertices[16] = P000; BoxVertices[17] = P100;
BoxVertices[18] = P010; BoxVertices[19] = P110;
BoxVertices[20] = P011; BoxVertices[21] = P111;
BoxVertices[22] = P001; BoxVertices[23] = P101;
BBoxAnemone->insert( Context.createCoordinates( BoxVertices ) );
}
BBoxAnemone->insert( Context.drawPrimitives( RenderBasin::LINES ) );
// actual rendering
BBoxAnemone->wave();
glEnable(GL_POINT_SMOOTH);
glPointSize(width);
RefPtr<Anemone> BBoxCornerAnemone = new Anemone();
{
MemVector<point> BoxVertices(8, true); // reserve space for 8 points
BoxVertices.push_back( P000 );
BoxVertices.push_back( P010 );
BoxVertices.push_back( P011 );
BoxVertices.push_back( P001 );
BoxVertices.push_back( P100 );
BoxVertices.push_back( P110 );
BoxVertices.push_back( P111 );
BoxVertices.push_back( P101 );
BBoxCornerAnemone->insert( Context.createCoordinates( BoxVertices ) );
}
BBoxCornerAnemone->insert( Context.drawPrimitives( RenderBasin::POINTS ) );
// actual rendering
BBoxCornerAnemone->wave();
return true;
}
using namespace Panthalassa;
static VSink< AcceptList<VBoundingBox>, BoundingBoxRenderer>
ThisIsMyOfficialCreator(
Category("Display") /
VIdentifier("BoundingVolume") /
Url( MY_URL )
,
ObjectQuality::MATURE);
}
A set of variable names, with indices associated to each type.
Definition Context.hpp:18
A point in physical 3D space.
Definition elementary/eagle/PhysicalSpace.hpp:106
3-dimensional vector.
Definition elementary/eagle/PhysicalSpace.hpp:170
Definition ColorSpace.hpp:110
A reference counting pointer class which keeps objects alive as long as strong pointers to these obje...
Definition RefPtr.hpp:405
Base class for Tentacles that are specialized for a specific purpose.
Definition Anemone.hpp:420
Abstract object for elementary render objects.
Definition Anemone.hpp:39
An input slot for VObjects, bound to a specific type.
Definition TypedSlot.hpp:57
bool setProperty(const string &theName, const Type &theValue) const
Set a property of the parameter that is associated with this slot.
Definition TypedSlot.hpp:718
A certain object (especcially input types) might have multiple implementations by the GUI or alternat...
Definition VCreationPreferences.hpp:24
A set of property elements for VCreator objects.
Definition VCreatorProperties.hpp:258
Base class for objects that implement a drawing routine using OpenGL.
Definition VGLRenderObject.hpp:20
Request structure.
Definition VRequest.hpp:24
Type trait for VValues that specify how to convert a certain value from and to text.
Definition VValue.hpp:108
MemCore::RefPtr< Eagle::BoundingBox > VBoundingBox
The Vish type to communicate bounding boxes.
Definition ocean/shrimp/BoundingBox.hpp:27
Geometric algebra of the physical 3D-space, by which we mean the Clifford algebara over Euclidean,...
Definition AnalyticFunction.hpp:31
Gather general basic mathematic functions which are not available in cmath here.
Definition Context.cpp:7
The Panthalassa namespace allows to conveniently specify the properties of a VCreator object during c...
Definition VCreatorProperties.hpp:385
The Vish namespace.
Definition Anemone.cpp:17
A convenience class that looks like a std::vector<>, but is actually referring to a reference-counted...
Definition elementary/memcore/Chunk.hpp:515
Pointer to a refcountable object which automatically initializes the pointer with constructing an obj...
Definition RefPtr.hpp:1138
By default, the Camera in Vish is NOT translated to the location of the specified observer,...
Definition FloatOrigin.hpp:86
A special vish context that is passed to VGLRenderObjects when rendering.
Definition VGLRenderContext.hpp:35
Implements a data sink.
Definition VPipeline.hpp:73