Commit 87aed8c0 authored by Jan Möbius's avatar Jan Möbius
Browse files

Separated Plane Datatype

parents
include(ACGCommon)
include_directories (
..
${ACG_INCLUDE_DIR}
${OPENMESH_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${OPENGL_INCLUDE_DIR}
${GLEW_INCLUDE_DIR}
${GLUT_INCLUDE_DIR}
)
link_directories (
${GLEW_LIBRARY_DIR}
${ADDITIONAL_PLUGINLIB_LINK_DIRS}
)
#=======================================================
# General defines
#=======================================================
# generate dllexport macros on windows
if (WIN32)
add_definitions (
-DPLUGINLIBDLL
-DACGDLL
-DUSEACG
)
endif ()
#=======================================================
# Cleanup
#=======================================================
# remove template cc files from source file list
acg_drop_templates (sources)
# collect all header,source files
acg_append_files (headers "*.hh" . )
acg_append_files (sources "*.cc" . )
# Match our current directory name
string (REGEX MATCH "[^/\\]*$" TYPENAME ${CMAKE_CURRENT_SOURCE_DIR})
string(TOUPPER ${TYPENAME} TYPENAME )
include_directories (
..
${ACG_INCLUDE_DIR}
${OPENMESH_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../..
${CMAKE_CURRENT_BINARY_DIR}
${OPENGL_INCLUDE_DIR}
${GLEW_INCLUDE_DIR}
${GLUT_INCLUDE_DIR}
)
acg_add_library ( ${TYPENAME} SHARED ${sources} ${headers} )
add_dependencies( ${TYPENAME} OpenMeshCore OpenMeshTools ACG OpenFlipperPluginLib)
target_link_libraries (${TYPENAME}
${OPENMESH_LIBRARIES}
ACG
${QT_LIBRARIES}
${OPENGL_LIBRARIES}
${GLEW_LIBRARY}
${GLUT_LIBRARIES}
PluginLib
)
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openflipper.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenFlipper. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
/**
* \file Plane.hh
* This File contains all required includes for using Planes
*/
#ifndef PLANE_INCLUDE_HH
#define PLANE_INCLUDE_HH
//== INCLUDES =================================================================
/** \def DATA_PLANE
* Use this macro to reference Plane objects
*/
#define DATA_PLANE typeId("Plane")
#include <ObjectTypes/Plane/PlaneObject.hh>
#include <ObjectTypes/Plane/PluginFunctionsPlane.hh>
#include <ObjectTypes/Plane/PlaneTypes.hh>
//=============================================================================
#endif // PLANE_INCLUDE_HH defined
//=============================================================================
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openflipper.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenFlipper. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Author$ *
* $Date$ *
* *
\*===========================================================================*/
#include <ACG/GL/acg_glew.hh>
#include "PlaneNode.hh"
//== IMPLEMENTATION ==========================================================
PlaneNode::PlaneNode(Plane& _plane, BaseNode *_parent, std::string _name)
:BaseNode(_parent, _name),
plane_(_plane),
vbo_(0),
vboNeedsUpdate_(true),//not initialized, so we need an update
sphere_(0)
{
vertexDecl_.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_POSITION);
vertexDecl_.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_NORMAL);
sphere_ = new ACG::GLSphere(10, 10);
setPlane(_plane);
}
PlaneNode::~PlaneNode()
{
if ( vbo_)
glDeleteBuffers(1,&vbo_);
}
void PlaneNode::boundingBox(ACG::Vec3d& _bbMin, ACG::Vec3d& _bbMax)
{
ACG::Vec3d pos = plane_.position - plane_.xDirection * 0.5 - plane_.yDirection * 0.5;
//add a little offset in normal direction
ACG::Vec3d pos0 = ACG::Vec3d( pos + plane_.normal * 0.1 );
ACG::Vec3d pos1 = ACG::Vec3d( pos - plane_.normal * 0.1 );
ACG::Vec3d xDird = ACG::Vec3d( plane_.xDirection );
ACG::Vec3d yDird = ACG::Vec3d( plane_.yDirection );
_bbMin.minimize( pos0 );
_bbMin.minimize( pos0 + xDird);
_bbMin.minimize( pos0 + yDird);
_bbMin.minimize( pos0 + xDird + yDird);
_bbMax.maximize( pos1 );
_bbMax.maximize( pos1 + xDird);
_bbMax.maximize( pos1 + yDird);
_bbMax.maximize( pos1 + xDird + yDird);
_bbMin.minimize( pos1 );
_bbMin.minimize( pos1 + xDird);
_bbMin.minimize( pos1 + yDird);
_bbMin.minimize( pos1 + xDird + yDird);
_bbMax.maximize( pos0 );
_bbMax.maximize( pos0 + xDird);
_bbMax.maximize( pos0 + yDird);
_bbMax.maximize( pos0 + xDird + yDird);
}
//----------------------------------------------------------------------------
ACG::SceneGraph::DrawModes::DrawMode
PlaneNode::availableDrawModes() const
{
return ( ACG::SceneGraph::DrawModes::POINTS |
ACG::SceneGraph::DrawModes::SOLID_FLAT_SHADED );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void PlaneNode::drawPlane( ACG::GLState& _state) {
const ACG::Vec3d xy = plane_.xDirection + plane_.yDirection;
// Array of coordinates for the plane
float vboData_[9 * 3 ] = { 0.0,0.0,0.0,
(float)plane_.xDirection[0],(float)plane_.xDirection[1],(float)plane_.xDirection[2],
(float)xy[0],(float)xy[1],(float)xy[2],
(float)plane_.yDirection[0],(float)plane_.yDirection[1],(float)plane_.yDirection[2],
0.0,0.0,0.0,
(float)plane_.yDirection[0],(float)plane_.yDirection[1],(float)plane_.yDirection[2],
(float)xy[0],(float)xy[1],(float)xy[2],
(float)plane_.xDirection[0],(float)plane_.xDirection[1],(float)plane_.xDirection[2],
0.0,0.0,0.0 };
// Enable the arrays
_state.enableClientState(GL_VERTEX_ARRAY);
_state.vertexPointer(3,GL_FLOAT,0,&vboData_[0]);
//first draw the lines
_state.set_color(ACG::Vec4f(1.0, 1.0, 1.0 , 1.0) );
glLineWidth(2.0);
glDrawArrays(GL_LINE_STRIP,0,5);
glLineWidth(1.0);
// Remember blending state
bool blending = _state.blending();
bool culling = _state.isStateEnabled(GL_CULL_FACE);
//then the red front side
ACG::GLState::enable (GL_BLEND);
ACG::GLState::blendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ACG::GLState::enable (GL_CULL_FACE);
_state.set_color(ACG::Vec4f( 0.6f, 0.15f, 0.2f, 0.5f));
glDrawArrays(GL_QUADS,0,4);
//finally the green back side
_state.set_color(ACG::Vec4f(0.1f, 0.8f, 0.2f, 0.5f ));
glDrawArrays(GL_QUADS,5,4);
if ( !blending )
ACG::GLState::disable(GL_BLEND);
if ( !culling )
ACG::GLState::disable(GL_CULL_FACE);
// deactivate vertex arrays after drawing
_state.disableClientState(GL_VERTEX_ARRAY);
}
//----------------------------------------------------------------
void PlaneNode::drawPlanePick( ACG::GLState& _state) {
_state.pick_set_maximum(1);
_state.pick_set_name(0);
const ACG::Vec3d xy = plane_.xDirection + plane_.yDirection;
// Array of coordinates for the plane
float vboData_[4* 3 ] = { 0.0,0.0,0.0,
(float)plane_.xDirection[0],(float)plane_.xDirection[1],(float)plane_.xDirection[2],
(float)xy[0],(float)xy[1],(float)xy[2],
(float)plane_.yDirection[0],(float)plane_.yDirection[1],(float)plane_.yDirection[2] };
// Enable the arrays
_state.enableClientState(GL_VERTEX_ARRAY);
_state.vertexPointer(3,GL_FLOAT,0,&vboData_[0]);
glDrawArrays(GL_QUADS,0,4);
// deactivate vertex arrays after drawing
_state.disableClientState(GL_VERTEX_ARRAY);
}
//----------------------------------------------------------------
void PlaneNode::draw(ACG::GLState& _state , const ACG::SceneGraph::DrawModes::DrawMode& /*_drawMode*/)
{
_state.push_modelview_matrix();
glPushAttrib(GL_COLOR_BUFFER_BIT);
glPushAttrib(GL_LIGHTING_BIT);
glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
ACG::GLState::enable(GL_COLOR_MATERIAL);
// plane_.position represents the center of the plane.
// Compute the corner position
ACG::Vec3d pos = plane_.position - plane_.xDirection*0.5 - plane_.yDirection*0.5;
// translate to corner position
_state.translate(pos[0], pos[1], pos[2]);
// draw the plane
drawPlane(_state);
glPopAttrib();
glPopAttrib();
_state.pop_modelview_matrix();
}
//----------------------------------------------------------------
void
PlaneNode::pick(ACG::GLState& _state, ACG::SceneGraph::PickTarget _target)
{
if (_target == ACG::SceneGraph::PICK_ANYTHING) {
_state.push_modelview_matrix();
ACG::Vec3d pos = plane_.position - plane_.xDirection*0.5 - plane_.yDirection*0.5;
_state.translate(pos[0], pos[1], pos[2]);
drawPlanePick(_state);
_state.pop_modelview_matrix();
}
}
//----------------------------------------------------------------
ACG::Vec3d PlaneNode::position()
{
return plane_.position;
}
//----------------------------------------------------------------
ACG::Vec3d PlaneNode::normal()
{
return plane_.normal;
}
//----------------------------------------------------------------
ACG::Vec3d PlaneNode::xDirection()
{
return plane_.xDirection;
}
//----------------------------------------------------------------
ACG::Vec3d PlaneNode::yDirection()
{
return plane_.yDirection;
}
//----------------------------------------------------------------
Plane& PlaneNode::getPlane()
{
return plane_;
}
//----------------------------------------------------------------
void PlaneNode::setPlane(Plane plane)
{
plane_ = plane;
update();
}
//----------------------------------------------------------------------------
void
PlaneNode::
addSphereAt(ACG::Vec3d _pos, ACG::IRenderer* _renderer, ACG::GLState& _state, ACG::RenderObject* _ro) {
// 1. Project point to screen
ACG::Vec3d projected = _state.project( _pos );
// 2. Shift it by the requested point size
// glPointSize defines the diameter but we want the radius, so we divide it by two
ACG::Vec3d shifted = projected;
shifted[0] = shifted[0] + (double)_state.point_size() / 2.0 ;
// 3. un-project into 3D
ACG::Vec3d unProjectedShifted = _state.unproject( shifted );
// 4. The difference vector defines the radius in 3D for the sphere
ACG::Vec3d difference = unProjectedShifted - _pos ;
const double sphereSize = difference.norm();
sphere_->addToRenderer(_renderer, _ro, sphereSize, ACG::Vec3f(_pos));
}
void PlaneNode::update() {
//update the plane in the next renderstep
//if the old renderer is used, nothing to do here
//if the new, shader based renderer is used, we have to update the vbo
// this is done at the next render call
//this method prevents, that the vbo is created, if we don't use a shader based renderer
vboNeedsUpdate_ = true;
}
//----------------------------------------------------------------------------
void PlaneNode::updateVBO()
{
if (!vboNeedsUpdate_)
return;
if ( !vbo_ ) {
glGenBuffersARB(1, &vbo_);
}
const ACG::Vec3d xy = plane_.xDirection + plane_.yDirection;
const ACG::Vec3d normal = (plane_.xDirection % plane_.yDirection).normalized();
// Array of coordinates for the plane ( duplicated due to front and back rendering )
// Interleaved with normals
// 8 vertices with (3 float for position + 3 float for normal)
const size_t vboSize = 8 * (3+3);
float vboData[vboSize] = { 0.0,0.0,0.0,
(float)normal[0],(float)normal[1],(float)normal[2],
(float)plane_.xDirection[0],(float)plane_.xDirection[1],(float)plane_.xDirection[2],
(float)normal[0],(float)normal[1],(float)normal[2],
(float)xy[0],(float)xy[1],(float)xy[2],
(float)normal[0],(float)normal[1],(float)normal[2],
(float)plane_.yDirection[0],(float)plane_.yDirection[1],(float)plane_.yDirection[2],
(float)normal[0],(float)normal[1],(float)normal[2],
(float)plane_.yDirection[0],(float)plane_.yDirection[1],(float)plane_.yDirection[2],
(float)-normal[0],(float)-normal[1],(float)-normal[2],
(float)xy[0],(float)xy[1],(float)xy[2],
(float)-normal[0],(float)-normal[1],(float)-normal[2],
(float)plane_.xDirection[0],(float)plane_.xDirection[1],(float)plane_.xDirection[2],
(float)-normal[0],(float)-normal[1],(float)-normal[2],
0.0,0.0,0.0,
(float)-normal[0],(float)-normal[1],(float)-normal[2]};
// Bind buffer
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_);
// Upload to buffer
glBufferDataARB(GL_ARRAY_BUFFER_ARB, vboSize * sizeof(float), &vboData[0], GL_STATIC_DRAW_ARB);
// Unbind
ACG::GLState::bindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
// VBO is updated for the new renderer
vboNeedsUpdate_ = false;
}
void
PlaneNode::
getRenderObjects(ACG::IRenderer* _renderer, ACG::GLState& _state , const ACG::SceneGraph::DrawModes::DrawMode& _drawMode , const ACG::SceneGraph::Material* _mat) {
// init base render object
ACG::RenderObject ro;
_state.enable(GL_COLOR_MATERIAL);
_state.disable(GL_LIGHTING);
ro.initFromState(&_state);
// plane_.position represents the center of the plane.
// Compute the corner position
const ACG::Vec3d pos = plane_.position - plane_.xDirection*0.5 - plane_.yDirection*0.5;
const ACG::Vec3d xy = plane_.xDirection + plane_.yDirection;
// translate to corner position and store that in renderer
_state.push_modelview_matrix();
_state.translate(pos[0], pos[1], pos[2]);
ro.modelview = _state.modelview();
_state.pop_modelview_matrix();
// Render with depth test enabled
ro.depthTest = true;
updateVBO();
// Set the buffers for rendering
ro.vertexBuffer = vbo_;
ro.vertexDecl = &vertexDecl_;
for (unsigned int i = 0; i < _drawMode.getNumLayers(); ++i)
{
ACG::SceneGraph::Material localMaterial = *_mat;
const ACG::SceneGraph::DrawModes::DrawModeProperties* props = _drawMode.getLayer(i);
ro.setupShaderGenFromDrawmode(props);
switch (props->primitive()) {
case ACG::SceneGraph::DrawModes::PRIMITIVE_POINT:
ro.blending = false;
//---------------------------------------------------
// No lighting!
// Therefore we need some emissive color
//---------------------------------------------------
localMaterial.baseColor( localMaterial.ambientColor() );
ro.setMaterial(&localMaterial);
//---------------------------------------------------
// Simulate glPointSize(12) with a sphere
//---------------------------------------------------
ro.debugName = "Plane Sphere x";
addSphereAt(plane_.xDirection,_renderer,_state,&ro);
ro.debugName = "Plane Sphere y";
addSphereAt(plane_.yDirection,_renderer,_state,&ro);
ro.debugName = "Plane Sphere xy";
addSphereAt(xy,_renderer,_state,&ro);
ro.debugName = "Plane Sphere 0";
addSphereAt(ACG::Vec3d(0.0,0.0,0.0),_renderer,_state,&ro);
break;