PageRenderTime 48ms CodeModel.GetById 16ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llmath/llbbox.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 178 lines | 119 code | 23 blank | 36 comment | 4 complexity | e399dc9bcd543ae3015b30278c616696 MD5 | raw file
  1/** 
  2 * @file llbbox.cpp
  3 * @brief General purpose bounding box class (Not axis aligned)
  4 *
  5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "linden_common.h"
 28
 29// self include
 30#include "llbbox.h"
 31
 32// library includes
 33#include "m4math.h"
 34
 35void LLBBox::addPointLocal(const LLVector3& p)
 36{
 37	if (mEmpty)
 38	{
 39		mMinLocal = p;
 40		mMaxLocal = p;
 41		mEmpty = FALSE;
 42	}
 43	else
 44	{
 45		mMinLocal.mV[VX] = llmin( p.mV[VX], mMinLocal.mV[VX] );
 46		mMinLocal.mV[VY] = llmin( p.mV[VY], mMinLocal.mV[VY] );
 47		mMinLocal.mV[VZ] = llmin( p.mV[VZ], mMinLocal.mV[VZ] );
 48		mMaxLocal.mV[VX] = llmax( p.mV[VX], mMaxLocal.mV[VX] );
 49		mMaxLocal.mV[VY] = llmax( p.mV[VY], mMaxLocal.mV[VY] );
 50		mMaxLocal.mV[VZ] = llmax( p.mV[VZ], mMaxLocal.mV[VZ] );
 51	}
 52}
 53
 54void LLBBox::addPointAgent( LLVector3 p)
 55{
 56	p -= mPosAgent;
 57	p.rotVec( ~mRotation );
 58	addPointLocal( p );
 59}
 60
 61
 62void LLBBox::addBBoxAgent(const LLBBox& b)
 63{
 64	if (mEmpty)
 65	{
 66		mPosAgent = b.mPosAgent;
 67		mRotation = b.mRotation;
 68		mMinLocal.clearVec();
 69		mMaxLocal.clearVec();
 70	}
 71	LLVector3 vertex[8];
 72	vertex[0].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] );
 73	vertex[1].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] );
 74	vertex[2].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] );
 75	vertex[3].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] );
 76	vertex[4].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] );
 77	vertex[5].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] );
 78	vertex[6].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] );
 79	vertex[7].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] );
 80
 81	LLMatrix4 m( b.mRotation );
 82	m.translate( b.mPosAgent );
 83	m.translate( -mPosAgent );
 84	m.rotate( ~mRotation );
 85
 86	for( S32 i=0; i<8; i++ )
 87	{
 88		addPointLocal( vertex[i] * m );
 89	}
 90}
 91
 92LLBBox LLBBox::getAxisAligned() const
 93{
 94	// no rotation = axis aligned rotation
 95	LLBBox aligned(mPosAgent, LLQuaternion(), LLVector3(), LLVector3());
 96
 97	// add the center point so that it's not empty
 98	aligned.addPointAgent(mPosAgent);
 99
100	// add our BBox
101	aligned.addBBoxAgent(*this);
102
103	return aligned;
104}
105
106void LLBBox::expand( F32 delta )
107{
108	mMinLocal.mV[VX] -= delta;
109	mMinLocal.mV[VY] -= delta;
110	mMinLocal.mV[VZ] -= delta;
111	mMaxLocal.mV[VX] += delta;
112	mMaxLocal.mV[VY] += delta;
113	mMaxLocal.mV[VZ] += delta;
114}
115
116LLVector3 LLBBox::localToAgent(const LLVector3& v) const
117{
118	LLMatrix4 m( mRotation );
119	m.translate( mPosAgent );
120	return v * m;
121}
122
123LLVector3 LLBBox::agentToLocal(const LLVector3& v) const
124{
125	LLMatrix4 m;
126	m.translate( -mPosAgent );
127	m.rotate( ~mRotation );  // inverse rotation
128	return v * m;
129}
130
131LLVector3 LLBBox::localToAgentBasis(const LLVector3& v) const
132{
133	LLMatrix4 m( mRotation );
134	return v * m;
135}
136
137LLVector3 LLBBox::agentToLocalBasis(const LLVector3& v) const
138{
139	LLMatrix4 m( ~mRotation );  // inverse rotation
140	return v * m;
141}
142
143BOOL LLBBox::containsPointLocal(const LLVector3& p) const
144{
145	if (  (p.mV[VX] < mMinLocal.mV[VX])
146		||(p.mV[VX] > mMaxLocal.mV[VX])
147		||(p.mV[VY] < mMinLocal.mV[VY])
148		||(p.mV[VY] > mMaxLocal.mV[VY])
149		||(p.mV[VZ] < mMinLocal.mV[VZ])
150		||(p.mV[VZ] > mMaxLocal.mV[VZ]))
151	{
152		return FALSE;
153	}
154	return TRUE;
155}
156
157BOOL LLBBox::containsPointAgent(const LLVector3& p) const
158{
159	LLVector3 point_local = agentToLocal(p);
160	return containsPointLocal(point_local);
161}
162
163LLVector3 LLBBox::getMinAgent() const
164{
165	return localToAgent(mMinLocal);
166}
167
168LLVector3 LLBBox::getMaxAgent() const
169{
170	return localToAgent(mMaxLocal);
171}
172
173/*
174LLBBox operator*(const LLBBox &a, const LLMatrix4 &b)
175{
176	return LLBBox( a.mMin * b, a.mMax * b );
177}
178*/