Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
CSE 472
Scene Graph
and Spatial Indexing
CSE 472 S2019
Scene Graph
Modeling/Rendering
C++ Classes
CSE 472 S2019
Modeling/Rendering
CSE 472 S2019
Graphical
Model
Rendering
Output Device
Rendering
Parameters
Does OpenGL Support Modeling
NO!
OpenGL only renders
You can skip the model, but…
Difficult to deal with variable objects
Loaded objects?
Often assumed some modeling API
Open Inventor from SGI is an example
Video games, High end modeling, etc.
CSE 472 S2019
Why Modeling
All of the model is in a uniform format
Alternative rendering can be supported
Advanced techniques can be supported
Shadows, Transparency, Fog, etc.
Auxiliary functions can be supported
Level of detail, navigation, collision detection
Store static content
Textures, bump maps
CSE 472 S2019
Why Modeling
All of the model is in a uniform format
Alternative rendering can be supported
Advanced techniques can be supported
Shadows, Transparency, Fog, etc.
Auxiliary functions can be supported
Level of detail
Navigation
Collision detection
Store static content
Textures, bump maps
CSE 472 S2019
Progressive 3D Data Transmission
CSE 472 S2019
Standards
There are surprisingly few standards for modeling
Models tend to be VERY application
specific
• Games have different requirements from CAD, which has different requirements from animation, etc.
Models tend to be very
“programmer visible”
CSE 472 S2019
What a Model Is…
Fundamentally: A Data Structure
Elements of a “scene graph”
Scene graph: Hierarchical
representation of a graphical scene
CSE 472 S2019[HTG03]
A Common Format: VRML
CSE 472 S2019
Vertices
(geometry)
v1 (x1;y1;z1)
v2 (x2;y2;z2)
v3 (x3;y3;z3)
v4 (x4;y4;z4)
v5 (x5;y5;z5)
v6 (x6;y6;z6)
v7 (x7;y7;z7)
Faces
(connectivity)
f1 (v1;v3;v2)
f2 (v4;v3;v1)
f3 (v4;v1;v5)
f4 (v1;v6;v5)
f5 (v6;v1;v7)
f6 (v2;v7;v1)
f7 (…)
V R M L
Valence n: n times in face list
→→→→ average 6
A Simple Polygon Model…
CSE 472 S2019
class CPolygon
{
public:
CPolygon();
virtual ~CPolygon();
void Render();
void AddVertex(double x, double y, double z);
private:
// A polygon is a list of vertices
std::list<CGrPoint> m_vertices;
};
Note: Too Simple, don’t use
That CGrPoint class…
class CGrPoint { public: CGrPoint() {} CGrPoint(double x, double y, double z=0, double w=1.) {m[0] = x; m[1] = y; m[2] = z; m[3] = w;} CGrPoint(const CGrPoint &p) {m[0]=p.m[0]; m[1]=p.m[1]; m[2]=p.m[2]; m[3]=p.m[3];}
CGrPoint &operator=(const CGrPoint &p) {m[0]=p.m[0]; m[1]=p.m[1]; m[2]=p.m[2]; m[3]=p.m[3]; return *this;}
double X() const {return m[0];} double X(double p) {return m[0] = p;} double Y() const {return m[1];} double Y(double p) {return m[1] = p;} double Z() const {return m[2];} double Z(double p) {return m[2] = p;} double W() const {return m[3];} double W(double p) {return m[3] = p;}
void Set(double x, double y, double z, double w=1.) {m[0] = x; m[1] = y; m[2] = z; m[3] = w;}
void glVertex() const {glVertex4dv(m);}
private: double m[4]; };
CSE 472 S2019
We really need…
Scene Graph
Primitives
• Things that actually render
Composite objects
Modeling of
• Transformations
• Color
• Other...
CSE 472 S2019
Example
PolygonPolygon PolygonPolygon…
CompositeComposite
TranslateTranslate
ColorColor
PolygonPolygon PolygonPolygon…
CompositeComposite
ColorColor
TranslateTranslateTranslateTranslate
CompositeComposite
Barbell
Ends
Barbell
Bar
BarbellHow do you
Render?
CSE 472 S2019
Tree Node Superclass
CSE 472 S2019
class CGrObject
{
public:
CGrObject() {}
virtual ~CGrObject();
virtual void Render() = 0;
};
This is an abstract base class
A Primitive
CSE 472 S2019
class CGrPolygon : public CGrObject
{
public:
CGrPolygon();
virtual ~CGrPolygon();
virtual void Render();
void AddVertex3d(double x, double y, double z);
void AddVertex3dv(double *p);
void AddVertices(double *a, double *b,
double *c, double *d=NULL);
private:
// A polygon is a list of vertices
std::vector<CGrPoint> m_vertices;
};
Using this class
CSE 472 S2019
// Non-equilateral tetrahedron points
double a[3] = {1.5, 0, 0}; double b[3] = {0, 0, 1.5};
double c[3] = {-1.5, 0, 0}; double d[3] = {0, 3, 0};
CGrPolygon *poly1, *poly2, *poly3;
poly1 = new CGrPolygon();
poly1->AddVertex3dv(a);
poly1->AddVertex3dv(b);
poly1->AddVertex3dv(c);
poly2 = new CGrPolygon();
poly2->AddVertices(d, b, a);
poly3 = new CGrPolygon(d, c, b);
b
ac
d
memory management??
We are allocating, so how do we ensure we deallocate?
We can’t deallocate when link removed
We have a graph, not a tree
Ideas?
CSE 472 S2019
Reference Counters
CSE 472 S2019
class CGrObject
{
public:
CGrObject() {m_refs = 0;}
virtual ~CGrObject();
virtual void Render() = 0;
void IncRef() {m_refs++;}
void DecRef() {m_refs--; if(m_refs == 0) {delete this;}}
private:
int m_refs;
};
A Template Pointer Class
CSE 472 S2019
template <class T> class CGrPtr
{
public:
CGrPtr() {m_ptr = NULL;}
CGrPtr(T *p_ptr) {m_ptr = p_ptr; if(m_ptr) m_ptr->IncRef();}
CGrPtr(CGrPtr &p_ptr) {m_ptr=p_ptr.m_ptr; if(m_ptr) m_ptr->IncRef();}
~CGrPtr() {Clear();}
void Clear() {if(m_ptr) {m_ptr->DecRef(); m_ptr = NULL;}}
T *operator=(T *t) {if (t) t->IncRef(); Clear(); m_ptr = t; return m_ptr;}
T *operator=(CGrPtr &t) {if (t.m_ptr) t.m_ptr->IncRef();
Clear(); m_ptr = t.m_ptr; return m_ptr;}
operator T *() const {return m_ptr;}
T *operator->() const {return m_ptr;}
private:
T *m_ptr;
};
Example: CGrPtr<CGrPolygon> poly = new CGrPolygon();
Previous Example Revised
CSE 472 S2019
// Non-equilateral tetrahedron points
double a[3] = {1.5, 0, 0}; double b[3] = {0, 0, 1.5};
double c[3] = {-1.5, 0, 0}; double d[3] = {0, 3, 0};
CGrPtr<CGrPolygon> poly1, poly2, poly3;
poly1 = new CGrPolygon();
poly1->AddVertex3dv(a);
poly1->AddVertex3dv(b);
poly1->AddVertex3dv(c);
poly2 = new CGrPolygon();
poly2->AddVertices(d, b, a);
poly3 = new CGrPolygon(d, c, b);
To render this:
poly1->Render();
poly2->Render();
poly3->Render();
To render this:
poly1->Render();
poly2->Render();
poly3->Render();
Methods in CGrPolygon
CSE 472 S2019
void CGrPolygon::AddVertex3d(double x, double y, double z)
{
m_vertices.push_back(CGrPoint(x, y, z));
}
void CGrPolygon::AddVertices(double *a, double *b, double *c, double *d)
{
m_vertices.push_back(CGrPoint(a[0], a[1], a[2]));
m_vertices.push_back(CGrPoint(b[0], b[1], b[2]));
m_vertices.push_back(CGrPoint(c[0], c[1], c[2]));
if(d)
m_vertices.push_back(CGrPoint(d[0], d[1], d[2]));
}
void CGrPolygon::Render()
{
glBegin(GL_POLYGON);
for(vector<CGrPoint>::iterator i=m_vertices.begin(); i!=m_vertices.end(); i++)
i->glVertex();
glEnd();
}
std::list<CGrPoint> m_vertices;
A Composite Class
CSE 472 S2019
class CGrComposite : public CGrObject
{
public:
CGrComposite() {}
~CGrComposite();
virtual void glRender();
void Child(CGrObject *p_child) {m_children.push_back(p_child);}
private:
std::list<CGrPtr<CGrObject> > m_children;
};
void CGrComposite::Render()
{
for(list<CGrPtr<CGrObject> >::iterator i=m_children.begin();
i != m_children.end(); i++)
(*i)->Render();
}
Creating the Tet
CSE 472 S2019
// The composite node that will contain everything
CGrPtr<CGrComposite> composite = new CGrComposite();
CGrPtr<CGrObject> obj = composite;
// Non-equilateral tetrahedron points
…
CGrPtr<CGrPolygon> poly;
// Polygon 1
poly = new CGrPolygon();
poly->AddVertex3dv(a);
poly->AddVertex3dv(b);
poly->AddVertex3dv(c);
// Add to composite
composite->Child(poly);
// Polygon 2
poly = new CGrPolygon();
poly->AddVertices(d, b, a);
composite->Child(poly);
// Polygon 3
poly = new CGrPolygon(d, c, b);
composite->Child(poly);
// Polygon 4
composite->Child(new CGrPolygon(d, a, c));
What we get…
CSE 472 S2019
CGrComposite
CGrPolygon CGrPolygon CGrPolygon CGrPolygon
What happens when I call render
on the CGrComposite object?
Constructive Solid Geometry
Composite (scene graph)
->Boolean Operations– Union, Intersection, Subtraction
• Usually in tree structure (with instancing)
CSE 472 S2019
[http://www.cs.mtu.edu/~shene]
CGrColor
CSE 472 S2019
class CGrColor : public CGrObject
{
public:
CGrColor() {c[0]=c[1]=c[2] = 0.; c[3] = 1.;}
CGrColor(double r, double g, double b) {c[0]=r; c[1]=g; c[2]=b; c[3] = 1.;}
CGrColor(double r, double g, double b, CGrObject *p_child)
{c[0]=r; c[1]=g; c[2]=b; c[3] = 1.; m_child=p_child;}
virtual ~CGrColor();
virtual void Render();
void Child(CGrObject *p_child) {m_child = p_child;}
private:
double c[4];
CGrPtr<CGrObject> m_child;
};
void CGrColor::glRender()
{
glColor4dv(c);
if(m_child)
m_child->glRender();
}
Adding Color to Model
CSE 472 S2019
CGrPtr<CGrColor> modelwcolor = new CGrColor(0., 0., 1., composite);
CGrColor node
CSE 472 S2019
CGrComposite
CGrPolygon CGrPolygon CGrPolygon CGrPolygon
CGrColor
A Translation Class
CSE 472 S2019
class CGrTranslate : public CGrObject
{
public:
CGrTranslate() {m_x=m_y=m_z = 0.;}
CGrTranslate(double x, double y, double z) {m_x=x; m_y=y; m_z=z;}
CGrTranslate(double x, double y, double z, CGrObject *p_child)
{m_x=x; m_y=y; m_z=z; m_child=p_child;}
~CGrTranslate();
virtual void Render();
void Child(CGrObject *p_child) {m_child = p_child;}
private:
CGrPtr<CGrObject> m_child;
double m_x, m_y, m_z;
};
Impl. Alternatives
CSE 472 S2019
void CGrTranslate::Render()
{
if(m_child)
{
glPushMatrix();
glTranslated(m_x, m_y, m_z);
m_child->glRender();
glPopMatrix();
}
}
void CGrTranslate::Render()
{
if(m_child)
{
glTranslated(m_x, m_y, m_z);
m_child->glRender();
}
}
Translate in Barbell
CSE 472 S2019
PolygonPolygon PolygonPolygon…
CompositeComposite
TranslateTranslate
ColorColor
PolygonPolygon PolygonPolygon…
CompositeComposite
ColorColor
TranslateTranslateTranslateTranslate
CompositeComposite
Barbell
Ends
Barbell
Bar
Very common…
CSE 472 S2019
TranslateTranslate
RotateRotate
TranslateTranslate
ObjectObject
Separator
PolygonPolygon PolygonPolygon…
CompositeComposite
TranslateTranslate
ColorColor
PolygonPolygon PolygonPolygon…
CompositeComposite
ColorColor
TranslateTranslateTranslateTranslate
CompositeComposite
Barbell
Ends
Barbell
Bar
SeparatorSeparator SeparatorSeparator SeparatorSeparator
Means: Go ahead and
mess with the transformation
matrix, I’m isolating my
children!
CSE 472 S2019
CGrSeparator
CSE 472 S2019
class CGrSeparator : public CGrObject
{
public:
CGrSeparator() {}
CGrSeparator(CGrObject *p_child) {m_child=p_child;}
~CGrSeparator();
virtual void Render();
void Child(CGrObject *p_child) {m_child = p_child;}
private:
CGrPtr<CGrObject> m_child;
};
void CGrSeparator::Render()
{
if(m_child)
{
glPushMatrix();
m_child->glRender();
glPopMatrix();
}
}
Bounding Boxes
AABB tree vs OBB tree
Bounding Sphere
CSE 472 S2019
[Cybercreations.com] [Gottschalk et al]
Spatial Organization
• Hierarchical Bounding Box Tree• Spatial Indexing or Partitioning
Going from x,y,z to Objects• Sometimes, with a viewing direction
BSP (k-d tree, octree)
Applications • collision detection, particle systems, user interaction, raytracing, painter’s algorithm…
CSE 472 S2019
Sample application
CSE 472 S2019
[Govindaraju et al. 05]
BSP Trees
CSE 472 S2019
Partition space into 2 half-spaces via a hyper-plane
a
b
c
d
e
a
cb
e d
Binary Space Partitioning
Painter’s Algorithm
CSE 472 S2019
Farthest z extent is insufficient
Cannot resolve dependency cycles
top
front
k-d Trees
k is dimensions
Node
Info
x, y
lt-link
ge-link
CSE 472 S2019
Quadtrees
2-d only
Split data 4 ways
Node:
info
x,y
nw,sw,ne,se
CSE 472 S2019
K-NN
CSE 472 S2019
[Wikipedia]