/****************************************************************************
Copyright (C) 2012-2012 Universite de Sherbrooke, Quebec, CANADA
All rights reserved.
Contact : richard.fournier@usherbrooke.ca
jean-francois.cote@nrcan-rncan.gc.ca
joris.ravaglia@gmail.com
Developers : Joris RAVAGLIA
Adapted by Alexandre Piboule for Computree 2.0
This file is part of Computree version 2.0.
Computree is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Computree is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Computree. If not, see .
*****************************************************************************/
#include "ct_beam.h"
#include
const CT_StandardBeamDrawManager CT_Beam::BEAM_DRAW_MANAGER;
CT_Beam::CT_Beam() : CT_AbstractItemDrawableWithoutPointCloud()
{
m_shot = new CT_Shot(true);
// Setting the center attribute from the CT_AbstractItemDrawableWithoutPointCloud class
setCenterX( 0 );
setCenterY( 0 );
setCenterZ( 0 );
setBaseDrawManager(&BEAM_DRAW_MANAGER);
}
CT_Beam::CT_Beam(const CT_OutAbstractSingularItemModel *model, const CT_AbstractResult *result) : CT_AbstractItemDrawableWithoutPointCloud(model, result)
{
m_shot = new CT_Shot(true);
// Setting the center attribute from the CT_AbstractItemDrawableWithoutPointCloud class
setCenterX( 0 );
setCenterY( 0 );
setCenterZ( 0 );
setBaseDrawManager(&BEAM_DRAW_MANAGER);
}
CT_Beam::CT_Beam(const CT_OutAbstractSingularItemModel *model,
const CT_AbstractResult *result,
const Eigen::Vector3d &origin,
const Eigen::Vector3d &direction) : CT_AbstractItemDrawableWithoutPointCloud(model, result)
{
Q_ASSERT( !(direction(0) == 0 && direction(1) == 0 && direction(2) == 0) );
m_shot = new CT_Shot(origin, direction.normalized());
// Setting the center attribute from the CT_AbstractItemDrawableWithoutPointCloud class
setCenterCoordinate(origin);
setBaseDrawManager(&BEAM_DRAW_MANAGER);
}
CT_Beam::CT_Beam(const QString &modelName, const CT_AbstractResult *result) : CT_AbstractItemDrawableWithoutPointCloud(modelName, result)
{
m_shot = new CT_Shot(true);
// Setting the center attribute from the CT_AbstractItemDrawableWithoutPointCloud class
setCenterX( 0 );
setCenterY( 0 );
setCenterZ( 0 );
setBaseDrawManager(&BEAM_DRAW_MANAGER);
}
CT_Beam::CT_Beam(const QString &modelName, const CT_AbstractResult *result, const Eigen::Vector3d &origin, const Eigen::Vector3d &direction) : CT_AbstractItemDrawableWithoutPointCloud(modelName, result)
{
Q_ASSERT( !(direction(0) == 0 && direction(1) == 0 && direction(2) == 0) );
m_shot = new CT_Shot(origin, direction.normalized());
// Setting the center attribute from the CT_AbstractItemDrawableWithoutPointCloud class
setCenterCoordinate(origin);
setBaseDrawManager(&BEAM_DRAW_MANAGER);
}
CT_Beam::~CT_Beam()
{
delete m_shot;
}
bool CT_Beam::intersect(const Eigen::Vector3d& bot, const Eigen::Vector3d& top, Eigen::Vector3d &nearP, Eigen::Vector3d &farP) const
{
double t0 = 0;
double t1 = std::numeric_limits::max();
if (!updateIntervals(bot(0), top(0), m_shot->getOrigin()(0), m_shot->getDirection()(0), t0, t1)) {return false;}
if (!updateIntervals(bot(1), top(1), m_shot->getOrigin()(1), m_shot->getDirection()(1), t0, t1)) {return false;}
if (!updateIntervals(bot(2), top(2), m_shot->getOrigin()(2), m_shot->getDirection()(2), t0, t1)) {return false;}
nearP = m_shot->getOrigin() + m_shot->getDirection()*t0;
farP = m_shot->getOrigin() + m_shot->getDirection()*t1;
return true;
}
bool CT_Beam::intersect(const Eigen::Vector3d& bot, const Eigen::Vector3d& top) const
{
double t0 = 0;
double t1 = std::numeric_limits::max();
if (!updateIntervals(bot(0), top(0), m_shot->getOrigin()(0), m_shot->getDirection()(0), t0, t1)) {return false;}
if (!updateIntervals(bot(1), top(1), m_shot->getOrigin()(1), m_shot->getDirection()(1), t0, t1)) {return false;}
if (!updateIntervals(bot(2), top(2), m_shot->getOrigin()(2), m_shot->getDirection()(2), t0, t1)) {return false;}
return true;
}
bool CT_Beam::updateIntervals(const double &bot, const double &top, const double &origin, const double &direction, double &t0, double &t1) const
{
// Update interval for bounding box slab
double invRayDir = 1.f / direction;
double tNear = (bot - origin) * invRayDir;
double tFar = (top - origin) * invRayDir;
// Update parametric interval from slab intersection $t$s
if (tNear > tFar) std::swap(tNear, tFar);
t0 = tNear > t0 ? tNear : t0;
t1 = tFar < t1 ? tFar : t1;
if (t0 > t1 && t0 - t1 > EPSILON_INTERSECTION_RAY ) // t0 being always > t1, (t0-t1) is always positive
{
return false;
}
return true;
}
CT_Beam* CT_Beam::copy(const CT_OutAbstractItemModel *model,
const CT_AbstractResult *result,
CT_ResultCopyModeList copyModeList)
{
CT_Beam *ray = new CT_Beam((const CT_OutAbstractSingularItemModel *)model, result, m_shot->getOrigin(), m_shot->getDirection());
ray->setId(id());
ray->setAlternativeDrawManager(getAlternativeDrawManager());
return ray;
}