1
/*************************************************************************
2
* Copyright (C) 2004 by Olivier Galizzi *
3
* olivier.galizzi@imag.fr *
5
* This program is free software; it is licensed under the terms of the *
6
* GNU General Public License v2 or later. See file LICENSE for details. *
7
*************************************************************************/
9
#include <yade/pkg/common/Bo1_Aabb.hpp>
11
YADE_PLUGIN((Bo1_Sphere_Aabb)(Bo1_Facet_Aabb)(Bo1_Box_Aabb));
13
void Bo1_Sphere_Aabb::go(const shared_ptr<Shape>& cm, shared_ptr<Bound>& bv, const Se3r& se3, const Body* b){
14
Sphere* sphere = static_cast<Sphere*>(cm.get());
15
if(!bv){ bv=shared_ptr<Bound>(new Aabb); }
16
Aabb* aabb=static_cast<Aabb*>(bv.get());
17
Vector3r halfSize = (aabbEnlargeFactor>0?aabbEnlargeFactor:1.)*Vector3r(sphere->radius,sphere->radius,sphere->radius);
18
if(!scene->isPeriodic){
19
aabb->min=se3.position-halfSize; aabb->max=se3.position+halfSize;
22
// adjust box size along axes so that sphere doesn't stick out of the box even if sheared (i.e. parallelepiped)
23
if(scene->cell->hasShear()) {
24
Vector3r refHalfSize(halfSize);
25
const Vector3r& cos=scene->cell->getCos();
26
for(int i=0; i<3; i++){
27
//cerr<<"cos["<<i<<"]"<<cos[i]<<" ";
28
int i1=(i+1)%3,i2=(i+2)%3;
29
halfSize[i1]+=.5*refHalfSize[i1]*(1/cos[i]-1);
30
halfSize[i2]+=.5*refHalfSize[i2]*(1/cos[i]-1);
33
//cerr<<" || "<<halfSize<<endl;
34
aabb->min = scene->cell->unshearPt(se3.position)-halfSize;
35
aabb->max = scene->cell->unshearPt(se3.position)+halfSize;
38
void Bo1_Facet_Aabb::go( const shared_ptr<Shape>& cm
39
, shared_ptr<Bound>& bv
43
if(!bv){ bv=shared_ptr<Bound>(new Aabb); }
44
Aabb* aabb=static_cast<Aabb*>(bv.get());
45
Facet* facet = static_cast<Facet*>(cm.get());
46
const Vector3r& O = se3.position;
47
Matrix3r facetAxisT=se3.orientation.toRotationMatrix();
48
const vector<Vector3r>& vertices=facet->vertices;
49
if(!scene->isPeriodic){
50
aabb->min=aabb->max = O + facetAxisT * vertices[0];
53
Vector3r v = O + facetAxisT * vertices[i];
54
aabb->min = aabb->min.cwiseMin(v);
55
aabb->max = aabb->max.cwiseMax(v);
58
Real inf=std::numeric_limits<Real>::infinity();
59
aabb->min=Vector3r(inf,inf,inf); aabb->max=Vector3r(-inf,-inf,-inf);
60
for(int i=0; i<3; i++){
61
Vector3r v=scene->cell->unshearPt(O+facetAxisT*vertices[i]);
62
aabb->min=aabb->min.cwiseMin(v);
63
aabb->max=aabb->max.cwiseMax(v);
68
void Bo1_Box_Aabb::go( const shared_ptr<Shape>& cm,
69
shared_ptr<Bound>& bv,
73
Box* box = static_cast<Box*>(cm.get());
74
if(!bv){ bv=shared_ptr<Bound>(new Aabb); }
75
Aabb* aabb=static_cast<Aabb*>(bv.get());
77
if(scene->isPeriodic && scene->cell->hasShear()) throw logic_error(__FILE__ "Boxes not (yet?) supported in sheared cell.");
79
Matrix3r r=se3.orientation.toRotationMatrix();
80
Vector3r halfSize(Vector3r::Zero());
81
for( int i=0; i<3; ++i )
82
for( int j=0; j<3; ++j )
83
halfSize[i] += std::abs( r(i,j) * box->extents[j] );
85
aabb->min = se3.position-halfSize;
86
aabb->max = se3.position+halfSize;