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 Cache 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)
, 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 )
,
}
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
void glTranslate(const Eagle::PhysicalSpace::point &origin)
Perform an OpenGL glTranslate() call on a point given in physical space.
Definition EagleGL.hpp:64
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
Base class for objects that implement a drawing routine using OpenGL.
Definition VGLRenderObject.hpp:20
Request structure.
Definition VRequest.hpp:24
string String(const T &Val)
Return the textual representation of some value.
Definition VValue.hpp:179
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
double P0(double x)
Definition Ylm.cpp:7
double norm(const PhysicalSpace::tvector &)
Compute the Euclidan norm of a vector.
Definition elementary/eagle/PhysicalSpace.hpp:474
double P1(double x)
Definition Ylm.cpp:12
StrongPtr< Object, ObjectBase > RefPtr
Convenience template typedef to use RefPtr instead of StrongPtr.
Definition RefPtr.hpp:776
The Panthalassa namespace allows to conveniently specify the properties of a VCreator object during c...
Definition VCreatorProperties.hpp:385
Wizt::VCreatorProperty< Wizt::VCreatorProperties::URL > Url
URL for online help.
Definition VCreatorProperties.hpp:402
Wizt::VCreatorProperty< Wizt::VCreatorProperties::DESCRIPTION > Description
Possibly complex description via UTF8 codes.
Definition VCreatorProperties.hpp:396
Wizt::VCreatorProperty< Wizt::VCreatorProperties::CATEGORY > Category
Classification, such as Display or Computer or Demo.
Definition VCreatorProperties.hpp:390
The Vish namespace.
Definition Anemone.cpp:17
virtual string createChildname(const string &parent_name) const
Virtual callback function that is called when a new child object is to be created from a parent objec...
@ DEFAULT_OBJECT
Usual objects shall be assigned a priority number around zero.
Definition RenderCategory.hpp:81
A convenience class that looks like a std::vector<>, but is actually referring to a reference-counted...
Definition elementary/memcore/Chunk.hpp:515
By default, the Camera in Vish is NOT translated to the location of the specified observer,...
Definition FloatOrigin.hpp:86
@ MATURE
This object is mature enough to be used, use it if you like.
Definition ObjectQuality.hpp:32
@ POINTS
draw as points
Definition RenderNamespace.hpp:80
@ LINES
draw as a set of line elements, bundling each two vertices independently
Definition RenderNamespace.hpp:87
A special vish context that is passed to VGLRenderObjects when rendering.
Definition VGLRenderContext.hpp:35
Implements a data sink.
Definition VPipeline.hpp:73