diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-04-29 07:43:28 +0300 | 
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-04-29 07:56:09 +0300 | 
| commit | 1b68f71348ecf3983b76b40d7940da8377f049b7 (patch) | |
| tree | 2974eddaef130a067c26033d60a59fc790365b3d /indra/llmath | |
| parent | af4ea94efc1999f3b19fd8d643d0331f0b77e265 (diff) | |
#824 Process source files in bulk: replace tabs with spaces, convert CRLF to LF, and trim trailing whitespaces as needed
Diffstat (limited to 'indra/llmath')
97 files changed, 24654 insertions, 24654 deletions
diff --git a/indra/llmath/camera.h b/indra/llmath/camera.h index 26f3c3d19f..14a08c5985 100644 --- a/indra/llmath/camera.h +++ b/indra/llmath/camera.h @@ -1,25 +1,25 @@ -/**  +/**   * @file camera.h   * @brief Legacy wrapper header.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ diff --git a/indra/llmath/coordframe.h b/indra/llmath/coordframe.h index 271bcb433c..e7395b1212 100644 --- a/indra/llmath/coordframe.h +++ b/indra/llmath/coordframe.h @@ -1,25 +1,25 @@ -/**  +/**   * @file coordframe.h   * @brief Legacy wrapper header.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ diff --git a/indra/llmath/llbbox.cpp b/indra/llmath/llbbox.cpp index 3e2c05a6e6..c4dffc8cf8 100644 --- a/indra/llmath/llbbox.cpp +++ b/indra/llmath/llbbox.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file llbbox.cpp   * @brief General purpose bounding box class (Not axis aligned)   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -34,145 +34,145 @@  void LLBBox::addPointLocal(const LLVector3& p)  { -	if (mEmpty) -	{ -		mMinLocal = p; -		mMaxLocal = p; -		mEmpty = FALSE; -	} -	else -	{ -		mMinLocal.mV[VX] = llmin( p.mV[VX], mMinLocal.mV[VX] ); -		mMinLocal.mV[VY] = llmin( p.mV[VY], mMinLocal.mV[VY] ); -		mMinLocal.mV[VZ] = llmin( p.mV[VZ], mMinLocal.mV[VZ] ); -		mMaxLocal.mV[VX] = llmax( p.mV[VX], mMaxLocal.mV[VX] ); -		mMaxLocal.mV[VY] = llmax( p.mV[VY], mMaxLocal.mV[VY] ); -		mMaxLocal.mV[VZ] = llmax( p.mV[VZ], mMaxLocal.mV[VZ] ); -	} +    if (mEmpty) +    { +        mMinLocal = p; +        mMaxLocal = p; +        mEmpty = FALSE; +    } +    else +    { +        mMinLocal.mV[VX] = llmin( p.mV[VX], mMinLocal.mV[VX] ); +        mMinLocal.mV[VY] = llmin( p.mV[VY], mMinLocal.mV[VY] ); +        mMinLocal.mV[VZ] = llmin( p.mV[VZ], mMinLocal.mV[VZ] ); +        mMaxLocal.mV[VX] = llmax( p.mV[VX], mMaxLocal.mV[VX] ); +        mMaxLocal.mV[VY] = llmax( p.mV[VY], mMaxLocal.mV[VY] ); +        mMaxLocal.mV[VZ] = llmax( p.mV[VZ], mMaxLocal.mV[VZ] ); +    }  }  void LLBBox::addPointAgent( LLVector3 p)  { -	p -= mPosAgent; -	p.rotVec( ~mRotation ); -	addPointLocal( p ); +    p -= mPosAgent; +    p.rotVec( ~mRotation ); +    addPointLocal( p );  }  void LLBBox::addBBoxAgent(const LLBBox& b)  { -	if (mEmpty) -	{ -		mPosAgent = b.mPosAgent; -		mRotation = b.mRotation; -		mMinLocal.clearVec(); -		mMaxLocal.clearVec(); -	} -	LLVector3 vertex[8]; -	vertex[0].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); -	vertex[1].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); -	vertex[2].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); -	vertex[3].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); -	vertex[4].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); -	vertex[5].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); -	vertex[6].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); -	vertex[7].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); - -	LLMatrix4 m( b.mRotation ); -	m.translate( b.mPosAgent ); -	m.translate( -mPosAgent ); -	m.rotate( ~mRotation ); - -	for( S32 i=0; i<8; i++ ) -	{ -		addPointLocal( vertex[i] * m ); -	} +    if (mEmpty) +    { +        mPosAgent = b.mPosAgent; +        mRotation = b.mRotation; +        mMinLocal.clearVec(); +        mMaxLocal.clearVec(); +    } +    LLVector3 vertex[8]; +    vertex[0].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); +    vertex[1].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); +    vertex[2].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); +    vertex[3].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); +    vertex[4].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); +    vertex[5].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); +    vertex[6].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); +    vertex[7].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + +    LLMatrix4 m( b.mRotation ); +    m.translate( b.mPosAgent ); +    m.translate( -mPosAgent ); +    m.rotate( ~mRotation ); + +    for( S32 i=0; i<8; i++ ) +    { +        addPointLocal( vertex[i] * m ); +    }  }  LLBBox LLBBox::getAxisAligned() const  { -	// no rotation = axis aligned rotation -	LLBBox aligned(mPosAgent, LLQuaternion(), LLVector3(), LLVector3()); +    // no rotation = axis aligned rotation +    LLBBox aligned(mPosAgent, LLQuaternion(), LLVector3(), LLVector3()); -	// add the center point so that it's not empty -	aligned.addPointAgent(mPosAgent); +    // add the center point so that it's not empty +    aligned.addPointAgent(mPosAgent); -	// add our BBox -	aligned.addBBoxAgent(*this); +    // add our BBox +    aligned.addBBoxAgent(*this); -	return aligned; +    return aligned;  }  void LLBBox::expand( F32 delta )  { -	mMinLocal.mV[VX] -= delta; -	mMinLocal.mV[VY] -= delta; -	mMinLocal.mV[VZ] -= delta; -	mMaxLocal.mV[VX] += delta; -	mMaxLocal.mV[VY] += delta; -	mMaxLocal.mV[VZ] += delta; +    mMinLocal.mV[VX] -= delta; +    mMinLocal.mV[VY] -= delta; +    mMinLocal.mV[VZ] -= delta; +    mMaxLocal.mV[VX] += delta; +    mMaxLocal.mV[VY] += delta; +    mMaxLocal.mV[VZ] += delta;  }  LLVector3 LLBBox::localToAgent(const LLVector3& v) const  { -	LLMatrix4 m( mRotation ); -	m.translate( mPosAgent ); -	return v * m; +    LLMatrix4 m( mRotation ); +    m.translate( mPosAgent ); +    return v * m;  }  LLVector3 LLBBox::agentToLocal(const LLVector3& v) const  { -	LLMatrix4 m; -	m.translate( -mPosAgent ); -	m.rotate( ~mRotation );  // inverse rotation -	return v * m; +    LLMatrix4 m; +    m.translate( -mPosAgent ); +    m.rotate( ~mRotation );  // inverse rotation +    return v * m;  }  LLVector3 LLBBox::localToAgentBasis(const LLVector3& v) const  { -	LLMatrix4 m( mRotation ); -	return v * m; +    LLMatrix4 m( mRotation ); +    return v * m;  }  LLVector3 LLBBox::agentToLocalBasis(const LLVector3& v) const  { -	LLMatrix4 m( ~mRotation );  // inverse rotation -	return v * m; +    LLMatrix4 m( ~mRotation );  // inverse rotation +    return v * m;  }  BOOL LLBBox::containsPointLocal(const LLVector3& p) const  { -	if (  (p.mV[VX] < mMinLocal.mV[VX]) -		||(p.mV[VX] > mMaxLocal.mV[VX]) -		||(p.mV[VY] < mMinLocal.mV[VY]) -		||(p.mV[VY] > mMaxLocal.mV[VY]) -		||(p.mV[VZ] < mMinLocal.mV[VZ]) -		||(p.mV[VZ] > mMaxLocal.mV[VZ])) -	{ -		return FALSE; -	} -	return TRUE; +    if (  (p.mV[VX] < mMinLocal.mV[VX]) +        ||(p.mV[VX] > mMaxLocal.mV[VX]) +        ||(p.mV[VY] < mMinLocal.mV[VY]) +        ||(p.mV[VY] > mMaxLocal.mV[VY]) +        ||(p.mV[VZ] < mMinLocal.mV[VZ]) +        ||(p.mV[VZ] > mMaxLocal.mV[VZ])) +    { +        return FALSE; +    } +    return TRUE;  }  BOOL LLBBox::containsPointAgent(const LLVector3& p) const  { -	LLVector3 point_local = agentToLocal(p); -	return containsPointLocal(point_local); +    LLVector3 point_local = agentToLocal(p); +    return containsPointLocal(point_local);  }  LLVector3 LLBBox::getMinAgent() const  { -	return localToAgent(mMinLocal); +    return localToAgent(mMinLocal);  }  LLVector3 LLBBox::getMaxAgent() const  { -	return localToAgent(mMaxLocal); +    return localToAgent(mMaxLocal);  }  /*  LLBBox operator*(const LLBBox &a, const LLMatrix4 &b)  { -	return LLBBox( a.mMin * b, a.mMax * b ); +    return LLBBox( a.mMin * b, a.mMax * b );  }  */ diff --git a/indra/llmath/llbbox.h b/indra/llmath/llbbox.h index 28e69b75e1..aac8628762 100644 --- a/indra/llmath/llbbox.h +++ b/indra/llmath/llbbox.h @@ -1,25 +1,25 @@ -/**  +/**   * @file llbbox.h   * @brief General purpose bounding box class   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -31,68 +31,68 @@  #include "llquaternion.h"  // Note: "local space" for an LLBBox is defined relative to agent space in terms of -// a translation followed by a rotation.  There is no scale term since the LLBBox's min and  +// a translation followed by a rotation.  There is no scale term since the LLBBox's min and  // max are not necessarily symetrical and define their own extents.  class LLBBox  {  public: -	LLBBox() {mEmpty = TRUE;} -	LLBBox( const LLVector3& pos_agent, -		const LLQuaternion& rot, -		const LLVector3& min_local, -		const LLVector3& max_local ) -		: -		mMinLocal( min_local ), mMaxLocal( max_local ), mPosAgent(pos_agent), mRotation( rot), mEmpty( TRUE ) -		{} +    LLBBox() {mEmpty = TRUE;} +    LLBBox( const LLVector3& pos_agent, +        const LLQuaternion& rot, +        const LLVector3& min_local, +        const LLVector3& max_local ) +        : +        mMinLocal( min_local ), mMaxLocal( max_local ), mPosAgent(pos_agent), mRotation( rot), mEmpty( TRUE ) +        {} + +    // Default copy constructor is OK. -	// Default copy constructor is OK. +    const LLVector3&    getPositionAgent() const            { return mPosAgent; } +    const LLQuaternion& getRotation() const                 { return mRotation; } -	const LLVector3&	getPositionAgent() const			{ return mPosAgent; } -	const LLQuaternion&	getRotation() const					{ return mRotation; } +    LLVector3           getMinAgent() const; +    const LLVector3&    getMinLocal() const                 { return mMinLocal; } +    void                setMinLocal( const LLVector3& min ) { mMinLocal = min; } -	LLVector3           getMinAgent() const; -	const LLVector3&	getMinLocal() const					{ return mMinLocal; } -	void				setMinLocal( const LLVector3& min )	{ mMinLocal = min; } +    LLVector3           getMaxAgent() const; +    const LLVector3&    getMaxLocal() const                 { return mMaxLocal; } +    void                setMaxLocal( const LLVector3& max ) { mMaxLocal = max; } -	LLVector3           getMaxAgent() const; -	const LLVector3&	getMaxLocal() const					{ return mMaxLocal; } -	void				setMaxLocal( const LLVector3& max )	{ mMaxLocal = max; } +    LLVector3           getCenterLocal() const              { return (mMaxLocal - mMinLocal) * 0.5f + mMinLocal; } +    LLVector3           getCenterAgent() const              { return localToAgent( getCenterLocal() ); } -	LLVector3			getCenterLocal() const				{ return (mMaxLocal - mMinLocal) * 0.5f + mMinLocal; } -	LLVector3			getCenterAgent() const				{ return localToAgent( getCenterLocal() ); } +    LLVector3           getExtentLocal() const              { return mMaxLocal - mMinLocal; } -	LLVector3			getExtentLocal() const				{ return mMaxLocal - mMinLocal; } +    BOOL                containsPointLocal(const LLVector3& p) const; +    BOOL                containsPointAgent(const LLVector3& p) const; -	BOOL				containsPointLocal(const LLVector3& p) const; -	BOOL				containsPointAgent(const LLVector3& p) const; +    void                addPointAgent(LLVector3 p); +    void                addBBoxAgent(const LLBBox& b); -	void				addPointAgent(LLVector3 p); -	void				addBBoxAgent(const LLBBox& b); -	 -	void				addPointLocal(const LLVector3& p); -	void				addBBoxLocal(const LLBBox& b) {	addPointLocal( b.mMinLocal ); addPointLocal( b.mMaxLocal ); } +    void                addPointLocal(const LLVector3& p); +    void                addBBoxLocal(const LLBBox& b) { addPointLocal( b.mMinLocal ); addPointLocal( b.mMaxLocal ); } -	void				expand( F32 delta ); +    void                expand( F32 delta ); -	LLVector3			localToAgent( const LLVector3& v ) const; -	LLVector3			agentToLocal( const LLVector3& v ) const; +    LLVector3           localToAgent( const LLVector3& v ) const; +    LLVector3           agentToLocal( const LLVector3& v ) const; -	// Changes rotation but not position -	LLVector3			localToAgentBasis(const LLVector3& v) const; -	LLVector3			agentToLocalBasis(const LLVector3& v) const; +    // Changes rotation but not position +    LLVector3           localToAgentBasis(const LLVector3& v) const; +    LLVector3           agentToLocalBasis(const LLVector3& v) const; -	// Get the smallest possible axis aligned bbox that contains this bbox -	LLBBox              getAxisAligned() const; +    // Get the smallest possible axis aligned bbox that contains this bbox +    LLBBox              getAxisAligned() const; -//	friend LLBBox operator*(const LLBBox& a, const LLMatrix4& b); +//  friend LLBBox operator*(const LLBBox& a, const LLMatrix4& b);  private: -	LLVector3			mMinLocal; -	LLVector3			mMaxLocal; -	LLVector3			mPosAgent;  // Position relative to Agent's Region -	LLQuaternion		mRotation; -	BOOL				mEmpty;		// Nothing has been added to this bbox yet +    LLVector3           mMinLocal; +    LLVector3           mMaxLocal; +    LLVector3           mPosAgent;  // Position relative to Agent's Region +    LLQuaternion        mRotation; +    BOOL                mEmpty;     // Nothing has been added to this bbox yet  };  //LLBBox operator*(const LLBBox &a, const LLMatrix4 &b); diff --git a/indra/llmath/llbboxlocal.cpp b/indra/llmath/llbboxlocal.cpp index bf0c1a7b93..cbb7a1b481 100644 --- a/indra/llmath/llbboxlocal.cpp +++ b/indra/llmath/llbboxlocal.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file llbboxlocal.cpp   * @brief General purpose bounding box class (Not axis aligned).   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -31,25 +31,25 @@  void LLBBoxLocal::addPoint(const LLVector3& p)  { -	mMin.mV[VX] = llmin( p.mV[VX], mMin.mV[VX] ); -	mMin.mV[VY] = llmin( p.mV[VY], mMin.mV[VY] ); -	mMin.mV[VZ] = llmin( p.mV[VZ], mMin.mV[VZ] ); -	mMax.mV[VX] = llmax( p.mV[VX], mMax.mV[VX] ); -	mMax.mV[VY] = llmax( p.mV[VY], mMax.mV[VY] ); -	mMax.mV[VZ] = llmax( p.mV[VZ], mMax.mV[VZ] ); +    mMin.mV[VX] = llmin( p.mV[VX], mMin.mV[VX] ); +    mMin.mV[VY] = llmin( p.mV[VY], mMin.mV[VY] ); +    mMin.mV[VZ] = llmin( p.mV[VZ], mMin.mV[VZ] ); +    mMax.mV[VX] = llmax( p.mV[VX], mMax.mV[VX] ); +    mMax.mV[VY] = llmax( p.mV[VY], mMax.mV[VY] ); +    mMax.mV[VZ] = llmax( p.mV[VZ], mMax.mV[VZ] );  }  void LLBBoxLocal::expand( F32 delta )  { -	mMin.mV[VX] -= delta; -	mMin.mV[VY] -= delta; -	mMin.mV[VZ] -= delta; -	mMax.mV[VX] += delta; -	mMax.mV[VY] += delta; -	mMax.mV[VZ] += delta; +    mMin.mV[VX] -= delta; +    mMin.mV[VY] -= delta; +    mMin.mV[VZ] -= delta; +    mMax.mV[VX] += delta; +    mMax.mV[VY] += delta; +    mMax.mV[VZ] += delta;  }  LLBBoxLocal operator*(const LLBBoxLocal &a, const LLMatrix4 &b)  { -	return LLBBoxLocal( a.mMin * b, a.mMax * b ); +    return LLBBoxLocal( a.mMin * b, a.mMax * b );  } diff --git a/indra/llmath/llbboxlocal.h b/indra/llmath/llbboxlocal.h index defb899248..e215e55460 100644 --- a/indra/llmath/llbboxlocal.h +++ b/indra/llmath/llbboxlocal.h @@ -1,25 +1,25 @@ -/**  +/**   * @file llbboxlocal.h   * @brief General purpose bounding box class.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -34,29 +34,29 @@ class LLMatrix4;  class LLBBoxLocal  {  public: -	LLBBoxLocal() {} -	LLBBoxLocal( const LLVector3& min, const LLVector3& max ) : mMin( min ), mMax( max ) {} -	// Default copy constructor is OK. +    LLBBoxLocal() {} +    LLBBoxLocal( const LLVector3& min, const LLVector3& max ) : mMin( min ), mMax( max ) {} +    // Default copy constructor is OK. -	const LLVector3&	getMin() const					{ return mMin; } -	void				setMin( const LLVector3& min )	{ mMin = min; } +    const LLVector3&    getMin() const                  { return mMin; } +    void                setMin( const LLVector3& min )  { mMin = min; } -	const LLVector3&	getMax() const					{ return mMax; } -	void				setMax( const LLVector3& max )	{ mMax = max; } +    const LLVector3&    getMax() const                  { return mMax; } +    void                setMax( const LLVector3& max )  { mMax = max; } -	LLVector3			getCenter() const				{ return (mMax - mMin) * 0.5f + mMin; } -	LLVector3			getExtent() const				{ return mMax - mMin; } +    LLVector3           getCenter() const               { return (mMax - mMin) * 0.5f + mMin; } +    LLVector3           getExtent() const               { return mMax - mMin; } -	void				addPoint(const LLVector3& p); -	void				addBBox(const LLBBoxLocal& b) {	addPoint( b.mMin );	addPoint( b.mMax ); } +    void                addPoint(const LLVector3& p); +    void                addBBox(const LLBBoxLocal& b) { addPoint( b.mMin ); addPoint( b.mMax ); } -	void				expand( F32 delta ); +    void                expand( F32 delta ); -	friend LLBBoxLocal operator*(const LLBBoxLocal& a, const LLMatrix4& b); +    friend LLBBoxLocal operator*(const LLBBoxLocal& a, const LLMatrix4& b);  private: -	LLVector3 mMin; -	LLVector3 mMax; +    LLVector3 mMin; +    LLVector3 mMax;  };  LLBBoxLocal operator*(const LLBBoxLocal &a, const LLMatrix4 &b); diff --git a/indra/llmath/llcalc.cpp b/indra/llmath/llcalc.cpp index edc6986cc9..e060b5df58 100644 --- a/indra/llmath/llcalc.cpp +++ b/indra/llmath/llcalc.cpp @@ -4,21 +4,21 @@   * $LicenseInfo:firstyear=2008&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2008, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @@ -71,16 +71,16 @@ LLCalc* LLCalc::sInstance = NULL;  LLCalc::LLCalc() : mLastErrorPos(0)  { -	// Init table of constants -	mConstants["PI"] = F_PI; -	mConstants["TWO_PI"] = F_TWO_PI; -	mConstants["PI_BY_TWO"] = F_PI_BY_TWO; -	mConstants["SQRT_TWO_PI"] = F_SQRT_TWO_PI; -	mConstants["SQRT2"] = F_SQRT2; -	mConstants["SQRT3"] = F_SQRT3; -	mConstants["DEG_TO_RAD"] = DEG_TO_RAD; -	mConstants["RAD_TO_DEG"] = RAD_TO_DEG; -	mConstants["GRAVITY"] = GRAVITY; +    // Init table of constants +    mConstants["PI"] = F_PI; +    mConstants["TWO_PI"] = F_TWO_PI; +    mConstants["PI_BY_TWO"] = F_PI_BY_TWO; +    mConstants["SQRT_TWO_PI"] = F_SQRT_TWO_PI; +    mConstants["SQRT2"] = F_SQRT2; +    mConstants["SQRT3"] = F_SQRT3; +    mConstants["DEG_TO_RAD"] = DEG_TO_RAD; +    mConstants["RAD_TO_DEG"] = RAD_TO_DEG; +    mConstants["GRAVITY"] = GRAVITY;  }  LLCalc::~LLCalc() @@ -90,73 +90,73 @@ LLCalc::~LLCalc()  //static  void LLCalc::cleanUp()  { -	delete sInstance; -	sInstance = NULL; +    delete sInstance; +    sInstance = NULL;  }  //static  LLCalc* LLCalc::getInstance()  { -    if (!sInstance)	sInstance = new LLCalc(); -	return sInstance; +    if (!sInstance) sInstance = new LLCalc(); +    return sInstance;  }  void LLCalc::setVar(const std::string& name, const F32& value)  { -	mVariables[name] = value; +    mVariables[name] = value;  }  void LLCalc::clearVar(const std::string& name)  { -	mVariables.erase(name); +    mVariables.erase(name);  }  void LLCalc::clearAllVariables()  { -	mVariables.clear(); +    mVariables.clear();  }  /*  void LLCalc::updateVariables(LLSD& vars)  { -	LLSD::map_iterator cIt = vars.beginMap(); -	for(; cIt != vars.endMap(); cIt++) -	{ -		setVar(cIt->first, (F32)(LLSD::Real)cIt->second); -	} +    LLSD::map_iterator cIt = vars.beginMap(); +    for(; cIt != vars.endMap(); cIt++) +    { +        setVar(cIt->first, (F32)(LLSD::Real)cIt->second); +    }  }  */  bool LLCalc::evalString(const std::string& expression, F32& result)  { -	std::string expr_upper = expression; -	LLStringUtil::toUpper(expr_upper); -	 -	LLCalcParser calc(result, &mConstants, &mVariables); - -	mLastErrorPos = 0; -	std::string::iterator start = expr_upper.begin(); - 	parse_info<std::string::iterator> info; -	 -	try -	{ -		info = parse(start, expr_upper.end(), calc, space_p); -		LL_DEBUGS() << "Math expression: " << expression << " = " << result << LL_ENDL; -	} -	catch(parser_error<std::string, std::string::iterator> &e) -	{ -		mLastErrorPos = e.where - expr_upper.begin(); -		 -		LL_INFOS() << "Calc parser exception: " << e.descriptor << " at " << mLastErrorPos << " in expression: " << expression << LL_ENDL; -		return false; -	} -	 -	if (!info.full) -	{ -		mLastErrorPos = info.stop - expr_upper.begin(); -		LL_INFOS() << "Unhandled syntax error at " << mLastErrorPos << " in expression: " << expression << LL_ENDL; -		return false; -	} -	 -	return true; +    std::string expr_upper = expression; +    LLStringUtil::toUpper(expr_upper); + +    LLCalcParser calc(result, &mConstants, &mVariables); + +    mLastErrorPos = 0; +    std::string::iterator start = expr_upper.begin(); +    parse_info<std::string::iterator> info; + +    try +    { +        info = parse(start, expr_upper.end(), calc, space_p); +        LL_DEBUGS() << "Math expression: " << expression << " = " << result << LL_ENDL; +    } +    catch(parser_error<std::string, std::string::iterator> &e) +    { +        mLastErrorPos = e.where - expr_upper.begin(); + +        LL_INFOS() << "Calc parser exception: " << e.descriptor << " at " << mLastErrorPos << " in expression: " << expression << LL_ENDL; +        return false; +    } + +    if (!info.full) +    { +        mLastErrorPos = info.stop - expr_upper.begin(); +        LL_INFOS() << "Unhandled syntax error at " << mLastErrorPos << " in expression: " << expression << LL_ENDL; +        return false; +    } + +    return true;  } diff --git a/indra/llmath/llcalc.h b/indra/llmath/llcalc.h index ceb9dce585..09672eb13b 100644 --- a/indra/llmath/llcalc.h +++ b/indra/llmath/llcalc.h @@ -4,21 +4,21 @@   * $LicenseInfo:firstyear=2008&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2008, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @@ -33,68 +33,68 @@  class LLCalc  {  public: -	LLCalc(); -	~LLCalc(); +    LLCalc(); +    ~LLCalc(); + +    // Variable name constants +    static const char* X_POS; +    static const char* Y_POS; +    static const char* Z_POS; +    static const char* X_SCALE; +    static const char* Y_SCALE; +    static const char* Z_SCALE; +    static const char* X_ROT; +    static const char* Y_ROT; +    static const char* Z_ROT; +    static const char* HOLLOW; +    static const char* CUT_BEGIN; +    static const char* CUT_END; +    static const char* PATH_BEGIN; +    static const char* PATH_END; +    static const char* TWIST_BEGIN; +    static const char* TWIST_END; +    static const char* X_SHEAR; +    static const char* Y_SHEAR; +    static const char* X_TAPER; +    static const char* Y_TAPER; +    static const char* RADIUS_OFFSET; +    static const char* REVOLUTIONS; +    static const char* SKEW; +    static const char* X_HOLE; +    static const char* Y_HOLE; +    static const char* TEX_U_SCALE; +    static const char* TEX_V_SCALE; +    static const char* TEX_U_OFFSET; +    static const char* TEX_V_OFFSET; +    static const char* TEX_ROTATION; +    static const char* TEX_TRANSPARENCY; +    static const char* TEX_GLOW; -	// Variable name constants -	static const char* X_POS; -	static const char* Y_POS; -	static const char* Z_POS; -	static const char* X_SCALE; -	static const char* Y_SCALE; -	static const char* Z_SCALE; -	static const char* X_ROT; -	static const char* Y_ROT; -	static const char* Z_ROT; -	static const char* HOLLOW; -	static const char* CUT_BEGIN; -	static const char* CUT_END; -	static const char* PATH_BEGIN; -	static const char* PATH_END; -	static const char* TWIST_BEGIN; -	static const char* TWIST_END; -	static const char* X_SHEAR; -	static const char* Y_SHEAR; -	static const char* X_TAPER; -	static const char* Y_TAPER; -	static const char* RADIUS_OFFSET; -	static const char* REVOLUTIONS; -	static const char* SKEW; -	static const char* X_HOLE; -	static const char* Y_HOLE; -	static const char* TEX_U_SCALE; -	static const char* TEX_V_SCALE; -	static const char* TEX_U_OFFSET; -	static const char* TEX_V_OFFSET; -	static const char* TEX_ROTATION; -	static const char* TEX_TRANSPARENCY; -	static const char* TEX_GLOW; +    void    setVar(const std::string& name, const F32& value); +    void    clearVar(const std::string& name); +    void    clearAllVariables(); +//  void    updateVariables(LLSD& vars); -	void	setVar(const std::string& name, const F32& value); -	void	clearVar(const std::string& name); -	void	clearAllVariables(); -//	void	updateVariables(LLSD& vars); +    bool    evalString(const std::string& expression, F32& result); +    std::string::size_type  getLastErrorPos()   { return mLastErrorPos; } -	bool	evalString(const std::string& expression, F32& result); -	std::string::size_type	getLastErrorPos()	{ return mLastErrorPos; } -	 -	static LLCalc* getInstance(); -	static void cleanUp(); +    static LLCalc* getInstance(); +    static void cleanUp(); + +    typedef std::map<std::string, F32> calc_map_t; -	typedef	std::map<std::string, F32> calc_map_t; -	  private: -	std::string::size_type	mLastErrorPos; -	 -	calc_map_t	mConstants; -	calc_map_t	mVariables; -	 -	// *TODO: Add support for storing user defined variables, and stored functions. -	//	Will need UI work, and a means to save them between sessions. -//	calc_map_t mUserVariables; -	 -	// "There shall be only one" -	static LLCalc*	sInstance; +    std::string::size_type  mLastErrorPos; + +    calc_map_t  mConstants; +    calc_map_t  mVariables; + +    // *TODO: Add support for storing user defined variables, and stored functions. +    //  Will need UI work, and a means to save them between sessions. +//  calc_map_t mUserVariables; + +    // "There shall be only one" +    static LLCalc*  sInstance;  };  #endif // LL_CALC_H diff --git a/indra/llmath/llcalcparser.cpp b/indra/llmath/llcalcparser.cpp index b4ca320659..7399c368f7 100644 --- a/indra/llmath/llcalcparser.cpp +++ b/indra/llmath/llcalcparser.cpp @@ -4,21 +4,21 @@   * $LicenseInfo:firstyear=2008&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2008, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @@ -31,33 +31,33 @@ using namespace boost::spirit::classic;  F32 LLCalcParser::lookup(const std::string::iterator& start, const std::string::iterator& end) const  { -	LLCalc::calc_map_t::iterator iter; +    LLCalc::calc_map_t::iterator iter; + +    std::string name(start, end); + +    if (mConstants) +    { +        iter = mConstants->find(name); +        if (iter != mConstants->end()) +        { +            return (*iter).second; +        } +    } +    else +    { +        // This should never happen! +        throw_(end, std::string("Missing constants table")); +    } + +    if (mVariables) +    { +        iter = mVariables->find(name); +        if (iter != mVariables->end()) +        { +            return (*iter).second; +        } +    } -	std::string name(start, end); -	 -	if (mConstants) -	{ -		iter = mConstants->find(name); -		if (iter != mConstants->end()) -		{ -			return (*iter).second; -		} -	} -	else -	{ -		// This should never happen! -		throw_(end, std::string("Missing constants table")); -	} -	 -	if (mVariables) -	{ -		iter = mVariables->find(name); -		if (iter != mVariables->end()) -		{ -			return (*iter).second; -		} -	} -	 -	throw_(end, std::string("Unknown symbol " + name)); -	return 0.f; +    throw_(end, std::string("Unknown symbol " + name)); +    return 0.f;  } diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h index dff5bf3af3..e8fdcc9ae3 100644 --- a/indra/llmath/llcalcparser.h +++ b/indra/llmath/llcalcparser.h @@ -4,21 +4,21 @@   * $LicenseInfo:firstyear=2008&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2008, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @@ -40,149 +40,149 @@ using namespace boost::spirit::classic;  struct LLCalcParser : grammar<LLCalcParser>  { -	LLCalcParser(F32& result, LLCalc::calc_map_t* constants, LLCalc::calc_map_t* vars) : -		mResult(result), mConstants(constants), mVariables(vars) {}; -	 -	struct value_closure : closure<value_closure, F32> -	{ -		member1 value; -	}; -	 -	template <typename ScannerT> -	struct definition -	{ -		// Rule declarations -		rule<ScannerT> statement, identifier; -		rule<ScannerT, value_closure::context_t> expression, term, -			power,  -			unary_expr,  -			factor,  -			unary_func,  -			binary_func, -			group; - -		// start() should return the starting symbol -		rule<ScannerT> const& start() const { return statement; } -		 -		definition(LLCalcParser const& self) -		{ -			using namespace phoenix; -			 -			assertion<std::string> assert_domain("Domain error"); -//			assertion<std::string> assert_symbol("Unknown symbol"); -			assertion<std::string> assert_syntax("Syntax error"); -			 -			identifier = -				lexeme_d[(alpha_p | '_') >> *(alnum_p | '_')] -			; -			 -			group = -				'(' >> expression[group.value = arg1] >> assert_syntax(ch_p(')')) -			; - -			unary_func = -				((str_p("SIN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_sin)(self,arg1)]) | -				 (str_p("COS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_cos)(self,arg1)]) | -				 (str_p("TAN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_tan)(self,arg1)]) | -				 (str_p("ASIN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_asin)(self,arg1)]) | -				 (str_p("ACOS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_acos)(self,arg1)]) | -				 (str_p("ATAN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_atan)(self,arg1)]) | -				 (str_p("SQRT") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_sqrt)(self,arg1)]) | -				 (str_p("LOG") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_log)(self,arg1)]) | -				 (str_p("EXP") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_exp)(self,arg1)]) | -				 (str_p("ABS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_fabs)(self,arg1)]) | -				 (str_p("FLR") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_floor)(self,arg1)]) | -				 (str_p("CEIL") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_ceil)(self,arg1)]) -				) >> assert_syntax(ch_p(')')) -			; -			 -			binary_func = -				((str_p("ATAN2") >> '(' >> expression[binary_func.value = arg1] >> ',' >> -				  expression[binary_func.value = phoenix::bind(&LLCalcParser::_atan2)(self, binary_func.value, arg1)]) | -				 (str_p("MIN") >> '(' >> expression[binary_func.value = arg1] >> ',' >>  -				  expression[binary_func.value = phoenix::bind(&LLCalcParser::_min)(self, binary_func.value, arg1)]) | -				 (str_p("MAX") >> '(' >> expression[binary_func.value = arg1] >> ',' >>  -				  expression[binary_func.value = phoenix::bind(&LLCalcParser::_max)(self, binary_func.value, arg1)]) -				) >> assert_syntax(ch_p(')')) -			; -			 -			// *TODO: Localisation of the decimal point? -			// Problem, LLLineEditor::postvalidateFloat accepts a comma when appropriate -			// for the current locale. However to do that here could clash with using -			// the comma as a separator when passing arguments to functions. -			factor = -				(ureal_p[factor.value = arg1] | -				 group[factor.value = arg1] | -				 unary_func[factor.value = arg1] | -				 binary_func[factor.value = arg1] | -				 // Lookup throws an Unknown Symbol error if it is unknown, while this works fine, -				 // would be "neater" to handle symbol lookup from here with an assertive parser. -//				 constants_p[factor.value = arg1]| -				 identifier[factor.value = phoenix::bind(&LLCalcParser::lookup)(self, arg1, arg2)] -				) >> -				// Detect and throw math errors. -				assert_domain(eps_p(phoenix::bind(&LLCalcParser::checkNaN)(self, factor.value))) -			; - -			unary_expr = -				!ch_p('+') >> factor[unary_expr.value = arg1] | -				'-' >> factor[unary_expr.value = -arg1] -			; -			 -			power = -				unary_expr[power.value = arg1] >> -				*('^' >> assert_syntax(unary_expr[power.value = phoenix::bind(&powf)(power.value, arg1)])) -			; -			 -			term = -				power[term.value = arg1] >> -				*(('*' >> assert_syntax(power[term.value *= arg1])) | -				  ('/' >> assert_syntax(power[term.value /= arg1])) | -				  ('%' >> assert_syntax(power[term.value = phoenix::bind(&fmodf)(term.value, arg1)])) -				) -			; -			 -			expression = -				assert_syntax(term[expression.value = arg1]) >> -				*(('+' >> assert_syntax(term[expression.value += arg1])) | -				  ('-' >> assert_syntax(term[expression.value -= arg1])) -				) -			; - -			statement = -				!ch_p('=') >> ( expression )[var(self.mResult) = arg1] >> (end_p) -			; -		} -	}; -	 +    LLCalcParser(F32& result, LLCalc::calc_map_t* constants, LLCalc::calc_map_t* vars) : +        mResult(result), mConstants(constants), mVariables(vars) {}; + +    struct value_closure : closure<value_closure, F32> +    { +        member1 value; +    }; + +    template <typename ScannerT> +    struct definition +    { +        // Rule declarations +        rule<ScannerT> statement, identifier; +        rule<ScannerT, value_closure::context_t> expression, term, +            power, +            unary_expr, +            factor, +            unary_func, +            binary_func, +            group; + +        // start() should return the starting symbol +        rule<ScannerT> const& start() const { return statement; } + +        definition(LLCalcParser const& self) +        { +            using namespace phoenix; + +            assertion<std::string> assert_domain("Domain error"); +//          assertion<std::string> assert_symbol("Unknown symbol"); +            assertion<std::string> assert_syntax("Syntax error"); + +            identifier = +                lexeme_d[(alpha_p | '_') >> *(alnum_p | '_')] +            ; + +            group = +                '(' >> expression[group.value = arg1] >> assert_syntax(ch_p(')')) +            ; + +            unary_func = +                ((str_p("SIN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_sin)(self,arg1)]) | +                 (str_p("COS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_cos)(self,arg1)]) | +                 (str_p("TAN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_tan)(self,arg1)]) | +                 (str_p("ASIN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_asin)(self,arg1)]) | +                 (str_p("ACOS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_acos)(self,arg1)]) | +                 (str_p("ATAN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_atan)(self,arg1)]) | +                 (str_p("SQRT") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_sqrt)(self,arg1)]) | +                 (str_p("LOG") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_log)(self,arg1)]) | +                 (str_p("EXP") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_exp)(self,arg1)]) | +                 (str_p("ABS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_fabs)(self,arg1)]) | +                 (str_p("FLR") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_floor)(self,arg1)]) | +                 (str_p("CEIL") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_ceil)(self,arg1)]) +                ) >> assert_syntax(ch_p(')')) +            ; + +            binary_func = +                ((str_p("ATAN2") >> '(' >> expression[binary_func.value = arg1] >> ',' >> +                  expression[binary_func.value = phoenix::bind(&LLCalcParser::_atan2)(self, binary_func.value, arg1)]) | +                 (str_p("MIN") >> '(' >> expression[binary_func.value = arg1] >> ',' >> +                  expression[binary_func.value = phoenix::bind(&LLCalcParser::_min)(self, binary_func.value, arg1)]) | +                 (str_p("MAX") >> '(' >> expression[binary_func.value = arg1] >> ',' >> +                  expression[binary_func.value = phoenix::bind(&LLCalcParser::_max)(self, binary_func.value, arg1)]) +                ) >> assert_syntax(ch_p(')')) +            ; + +            // *TODO: Localisation of the decimal point? +            // Problem, LLLineEditor::postvalidateFloat accepts a comma when appropriate +            // for the current locale. However to do that here could clash with using +            // the comma as a separator when passing arguments to functions. +            factor = +                (ureal_p[factor.value = arg1] | +                 group[factor.value = arg1] | +                 unary_func[factor.value = arg1] | +                 binary_func[factor.value = arg1] | +                 // Lookup throws an Unknown Symbol error if it is unknown, while this works fine, +                 // would be "neater" to handle symbol lookup from here with an assertive parser. +//               constants_p[factor.value = arg1]| +                 identifier[factor.value = phoenix::bind(&LLCalcParser::lookup)(self, arg1, arg2)] +                ) >> +                // Detect and throw math errors. +                assert_domain(eps_p(phoenix::bind(&LLCalcParser::checkNaN)(self, factor.value))) +            ; + +            unary_expr = +                !ch_p('+') >> factor[unary_expr.value = arg1] | +                '-' >> factor[unary_expr.value = -arg1] +            ; + +            power = +                unary_expr[power.value = arg1] >> +                *('^' >> assert_syntax(unary_expr[power.value = phoenix::bind(&powf)(power.value, arg1)])) +            ; + +            term = +                power[term.value = arg1] >> +                *(('*' >> assert_syntax(power[term.value *= arg1])) | +                  ('/' >> assert_syntax(power[term.value /= arg1])) | +                  ('%' >> assert_syntax(power[term.value = phoenix::bind(&fmodf)(term.value, arg1)])) +                ) +            ; + +            expression = +                assert_syntax(term[expression.value = arg1]) >> +                *(('+' >> assert_syntax(term[expression.value += arg1])) | +                  ('-' >> assert_syntax(term[expression.value -= arg1])) +                ) +            ; + +            statement = +                !ch_p('=') >> ( expression )[var(self.mResult) = arg1] >> (end_p) +            ; +        } +    }; +  private: -	// Member functions for semantic actions -	F32	lookup(const std::string::iterator&, const std::string::iterator&) const; -	F32 _min(const F32& a, const F32& b) const { return llmin(a, b); } -	F32 _max(const F32& a, const F32& b) const { return llmax(a, b); } -	 -	bool checkNaN(const F32& a) const { return !llisnan(a); } -	 -	//FIX* non ambiguous function fix making SIN() work for calc -Cryogenic Blitz -	F32 _sin(const F32& a) const { return sin(DEG_TO_RAD * a); } -	F32 _cos(const F32& a) const { return cos(DEG_TO_RAD * a); } -	F32 _tan(const F32& a) const { return tan(DEG_TO_RAD * a); } -	F32 _asin(const F32& a) const { return asin(a) * RAD_TO_DEG; } -	F32 _acos(const F32& a) const { return acos(a) * RAD_TO_DEG; } -	F32 _atan(const F32& a) const { return atan(a) * RAD_TO_DEG; } -	F32 _sqrt(const F32& a) const { return sqrt(a); } -	F32 _log(const F32& a) const { return log(a); } -	F32 _exp(const F32& a) const { return exp(a); } -	F32 _fabs(const F32& a) const { return fabs(a); } -	F32 _floor(const F32& a) const { return (F32)llfloor(a); } -	F32 _ceil(const F32& a) const { return llceil(a); } -	F32 _atan2(const F32& a,const F32& b) const { return atan2(a,b); } - -	LLCalc::calc_map_t* mConstants; -	LLCalc::calc_map_t* mVariables; -//	LLCalc::calc_map_t* mUserVariables; -	 -	F32&		mResult; +    // Member functions for semantic actions +    F32 lookup(const std::string::iterator&, const std::string::iterator&) const; +    F32 _min(const F32& a, const F32& b) const { return llmin(a, b); } +    F32 _max(const F32& a, const F32& b) const { return llmax(a, b); } + +    bool checkNaN(const F32& a) const { return !llisnan(a); } + +    //FIX* non ambiguous function fix making SIN() work for calc -Cryogenic Blitz +    F32 _sin(const F32& a) const { return sin(DEG_TO_RAD * a); } +    F32 _cos(const F32& a) const { return cos(DEG_TO_RAD * a); } +    F32 _tan(const F32& a) const { return tan(DEG_TO_RAD * a); } +    F32 _asin(const F32& a) const { return asin(a) * RAD_TO_DEG; } +    F32 _acos(const F32& a) const { return acos(a) * RAD_TO_DEG; } +    F32 _atan(const F32& a) const { return atan(a) * RAD_TO_DEG; } +    F32 _sqrt(const F32& a) const { return sqrt(a); } +    F32 _log(const F32& a) const { return log(a); } +    F32 _exp(const F32& a) const { return exp(a); } +    F32 _fabs(const F32& a) const { return fabs(a); } +    F32 _floor(const F32& a) const { return (F32)llfloor(a); } +    F32 _ceil(const F32& a) const { return llceil(a); } +    F32 _atan2(const F32& a,const F32& b) const { return atan2(a,b); } + +    LLCalc::calc_map_t* mConstants; +    LLCalc::calc_map_t* mVariables; +//  LLCalc::calc_map_t* mUserVariables; + +    F32&        mResult;  };  #endif // LL_CALCPARSER_H diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index 18d704dd0f..3daed2ac31 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file llcamera.cpp   * @brief Implementation of the LLCamera class.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -32,43 +32,43 @@  // ---------------- Constructors and destructors ----------------  LLCamera::LLCamera() : -	LLCoordFrame(), -	mView(DEFAULT_FIELD_OF_VIEW), -	mAspect(DEFAULT_ASPECT_RATIO), -	mViewHeightInPixels( -1 ),			// invalid height -	mNearPlane(DEFAULT_NEAR_PLANE), -	mFarPlane(DEFAULT_FAR_PLANE), -	mFixedDistance(-1.f), -	mPlaneCount(6), -	mFrustumCornerDist(0.f) -{ -	for (U32 i = 0; i < PLANE_MASK_NUM; i++) -	{ -		mPlaneMask[i] = PLANE_MASK_NONE; -	} - -	calculateFrustumPlanes(); -}  +    LLCoordFrame(), +    mView(DEFAULT_FIELD_OF_VIEW), +    mAspect(DEFAULT_ASPECT_RATIO), +    mViewHeightInPixels( -1 ),          // invalid height +    mNearPlane(DEFAULT_NEAR_PLANE), +    mFarPlane(DEFAULT_FAR_PLANE), +    mFixedDistance(-1.f), +    mPlaneCount(6), +    mFrustumCornerDist(0.f) +{ +    for (U32 i = 0; i < PLANE_MASK_NUM; i++) +    { +        mPlaneMask[i] = PLANE_MASK_NONE; +    } + +    calculateFrustumPlanes(); +}  LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane) : -	LLCoordFrame(), -	mViewHeightInPixels(view_height_in_pixels), -	mFixedDistance(-1.f), -	mPlaneCount(6), -	mFrustumCornerDist(0.f) -{ -	for (U32 i = 0; i < PLANE_MASK_NUM; i++) -	{ -		mPlaneMask[i] = PLANE_MASK_NONE; -	} - -	mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO); -	mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE); -	if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE; -	mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE); - -	setView(vertical_fov_rads); -}  +    LLCoordFrame(), +    mViewHeightInPixels(view_height_in_pixels), +    mFixedDistance(-1.f), +    mPlaneCount(6), +    mFrustumCornerDist(0.f) +{ +    for (U32 i = 0; i < PLANE_MASK_NUM; i++) +    { +        mPlaneMask[i] = PLANE_MASK_NONE; +    } + +    mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO); +    mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE); +    if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE; +    mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE); + +    setView(vertical_fov_rads); +}  LLCamera::~LLCamera()  { @@ -77,20 +77,20 @@ LLCamera::~LLCamera()  // ---------------- LLCamera::getFoo() member functions ---------------- -F32 LLCamera::getMinView() const  +F32 LLCamera::getMinView() const  { -	// minimum vertical fov needs to be constrained in narrow windows. -	return mAspect > 1 -		? MIN_FIELD_OF_VIEW // wide views -		: MIN_FIELD_OF_VIEW * 1/mAspect; // clamps minimum width in narrow views +    // minimum vertical fov needs to be constrained in narrow windows. +    return mAspect > 1 +        ? MIN_FIELD_OF_VIEW // wide views +        : MIN_FIELD_OF_VIEW * 1/mAspect; // clamps minimum width in narrow views  } -F32 LLCamera::getMaxView() const  +F32 LLCamera::getMaxView() const  { -	// maximum vertical fov needs to be constrained in wide windows. -	return mAspect > 1  -		? MAX_FIELD_OF_VIEW / mAspect  // clamps maximum width in wide views -		: MAX_FIELD_OF_VIEW; // narrow views +    // maximum vertical fov needs to be constrained in wide windows. +    return mAspect > 1 +        ? MAX_FIELD_OF_VIEW / mAspect  // clamps maximum width in wide views +        : MAX_FIELD_OF_VIEW; // narrow views  }  LLPlane LLCamera::getUserClipPlane() @@ -102,437 +102,437 @@ LLPlane LLCamera::getUserClipPlane()  void LLCamera::setUserClipPlane(LLPlane& plane)  { -	mPlaneCount = AGENT_PLANE_USER_CLIP_NUM; -	mAgentPlanes[AGENT_PLANE_USER_CLIP] = plane; -	mPlaneMask[AGENT_PLANE_USER_CLIP] = plane.calcPlaneMask(); +    mPlaneCount = AGENT_PLANE_USER_CLIP_NUM; +    mAgentPlanes[AGENT_PLANE_USER_CLIP] = plane; +    mPlaneMask[AGENT_PLANE_USER_CLIP] = plane.calcPlaneMask();  }  void LLCamera::disableUserClipPlane()  { -	mPlaneCount = AGENT_PLANE_NO_USER_CLIP_NUM; +    mPlaneCount = AGENT_PLANE_NO_USER_CLIP_NUM;  } -void LLCamera::setView(F32 vertical_fov_rads)  +void LLCamera::setView(F32 vertical_fov_rads)  { -	mView = llclamp(vertical_fov_rads, MIN_FIELD_OF_VIEW, MAX_FIELD_OF_VIEW); -	calculateFrustumPlanes(); +    mView = llclamp(vertical_fov_rads, MIN_FIELD_OF_VIEW, MAX_FIELD_OF_VIEW); +    calculateFrustumPlanes();  }  void LLCamera::setViewHeightInPixels(S32 height)  { -	mViewHeightInPixels = height; +    mViewHeightInPixels = height; -	// Don't really need to do this, but update the pixel meter ratio with it. -	calculateFrustumPlanes(); +    // Don't really need to do this, but update the pixel meter ratio with it. +    calculateFrustumPlanes();  } -void LLCamera::setAspect(F32 aspect_ratio)  +void LLCamera::setAspect(F32 aspect_ratio)  { -	mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO); -	calculateFrustumPlanes(); +    mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO); +    calculateFrustumPlanes();  } -void LLCamera::setNear(F32 near_plane)  +void LLCamera::setNear(F32 near_plane)  { -	mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE); -	calculateFrustumPlanes(); +    mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE); +    calculateFrustumPlanes();  } -void LLCamera::setFar(F32 far_plane)  +void LLCamera::setFar(F32 far_plane)  { -	mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE); -	calculateFrustumPlanes(); +    mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE); +    calculateFrustumPlanes();  } -// ---------------- read/write to buffer ----------------  +// ---------------- read/write to buffer ----------------  size_t LLCamera::writeFrustumToBuffer(char *buffer) const  { -	memcpy(buffer, &mView, sizeof(F32));		/* Flawfinder: ignore */		 -	buffer += sizeof(F32); -	memcpy(buffer, &mAspect, sizeof(F32));		/* Flawfinder: ignore */ -	buffer += sizeof(F32); -	memcpy(buffer, &mNearPlane, sizeof(F32));	/* Flawfinder: ignore */ -	buffer += sizeof(F32); -	memcpy(buffer, &mFarPlane, sizeof(F32));		/* Flawfinder: ignore */ -	return 4*sizeof(F32); +    memcpy(buffer, &mView, sizeof(F32));        /* Flawfinder: ignore */ +    buffer += sizeof(F32); +    memcpy(buffer, &mAspect, sizeof(F32));      /* Flawfinder: ignore */ +    buffer += sizeof(F32); +    memcpy(buffer, &mNearPlane, sizeof(F32));   /* Flawfinder: ignore */ +    buffer += sizeof(F32); +    memcpy(buffer, &mFarPlane, sizeof(F32));        /* Flawfinder: ignore */ +    return 4*sizeof(F32);  }  size_t LLCamera::readFrustumFromBuffer(const char *buffer)  { -	memcpy(&mView, buffer, sizeof(F32));		/* Flawfinder: ignore */ -	buffer += sizeof(F32); -	memcpy(&mAspect, buffer, sizeof(F32));		/* Flawfinder: ignore */ -	buffer += sizeof(F32); -	memcpy(&mNearPlane, buffer, sizeof(F32));	/* Flawfinder: ignore */ -	buffer += sizeof(F32); -	memcpy(&mFarPlane, buffer, sizeof(F32));		/* Flawfinder: ignore */ -	return 4*sizeof(F32); +    memcpy(&mView, buffer, sizeof(F32));        /* Flawfinder: ignore */ +    buffer += sizeof(F32); +    memcpy(&mAspect, buffer, sizeof(F32));      /* Flawfinder: ignore */ +    buffer += sizeof(F32); +    memcpy(&mNearPlane, buffer, sizeof(F32));   /* Flawfinder: ignore */ +    buffer += sizeof(F32); +    memcpy(&mFarPlane, buffer, sizeof(F32));        /* Flawfinder: ignore */ +    return 4*sizeof(F32);  } -// ---------------- test methods  ----------------  +// ---------------- test methods  ---------------- -static	const LLVector4a sFrustumScaler[] =  +static  const LLVector4a sFrustumScaler[] =  { -	LLVector4a(-1,-1,-1), -	LLVector4a( 1,-1,-1), -	LLVector4a(-1, 1,-1), -	LLVector4a( 1, 1,-1), -	LLVector4a(-1,-1, 1), -	LLVector4a( 1,-1, 1), -	LLVector4a(-1, 1, 1), -	LLVector4a( 1, 1, 1)		// 8 entries +    LLVector4a(-1,-1,-1), +    LLVector4a( 1,-1,-1), +    LLVector4a(-1, 1,-1), +    LLVector4a( 1, 1,-1), +    LLVector4a(-1,-1, 1), +    LLVector4a( 1,-1, 1), +    LLVector4a(-1, 1, 1), +    LLVector4a( 1, 1, 1)        // 8 entries  };  bool LLCamera::isChanged()  { -	bool changed = false; -	for (U32 i = 0; i < mPlaneCount; i++) -	{ -		U8 mask = mPlaneMask[i]; -		if (mask != 0xff && !changed) -		{ -			changed = !mAgentPlanes[i].equal(mLastAgentPlanes[i]); -		} -		mLastAgentPlanes[i].set(mAgentPlanes[i]); -	} - -	return changed; +    bool changed = false; +    for (U32 i = 0; i < mPlaneCount; i++) +    { +        U8 mask = mPlaneMask[i]; +        if (mask != 0xff && !changed) +        { +            changed = !mAgentPlanes[i].equal(mLastAgentPlanes[i]); +        } +        mLastAgentPlanes[i].set(mAgentPlanes[i]); +    } + +    return changed;  } -S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius, const LLPlane* planes)  -{ -	if(!planes) -	{ -		//use agent space -		planes = mAgentPlanes; -	} - -	U8 mask = 0; -	bool result = false; -	LLVector4a rscale, maxp, minp; -	LLSimdScalar d; -	U32 max_planes = llmin(mPlaneCount, (U32) AGENT_PLANE_USER_CLIP_NUM);		// mAgentPlanes[] size is 7 -	for (U32 i = 0; i < max_planes; i++) -	{ -		mask = mPlaneMask[i]; -		if (mask < PLANE_MASK_NUM) -		{ -			const LLPlane& p(planes[i]); -			p.getAt<3>(d); -			rscale.setMul(radius, sFrustumScaler[mask]); -			minp.setSub(center, rscale); -			d = -d; -			if (p.dot3(minp).getF32() > d)  -			{ -				return 0; -			} -			 -			if(!result) -			{ -				maxp.setAdd(center, rscale); -				result = (p.dot3(maxp).getF32() > d); -			} -		} -	} - -	return result?1:2; +S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius, const LLPlane* planes) +{ +    if(!planes) +    { +        //use agent space +        planes = mAgentPlanes; +    } + +    U8 mask = 0; +    bool result = false; +    LLVector4a rscale, maxp, minp; +    LLSimdScalar d; +    U32 max_planes = llmin(mPlaneCount, (U32) AGENT_PLANE_USER_CLIP_NUM);       // mAgentPlanes[] size is 7 +    for (U32 i = 0; i < max_planes; i++) +    { +        mask = mPlaneMask[i]; +        if (mask < PLANE_MASK_NUM) +        { +            const LLPlane& p(planes[i]); +            p.getAt<3>(d); +            rscale.setMul(radius, sFrustumScaler[mask]); +            minp.setSub(center, rscale); +            d = -d; +            if (p.dot3(minp).getF32() > d) +            { +                return 0; +            } + +            if(!result) +            { +                maxp.setAdd(center, rscale); +                result = (p.dot3(maxp).getF32() > d); +            } +        } +    } + +    return result?1:2;  }  //exactly same as the function AABBInFrustum(...)  //except uses mRegionPlanes instead of mAgentPlanes. -S32 LLCamera::AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius)  +S32 LLCamera::AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius)  { -	return AABBInFrustum(center, radius, mRegionPlanes); +    return AABBInFrustum(center, radius, mRegionPlanes);  } -S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes)  -{ -	if(!planes) -	{ -		//use agent space -		planes = mAgentPlanes; -	} - -	U8 mask = 0; -	bool result = false; -	LLVector4a rscale, maxp, minp; -	LLSimdScalar d; -	U32 max_planes = llmin(mPlaneCount, (U32) AGENT_PLANE_USER_CLIP_NUM);		// mAgentPlanes[] size is 7 -	for (U32 i = 0; i < max_planes; i++) -	{ -		mask = mPlaneMask[i]; -		if ((i != 5) && (mask < PLANE_MASK_NUM)) -		{ -			const LLPlane& p(planes[i]); -			p.getAt<3>(d); -			rscale.setMul(radius, sFrustumScaler[mask]); -			minp.setSub(center, rscale); -			d = -d; -			if (p.dot3(minp).getF32() > d)  -			{ -				return 0; -			} -			 -			if(!result) -			{ -				maxp.setAdd(center, rscale); -				result = (p.dot3(maxp).getF32() > d); -			} -		} -	} - -	return result?1:2; +S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes) +{ +    if(!planes) +    { +        //use agent space +        planes = mAgentPlanes; +    } + +    U8 mask = 0; +    bool result = false; +    LLVector4a rscale, maxp, minp; +    LLSimdScalar d; +    U32 max_planes = llmin(mPlaneCount, (U32) AGENT_PLANE_USER_CLIP_NUM);       // mAgentPlanes[] size is 7 +    for (U32 i = 0; i < max_planes; i++) +    { +        mask = mPlaneMask[i]; +        if ((i != 5) && (mask < PLANE_MASK_NUM)) +        { +            const LLPlane& p(planes[i]); +            p.getAt<3>(d); +            rscale.setMul(radius, sFrustumScaler[mask]); +            minp.setSub(center, rscale); +            d = -d; +            if (p.dot3(minp).getF32() > d) +            { +                return 0; +            } + +            if(!result) +            { +                maxp.setAdd(center, rscale); +                result = (p.dot3(maxp).getF32() > d); +            } +        } +    } + +    return result?1:2;  }  //exactly same as the function AABBInFrustumNoFarClip(...)  //except uses mRegionPlanes instead of mAgentPlanes. -S32 LLCamera::AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)  +S32 LLCamera::AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)  { -	return AABBInFrustumNoFarClip(center, radius, mRegionPlanes); +    return AABBInFrustumNoFarClip(center, radius, mRegionPlanes);  } -int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius)  +int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius)  { -	LLVector3 dist = sphere_center-mFrustCenter; -	float dsq = dist * dist; -	float rsq = mFarPlane*0.5f + radius; -	rsq *= rsq; +    LLVector3 dist = sphere_center-mFrustCenter; +    float dsq = dist * dist; +    float rsq = mFarPlane*0.5f + radius; +    rsq *= rsq; -	if (dsq < rsq)  -	{ -		return 1; -	} -	 -	return 0;	 +    if (dsq < rsq) +    { +        return 1; +    } + +    return 0;  }  // Return 1 if sphere is in frustum, 2 if fully in frustum, otherwise 0.  // NOTE: 'center' is in absolute frame. -int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) const  -{ -	// Returns 1 if sphere is in frustum, 0 if not. -	bool res = false; -	for (int i = 0; i < 6; i++) -	{ -		if (mPlaneMask[i] != PLANE_MASK_NONE) -		{ -			float d = mAgentPlanes[i].dist(sphere_center); - -			if (d > radius)  -			{ -				return 0; -			} -			res = res || (d > -radius); -		} -	} - -	return res?1:2; +int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) const +{ +    // Returns 1 if sphere is in frustum, 0 if not. +    bool res = false; +    for (int i = 0; i < 6; i++) +    { +        if (mPlaneMask[i] != PLANE_MASK_NONE) +        { +            float d = mAgentPlanes[i].dist(sphere_center); + +            if (d > radius) +            { +                return 0; +            } +            res = res || (d > -radius); +        } +    } + +    return res?1:2;  }  // return height of a sphere of given radius, located at center, in pixels  F32 LLCamera::heightInPixels(const LLVector3 ¢er, F32 radius ) const  { -	if (radius == 0.f) return 0.f; +    if (radius == 0.f) return 0.f; -	// If height initialized -	if (mViewHeightInPixels > -1) -	{ -		// Convert sphere to coord system with 0,0,0 at camera -		LLVector3 vec = center - mOrigin; +    // If height initialized +    if (mViewHeightInPixels > -1) +    { +        // Convert sphere to coord system with 0,0,0 at camera +        LLVector3 vec = center - mOrigin; -		// Compute distance to sphere -		F32 dist = vec.magVec(); +        // Compute distance to sphere +        F32 dist = vec.magVec(); -		// Calculate angle of whole object -		F32 angle = 2.0f * (F32) atan2(radius, dist); +        // Calculate angle of whole object +        F32 angle = 2.0f * (F32) atan2(radius, dist); -		// Calculate fraction of field of view -		F32 fraction_of_fov = angle / mView; +        // Calculate fraction of field of view +        F32 fraction_of_fov = angle / mView; -		// Compute number of pixels tall, based on vertical field of view -		return (fraction_of_fov * mViewHeightInPixels); -	} -	else -	{ -		// return invalid height -		return -1.0f; -	} +        // Compute number of pixels tall, based on vertical field of view +        return (fraction_of_fov * mViewHeightInPixels); +    } +    else +    { +        // return invalid height +        return -1.0f; +    }  } -// ---------------- friends and operators ----------------   +// ---------------- friends and operators ---------------- -std::ostream& operator<<(std::ostream &s, const LLCamera &C)  +std::ostream& operator<<(std::ostream &s, const LLCamera &C)  { -	s << "{ \n"; -	s << "  Center = " << C.getOrigin() << "\n"; -	s << "  AtAxis = " << C.getXAxis() << "\n"; -	s << "  LeftAxis = " << C.getYAxis() << "\n"; -	s << "  UpAxis = " << C.getZAxis() << "\n"; -	s << "  View = " << C.getView() << "\n"; -	s << "  Aspect = " << C.getAspect() << "\n"; -	s << "  NearPlane   = " << C.mNearPlane << "\n"; -	s << "  FarPlane    = " << C.mFarPlane << "\n"; -	s << "}"; -	return s; +    s << "{ \n"; +    s << "  Center = " << C.getOrigin() << "\n"; +    s << "  AtAxis = " << C.getXAxis() << "\n"; +    s << "  LeftAxis = " << C.getYAxis() << "\n"; +    s << "  UpAxis = " << C.getZAxis() << "\n"; +    s << "  View = " << C.getView() << "\n"; +    s << "  Aspect = " << C.getAspect() << "\n"; +    s << "  NearPlane   = " << C.mNearPlane << "\n"; +    s << "  FarPlane    = " << C.mFarPlane << "\n"; +    s << "}"; +    return s;  }  // ----------------  private member functions ---------------- -void LLCamera::calculateFrustumPlanes()  +void LLCamera::calculateFrustumPlanes()  { -	// The planes only change when any of the frustum descriptions change. -	// They are not affected by changes of the position of the Frustum -	// because they are known in the view frame and the position merely -	// provides information on how to get from the absolute frame to the  -	// view frame. +    // The planes only change when any of the frustum descriptions change. +    // They are not affected by changes of the position of the Frustum +    // because they are known in the view frame and the position merely +    // provides information on how to get from the absolute frame to the +    // view frame. -	F32 left,right,top,bottom; -	top = mFarPlane * (F32)tanf(0.5f * mView); -	bottom = -top; -	left = top * mAspect; -	right = -left; +    F32 left,right,top,bottom; +    top = mFarPlane * (F32)tanf(0.5f * mView); +    bottom = -top; +    left = top * mAspect; +    right = -left; -	calculateFrustumPlanes(left, right, top, bottom); +    calculateFrustumPlanes(left, right, top, bottom);  }  LLPlane planeFromPoints(LLVector3 p1, LLVector3 p2, LLVector3 p3)  { -	LLVector3 n = ((p2-p1)%(p3-p1)); -	n.normVec(); +    LLVector3 n = ((p2-p1)%(p3-p1)); +    n.normVec(); -	return LLPlane(p1, n); +    return LLPlane(p1, n);  }  void LLCamera::ignoreAgentFrustumPlane(S32 idx)  { -	if (idx < 0 || idx > (S32) mPlaneCount) -	{ -		return; -	} +    if (idx < 0 || idx > (S32) mPlaneCount) +    { +        return; +    } -	mPlaneMask[idx] = PLANE_MASK_NONE; -	mAgentPlanes[idx].clear(); +    mPlaneMask[idx] = PLANE_MASK_NONE; +    mAgentPlanes[idx].clear();  }  void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)  { -	 -	for (int i = 0; i < AGENT_FRUSTRUM_NUM; i++) -	{ -		mAgentFrustum[i] = frust[i]; -	} -	mFrustumCornerDist = (frust[5] - getOrigin()).magVec(); +    for (int i = 0; i < AGENT_FRUSTRUM_NUM; i++) +    { +        mAgentFrustum[i] = frust[i]; +    } + +    mFrustumCornerDist = (frust[5] - getOrigin()).magVec(); -	//frust contains the 8 points of the frustum, calculate 6 planes +    //frust contains the 8 points of the frustum, calculate 6 planes -	//order of planes is important, keep most likely to fail in the front of the list +    //order of planes is important, keep most likely to fail in the front of the list -	//near - frust[0], frust[1], frust[2] -	mAgentPlanes[AGENT_PLANE_NEAR] = planeFromPoints(frust[0], frust[1], frust[2]); +    //near - frust[0], frust[1], frust[2] +    mAgentPlanes[AGENT_PLANE_NEAR] = planeFromPoints(frust[0], frust[1], frust[2]); -	//far   -	mAgentPlanes[AGENT_PLANE_FAR] = planeFromPoints(frust[5], frust[4], frust[6]); +    //far +    mAgentPlanes[AGENT_PLANE_FAR] = planeFromPoints(frust[5], frust[4], frust[6]); -	//left   -	mAgentPlanes[AGENT_PLANE_LEFT] = planeFromPoints(frust[4], frust[0], frust[7]); +    //left +    mAgentPlanes[AGENT_PLANE_LEFT] = planeFromPoints(frust[4], frust[0], frust[7]); -	//right   -	mAgentPlanes[AGENT_PLANE_RIGHT] = planeFromPoints(frust[1], frust[5], frust[6]); +    //right +    mAgentPlanes[AGENT_PLANE_RIGHT] = planeFromPoints(frust[1], frust[5], frust[6]); -	//top   -	mAgentPlanes[AGENT_PLANE_TOP] = planeFromPoints(frust[3], frust[2], frust[6]); +    //top +    mAgentPlanes[AGENT_PLANE_TOP] = planeFromPoints(frust[3], frust[2], frust[6]); -	//bottom   -	mAgentPlanes[AGENT_PLANE_BOTTOM] = planeFromPoints(frust[1], frust[0], frust[4]); +    //bottom +    mAgentPlanes[AGENT_PLANE_BOTTOM] = planeFromPoints(frust[1], frust[0], frust[4]); -	//cache plane octant facing mask for use in AABBInFrustum -	for (U32 i = 0; i < mPlaneCount; i++) -	{ -		mPlaneMask[i] = mAgentPlanes[i].calcPlaneMask(); -	} +    //cache plane octant facing mask for use in AABBInFrustum +    for (U32 i = 0; i < mPlaneCount; i++) +    { +        mPlaneMask[i] = mAgentPlanes[i].calcPlaneMask(); +    }  }  //calculate regional planes from mAgentPlanes.  //vector "shift" is the vector of the region origin in the agent space. -void LLCamera::calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance)  -{ -	F32 far_w; -	{ -		LLVector3 p = getOrigin(); -		LLVector3 n(mAgentPlanes[5][0], mAgentPlanes[5][1], mAgentPlanes[5][2]); -		F32 dd = n * p; -		if(dd + mAgentPlanes[5][3] < 0) //signed distance -		{ -			far_w = -far_clip_distance - dd; -		} -		else -		{ -			far_w = far_clip_distance - dd; -		} -		far_w += n * shift; -	} - -	F32 d; -	LLVector3 n; -	for(S32 i = 0 ; i < 7; i++) -	{ -		if (mPlaneMask[i] != 0xff) -		{ -			n.setVec(mAgentPlanes[i][0], mAgentPlanes[i][1], mAgentPlanes[i][2]); - -			if(i != 5) -			{ -				d = mAgentPlanes[i][3] + n * shift; -			} -			else -			{ -				d = far_w; -			} -			mRegionPlanes[i].setVec(n, d); -		} -	} +void LLCamera::calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance) +{ +    F32 far_w; +    { +        LLVector3 p = getOrigin(); +        LLVector3 n(mAgentPlanes[5][0], mAgentPlanes[5][1], mAgentPlanes[5][2]); +        F32 dd = n * p; +        if(dd + mAgentPlanes[5][3] < 0) //signed distance +        { +            far_w = -far_clip_distance - dd; +        } +        else +        { +            far_w = far_clip_distance - dd; +        } +        far_w += n * shift; +    } + +    F32 d; +    LLVector3 n; +    for(S32 i = 0 ; i < 7; i++) +    { +        if (mPlaneMask[i] != 0xff) +        { +            n.setVec(mAgentPlanes[i][0], mAgentPlanes[i][1], mAgentPlanes[i][2]); + +            if(i != 5) +            { +                d = mAgentPlanes[i][3] + n * shift; +            } +            else +            { +                d = far_w; +            } +            mRegionPlanes[i].setVec(n, d); +        } +    }  }  void LLCamera::calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom)  { -	//calculate center and radius squared of frustum in world absolute coordinates -	static LLVector3 const X_AXIS(1.f, 0.f, 0.f); -	mFrustCenter = X_AXIS*mFarPlane*0.5f; -	mFrustCenter = transformToAbsolute(mFrustCenter); -	mFrustRadiusSquared = mFarPlane*0.5f; -	mFrustRadiusSquared *= mFrustRadiusSquared * 1.05f; //pad radius squared by 5% +    //calculate center and radius squared of frustum in world absolute coordinates +    static LLVector3 const X_AXIS(1.f, 0.f, 0.f); +    mFrustCenter = X_AXIS*mFarPlane*0.5f; +    mFrustCenter = transformToAbsolute(mFrustCenter); +    mFrustRadiusSquared = mFarPlane*0.5f; +    mFrustRadiusSquared *= mFrustRadiusSquared * 1.05f; //pad radius squared by 5%  }  // x and y are in WINDOW space, so x = Y-Axis (left/right), y= Z-Axis(Up/Down)  void LLCamera::calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2)  { -	F32 bottom, top, left, right; -	F32 view_height = (F32)tanf(0.5f * mView) * mFarPlane; -	F32 view_width = view_height * mAspect; -	 -	left = 	 x1 * -2.f * view_width; -	right =  x2 * -2.f * view_width; -	bottom = y1 * 2.f * view_height;  -	top = 	 y2 * 2.f * view_height; +    F32 bottom, top, left, right; +    F32 view_height = (F32)tanf(0.5f * mView) * mFarPlane; +    F32 view_width = view_height * mAspect; + +    left =   x1 * -2.f * view_width; +    right =  x2 * -2.f * view_width; +    bottom = y1 * 2.f * view_height; +    top =    y2 * 2.f * view_height; -	calculateFrustumPlanes(left, right, top, bottom); +    calculateFrustumPlanes(left, right, top, bottom);  } -// NOTE: this is the OpenGL matrix that will transform the default OpenGL view  +// NOTE: this is the OpenGL matrix that will transform the default OpenGL view  // (-Z=at, Y=up) to the default view of the LLCamera class (X=at, Z=up): -//  +//  // F32 cfr_transform =  {  0.f,  0.f, -1.f,  0.f,   // -Z becomes X -// 						  -1.f,  0.f,  0.f,  0.f,   // -X becomes Y -//  					   0.f,  1.f,  0.f,  0.f,   //  Y becomes Z -// 						   0.f,  0.f,  0.f,  1.f }; +//                        -1.f,  0.f,  0.f,  0.f,   // -X becomes Y +//                         0.f,  1.f,  0.f,  0.f,   //  Y becomes Z +//                         0.f,  0.f,  0.f,  1.f }; diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index c4d04f5d02..3b52810855 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -1,25 +1,25 @@ -/**  +/**   * @file llcamera.h   * @brief Header file for the LLCamera class.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -33,26 +33,26 @@  #include "llplane.h"  #include "llvector4a.h" -const F32 DEFAULT_FIELD_OF_VIEW 	= 60.f * DEG_TO_RAD; -const F32 DEFAULT_ASPECT_RATIO 		= 640.f / 480.f; -const F32 DEFAULT_NEAR_PLANE 		= 0.25f; -const F32 DEFAULT_FAR_PLANE 		= 64.f;	// far reaches across two horizontal, not diagonal, regions +const F32 DEFAULT_FIELD_OF_VIEW     = 60.f * DEG_TO_RAD; +const F32 DEFAULT_ASPECT_RATIO      = 640.f / 480.f; +const F32 DEFAULT_NEAR_PLANE        = 0.25f; +const F32 DEFAULT_FAR_PLANE         = 64.f; // far reaches across two horizontal, not diagonal, regions -const F32 MAX_ASPECT_RATIO 	= 50.0f; -const F32 MAX_NEAR_PLANE 	= 1023.9f; // Clamp the near plane just before the skybox ends -const F32 MAX_FAR_PLANE 	= 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though. -const F32 MAX_FAR_CLIP		= 512.0f; +const F32 MAX_ASPECT_RATIO  = 50.0f; +const F32 MAX_NEAR_PLANE    = 1023.9f; // Clamp the near plane just before the skybox ends +const F32 MAX_FAR_PLANE     = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though. +const F32 MAX_FAR_CLIP      = 512.0f; -const F32 MIN_ASPECT_RATIO 	= 0.02f; -const F32 MIN_NEAR_PLANE 	= 0.1f; -const F32 MIN_FAR_PLANE 	= 0.2f; +const F32 MIN_ASPECT_RATIO  = 0.02f; +const F32 MIN_NEAR_PLANE    = 0.1f; +const F32 MIN_FAR_PLANE     = 0.2f;  // Min/Max FOV values for square views. Call getMin/MaxView to get extremes based on current aspect ratio.  static const F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD;  static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;  // An LLCamera is an LLCoorFrame with a view frustum. -// This means that it has several methods for moving it around  +// This means that it has several methods for moving it around  // that are inherited from the LLCoordFrame() class :  //  // setOrigin(), setAxes() @@ -62,163 +62,163 @@ static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;  LL_ALIGN_PREFIX(16)  class LLCamera -: 	public LLCoordFrame +:   public LLCoordFrame  {  public: -	 -	LLCamera(const LLCamera& rhs) -	{ -		*this = rhs; -	} -	 -	enum { -		PLANE_LEFT = 0, -		PLANE_RIGHT = 1, -		PLANE_BOTTOM = 2, -		PLANE_TOP = 3, -		PLANE_NUM = 4, -		PLANE_MASK_NONE = 0xff		// Disable this plane -	}; -	enum { -		PLANE_LEFT_MASK = (1<<PLANE_LEFT), -		PLANE_RIGHT_MASK = (1<<PLANE_RIGHT), -		PLANE_BOTTOM_MASK = (1<<PLANE_BOTTOM), -		PLANE_TOP_MASK = (1<<PLANE_TOP), -		PLANE_ALL_MASK = 0xf, -	}; - -	enum -	{	// Indexes to mAgentPlanes[] and mPlaneMask[] -		AGENT_PLANE_LEFT = 0, -		AGENT_PLANE_RIGHT = 1, -		AGENT_PLANE_NEAR = 2, -		AGENT_PLANE_BOTTOM = 3, -		AGENT_PLANE_TOP = 4, -		AGENT_PLANE_FAR = 5, -		AGENT_PLANE_USER_CLIP = 6 -	}; -	enum -	{	// Sizes for mAgentPlanes[].  7th entry is special case for user clip -		AGENT_PLANE_NO_USER_CLIP_NUM = 6, -		AGENT_PLANE_USER_CLIP_NUM = 7, -		PLANE_MASK_NUM = 8			// 7 actually used, 8 is for alignment -	}; - -	enum -	{ -		AGENT_FRUSTRUM_NUM = 8 -	}; -	 -	enum { -		HORIZ_PLANE_LEFT = 0, -		HORIZ_PLANE_RIGHT = 1, -		HORIZ_PLANE_NUM = 2 -	}; -	enum { -		HORIZ_PLANE_LEFT_MASK = (1<<HORIZ_PLANE_LEFT), -		HORIZ_PLANE_RIGHT_MASK = (1<<HORIZ_PLANE_RIGHT), -		HORIZ_PLANE_ALL_MASK = 0x3 -	}; + +    LLCamera(const LLCamera& rhs) +    { +        *this = rhs; +    } + +    enum { +        PLANE_LEFT = 0, +        PLANE_RIGHT = 1, +        PLANE_BOTTOM = 2, +        PLANE_TOP = 3, +        PLANE_NUM = 4, +        PLANE_MASK_NONE = 0xff      // Disable this plane +    }; +    enum { +        PLANE_LEFT_MASK = (1<<PLANE_LEFT), +        PLANE_RIGHT_MASK = (1<<PLANE_RIGHT), +        PLANE_BOTTOM_MASK = (1<<PLANE_BOTTOM), +        PLANE_TOP_MASK = (1<<PLANE_TOP), +        PLANE_ALL_MASK = 0xf, +    }; + +    enum +    {   // Indexes to mAgentPlanes[] and mPlaneMask[] +        AGENT_PLANE_LEFT = 0, +        AGENT_PLANE_RIGHT = 1, +        AGENT_PLANE_NEAR = 2, +        AGENT_PLANE_BOTTOM = 3, +        AGENT_PLANE_TOP = 4, +        AGENT_PLANE_FAR = 5, +        AGENT_PLANE_USER_CLIP = 6 +    }; +    enum +    {   // Sizes for mAgentPlanes[].  7th entry is special case for user clip +        AGENT_PLANE_NO_USER_CLIP_NUM = 6, +        AGENT_PLANE_USER_CLIP_NUM = 7, +        PLANE_MASK_NUM = 8          // 7 actually used, 8 is for alignment +    }; + +    enum +    { +        AGENT_FRUSTRUM_NUM = 8 +    }; + +    enum { +        HORIZ_PLANE_LEFT = 0, +        HORIZ_PLANE_RIGHT = 1, +        HORIZ_PLANE_NUM = 2 +    }; +    enum { +        HORIZ_PLANE_LEFT_MASK = (1<<HORIZ_PLANE_LEFT), +        HORIZ_PLANE_RIGHT_MASK = (1<<HORIZ_PLANE_RIGHT), +        HORIZ_PLANE_ALL_MASK = 0x3 +    };  private: -	LL_ALIGN_16(LLPlane mAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]);  //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP -	LL_ALIGN_16(LLPlane mRegionPlanes[AGENT_PLANE_USER_CLIP_NUM]);  //frustum planes in a local region space, derived from mAgentPlanes -	LL_ALIGN_16(LLPlane mLastAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]); -	U8 mPlaneMask[PLANE_MASK_NUM];         // 8 for alignment	 -	 -	F32 mView;					// angle between top and bottom frustum planes in radians. -	F32 mAspect;				// width/height -	S32 mViewHeightInPixels;	// for ViewHeightInPixels() only -	F32 mNearPlane; -	F32 mFarPlane; -	F32 mFixedDistance;			// Always return this distance, unless < 0 -	LLVector3 mFrustCenter;		// center of frustum and radius squared for ultra-quick exclusion test -	F32 mFrustRadiusSquared; -	 -	U32 mPlaneCount;  //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in - -	LLVector3 mWorldPlanePos;		// Position of World Planes (may be offset from camera) +    LL_ALIGN_16(LLPlane mAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]);  //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP +    LL_ALIGN_16(LLPlane mRegionPlanes[AGENT_PLANE_USER_CLIP_NUM]);  //frustum planes in a local region space, derived from mAgentPlanes +    LL_ALIGN_16(LLPlane mLastAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]); +    U8 mPlaneMask[PLANE_MASK_NUM];         // 8 for alignment + +    F32 mView;                  // angle between top and bottom frustum planes in radians. +    F32 mAspect;                // width/height +    S32 mViewHeightInPixels;    // for ViewHeightInPixels() only +    F32 mNearPlane; +    F32 mFarPlane; +    F32 mFixedDistance;         // Always return this distance, unless < 0 +    LLVector3 mFrustCenter;     // center of frustum and radius squared for ultra-quick exclusion test +    F32 mFrustRadiusSquared; + +    U32 mPlaneCount;  //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in + +    LLVector3 mWorldPlanePos;       // Position of World Planes (may be offset from camera)  public: -	LLVector3 mAgentFrustum[AGENT_FRUSTRUM_NUM];  //8 corners of 6-plane frustum -	F32	mFrustumCornerDist;		//distance to corner of frustum against far clip plane -	LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx]; } +    LLVector3 mAgentFrustum[AGENT_FRUSTRUM_NUM];  //8 corners of 6-plane frustum +    F32 mFrustumCornerDist;     //distance to corner of frustum against far clip plane +    LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx]; }  public: -	LLCamera(); -	LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane); -	virtual ~LLCamera(); -	 -	bool isChanged(); //check if mAgentPlanes changed since last frame. +    LLCamera(); +    LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane); +    virtual ~LLCamera(); + +    bool isChanged(); //check if mAgentPlanes changed since last frame.      LLPlane getUserClipPlane(); -	void setUserClipPlane(LLPlane& plane); -	void disableUserClipPlane(); -	virtual void setView(F32 vertical_fov_rads); -	void setViewHeightInPixels(S32 height); -	void setAspect(F32 new_aspect); -	void setNear(F32 new_near); -	void setFar(F32 new_far); - -	F32 getView() const							{ return mView; }				// vertical FOV in radians -	S32 getViewHeightInPixels() const			{ return mViewHeightInPixels; } -	F32 getAspect() const						{ return mAspect; }				// width / height -	F32 getNear() const							{ return mNearPlane; }			// meters -	F32 getFar() const							{ return mFarPlane; }			// meters - -	// The values returned by the min/max view getters depend upon the aspect ratio -	// at the time they are called and therefore should not be cached. -	F32 getMinView() const; -	F32 getMaxView() const; -	 -	F32 getYaw() const -	{ -		return atan2f(mXAxis[VY], mXAxis[VX]); -	} -	F32 getPitch() const -	{ -		F32 xylen = sqrtf(mXAxis[VX]*mXAxis[VX] + mXAxis[VY]*mXAxis[VY]); -		return atan2f(mXAxis[VZ], xylen); -	} - -	const LLVector3& getWorldPlanePos() const		{ return mWorldPlanePos; } -	 -	// Copy mView, mAspect, mNearPlane, and mFarPlane to buffer. -	// Return number of bytes copied. -	size_t writeFrustumToBuffer(char *buffer) const; - -	// Copy mView, mAspect, mNearPlane, and mFarPlane from buffer. -	// Return number of bytes copied. -	size_t readFrustumFromBuffer(const char *buffer); -	void calcAgentFrustumPlanes(LLVector3* frust); -	void calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance); //calculate regional planes from mAgentPlanes. -	void ignoreAgentFrustumPlane(S32 idx); - -	// Returns 1 if partly in, 2 if fully in. -	// NOTE: 'center' is in absolute frame. -	S32 sphereInFrustum(const LLVector3 ¢er, const F32 radius) const; -	S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); } -	S32 sphereInFrustumFull(const LLVector3 ¢er, const F32 radius) const { return sphereInFrustum(center, radius); } -	S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL); -	S32 AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius); -	S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL); -	S32 AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius); - -	//does a quick 'n dirty sphere-sphere check -	S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius);  - -	// Returns height of object in pixels (must be height because field of view -	// is based on window height). -	F32 heightInPixels(const LLVector3 ¢er, F32 radius ) const; - -	// return the distance from pos to camera if visible (-distance if not visible) -	void setFixedDistance(F32 distance) { mFixedDistance = distance; } -	 -	friend std::ostream& operator<<(std::ostream &s, const LLCamera &C); +    void setUserClipPlane(LLPlane& plane); +    void disableUserClipPlane(); +    virtual void setView(F32 vertical_fov_rads); +    void setViewHeightInPixels(S32 height); +    void setAspect(F32 new_aspect); +    void setNear(F32 new_near); +    void setFar(F32 new_far); + +    F32 getView() const                         { return mView; }               // vertical FOV in radians +    S32 getViewHeightInPixels() const           { return mViewHeightInPixels; } +    F32 getAspect() const                       { return mAspect; }             // width / height +    F32 getNear() const                         { return mNearPlane; }          // meters +    F32 getFar() const                          { return mFarPlane; }           // meters + +    // The values returned by the min/max view getters depend upon the aspect ratio +    // at the time they are called and therefore should not be cached. +    F32 getMinView() const; +    F32 getMaxView() const; + +    F32 getYaw() const +    { +        return atan2f(mXAxis[VY], mXAxis[VX]); +    } +    F32 getPitch() const +    { +        F32 xylen = sqrtf(mXAxis[VX]*mXAxis[VX] + mXAxis[VY]*mXAxis[VY]); +        return atan2f(mXAxis[VZ], xylen); +    } + +    const LLVector3& getWorldPlanePos() const       { return mWorldPlanePos; } + +    // Copy mView, mAspect, mNearPlane, and mFarPlane to buffer. +    // Return number of bytes copied. +    size_t writeFrustumToBuffer(char *buffer) const; + +    // Copy mView, mAspect, mNearPlane, and mFarPlane from buffer. +    // Return number of bytes copied. +    size_t readFrustumFromBuffer(const char *buffer); +    void calcAgentFrustumPlanes(LLVector3* frust); +    void calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance); //calculate regional planes from mAgentPlanes. +    void ignoreAgentFrustumPlane(S32 idx); + +    // Returns 1 if partly in, 2 if fully in. +    // NOTE: 'center' is in absolute frame. +    S32 sphereInFrustum(const LLVector3 ¢er, const F32 radius) const; +    S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); } +    S32 sphereInFrustumFull(const LLVector3 ¢er, const F32 radius) const { return sphereInFrustum(center, radius); } +    S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL); +    S32 AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius); +    S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL); +    S32 AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius); + +    //does a quick 'n dirty sphere-sphere check +    S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius); + +    // Returns height of object in pixels (must be height because field of view +    // is based on window height). +    F32 heightInPixels(const LLVector3 ¢er, F32 radius ) const; + +    // return the distance from pos to camera if visible (-distance if not visible) +    void setFixedDistance(F32 distance) { mFixedDistance = distance; } + +    friend std::ostream& operator<<(std::ostream &s, const LLCamera &C);  protected: -	void calculateFrustumPlanes(); -	void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom); -	void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2); +    void calculateFrustumPlanes(); +    void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom); +    void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2);  } LL_ALIGN_POSTFIX(16); diff --git a/indra/llmath/llcoord.h b/indra/llmath/llcoord.h index 9b76268afd..120556c9fe 100644 --- a/indra/llmath/llcoord.h +++ b/indra/llmath/llcoord.h @@ -1,24 +1,24 @@ -/**  +/**   * @file llcoord.h   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -37,10 +37,10 @@ typedef LLCoord<LL_COORD_TYPE_SCREEN> LLCoordScreen;  struct LLCoordCommon  { -	LLCoordCommon(S32 x, S32 y) : mX(x), mY(y) {} -	LLCoordCommon() : mX(0), mY(0) {} -	S32 mX; -	S32 mY; +    LLCoordCommon(S32 x, S32 y) : mX(x), mY(y) {} +    LLCoordCommon() : mX(0), mY(0) {} +    S32 mX; +    S32 mY;  };  // A two-dimensional pixel value @@ -48,65 +48,65 @@ template<typename COORD_FRAME>  class LLCoord : protected COORD_FRAME  {  public: -	typedef LLCoord<COORD_FRAME> self_t; -	typename COORD_FRAME::value_t	mX; -	typename COORD_FRAME::value_t	mY; - -	LLCoord():	mX(0), mY(0) -	{} -	LLCoord(typename COORD_FRAME::value_t x, typename COORD_FRAME::value_t y): mX(x), mY(y) -	{} - -	LLCoord(const LLCoordCommon& other) -	{ -		COORD_FRAME::convertFromCommon(other); -	} - -	LLCoordCommon convert() const -	{ -		return COORD_FRAME::convertToCommon(); -	} - -	void set(typename COORD_FRAME::value_t x, typename COORD_FRAME::value_t y) { mX = x; mY = y;} -	bool operator==(const self_t& other) const { return mX == other.mX && mY == other.mY; } -	bool operator!=(const self_t& other) const { return !(*this == other); } - -	static const self_t& getTypedCoords(const COORD_FRAME& self) { return static_cast<const self_t&>(self); } -	static self_t& getTypedCoords(COORD_FRAME& self) { return static_cast<self_t&>(self); } +    typedef LLCoord<COORD_FRAME> self_t; +    typename COORD_FRAME::value_t   mX; +    typename COORD_FRAME::value_t   mY; + +    LLCoord():  mX(0), mY(0) +    {} +    LLCoord(typename COORD_FRAME::value_t x, typename COORD_FRAME::value_t y): mX(x), mY(y) +    {} + +    LLCoord(const LLCoordCommon& other) +    { +        COORD_FRAME::convertFromCommon(other); +    } + +    LLCoordCommon convert() const +    { +        return COORD_FRAME::convertToCommon(); +    } + +    void set(typename COORD_FRAME::value_t x, typename COORD_FRAME::value_t y) { mX = x; mY = y;} +    bool operator==(const self_t& other) const { return mX == other.mX && mY == other.mY; } +    bool operator!=(const self_t& other) const { return !(*this == other); } + +    static const self_t& getTypedCoords(const COORD_FRAME& self) { return static_cast<const self_t&>(self); } +    static self_t& getTypedCoords(COORD_FRAME& self) { return static_cast<self_t&>(self); }  }; -struct LL_COORD_TYPE_GL  +struct LL_COORD_TYPE_GL  { -	typedef S32 value_t; - -	LLCoordCommon convertToCommon() const -	{ -		const LLCoordGL& self = LLCoordGL::getTypedCoords(*this); -		return LLCoordCommon(self.mX, self.mY); -	} - -	void convertFromCommon(const LLCoordCommon& from) -	{ -		LLCoordGL& self = LLCoordGL::getTypedCoords(*this); -		self.mX = from.mX; -		self.mY = from.mY; -	} +    typedef S32 value_t; + +    LLCoordCommon convertToCommon() const +    { +        const LLCoordGL& self = LLCoordGL::getTypedCoords(*this); +        return LLCoordCommon(self.mX, self.mY); +    } + +    void convertFromCommon(const LLCoordCommon& from) +    { +        LLCoordGL& self = LLCoordGL::getTypedCoords(*this); +        self.mX = from.mX; +        self.mY = from.mY; +    }  }; -struct LL_COORD_TYPE_WINDOW  +struct LL_COORD_TYPE_WINDOW  { -	typedef S32 value_t; +    typedef S32 value_t; -	LLCoordCommon convertToCommon() const; -	void convertFromCommon(const LLCoordCommon& from); +    LLCoordCommon convertToCommon() const; +    void convertFromCommon(const LLCoordCommon& from);  }; -struct LL_COORD_TYPE_SCREEN  +struct LL_COORD_TYPE_SCREEN  { -	typedef S32 value_t; +    typedef S32 value_t; -	LLCoordCommon convertToCommon() const; -	void convertFromCommon(const LLCoordCommon& from); +    LLCoordCommon convertToCommon() const; +    void convertFromCommon(const LLCoordCommon& from);  };  #endif diff --git a/indra/llmath/llcoordframe.cpp b/indra/llmath/llcoordframe.cpp index b25fd948f5..4d6276b2cd 100644 --- a/indra/llmath/llcoordframe.cpp +++ b/indra/llmath/llcoordframe.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file llcoordframe.cpp   * @brief LLCoordFrame class implementation.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -49,168 +49,168 @@      }  #ifndef X_AXIS -	#define X_AXIS 1.0f,0.0f,0.0f -	#define Y_AXIS 0.0f,1.0f,0.0f -	#define Z_AXIS 0.0f,0.0f,1.0f +    #define X_AXIS 1.0f,0.0f,0.0f +    #define Y_AXIS 0.0f,1.0f,0.0f +    #define Z_AXIS 0.0f,0.0f,1.0f  #endif  // Constructors  LLCoordFrame::LLCoordFrame() : -	mOrigin(0.f, 0.f, 0.f), -	mXAxis(X_AXIS), -	mYAxis(Y_AXIS), -	mZAxis(Z_AXIS) +    mOrigin(0.f, 0.f, 0.f), +    mXAxis(X_AXIS), +    mYAxis(Y_AXIS), +    mZAxis(Z_AXIS)  {  }  LLCoordFrame::LLCoordFrame(const LLVector3 &origin) : -	mOrigin(origin),  -	mXAxis(X_AXIS), -	mYAxis(Y_AXIS), -	mZAxis(Z_AXIS) +    mOrigin(origin), +    mXAxis(X_AXIS), +    mYAxis(Y_AXIS), +    mZAxis(Z_AXIS)  {      CHECK_FINITE(mOrigin);  }  LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLVector3 &direction) : -	mOrigin(origin) +    mOrigin(origin)  { -	lookDir(direction); -	 +    lookDir(direction); +      CHECK_FINITE_OBJ();  }  LLCoordFrame::LLCoordFrame(const LLVector3 &x_axis, -						   const LLVector3 &y_axis, -						   const LLVector3 &z_axis) :  -	mOrigin(0.f, 0.f, 0.f),  -	mXAxis(x_axis),  -	mYAxis(y_axis),  -	mZAxis(z_axis) +                           const LLVector3 &y_axis, +                           const LLVector3 &z_axis) : +    mOrigin(0.f, 0.f, 0.f), +    mXAxis(x_axis), +    mYAxis(y_axis), +    mZAxis(z_axis)  { -	CHECK_FINITE_OBJ(); +    CHECK_FINITE_OBJ();  }  LLCoordFrame::LLCoordFrame(const LLVector3 &origin, -						   const LLVector3 &x_axis, -						   const LLVector3 &y_axis, -						   const LLVector3 &z_axis) :  -	mOrigin(origin),  -	mXAxis(x_axis),  -	mYAxis(y_axis),  -	mZAxis(z_axis) +                           const LLVector3 &x_axis, +                           const LLVector3 &y_axis, +                           const LLVector3 &z_axis) : +    mOrigin(origin), +    mXAxis(x_axis), +    mYAxis(y_axis), +    mZAxis(z_axis)  { -	CHECK_FINITE_OBJ(); +    CHECK_FINITE_OBJ();  } -LLCoordFrame::LLCoordFrame(const LLVector3 &origin,  -						   const LLMatrix3 &rotation) : -	mOrigin(origin), -	mXAxis(rotation.mMatrix[VX]), -	mYAxis(rotation.mMatrix[VY]), -	mZAxis(rotation.mMatrix[VZ]) +LLCoordFrame::LLCoordFrame(const LLVector3 &origin, +                           const LLMatrix3 &rotation) : +    mOrigin(origin), +    mXAxis(rotation.mMatrix[VX]), +    mYAxis(rotation.mMatrix[VY]), +    mZAxis(rotation.mMatrix[VZ])  { -	CHECK_FINITE_OBJ(); +    CHECK_FINITE_OBJ();  }  LLCoordFrame::LLCoordFrame(const LLQuaternion &q) : -	mOrigin(0.f, 0.f, 0.f) +    mOrigin(0.f, 0.f, 0.f)  { -	LLMatrix3 rotation_matrix(q); -	mXAxis.setVec(rotation_matrix.mMatrix[VX]); -	mYAxis.setVec(rotation_matrix.mMatrix[VY]); -	mZAxis.setVec(rotation_matrix.mMatrix[VZ]); +    LLMatrix3 rotation_matrix(q); +    mXAxis.setVec(rotation_matrix.mMatrix[VX]); +    mYAxis.setVec(rotation_matrix.mMatrix[VY]); +    mZAxis.setVec(rotation_matrix.mMatrix[VZ]); -	CHECK_FINITE_OBJ(); +    CHECK_FINITE_OBJ();  }  LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLQuaternion &q) : -	mOrigin(origin) +    mOrigin(origin)  { -	LLMatrix3 rotation_matrix(q); -	mXAxis.setVec(rotation_matrix.mMatrix[VX]); -	mYAxis.setVec(rotation_matrix.mMatrix[VY]); -	mZAxis.setVec(rotation_matrix.mMatrix[VZ]); +    LLMatrix3 rotation_matrix(q); +    mXAxis.setVec(rotation_matrix.mMatrix[VX]); +    mYAxis.setVec(rotation_matrix.mMatrix[VY]); +    mZAxis.setVec(rotation_matrix.mMatrix[VZ]); -	CHECK_FINITE_OBJ(); +    CHECK_FINITE_OBJ();  }  LLCoordFrame::LLCoordFrame(const LLMatrix4 &mat) : -	mOrigin(mat.mMatrix[VW]), -	mXAxis(mat.mMatrix[VX]), -	mYAxis(mat.mMatrix[VY]), -	mZAxis(mat.mMatrix[VZ]) +    mOrigin(mat.mMatrix[VW]), +    mXAxis(mat.mMatrix[VX]), +    mYAxis(mat.mMatrix[VY]), +    mZAxis(mat.mMatrix[VZ])  { -	CHECK_FINITE_OBJ(); +    CHECK_FINITE_OBJ();  }  // The folowing two constructors are dangerous due to implicit casting and have been disabled - SJB  /*  LLCoordFrame::LLCoordFrame(const F32 *origin, const F32 *rotation) : -	mOrigin(origin), -	mXAxis(rotation+3*VX), -	mYAxis(rotation+3*VY), -	mZAxis(rotation+3*VZ) +    mOrigin(origin), +    mXAxis(rotation+3*VX), +    mYAxis(rotation+3*VY), +    mZAxis(rotation+3*VZ)  { -	CHECK_FINITE_OBJ(); +    CHECK_FINITE_OBJ();  }  */  /*  LLCoordFrame::LLCoordFrame(const F32 *origin_and_rotation) : -	mOrigin(origin_and_rotation), -	mXAxis(origin_and_rotation + 3*(VX+1)), -	mYAxis(origin_and_rotation + 3*(VY+1)), -	mZAxis(origin_and_rotation + 3*(VZ+1)) +    mOrigin(origin_and_rotation), +    mXAxis(origin_and_rotation + 3*(VX+1)), +    mYAxis(origin_and_rotation + 3*(VY+1)), +    mZAxis(origin_and_rotation + 3*(VZ+1))  { -	CHECK_FINITE_OBJ(); +    CHECK_FINITE_OBJ();  }  */ -void LLCoordFrame::reset()  +void LLCoordFrame::reset()  { -	mOrigin.setVec(0.0f, 0.0f, 0.0f); -	resetAxes(); +    mOrigin.setVec(0.0f, 0.0f, 0.0f); +    resetAxes();  }  void LLCoordFrame::resetAxes()  { -	mXAxis.setVec(1.0f, 0.0f, 0.0f); -	mYAxis.setVec(0.0f, 1.0f, 0.0f); -	mZAxis.setVec(0.0f, 0.0f, 1.0f); +    mXAxis.setVec(1.0f, 0.0f, 0.0f); +    mYAxis.setVec(0.0f, 1.0f, 0.0f); +    mZAxis.setVec(0.0f, 0.0f, 1.0f);  }  // setOrigin() member functions set mOrigin -void LLCoordFrame::setOrigin(F32 x, F32 y, F32 z)  +void LLCoordFrame::setOrigin(F32 x, F32 y, F32 z)  { -	mOrigin.setVec(x, y, z);  +    mOrigin.setVec(x, y, z);      CHECK_FINITE(mOrigin);  }  void LLCoordFrame::setOrigin(const LLVector3 &new_origin)  { -	mOrigin = new_origin;  -	CHECK_FINITE(mOrigin); +    mOrigin = new_origin; +    CHECK_FINITE(mOrigin);  }  void LLCoordFrame::setOrigin(const F32 *origin)  { -	mOrigin.mV[VX] = *(origin + VX); -	mOrigin.mV[VY] = *(origin + VY); -	mOrigin.mV[VZ] = *(origin + VZ); +    mOrigin.mV[VX] = *(origin + VX); +    mOrigin.mV[VY] = *(origin + VY); +    mOrigin.mV[VZ] = *(origin + VZ);      CHECK_FINITE(mOrigin);  }  void LLCoordFrame::setOrigin(const LLCoordFrame &frame)  { -	mOrigin = frame.getOrigin(); +    mOrigin = frame.getOrigin();      CHECK_FINITE(mOrigin);  } @@ -218,79 +218,79 @@ void LLCoordFrame::setOrigin(const LLCoordFrame &frame)  // the arguments are orthogonal and normalized.  void LLCoordFrame::setAxes(const LLVector3 &x_axis, -						  const LLVector3 &y_axis, -						  const LLVector3 &z_axis) +                          const LLVector3 &y_axis, +                          const LLVector3 &z_axis)  { -	mXAxis = x_axis; -	mYAxis = y_axis; -	mZAxis = z_axis; -	CHECK_FINITE_OBJ(); +    mXAxis = x_axis; +    mYAxis = y_axis; +    mZAxis = z_axis; +    CHECK_FINITE_OBJ();  }  void LLCoordFrame::setAxes(const LLMatrix3 &rotation_matrix)  { -	mXAxis.setVec(rotation_matrix.mMatrix[VX]); -	mYAxis.setVec(rotation_matrix.mMatrix[VY]); -	mZAxis.setVec(rotation_matrix.mMatrix[VZ]); -	CHECK_FINITE_OBJ(); +    mXAxis.setVec(rotation_matrix.mMatrix[VX]); +    mYAxis.setVec(rotation_matrix.mMatrix[VY]); +    mZAxis.setVec(rotation_matrix.mMatrix[VZ]); +    CHECK_FINITE_OBJ();  }  void LLCoordFrame::setAxes(const LLQuaternion &q )  { -	LLMatrix3 rotation_matrix(q); -	setAxes(rotation_matrix); -	CHECK_FINITE_OBJ(); +    LLMatrix3 rotation_matrix(q); +    setAxes(rotation_matrix); +    CHECK_FINITE_OBJ();  } -void LLCoordFrame::setAxes(  const F32 *rotation_matrix )  +void LLCoordFrame::setAxes(  const F32 *rotation_matrix )  { -	mXAxis.mV[VX] = *(rotation_matrix + 3*VX + VX); -	mXAxis.mV[VY] = *(rotation_matrix + 3*VX + VY); -	mXAxis.mV[VZ] = *(rotation_matrix + 3*VX + VZ); -	mYAxis.mV[VX] = *(rotation_matrix + 3*VY + VX); -	mYAxis.mV[VY] = *(rotation_matrix + 3*VY + VY); -	mYAxis.mV[VZ] = *(rotation_matrix + 3*VY + VZ); -	mZAxis.mV[VX] = *(rotation_matrix + 3*VZ + VX); -	mZAxis.mV[VY] = *(rotation_matrix + 3*VZ + VY); -	mZAxis.mV[VZ] = *(rotation_matrix + 3*VZ + VZ); +    mXAxis.mV[VX] = *(rotation_matrix + 3*VX + VX); +    mXAxis.mV[VY] = *(rotation_matrix + 3*VX + VY); +    mXAxis.mV[VZ] = *(rotation_matrix + 3*VX + VZ); +    mYAxis.mV[VX] = *(rotation_matrix + 3*VY + VX); +    mYAxis.mV[VY] = *(rotation_matrix + 3*VY + VY); +    mYAxis.mV[VZ] = *(rotation_matrix + 3*VY + VZ); +    mZAxis.mV[VX] = *(rotation_matrix + 3*VZ + VX); +    mZAxis.mV[VY] = *(rotation_matrix + 3*VZ + VY); +    mZAxis.mV[VZ] = *(rotation_matrix + 3*VZ + VZ); -	CHECK_FINITE_OBJ(); +    CHECK_FINITE_OBJ();  }  void LLCoordFrame::setAxes(const LLCoordFrame &frame)  { -	mXAxis = frame.getXAxis(); -	mYAxis = frame.getYAxis(); -	mZAxis = frame.getZAxis(); -	CHECK_FINITE_OBJ(); +    mXAxis = frame.getXAxis(); +    mYAxis = frame.getYAxis(); +    mZAxis = frame.getZAxis(); +    CHECK_FINITE_OBJ();  }  // translate() member functions move mOrigin to a relative position  void LLCoordFrame::translate(F32 x, F32 y, F32 z)  { -	mOrigin.mV[VX] += x; -	mOrigin.mV[VY] += y; -	mOrigin.mV[VZ] += z; +    mOrigin.mV[VX] += x; +    mOrigin.mV[VY] += y; +    mOrigin.mV[VZ] += z;      CHECK_FINITE(mOrigin);  }  void LLCoordFrame::translate(const LLVector3 &v)  { -	mOrigin += v; +    mOrigin += v;      CHECK_FINITE(mOrigin);  }  void LLCoordFrame::translate(const F32 *origin)  { -	mOrigin.mV[VX] += *(origin + VX); -	mOrigin.mV[VY] += *(origin + VY); -	mOrigin.mV[VZ] += *(origin + VZ); -	CHECK_FINITE(mOrigin); +    mOrigin.mV[VX] += *(origin + VX); +    mOrigin.mV[VY] += *(origin + VY); +    mOrigin.mV[VZ] += *(origin + VZ); +    CHECK_FINITE(mOrigin);  } @@ -298,58 +298,58 @@ void LLCoordFrame::translate(const F32 *origin)  void LLCoordFrame::rotate(F32 angle, F32 x, F32 y, F32 z)  { -	LLQuaternion q(angle, LLVector3(x,y,z)); -	rotate(q); +    LLQuaternion q(angle, LLVector3(x,y,z)); +    rotate(q);      CHECK_FINITE_OBJ();  }  void LLCoordFrame::rotate(F32 angle, const LLVector3 &rotation_axis)  { -	LLQuaternion q(angle, rotation_axis); -	rotate(q); +    LLQuaternion q(angle, rotation_axis); +    rotate(q);      CHECK_FINITE_OBJ();  }  void LLCoordFrame::rotate(const LLQuaternion &q)  { -	LLMatrix3 rotation_matrix(q); -	rotate(rotation_matrix); +    LLMatrix3 rotation_matrix(q); +    rotate(rotation_matrix);      CHECK_FINITE_OBJ();  }  void LLCoordFrame::rotate(const LLMatrix3 &rotation_matrix)  { -	mXAxis.rotVec(rotation_matrix); -	mYAxis.rotVec(rotation_matrix); -	orthonormalize(); +    mXAxis.rotVec(rotation_matrix); +    mYAxis.rotVec(rotation_matrix); +    orthonormalize();      CHECK_FINITE_OBJ();  }  void LLCoordFrame::roll(F32 angle)  { -	LLQuaternion q(angle, mXAxis); -	LLMatrix3 rotation_matrix(q); -	rotate(rotation_matrix); +    LLQuaternion q(angle, mXAxis); +    LLMatrix3 rotation_matrix(q); +    rotate(rotation_matrix);      CHECK_FINITE_OBJ();  }  void LLCoordFrame::pitch(F32 angle)  { -	LLQuaternion q(angle, mYAxis); -	LLMatrix3 rotation_matrix(q); -	rotate(rotation_matrix); -	CHECK_FINITE_OBJ(); +    LLQuaternion q(angle, mYAxis); +    LLMatrix3 rotation_matrix(q); +    rotate(rotation_matrix); +    CHECK_FINITE_OBJ();  }  void LLCoordFrame::yaw(F32 angle)  { -	LLQuaternion q(angle, mZAxis); -	LLMatrix3 rotation_matrix(q); -	rotate(rotation_matrix); +    LLQuaternion q(angle, mZAxis); +    LLMatrix3 rotation_matrix(q); +    rotate(rotation_matrix);      CHECK_FINITE_OBJ();  } @@ -358,61 +358,61 @@ void LLCoordFrame::yaw(F32 angle)  LLQuaternion LLCoordFrame::getQuaternion() const  { -	LLQuaternion quat(mXAxis, mYAxis, mZAxis); -	return quat; +    LLQuaternion quat(mXAxis, mYAxis, mZAxis); +    return quat;  }  void LLCoordFrame::getMatrixToLocal(LLMatrix4& mat) const  { -	mat.setFwdCol(mXAxis); -	mat.setLeftCol(mYAxis); -	mat.setUpCol(mZAxis); +    mat.setFwdCol(mXAxis); +    mat.setLeftCol(mYAxis); +    mat.setUpCol(mZAxis); -	mat.mMatrix[3][0] = -(mOrigin * LLVector3(mat.mMatrix[0][0], mat.mMatrix[1][0], mat.mMatrix[2][0])); -	mat.mMatrix[3][1] = -(mOrigin * LLVector3(mat.mMatrix[0][1], mat.mMatrix[1][1], mat.mMatrix[2][1])); -	mat.mMatrix[3][2] = -(mOrigin * LLVector3(mat.mMatrix[0][2], mat.mMatrix[1][2], mat.mMatrix[2][2])); +    mat.mMatrix[3][0] = -(mOrigin * LLVector3(mat.mMatrix[0][0], mat.mMatrix[1][0], mat.mMatrix[2][0])); +    mat.mMatrix[3][1] = -(mOrigin * LLVector3(mat.mMatrix[0][1], mat.mMatrix[1][1], mat.mMatrix[2][1])); +    mat.mMatrix[3][2] = -(mOrigin * LLVector3(mat.mMatrix[0][2], mat.mMatrix[1][2], mat.mMatrix[2][2]));  }  void LLCoordFrame::getRotMatrixToParent(LLMatrix4& mat) const  { -	// Note: moves into CFR -	mat.setFwdRow(	-mYAxis ); -	mat.setLeftRow(	 mZAxis ); -	mat.setUpRow(	-mXAxis ); +    // Note: moves into CFR +    mat.setFwdRow(  -mYAxis ); +    mat.setLeftRow(  mZAxis ); +    mat.setUpRow(   -mXAxis );  }  size_t LLCoordFrame::writeOrientation(char *buffer) const  { -	memcpy(buffer, mOrigin.mV, 3*sizeof(F32)); /*Flawfinder: ignore */ -	buffer += 3*sizeof(F32); -	memcpy(buffer, mXAxis.mV, 3*sizeof(F32)); /*Flawfinder: ignore */ -	buffer += 3*sizeof(F32); -	memcpy(buffer, mYAxis.mV, 3*sizeof(F32));/*Flawfinder: ignore */ -	buffer += 3*sizeof(F32); -	memcpy(buffer, mZAxis.mV, 3*sizeof(F32));	/*Flawfinder: ignore */ -	return 12*sizeof(F32); +    memcpy(buffer, mOrigin.mV, 3*sizeof(F32)); /*Flawfinder: ignore */ +    buffer += 3*sizeof(F32); +    memcpy(buffer, mXAxis.mV, 3*sizeof(F32)); /*Flawfinder: ignore */ +    buffer += 3*sizeof(F32); +    memcpy(buffer, mYAxis.mV, 3*sizeof(F32));/*Flawfinder: ignore */ +    buffer += 3*sizeof(F32); +    memcpy(buffer, mZAxis.mV, 3*sizeof(F32));   /*Flawfinder: ignore */ +    return 12*sizeof(F32);  }  size_t LLCoordFrame::readOrientation(const char *buffer)  { -	memcpy(mOrigin.mV, buffer, 3*sizeof(F32));	/*Flawfinder: ignore */ -	buffer += 3*sizeof(F32); -	memcpy(mXAxis.mV, buffer, 3*sizeof(F32));	/*Flawfinder: ignore */ -	buffer += 3*sizeof(F32); -	memcpy(mYAxis.mV, buffer, 3*sizeof(F32));	/*Flawfinder: ignore */ -	buffer += 3*sizeof(F32); -	memcpy(mZAxis.mV, buffer, 3*sizeof(F32));	/*Flawfinder: ignore */ - -	if( !isFinite() ) -	{ -		reset(); -		LL_WARNS() << "Non Finite in LLCoordFrame::readOrientation()" << LL_ENDL; -	} +    memcpy(mOrigin.mV, buffer, 3*sizeof(F32));  /*Flawfinder: ignore */ +    buffer += 3*sizeof(F32); +    memcpy(mXAxis.mV, buffer, 3*sizeof(F32));   /*Flawfinder: ignore */ +    buffer += 3*sizeof(F32); +    memcpy(mYAxis.mV, buffer, 3*sizeof(F32));   /*Flawfinder: ignore */ +    buffer += 3*sizeof(F32); +    memcpy(mZAxis.mV, buffer, 3*sizeof(F32));   /*Flawfinder: ignore */ + +    if( !isFinite() ) +    { +        reset(); +        LL_WARNS() << "Non Finite in LLCoordFrame::readOrientation()" << LL_ENDL; +    } -	return 12*sizeof(F32); +    return 12*sizeof(F32);  } @@ -420,107 +420,107 @@ size_t LLCoordFrame::readOrientation(const char *buffer)  LLVector3 LLCoordFrame::rotateToLocal(const LLVector3 &absolute_vector) const  { -	LLVector3 local_vector(mXAxis * absolute_vector, -						   mYAxis * absolute_vector, -						   mZAxis * absolute_vector); -	return local_vector; +    LLVector3 local_vector(mXAxis * absolute_vector, +                           mYAxis * absolute_vector, +                           mZAxis * absolute_vector); +    return local_vector;  }  LLVector4 LLCoordFrame::rotateToLocal(const LLVector4 &absolute_vector) const  { -	LLVector4 local_vector; -	local_vector.mV[VX] = mXAxis.mV[VX] * absolute_vector.mV[VX] + -						  mXAxis.mV[VY] * absolute_vector.mV[VY] + -						  mXAxis.mV[VZ] * absolute_vector.mV[VZ]; -	local_vector.mV[VY] = mYAxis.mV[VX] * absolute_vector.mV[VX] + -						  mYAxis.mV[VY] * absolute_vector.mV[VY] + -						  mYAxis.mV[VZ] * absolute_vector.mV[VZ]; -	local_vector.mV[VZ] = mZAxis.mV[VX] * absolute_vector.mV[VX] + -						  mZAxis.mV[VY] * absolute_vector.mV[VY] + -						  mZAxis.mV[VZ] * absolute_vector.mV[VZ]; -	local_vector.mV[VW] = absolute_vector.mV[VW]; -	return local_vector; +    LLVector4 local_vector; +    local_vector.mV[VX] = mXAxis.mV[VX] * absolute_vector.mV[VX] + +                          mXAxis.mV[VY] * absolute_vector.mV[VY] + +                          mXAxis.mV[VZ] * absolute_vector.mV[VZ]; +    local_vector.mV[VY] = mYAxis.mV[VX] * absolute_vector.mV[VX] + +                          mYAxis.mV[VY] * absolute_vector.mV[VY] + +                          mYAxis.mV[VZ] * absolute_vector.mV[VZ]; +    local_vector.mV[VZ] = mZAxis.mV[VX] * absolute_vector.mV[VX] + +                          mZAxis.mV[VY] * absolute_vector.mV[VY] + +                          mZAxis.mV[VZ] * absolute_vector.mV[VZ]; +    local_vector.mV[VW] = absolute_vector.mV[VW]; +    return local_vector;  }  LLVector3 LLCoordFrame::rotateToAbsolute(const LLVector3 &local_vector) const  { -	LLVector3 absolute_vector; -	absolute_vector.mV[VX] = mXAxis.mV[VX] * local_vector.mV[VX] + -							 mYAxis.mV[VX] * local_vector.mV[VY] + -							 mZAxis.mV[VX] * local_vector.mV[VZ]; -	absolute_vector.mV[VY] = mXAxis.mV[VY] * local_vector.mV[VX] + -							 mYAxis.mV[VY] * local_vector.mV[VY] + -							 mZAxis.mV[VY] * local_vector.mV[VZ]; -	absolute_vector.mV[VZ] = mXAxis.mV[VZ] * local_vector.mV[VX] + -							 mYAxis.mV[VZ] * local_vector.mV[VY] + -							 mZAxis.mV[VZ] * local_vector.mV[VZ]; -	return absolute_vector; +    LLVector3 absolute_vector; +    absolute_vector.mV[VX] = mXAxis.mV[VX] * local_vector.mV[VX] + +                             mYAxis.mV[VX] * local_vector.mV[VY] + +                             mZAxis.mV[VX] * local_vector.mV[VZ]; +    absolute_vector.mV[VY] = mXAxis.mV[VY] * local_vector.mV[VX] + +                             mYAxis.mV[VY] * local_vector.mV[VY] + +                             mZAxis.mV[VY] * local_vector.mV[VZ]; +    absolute_vector.mV[VZ] = mXAxis.mV[VZ] * local_vector.mV[VX] + +                             mYAxis.mV[VZ] * local_vector.mV[VY] + +                             mZAxis.mV[VZ] * local_vector.mV[VZ]; +    return absolute_vector;  }  LLVector4 LLCoordFrame::rotateToAbsolute(const LLVector4 &local_vector) const  { -	LLVector4 absolute_vector; -	absolute_vector.mV[VX] = mXAxis.mV[VX] * local_vector.mV[VX] + -							 mYAxis.mV[VX] * local_vector.mV[VY] + -							 mZAxis.mV[VX] * local_vector.mV[VZ]; -	absolute_vector.mV[VY] = mXAxis.mV[VY] * local_vector.mV[VX] + -							 mYAxis.mV[VY] * local_vector.mV[VY] + -							 mZAxis.mV[VY] * local_vector.mV[VZ]; -	absolute_vector.mV[VZ] = mXAxis.mV[VZ] * local_vector.mV[VX] + -							 mYAxis.mV[VZ] * local_vector.mV[VY] + -							 mZAxis.mV[VZ] * local_vector.mV[VZ]; -	absolute_vector.mV[VW] = local_vector[VW]; -	return absolute_vector; +    LLVector4 absolute_vector; +    absolute_vector.mV[VX] = mXAxis.mV[VX] * local_vector.mV[VX] + +                             mYAxis.mV[VX] * local_vector.mV[VY] + +                             mZAxis.mV[VX] * local_vector.mV[VZ]; +    absolute_vector.mV[VY] = mXAxis.mV[VY] * local_vector.mV[VX] + +                             mYAxis.mV[VY] * local_vector.mV[VY] + +                             mZAxis.mV[VY] * local_vector.mV[VZ]; +    absolute_vector.mV[VZ] = mXAxis.mV[VZ] * local_vector.mV[VX] + +                             mYAxis.mV[VZ] * local_vector.mV[VY] + +                             mZAxis.mV[VZ] * local_vector.mV[VZ]; +    absolute_vector.mV[VW] = local_vector[VW]; +    return absolute_vector;  }  void LLCoordFrame::orthonormalize()  // Makes sure the axes are orthogonal and normalized.  { -	mXAxis.normVec();						// X is renormalized -	mYAxis -= mXAxis * (mXAxis * mYAxis);	// Y remains in X-Y plane -	mYAxis.normVec();						// Y is normalized -	mZAxis = mXAxis % mYAxis;				// Z = X cross Y +    mXAxis.normVec();                       // X is renormalized +    mYAxis -= mXAxis * (mXAxis * mYAxis);   // Y remains in X-Y plane +    mYAxis.normVec();                       // Y is normalized +    mZAxis = mXAxis % mYAxis;               // Z = X cross Y  }  LLVector3 LLCoordFrame::transformToLocal(const LLVector3 &absolute_vector) const  { -	return rotateToLocal(absolute_vector - mOrigin); +    return rotateToLocal(absolute_vector - mOrigin);  }  LLVector4 LLCoordFrame::transformToLocal(const LLVector4 &absolute_vector) const  { -	LLVector4 local_vector(absolute_vector); -	local_vector.mV[VX] -= mOrigin.mV[VX]; -	local_vector.mV[VY] -= mOrigin.mV[VY]; -	local_vector.mV[VZ] -= mOrigin.mV[VZ]; -	return rotateToLocal(local_vector); +    LLVector4 local_vector(absolute_vector); +    local_vector.mV[VX] -= mOrigin.mV[VX]; +    local_vector.mV[VY] -= mOrigin.mV[VY]; +    local_vector.mV[VZ] -= mOrigin.mV[VZ]; +    return rotateToLocal(local_vector);  }  LLVector3 LLCoordFrame::transformToAbsolute(const LLVector3 &local_vector) const  { -	return (rotateToAbsolute(local_vector) + mOrigin); +    return (rotateToAbsolute(local_vector) + mOrigin);  }  LLVector4 LLCoordFrame::transformToAbsolute(const LLVector4 &local_vector) const  { -	LLVector4 absolute_vector; -	absolute_vector = rotateToAbsolute(local_vector); -	absolute_vector.mV[VX] += mOrigin.mV[VX]; -	absolute_vector.mV[VY] += mOrigin.mV[VY]; -	absolute_vector.mV[VZ] += mOrigin.mV[VZ]; -	return absolute_vector; +    LLVector4 absolute_vector; +    absolute_vector = rotateToAbsolute(local_vector); +    absolute_vector.mV[VX] += mOrigin.mV[VX]; +    absolute_vector.mV[VY] += mOrigin.mV[VY]; +    absolute_vector.mV[VZ] += mOrigin.mV[VZ]; +    return absolute_vector;  } -// This is how you combine a translation and rotation of a  +// This is how you combine a translation and rotation of a  // coordinate frame to get an OpenGL transformation matrix:  //  //     translation   *   rotation      =          transformation matrix @@ -531,129 +531,129 @@ LLVector4 LLCoordFrame::transformToAbsolute(const LLVector4 &local_vector) const  //  V | 0  0  1  0 |   | c  f  i  0 |     |     c            f            i          0 |  //    |-x -y -z  1 |   | 0  0  0  1 |     |-(ax+by+cz)  -(dx+ey+fz)  -(gx+hy+iz)     1 |  // -// where {a,b,c} = x-axis  -//       {d,e,f} = y-axis  -//       {g,h,i} = z-axis  +// where {a,b,c} = x-axis +//       {d,e,f} = y-axis +//       {g,h,i} = z-axis  //       {x,y,z} = origin  void LLCoordFrame::getOpenGLTranslation(F32 *ogl_matrix) const  { -	*(ogl_matrix + 0)  = 1.0f; -	*(ogl_matrix + 1)  = 0.0f; -	*(ogl_matrix + 2)  = 0.0f; -	*(ogl_matrix + 3)  = 0.0f; +    *(ogl_matrix + 0)  = 1.0f; +    *(ogl_matrix + 1)  = 0.0f; +    *(ogl_matrix + 2)  = 0.0f; +    *(ogl_matrix + 3)  = 0.0f; -	*(ogl_matrix + 4)  = 0.0f; -	*(ogl_matrix + 5)  = 1.0f; -	*(ogl_matrix + 6)  = 0.0f; -	*(ogl_matrix + 7)  = 0.0f; +    *(ogl_matrix + 4)  = 0.0f; +    *(ogl_matrix + 5)  = 1.0f; +    *(ogl_matrix + 6)  = 0.0f; +    *(ogl_matrix + 7)  = 0.0f; -	*(ogl_matrix + 8)  = 0.0f; -	*(ogl_matrix + 9)  = 0.0f; -	*(ogl_matrix + 10) = 1.0f; -	*(ogl_matrix + 11) = 0.0f; +    *(ogl_matrix + 8)  = 0.0f; +    *(ogl_matrix + 9)  = 0.0f; +    *(ogl_matrix + 10) = 1.0f; +    *(ogl_matrix + 11) = 0.0f; -	*(ogl_matrix + 12) = -mOrigin.mV[VX]; -	*(ogl_matrix + 13) = -mOrigin.mV[VY]; -	*(ogl_matrix + 14) = -mOrigin.mV[VZ]; -	*(ogl_matrix + 15) = 1.0f; +    *(ogl_matrix + 12) = -mOrigin.mV[VX]; +    *(ogl_matrix + 13) = -mOrigin.mV[VY]; +    *(ogl_matrix + 14) = -mOrigin.mV[VZ]; +    *(ogl_matrix + 15) = 1.0f;  }  void LLCoordFrame::getOpenGLRotation(F32 *ogl_matrix) const  { -	*(ogl_matrix + 0)  = mXAxis.mV[VX]; -	*(ogl_matrix + 4)  = mXAxis.mV[VY]; -	*(ogl_matrix + 8)  = mXAxis.mV[VZ]; +    *(ogl_matrix + 0)  = mXAxis.mV[VX]; +    *(ogl_matrix + 4)  = mXAxis.mV[VY]; +    *(ogl_matrix + 8)  = mXAxis.mV[VZ]; -	*(ogl_matrix + 1)  = mYAxis.mV[VX]; -	*(ogl_matrix + 5)  = mYAxis.mV[VY]; -	*(ogl_matrix + 9)  = mYAxis.mV[VZ]; +    *(ogl_matrix + 1)  = mYAxis.mV[VX]; +    *(ogl_matrix + 5)  = mYAxis.mV[VY]; +    *(ogl_matrix + 9)  = mYAxis.mV[VZ]; -	*(ogl_matrix + 2)  = mZAxis.mV[VX]; -	*(ogl_matrix + 6)  = mZAxis.mV[VY]; -	*(ogl_matrix + 10) = mZAxis.mV[VZ]; +    *(ogl_matrix + 2)  = mZAxis.mV[VX]; +    *(ogl_matrix + 6)  = mZAxis.mV[VY]; +    *(ogl_matrix + 10) = mZAxis.mV[VZ]; -	*(ogl_matrix + 3)  = 0.0f; -	*(ogl_matrix + 7)  = 0.0f; -	*(ogl_matrix + 11) = 0.0f; +    *(ogl_matrix + 3)  = 0.0f; +    *(ogl_matrix + 7)  = 0.0f; +    *(ogl_matrix + 11) = 0.0f; -	*(ogl_matrix + 12) = 0.0f; -	*(ogl_matrix + 13) = 0.0f; -	*(ogl_matrix + 14) = 0.0f; -	*(ogl_matrix + 15) = 1.0f; +    *(ogl_matrix + 12) = 0.0f; +    *(ogl_matrix + 13) = 0.0f; +    *(ogl_matrix + 14) = 0.0f; +    *(ogl_matrix + 15) = 1.0f;  }  void LLCoordFrame::getOpenGLTransform(F32 *ogl_matrix) const  { -	*(ogl_matrix + 0)  = mXAxis.mV[VX]; -	*(ogl_matrix + 4)  = mXAxis.mV[VY]; -	*(ogl_matrix + 8)  = mXAxis.mV[VZ]; -	*(ogl_matrix + 12) = -mOrigin * mXAxis; +    *(ogl_matrix + 0)  = mXAxis.mV[VX]; +    *(ogl_matrix + 4)  = mXAxis.mV[VY]; +    *(ogl_matrix + 8)  = mXAxis.mV[VZ]; +    *(ogl_matrix + 12) = -mOrigin * mXAxis; -	*(ogl_matrix + 1)  = mYAxis.mV[VX]; -	*(ogl_matrix + 5)  = mYAxis.mV[VY]; -	*(ogl_matrix + 9)  = mYAxis.mV[VZ]; -	*(ogl_matrix + 13) = -mOrigin * mYAxis; +    *(ogl_matrix + 1)  = mYAxis.mV[VX]; +    *(ogl_matrix + 5)  = mYAxis.mV[VY]; +    *(ogl_matrix + 9)  = mYAxis.mV[VZ]; +    *(ogl_matrix + 13) = -mOrigin * mYAxis; -	*(ogl_matrix + 2)  = mZAxis.mV[VX]; -	*(ogl_matrix + 6)  = mZAxis.mV[VY]; -	*(ogl_matrix + 10) = mZAxis.mV[VZ]; -	*(ogl_matrix + 14) = -mOrigin * mZAxis; +    *(ogl_matrix + 2)  = mZAxis.mV[VX]; +    *(ogl_matrix + 6)  = mZAxis.mV[VY]; +    *(ogl_matrix + 10) = mZAxis.mV[VZ]; +    *(ogl_matrix + 14) = -mOrigin * mZAxis; -	*(ogl_matrix + 3)  = 0.0f; -	*(ogl_matrix + 7)  = 0.0f; -	*(ogl_matrix + 11) = 0.0f; -	*(ogl_matrix + 15) = 1.0f; +    *(ogl_matrix + 3)  = 0.0f; +    *(ogl_matrix + 7)  = 0.0f; +    *(ogl_matrix + 11) = 0.0f; +    *(ogl_matrix + 15) = 1.0f;  }  // at and up_direction are presumed to be normalized  void LLCoordFrame::lookDir(const LLVector3 &at, const LLVector3 &up_direction)  { -	// Make sure 'at' and 'up_direction' are not parallel -	// and that neither are zero-length vectors -	LLVector3 left(up_direction % at); -	if (left.isNull())  -	{ -		//tweak lookat pos so we don't get a degenerate matrix -		LLVector3 tempat(at[VX] + 0.01f, at[VY], at[VZ]); -		tempat.normVec(); -		left = (up_direction % tempat); -	} -	left.normVec(); +    // Make sure 'at' and 'up_direction' are not parallel +    // and that neither are zero-length vectors +    LLVector3 left(up_direction % at); +    if (left.isNull()) +    { +        //tweak lookat pos so we don't get a degenerate matrix +        LLVector3 tempat(at[VX] + 0.01f, at[VY], at[VZ]); +        tempat.normVec(); +        left = (up_direction % tempat); +    } +    left.normVec(); -	LLVector3 up = at % left; +    LLVector3 up = at % left; -	if (at.isFinite() && left.isFinite() && up.isFinite()) -	{ -		setAxes(at, left, up); -	} +    if (at.isFinite() && left.isFinite() && up.isFinite()) +    { +        setAxes(at, left, up); +    }  }  void LLCoordFrame::lookDir(const LLVector3 &xuv)  { -	static LLVector3 up_direction(0.0f, 0.0f, 1.0f); -	lookDir(xuv, up_direction); +    static LLVector3 up_direction(0.0f, 0.0f, 1.0f); +    lookDir(xuv, up_direction);  }  void LLCoordFrame::lookAt(const LLVector3 &origin, const LLVector3 &point_of_interest, const LLVector3 &up_direction)  { -	setOrigin(origin); -	LLVector3 at(point_of_interest - origin); -	at.normVec(); -	lookDir(at, up_direction); +    setOrigin(origin); +    LLVector3 at(point_of_interest - origin); +    at.normVec(); +    lookDir(at, up_direction);  }  void LLCoordFrame::lookAt(const LLVector3 &origin, const LLVector3 &point_of_interest)  { -	static LLVector3 up_direction(0.0f, 0.0f, 1.0f); +    static LLVector3 up_direction(0.0f, 0.0f, 1.0f); -	setOrigin(origin); -	LLVector3 at(point_of_interest - origin); -	at.normVec(); -	lookDir(at, up_direction); +    setOrigin(origin); +    LLVector3 at(point_of_interest - origin); +    at.normVec(); +    lookDir(at, up_direction);  } @@ -661,13 +661,13 @@ void LLCoordFrame::lookAt(const LLVector3 &origin, const LLVector3 &point_of_int  std::ostream& operator<<(std::ostream &s, const LLCoordFrame &C)  { -	s << "{ " -	  << " origin = " << C.mOrigin -	  << " x_axis = " << C.mXAxis -	  << " y_axis = " << C.mYAxis -	  << " z_axis = " << C.mZAxis -	<< " }"; -	return s; +    s << "{ " +      << " origin = " << C.mOrigin +      << " x_axis = " << C.mXAxis +      << " y_axis = " << C.mYAxis +      << " z_axis = " << C.mZAxis +    << " }"; +    return s;  } diff --git a/indra/llmath/llcoordframe.h b/indra/llmath/llcoordframe.h index 909adf260c..802b98425a 100644 --- a/indra/llmath/llcoordframe.h +++ b/indra/llmath/llcoordframe.h @@ -1,25 +1,25 @@ -/**  +/**   * @file llcoordframe.h   * @brief LLCoordFrame class header file.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -32,141 +32,141 @@  #include "llerror.h"  // XXX : The constructors of the LLCoordFrame class assume that all vectors -//		 and quaternion being passed as arguments are normalized, and all matrix  -// 		 arguments are unitary.  VERY BAD things will happen if these assumptions fail. -//		 Also, segfault hazzards exist in methods that accept F32* arguments. +//       and quaternion being passed as arguments are normalized, and all matrix +//       arguments are unitary.  VERY BAD things will happen if these assumptions fail. +//       Also, segfault hazzards exist in methods that accept F32* arguments. -class LLCoordFrame  +class LLCoordFrame  {  public: -	LLCoordFrame();											// Inits at zero with identity rotation -	explicit LLCoordFrame(const LLVector3 &origin);			// Sets origin, and inits rotation = Identity -	LLCoordFrame(const LLVector3 &x_axis,  -				 const LLVector3 &y_axis,  -				 const LLVector3 &z_axis);					// Sets coordinate axes and inits origin at zero -	LLCoordFrame(const LLVector3 &origin,  -				 const LLVector3 &x_axis,  -				 const LLVector3 &y_axis,  -				 const LLVector3 &z_axis);					// Sets the origin and coordinate axes -	LLCoordFrame(const LLVector3 &origin,  -				 const LLMatrix3 &rotation);				// Sets axes to 3x3 matrix -	LLCoordFrame(const LLVector3 &origin,  -				 const LLVector3 &direction);				// Sets origin and calls lookDir(direction) -	explicit LLCoordFrame(const LLQuaternion &q);			// Sets axes using q and inits mOrigin to zero  -	LLCoordFrame(const LLVector3 &origin,  -				 const LLQuaternion &q);					// Uses quaternion to init axes -	explicit LLCoordFrame(const LLMatrix4 &mat);			// Extracts frame from a 4x4 matrix -	// The folowing two constructors are dangerous due to implicit casting and have been disabled - SJB -	//LLCoordFrame(const F32 *origin, const F32 *rotation);	// Assumes "origin" is 1x3 and "rotation" is 1x9 array -	//LLCoordFrame(const F32 *origin_and_rotation);			// Assumes "origin_and_rotation" is 1x12 array - -	BOOL isFinite() { return mOrigin.isFinite() && mXAxis.isFinite() && mYAxis.isFinite() && mZAxis.isFinite(); } - -	void reset(); -	void resetAxes(); - -	void setOrigin(F32 x, F32 y, F32 z);					// Set mOrigin -	void setOrigin(const LLVector3 &origin); -	void setOrigin(const F32 *origin); -	void setOrigin(const LLCoordFrame &frame); - -	inline void setOriginX(F32 x) { mOrigin.mV[VX] = x; } -	inline void setOriginY(F32 y) { mOrigin.mV[VY] = y; } -	inline void setOriginZ(F32 z) { mOrigin.mV[VZ] = z; } - -	void setAxes(const LLVector3 &x_axis, 					// Set axes -				 const LLVector3 &y_axis,  -				 const LLVector3 &z_axis); -	void setAxes(const LLMatrix3 &rotation_matrix); -	void setAxes(const LLQuaternion &q); -	void setAxes(const F32 *rotation_matrix); -	void setAxes(const LLCoordFrame &frame); - -	void translate(F32 x, F32 y, F32 z);					// Move mOrgin -	void translate(const LLVector3 &v); -	void translate(const F32 *origin); - -	void rotate(F32 angle, F32 x, F32 y, F32 z);			// Move axes -	void rotate(F32 angle, const LLVector3 &rotation_axis); -	void rotate(const LLQuaternion &q); -	void rotate(const LLMatrix3 &m); - -	void orthonormalize();	// Makes sure axes are unitary and orthogonal. - -	// These methods allow rotations in the LLCoordFrame's frame -	void roll(F32 angle);		// RH rotation about mXAxis, radians -	void pitch(F32 angle);		// RH rotation about mYAxis, radians -	void yaw(F32 angle);		// RH rotation about mZAxis, radians - -	inline const LLVector3 &getOrigin() const { return mOrigin; } - -	inline const LLVector3 &getXAxis() const  { return mXAxis; } -	inline const LLVector3 &getYAxis() const  { return mYAxis; } -	inline const LLVector3 &getZAxis() const  { return mZAxis; } - -	inline const LLVector3 &getAtAxis() const   { return mXAxis; } -	inline const LLVector3 &getLeftAxis() const { return mYAxis; } -	inline const LLVector3 &getUpAxis() const   { return mZAxis; } -	 -	// These return representations of the rotation or orientation of the LLFrame -	// it its absolute frame.  That is, these rotations acting on the X-axis {1,0,0} -	// will produce the mXAxis. -	//		LLMatrix3 getMatrix3() const;				// Returns axes in 3x3 matrix  -	LLQuaternion getQuaternion() const;			// Returns axes in quaternion form - -	// Same as above, except it also includes the translation of the LLFrame -	//		LLMatrix4 getMatrix4() const;				// Returns position and axes in 4x4 matrix - -	// Returns matrix which expresses point in local frame in the parent frame -	void getMatrixToParent(LLMatrix4 &mat) const; -	// Returns matrix which expresses point in parent frame in the local frame -	void getMatrixToLocal(LLMatrix4 &mat) const; // Returns matrix which expresses point in parent frame in the local frame - -	void getRotMatrixToParent(LLMatrix4 &mat) const; - -	// Copies mOrigin, then the three axes to buffer, returns number of bytes copied. -	size_t writeOrientation(char *buffer) const; -		 -	// Copies mOrigin, then the three axes from buffer, returns the number of bytes copied. -	// Assumes the data in buffer is correct. -	size_t readOrientation(const char *buffer); - -	LLVector3 rotateToLocal(const LLVector3 &v) const;		// Returns v' rotated to local -	LLVector4 rotateToLocal(const LLVector4 &v) const;		// Returns v' rotated to local -	LLVector3 rotateToAbsolute(const LLVector3 &v) const;	// Returns v' rotated to absolute -	LLVector4 rotateToAbsolute(const LLVector4 &v) const;	// Returns v' rotated to absolute - -	LLVector3 transformToLocal(const LLVector3 &v) const;		// Returns v' in local coord -	LLVector4 transformToLocal(const LLVector4 &v) const;		// Returns v' in local coord -	LLVector3 transformToAbsolute(const LLVector3 &v) const;	// Returns v' in absolute coord -	LLVector4 transformToAbsolute(const LLVector4 &v) const;	// Returns v' in absolute coord - -	// Write coord frame orientation into provided array in OpenGL matrix format. -	void getOpenGLTranslation(F32 *ogl_matrix) const; -	void getOpenGLRotation(F32 *ogl_matrix) const; -	void getOpenGLTransform(F32 *ogl_matrix) const; - -	// lookDir orients to (xuv, presumed normalized) and does not affect origin -	void lookDir(const LLVector3 &xuv, const LLVector3 &up); -	void lookDir(const LLVector3 &xuv); // up = 0,0,1 -	// lookAt orients to (point_of_interest - origin) and sets origin -	void lookAt(const LLVector3 &origin, const LLVector3 &point_of_interest, const LLVector3 &up); -	void lookAt(const LLVector3 &origin, const LLVector3 &point_of_interest); // up = 0,0,1 - -	// deprecated -	void setOriginAndLookAt(const LLVector3 &origin, const LLVector3 &up, const LLVector3 &point_of_interest) -	{ -		lookAt(origin, point_of_interest, up); -	} -	 -	friend std::ostream& operator<<(std::ostream &s, const LLCoordFrame &C); - -	// These vectors are in absolute frame -	LLVector3 mOrigin; -	LLVector3 mXAxis; -	LLVector3 mYAxis; -	LLVector3 mZAxis; +    LLCoordFrame();                                         // Inits at zero with identity rotation +    explicit LLCoordFrame(const LLVector3 &origin);         // Sets origin, and inits rotation = Identity +    LLCoordFrame(const LLVector3 &x_axis, +                 const LLVector3 &y_axis, +                 const LLVector3 &z_axis);                  // Sets coordinate axes and inits origin at zero +    LLCoordFrame(const LLVector3 &origin, +                 const LLVector3 &x_axis, +                 const LLVector3 &y_axis, +                 const LLVector3 &z_axis);                  // Sets the origin and coordinate axes +    LLCoordFrame(const LLVector3 &origin, +                 const LLMatrix3 &rotation);                // Sets axes to 3x3 matrix +    LLCoordFrame(const LLVector3 &origin, +                 const LLVector3 &direction);               // Sets origin and calls lookDir(direction) +    explicit LLCoordFrame(const LLQuaternion &q);           // Sets axes using q and inits mOrigin to zero +    LLCoordFrame(const LLVector3 &origin, +                 const LLQuaternion &q);                    // Uses quaternion to init axes +    explicit LLCoordFrame(const LLMatrix4 &mat);            // Extracts frame from a 4x4 matrix +    // The folowing two constructors are dangerous due to implicit casting and have been disabled - SJB +    //LLCoordFrame(const F32 *origin, const F32 *rotation); // Assumes "origin" is 1x3 and "rotation" is 1x9 array +    //LLCoordFrame(const F32 *origin_and_rotation);         // Assumes "origin_and_rotation" is 1x12 array + +    BOOL isFinite() { return mOrigin.isFinite() && mXAxis.isFinite() && mYAxis.isFinite() && mZAxis.isFinite(); } + +    void reset(); +    void resetAxes(); + +    void setOrigin(F32 x, F32 y, F32 z);                    // Set mOrigin +    void setOrigin(const LLVector3 &origin); +    void setOrigin(const F32 *origin); +    void setOrigin(const LLCoordFrame &frame); + +    inline void setOriginX(F32 x) { mOrigin.mV[VX] = x; } +    inline void setOriginY(F32 y) { mOrigin.mV[VY] = y; } +    inline void setOriginZ(F32 z) { mOrigin.mV[VZ] = z; } + +    void setAxes(const LLVector3 &x_axis,                   // Set axes +                 const LLVector3 &y_axis, +                 const LLVector3 &z_axis); +    void setAxes(const LLMatrix3 &rotation_matrix); +    void setAxes(const LLQuaternion &q); +    void setAxes(const F32 *rotation_matrix); +    void setAxes(const LLCoordFrame &frame); + +    void translate(F32 x, F32 y, F32 z);                    // Move mOrgin +    void translate(const LLVector3 &v); +    void translate(const F32 *origin); + +    void rotate(F32 angle, F32 x, F32 y, F32 z);            // Move axes +    void rotate(F32 angle, const LLVector3 &rotation_axis); +    void rotate(const LLQuaternion &q); +    void rotate(const LLMatrix3 &m); + +    void orthonormalize();  // Makes sure axes are unitary and orthogonal. + +    // These methods allow rotations in the LLCoordFrame's frame +    void roll(F32 angle);       // RH rotation about mXAxis, radians +    void pitch(F32 angle);      // RH rotation about mYAxis, radians +    void yaw(F32 angle);        // RH rotation about mZAxis, radians + +    inline const LLVector3 &getOrigin() const { return mOrigin; } + +    inline const LLVector3 &getXAxis() const  { return mXAxis; } +    inline const LLVector3 &getYAxis() const  { return mYAxis; } +    inline const LLVector3 &getZAxis() const  { return mZAxis; } + +    inline const LLVector3 &getAtAxis() const   { return mXAxis; } +    inline const LLVector3 &getLeftAxis() const { return mYAxis; } +    inline const LLVector3 &getUpAxis() const   { return mZAxis; } + +    // These return representations of the rotation or orientation of the LLFrame +    // it its absolute frame.  That is, these rotations acting on the X-axis {1,0,0} +    // will produce the mXAxis. +    //      LLMatrix3 getMatrix3() const;               // Returns axes in 3x3 matrix +    LLQuaternion getQuaternion() const;         // Returns axes in quaternion form + +    // Same as above, except it also includes the translation of the LLFrame +    //      LLMatrix4 getMatrix4() const;               // Returns position and axes in 4x4 matrix + +    // Returns matrix which expresses point in local frame in the parent frame +    void getMatrixToParent(LLMatrix4 &mat) const; +    // Returns matrix which expresses point in parent frame in the local frame +    void getMatrixToLocal(LLMatrix4 &mat) const; // Returns matrix which expresses point in parent frame in the local frame + +    void getRotMatrixToParent(LLMatrix4 &mat) const; + +    // Copies mOrigin, then the three axes to buffer, returns number of bytes copied. +    size_t writeOrientation(char *buffer) const; + +    // Copies mOrigin, then the three axes from buffer, returns the number of bytes copied. +    // Assumes the data in buffer is correct. +    size_t readOrientation(const char *buffer); + +    LLVector3 rotateToLocal(const LLVector3 &v) const;      // Returns v' rotated to local +    LLVector4 rotateToLocal(const LLVector4 &v) const;      // Returns v' rotated to local +    LLVector3 rotateToAbsolute(const LLVector3 &v) const;   // Returns v' rotated to absolute +    LLVector4 rotateToAbsolute(const LLVector4 &v) const;   // Returns v' rotated to absolute + +    LLVector3 transformToLocal(const LLVector3 &v) const;       // Returns v' in local coord +    LLVector4 transformToLocal(const LLVector4 &v) const;       // Returns v' in local coord +    LLVector3 transformToAbsolute(const LLVector3 &v) const;    // Returns v' in absolute coord +    LLVector4 transformToAbsolute(const LLVector4 &v) const;    // Returns v' in absolute coord + +    // Write coord frame orientation into provided array in OpenGL matrix format. +    void getOpenGLTranslation(F32 *ogl_matrix) const; +    void getOpenGLRotation(F32 *ogl_matrix) const; +    void getOpenGLTransform(F32 *ogl_matrix) const; + +    // lookDir orients to (xuv, presumed normalized) and does not affect origin +    void lookDir(const LLVector3 &xuv, const LLVector3 &up); +    void lookDir(const LLVector3 &xuv); // up = 0,0,1 +    // lookAt orients to (point_of_interest - origin) and sets origin +    void lookAt(const LLVector3 &origin, const LLVector3 &point_of_interest, const LLVector3 &up); +    void lookAt(const LLVector3 &origin, const LLVector3 &point_of_interest); // up = 0,0,1 + +    // deprecated +    void setOriginAndLookAt(const LLVector3 &origin, const LLVector3 &up, const LLVector3 &point_of_interest) +    { +        lookAt(origin, point_of_interest, up); +    } + +    friend std::ostream& operator<<(std::ostream &s, const LLCoordFrame &C); + +    // These vectors are in absolute frame +    LLVector3 mOrigin; +    LLVector3 mXAxis; +    LLVector3 mYAxis; +    LLVector3 mZAxis;  }; diff --git a/indra/llmath/llinterp.h b/indra/llmath/llinterp.h index 5187646179..116e949663 100644 --- a/indra/llmath/llinterp.h +++ b/indra/llmath/llinterp.h @@ -1,24 +1,24 @@ -/**  +/**   * @file llinterp.h   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -30,7 +30,7 @@  // macro definitions for common math constants (e.g. M_PI) are declared under the _USE_MATH_DEFINES  // on Windows system.  // So, let's define _USE_MATH_DEFINES before including math.h -	#define _USE_MATH_DEFINES +    #define _USE_MATH_DEFINES  #endif  #include "math.h" @@ -40,8 +40,8 @@  class LLInterpVal  {  public: -	virtual ~LLInterpVal() {} -	virtual void interp(LLInterpVal &target, const F32 frac); // Linear interpolation for each type +    virtual ~LLInterpVal() {} +    virtual void interp(LLInterpVal &target, const F32 frac); // Linear interpolation for each type  };  template <typename Type> @@ -49,57 +49,57 @@ class LLInterp  {  public:          LLInterp(); -	virtual ~LLInterp() {} +    virtual ~LLInterp() {} + +    virtual void start(); +    void update(const F32 time); +    const Type &getCurVal() const; -	virtual void start(); -	void update(const F32 time); -	const Type &getCurVal() const; +    void setStartVal(const Type &start_val); +    const Type &getStartVal() const; -	void setStartVal(const Type &start_val); -	const Type &getStartVal() const; +    void setEndVal(const Type &target_val); +    const Type &getEndVal() const; -	void setEndVal(const Type &target_val); -	const Type &getEndVal() const; +    void setStartTime(const F32 time); +    F32 getStartTime() const; -	void setStartTime(const F32 time); -	F32 getStartTime() const; +    void setEndTime(const F32 time); +    F32 getEndTime() const; -	void setEndTime(const F32 time); -	F32 getEndTime() const; +    BOOL isActive() const; +    BOOL isDone() const; -	BOOL isActive() const; -	BOOL isDone() const; -	  protected: -	F32 mStartTime; -	F32 mEndTime; -	F32 mDuration; -	BOOL mActive; -	BOOL mDone; +    F32 mStartTime; +    F32 mEndTime; +    F32 mDuration; +    BOOL mActive; +    BOOL mDone; -	Type mStartVal; -	Type mEndVal; +    Type mStartVal; +    Type mEndVal; -	F32 mCurTime; -	Type mCurVal; +    F32 mCurTime; +    Type mCurVal;  };  template <typename Type>  class LLInterpLinear : public LLInterp<Type>  {  public: -	/*virtual*/ void start(); -	void update(const F32 time); -	F32 getCurFrac() const; +    /*virtual*/ void start(); +    void update(const F32 time); +    F32 getCurFrac() const;  protected: -	F32 mCurFrac; +    F32 mCurFrac;  };  template <typename Type>  class LLInterpExp : public LLInterpLinear<Type>  {  public: -	void update(const F32 time); +    void update(const F32 time);  protected:  }; @@ -107,28 +107,28 @@ template <typename Type>  class LLInterpAttractor : public LLInterp<Type>  {  public: -	LLInterpAttractor(); -	/*virtual*/ void start(); -	void setStartVel(const Type &vel); -	void setForce(const F32 force); -	void update(const F32 time); +    LLInterpAttractor(); +    /*virtual*/ void start(); +    void setStartVel(const Type &vel); +    void setForce(const F32 force); +    void update(const F32 time);  protected: -	F32 mForce; -	Type mStartVel; -	Type mVelocity; +    F32 mForce; +    Type mStartVel; +    Type mVelocity;  };  template <typename Type>  class LLInterpFunc : public LLInterp<Type>  {  public: -	LLInterpFunc(); -	void update(const F32 time); +    LLInterpFunc(); +    void update(const F32 time); -	void setFunc(Type (*)(const F32, void *data), void *data); +    void setFunc(Type (*)(const F32, void *data), void *data);  protected: -	Type (*mFunc)(const F32 time, void *data); -	void *mData; +    Type (*mFunc)(const F32 time, void *data); +    void *mData;  }; @@ -147,93 +147,93 @@ template <typename Type>  LLInterp<Type>::LLInterp()  : mStartVal(Type()), mEndVal(Type()), mCurVal(Type())  { -	mStartTime = 0.f; -	mEndTime = 1.f; -	mDuration = 1.f; -	mCurTime = 0.f; -	mDone = FALSE; -	mActive = FALSE; +    mStartTime = 0.f; +    mEndTime = 1.f; +    mDuration = 1.f; +    mCurTime = 0.f; +    mDone = FALSE; +    mActive = FALSE;  }  template <class Type>  void LLInterp<Type>::setStartVal(const Type &start_val)  { -	mStartVal = start_val; +    mStartVal = start_val;  }  template <class Type>  void LLInterp<Type>::start()  { -	mCurVal = mStartVal; -	mCurTime = mStartTime; -	mDone = FALSE; -	mActive = FALSE; +    mCurVal = mStartVal; +    mCurTime = mStartTime; +    mDone = FALSE; +    mActive = FALSE;  }  template <class Type>  const Type &LLInterp<Type>::getStartVal() const  { -	return mStartVal; +    return mStartVal;  }  template <class Type>  void LLInterp<Type>::setEndVal(const Type &end_val)  { -	mEndVal = end_val; +    mEndVal = end_val;  }  template <class Type>  const Type &LLInterp<Type>::getEndVal() const  { -	return mEndVal; +    return mEndVal;  }  template <class Type>  const Type &LLInterp<Type>::getCurVal() const  { -	return mCurVal; +    return mCurVal;  }  template <class Type>  void LLInterp<Type>::setStartTime(const F32 start_time)  { -	mStartTime = start_time; -	mDuration = mEndTime - mStartTime; +    mStartTime = start_time; +    mDuration = mEndTime - mStartTime;  }  template <class Type>  F32 LLInterp<Type>::getStartTime() const  { -	return mStartTime; +    return mStartTime;  }  template <class Type>  void LLInterp<Type>::setEndTime(const F32 end_time)  { -	mEndTime = end_time; -	mDuration = mEndTime - mStartTime; +    mEndTime = end_time; +    mDuration = mEndTime - mStartTime;  }  template <class Type>  F32 LLInterp<Type>::getEndTime() const  { -	return mEndTime; +    return mEndTime;  }  template <class Type>  BOOL LLInterp<Type>::isDone() const  { -	return mDone; +    return mDone;  }  template <class Type>  BOOL LLInterp<Type>::isActive() const  { -	return mActive; +    return mActive;  }  ////////////////////////////// @@ -243,53 +243,53 @@ BOOL LLInterp<Type>::isActive() const  template <typename Type>  void LLInterpLinear<Type>::start()  { -	LLInterp<Type>::start(); -	mCurFrac = 0.f; +    LLInterp<Type>::start(); +    mCurFrac = 0.f;  }  template <typename Type>  void LLInterpLinear<Type>::update(const F32 time)  { -	F32 target_frac = (time - this->mStartTime) / this->mDuration; -	F32 dfrac = target_frac - this->mCurFrac; -	if (target_frac >= 0.f) -	{ -		this->mActive = TRUE; -	} -	 -	if (target_frac > 1.f) -	{ -		this->mCurVal = this->mEndVal; -		this->mCurFrac = 1.f; -		this->mCurTime = time; -		this->mDone = TRUE; -		return; -	} - -	target_frac = llmin(1.f, target_frac); -	target_frac = llmax(0.f, target_frac); - -	if (dfrac >= 0.f) -	{ -		F32 total_frac = 1.f - this->mCurFrac; -		F32 inc_frac = dfrac / total_frac; -		this->mCurVal = inc_frac * this->mEndVal + (1.f - inc_frac) * this->mCurVal; -		this->mCurTime = time; -	} -	else -	{ -		F32 total_frac = this->mCurFrac - 1.f; -		F32 inc_frac = dfrac / total_frac; -		this->mCurVal = inc_frac * this->mStartVal + (1.f - inc_frac) * this->mCurVal; -		this->mCurTime = time; -	} -	mCurFrac = target_frac; +    F32 target_frac = (time - this->mStartTime) / this->mDuration; +    F32 dfrac = target_frac - this->mCurFrac; +    if (target_frac >= 0.f) +    { +        this->mActive = TRUE; +    } + +    if (target_frac > 1.f) +    { +        this->mCurVal = this->mEndVal; +        this->mCurFrac = 1.f; +        this->mCurTime = time; +        this->mDone = TRUE; +        return; +    } + +    target_frac = llmin(1.f, target_frac); +    target_frac = llmax(0.f, target_frac); + +    if (dfrac >= 0.f) +    { +        F32 total_frac = 1.f - this->mCurFrac; +        F32 inc_frac = dfrac / total_frac; +        this->mCurVal = inc_frac * this->mEndVal + (1.f - inc_frac) * this->mCurVal; +        this->mCurTime = time; +    } +    else +    { +        F32 total_frac = this->mCurFrac - 1.f; +        F32 inc_frac = dfrac / total_frac; +        this->mCurVal = inc_frac * this->mStartVal + (1.f - inc_frac) * this->mCurVal; +        this->mCurTime = time; +    } +    mCurFrac = target_frac;  }  template <class Type>  F32 LLInterpLinear<Type>::getCurFrac() const  { -	return mCurFrac; +    return mCurFrac;  } @@ -302,54 +302,54 @@ F32 LLInterpLinear<Type>::getCurFrac() const  template <class Type>  LLInterpAttractor<Type>::LLInterpAttractor() : LLInterp<Type>()  { -	mForce = 0.1f; -	mVelocity *= 0.f; -	mStartVel *= 0.f; +    mForce = 0.1f; +    mVelocity *= 0.f; +    mStartVel *= 0.f;  }  template <class Type>  void LLInterpAttractor<Type>::start()  { -	LLInterp<Type>::start(); -	mVelocity = mStartVel; +    LLInterp<Type>::start(); +    mVelocity = mStartVel;  }  template <class Type>  void LLInterpAttractor<Type>::setStartVel(const Type &vel)  { -	mStartVel = vel; +    mStartVel = vel;  }  template <class Type>  void LLInterpAttractor<Type>::setForce(const F32 force)  { -	mForce = force; +    mForce = force;  }  template <class Type>  void LLInterpAttractor<Type>::update(const F32 time)  { -	if (time > this->mStartTime) -	{ -		this->mActive = TRUE; -	} -	else -	{ -		return; -	} -	if (time > this->mEndTime) -	{ -		this->mDone = TRUE; -		return; -	} - -	F32 dt = time - this->mCurTime; -	Type dist_val = this->mEndVal - this->mCurVal; -	Type dv = 0.5*dt*dt*this->mForce*dist_val; -	this->mVelocity += dv; -	this->mCurVal += this->mVelocity * dt; -	this->mCurTime = time; +    if (time > this->mStartTime) +    { +        this->mActive = TRUE; +    } +    else +    { +        return; +    } +    if (time > this->mEndTime) +    { +        this->mDone = TRUE; +        return; +    } + +    F32 dt = time - this->mCurTime; +    Type dist_val = this->mEndVal - this->mCurVal; +    Type dv = 0.5*dt*dt*this->mForce*dist_val; +    this->mVelocity += dv; +    this->mCurVal += this->mVelocity * dt; +    this->mCurTime = time;  } @@ -362,36 +362,36 @@ void LLInterpAttractor<Type>::update(const F32 time)  template <class Type>  LLInterpFunc<Type>::LLInterpFunc() : LLInterp<Type>()  { -	mFunc = NULL; -	mData = NULL; +    mFunc = NULL; +    mData = NULL;  }  template <class Type>  void LLInterpFunc<Type>::setFunc(Type (*func)(const F32, void *data), void *data)  { -	mFunc = func; -	mData = data; +    mFunc = func; +    mData = data;  }  template <class Type>  void LLInterpFunc<Type>::update(const F32 time)  { -	if (time > this->mStartTime) -	{ -		this->mActive = TRUE; -	} -	else -	{ -		return; -	} -	if (time > this->mEndTime) -	{ -		this->mDone = TRUE; -		return; -	} - -	this->mCurVal = (*mFunc)(time - this->mStartTime, mData); -	this->mCurTime = time; +    if (time > this->mStartTime) +    { +        this->mActive = TRUE; +    } +    else +    { +        return; +    } +    if (time > this->mEndTime) +    { +        this->mDone = TRUE; +        return; +    } + +    this->mCurVal = (*mFunc)(time - this->mStartTime, mData); +    this->mCurTime = time;  }  ////////////////////////////// @@ -402,24 +402,24 @@ void LLInterpFunc<Type>::update(const F32 time)  template <class Type>  void LLInterpExp<Type>::update(const F32 time)  { -	F32 target_frac = (time - this->mStartTime) / this->mDuration; -	if (target_frac >= 0.f) -	{ -		this->mActive = TRUE; -	} -	 -	if (target_frac > 1.f) -	{ -		this->mCurVal = this->mEndVal; -		this->mCurFrac = 1.f; -		this->mCurTime = time; -		this->mDone = TRUE; -		return; -	} - -	this->mCurFrac = 1.f - (F32)(exp(-2.f*target_frac)); -	this->mCurVal = this->mStartVal + this->mCurFrac * (this->mEndVal - this->mStartVal); -	this->mCurTime = time; +    F32 target_frac = (time - this->mStartTime) / this->mDuration; +    if (target_frac >= 0.f) +    { +        this->mActive = TRUE; +    } + +    if (target_frac > 1.f) +    { +        this->mCurVal = this->mEndVal; +        this->mCurFrac = 1.f; +        this->mCurTime = time; +        this->mDone = TRUE; +        return; +    } + +    this->mCurFrac = 1.f - (F32)(exp(-2.f*target_frac)); +    this->mCurVal = this->mStartVal + this->mCurFrac * (this->mEndVal - this->mStartVal); +    this->mCurTime = time;  }  #endif // LL_LLINTERP_H diff --git a/indra/llmath/llline.cpp b/indra/llmath/llline.cpp index cfee315b55..70c68dd42f 100644 --- a/indra/llmath/llline.cpp +++ b/indra/llmath/llline.cpp @@ -1,4 +1,4 @@ -/**  +/**   * @file llline.cpp   * @author Andrew Meadows   * @brief Simple line class that can compute nearest approach between two lines @@ -6,21 +6,21 @@   * $LicenseInfo:firstyear=2006&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -33,87 +33,87 @@  const F32 SOME_VERY_SMALL_NUMBER = 1.0e-8f;  LLLine::LLLine() -:	mPoint(0.f, 0.f, 0.f), -	mDirection(1.f, 0.f, 0.f) +:   mPoint(0.f, 0.f, 0.f), +    mDirection(1.f, 0.f, 0.f)  { }  LLLine::LLLine( const LLVector3& first_point, const LLVector3& second_point )  { -	setPoints(first_point, second_point); +    setPoints(first_point, second_point);  }  void LLLine::setPoints( const LLVector3& first_point, const LLVector3& second_point )  { -	mPoint = first_point; -	mDirection = second_point - first_point; -	mDirection.normalize(); +    mPoint = first_point; +    mDirection = second_point - first_point; +    mDirection.normalize();  }  void LLLine::setPointDirection( const LLVector3& first_point, const LLVector3& second_point )  { -	setPoints(first_point, first_point + second_point); +    setPoints(first_point, first_point + second_point);  }  bool LLLine::intersects( const LLVector3& point, F32 radius ) const  { -	LLVector3 other_direction = point - mPoint; -	LLVector3 nearest_point = mPoint + mDirection * (other_direction * mDirection); -	F32 nearest_approach = (nearest_point - point).length(); -	return (nearest_approach <= radius); +    LLVector3 other_direction = point - mPoint; +    LLVector3 nearest_point = mPoint + mDirection * (other_direction * mDirection); +    F32 nearest_approach = (nearest_point - point).length(); +    return (nearest_approach <= radius);  }  // returns the point on this line that is closest to some_point  LLVector3 LLLine::nearestApproach( const LLVector3& some_point ) const  { -	return (mPoint + mDirection * ((some_point - mPoint) * mDirection)); +    return (mPoint + mDirection * ((some_point - mPoint) * mDirection));  }  // the accuracy of this method sucks when you give it two nearly  // parallel lines, so you should probably check for parallelism  // before you call this -//  +//  // returns the point on this line that is closest to other_line  LLVector3 LLLine::nearestApproach( const LLLine& other_line ) const  { -	LLVector3 between_points = other_line.mPoint - mPoint; -	F32 dir_dot_dir = mDirection * other_line.mDirection; -	F32 one_minus_dir_dot_dir = 1.0f - fabs(dir_dot_dir); -	if ( one_minus_dir_dot_dir < SOME_VERY_SMALL_NUMBER ) -	{ +    LLVector3 between_points = other_line.mPoint - mPoint; +    F32 dir_dot_dir = mDirection * other_line.mDirection; +    F32 one_minus_dir_dot_dir = 1.0f - fabs(dir_dot_dir); +    if ( one_minus_dir_dot_dir < SOME_VERY_SMALL_NUMBER ) +    {  #ifdef LL_DEBUG -		LL_WARNS() << "LLLine::nearestApproach() was given two very " -			<< "nearly parallel lines dir1 = " << mDirection  -			<< " dir2 = " << other_line.mDirection << " with 1-dot_product = "  -			<< one_minus_dir_dot_dir << LL_ENDL; +        LL_WARNS() << "LLLine::nearestApproach() was given two very " +            << "nearly parallel lines dir1 = " << mDirection +            << " dir2 = " << other_line.mDirection << " with 1-dot_product = " +            << one_minus_dir_dot_dir << LL_ENDL;  #endif -		// the lines are approximately parallel -		// We shouldn't fall in here because this check should have been made -		// BEFORE this function was called.  We dare not continue with the  -		// computations for fear of division by zero, but we have to return  -		// something so we return a bogus point -- caller beware. -		return 0.5f * (mPoint + other_line.mPoint); -	} - -	F32 odir_dot_bp = other_line.mDirection * between_points; - -	F32 numerator = 0; -	F32 denominator = 0; -	for (S32 i=0; i<3; i++) -	{ -		F32 factor = dir_dot_dir * other_line.mDirection.mV[i] - mDirection.mV[i]; -		numerator += ( between_points.mV[i] - odir_dot_bp * other_line.mDirection.mV[i] ) * factor; -		denominator -= factor * factor; -	} - -	F32 length_to_nearest_approach = numerator / denominator; - -	return mPoint + length_to_nearest_approach * mDirection; +        // the lines are approximately parallel +        // We shouldn't fall in here because this check should have been made +        // BEFORE this function was called.  We dare not continue with the +        // computations for fear of division by zero, but we have to return +        // something so we return a bogus point -- caller beware. +        return 0.5f * (mPoint + other_line.mPoint); +    } + +    F32 odir_dot_bp = other_line.mDirection * between_points; + +    F32 numerator = 0; +    F32 denominator = 0; +    for (S32 i=0; i<3; i++) +    { +        F32 factor = dir_dot_dir * other_line.mDirection.mV[i] - mDirection.mV[i]; +        numerator += ( between_points.mV[i] - odir_dot_bp * other_line.mDirection.mV[i] ) * factor; +        denominator -= factor * factor; +    } + +    F32 length_to_nearest_approach = numerator / denominator; + +    return mPoint + length_to_nearest_approach * mDirection;  }  std::ostream& operator<<( std::ostream& output_stream, const LLLine& line )  { -	output_stream << "{point=" << line.mPoint << "," << "dir=" << line.mDirection << "}"; -	return output_stream; +    output_stream << "{point=" << line.mPoint << "," << "dir=" << line.mDirection << "}"; +    return output_stream;  } @@ -124,72 +124,72 @@ F32 TOO_SMALL_FOR_DIVISION = 0.0001f;  // on success stores the intersection point in 'result'  bool LLLine::intersectsPlane( LLVector3& result, const LLLine& plane ) const  { -	// p = P + l * d     equation for a line -	//  -	// N * p = D         equation for a point -	// -	// N * (P + l * d) = D -	// N*P + l * (N*d) = D -	// l * (N*d) = D - N*P -	// l =  ( D - N*P ) / ( N*d ) -	// - -	F32 dot = plane.mDirection * mDirection; -	if (fabs(dot) < TOO_SMALL_FOR_DIVISION) -	{ -		return false; -	} - -	F32 plane_dot = plane.mDirection * plane.mPoint; -	F32 length = ( plane_dot - (plane.mDirection * mPoint) ) / dot; -	result = mPoint + length * mDirection; -	return true; +    // p = P + l * d     equation for a line +    // +    // N * p = D         equation for a point +    // +    // N * (P + l * d) = D +    // N*P + l * (N*d) = D +    // l * (N*d) = D - N*P +    // l =  ( D - N*P ) / ( N*d ) +    // + +    F32 dot = plane.mDirection * mDirection; +    if (fabs(dot) < TOO_SMALL_FOR_DIVISION) +    { +        return false; +    } + +    F32 plane_dot = plane.mDirection * plane.mPoint; +    F32 length = ( plane_dot - (plane.mDirection * mPoint) ) / dot; +    result = mPoint + length * mDirection; +    return true;  } -//static  -// returns 'true' if planes intersect, and stores the result  +//static +// returns 'true' if planes intersect, and stores the result  // the second and third arguments are treated as planes  // where mPoint is on the plane and mDirection is the normal -// result.mPoint will be the intersection line's closest approach  +// result.mPoint will be the intersection line's closest approach  // to first_plane.mPoint  bool LLLine::getIntersectionBetweenTwoPlanes( LLLine& result, const LLLine& first_plane, const LLLine& second_plane )  { -	// TODO -- if we ever get some generic matrix solving code in our libs -	// then we should just use that, since this problem is really just -	// linear algebra. - -	F32 dot = fabs(first_plane.mDirection * second_plane.mDirection); -	if (dot > ALMOST_PARALLEL) -	{ -		// the planes are nearly parallel -		return false; -	} - -	LLVector3 direction = first_plane.mDirection % second_plane.mDirection; -	direction.normalize(); - -	LLVector3 first_intersection; -	{ -		LLLine intersection_line(first_plane); -		intersection_line.mDirection = direction % first_plane.mDirection; -		intersection_line.mDirection.normalize(); -		intersection_line.intersectsPlane(first_intersection, second_plane); -	} - -	/* -	LLVector3 second_intersection; -	{ -		LLLine intersection_line(second_plane); -		intersection_line.mDirection = direction % second_plane.mDirection; -		intersection_line.mDirection.normalize(); -		intersection_line.intersectsPlane(second_intersection, first_plane); -	} -	*/ - -	result.mPoint = first_intersection; -	result.mDirection = direction; - -	return true; +    // TODO -- if we ever get some generic matrix solving code in our libs +    // then we should just use that, since this problem is really just +    // linear algebra. + +    F32 dot = fabs(first_plane.mDirection * second_plane.mDirection); +    if (dot > ALMOST_PARALLEL) +    { +        // the planes are nearly parallel +        return false; +    } + +    LLVector3 direction = first_plane.mDirection % second_plane.mDirection; +    direction.normalize(); + +    LLVector3 first_intersection; +    { +        LLLine intersection_line(first_plane); +        intersection_line.mDirection = direction % first_plane.mDirection; +        intersection_line.mDirection.normalize(); +        intersection_line.intersectsPlane(first_intersection, second_plane); +    } + +    /* +    LLVector3 second_intersection; +    { +        LLLine intersection_line(second_plane); +        intersection_line.mDirection = direction % second_plane.mDirection; +        intersection_line.mDirection.normalize(); +        intersection_line.intersectsPlane(second_intersection, first_plane); +    } +    */ + +    result.mPoint = first_intersection; +    result.mDirection = direction; + +    return true;  } diff --git a/indra/llmath/llline.h b/indra/llmath/llline.h index e1cbc1323e..33c1eb61a4 100644 --- a/indra/llmath/llline.h +++ b/indra/llmath/llline.h @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2006&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -38,42 +38,42 @@ const F32 DEFAULT_INTERSECTION_ERROR = 0.000001f;  class LLLine  {  public: -	LLLine(); -	LLLine( const LLVector3& first_point, const LLVector3& second_point ); -	virtual ~LLLine() {}; +    LLLine(); +    LLLine( const LLVector3& first_point, const LLVector3& second_point ); +    virtual ~LLLine() {}; -	void setPointDirection( const LLVector3& first_point, const LLVector3& second_point ); -	void setPoints( const LLVector3& first_point, const LLVector3& second_point ); +    void setPointDirection( const LLVector3& first_point, const LLVector3& second_point ); +    void setPoints( const LLVector3& first_point, const LLVector3& second_point ); -	bool intersects( const LLVector3& point, F32 radius = DEFAULT_INTERSECTION_ERROR ) const; +    bool intersects( const LLVector3& point, F32 radius = DEFAULT_INTERSECTION_ERROR ) const; -	// returns the point on this line that is closest to some_point -	LLVector3 nearestApproach( const LLVector3& some_point ) const; +    // returns the point on this line that is closest to some_point +    LLVector3 nearestApproach( const LLVector3& some_point ) const; -	// returns the point on this line that is closest to other_line -	LLVector3 nearestApproach( const LLLine& other_line ) const; +    // returns the point on this line that is closest to other_line +    LLVector3 nearestApproach( const LLLine& other_line ) const; -	friend std::ostream& operator<<( std::ostream& output_stream, const LLLine& line ); +    friend std::ostream& operator<<( std::ostream& output_stream, const LLLine& line ); -	// returns 'true' if this line intersects the plane -	// on success stores the intersection point in 'result' -	bool intersectsPlane( LLVector3& result, const LLLine& plane ) const; +    // returns 'true' if this line intersects the plane +    // on success stores the intersection point in 'result' +    bool intersectsPlane( LLVector3& result, const LLLine& plane ) const; -	// returns 'true' if planes intersect, and stores the result  -	// the second and third arguments are treated as planes -	// where mPoint is on the plane and mDirection is the normal -	// result.mPoint will be the intersection line's closest approach  -	// to first_plane.mPoint -	static bool getIntersectionBetweenTwoPlanes( LLLine& result, const LLLine& first_plane, const LLLine& second_plane ); +    // returns 'true' if planes intersect, and stores the result +    // the second and third arguments are treated as planes +    // where mPoint is on the plane and mDirection is the normal +    // result.mPoint will be the intersection line's closest approach +    // to first_plane.mPoint +    static bool getIntersectionBetweenTwoPlanes( LLLine& result, const LLLine& first_plane, const LLLine& second_plane ); -	const LLVector3& getPoint() const { return mPoint; } -	const LLVector3& getDirection() const { return mDirection; } +    const LLVector3& getPoint() const { return mPoint; } +    const LLVector3& getDirection() const { return mDirection; }  protected: -	// these are protected because some code assumes that the normal is  -	// always correct and properly normalized. -	LLVector3 mPoint; -	LLVector3 mDirection; +    // these are protected because some code assumes that the normal is +    // always correct and properly normalized. +    LLVector3 mPoint; +    LLVector3 mDirection;  }; diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index e4ccd81faf..f425b590e4 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -5,21 +5,21 @@   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -42,47 +42,47 @@  // work around for Windows & older gcc non-standard function names.  #if LL_WINDOWS  #include <float.h> -#define llisnan(val)	_isnan(val) -#define llfinite(val)	_finite(val) +#define llisnan(val)    _isnan(val) +#define llfinite(val)   _finite(val)  #elif (LL_LINUX && __GNUC__ <= 2) -#define llisnan(val)	isnan(val) -#define llfinite(val)	isfinite(val) +#define llisnan(val)    isnan(val) +#define llfinite(val)   isfinite(val)  #else -#define llisnan(val)	std::isnan(val) -#define llfinite(val)	std::isfinite(val) +#define llisnan(val)    std::isnan(val) +#define llfinite(val)   std::isfinite(val)  #endif  // Single Precision Floating Point Routines -// (There used to be more defined here, but they appeared to be redundant and  +// (There used to be more defined here, but they appeared to be redundant and  // were breaking some other includes. Removed by Falcon, reviewed by Andrew, 11/25/09)  /*#ifndef tanf -#define tanf(x)		((F32)tan((F64)(x))) +#define tanf(x)     ((F32)tan((F64)(x)))  #endif*/ -const F32	GRAVITY			= -9.8f; +const F32   GRAVITY         = -9.8f;  // mathematical constants -const F32	F_PI		= 3.1415926535897932384626433832795f; -const F32	F_TWO_PI	= 6.283185307179586476925286766559f; -const F32	F_PI_BY_TWO	= 1.5707963267948966192313216916398f; -const F32	F_SQRT_TWO_PI = 2.506628274631000502415765284811f; -const F32	F_E			= 2.71828182845904523536f; -const F32	F_SQRT2		= 1.4142135623730950488016887242097f; -const F32	F_SQRT3		= 1.73205080756888288657986402541f; -const F32	OO_SQRT2	= 0.7071067811865475244008443621049f; -const F32	OO_SQRT3	= 0.577350269189625764509f; -const F32	DEG_TO_RAD	= 0.017453292519943295769236907684886f; -const F32	RAD_TO_DEG	= 57.295779513082320876798154814105f; -const F32	F_APPROXIMATELY_ZERO = 0.00001f; -const F32	F_LN10		= 2.3025850929940456840179914546844f; -const F32	OO_LN10		= 0.43429448190325182765112891891661; -const F32	F_LN2		= 0.69314718056f; -const F32	OO_LN2		= 1.4426950408889634073599246810019f; - -const F32	F_ALMOST_ZERO	= 0.0001f; -const F32	F_ALMOST_ONE	= 1.0f - F_ALMOST_ZERO; - -const F32	GIMBAL_THRESHOLD = 0.000436f; // sets the gimballock threshold 0.025 away from +/-90 degrees +const F32   F_PI        = 3.1415926535897932384626433832795f; +const F32   F_TWO_PI    = 6.283185307179586476925286766559f; +const F32   F_PI_BY_TWO = 1.5707963267948966192313216916398f; +const F32   F_SQRT_TWO_PI = 2.506628274631000502415765284811f; +const F32   F_E         = 2.71828182845904523536f; +const F32   F_SQRT2     = 1.4142135623730950488016887242097f; +const F32   F_SQRT3     = 1.73205080756888288657986402541f; +const F32   OO_SQRT2    = 0.7071067811865475244008443621049f; +const F32   OO_SQRT3    = 0.577350269189625764509f; +const F32   DEG_TO_RAD  = 0.017453292519943295769236907684886f; +const F32   RAD_TO_DEG  = 57.295779513082320876798154814105f; +const F32   F_APPROXIMATELY_ZERO = 0.00001f; +const F32   F_LN10      = 2.3025850929940456840179914546844f; +const F32   OO_LN10     = 0.43429448190325182765112891891661; +const F32   F_LN2       = 0.69314718056f; +const F32   OO_LN2      = 1.4426950408889634073599246810019f; + +const F32   F_ALMOST_ZERO   = 0.0001f; +const F32   F_ALMOST_ONE    = 1.0f - F_ALMOST_ZERO; + +const F32   GIMBAL_THRESHOLD = 0.000436f; // sets the gimballock threshold 0.025 away from +/-90 degrees  // formula: GIMBAL_THRESHOLD = sin(DEG_TO_RAD * gimbal_threshold_angle);  // BUG: Eliminate in favor of F_APPROXIMATELY_ZERO above? @@ -97,7 +97,7 @@ inline bool is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f <  // x = <sign>1 <exponent>00000010 <mantissa>00000000000000000000000  // y = <sign>1 <exponent>00000001 <mantissa>11111111111111111111111  // -// interpreted as ints =  +// interpreted as ints =  // x = 10000001000000000000000000000000  // y = 10000000111111111111111111111111  // which is clearly a different of 1 in the least significant bit @@ -112,92 +112,92 @@ inline bool is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f <  // WARNING: NaNs can compare equal  // There is no special treatment of exceptional values like NaNs  // -// WARNING: Infinity is comparable with F32_MAX and negative  +// WARNING: Infinity is comparable with F32_MAX and negative  // infinity is comparable with F32_MIN  // handles negative and positive zeros  inline bool is_zero(F32 x)  { -	return (*(U32*)(&x) & 0x7fffffff) == 0; +    return (*(U32*)(&x) & 0x7fffffff) == 0;  }  inline bool is_approx_equal(F32 x, F32 y)  { -	const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02; -	return (std::abs((S32) ((U32&)x - (U32&)y) ) < COMPARE_MANTISSA_UP_TO_BIT); +    const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02; +    return (std::abs((S32) ((U32&)x - (U32&)y) ) < COMPARE_MANTISSA_UP_TO_BIT);  }  inline bool is_approx_equal(F64 x, F64 y)  { -	const S64 COMPARE_MANTISSA_UP_TO_BIT = 0x02; -	return (std::abs((S32) ((U64&)x - (U64&)y) ) < COMPARE_MANTISSA_UP_TO_BIT); +    const S64 COMPARE_MANTISSA_UP_TO_BIT = 0x02; +    return (std::abs((S32) ((U64&)x - (U64&)y) ) < COMPARE_MANTISSA_UP_TO_BIT);  }  inline S32 llabs(const S32 a)  { -	return S32(std::labs(a)); +    return S32(std::labs(a));  }  inline F32 llabs(const F32 a)  { -	return F32(std::fabs(a)); +    return F32(std::fabs(a));  }  inline F64 llabs(const F64 a)  { -	return F64(std::fabs(a)); +    return F64(std::fabs(a));  }  inline S32 lltrunc( F32 f )  {  #if LL_WINDOWS && !defined( __INTEL_COMPILER ) && (ADDRESS_SIZE == 32) -		// Avoids changing the floating point control word. -		// Add or subtract 0.5 - epsilon and then round -		const static U32 zpfp[] = { 0xBEFFFFFF, 0x3EFFFFFF }; -		S32 result; -		__asm { -			fld		f -			mov		eax,	f -			shr		eax,	29 -			and		eax,	4 -			fadd	dword ptr [zpfp + eax] -			fistp	result -		} -		return result; +        // Avoids changing the floating point control word. +        // Add or subtract 0.5 - epsilon and then round +        const static U32 zpfp[] = { 0xBEFFFFFF, 0x3EFFFFFF }; +        S32 result; +        __asm { +            fld     f +            mov     eax,    f +            shr     eax,    29 +            and     eax,    4 +            fadd    dword ptr [zpfp + eax] +            fistp   result +        } +        return result;  #else -		return (S32)f; +        return (S32)f;  #endif  }  inline S32 lltrunc( F64 f )  { -	return (S32)f; +    return (S32)f;  }  inline S32 llfloor( F32 f )  {  #if LL_WINDOWS && !defined( __INTEL_COMPILER ) && (ADDRESS_SIZE == 32) -		// Avoids changing the floating point control word. -		// Accurate (unlike Stereopsis version) for all values between S32_MIN and S32_MAX and slightly faster than Stereopsis version. -		// Add -(0.5 - epsilon) and then round -		const U32 zpfp = 0xBEFFFFFF; -		S32 result; -		__asm {  -			fld		f -			fadd	dword ptr [zpfp] -			fistp	result -		} -		return result; +        // Avoids changing the floating point control word. +        // Accurate (unlike Stereopsis version) for all values between S32_MIN and S32_MAX and slightly faster than Stereopsis version. +        // Add -(0.5 - epsilon) and then round +        const U32 zpfp = 0xBEFFFFFF; +        S32 result; +        __asm { +            fld     f +            fadd    dword ptr [zpfp] +            fistp   result +        } +        return result;  #else -		return (S32)floor(f); +        return (S32)floor(f);  #endif  }  inline S32 llceil( F32 f )  { -	// This could probably be optimized, but this works. -	return (S32)ceil(f); +    // This could probably be optimized, but this works. +    return (S32)ceil(f);  } @@ -205,7 +205,7 @@ inline S32 llceil( F32 f )  // Use this round.  Does an arithmetic round (0.5 always rounds up)  inline S32 ll_round(const F32 val)  { -	return llfloor(val + 0.5f); +    return llfloor(val + 0.5f);  }  #else // BOGUS_ROUND @@ -214,61 +214,61 @@ inline S32 ll_round(const F32 val)  // llfloor(val + 0.5f), which is consistent on all platforms.  inline S32 ll_round(const F32 val)  { -	#if LL_WINDOWS -		// Note: assumes that the floating point control word is set to rounding mode (the default) -		S32 ret_val; -		_asm fld	val -		_asm fistp	ret_val; -		return ret_val; -	#elif LL_LINUX -		// Note: assumes that the floating point control word is set -		// to rounding mode (the default) -		S32 ret_val; -		__asm__ __volatile__( "flds %1    \n\t" -							  "fistpl %0  \n\t" -							  : "=m" (ret_val) -							  : "m" (val) ); -		return ret_val; -	#else -		return llfloor(val + 0.5f); -	#endif +    #if LL_WINDOWS +        // Note: assumes that the floating point control word is set to rounding mode (the default) +        S32 ret_val; +        _asm fld    val +        _asm fistp  ret_val; +        return ret_val; +    #elif LL_LINUX +        // Note: assumes that the floating point control word is set +        // to rounding mode (the default) +        S32 ret_val; +        __asm__ __volatile__( "flds %1    \n\t" +                              "fistpl %0  \n\t" +                              : "=m" (ret_val) +                              : "m" (val) ); +        return ret_val; +    #else +        return llfloor(val + 0.5f); +    #endif  }  // A fast arithmentic round on intel, from Laurent de Soras http://ldesoras.free.fr  inline int round_int(double x)  { -	const float round_to_nearest = 0.5f; -	int i; -	__asm -	{ -		fld x -		fadd st, st (0) -		fadd round_to_nearest -		fistp i -		sar i, 1 -	} -	return (i); +    const float round_to_nearest = 0.5f; +    int i; +    __asm +    { +        fld x +        fadd st, st (0) +        fadd round_to_nearest +        fistp i +        sar i, 1 +    } +    return (i);  }  #endif // BOGUS_ROUND  inline F64 ll_round(const F64 val)  { -	return F64(floor(val + 0.5f)); +    return F64(floor(val + 0.5f));  }  inline F32 ll_round( F32 val, F32 nearest )  { -	return F32(floor(val * (1.0f / nearest) + 0.5f)) * nearest; +    return F32(floor(val * (1.0f / nearest) + 0.5f)) * nearest;  }  inline F64 ll_round( F64 val, F64 nearest )  { -	return F64(floor(val * (1.0 / nearest) + 0.5)) * nearest; +    return F64(floor(val * (1.0 / nearest) + 0.5)) * nearest;  }  // these provide minimum peak error  // -// avg  error = -0.013049  +// avg  error = -0.013049  // peak error = -31.4 dB  // RMS  error = -28.1 dB @@ -277,7 +277,7 @@ const F32 FAST_MAG_BETA = 0.397824734759f;  // these provide minimum RMS error  // -// avg  error = 0.000003  +// avg  error = 0.000003  // peak error = -32.6 dB  // RMS  error = -25.7 dB  // @@ -285,10 +285,10 @@ const F32 FAST_MAG_BETA = 0.397824734759f;  //const F32 FAST_MAG_BETA = 0.392699081699f;  inline F32 fastMagnitude(F32 a, F32 b) -{  -	a = (a > 0) ? a : -a; -	b = (b > 0) ? b : -b; -	return(FAST_MAG_ALPHA * llmax(a,b) + FAST_MAG_BETA * llmin(a,b)); +{ +    a = (a > 0) ? a : -a; +    b = (b > 0) ? b : -b; +    return(FAST_MAG_ALPHA * llmax(a,b) + FAST_MAG_BETA * llmin(a,b));  } @@ -299,16 +299,16 @@ inline F32 fastMagnitude(F32 a, F32 b)  //  // Culled from www.stereopsis.com/FPU.html -const F64 LL_DOUBLE_TO_FIX_MAGIC	= 68719476736.0*1.5;     //2^36 * 1.5,  (52-_shiftamt=36) uses limited precisicion to floor -const S32 LL_SHIFT_AMOUNT			= 16;                    //16.16 fixed point representation, +const F64 LL_DOUBLE_TO_FIX_MAGIC    = 68719476736.0*1.5;     //2^36 * 1.5,  (52-_shiftamt=36) uses limited precisicion to floor +const S32 LL_SHIFT_AMOUNT           = 16;                    //16.16 fixed point representation,  // Endian dependent code  #ifdef LL_LITTLE_ENDIAN -	#define LL_EXP_INDEX				1 -	#define LL_MAN_INDEX				0 +    #define LL_EXP_INDEX                1 +    #define LL_MAN_INDEX                0  #else -	#define LL_EXP_INDEX				0 -	#define LL_MAN_INDEX				1 +    #define LL_EXP_INDEX                0 +    #define LL_MAN_INDEX                1  #endif  //////////////////////////////////////////////// @@ -320,138 +320,138 @@ const S32 LL_SHIFT_AMOUNT			= 16;                    //16.16 fixed point represe  // http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf  static union  { -	double d; -	struct -	{ +    double d; +    struct +    {  #ifdef LL_LITTLE_ENDIAN -		S32 j, i; +        S32 j, i;  #else -		S32 i, j; +        S32 i, j;  #endif -	} n; +    } n;  } LLECO; // not sure what the name means  #define LL_EXP_A (1048576 * OO_LN2) // use 1512775 for integer -#define LL_EXP_C (60801)			// this value of C good for -4 < y < 4 +#define LL_EXP_C (60801)            // this value of C good for -4 < y < 4  #define LL_FAST_EXP(y) (LLECO.n.i = ll_round(F32(LL_EXP_A*(y))) + (1072693248 - LL_EXP_C), LLECO.d)  inline F32 llfastpow(const F32 x, const F32 y)  { -	return (F32)(LL_FAST_EXP(y * log(x))); +    return (F32)(LL_FAST_EXP(y * log(x)));  }  inline F32 snap_to_sig_figs(F32 foo, S32 sig_figs)  { -	// compute the power of ten -	F32 bar = 1.f; -	for (S32 i = 0; i < sig_figs; i++) -	{ -		bar *= 10.f; -	} +    // compute the power of ten +    F32 bar = 1.f; +    for (S32 i = 0; i < sig_figs; i++) +    { +        bar *= 10.f; +    } -	F32 sign = (foo > 0.f) ? 1.f : -1.f; -	F32 new_foo = F32( S64(foo * bar + sign * 0.5f)); -	new_foo /= bar; +    F32 sign = (foo > 0.f) ? 1.f : -1.f; +    F32 new_foo = F32( S64(foo * bar + sign * 0.5f)); +    new_foo /= bar; -	return new_foo; +    return new_foo;  } -inline F32 lerp(F32 a, F32 b, F32 u)  +inline F32 lerp(F32 a, F32 b, F32 u)  { -	return a + ((b - a) * u); +    return a + ((b - a) * u);  }  inline F32 lerp2d(F32 x00, F32 x01, F32 x10, F32 x11, F32 u, F32 v)  { -	F32 a = x00 + (x01-x00)*u; -	F32 b = x10 + (x11-x10)*u; -	F32 r = a + (b-a)*v; -	return r; +    F32 a = x00 + (x01-x00)*u; +    F32 b = x10 + (x11-x10)*u; +    F32 r = a + (b-a)*v; +    return r;  }  inline F32 ramp(F32 x, F32 a, F32 b)  { -	return (a == b) ? 0.0f : ((a - x) / (a - b)); +    return (a == b) ? 0.0f : ((a - x) / (a - b));  }  inline F32 rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2)  { -	return lerp(y1, y2, ramp(x, x1, x2)); +    return lerp(y1, y2, ramp(x, x1, x2));  }  inline F32 clamp_rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2)  { -	if (y1 < y2) -	{ -		return llclamp(rescale(x,x1,x2,y1,y2),y1,y2); -	} -	else -	{ -		return llclamp(rescale(x,x1,x2,y1,y2),y2,y1); -	} +    if (y1 < y2) +    { +        return llclamp(rescale(x,x1,x2,y1,y2),y1,y2); +    } +    else +    { +        return llclamp(rescale(x,x1,x2,y1,y2),y2,y1); +    }  }  inline F32 cubic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 )  { -	if (x <= x0) -		return s0; +    if (x <= x0) +        return s0; -	if (x >= x1) -		return s1; +    if (x >= x1) +        return s1; -	F32 f = (x - x0) / (x1 - x0); +    F32 f = (x - x0) / (x1 - x0); -	return	s0 + (s1 - s0) * (f * f) * (3.0f - 2.0f * f); +    return  s0 + (s1 - s0) * (f * f) * (3.0f - 2.0f * f);  }  inline F32 cubic_step( F32 x )  { -	x = llclampf(x); +    x = llclampf(x); -	return	(x * x) * (3.0f - 2.0f * x); +    return  (x * x) * (3.0f - 2.0f * x);  }  inline F32 quadratic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 )  { -	if (x <= x0) -		return s0; +    if (x <= x0) +        return s0; -	if (x >= x1) -		return s1; +    if (x >= x1) +        return s1; -	F32 f = (x - x0) / (x1 - x0); -	F32 f_squared = f * f; +    F32 f = (x - x0) / (x1 - x0); +    F32 f_squared = f * f; -	return	(s0 * (1.f - f_squared)) + ((s1 - s0) * f_squared); +    return  (s0 * (1.f - f_squared)) + ((s1 - s0) * f_squared);  }  inline F32 llsimple_angle(F32 angle)  { -	while(angle <= -F_PI) -		angle += F_TWO_PI; -	while(angle >  F_PI) -		angle -= F_TWO_PI; -	return angle; +    while(angle <= -F_PI) +        angle += F_TWO_PI; +    while(angle >  F_PI) +        angle -= F_TWO_PI; +    return angle;  }  //SDK - Renamed this to get_lower_power_two, since this is what this actually does.  inline U32 get_lower_power_two(U32 val, U32 max_power_two)  { -	if(!max_power_two) -	{ -		max_power_two = 1 << 31 ; -	} -	if(max_power_two & (max_power_two - 1)) -	{ -		return 0 ; -	} +    if(!max_power_two) +    { +        max_power_two = 1 << 31 ; +    } +    if(max_power_two & (max_power_two - 1)) +    { +        return 0 ; +    } + +    for(; val < max_power_two ; max_power_two >>= 1) ; -	for(; val < max_power_two ; max_power_two >>= 1) ; -	 -	return max_power_two ; +    return max_power_two ;  }  // calculate next highest power of two, limited by max_power_two @@ -462,76 +462,76 @@ inline U32 get_lower_power_two(U32 val, U32 max_power_two)  // WARNING: this only works with 32 bit ints.  inline U32 get_next_power_two(U32 val, U32 max_power_two)  { -	if(!max_power_two) -	{ -		max_power_two = 1 << 31 ; -	} +    if(!max_power_two) +    { +        max_power_two = 1 << 31 ; +    } -	if(val >= max_power_two) -	{ -		return max_power_two; -	} +    if(val >= max_power_two) +    { +        return max_power_two; +    } -	val--; -	val = (val >> 1) | val; -	val = (val >> 2) | val; -	val = (val >> 4) | val; -	val = (val >> 8) | val; -	val = (val >> 16) | val; -	val++; +    val--; +    val = (val >> 1) | val; +    val = (val >> 2) | val; +    val = (val >> 4) | val; +    val = (val >> 8) | val; +    val = (val >> 16) | val; +    val++; -	return val; +    return val;  }  //get the gaussian value given the linear distance from axis x and guassian value o  inline F32 llgaussian(F32 x, F32 o)  { -	return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o)); +    return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o));  }  //helper function for removing outliers  template <class VEC_TYPE>  inline void ll_remove_outliers(std::vector<VEC_TYPE>& data, F32 k)  { -	if (data.size() < 100) -	{ //not enough samples -		return; -	} +    if (data.size() < 100) +    { //not enough samples +        return; +    } -	VEC_TYPE Q1 = data[data.size()/4]; -	VEC_TYPE Q3 = data[data.size()-data.size()/4-1]; +    VEC_TYPE Q1 = data[data.size()/4]; +    VEC_TYPE Q3 = data[data.size()-data.size()/4-1]; -	if ((F32)(Q3-Q1) < 1.f) -	{ -		// not enough variation to detect outliers -		return; -	} +    if ((F32)(Q3-Q1) < 1.f) +    { +        // not enough variation to detect outliers +        return; +    } -	VEC_TYPE min = (VEC_TYPE) ((F32) Q1-k * (F32) (Q3-Q1)); -	VEC_TYPE max = (VEC_TYPE) ((F32) Q3+k * (F32) (Q3-Q1)); +    VEC_TYPE min = (VEC_TYPE) ((F32) Q1-k * (F32) (Q3-Q1)); +    VEC_TYPE max = (VEC_TYPE) ((F32) Q3+k * (F32) (Q3-Q1)); -	U32 i = 0; -	while (i < data.size() && data[i] < min) -	{ -		i++; -	} +    U32 i = 0; +    while (i < data.size() && data[i] < min) +    { +        i++; +    } -	S32 j = data.size()-1; -	while (j > 0 && data[j] > max) -	{ -		j--; -	} +    S32 j = data.size()-1; +    while (j > 0 && data[j] > max) +    { +        j--; +    } -	if (j < data.size()-1) -	{ -		data.erase(data.begin()+j, data.end()); -	} +    if (j < data.size()-1) +    { +        data.erase(data.begin()+j, data.end()); +    } -	if (i > 0) -	{ -		data.erase(data.begin(), data.begin()+i); -	} +    if (i > 0) +    { +        data.erase(data.begin(), data.begin()+i); +    }  }  // Converts given value from a linear RGB floating point value (0..1) to a gamma corrected (sRGB) value. @@ -551,7 +551,7 @@ inline float linearTosRGB(const float val) {  // Converts given value from a gamma corrected (sRGB) floating point value (0..1) to a linear color value.  // Some shaders require color values in linear space, while others require color values in gamma corrected (sRGB) space.  // Note: In our code, values labeled as sRGB are gamma corrected linear values, NOT linear values with monitor gamma applied -// Note: Stored color values should generally be gamma corrected sRGB.   +// Note: Stored color values should generally be gamma corrected sRGB.  //       If you're serializing the return value of this function, you're probably doing it wrong.  // Note: DO NOT cache the conversion.  This leads to error prone synchronization and is actually slower in the typical case due to cache misses.  inline float sRGBtoLinear(const float val) { diff --git a/indra/llmath/llmatrix3a.cpp b/indra/llmath/llmatrix3a.cpp index ab077abcb0..48a72e71e1 100644 --- a/indra/llmath/llmatrix3a.cpp +++ b/indra/llmath/llmatrix3a.cpp @@ -1,134 +1,134 @@ -/**  +/**   * @file llvector4a.cpp   * @brief SIMD vector implementation   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */  #include "llmath.h" -static LL_ALIGN_16(const F32 M_IDENT_3A[12]) =  -												{	1.f, 0.f, 0.f, 0.f, // Column 1 -													0.f, 1.f, 0.f, 0.f, // Column 2 -													0.f, 0.f, 1.f, 0.f }; // Column 3 +static LL_ALIGN_16(const F32 M_IDENT_3A[12]) = +                                                {   1.f, 0.f, 0.f, 0.f, // Column 1 +                                                    0.f, 1.f, 0.f, 0.f, // Column 2 +                                                    0.f, 0.f, 1.f, 0.f }; // Column 3  extern const LLMatrix3a LL_M3A_IDENTITY = *reinterpret_cast<const LLMatrix3a*> (M_IDENT_3A);  void LLMatrix3a::setMul( const LLMatrix3a& lhs, const LLMatrix3a& rhs )  { -	const LLVector4a col0 = lhs.getColumn(0); -	const LLVector4a col1 = lhs.getColumn(1); -	const LLVector4a col2 = lhs.getColumn(2); - -	for ( int i = 0; i < 3; i++ ) -	{ -		LLVector4a xxxx = _mm_load_ss( rhs.mColumns[i].getF32ptr() ); -		xxxx.splat<0>( xxxx ); -		xxxx.mul( col0 ); - -		{ -			LLVector4a yyyy = _mm_load_ss( rhs.mColumns[i].getF32ptr() +  1 ); -			yyyy.splat<0>( yyyy ); -			yyyy.mul( col1 );  -			xxxx.add( yyyy ); -		} - -		{ -			LLVector4a zzzz = _mm_load_ss( rhs.mColumns[i].getF32ptr() +  2 ); -			zzzz.splat<0>( zzzz ); -			zzzz.mul( col2 ); -			xxxx.add( zzzz ); -		} - -		xxxx.store4a( mColumns[i].getF32ptr() ); -	} -	 +    const LLVector4a col0 = lhs.getColumn(0); +    const LLVector4a col1 = lhs.getColumn(1); +    const LLVector4a col2 = lhs.getColumn(2); + +    for ( int i = 0; i < 3; i++ ) +    { +        LLVector4a xxxx = _mm_load_ss( rhs.mColumns[i].getF32ptr() ); +        xxxx.splat<0>( xxxx ); +        xxxx.mul( col0 ); + +        { +            LLVector4a yyyy = _mm_load_ss( rhs.mColumns[i].getF32ptr() +  1 ); +            yyyy.splat<0>( yyyy ); +            yyyy.mul( col1 ); +            xxxx.add( yyyy ); +        } + +        { +            LLVector4a zzzz = _mm_load_ss( rhs.mColumns[i].getF32ptr() +  2 ); +            zzzz.splat<0>( zzzz ); +            zzzz.mul( col2 ); +            xxxx.add( zzzz ); +        } + +        xxxx.store4a( mColumns[i].getF32ptr() ); +    } +  }  /*static */void LLMatrix3a::batchTransform( const LLMatrix3a& xform, const LLVector4a* src, int numVectors, LLVector4a* dst )  { -	const LLVector4a col0 = xform.getColumn(0); -	const LLVector4a col1 = xform.getColumn(1); -	const LLVector4a col2 = xform.getColumn(2); -	const LLVector4a* maxAddr = src + numVectors; - -	if ( numVectors & 0x1 ) -	{ -		LLVector4a xxxx = _mm_load_ss( (const F32*)src ); -		LLVector4a yyyy = _mm_load_ss( (const F32*)src + 1 ); -		LLVector4a zzzz = _mm_load_ss( (const F32*)src + 2 ); -		xxxx.splat<0>( xxxx ); -		yyyy.splat<0>( yyyy ); -		zzzz.splat<0>( zzzz ); -		xxxx.mul( col0 ); -		yyyy.mul( col1 );  -		zzzz.mul( col2 ); -		xxxx.add( yyyy ); -		xxxx.add( zzzz ); -		xxxx.store4a( (F32*)dst ); -		src++; -		dst++; -	} - - -	numVectors >>= 1; -	while ( src < maxAddr ) -	{ -		_mm_prefetch( (const char*)(src + 32 ), _MM_HINT_NTA ); -		_mm_prefetch( (const char*)(dst + 32), _MM_HINT_NTA ); -		LLVector4a xxxx = _mm_load_ss( (const F32*)src ); -		LLVector4a xxxx1= _mm_load_ss( (const F32*)(src + 1) ); - -		xxxx.splat<0>( xxxx ); -		xxxx1.splat<0>( xxxx1 ); -		xxxx.mul( col0 ); -		xxxx1.mul( col0 ); - -		{ -			LLVector4a yyyy = _mm_load_ss( (const F32*)src + 1 ); -			LLVector4a yyyy1 = _mm_load_ss( (const F32*)(src + 1) + 1); -			yyyy.splat<0>( yyyy ); -			yyyy1.splat<0>( yyyy1 ); -			yyyy.mul( col1 ); -			yyyy1.mul( col1 ); -			xxxx.add( yyyy ); -			xxxx1.add( yyyy1 ); -		} - -		{ -			LLVector4a zzzz = _mm_load_ss( (const F32*)(src) + 2 ); -			LLVector4a zzzz1 = _mm_load_ss( (const F32*)(++src) + 2 ); -			zzzz.splat<0>( zzzz ); -			zzzz1.splat<0>( zzzz1 ); -			zzzz.mul( col2 ); -			zzzz1.mul( col2 ); -			xxxx.add( zzzz ); -			xxxx1.add( zzzz1 ); -		} - -		xxxx.store4a(dst->getF32ptr()); -		src++; -		dst++; - -		xxxx1.store4a((F32*)dst++); -	} +    const LLVector4a col0 = xform.getColumn(0); +    const LLVector4a col1 = xform.getColumn(1); +    const LLVector4a col2 = xform.getColumn(2); +    const LLVector4a* maxAddr = src + numVectors; + +    if ( numVectors & 0x1 ) +    { +        LLVector4a xxxx = _mm_load_ss( (const F32*)src ); +        LLVector4a yyyy = _mm_load_ss( (const F32*)src + 1 ); +        LLVector4a zzzz = _mm_load_ss( (const F32*)src + 2 ); +        xxxx.splat<0>( xxxx ); +        yyyy.splat<0>( yyyy ); +        zzzz.splat<0>( zzzz ); +        xxxx.mul( col0 ); +        yyyy.mul( col1 ); +        zzzz.mul( col2 ); +        xxxx.add( yyyy ); +        xxxx.add( zzzz ); +        xxxx.store4a( (F32*)dst ); +        src++; +        dst++; +    } + + +    numVectors >>= 1; +    while ( src < maxAddr ) +    { +        _mm_prefetch( (const char*)(src + 32 ), _MM_HINT_NTA ); +        _mm_prefetch( (const char*)(dst + 32), _MM_HINT_NTA ); +        LLVector4a xxxx = _mm_load_ss( (const F32*)src ); +        LLVector4a xxxx1= _mm_load_ss( (const F32*)(src + 1) ); + +        xxxx.splat<0>( xxxx ); +        xxxx1.splat<0>( xxxx1 ); +        xxxx.mul( col0 ); +        xxxx1.mul( col0 ); + +        { +            LLVector4a yyyy = _mm_load_ss( (const F32*)src + 1 ); +            LLVector4a yyyy1 = _mm_load_ss( (const F32*)(src + 1) + 1); +            yyyy.splat<0>( yyyy ); +            yyyy1.splat<0>( yyyy1 ); +            yyyy.mul( col1 ); +            yyyy1.mul( col1 ); +            xxxx.add( yyyy ); +            xxxx1.add( yyyy1 ); +        } + +        { +            LLVector4a zzzz = _mm_load_ss( (const F32*)(src) + 2 ); +            LLVector4a zzzz1 = _mm_load_ss( (const F32*)(++src) + 2 ); +            zzzz.splat<0>( zzzz ); +            zzzz1.splat<0>( zzzz1 ); +            zzzz.mul( col2 ); +            zzzz1.mul( col2 ); +            xxxx.add( zzzz ); +            xxxx1.add( zzzz1 ); +        } + +        xxxx.store4a(dst->getF32ptr()); +        src++; +        dst++; + +        xxxx1.store4a((F32*)dst++); +    }  } diff --git a/indra/llmath/llmatrix3a.h b/indra/llmath/llmatrix3a.h index 9916cfd2da..dff6604ae5 100644 --- a/indra/llmath/llmatrix3a.h +++ b/indra/llmath/llmatrix3a.h @@ -1,31 +1,31 @@ -/**  +/**   * @file llmatrix3a.h   * @brief LLMatrix3a class header file - memory aligned and vectorized 3x3 matrix   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -#ifndef	LL_LLMATRIX3A_H -#define	LL_LLMATRIX3A_H +#ifndef LL_LLMATRIX3A_H +#define LL_LLMATRIX3A_H  /////////////////////////////  // LLMatrix3a, LLRotation @@ -38,91 +38,91 @@  // Huseby).  ///////////////////////////// -// LLMatrix3a is the base class for LLRotation, which should be used instead any time you're dealing with a  +// LLMatrix3a is the base class for LLRotation, which should be used instead any time you're dealing with a  // rotation matrix.  class LLMatrix3a  {  public: -	// Utility function for quickly transforming an array of LLVector4a's -	// For transforming a single LLVector4a, see LLVector4a::setRotated -	static void batchTransform( const LLMatrix3a& xform, const LLVector4a* src, int numVectors, LLVector4a* dst ); +    // Utility function for quickly transforming an array of LLVector4a's +    // For transforming a single LLVector4a, see LLVector4a::setRotated +    static void batchTransform( const LLMatrix3a& xform, const LLVector4a* src, int numVectors, LLVector4a* dst ); + +    // Utility function to obtain the identity matrix +    static inline const LLMatrix3a& getIdentity(); -	// Utility function to obtain the identity matrix -	static inline const LLMatrix3a& getIdentity(); +    ////////////////////////// +    // Ctors +    ////////////////////////// -	////////////////////////// -	// Ctors -	////////////////////////// -	 -	// Ctor -	LLMatrix3a() {} +    // Ctor +    LLMatrix3a() {} -	// Ctor for setting by columns -	inline LLMatrix3a( const LLVector4a& c0, const LLVector4a& c1, const LLVector4a& c2 ); +    // Ctor for setting by columns +    inline LLMatrix3a( const LLVector4a& c0, const LLVector4a& c1, const LLVector4a& c2 ); -	////////////////////////// -	// Get/Set -	////////////////////////// +    ////////////////////////// +    // Get/Set +    ////////////////////////// -	// Loads from an LLMatrix3 -	inline void loadu(const LLMatrix3& src); -	 -	// Set rows -	inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2); -	 -	// Set columns -	inline void setColumns(const LLVector4a& c0, const LLVector4a& c1, const LLVector4a& c2); +    // Loads from an LLMatrix3 +    inline void loadu(const LLMatrix3& src); -	// Get the read-only access to a specified column. Valid columns are 0-2, but the  -	// function is unchecked. You've been warned. -	inline const LLVector4a& getColumn(const U32 column) const; +    // Set rows +    inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2); -	///////////////////////// -	// Matrix modification -	///////////////////////// -	 -	// Set this matrix to the product of lhs and rhs ( this = lhs * rhs ) -	void setMul( const LLMatrix3a& lhs, const LLMatrix3a& rhs ); +    // Set columns +    inline void setColumns(const LLVector4a& c0, const LLVector4a& c1, const LLVector4a& c2); -	// Set this matrix to the transpose of src -	inline void setTranspose(const LLMatrix3a& src); +    // Get the read-only access to a specified column. Valid columns are 0-2, but the +    // function is unchecked. You've been warned. +    inline const LLVector4a& getColumn(const U32 column) const; -	// Set this matrix to a*w + b*(1-w) -	inline void setLerp(const LLMatrix3a& a, const LLMatrix3a& b, F32 w); +    ///////////////////////// +    // Matrix modification +    ///////////////////////// -	///////////////////////// -	// Matrix inspection -	///////////////////////// +    // Set this matrix to the product of lhs and rhs ( this = lhs * rhs ) +    void setMul( const LLMatrix3a& lhs, const LLMatrix3a& rhs ); -	// Sets all 4 elements in 'dest' to the determinant of this matrix. -	// If you will be using the determinant in subsequent ops with LLVector4a, use this version -	inline void getDeterminant( LLVector4a& dest ) const; +    // Set this matrix to the transpose of src +    inline void setTranspose(const LLMatrix3a& src); -	// Returns the determinant as an LLSimdScalar. Use this if you will be using the determinant -	// primary for scalar operations. -	inline LLSimdScalar getDeterminant() const; +    // Set this matrix to a*w + b*(1-w) +    inline void setLerp(const LLMatrix3a& a, const LLMatrix3a& b, F32 w); -	// Returns nonzero if rows 0-2 and colums 0-2 contain no NaN or INF values. Row 3 is ignored -	inline LLBool32 isFinite() const; +    ///////////////////////// +    // Matrix inspection +    ///////////////////////// -	// Returns true if this matrix is equal to 'rhs' up to 'tolerance' -	inline bool isApproximatelyEqual( const LLMatrix3a& rhs, F32 tolerance = F_APPROXIMATELY_ZERO ) const; +    // Sets all 4 elements in 'dest' to the determinant of this matrix. +    // If you will be using the determinant in subsequent ops with LLVector4a, use this version +    inline void getDeterminant( LLVector4a& dest ) const; + +    // Returns the determinant as an LLSimdScalar. Use this if you will be using the determinant +    // primary for scalar operations. +    inline LLSimdScalar getDeterminant() const; + +    // Returns nonzero if rows 0-2 and colums 0-2 contain no NaN or INF values. Row 3 is ignored +    inline LLBool32 isFinite() const; + +    // Returns true if this matrix is equal to 'rhs' up to 'tolerance' +    inline bool isApproximatelyEqual( const LLMatrix3a& rhs, F32 tolerance = F_APPROXIMATELY_ZERO ) const;  protected: -	LL_ALIGN_16(LLVector4a mColumns[3]); +    LL_ALIGN_16(LLVector4a mColumns[3]);  };  class LLRotation : public LLMatrix3a  {  public: -	 -	LLRotation() {} -	 -	// Returns true if this rotation is orthonormal with det ~= 1 -	inline bool isOkRotation() const;		 + +    LLRotation() {} + +    // Returns true if this rotation is orthonormal with det ~= 1 +    inline bool isOkRotation() const;  };  #endif diff --git a/indra/llmath/llmatrix3a.inl b/indra/llmath/llmatrix3a.inl index 37819fea3c..262810746e 100644 --- a/indra/llmath/llmatrix3a.inl +++ b/indra/llmath/llmatrix3a.inl @@ -1,25 +1,25 @@ -/**  +/**   * @file llmatrix3a.inl   * @brief LLMatrix3a inline definitions   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -29,91 +29,91 @@  inline LLMatrix3a::LLMatrix3a( const LLVector4a& c0, const LLVector4a& c1, const LLVector4a& c2 )  { -	setColumns( c0, c1, c2 ); +    setColumns( c0, c1, c2 );  }  inline void LLMatrix3a::loadu(const LLMatrix3& src)  { -	mColumns[0].load3(src.mMatrix[0]); -	mColumns[1].load3(src.mMatrix[1]); -	mColumns[2].load3(src.mMatrix[2]); +    mColumns[0].load3(src.mMatrix[0]); +    mColumns[1].load3(src.mMatrix[1]); +    mColumns[2].load3(src.mMatrix[2]);  }  inline void LLMatrix3a::setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2)  { -	mColumns[0] = r0; -	mColumns[1] = r1; -	mColumns[2] = r2; -	setTranspose( *this ); +    mColumns[0] = r0; +    mColumns[1] = r1; +    mColumns[2] = r2; +    setTranspose( *this );  }  inline void LLMatrix3a::setColumns(const LLVector4a& c0, const LLVector4a& c1, const LLVector4a& c2)  { -	mColumns[0] = c0; -	mColumns[1] = c1; -	mColumns[2] = c2; +    mColumns[0] = c0; +    mColumns[1] = c1; +    mColumns[2] = c2;  }  inline void LLMatrix3a::setTranspose(const LLMatrix3a& src)  { -	const LLQuad srcCol0 = src.mColumns[0]; -	const LLQuad srcCol1 = src.mColumns[1]; -	const LLQuad unpacklo = _mm_unpacklo_ps( srcCol0, srcCol1 ); -	mColumns[0] = _mm_movelh_ps( unpacklo, src.mColumns[2] ); -	mColumns[1] = _mm_shuffle_ps( _mm_movehl_ps( srcCol0, unpacklo ), src.mColumns[2], _MM_SHUFFLE(0, 1, 1, 0) ); -	mColumns[2] = _mm_shuffle_ps( _mm_unpackhi_ps( srcCol0, srcCol1 ), src.mColumns[2], _MM_SHUFFLE(0, 2, 1, 0) ); +    const LLQuad srcCol0 = src.mColumns[0]; +    const LLQuad srcCol1 = src.mColumns[1]; +    const LLQuad unpacklo = _mm_unpacklo_ps( srcCol0, srcCol1 ); +    mColumns[0] = _mm_movelh_ps( unpacklo, src.mColumns[2] ); +    mColumns[1] = _mm_shuffle_ps( _mm_movehl_ps( srcCol0, unpacklo ), src.mColumns[2], _MM_SHUFFLE(0, 1, 1, 0) ); +    mColumns[2] = _mm_shuffle_ps( _mm_unpackhi_ps( srcCol0, srcCol1 ), src.mColumns[2], _MM_SHUFFLE(0, 2, 1, 0) );  }  inline const LLVector4a& LLMatrix3a::getColumn(const U32 column) const  { -	llassert( column < 3 ); -	return mColumns[column]; +    llassert( column < 3 ); +    return mColumns[column];  }  inline void LLMatrix3a::setLerp(const LLMatrix3a& a, const LLMatrix3a& b, F32 w)  { -	mColumns[0].setLerp( a.mColumns[0], b.mColumns[0], w ); -	mColumns[1].setLerp( a.mColumns[1], b.mColumns[1], w ); -	mColumns[2].setLerp( a.mColumns[2], b.mColumns[2], w ); +    mColumns[0].setLerp( a.mColumns[0], b.mColumns[0], w ); +    mColumns[1].setLerp( a.mColumns[1], b.mColumns[1], w ); +    mColumns[2].setLerp( a.mColumns[2], b.mColumns[2], w );  }  inline LLBool32 LLMatrix3a::isFinite() const  { -	return mColumns[0].isFinite3() && mColumns[1].isFinite3() && mColumns[2].isFinite3(); +    return mColumns[0].isFinite3() && mColumns[1].isFinite3() && mColumns[2].isFinite3();  }  inline void LLMatrix3a::getDeterminant( LLVector4a& dest ) const  { -	LLVector4a col1xcol2; col1xcol2.setCross3( mColumns[1], mColumns[2] ); -	dest.setAllDot3( col1xcol2, mColumns[0] ); +    LLVector4a col1xcol2; col1xcol2.setCross3( mColumns[1], mColumns[2] ); +    dest.setAllDot3( col1xcol2, mColumns[0] );  }  inline LLSimdScalar LLMatrix3a::getDeterminant() const  { -	LLVector4a col1xcol2; col1xcol2.setCross3( mColumns[1], mColumns[2] ); -	return col1xcol2.dot3( mColumns[0] ); +    LLVector4a col1xcol2; col1xcol2.setCross3( mColumns[1], mColumns[2] ); +    return col1xcol2.dot3( mColumns[0] );  }  inline bool LLMatrix3a::isApproximatelyEqual( const LLMatrix3a& rhs, F32 tolerance /*= F_APPROXIMATELY_ZERO*/ ) const  { -	return rhs.getColumn(0).equals3(mColumns[0], tolerance)  -		&& rhs.getColumn(1).equals3(mColumns[1], tolerance)  -		&& rhs.getColumn(2).equals3(mColumns[2], tolerance);  +    return rhs.getColumn(0).equals3(mColumns[0], tolerance) +        && rhs.getColumn(1).equals3(mColumns[1], tolerance) +        && rhs.getColumn(2).equals3(mColumns[2], tolerance);  }  inline const LLMatrix3a& LLMatrix3a::getIdentity()  { -	extern const LLMatrix3a LL_M3A_IDENTITY; -	return LL_M3A_IDENTITY; +    extern const LLMatrix3a LL_M3A_IDENTITY; +    return LL_M3A_IDENTITY;  }  inline bool LLRotation::isOkRotation() const  { -	LLMatrix3a transpose; transpose.setTranspose( *this ); -	LLMatrix3a product; product.setMul( *this, transpose ); +    LLMatrix3a transpose; transpose.setTranspose( *this ); +    LLMatrix3a product; product.setMul( *this, transpose ); -	LLSimdScalar detMinusOne = getDeterminant() - 1.f; +    LLSimdScalar detMinusOne = getDeterminant() - 1.f; -	return product.isApproximatelyEqual( LLMatrix3a::getIdentity() ) && (detMinusOne.getAbs() < F_APPROXIMATELY_ZERO); +    return product.isApproximatelyEqual( LLMatrix3a::getIdentity() ) && (detMinusOne.getAbs() < F_APPROXIMATELY_ZERO);  } diff --git a/indra/llmath/llmatrix4a.cpp b/indra/llmath/llmatrix4a.cpp index fe8f0b98f3..00e30a248b 100644 --- a/indra/llmath/llmatrix4a.cpp +++ b/indra/llmath/llmatrix4a.cpp @@ -33,48 +33,48 @@  // necessarily the fastest way to implement.  void matMulBoundBox(const LLMatrix4a &mat, const LLVector4a *in_extents, LLVector4a *out_extents)  { -		//get 8 corners of bounding box -		LLVector4Logical mask[6]; +        //get 8 corners of bounding box +        LLVector4Logical mask[6]; -		for (U32 i = 0; i < 6; ++i) -		{ -			mask[i].clear(); -		} +        for (U32 i = 0; i < 6; ++i) +        { +            mask[i].clear(); +        } -		mask[0].setElement<2>(); //001 -		mask[1].setElement<1>(); //010 -		mask[2].setElement<1>(); //011 -		mask[2].setElement<2>(); -		mask[3].setElement<0>(); //100 -		mask[4].setElement<0>(); //101 -		mask[4].setElement<2>(); -		mask[5].setElement<0>(); //110 -		mask[5].setElement<1>(); +        mask[0].setElement<2>(); //001 +        mask[1].setElement<1>(); //010 +        mask[2].setElement<1>(); //011 +        mask[2].setElement<2>(); +        mask[3].setElement<0>(); //100 +        mask[4].setElement<0>(); //101 +        mask[4].setElement<2>(); +        mask[5].setElement<0>(); //110 +        mask[5].setElement<1>(); -		LLVector4a v[8]; +        LLVector4a v[8]; -		v[6] = in_extents[0]; -		v[7] = in_extents[1]; +        v[6] = in_extents[0]; +        v[7] = in_extents[1]; -		for (U32 i = 0; i < 6; ++i) -		{ -			v[i].setSelectWithMask(mask[i], in_extents[0], in_extents[1]); -		} +        for (U32 i = 0; i < 6; ++i) +        { +            v[i].setSelectWithMask(mask[i], in_extents[0], in_extents[1]); +        } -		LLVector4a tv[8]; +        LLVector4a tv[8]; -		//transform bounding box into drawable space -		for (U32 i = 0; i < 8; ++i) -		{ -			mat.affineTransform(v[i], tv[i]); -		} -	 -		//find bounding box -		out_extents[0] = out_extents[1] = tv[0]; +        //transform bounding box into drawable space +        for (U32 i = 0; i < 8; ++i) +        { +            mat.affineTransform(v[i], tv[i]); +        } -		for (U32 i = 1; i < 8; ++i) -		{ -			out_extents[0].setMin(out_extents[0], tv[i]); -			out_extents[1].setMax(out_extents[1], tv[i]); -		} +        //find bounding box +        out_extents[0] = out_extents[1] = tv[0]; + +        for (U32 i = 1; i < 8; ++i) +        { +            out_extents[0].setMin(out_extents[0], tv[i]); +            out_extents[1].setMax(out_extents[1], tv[i]); +        }  } diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 2cf50e9cd2..348feba27e 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -1,31 +1,31 @@ -/**  +/**   * @file llmatrix4a.h   * @brief LLMatrix4a class header file - memory aligned and vectorized 4x4 matrix   *   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -#ifndef	LL_LLMATRIX4A_H -#define	LL_LLMATRIX4A_H +#ifndef LL_LLMATRIX4A_H +#define LL_LLMATRIX4A_H  #include "llvector4a.h"  #include "m4math.h" @@ -34,7 +34,7 @@  class LLMatrix4a  {  public: -	LL_ALIGN_16(LLVector4a mMatrix[4]); +    LL_ALIGN_16(LLVector4a mMatrix[4]);      LLMatrix4a()      { @@ -56,13 +56,13 @@ public:          return (F32*)&mMatrix;      } -	inline void clear() -	{ -		mMatrix[0].clear(); -		mMatrix[1].clear(); -		mMatrix[2].clear(); -		mMatrix[3].clear(); -	} +    inline void clear() +    { +        mMatrix[0].clear(); +        mMatrix[1].clear(); +        mMatrix[2].clear(); +        mMatrix[3].clear(); +    }      inline void setIdentity()      { @@ -72,14 +72,14 @@ public:          mMatrix[3].set(0.f, 0.f, 0.f, 1.f);      } -	inline void loadu(const LLMatrix4& src) -	{ -		mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]); -		mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]); -		mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]); -		mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]); -	} -     +    inline void loadu(const LLMatrix4& src) +    { +        mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]); +        mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]); +        mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]); +        mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]); +    } +      inline void loadu(const F32* src)      {          mMatrix[0] = _mm_loadu_ps(src); @@ -88,90 +88,90 @@ public:          mMatrix[3] = _mm_loadu_ps(src+12);      } -	inline void loadu(const LLMatrix3& src) -	{ -		mMatrix[0].load3(src.mMatrix[0]); -		mMatrix[1].load3(src.mMatrix[1]); -		mMatrix[2].load3(src.mMatrix[2]); -		mMatrix[3].set(0,0,0,1.f); -	} - -	inline void add(const LLMatrix4a& rhs) -	{ -		mMatrix[0].add(rhs.mMatrix[0]); -		mMatrix[1].add(rhs.mMatrix[1]); -		mMatrix[2].add(rhs.mMatrix[2]); -		mMatrix[3].add(rhs.mMatrix[3]); -	} - -	inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2) -	{ -		mMatrix[0] = r0; -		mMatrix[1] = r1; -		mMatrix[2] = r2; -	} - -	inline void setMul(const LLMatrix4a& m, const F32 s) -	{ -		mMatrix[0].setMul(m.mMatrix[0], s); -		mMatrix[1].setMul(m.mMatrix[1], s); -		mMatrix[2].setMul(m.mMatrix[2], s); -		mMatrix[3].setMul(m.mMatrix[3], s); -	} - -	inline void setLerp(const LLMatrix4a& a, const LLMatrix4a& b, F32 w) -	{ -		LLVector4a d0,d1,d2,d3; -		d0.setSub(b.mMatrix[0], a.mMatrix[0]); -		d1.setSub(b.mMatrix[1], a.mMatrix[1]); -		d2.setSub(b.mMatrix[2], a.mMatrix[2]); -		d3.setSub(b.mMatrix[3], a.mMatrix[3]); - -		// this = a + d*w -		 -		d0.mul(w); -		d1.mul(w); -		d2.mul(w); -		d3.mul(w); - -		mMatrix[0].setAdd(a.mMatrix[0],d0); -		mMatrix[1].setAdd(a.mMatrix[1],d1); -		mMatrix[2].setAdd(a.mMatrix[2],d2); -		mMatrix[3].setAdd(a.mMatrix[3],d3); -	} - -	inline void rotate(const LLVector4a& v, LLVector4a& res) const -	{ -		LLVector4a y,z; - -		res = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); -		y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); -		z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); -		 -		res.mul(mMatrix[0]); -		y.mul(mMatrix[1]); -		z.mul(mMatrix[2]); - -		res.add(y); -		res.add(z); -	} - -	inline void affineTransformSSE(const LLVector4a& v, LLVector4a& res) const -	{ -		LLVector4a x,y,z; - -		x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); -		y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); -		z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); -		 -		x.mul(mMatrix[0]); -		y.mul(mMatrix[1]); -		z.mul(mMatrix[2]); - -		x.add(y); -		z.add(mMatrix[3]); -		res.setAdd(x,z); -	} +    inline void loadu(const LLMatrix3& src) +    { +        mMatrix[0].load3(src.mMatrix[0]); +        mMatrix[1].load3(src.mMatrix[1]); +        mMatrix[2].load3(src.mMatrix[2]); +        mMatrix[3].set(0,0,0,1.f); +    } + +    inline void add(const LLMatrix4a& rhs) +    { +        mMatrix[0].add(rhs.mMatrix[0]); +        mMatrix[1].add(rhs.mMatrix[1]); +        mMatrix[2].add(rhs.mMatrix[2]); +        mMatrix[3].add(rhs.mMatrix[3]); +    } + +    inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2) +    { +        mMatrix[0] = r0; +        mMatrix[1] = r1; +        mMatrix[2] = r2; +    } + +    inline void setMul(const LLMatrix4a& m, const F32 s) +    { +        mMatrix[0].setMul(m.mMatrix[0], s); +        mMatrix[1].setMul(m.mMatrix[1], s); +        mMatrix[2].setMul(m.mMatrix[2], s); +        mMatrix[3].setMul(m.mMatrix[3], s); +    } + +    inline void setLerp(const LLMatrix4a& a, const LLMatrix4a& b, F32 w) +    { +        LLVector4a d0,d1,d2,d3; +        d0.setSub(b.mMatrix[0], a.mMatrix[0]); +        d1.setSub(b.mMatrix[1], a.mMatrix[1]); +        d2.setSub(b.mMatrix[2], a.mMatrix[2]); +        d3.setSub(b.mMatrix[3], a.mMatrix[3]); + +        // this = a + d*w + +        d0.mul(w); +        d1.mul(w); +        d2.mul(w); +        d3.mul(w); + +        mMatrix[0].setAdd(a.mMatrix[0],d0); +        mMatrix[1].setAdd(a.mMatrix[1],d1); +        mMatrix[2].setAdd(a.mMatrix[2],d2); +        mMatrix[3].setAdd(a.mMatrix[3],d3); +    } + +    inline void rotate(const LLVector4a& v, LLVector4a& res) const +    { +        LLVector4a y,z; + +        res = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); +        y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); +        z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); + +        res.mul(mMatrix[0]); +        y.mul(mMatrix[1]); +        z.mul(mMatrix[2]); + +        res.add(y); +        res.add(z); +    } + +    inline void affineTransformSSE(const LLVector4a& v, LLVector4a& res) const +    { +        LLVector4a x,y,z; + +        x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); +        y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); +        z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); + +        x.mul(mMatrix[0]); +        y.mul(mMatrix[1]); +        z.mul(mMatrix[2]); + +        x.add(y); +        z.add(mMatrix[3]); +        res.setAdd(x,z); +    }      inline void affineTransformNonSSE(const LLVector4a& v, LLVector4a& res) const      { @@ -182,7 +182,7 @@ public:          res.set(x,y,z,w);      } -	inline void affineTransform(const LLVector4a& v, LLVector4a& res) const +    inline void affineTransform(const LLVector4a& v, LLVector4a& res) const      {          affineTransformSSE(v,res);      } @@ -226,7 +226,7 @@ inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m)  {      s << "[" << m.mMatrix[0] << ", " << m.mMatrix[1] << ", " << m.mMatrix[2] << ", " << m.mMatrix[3] << "]";      return s; -}  +}  void matMulBoundBox(const LLMatrix4a &a, const LLVector4a *in_extents, LLVector4a *out_extents); diff --git a/indra/llmath/llmodularmath.cpp b/indra/llmath/llmodularmath.cpp index cdc20028bf..7a22866b5e 100644 --- a/indra/llmath/llmodularmath.cpp +++ b/indra/llmath/llmodularmath.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file llmodularmath.cpp   * @brief LLModularMath class implementation   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ diff --git a/indra/llmath/llmodularmath.h b/indra/llmath/llmodularmath.h index 0d4d28fadc..e0ae71417a 100644 --- a/indra/llmath/llmodularmath.h +++ b/indra/llmath/llmodularmath.h @@ -1,25 +1,25 @@ -/**  +/**   * @file llmodularmath.h   * @brief Useful modular math functions.   *   * $LicenseInfo:firstyear=2008&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -32,21 +32,21 @@ namespace LLModularMath      // Return difference between lhs and rhs      // treating the U32 operands and result      // as unsigned values of given width. -	template<int width> -	inline U32 subtract(U32 lhs, U32 rhs) -	{ -		// Generate a bit mask which will truncate -		// unsigned values to given width at compile time. -		const U32 mask = (1 << width) - 1; -		 -		// Operands are unsigned, so modular -		// arithmetic applies. If lhs < rhs, -		// difference will wrap in to lower -		// bits of result, which is then masked -		// to give a value that can be represented -		// by an unsigned value of width bits. -		return mask & (lhs - rhs); -	}	 +    template<int width> +    inline U32 subtract(U32 lhs, U32 rhs) +    { +        // Generate a bit mask which will truncate +        // unsigned values to given width at compile time. +        const U32 mask = (1 << width) - 1; + +        // Operands are unsigned, so modular +        // arithmetic applies. If lhs < rhs, +        // difference will wrap in to lower +        // bits of result, which is then masked +        // to give a value that can be represented +        // by an unsigned value of width bits. +        return mask & (lhs - rhs); +    }  }  #endif diff --git a/indra/llmath/lloctree.cpp b/indra/llmath/lloctree.cpp index 3fcb3a27d7..1d87ca797f 100644 --- a/indra/llmath/lloctree.cpp +++ b/indra/llmath/lloctree.cpp @@ -1,24 +1,24 @@ -/**  +/**   * @file lloctree.cpp   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 318ee65cc0..88ba006269 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -1,25 +1,25 @@ -/**  +/**   * @file lloctree.h - * @brief Octree declaration.  + * @brief Octree declaration.   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -61,11 +61,11 @@ template <class T, typename T_PTR>  class LLOctreeListener: public LLTreeListener<T>  {  public: -	typedef LLTreeListener<T> BaseType; +    typedef LLTreeListener<T> BaseType;      typedef LLOctreeNode<T, T_PTR> oct_node; -	virtual void handleChildAddition(const oct_node* parent, oct_node* child) = 0; -	virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0; +    virtual void handleChildAddition(const oct_node* parent, oct_node* child) = 0; +    virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0;  };  template <class T, typename T_PTR> @@ -80,7 +80,7 @@ template <class T, typename T_PTR>  class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T, T_PTR>  {  public: -	virtual void traverse(const LLOctreeNode<T, T_PTR>* node) override; +    virtual void traverse(const LLOctreeNode<T, T_PTR>* node) override;  };  template <class T, typename T_PTR> @@ -94,7 +94,7 @@ public:      typedef std::vector<T_PTR>                                  element_list;      typedef typename element_list::iterator                     element_iter;      typedef typename element_list::const_iterator               const_element_iter; -	typedef typename std::vector<LLTreeListener<T>*>::iterator	tree_listener_iter; +    typedef typename std::vector<LLTreeListener<T>*>::iterator  tree_listener_iter;      typedef LLOctreeNode<T, T_PTR>**                            child_list;      typedef LLOctreeNode<T, T_PTR>**                            child_iter; @@ -107,568 +107,568 @@ public:          NO_CHILD_NODES = 255 // Note: This is an U8 to match the max value in mChildMap[]      }; -	LLOctreeNode(	const LLVector4a& center,  -					const LLVector4a& size,  -					BaseType* parent,  -					U8 octant = NO_CHILD_NODES) -	:	mParent((oct_node*)parent),  -		mOctant(octant)  -	{  -		llassert(size[0] >= gOctreeMinSize*0.5f); - -		mCenter = center; -		mSize = size; - -		updateMinMax(); -		if ((mOctant == NO_CHILD_NODES) && mParent) -		{ -			mOctant = ((oct_node*) mParent)->getOctant(mCenter); -		} - -		clearChildren(); -	} - -	virtual ~LLOctreeNode() -	{  -		BaseType::destroyListeners(); -		 +    LLOctreeNode(   const LLVector4a& center, +                    const LLVector4a& size, +                    BaseType* parent, +                    U8 octant = NO_CHILD_NODES) +    :   mParent((oct_node*)parent), +        mOctant(octant) +    { +        llassert(size[0] >= gOctreeMinSize*0.5f); + +        mCenter = center; +        mSize = size; + +        updateMinMax(); +        if ((mOctant == NO_CHILD_NODES) && mParent) +        { +            mOctant = ((oct_node*) mParent)->getOctant(mCenter); +        } + +        clearChildren(); +    } + +    virtual ~LLOctreeNode() +    { +        BaseType::destroyListeners(); +          const U32 element_count = getElementCount();          for (U32 i = 0; i < element_count; ++i) -		{ -			mData[i]->setBinIndex(-1); -			mData[i] = NULL; -		} - -		mData.clear(); - -		for (U32 i = 0; i < getChildCount(); i++) -		{ -			delete getChild(i); -		}  -	} - -	inline const BaseType* getParent()	const			{ return mParent; } -	inline void setParent(BaseType* parent)				{ mParent = (oct_node*) parent; } -	inline const LLVector4a& getCenter() const			{ return mCenter; } -	inline const LLVector4a& getSize() const			{ return mSize; } -	inline void setCenter(const LLVector4a& center)		{ mCenter = center; } -	inline void setSize(const LLVector4a& size)			{ mSize = size; } -    inline oct_node* getNodeAt(T* data)					{ return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } -	inline U8 getOctant() const							{ return mOctant; } -	inline const oct_node*	getOctParent() const		{ return (const oct_node*) getParent(); } -	inline oct_node* getOctParent() 					{ return (oct_node*) getParent(); } -	 -	U8 getOctant(const LLVector4a& pos) const			//get the octant pos is in -	{ -		return (U8) (pos.greaterThan(mCenter).getGatheredBits() & 0x7); -	} -	 -	inline bool isInside(const LLVector4a& pos, const F32& rad) const -	{ -		return rad <= mSize[0]*2.f && isInside(pos);  -	} - -	inline bool isInside(T* data) const -	{  -		return isInside(data->getPositionGroup(), data->getBinRadius()); -	} - -	bool isInside(const LLVector4a& pos) const -	{ -		S32 gt = pos.greaterThan(mMax).getGatheredBits() & 0x7; -		if (gt) -		{ -			return false; -		} - -		S32 lt = pos.lessEqual(mMin).getGatheredBits() & 0x7; -		if (lt) -		{ -			return false; -		} -				 -		return true; -	} -	 -	void updateMinMax() -	{ -		mMax.setAdd(mCenter, mSize); -		mMin.setSub(mCenter, mSize); -	} - -	inline oct_listener* getOctListener(U32 index)  -	{  -		return (oct_listener*) BaseType::getListener(index);  -	} - -	inline bool contains(T* xform) -	{ -		return contains(xform->getBinRadius()); -	} - -	bool contains(F32 radius) -	{ -		if (mParent == NULL) -		{	//root node contains nothing -			return false; -		} - -		F32 size = mSize[0]; -		F32 p_size = size * 2.f; - -		return (radius <= gOctreeMinSize && size <= gOctreeMinSize) || -				(radius <= p_size && radius > size); -	} - -	static void pushCenter(LLVector4a ¢er, const LLVector4a &size, const T* data) -	{ -		const LLVector4a& pos = data->getPositionGroup(); - -		LLVector4Logical gt = pos.greaterThan(center); - -		LLVector4a up; -		up = _mm_and_ps(size, gt); - -		LLVector4a down; -		down = _mm_andnot_ps(gt, size); - -		center.add(up); -		center.sub(down); -	} - -	void accept(oct_traveler* visitor)				{ visitor->visit(this); } -	virtual bool isLeaf() const						{ return mChildCount == 0; } -	 +        { +            mData[i]->setBinIndex(-1); +            mData[i] = NULL; +        } + +        mData.clear(); + +        for (U32 i = 0; i < getChildCount(); i++) +        { +            delete getChild(i); +        } +    } + +    inline const BaseType* getParent()  const           { return mParent; } +    inline void setParent(BaseType* parent)             { mParent = (oct_node*) parent; } +    inline const LLVector4a& getCenter() const          { return mCenter; } +    inline const LLVector4a& getSize() const            { return mSize; } +    inline void setCenter(const LLVector4a& center)     { mCenter = center; } +    inline void setSize(const LLVector4a& size)         { mSize = size; } +    inline oct_node* getNodeAt(T* data)                 { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } +    inline U8 getOctant() const                         { return mOctant; } +    inline const oct_node*  getOctParent() const        { return (const oct_node*) getParent(); } +    inline oct_node* getOctParent()                     { return (oct_node*) getParent(); } + +    U8 getOctant(const LLVector4a& pos) const           //get the octant pos is in +    { +        return (U8) (pos.greaterThan(mCenter).getGatheredBits() & 0x7); +    } + +    inline bool isInside(const LLVector4a& pos, const F32& rad) const +    { +        return rad <= mSize[0]*2.f && isInside(pos); +    } + +    inline bool isInside(T* data) const +    { +        return isInside(data->getPositionGroup(), data->getBinRadius()); +    } + +    bool isInside(const LLVector4a& pos) const +    { +        S32 gt = pos.greaterThan(mMax).getGatheredBits() & 0x7; +        if (gt) +        { +            return false; +        } + +        S32 lt = pos.lessEqual(mMin).getGatheredBits() & 0x7; +        if (lt) +        { +            return false; +        } + +        return true; +    } + +    void updateMinMax() +    { +        mMax.setAdd(mCenter, mSize); +        mMin.setSub(mCenter, mSize); +    } + +    inline oct_listener* getOctListener(U32 index) +    { +        return (oct_listener*) BaseType::getListener(index); +    } + +    inline bool contains(T* xform) +    { +        return contains(xform->getBinRadius()); +    } + +    bool contains(F32 radius) +    { +        if (mParent == NULL) +        {   //root node contains nothing +            return false; +        } + +        F32 size = mSize[0]; +        F32 p_size = size * 2.f; + +        return (radius <= gOctreeMinSize && size <= gOctreeMinSize) || +                (radius <= p_size && radius > size); +    } + +    static void pushCenter(LLVector4a ¢er, const LLVector4a &size, const T* data) +    { +        const LLVector4a& pos = data->getPositionGroup(); + +        LLVector4Logical gt = pos.greaterThan(center); + +        LLVector4a up; +        up = _mm_and_ps(size, gt); + +        LLVector4a down; +        down = _mm_andnot_ps(gt, size); + +        center.add(up); +        center.sub(down); +    } + +    void accept(oct_traveler* visitor)              { visitor->visit(this); } +    virtual bool isLeaf() const                     { return mChildCount == 0; } +      U32 getElementCount() const                     { return (U32)mData.size(); }      bool isEmpty() const                            { return mData.empty(); }      element_iter getDataBegin()                     { return mData.begin(); }      element_iter getDataEnd()                       { return mData.end(); }      const_element_iter getDataBegin() const         { return mData.cbegin(); }      const_element_iter getDataEnd() const           { return mData.cend(); } -		 -	U32 getChildCount()	const						{ return mChildCount; } -	oct_node* getChild(U32 index)					{ return mChild[index]; } -	const oct_node* getChild(U32 index) const		{ return mChild[index]; } -	child_list& getChildren()						{ return mChild; } -	const child_list& getChildren() const			{ return mChild; } -	 -	void accept(tree_traveler* visitor) const		{ visitor->visit(this); } -	void accept(oct_traveler* visitor) const		{ visitor->visit(this); } -	 -	void validateChildMap() -	{ -		for (U32 i = 0; i < 8; i++) -		{ -			U8 idx = mChildMap[i]; -			if (idx != NO_CHILD_NODES) -			{ -                oct_node* child = mChild[idx]; -				if (child->getOctant() != i) -				{ -					LL_ERRS() << "Invalid child map, bad octant data." << LL_ENDL; -				} +    U32 getChildCount() const                       { return mChildCount; } +    oct_node* getChild(U32 index)                   { return mChild[index]; } +    const oct_node* getChild(U32 index) const       { return mChild[index]; } +    child_list& getChildren()                       { return mChild; } +    const child_list& getChildren() const           { return mChild; } + +    void accept(tree_traveler* visitor) const       { visitor->visit(this); } +    void accept(oct_traveler* visitor) const        { visitor->visit(this); } + +    void validateChildMap() +    { +        for (U32 i = 0; i < 8; i++) +        { +            U8 idx = mChildMap[i]; +            if (idx != NO_CHILD_NODES) +            { +                oct_node* child = mChild[idx]; -				if (getOctant(child->getCenter()) != child->getOctant()) -				{ -					LL_ERRS() << "Invalid child octant compared to position data." << LL_ENDL; -				} -			} -		} -	} +                if (child->getOctant() != i) +                { +                    LL_ERRS() << "Invalid child map, bad octant data." << LL_ENDL; +                } + +                if (getOctant(child->getCenter()) != child->getOctant()) +                { +                    LL_ERRS() << "Invalid child octant compared to position data." << LL_ENDL; +                } +            } +        } +    } -	oct_node* getNodeAt(const LLVector4a& pos, const F32& rad) -	{  +    oct_node* getNodeAt(const LLVector4a& pos, const F32& rad) +    {          oct_node* node = this; -		if (node->isInside(pos, rad)) -		{ -			//do a quick search by octant -			U8 octant = node->getOctant(pos); -			 -			//traverse the tree until we find a node that has no node -			//at the appropriate octant or is smaller than the object.   -			//by definition, that node is the smallest node that contains  -			// the data -			U8 next_node = node->mChildMap[octant]; -			 -			while (next_node != NO_CHILD_NODES && node->getSize()[0] >= rad) -			{	 -				node = node->getChild(next_node); -				octant = node->getOctant(pos); -				next_node = node->mChildMap[octant]; -			} -		} -		else if (!node->contains(rad) && node->getParent()) -		{ //if we got here, data does not exist in this node +        if (node->isInside(pos, rad)) +        { +            //do a quick search by octant +            U8 octant = node->getOctant(pos); + +            //traverse the tree until we find a node that has no node +            //at the appropriate octant or is smaller than the object. +            //by definition, that node is the smallest node that contains +            // the data +            U8 next_node = node->mChildMap[octant]; + +            while (next_node != NO_CHILD_NODES && node->getSize()[0] >= rad) +            { +                node = node->getChild(next_node); +                octant = node->getOctant(pos); +                next_node = node->mChildMap[octant]; +            } +        } +        else if (!node->contains(rad) && node->getParent()) +        { //if we got here, data does not exist in this node              return ((oct_node*) node->getParent())->getNodeAt(pos, rad); -		} +        } + +        return node; +    } -		return node; -	} -	 -	virtual bool insert(T* data) -	{ +    virtual bool insert(T* data) +    {          //LL_PROFILE_ZONE_NAMED_COLOR("Octree::insert()",OCTREE_DEBUG_COLOR_INSERT); -		if (data == NULL || data->getBinIndex() != -1) -		{ -			OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << LL_ENDL; -			return false; -		} +        if (data == NULL || data->getBinIndex() != -1) +        { +            OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << LL_ENDL; +            return false; +        }          oct_node* parent = getOctParent(); -		//is it here? -		if (isInside(data->getPositionGroup())) -		{ -			if ((((getElementCount() < gOctreeMaxCapacity || getSize()[0] <= gOctreeMinSize) && contains(data->getBinRadius())) || -				(data->getBinRadius() > getSize()[0] &&	parent && parent->getElementCount() >= gOctreeMaxCapacity)))  -			{ //it belongs here +        //is it here? +        if (isInside(data->getPositionGroup())) +        { +            if ((((getElementCount() < gOctreeMaxCapacity || getSize()[0] <= gOctreeMinSize) && contains(data->getBinRadius())) || +                (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) +            { //it belongs here                  mData.push_back(data);                  data->setBinIndex(getElementCount() - 1); -				BaseType::insert(data); -				return true; -			} -			else -			{ 	 -				//find a child to give it to -				oct_node* child = NULL; -				for (U32 i = 0; i < getChildCount(); i++) -				{ -					child = getChild(i); -					if (child->isInside(data->getPositionGroup())) -					{ -						child->insert(data); -						return false; -					} -				} -				 -				//it's here, but no kids are in the right place, make a new kid -				LLVector4a center = getCenter(); -				LLVector4a size = getSize(); -				size.mul(0.5f); -		        		 -				//push center in direction of data +                BaseType::insert(data); +                return true; +            } +            else +            { +                //find a child to give it to +                oct_node* child = NULL; +                for (U32 i = 0; i < getChildCount(); i++) +                { +                    child = getChild(i); +                    if (child->isInside(data->getPositionGroup())) +                    { +                        child->insert(data); +                        return false; +                    } +                } + +                //it's here, but no kids are in the right place, make a new kid +                LLVector4a center = getCenter(); +                LLVector4a size = getSize(); +                size.mul(0.5f); + +                //push center in direction of data                  oct_node::pushCenter(center, size, data); -				// handle case where floating point number gets too small -				LLVector4a val; -				val.setSub(center, getCenter()); -				val.setAbs(val); -				LLVector4a min_diff(gOctreeMinSize); +                // handle case where floating point number gets too small +                LLVector4a val; +                val.setSub(center, getCenter()); +                val.setAbs(val); +                LLVector4a min_diff(gOctreeMinSize); -				S32 lt = val.lessThan(min_diff).getGatheredBits() & 0x7; +                S32 lt = val.lessThan(min_diff).getGatheredBits() & 0x7; -				if( lt == 0x7 ) -				{ +                if( lt == 0x7 ) +                {                      mData.push_back(data);                      data->setBinIndex(getElementCount() - 1); -					BaseType::insert(data); -					return true; -				} +                    BaseType::insert(data); +                    return true; +                }  #if LL_OCTREE_PARANOIA_CHECK -				if (getChildCount() == 8) -				{ -					//this really isn't possible, something bad has happened -					OCT_ERRS << "Octree detected floating point error and gave up." << LL_ENDL; -					return false; -				} -				 -				//make sure no existing node matches this position -				for (U32 i = 0; i < getChildCount(); i++) -				{ -					if (mChild[i]->getCenter().equals3(center)) -					{ -						OCT_ERRS << "Octree detected duplicate child center and gave up." << LL_ENDL; -						return false; -					} -				} +                if (getChildCount() == 8) +                { +                    //this really isn't possible, something bad has happened +                    OCT_ERRS << "Octree detected floating point error and gave up." << LL_ENDL; +                    return false; +                } + +                //make sure no existing node matches this position +                for (U32 i = 0; i < getChildCount(); i++) +                { +                    if (mChild[i]->getCenter().equals3(center)) +                    { +                        OCT_ERRS << "Octree detected duplicate child center and gave up." << LL_ENDL; +                        return false; +                    } +                }  #endif -				llassert(size[0] >= gOctreeMinSize*0.5f); -				//make the new kid +                llassert(size[0] >= gOctreeMinSize*0.5f); +                //make the new kid                  child = new oct_node(center, size, this); -				addChild(child); -								 -				child->insert(data); -			} -		} -		else if (parent) -		{ -			//it's not in here, give it to the root -			OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL; - -			oct_node* node = this; - -			while (parent) -			{ -				node = parent; -				parent = node->getOctParent(); -			} - -			node->insert(data); -		} -		else -		{ -			// It's not in here, and we are root. -			// LLOctreeRoot::insert() should have expanded -			// root by now, something is wrong -			OCT_ERRS << "Octree insertion failed! Root expansion failed." << LL_ENDL; -		} - -		return false; -	} - -	void _remove(T* data, S32 i) +                addChild(child); + +                child->insert(data); +            } +        } +        else if (parent) +        { +            //it's not in here, give it to the root +            OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL; + +            oct_node* node = this; + +            while (parent) +            { +                node = parent; +                parent = node->getOctParent(); +            } + +            node->insert(data); +        } +        else +        { +            // It's not in here, and we are root. +            // LLOctreeRoot::insert() should have expanded +            // root by now, something is wrong +            OCT_ERRS << "Octree insertion failed! Root expansion failed." << LL_ENDL; +        } + +        return false; +    } + +    void _remove(T* data, S32 i)      { //precondition -- getElementCount() > 0, idx is in range [0, getElementCount()) -		data->setBinIndex(-1);  -		 +        data->setBinIndex(-1); +          const U32 new_element_count = getElementCount() - 1; -		if (new_element_count > 0) -		{ -			if (new_element_count != i) -			{ -				mData[i] = mData[new_element_count]; //might unref data, do not access data after this point -				mData[i]->setBinIndex(i); -			} - -			mData[new_element_count] = NULL; -			mData.pop_back(); -		} -		else -		{ -			mData.clear(); -		} - -		this->notifyRemoval(data); -		checkAlive(); -	} - -	bool remove(T* data) -	{ +        if (new_element_count > 0) +        { +            if (new_element_count != i) +            { +                mData[i] = mData[new_element_count]; //might unref data, do not access data after this point +                mData[i]->setBinIndex(i); +            } + +            mData[new_element_count] = NULL; +            mData.pop_back(); +        } +        else +        { +            mData.clear(); +        } + +        this->notifyRemoval(data); +        checkAlive(); +    } + +    bool remove(T* data) +    {          //LL_PROFILE_ZONE_NAMED_COLOR("Octree::remove()", OCTREE_DEBUG_COLOR_REMOVE); -		S32 i = data->getBinIndex(); +        S32 i = data->getBinIndex();          if (i >= 0 && i < getElementCount()) -		{ -			if (mData[i] == data) -			{ //found it -				_remove(data, i); -				llassert(data->getBinIndex() == -1); -				return true; -			} -		} -		 -		if (isInside(data)) -		{ -			oct_node* dest = getNodeAt(data); - -			if (dest != this) -			{ -				bool ret = dest->remove(data); -				llassert(data->getBinIndex() == -1); -				return ret; -			} -		} - -		//SHE'S GONE MISSING... -		//none of the children have it, let's just brute force this bastard out -		//starting with the root node (UGLY CODE COMETH!) -		oct_node* parent = getOctParent(); -		oct_node* node = this; - -		while (parent != NULL) -		{ -			node = parent; -			parent = node->getOctParent(); -		} - -		//node is now root -		LL_WARNS() << "!!! OCTREE REMOVING ELEMENT BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << LL_ENDL; -		node->removeByAddress(data); -		llassert(data->getBinIndex() == -1); -		return true; -	} - -	void removeByAddress(T* data) -	{ +        { +            if (mData[i] == data) +            { //found it +                _remove(data, i); +                llassert(data->getBinIndex() == -1); +                return true; +            } +        } + +        if (isInside(data)) +        { +            oct_node* dest = getNodeAt(data); + +            if (dest != this) +            { +                bool ret = dest->remove(data); +                llassert(data->getBinIndex() == -1); +                return ret; +            } +        } + +        //SHE'S GONE MISSING... +        //none of the children have it, let's just brute force this bastard out +        //starting with the root node (UGLY CODE COMETH!) +        oct_node* parent = getOctParent(); +        oct_node* node = this; + +        while (parent != NULL) +        { +            node = parent; +            parent = node->getOctParent(); +        } + +        //node is now root +        LL_WARNS() << "!!! OCTREE REMOVING ELEMENT BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << LL_ENDL; +        node->removeByAddress(data); +        llassert(data->getBinIndex() == -1); +        return true; +    } + +    void removeByAddress(T* data) +    {          const U32 element_count = getElementCount();          for (U32 i = 0; i < element_count; ++i) -		{ -			if (mData[i] == data) -			{ //we have data -				_remove(data, i); -				LL_WARNS() << "FOUND!" << LL_ENDL; -				return; -			} -		} -		 -		for (U32 i = 0; i < getChildCount(); i++) -		{	//we don't contain data, so pass this guy down +        { +            if (mData[i] == data) +            { //we have data +                _remove(data, i); +                LL_WARNS() << "FOUND!" << LL_ENDL; +                return; +            } +        } + +        for (U32 i = 0; i < getChildCount(); i++) +        {   //we don't contain data, so pass this guy down              oct_node* child = (oct_node*) getChild(i); -			child->removeByAddress(data); -		} -	} - -	void clearChildren() -	{ -		mChildCount = 0; -		memset(mChildMap, NO_CHILD_NODES, sizeof(mChildMap)); -	} - -	void validate() -	{ +            child->removeByAddress(data); +        } +    } + +    void clearChildren() +    { +        mChildCount = 0; +        memset(mChildMap, NO_CHILD_NODES, sizeof(mChildMap)); +    } + +    void validate() +    {  #if LL_OCTREE_PARANOIA_CHECK -		for (U32 i = 0; i < getChildCount(); i++) -		{ -			mChild[i]->validate(); -			if (mChild[i]->getParent() != this) -			{ -				LL_ERRS() << "Octree child has invalid parent." << LL_ENDL; -			} -		} +        for (U32 i = 0; i < getChildCount(); i++) +        { +            mChild[i]->validate(); +            if (mChild[i]->getParent() != this) +            { +                LL_ERRS() << "Octree child has invalid parent." << LL_ENDL; +            } +        }  #endif -	} - -	virtual bool balance() -	{	 -		return false; -	} - -	void destroy() -	{ -		for (U32 i = 0; i < getChildCount(); i++)  -		{	 -			mChild[i]->destroy(); -			delete mChild[i]; -		} -	} - -	void addChild(oct_node* child, BOOL silent = FALSE)  -	{ +    } + +    virtual bool balance() +    { +        return false; +    } + +    void destroy() +    { +        for (U32 i = 0; i < getChildCount(); i++) +        { +            mChild[i]->destroy(); +            delete mChild[i]; +        } +    } + +    void addChild(oct_node* child, BOOL silent = FALSE) +    {  #if LL_OCTREE_PARANOIA_CHECK -		if (child->getSize().equals3(getSize())) -		{ -			OCT_ERRS << "Child size is same as parent size!" << LL_ENDL; -		} - -		for (U32 i = 0; i < getChildCount(); i++) -		{ -			if(!mChild[i]->getSize().equals3(child->getSize()))  -			{ -				OCT_ERRS <<"Invalid octree child size." << LL_ENDL; -			} -			if (mChild[i]->getCenter().equals3(child->getCenter())) -			{ -				OCT_ERRS <<"Duplicate octree child position." << LL_ENDL; -			} -		} - -		if (mChild.size() >= 8) -		{ -			OCT_ERRS <<"Octree node has too many children... why?" << LL_ENDL; -		} +        if (child->getSize().equals3(getSize())) +        { +            OCT_ERRS << "Child size is same as parent size!" << LL_ENDL; +        } + +        for (U32 i = 0; i < getChildCount(); i++) +        { +            if(!mChild[i]->getSize().equals3(child->getSize())) +            { +                OCT_ERRS <<"Invalid octree child size." << LL_ENDL; +            } +            if (mChild[i]->getCenter().equals3(child->getCenter())) +            { +                OCT_ERRS <<"Duplicate octree child position." << LL_ENDL; +            } +        } + +        if (mChild.size() >= 8) +        { +            OCT_ERRS <<"Octree node has too many children... why?" << LL_ENDL; +        }  #endif -		mChildMap[child->getOctant()] = mChildCount; - -		mChild[mChildCount] = child; -		++mChildCount; -		child->setParent(this); - -		if (!silent) -		{ -			for (U32 i = 0; i < this->getListenerCount(); i++) -			{ -				oct_listener* listener = getOctListener(i); -				listener->handleChildAddition(this, child); -			} -		} -	} - -	void removeChild(S32 index, BOOL destroy = FALSE) -	{ -		for (U32 i = 0; i < this->getListenerCount(); i++) -		{ -			oct_listener* listener = getOctListener(i); -			listener->handleChildRemoval(this, getChild(index)); -		} -		 -		if (destroy) -		{ -			mChild[index]->destroy(); -			delete mChild[index]; -		} - -		--mChildCount; - -		mChild[index] = mChild[mChildCount]; - -		//rebuild child map -		memset(mChildMap, NO_CHILD_NODES, sizeof(mChildMap)); - -		for (U32 i = 0; i < mChildCount; ++i) -		{ -			mChildMap[mChild[i]->getOctant()] = i; -		} - -		checkAlive(); -	} - -	void checkAlive() -	{ -		if (getChildCount() == 0 && getElementCount() == 0) -		{ -			oct_node* parent = getOctParent(); -			if (parent) -			{ -				parent->deleteChild(this); -			} -		} -	} - -	void deleteChild(oct_node* node) -	{ -		for (U32 i = 0; i < getChildCount(); i++) -		{ -			if (getChild(i) == node) -			{ -				removeChild(i, TRUE); -				return; -			} -		} - -		OCT_ERRS << "Octree failed to delete requested child." << LL_ENDL; -	} +        mChildMap[child->getOctant()] = mChildCount; + +        mChild[mChildCount] = child; +        ++mChildCount; +        child->setParent(this); + +        if (!silent) +        { +            for (U32 i = 0; i < this->getListenerCount(); i++) +            { +                oct_listener* listener = getOctListener(i); +                listener->handleChildAddition(this, child); +            } +        } +    } + +    void removeChild(S32 index, BOOL destroy = FALSE) +    { +        for (U32 i = 0; i < this->getListenerCount(); i++) +        { +            oct_listener* listener = getOctListener(i); +            listener->handleChildRemoval(this, getChild(index)); +        } + +        if (destroy) +        { +            mChild[index]->destroy(); +            delete mChild[index]; +        } + +        --mChildCount; + +        mChild[index] = mChild[mChildCount]; + +        //rebuild child map +        memset(mChildMap, NO_CHILD_NODES, sizeof(mChildMap)); + +        for (U32 i = 0; i < mChildCount; ++i) +        { +            mChildMap[mChild[i]->getOctant()] = i; +        } + +        checkAlive(); +    } + +    void checkAlive() +    { +        if (getChildCount() == 0 && getElementCount() == 0) +        { +            oct_node* parent = getOctParent(); +            if (parent) +            { +                parent->deleteChild(this); +            } +        } +    } + +    void deleteChild(oct_node* node) +    { +        for (U32 i = 0; i < getChildCount(); i++) +        { +            if (getChild(i) == node) +            { +                removeChild(i, TRUE); +                return; +            } +        } + +        OCT_ERRS << "Octree failed to delete requested child." << LL_ENDL; +    }  protected: -	typedef enum -	{ -		CENTER = 0, -		SIZE = 1, -		MAX = 2, -		MIN = 3 -	} eDName; - -	LLVector4a mCenter; -	LLVector4a mSize; -	LLVector4a mMax; -	LLVector4a mMin; -	 -	oct_node* mParent; -	U8 mOctant; +    typedef enum +    { +        CENTER = 0, +        SIZE = 1, +        MAX = 2, +        MIN = 3 +    } eDName; + +    LLVector4a mCenter; +    LLVector4a mSize; +    LLVector4a mMax; +    LLVector4a mMin; + +    oct_node* mParent; +    U8 mOctant;      oct_node* mChild[8]; -	U8 mChildMap[8]; -	U32 mChildCount; +    U8 mChildMap[8]; +    U32 mChildCount; -	element_list mData; -};  +    element_list mData; +};  //just like a regular node, except it might expand on insert and compress on balance  template <class T, typename T_PTR> @@ -678,152 +678,152 @@ public:      typedef LLOctreeNode<T, T_PTR> BaseType;      typedef LLOctreeNode<T, T_PTR> oct_node; -	LLOctreeRoot(const LLVector4a& center,  -				 const LLVector4a& size,  -				 BaseType* parent) -	:	BaseType(center, size, parent) -	{ -	} -	 -	bool balance() override -	{	 +    LLOctreeRoot(const LLVector4a& center, +                 const LLVector4a& size, +                 BaseType* parent) +    :   BaseType(center, size, parent) +    { +    } + +    bool balance() override +    {          //LL_PROFILE_ZONE_NAMED_COLOR("Octree::balance()",OCTREE_DEBUG_COLOR_BALANCE); -		if (this->getChildCount() == 1 &&  -			!(this->mChild[0]->isLeaf()) && -			this->mChild[0]->getElementCount() == 0) -		{ //if we have only one child and that child is an empty branch, make that child the root -			oct_node* child = this->mChild[0]; -					 -			//make the root node look like the child -			this->setCenter(this->mChild[0]->getCenter()); -			this->setSize(this->mChild[0]->getSize()); -			this->updateMinMax(); - -			//reset root node child list -			this->clearChildren(); - -			//copy the child's children into the root node silently  -			//(don't notify listeners of addition) -			for (U32 i = 0; i < child->getChildCount(); i++) -			{ -				this->addChild(child->getChild(i), TRUE); -			} - -			//destroy child -			child->clearChildren(); -			delete child; - -			return false; -		} -		 -		return true; -	} - -	// LLOctreeRoot::insert -	bool insert(T* data) override -	{ -		if (data == NULL)  -		{ -			OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE ROOT !!!" << LL_ENDL; -			return false; -		} -		 -		if (data->getBinRadius() > 4096.0) -		{ -			OCT_ERRS << "!!! ELEMENT EXCEEDS MAXIMUM SIZE IN OCTREE ROOT !!!" << LL_ENDL; -			return false; -		} -		 -		LLVector4a MAX_MAG; -		MAX_MAG.splat(1024.f*1024.f); - -		const LLVector4a& v = data->getPositionGroup(); - -		LLVector4a val; -		val.setSub(v, BaseType::mCenter); -		val.setAbs(val); -		S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7; - -		if (lt != 0x7) -		{ -			//OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << LL_ENDL; -			return false; -		} - -		if (this->getSize()[0] > data->getBinRadius() && this->isInside(data->getPositionGroup())) -		{ -			//we got it, just act like a branch -			oct_node* node = this->getNodeAt(data); -			if (node == this) -			{ +        if (this->getChildCount() == 1 && +            !(this->mChild[0]->isLeaf()) && +            this->mChild[0]->getElementCount() == 0) +        { //if we have only one child and that child is an empty branch, make that child the root +            oct_node* child = this->mChild[0]; + +            //make the root node look like the child +            this->setCenter(this->mChild[0]->getCenter()); +            this->setSize(this->mChild[0]->getSize()); +            this->updateMinMax(); + +            //reset root node child list +            this->clearChildren(); + +            //copy the child's children into the root node silently +            //(don't notify listeners of addition) +            for (U32 i = 0; i < child->getChildCount(); i++) +            { +                this->addChild(child->getChild(i), TRUE); +            } + +            //destroy child +            child->clearChildren(); +            delete child; + +            return false; +        } + +        return true; +    } + +    // LLOctreeRoot::insert +    bool insert(T* data) override +    { +        if (data == NULL) +        { +            OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE ROOT !!!" << LL_ENDL; +            return false; +        } + +        if (data->getBinRadius() > 4096.0) +        { +            OCT_ERRS << "!!! ELEMENT EXCEEDS MAXIMUM SIZE IN OCTREE ROOT !!!" << LL_ENDL; +            return false; +        } + +        LLVector4a MAX_MAG; +        MAX_MAG.splat(1024.f*1024.f); + +        const LLVector4a& v = data->getPositionGroup(); + +        LLVector4a val; +        val.setSub(v, BaseType::mCenter); +        val.setAbs(val); +        S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7; + +        if (lt != 0x7) +        { +            //OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << LL_ENDL; +            return false; +        } + +        if (this->getSize()[0] > data->getBinRadius() && this->isInside(data->getPositionGroup())) +        { +            //we got it, just act like a branch +            oct_node* node = this->getNodeAt(data); +            if (node == this) +            {                  oct_node::insert(data); -			} -			else if (node->isInside(data->getPositionGroup())) -			{ -				node->insert(data); -			} -			else -			{ -				// calling node->insert(data) will return us to root -				OCT_ERRS << "Failed to insert data at child node" << LL_ENDL; -			} -		} -		else if (this->getChildCount() == 0) -		{ -			//first object being added, just wrap it up -			while (!(this->getSize()[0] > data->getBinRadius() && this->isInside(data->getPositionGroup()))) -			{ -				LLVector4a center, size; -				center = this->getCenter(); -				size = this->getSize(); +            } +            else if (node->isInside(data->getPositionGroup())) +            { +                node->insert(data); +            } +            else +            { +                // calling node->insert(data) will return us to root +                OCT_ERRS << "Failed to insert data at child node" << LL_ENDL; +            } +        } +        else if (this->getChildCount() == 0) +        { +            //first object being added, just wrap it up +            while (!(this->getSize()[0] > data->getBinRadius() && this->isInside(data->getPositionGroup()))) +            { +                LLVector4a center, size; +                center = this->getCenter(); +                size = this->getSize();                  oct_node::pushCenter(center, size, data); -				this->setCenter(center); -				size.mul(2.f); -				this->setSize(size); -				this->updateMinMax(); -			} +                this->setCenter(center); +                size.mul(2.f); +                this->setSize(size); +                this->updateMinMax(); +            }              oct_node::insert(data); -		} -		else -		{ -			while (!(this->getSize()[0] > data->getBinRadius() && this->isInside(data->getPositionGroup()))) -			{ -				//the data is outside the root node, we need to grow -				LLVector4a center(this->getCenter()); -				LLVector4a size(this->getSize()); - -				//expand this node -				LLVector4a newcenter(center); +        } +        else +        { +            while (!(this->getSize()[0] > data->getBinRadius() && this->isInside(data->getPositionGroup()))) +            { +                //the data is outside the root node, we need to grow +                LLVector4a center(this->getCenter()); +                LLVector4a size(this->getSize()); + +                //expand this node +                LLVector4a newcenter(center);                  oct_node::pushCenter(newcenter, size, data); -				this->setCenter(newcenter); -				LLVector4a size2 = size; -				size2.mul(2.f); -				this->setSize(size2); -				this->updateMinMax(); +                this->setCenter(newcenter); +                LLVector4a size2 = size; +                size2.mul(2.f); +                this->setSize(size2); +                this->updateMinMax(); -				llassert(size[0] >= gOctreeMinSize); +                llassert(size[0] >= gOctreeMinSize); -				//copy our children to a new branch +                //copy our children to a new branch                  oct_node* newnode = new oct_node(center, size, this); -				 -				for (U32 i = 0; i < this->getChildCount(); i++) -				{ + +                for (U32 i = 0; i < this->getChildCount(); i++) +                {                      oct_node* child = this->getChild(i); -					newnode->addChild(child); -				} +                    newnode->addChild(child); +                } -				//clear our children and add the root copy -				this->clearChildren(); -				this->addChild(newnode); -			} +                //clear our children and add the root copy +                this->clearChildren(); +                this->addChild(newnode); +            } -			//insert the data -			insert(data); -		} +            //insert the data +            insert(data); +        } -		return false; -	} +        return false; +    }      bool isLeaf() const override      { @@ -833,26 +833,26 @@ public:  };  //======================== -//		LLOctreeTraveler +//      LLOctreeTraveler  //========================  template <class T, typename T_PTR>  void LLOctreeTraveler<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node)  { -	node->accept(this); -	for (U32 i = 0; i < node->getChildCount(); i++) -	{ -		traverse(node->getChild(i)); -	} +    node->accept(this); +    for (U32 i = 0; i < node->getChildCount(); i++) +    { +        traverse(node->getChild(i)); +    }  }  template <class T, typename T_PTR>  void LLOctreeTravelerDepthFirst<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node)  { -	for (U32 i = 0; i < node->getChildCount(); i++) -	{ -		traverse(node->getChild(i)); -	} -	node->accept(this); +    for (U32 i = 0; i < node->getChildCount(); i++) +    { +        traverse(node->getChild(i)); +    } +    node->accept(this);  }  #endif diff --git a/indra/llmath/llperlin.cpp b/indra/llmath/llperlin.cpp index e1da2bf92b..1fcad07f49 100644 --- a/indra/llmath/llperlin.cpp +++ b/indra/llmath/llperlin.cpp @@ -1,24 +1,24 @@ -/**  +/**   * @file llperlin.cpp   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -44,69 +44,69 @@ bool LLPerlinNoise::sInitialized = 0;  static void normalize2(F32 v[2])  { -	F32 s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1]); -	v[0] = v[0] * s; -	v[1] = v[1] * s; +    F32 s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1]); +    v[0] = v[0] * s; +    v[1] = v[1] * s;  }  static void normalize3(F32 v[3])  { -	F32 s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); -	v[0] = v[0] * s; -	v[1] = v[1] * s; -	v[2] = v[2] * s; +    F32 s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +    v[0] = v[0] * s; +    v[1] = v[1] * s; +    v[2] = v[2] * s;  }  static void fast_setup(F32 vec, U8 &b0, U8 &b1, F32 &r0, F32 &r1)  { -	S32 t_S32; - -	r1	= vec + NF32; -	t_S32 = lltrunc(r1); -	b0 = (U8)t_S32; -	b1 = b0 + 1; -	r0 = r1 - t_S32; -	r1 = r0 - 1.f; +    S32 t_S32; + +    r1  = vec + NF32; +    t_S32 = lltrunc(r1); +    b0 = (U8)t_S32; +    b1 = b0 + 1; +    r0 = r1 - t_S32; +    r1 = r0 - 1.f;  }  void LLPerlinNoise::init(void)  { -	int i, j, k; - -	for (i = 0 ; i < B ; i++) -	{ -		p[i] = i; - -		g1[i] = (F32)((rand() % (B + B)) - B) / B; - -		for (j = 0 ; j < 2 ; j++) -			g2[i][j] = (F32)((rand() % (B + B)) - B) / B; -		normalize2(g2[i]); - -		for (j = 0 ; j < 3 ; j++) -			g3[i][j] = (F32)((rand() % (B + B)) - B) / B; -		normalize3(g3[i]); -	} - -	while (--i) -	{ -		k = p[i]; -		p[i] = p[j = rand() % B]; -		p[j] = k; -	} - -	for (i = 0 ; i < B + 2 ; i++) -	{ -		p[B + i] = p[i]; -		g1[B + i] = g1[i]; -		for (j = 0 ; j < 2 ; j++) -			g2[B + i][j] = g2[i][j]; -		for (j = 0 ; j < 3 ; j++) -			g3[B + i][j] = g3[i][j]; -	} - -	sInitialized = true; +    int i, j, k; + +    for (i = 0 ; i < B ; i++) +    { +        p[i] = i; + +        g1[i] = (F32)((rand() % (B + B)) - B) / B; + +        for (j = 0 ; j < 2 ; j++) +            g2[i][j] = (F32)((rand() % (B + B)) - B) / B; +        normalize2(g2[i]); + +        for (j = 0 ; j < 3 ; j++) +            g3[i][j] = (F32)((rand() % (B + B)) - B) / B; +        normalize3(g3[i]); +    } + +    while (--i) +    { +        k = p[i]; +        p[i] = p[j = rand() % B]; +        p[j] = k; +    } + +    for (i = 0 ; i < B + 2 ; i++) +    { +        p[B + i] = p[i]; +        g1[B + i] = g1[i]; +        for (j = 0 ; j < 2 ; j++) +            g2[B + i][j] = g2[i][j]; +        for (j = 0 ; j < 3 ; j++) +            g3[B + i][j] = g3[i][j]; +    } + +    sInitialized = true;  } @@ -119,176 +119,176 @@ void LLPerlinNoise::init(void)  F32 LLPerlinNoise::noise1(F32 x)  { -	int bx0, bx1; -	F32 rx0, rx1, sx, t, u, v; +    int bx0, bx1; +    F32 rx0, rx1, sx, t, u, v; -	if (!sInitialized) -		init(); +    if (!sInitialized) +        init(); -	t = x + N; -	bx0 = (lltrunc(t)) & BM; -	bx1 = (bx0+1) & BM; -	rx0 = t - lltrunc(t); -	rx1 = rx0 - 1.f; +    t = x + N; +    bx0 = (lltrunc(t)) & BM; +    bx1 = (bx0+1) & BM; +    rx0 = t - lltrunc(t); +    rx1 = rx0 - 1.f; -	sx = s_curve(rx0); +    sx = s_curve(rx0); -	u = rx0 * g1[ p[ bx0 ] ]; -	v = rx1 * g1[ p[ bx1 ] ]; +    u = rx0 * g1[ p[ bx0 ] ]; +    v = rx1 * g1[ p[ bx1 ] ]; -	return lerp_m(sx, u, v); +    return lerp_m(sx, u, v);  }  static F32 fast_at2(F32 rx, F32 ry, F32 *q)  { -	return rx * q[0] + ry * q[1]; +    return rx * q[0] + ry * q[1];  }  F32 LLPerlinNoise::noise2(F32 x, F32 y)  { -	U8 bx0, bx1, by0, by1; -	U32 b00, b10, b01, b11; -	F32 rx0, rx1, ry0, ry1, *q, sx, sy, a, b, u, v; -	S32 i, j; +    U8 bx0, bx1, by0, by1; +    U32 b00, b10, b01, b11; +    F32 rx0, rx1, ry0, ry1, *q, sx, sy, a, b, u, v; +    S32 i, j; -	if (!sInitialized) -		init(); +    if (!sInitialized) +        init(); -	fast_setup(x, bx0, bx1, rx0, rx1); -	fast_setup(y, by0, by1, ry0, ry1); +    fast_setup(x, bx0, bx1, rx0, rx1); +    fast_setup(y, by0, by1, ry0, ry1); -	i = *(p + bx0); -	j = *(p + bx1); +    i = *(p + bx0); +    j = *(p + bx1); -	b00 = *(p + i + by0); -	b10 = *(p + j + by0); -	b01 = *(p + i + by1); -	b11 = *(p + j + by1); +    b00 = *(p + i + by0); +    b10 = *(p + j + by0); +    b01 = *(p + i + by1); +    b11 = *(p + j + by1); -	sx = s_curve(rx0); -	sy = s_curve(ry0); +    sx = s_curve(rx0); +    sy = s_curve(ry0); -	q = *(g2 + b00); -	u = fast_at2(rx0, ry0, q); -	q = *(g2 + b10);  -	v = fast_at2(rx1, ry0, q); -	a = lerp_m(sx, u, v); +    q = *(g2 + b00); +    u = fast_at2(rx0, ry0, q); +    q = *(g2 + b10); +    v = fast_at2(rx1, ry0, q); +    a = lerp_m(sx, u, v); -	q = *(g2 + b01);  -	u = fast_at2(rx0,ry1,q); -	q = *(g2 + b11);  -	v = fast_at2(rx1,ry1,q); -	b = lerp_m(sx, u, v); +    q = *(g2 + b01); +    u = fast_at2(rx0,ry1,q); +    q = *(g2 + b11); +    v = fast_at2(rx1,ry1,q); +    b = lerp_m(sx, u, v); -	return lerp_m(sy, a, b); +    return lerp_m(sy, a, b);  }  static F32 fast_at3(F32 rx, F32 ry, F32 rz, F32 *q)  { -	return rx * q[0] + ry * q[1] + rz * q[2]; +    return rx * q[0] + ry * q[1] + rz * q[2];  }  F32 LLPerlinNoise::noise3(F32 x, F32 y, F32 z)  { -	U8 bx0, bx1, by0, by1, bz0, bz1; -	S32 b00, b10, b01, b11; -	F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; -	S32 i, j; - -	if (!sInitialized) -		init(); - -	fast_setup(x, bx0,bx1, rx0,rx1); -	fast_setup(y, by0,by1, ry0,ry1); -	fast_setup(z, bz0,bz1, rz0,rz1); - -	i = p[ bx0 ]; -	j = p[ bx1 ]; - -	b00 = p[ i + by0 ]; -	b10 = p[ j + by0 ]; -	b01 = p[ i + by1 ]; -	b11 = p[ j + by1 ]; - -	t  = s_curve(rx0); -	sy = s_curve(ry0); -	sz = s_curve(rz0); - -	q = g3[ b00 + bz0 ];  -	u = fast_at3(rx0,ry0,rz0,q); -	q = g3[ b10 + bz0 ]; -	v = fast_at3(rx1,ry0,rz0,q); -	a = lerp_m(t, u, v); - -	q = g3[ b01 + bz0 ]; -	u = fast_at3(rx0,ry1,rz0,q); -	q = g3[ b11 + bz0 ]; -	v = fast_at3(rx1,ry1,rz0,q); -	b = lerp_m(t, u, v); - -	c = lerp_m(sy, a, b); - -	q = g3[ b00 + bz1 ]; -	u = fast_at3(rx0,ry0,rz1,q); -	q = g3[ b10 + bz1 ]; -	v = fast_at3(rx1,ry0,rz1,q); -	a = lerp_m(t, u, v); - -	q = g3[ b01 + bz1 ]; -	u = fast_at3(rx0,ry1,rz1,q); -	q = g3[ b11 + bz1 ]; -	v = fast_at3(rx1,ry1,rz1,q); -	b = lerp_m(t, u, v); - -	d = lerp_m(sy, a, b); - -	return lerp_m(sz, c, d); +    U8 bx0, bx1, by0, by1, bz0, bz1; +    S32 b00, b10, b01, b11; +    F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; +    S32 i, j; + +    if (!sInitialized) +        init(); + +    fast_setup(x, bx0,bx1, rx0,rx1); +    fast_setup(y, by0,by1, ry0,ry1); +    fast_setup(z, bz0,bz1, rz0,rz1); + +    i = p[ bx0 ]; +    j = p[ bx1 ]; + +    b00 = p[ i + by0 ]; +    b10 = p[ j + by0 ]; +    b01 = p[ i + by1 ]; +    b11 = p[ j + by1 ]; + +    t  = s_curve(rx0); +    sy = s_curve(ry0); +    sz = s_curve(rz0); + +    q = g3[ b00 + bz0 ]; +    u = fast_at3(rx0,ry0,rz0,q); +    q = g3[ b10 + bz0 ]; +    v = fast_at3(rx1,ry0,rz0,q); +    a = lerp_m(t, u, v); + +    q = g3[ b01 + bz0 ]; +    u = fast_at3(rx0,ry1,rz0,q); +    q = g3[ b11 + bz0 ]; +    v = fast_at3(rx1,ry1,rz0,q); +    b = lerp_m(t, u, v); + +    c = lerp_m(sy, a, b); + +    q = g3[ b00 + bz1 ]; +    u = fast_at3(rx0,ry0,rz1,q); +    q = g3[ b10 + bz1 ]; +    v = fast_at3(rx1,ry0,rz1,q); +    a = lerp_m(t, u, v); + +    q = g3[ b01 + bz1 ]; +    u = fast_at3(rx0,ry1,rz1,q); +    q = g3[ b11 + bz1 ]; +    v = fast_at3(rx1,ry1,rz1,q); +    b = lerp_m(t, u, v); + +    d = lerp_m(sy, a, b); + +    return lerp_m(sz, c, d);  }  F32 LLPerlinNoise::turbulence2(F32 x, F32 y, F32 freq)  { -	F32 t, lx, ly; - -	for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) -	{ -		lx = freq * x; -		ly = freq * y; -		t += noise2(lx, ly)/freq; -	} -	return t; +    F32 t, lx, ly; + +    for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) +    { +        lx = freq * x; +        ly = freq * y; +        t += noise2(lx, ly)/freq; +    } +    return t;  }  F32 LLPerlinNoise::turbulence3(F32 x, F32 y, F32 z, F32 freq)  { -	F32 t, lx, ly, lz; - -	for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) -	{ -		lx = freq * x; -		ly = freq * y; -		lz = freq * z; -		t += noise3(lx,ly,lz)/freq; -//		t += fabs(noise3(lx,ly,lz)) / freq;					// Like snow - bubbly at low frequencies -//		t += sqrt(fabs(noise3(lx,ly,lz))) / freq;			// Better at low freq -//		t += (noise3(lx,ly,lz)*noise3(lx,ly,lz)) / freq;		 -	} -	return t; +    F32 t, lx, ly, lz; + +    for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) +    { +        lx = freq * x; +        ly = freq * y; +        lz = freq * z; +        t += noise3(lx,ly,lz)/freq; +//      t += fabs(noise3(lx,ly,lz)) / freq;                 // Like snow - bubbly at low frequencies +//      t += sqrt(fabs(noise3(lx,ly,lz))) / freq;           // Better at low freq +//      t += (noise3(lx,ly,lz)*noise3(lx,ly,lz)) / freq; +    } +    return t;  }  F32 LLPerlinNoise::clouds3(F32 x, F32 y, F32 z, F32 freq)  { -	F32 t, lx, ly, lz; - -	for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) -	{ -		lx = freq * x; -		ly = freq * y; -		lz = freq * z; -//		t += noise3(lx,ly,lz)/freq; -//		t += fabs(noise3(lx,ly,lz)) / freq;					// Like snow - bubbly at low frequencies -//		t += sqrt(fabs(noise3(lx,ly,lz))) / freq;			// Better at low freq -		t += (noise3(lx,ly,lz)*noise3(lx,ly,lz)) / freq;		 -	} -	return t; +    F32 t, lx, ly, lz; + +    for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) +    { +        lx = freq * x; +        ly = freq * y; +        lz = freq * z; +//      t += noise3(lx,ly,lz)/freq; +//      t += fabs(noise3(lx,ly,lz)) / freq;                 // Like snow - bubbly at low frequencies +//      t += sqrt(fabs(noise3(lx,ly,lz))) / freq;           // Better at low freq +        t += (noise3(lx,ly,lz)*noise3(lx,ly,lz)) / freq; +    } +    return t;  } diff --git a/indra/llmath/llperlin.h b/indra/llmath/llperlin.h index 40cf19d1ec..2b001ba951 100644 --- a/indra/llmath/llperlin.h +++ b/indra/llmath/llperlin.h @@ -1,24 +1,24 @@ -/**  +/**   * @file llperlin.h   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -32,15 +32,15 @@  class LLPerlinNoise  {  public: -	static F32 noise1(F32 x); -	static F32 noise2(F32 x, F32 y); -	static F32 noise3(F32 x, F32 y, F32 z); -	static F32 turbulence2(F32 x, F32 y, F32 freq); -	static F32 turbulence3(F32 x, F32 y, F32 z, F32 freq); -	static F32 clouds3(F32 x, F32 y, F32 z, F32 freq); +    static F32 noise1(F32 x); +    static F32 noise2(F32 x, F32 y); +    static F32 noise3(F32 x, F32 y, F32 z); +    static F32 turbulence2(F32 x, F32 y, F32 freq); +    static F32 turbulence3(F32 x, F32 y, F32 z, F32 freq); +    static F32 clouds3(F32 x, F32 y, F32 z, F32 freq);  private: -	static bool sInitialized; -	static void init(void); +    static bool sInitialized; +    static void init(void);  };  #endif // LL_PERLIN_ diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h index 64a3eed0e5..4e8546e32b 100644 --- a/indra/llmath/llplane.h +++ b/indra/llmath/llplane.h @@ -1,24 +1,24 @@ -/**  +/**   * @file llplane.h   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -31,7 +31,7 @@  // A simple way to specify a plane is to give its normal,  // and it's nearest approach to the origin. -//  +//  // Given the equation for a plane : A*x + B*y + C*z + D = 0  // The plane normal = [A, B, C]  // The closest approach = D / sqrt(A*A + B*B + C*C) @@ -41,67 +41,67 @@ LL_ALIGN_PREFIX(16)  class LLPlane  {  public: -	 -	// Constructors -	LLPlane() {}; // no default constructor -	LLPlane(const LLVector3 &p0, F32 d) { setVec(p0, d); } -	LLPlane(const LLVector3 &p0, const LLVector3 &n) { setVec(p0, n); } -	inline void setVec(const LLVector3 &p0, F32 d) { mV.set(p0[0], p0[1], p0[2], d); } -	 -	// Set -	inline void setVec(const LLVector3 &p0, const LLVector3 &n) -	{ -		F32 d = -(p0 * n); -		setVec(n, d); -	} -	inline void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2) -	{ -		LLVector3 u, v, w; -		u = p1 - p0; -		v = p2 - p0; -		w = u % v; -		w.normVec(); -		F32 d = -(w * p0); -		setVec(w, d); -	} -	 -	inline LLPlane& operator=(const LLVector4& v2) {  mV.set(v2[0],v2[1],v2[2],v2[3]); return *this;} -	 -	inline LLPlane& operator=(const LLVector4a& v2) {  mV.set(v2[0],v2[1],v2[2],v2[3]); return *this;}	 -	 -	inline void set(const LLPlane& p2) { mV = p2.mV; } -	 -	//  -	F32 dist(const LLVector3 &v2) const { return mV[0]*v2[0] + mV[1]*v2[1] + mV[2]*v2[2] + mV[3]; } -	 -	inline LLSimdScalar dot3(const LLVector4a& b) const { return mV.dot3(b); } -	 -	// Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates -	// the data at the whole vector level or you will incur a substantial penalty. Consider using the splat functions instead	 -	inline F32 operator[](const S32 idx) const { return mV[idx]; } -	 -	// preferable when index is known at compile time -	template <int N> LL_FORCE_INLINE void getAt(LLSimdScalar& v) const { v = mV.getScalarAt<N>(); }  -	 -	// reset the vector to 0, 0, 0, 1 -	inline void clear() { mV.set(0, 0, 0, 1); } -	 -	inline void getVector3(LLVector3& vec) const { vec.set(mV[0], mV[1], mV[2]); } -	 -	// Retrieve the mask indicating which of the x, y, or z axis are greater or equal to zero. -	inline U8 calcPlaneMask()  -	{  -		return mV.greaterEqual(LLVector4a::getZero()).getGatheredBits() & LLVector4Logical::MASK_XYZ; -	} -	 -	//check if two planes are nearly same -	bool equal(const LLPlane& p) const -	{ -		return mV.equals4(p.mV); -	} + +    // Constructors +    LLPlane() {}; // no default constructor +    LLPlane(const LLVector3 &p0, F32 d) { setVec(p0, d); } +    LLPlane(const LLVector3 &p0, const LLVector3 &n) { setVec(p0, n); } +    inline void setVec(const LLVector3 &p0, F32 d) { mV.set(p0[0], p0[1], p0[2], d); } + +    // Set +    inline void setVec(const LLVector3 &p0, const LLVector3 &n) +    { +        F32 d = -(p0 * n); +        setVec(n, d); +    } +    inline void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2) +    { +        LLVector3 u, v, w; +        u = p1 - p0; +        v = p2 - p0; +        w = u % v; +        w.normVec(); +        F32 d = -(w * p0); +        setVec(w, d); +    } + +    inline LLPlane& operator=(const LLVector4& v2) {  mV.set(v2[0],v2[1],v2[2],v2[3]); return *this;} + +    inline LLPlane& operator=(const LLVector4a& v2) {  mV.set(v2[0],v2[1],v2[2],v2[3]); return *this;} + +    inline void set(const LLPlane& p2) { mV = p2.mV; } + +    // +    F32 dist(const LLVector3 &v2) const { return mV[0]*v2[0] + mV[1]*v2[1] + mV[2]*v2[2] + mV[3]; } + +    inline LLSimdScalar dot3(const LLVector4a& b) const { return mV.dot3(b); } + +    // Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates +    // the data at the whole vector level or you will incur a substantial penalty. Consider using the splat functions instead +    inline F32 operator[](const S32 idx) const { return mV[idx]; } + +    // preferable when index is known at compile time +    template <int N> LL_FORCE_INLINE void getAt(LLSimdScalar& v) const { v = mV.getScalarAt<N>(); } + +    // reset the vector to 0, 0, 0, 1 +    inline void clear() { mV.set(0, 0, 0, 1); } + +    inline void getVector3(LLVector3& vec) const { vec.set(mV[0], mV[1], mV[2]); } + +    // Retrieve the mask indicating which of the x, y, or z axis are greater or equal to zero. +    inline U8 calcPlaneMask() +    { +        return mV.greaterEqual(LLVector4a::getZero()).getGatheredBits() & LLVector4Logical::MASK_XYZ; +    } + +    //check if two planes are nearly same +    bool equal(const LLPlane& p) const +    { +        return mV.equals4(p.mV); +    }  private: -	LLVector4a mV; +    LLVector4a mV;  } LL_ALIGN_POSTFIX(16); diff --git a/indra/llmath/llquantize.h b/indra/llmath/llquantize.h index 10c950abbb..e8d880122e 100644 --- a/indra/llmath/llquantize.h +++ b/indra/llmath/llquantize.h @@ -1,4 +1,4 @@ -/**  +/**   * @file llquantize.h   * @brief useful routines for quantizing floats to various length ints   * and back out again @@ -6,21 +6,21 @@   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -41,112 +41,112 @@ const F32 OOU8MAX = 1.f/(F32)(U8MAX);  LL_ALIGN_16( const F32 F_OOU8MAX_4A[4] ) = { OOU8MAX, OOU8MAX, OOU8MAX, OOU8MAX };  const U8 FIRSTVALIDCHAR = 54; -const U8 MAXSTRINGVAL = U8MAX - FIRSTVALIDCHAR; //we don't allow newline or null  +const U8 MAXSTRINGVAL = U8MAX - FIRSTVALIDCHAR; //we don't allow newline or null  inline U16 F32_to_U16_ROUND(F32 val, F32 lower, F32 upper)  { -	val = llclamp(val, lower, upper); -	// make sure that the value is positive and normalized to <0, 1> -	val -= lower; -	val /= (upper - lower); +    val = llclamp(val, lower, upper); +    // make sure that the value is positive and normalized to <0, 1> +    val -= lower; +    val /= (upper - lower); -	// round the value.   Sreturn the U16 -	return (U16)(ll_round(val*U16MAX)); +    // round the value.   Sreturn the U16 +    return (U16)(ll_round(val*U16MAX));  }  inline U16 F32_to_U16(F32 val, F32 lower, F32 upper)  { -	val = llclamp(val, lower, upper); -	// make sure that the value is positive and normalized to <0, 1> -	val -= lower; -	val /= (upper - lower); +    val = llclamp(val, lower, upper); +    // make sure that the value is positive and normalized to <0, 1> +    val -= lower; +    val /= (upper - lower); -	// return the U16 -	return (U16)(llfloor(val*U16MAX)); +    // return the U16 +    return (U16)(llfloor(val*U16MAX));  }  inline F32 U16_to_F32(U16 ival, F32 lower, F32 upper)  { -	F32 val = ival*OOU16MAX; -	F32 delta = (upper - lower); -	val *= delta; -	val += lower; +    F32 val = ival*OOU16MAX; +    F32 delta = (upper - lower); +    val *= delta; +    val += lower; -	F32 max_error = delta*OOU16MAX; +    F32 max_error = delta*OOU16MAX; -	// make sure that zero's come through as zero -	if (fabsf(val) < max_error) -		val = 0.f; +    // make sure that zero's come through as zero +    if (fabsf(val) < max_error) +        val = 0.f; -	return val; +    return val;  }  inline U8 F32_to_U8_ROUND(F32 val, F32 lower, F32 upper)  { -	val = llclamp(val, lower, upper); -	// make sure that the value is positive and normalized to <0, 1> -	val -= lower; -	val /= (upper - lower); +    val = llclamp(val, lower, upper); +    // make sure that the value is positive and normalized to <0, 1> +    val -= lower; +    val /= (upper - lower); -	// return the rounded U8 -	return (U8)(ll_round(val*U8MAX)); +    // return the rounded U8 +    return (U8)(ll_round(val*U8MAX));  }  inline U8 F32_to_U8(F32 val, F32 lower, F32 upper)  { -	val = llclamp(val, lower, upper); -	// make sure that the value is positive and normalized to <0, 1> -	val -= lower; -	val /= (upper - lower); +    val = llclamp(val, lower, upper); +    // make sure that the value is positive and normalized to <0, 1> +    val -= lower; +    val /= (upper - lower); -	// return the U8 -	return (U8)(llfloor(val*U8MAX)); +    // return the U8 +    return (U8)(llfloor(val*U8MAX));  }  inline F32 U8_to_F32(U8 ival, F32 lower, F32 upper)  { -	F32 val = ival*OOU8MAX; -	F32 delta = (upper - lower); -	val *= delta; -	val += lower; +    F32 val = ival*OOU8MAX; +    F32 delta = (upper - lower); +    val *= delta; +    val += lower; -	F32 max_error = delta*OOU8MAX; +    F32 max_error = delta*OOU8MAX; -	// make sure that zero's come through as zero -	if (fabsf(val) < max_error) -		val = 0.f; +    // make sure that zero's come through as zero +    if (fabsf(val) < max_error) +        val = 0.f; -	return val; +    return val;  }  inline U8 F32_TO_STRING(F32 val, F32 lower, F32 upper)  { -	val = llclamp(val, lower, upper); //[lower, upper] -	// make sure that the value is positive and normalized to <0, 1> -	val -= lower;					//[0, upper-lower] -	val /= (upper - lower);			//[0,1] -	val = val * MAXSTRINGVAL;		//[0, MAXSTRINGVAL] -	val = floor(val + 0.5f);		//[0, MAXSTRINGVAL] - -	U8 stringVal = (U8)(val) + FIRSTVALIDCHAR;			//[FIRSTVALIDCHAR, MAXSTRINGVAL + FIRSTVALIDCHAR] -	return stringVal; +    val = llclamp(val, lower, upper); //[lower, upper] +    // make sure that the value is positive and normalized to <0, 1> +    val -= lower;                   //[0, upper-lower] +    val /= (upper - lower);         //[0,1] +    val = val * MAXSTRINGVAL;       //[0, MAXSTRINGVAL] +    val = floor(val + 0.5f);        //[0, MAXSTRINGVAL] + +    U8 stringVal = (U8)(val) + FIRSTVALIDCHAR;          //[FIRSTVALIDCHAR, MAXSTRINGVAL + FIRSTVALIDCHAR] +    return stringVal;  }  inline F32 STRING_TO_F32(U8 ival, F32 lower, F32 upper)  { -	// remove empty space left for NULL, newline, etc. -	ival -= FIRSTVALIDCHAR;								//[0, MAXSTRINGVAL] +    // remove empty space left for NULL, newline, etc. +    ival -= FIRSTVALIDCHAR;                             //[0, MAXSTRINGVAL] -	F32 val = (F32)ival * (1.f / (F32)MAXSTRINGVAL);	//[0, 1] -	F32 delta = (upper - lower); -	val *= delta;										//[0, upper - lower] -	val += lower;										//[lower, upper] +    F32 val = (F32)ival * (1.f / (F32)MAXSTRINGVAL);    //[0, 1] +    F32 delta = (upper - lower); +    val *= delta;                                       //[0, upper - lower] +    val += lower;                                       //[lower, upper] -	return val; +    return val;  }  #endif diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp index 57a976b57a..ce0a88c26f 100644 --- a/indra/llmath/llquaternion.cpp +++ b/indra/llmath/llquaternion.cpp @@ -5,28 +5,28 @@   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */  #include "linden_common.h" -#include "llmath.h"	// for F_PI +#include "llmath.h" // for F_PI  #include "llquaternion.h" @@ -41,67 +41,67 @@  // WARNING: Don't use this for global const definitions!  using this  // at the top of a *.cpp file might not give you what you think.  const LLQuaternion LLQuaternion::DEFAULT; -  +  // Constructors  LLQuaternion::LLQuaternion(const LLMatrix4 &mat)  { -	*this = mat.quaternion(); -	normalize(); +    *this = mat.quaternion(); +    normalize();  }  LLQuaternion::LLQuaternion(const LLMatrix3 &mat)  { -	*this = mat.quaternion(); -	normalize(); +    *this = mat.quaternion(); +    normalize();  }  LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec)  { -	F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); -	if (mag > FP_MAG_THRESHOLD) -	{ -		angle *= 0.5; -		F32 c = cosf(angle); -		F32 s = sinf(angle) / mag; -		mQ[VX] = vec.mV[VX] * s; -		mQ[VY] = vec.mV[VY] * s; -		mQ[VZ] = vec.mV[VZ] * s; -		mQ[VW] = c; -	} -	else -	{ -		loadIdentity(); -	} +    F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); +    if (mag > FP_MAG_THRESHOLD) +    { +        angle *= 0.5; +        F32 c = cosf(angle); +        F32 s = sinf(angle) / mag; +        mQ[VX] = vec.mV[VX] * s; +        mQ[VY] = vec.mV[VY] * s; +        mQ[VZ] = vec.mV[VZ] * s; +        mQ[VW] = c; +    } +    else +    { +        loadIdentity(); +    }  }  LLQuaternion::LLQuaternion(F32 angle, const LLVector3 &vec)  { -	F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); -	if (mag > FP_MAG_THRESHOLD) -	{ -		angle *= 0.5; -		F32 c = cosf(angle); -		F32 s = sinf(angle) / mag; -		mQ[VX] = vec.mV[VX] * s; -		mQ[VY] = vec.mV[VY] * s; -		mQ[VZ] = vec.mV[VZ] * s; -		mQ[VW] = c; -	} -	else -	{ -		loadIdentity(); -	} +    F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); +    if (mag > FP_MAG_THRESHOLD) +    { +        angle *= 0.5; +        F32 c = cosf(angle); +        F32 s = sinf(angle) / mag; +        mQ[VX] = vec.mV[VX] * s; +        mQ[VY] = vec.mV[VY] * s; +        mQ[VZ] = vec.mV[VZ] * s; +        mQ[VW] = c; +    } +    else +    { +        loadIdentity(); +    }  }  LLQuaternion::LLQuaternion(const LLVector3 &x_axis, -						   const LLVector3 &y_axis, -						   const LLVector3 &z_axis) +                           const LLVector3 &y_axis, +                           const LLVector3 &z_axis)  { -	LLMatrix3 mat; -	mat.setRows(x_axis, y_axis, z_axis); -	*this = mat.quaternion(); -	normalize(); +    LLMatrix3 mat; +    mat.setRows(x_axis, y_axis, z_axis); +    *this = mat.quaternion(); +    normalize();  }  LLQuaternion::LLQuaternion(const LLSD &sd) @@ -110,34 +110,34 @@ LLQuaternion::LLQuaternion(const LLSD &sd)  }  // Quatizations -void	LLQuaternion::quantize16(F32 lower, F32 upper) +void    LLQuaternion::quantize16(F32 lower, F32 upper)  { -	F32 x = mQ[VX]; -	F32 y = mQ[VY]; -	F32 z = mQ[VZ]; -	F32 s = mQ[VS]; +    F32 x = mQ[VX]; +    F32 y = mQ[VY]; +    F32 z = mQ[VZ]; +    F32 s = mQ[VS]; -	x = U16_to_F32(F32_to_U16_ROUND(x, lower, upper), lower, upper); -	y = U16_to_F32(F32_to_U16_ROUND(y, lower, upper), lower, upper); -	z = U16_to_F32(F32_to_U16_ROUND(z, lower, upper), lower, upper); -	s = U16_to_F32(F32_to_U16_ROUND(s, lower, upper), lower, upper); +    x = U16_to_F32(F32_to_U16_ROUND(x, lower, upper), lower, upper); +    y = U16_to_F32(F32_to_U16_ROUND(y, lower, upper), lower, upper); +    z = U16_to_F32(F32_to_U16_ROUND(z, lower, upper), lower, upper); +    s = U16_to_F32(F32_to_U16_ROUND(s, lower, upper), lower, upper); -	mQ[VX] = x; -	mQ[VY] = y; -	mQ[VZ] = z; -	mQ[VS] = s; +    mQ[VX] = x; +    mQ[VY] = y; +    mQ[VZ] = z; +    mQ[VS] = s; -	normalize(); +    normalize();  } -void	LLQuaternion::quantize8(F32 lower, F32 upper) +void    LLQuaternion::quantize8(F32 lower, F32 upper)  { -	mQ[VX] = U8_to_F32(F32_to_U8_ROUND(mQ[VX], lower, upper), lower, upper); -	mQ[VY] = U8_to_F32(F32_to_U8_ROUND(mQ[VY], lower, upper), lower, upper); -	mQ[VZ] = U8_to_F32(F32_to_U8_ROUND(mQ[VZ], lower, upper), lower, upper); -	mQ[VS] = U8_to_F32(F32_to_U8_ROUND(mQ[VS], lower, upper), lower, upper); +    mQ[VX] = U8_to_F32(F32_to_U8_ROUND(mQ[VX], lower, upper), lower, upper); +    mQ[VY] = U8_to_F32(F32_to_U8_ROUND(mQ[VY], lower, upper), lower, upper); +    mQ[VZ] = U8_to_F32(F32_to_U8_ROUND(mQ[VZ], lower, upper), lower, upper); +    mQ[VS] = U8_to_F32(F32_to_U8_ROUND(mQ[VS], lower, upper), lower, upper); -	normalize(); +    normalize();  }  // LLVector3 Magnitude and Normalization Functions @@ -145,190 +145,190 @@ void	LLQuaternion::quantize8(F32 lower, F32 upper)  // Set LLQuaternion routines -const LLQuaternion&	LLQuaternion::setAngleAxis(F32 angle, F32 x, F32 y, F32 z) -{ -	F32 mag = sqrtf(x * x + y * y + z * z); -	if (mag > FP_MAG_THRESHOLD) -	{ -		angle *= 0.5; -		F32 c = cosf(angle); -		F32 s = sinf(angle) / mag; -		mQ[VX] = x * s; -		mQ[VY] = y * s; -		mQ[VZ] = z * s; -		mQ[VW] = c; -	} -	else -	{ -		loadIdentity(); -	} -	return (*this); -} - -const LLQuaternion&	LLQuaternion::setAngleAxis(F32 angle, const LLVector3 &vec) -{ -	F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); -	if (mag > FP_MAG_THRESHOLD) -	{ -		angle *= 0.5; -		F32 c = cosf(angle); -		F32 s = sinf(angle) / mag; -		mQ[VX] = vec.mV[VX] * s; -		mQ[VY] = vec.mV[VY] * s; -		mQ[VZ] = vec.mV[VZ] * s; -		mQ[VW] = c; -	} -	else -	{ -		loadIdentity(); -	} -	return (*this); -} - -const LLQuaternion&	LLQuaternion::setAngleAxis(F32 angle, const LLVector4 &vec) -{ -	F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); -	if (mag > FP_MAG_THRESHOLD) -	{ -		angle *= 0.5; -		F32 c = cosf(angle); -		F32 s = sinf(angle) / mag; -		mQ[VX] = vec.mV[VX] * s; -		mQ[VY] = vec.mV[VY] * s; -		mQ[VZ] = vec.mV[VZ] * s; -		mQ[VW] = c; -	} -	else -	{ -		loadIdentity(); -	} -	return (*this); -} - -const LLQuaternion&	LLQuaternion::setEulerAngles(F32 roll, F32 pitch, F32 yaw) -{ -	LLMatrix3 rot_mat(roll, pitch, yaw); -	rot_mat.orthogonalize(); -	*this = rot_mat.quaternion(); -		 -	normalize(); -	return (*this); +const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, F32 x, F32 y, F32 z) +{ +    F32 mag = sqrtf(x * x + y * y + z * z); +    if (mag > FP_MAG_THRESHOLD) +    { +        angle *= 0.5; +        F32 c = cosf(angle); +        F32 s = sinf(angle) / mag; +        mQ[VX] = x * s; +        mQ[VY] = y * s; +        mQ[VZ] = z * s; +        mQ[VW] = c; +    } +    else +    { +        loadIdentity(); +    } +    return (*this); +} + +const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector3 &vec) +{ +    F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); +    if (mag > FP_MAG_THRESHOLD) +    { +        angle *= 0.5; +        F32 c = cosf(angle); +        F32 s = sinf(angle) / mag; +        mQ[VX] = vec.mV[VX] * s; +        mQ[VY] = vec.mV[VY] * s; +        mQ[VZ] = vec.mV[VZ] * s; +        mQ[VW] = c; +    } +    else +    { +        loadIdentity(); +    } +    return (*this); +} + +const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector4 &vec) +{ +    F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); +    if (mag > FP_MAG_THRESHOLD) +    { +        angle *= 0.5; +        F32 c = cosf(angle); +        F32 s = sinf(angle) / mag; +        mQ[VX] = vec.mV[VX] * s; +        mQ[VY] = vec.mV[VY] * s; +        mQ[VZ] = vec.mV[VZ] * s; +        mQ[VW] = c; +    } +    else +    { +        loadIdentity(); +    } +    return (*this); +} + +const LLQuaternion& LLQuaternion::setEulerAngles(F32 roll, F32 pitch, F32 yaw) +{ +    LLMatrix3 rot_mat(roll, pitch, yaw); +    rot_mat.orthogonalize(); +    *this = rot_mat.quaternion(); + +    normalize(); +    return (*this);  }  // deprecated -const LLQuaternion&	LLQuaternion::set(const LLMatrix3 &mat) +const LLQuaternion& LLQuaternion::set(const LLMatrix3 &mat)  { -	*this = mat.quaternion(); -	normalize(); -	return (*this); +    *this = mat.quaternion(); +    normalize(); +    return (*this);  }  // deprecated -const LLQuaternion&	LLQuaternion::set(const LLMatrix4 &mat) +const LLQuaternion& LLQuaternion::set(const LLMatrix4 &mat)  { -	*this = mat.quaternion(); -	normalize(); -	return (*this); +    *this = mat.quaternion(); +    normalize(); +    return (*this);  }  // deprecated -const LLQuaternion&	LLQuaternion::setQuat(F32 angle, F32 x, F32 y, F32 z) -{ -	F32 mag = sqrtf(x * x + y * y + z * z); -	if (mag > FP_MAG_THRESHOLD) -	{ -		angle *= 0.5; -		F32 c = cosf(angle); -		F32 s = sinf(angle) / mag; -		mQ[VX] = x * s; -		mQ[VY] = y * s; -		mQ[VZ] = z * s; -		mQ[VW] = c; -	} -	else -	{ -		loadIdentity(); -	} -	return (*this); +const LLQuaternion& LLQuaternion::setQuat(F32 angle, F32 x, F32 y, F32 z) +{ +    F32 mag = sqrtf(x * x + y * y + z * z); +    if (mag > FP_MAG_THRESHOLD) +    { +        angle *= 0.5; +        F32 c = cosf(angle); +        F32 s = sinf(angle) / mag; +        mQ[VX] = x * s; +        mQ[VY] = y * s; +        mQ[VZ] = z * s; +        mQ[VW] = c; +    } +    else +    { +        loadIdentity(); +    } +    return (*this);  }  // deprecated -const LLQuaternion&	LLQuaternion::setQuat(F32 angle, const LLVector3 &vec) -{ -	F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); -	if (mag > FP_MAG_THRESHOLD) -	{ -		angle *= 0.5; -		F32 c = cosf(angle); -		F32 s = sinf(angle) / mag; -		mQ[VX] = vec.mV[VX] * s; -		mQ[VY] = vec.mV[VY] * s; -		mQ[VZ] = vec.mV[VZ] * s; -		mQ[VW] = c; -	} -	else -	{ -		loadIdentity(); -	} -	return (*this); -} - -const LLQuaternion&	LLQuaternion::setQuat(F32 angle, const LLVector4 &vec) -{ -	F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); -	if (mag > FP_MAG_THRESHOLD) -	{ -		angle *= 0.5; -		F32 c = cosf(angle); -		F32 s = sinf(angle) / mag; -		mQ[VX] = vec.mV[VX] * s; -		mQ[VY] = vec.mV[VY] * s; -		mQ[VZ] = vec.mV[VZ] * s; -		mQ[VW] = c; -	} -	else -	{ -		loadIdentity(); -	} -	return (*this); -} - -const LLQuaternion&	LLQuaternion::setQuat(F32 roll, F32 pitch, F32 yaw) -{ -	roll  *= 0.5f; -	pitch *= 0.5f; -	yaw   *= 0.5f; -	F32 sinX = sinf(roll); -	F32 cosX = cosf(roll); -	F32 sinY = sinf(pitch); -	F32 cosY = cosf(pitch); -	F32 sinZ = sinf(yaw); -	F32 cosZ = cosf(yaw); -	mQ[VW] = cosX * cosY * cosZ - sinX * sinY * sinZ; -	mQ[VX] = sinX * cosY * cosZ + cosX * sinY * sinZ; -	mQ[VY] = cosX * sinY * cosZ - sinX * cosY * sinZ; -	mQ[VZ] = cosX * cosY * sinZ + sinX * sinY * cosZ; -	return (*this); -} - -const LLQuaternion&	LLQuaternion::setQuat(const LLMatrix3 &mat) -{ -	*this = mat.quaternion(); -	normalize(); -	return (*this); -} - -const LLQuaternion&	LLQuaternion::setQuat(const LLMatrix4 &mat) -{ -	*this = mat.quaternion(); -	normalize(); -	return (*this); +const LLQuaternion& LLQuaternion::setQuat(F32 angle, const LLVector3 &vec) +{ +    F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); +    if (mag > FP_MAG_THRESHOLD) +    { +        angle *= 0.5; +        F32 c = cosf(angle); +        F32 s = sinf(angle) / mag; +        mQ[VX] = vec.mV[VX] * s; +        mQ[VY] = vec.mV[VY] * s; +        mQ[VZ] = vec.mV[VZ] * s; +        mQ[VW] = c; +    } +    else +    { +        loadIdentity(); +    } +    return (*this); +} + +const LLQuaternion& LLQuaternion::setQuat(F32 angle, const LLVector4 &vec) +{ +    F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); +    if (mag > FP_MAG_THRESHOLD) +    { +        angle *= 0.5; +        F32 c = cosf(angle); +        F32 s = sinf(angle) / mag; +        mQ[VX] = vec.mV[VX] * s; +        mQ[VY] = vec.mV[VY] * s; +        mQ[VZ] = vec.mV[VZ] * s; +        mQ[VW] = c; +    } +    else +    { +        loadIdentity(); +    } +    return (*this); +} + +const LLQuaternion& LLQuaternion::setQuat(F32 roll, F32 pitch, F32 yaw) +{ +    roll  *= 0.5f; +    pitch *= 0.5f; +    yaw   *= 0.5f; +    F32 sinX = sinf(roll); +    F32 cosX = cosf(roll); +    F32 sinY = sinf(pitch); +    F32 cosY = cosf(pitch); +    F32 sinZ = sinf(yaw); +    F32 cosZ = cosf(yaw); +    mQ[VW] = cosX * cosY * cosZ - sinX * sinY * sinZ; +    mQ[VX] = sinX * cosY * cosZ + cosX * sinY * sinZ; +    mQ[VY] = cosX * sinY * cosZ - sinX * cosY * sinZ; +    mQ[VZ] = cosX * cosY * sinZ + sinX * sinY * cosZ; +    return (*this); +} + +const LLQuaternion& LLQuaternion::setQuat(const LLMatrix3 &mat) +{ +    *this = mat.quaternion(); +    normalize(); +    return (*this); +} + +const LLQuaternion& LLQuaternion::setQuat(const LLMatrix4 &mat) +{ +    *this = mat.quaternion(); +    normalize(); +    return (*this);  //#if 1 -//	// NOTE: LLQuaternion's are actually inverted with respect to -//	// the matrices, so this code also assumes inverted quaternions -//	// (-x, -y, -z, w). The result is that roll,pitch,yaw are applied -//	// in reverse order (yaw,pitch,roll). -//	F64 cosX = cos(roll); +//  // NOTE: LLQuaternion's are actually inverted with respect to +//  // the matrices, so this code also assumes inverted quaternions +//  // (-x, -y, -z, w). The result is that roll,pitch,yaw are applied +//  // in reverse order (yaw,pitch,roll). +//  F64 cosX = cos(roll);  //    F64 cosY = cos(pitch);  //    F64 cosZ = cos(yaw);  // @@ -337,24 +337,24 @@ const LLQuaternion&	LLQuaternion::setQuat(const LLMatrix4 &mat)  //    F64 sinZ = sin(yaw);  //  //    mQ[VW] = (F32)sqrt(cosY*cosZ - sinX*sinY*sinZ + cosX*cosZ + cosX*cosY + 1.0)*.5; -//	if (fabs(mQ[VW]) < F_APPROXIMATELY_ZERO) -//	{ -//		// null rotation, any axis will do -//		mQ[VX] = 0.0f; -//		mQ[VY] = 1.0f; -//		mQ[VZ] = 0.0f; -//	} -//	else -//	{ -//		F32 inv_s = 1.0f / (4.0f * mQ[VW]); -//		mQ[VX] = (F32)-(-sinX*cosY - cosX*sinY*sinZ - sinX*cosZ) * inv_s; -//		mQ[VY] = (F32)-(-cosX*sinY*cosZ + sinX*sinZ - sinY) * inv_s; -//		mQ[VZ] = (F32)-(-cosY*sinZ - sinX*sinY*cosZ - cosX*sinZ) * inv_s;		 -//	} +//  if (fabs(mQ[VW]) < F_APPROXIMATELY_ZERO) +//  { +//      // null rotation, any axis will do +//      mQ[VX] = 0.0f; +//      mQ[VY] = 1.0f; +//      mQ[VZ] = 0.0f; +//  } +//  else +//  { +//      F32 inv_s = 1.0f / (4.0f * mQ[VW]); +//      mQ[VX] = (F32)-(-sinX*cosY - cosX*sinY*sinZ - sinX*cosZ) * inv_s; +//      mQ[VY] = (F32)-(-cosX*sinY*cosZ + sinX*sinZ - sinY) * inv_s; +//      mQ[VZ] = (F32)-(-cosY*sinZ - sinX*sinY*cosZ - cosX*sinZ) * inv_s; +//  }  //  //#else // This only works on a certain subset of roll/pitch/yaw -//	 -//	F64 cosX = cosf(roll/2.0); +// +//  F64 cosX = cosf(roll/2.0);  //    F64 cosY = cosf(pitch/2.0);  //    F64 cosZ = cosf(yaw/2.0);  // @@ -368,19 +368,19 @@ const LLQuaternion&	LLQuaternion::setQuat(const LLMatrix4 &mat)  //    mQ[VZ] = (F32)(cosX*cosY*sinZ - sinX*sinY*cosZ);  //#endif  // -//	normalize(); -//	return (*this); +//  normalize(); +//  return (*this);  }  // SJB: This code is correct for a logicly stored (non-transposed) matrix; -//		Our matrices are stored transposed, OpenGL style, so this generates the -//		INVERSE matrix, or the CORRECT matrix form an INVERSE quaternion. -//		Because we use similar logic in LLMatrix3::quaternion(), -//		we are internally consistant so everything works OK :) -LLMatrix3	LLQuaternion::getMatrix3(void) const +//      Our matrices are stored transposed, OpenGL style, so this generates the +//      INVERSE matrix, or the CORRECT matrix form an INVERSE quaternion. +//      Because we use similar logic in LLMatrix3::quaternion(), +//      we are internally consistant so everything works OK :) +LLMatrix3   LLQuaternion::getMatrix3(void) const  { -	LLMatrix3	mat; -	F32		xx, xy, xz, xw, yy, yz, yw, zz, zw; +    LLMatrix3   mat; +    F32     xx, xy, xz, xw, yy, yz, yw, zz, zw;      xx      = mQ[VX] * mQ[VX];      xy      = mQ[VX] * mQ[VY]; @@ -395,24 +395,24 @@ LLMatrix3	LLQuaternion::getMatrix3(void) const      zw      = mQ[VZ] * mQ[VW];      mat.mMatrix[0][0]  = 1.f - 2.f * ( yy + zz ); -    mat.mMatrix[0][1]  =	   2.f * ( xy + zw ); -    mat.mMatrix[0][2]  =	   2.f * ( xz - yw ); +    mat.mMatrix[0][1]  =       2.f * ( xy + zw ); +    mat.mMatrix[0][2]  =       2.f * ( xz - yw ); -    mat.mMatrix[1][0]  =	   2.f * ( xy - zw ); +    mat.mMatrix[1][0]  =       2.f * ( xy - zw );      mat.mMatrix[1][1]  = 1.f - 2.f * ( xx + zz ); -    mat.mMatrix[1][2]  =	   2.f * ( yz + xw ); +    mat.mMatrix[1][2]  =       2.f * ( yz + xw ); -    mat.mMatrix[2][0]  =	   2.f * ( xz + yw ); -    mat.mMatrix[2][1]  =	   2.f * ( yz - xw ); +    mat.mMatrix[2][0]  =       2.f * ( xz + yw ); +    mat.mMatrix[2][1]  =       2.f * ( yz - xw );      mat.mMatrix[2][2]  = 1.f - 2.f * ( xx + yy ); -	return mat; +    return mat;  } -LLMatrix4	LLQuaternion::getMatrix4(void) const +LLMatrix4   LLQuaternion::getMatrix4(void) const  { -	LLMatrix4	mat; -	F32		xx, xy, xz, xw, yy, yz, yw, zz, zw; +    LLMatrix4   mat; +    F32     xx, xy, xz, xw, yy, yz, yw, zz, zw;      xx      = mQ[VX] * mQ[VX];      xy      = mQ[VX] * mQ[VY]; @@ -427,20 +427,20 @@ LLMatrix4	LLQuaternion::getMatrix4(void) const      zw      = mQ[VZ] * mQ[VW];      mat.mMatrix[0][0]  = 1.f - 2.f * ( yy + zz ); -    mat.mMatrix[0][1]  =	   2.f * ( xy + zw ); -    mat.mMatrix[0][2]  =	   2.f * ( xz - yw ); +    mat.mMatrix[0][1]  =       2.f * ( xy + zw ); +    mat.mMatrix[0][2]  =       2.f * ( xz - yw ); -    mat.mMatrix[1][0]  =	   2.f * ( xy - zw ); +    mat.mMatrix[1][0]  =       2.f * ( xy - zw );      mat.mMatrix[1][1]  = 1.f - 2.f * ( xx + zz ); -    mat.mMatrix[1][2]  =	   2.f * ( yz + xw ); +    mat.mMatrix[1][2]  =       2.f * ( yz + xw ); -    mat.mMatrix[2][0]  =	   2.f * ( xz + yw ); -    mat.mMatrix[2][1]  =	   2.f * ( yz - xw ); +    mat.mMatrix[2][0]  =       2.f * ( xz + yw ); +    mat.mMatrix[2][1]  =       2.f * ( yz - xw );      mat.mMatrix[2][2]  = 1.f - 2.f * ( xx + yy ); -	// TODO -- should we set the translation portion to zero? +    // TODO -- should we set the translation portion to zero? -	return mat; +    return mat;  } @@ -452,110 +452,110 @@ LLMatrix4	LLQuaternion::getMatrix4(void) const  // calculate the shortest rotation from a to b  void LLQuaternion::shortestArc(const LLVector3 &a, const LLVector3 &b)  { -	F32 ab = a * b; // dotproduct -	LLVector3 c = a % b; // crossproduct -	F32 cc = c * c; // squared length of the crossproduct -	if (ab * ab + cc) // test if the arguments have sufficient magnitude -	{ -		if (cc > 0.0f) // test if the arguments are (anti)parallel -		{ -			F32 s = sqrtf(ab * ab + cc) + ab; // note: don't try to optimize this line -			F32 m = 1.0f / sqrtf(cc + s * s); // the inverted magnitude of the quaternion -			mQ[VX] = c.mV[VX] * m; -			mQ[VY] = c.mV[VY] * m; -			mQ[VZ] = c.mV[VZ] * m; -			mQ[VW] = s * m; -			return; -		} -		if (ab < 0.0f) // test if the angle is bigger than PI/2 (anti parallel) -		{ -			c = a - b; // the arguments are anti-parallel, we have to choose an axis -			F32 m = sqrtf(c.mV[VX] * c.mV[VX] +  c.mV[VY] * c.mV[VY]); // the length projected on the XY-plane -			if (m > FP_MAG_THRESHOLD) -			{ -				mQ[VX] = -c.mV[VY] / m; // return the quaternion with the axis in the XY-plane -				mQ[VY] =  c.mV[VX] / m; -				mQ[VZ] = 0.0f; -				mQ[VW] = 0.0f; -				return; -			} -			else // the vectors are parallel to the Z-axis -			{ -				mQ[VX] = 1.0f; // rotate around the X-axis -				mQ[VY] = 0.0f; -				mQ[VZ] = 0.0f; -				mQ[VW] = 0.0f; -				return; -			} -		} -	} -	loadIdentity(); +    F32 ab = a * b; // dotproduct +    LLVector3 c = a % b; // crossproduct +    F32 cc = c * c; // squared length of the crossproduct +    if (ab * ab + cc) // test if the arguments have sufficient magnitude +    { +        if (cc > 0.0f) // test if the arguments are (anti)parallel +        { +            F32 s = sqrtf(ab * ab + cc) + ab; // note: don't try to optimize this line +            F32 m = 1.0f / sqrtf(cc + s * s); // the inverted magnitude of the quaternion +            mQ[VX] = c.mV[VX] * m; +            mQ[VY] = c.mV[VY] * m; +            mQ[VZ] = c.mV[VZ] * m; +            mQ[VW] = s * m; +            return; +        } +        if (ab < 0.0f) // test if the angle is bigger than PI/2 (anti parallel) +        { +            c = a - b; // the arguments are anti-parallel, we have to choose an axis +            F32 m = sqrtf(c.mV[VX] * c.mV[VX] +  c.mV[VY] * c.mV[VY]); // the length projected on the XY-plane +            if (m > FP_MAG_THRESHOLD) +            { +                mQ[VX] = -c.mV[VY] / m; // return the quaternion with the axis in the XY-plane +                mQ[VY] =  c.mV[VX] / m; +                mQ[VZ] = 0.0f; +                mQ[VW] = 0.0f; +                return; +            } +            else // the vectors are parallel to the Z-axis +            { +                mQ[VX] = 1.0f; // rotate around the X-axis +                mQ[VY] = 0.0f; +                mQ[VZ] = 0.0f; +                mQ[VW] = 0.0f; +                return; +            } +        } +    } +    loadIdentity();  }  // constrains rotation to a cone angle specified in radians  const LLQuaternion &LLQuaternion::constrain(F32 radians)  { -	const F32 cos_angle_lim = cosf( radians/2 );	// mQ[VW] limit -	const F32 sin_angle_lim = sinf( radians/2 );	// rotation axis length	limit +    const F32 cos_angle_lim = cosf( radians/2 );    // mQ[VW] limit +    const F32 sin_angle_lim = sinf( radians/2 );    // rotation axis length limit -	if (mQ[VW] < 0.f) -	{ -		mQ[VX] *= -1.f; -		mQ[VY] *= -1.f; -		mQ[VZ] *= -1.f; -		mQ[VW] *= -1.f; -	} +    if (mQ[VW] < 0.f) +    { +        mQ[VX] *= -1.f; +        mQ[VY] *= -1.f; +        mQ[VZ] *= -1.f; +        mQ[VW] *= -1.f; +    } -	// if rotation angle is greater than limit (cos is less than limit) -	if( mQ[VW] < cos_angle_lim ) -	{ -		mQ[VW] = cos_angle_lim; -		F32 axis_len = sqrtf( mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] ); // sin(theta/2) -		F32 axis_mult_fact = sin_angle_lim / axis_len; -		mQ[VX] *= axis_mult_fact; -		mQ[VY] *= axis_mult_fact; -		mQ[VZ] *= axis_mult_fact; -	} +    // if rotation angle is greater than limit (cos is less than limit) +    if( mQ[VW] < cos_angle_lim ) +    { +        mQ[VW] = cos_angle_lim; +        F32 axis_len = sqrtf( mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] ); // sin(theta/2) +        F32 axis_mult_fact = sin_angle_lim / axis_len; +        mQ[VX] *= axis_mult_fact; +        mQ[VY] *= axis_mult_fact; +        mQ[VZ] *= axis_mult_fact; +    } -	return *this; +    return *this;  }  // Operators  std::ostream& operator<<(std::ostream &s, const LLQuaternion &a)  { -	s << "{ "  -		<< a.mQ[VX] << ", " << a.mQ[VY] << ", " << a.mQ[VZ] << ", " << a.mQ[VW]  -	<< " }"; -	return s; +    s << "{ " +        << a.mQ[VX] << ", " << a.mQ[VY] << ", " << a.mQ[VZ] << ", " << a.mQ[VW] +    << " }"; +    return s;  }  // Does NOT renormalize the result -LLQuaternion	operator*(const LLQuaternion &a, const LLQuaternion &b) +LLQuaternion    operator*(const LLQuaternion &a, const LLQuaternion &b)  { -//	LLQuaternion::mMultCount++; +//  LLQuaternion::mMultCount++; -	LLQuaternion q( -		b.mQ[3] * a.mQ[0] + b.mQ[0] * a.mQ[3] + b.mQ[1] * a.mQ[2] - b.mQ[2] * a.mQ[1], -		b.mQ[3] * a.mQ[1] + b.mQ[1] * a.mQ[3] + b.mQ[2] * a.mQ[0] - b.mQ[0] * a.mQ[2], -		b.mQ[3] * a.mQ[2] + b.mQ[2] * a.mQ[3] + b.mQ[0] * a.mQ[1] - b.mQ[1] * a.mQ[0], -		b.mQ[3] * a.mQ[3] - b.mQ[0] * a.mQ[0] - b.mQ[1] * a.mQ[1] - b.mQ[2] * a.mQ[2] -	); -	return q; +    LLQuaternion q( +        b.mQ[3] * a.mQ[0] + b.mQ[0] * a.mQ[3] + b.mQ[1] * a.mQ[2] - b.mQ[2] * a.mQ[1], +        b.mQ[3] * a.mQ[1] + b.mQ[1] * a.mQ[3] + b.mQ[2] * a.mQ[0] - b.mQ[0] * a.mQ[2], +        b.mQ[3] * a.mQ[2] + b.mQ[2] * a.mQ[3] + b.mQ[0] * a.mQ[1] - b.mQ[1] * a.mQ[0], +        b.mQ[3] * a.mQ[3] - b.mQ[0] * a.mQ[0] - b.mQ[1] * a.mQ[1] - b.mQ[2] * a.mQ[2] +    ); +    return q;  }  /* -LLMatrix4	operator*(const LLMatrix4 &m, const LLQuaternion &q) +LLMatrix4   operator*(const LLMatrix4 &m, const LLQuaternion &q)  { -	LLMatrix4 qmat(q); -	return (m*qmat); +    LLMatrix4 qmat(q); +    return (m*qmat);  }  */ -LLVector4		operator*(const LLVector4 &a, const LLQuaternion &rot) +LLVector4       operator*(const LLVector4 &a, const LLQuaternion &rot)  {      F32 rw = - rot.mQ[VX] * a.mV[VX] - rot.mQ[VY] * a.mV[VY] - rot.mQ[VZ] * a.mV[VZ];      F32 rx =   rot.mQ[VW] * a.mV[VX] + rot.mQ[VY] * a.mV[VZ] - rot.mQ[VZ] * a.mV[VY]; @@ -569,7 +569,7 @@ LLVector4		operator*(const LLVector4 &a, const LLQuaternion &rot)      return LLVector4(nx, ny, nz, a.mV[VW]);  } -LLVector3		operator*(const LLVector3 &a, const LLQuaternion &rot) +LLVector3       operator*(const LLVector3 &a, const LLQuaternion &rot)  {      F32 rw = - rot.mQ[VX] * a.mV[VX] - rot.mQ[VY] * a.mV[VY] - rot.mQ[VZ] * a.mV[VZ];      F32 rx =   rot.mQ[VW] * a.mV[VX] + rot.mQ[VY] * a.mV[VZ] - rot.mQ[VZ] * a.mV[VY]; @@ -583,7 +583,7 @@ LLVector3		operator*(const LLVector3 &a, const LLQuaternion &rot)      return LLVector3(nx, ny, nz);  } -LLVector3d		operator*(const LLVector3d &a, const LLQuaternion &rot) +LLVector3d      operator*(const LLVector3d &a, const LLQuaternion &rot)  {      F64 rw = - rot.mQ[VX] * a.mdV[VX] - rot.mQ[VY] * a.mdV[VY] - rot.mQ[VZ] * a.mdV[VZ];      F64 rx =   rot.mQ[VW] * a.mdV[VX] + rot.mQ[VY] * a.mdV[VZ] - rot.mQ[VZ] * a.mdV[VY]; @@ -599,10 +599,10 @@ LLVector3d		operator*(const LLVector3d &a, const LLQuaternion &rot)  F32 dot(const LLQuaternion &a, const LLQuaternion &b)  { -	return a.mQ[VX] * b.mQ[VX] +  -		   a.mQ[VY] * b.mQ[VY] +  -		   a.mQ[VZ] * b.mQ[VZ] +  -		   a.mQ[VW] * b.mQ[VW];  +    return a.mQ[VX] * b.mQ[VX] + +           a.mQ[VY] * b.mQ[VY] + +           a.mQ[VZ] * b.mQ[VZ] + +           a.mQ[VW] * b.mQ[VW];  }  // DEMO HACK: This lerp is probably inocrrect now due intermediate normalization @@ -611,258 +611,258 @@ F32 dot(const LLQuaternion &a, const LLQuaternion &b)  // linear interpolation  LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q)  { -	LLQuaternion r; -	r = t * (q - p) + p; -	r.normalize(); -	return r; +    LLQuaternion r; +    r = t * (q - p) + p; +    r.normalize(); +    return r;  }  #endif  // lerp from identity to q  LLQuaternion lerp(F32 t, const LLQuaternion &q)  { -	LLQuaternion r; -	r.mQ[VX] = t * q.mQ[VX]; -	r.mQ[VY] = t * q.mQ[VY]; -	r.mQ[VZ] = t * q.mQ[VZ]; -	r.mQ[VW] = t * (q.mQ[VZ] - 1.f) + 1.f; -	r.normalize(); -	return r; +    LLQuaternion r; +    r.mQ[VX] = t * q.mQ[VX]; +    r.mQ[VY] = t * q.mQ[VY]; +    r.mQ[VZ] = t * q.mQ[VZ]; +    r.mQ[VW] = t * (q.mQ[VZ] - 1.f) + 1.f; +    r.normalize(); +    return r;  }  LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q)  { -	LLQuaternion r; -	F32 inv_t; +    LLQuaternion r; +    F32 inv_t; -	inv_t = 1.f - t; +    inv_t = 1.f - t; -	r.mQ[VX] = t * q.mQ[VX] + (inv_t * p.mQ[VX]); -	r.mQ[VY] = t * q.mQ[VY] + (inv_t * p.mQ[VY]); -	r.mQ[VZ] = t * q.mQ[VZ] + (inv_t * p.mQ[VZ]); -	r.mQ[VW] = t * q.mQ[VW] + (inv_t * p.mQ[VW]); -	r.normalize(); -	return r; +    r.mQ[VX] = t * q.mQ[VX] + (inv_t * p.mQ[VX]); +    r.mQ[VY] = t * q.mQ[VY] + (inv_t * p.mQ[VY]); +    r.mQ[VZ] = t * q.mQ[VZ] + (inv_t * p.mQ[VZ]); +    r.mQ[VW] = t * q.mQ[VW] + (inv_t * p.mQ[VW]); +    r.normalize(); +    return r;  }  // spherical linear interpolation  LLQuaternion slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b )  { -	// cosine theta = dot product of a and b -	F32 cos_t = a.mQ[0]*b.mQ[0] + a.mQ[1]*b.mQ[1] + a.mQ[2]*b.mQ[2] + a.mQ[3]*b.mQ[3]; -	 -	// if b is on opposite hemisphere from a, use -a instead -	int bflip; - 	if (cos_t < 0.0f) -	{ -		cos_t = -cos_t; -		bflip = TRUE; -	} -	else -		bflip = FALSE; - -	// if B is (within precision limits) the same as A, -	// just linear interpolate between A and B. -	F32 alpha;	// interpolant -	F32 beta;		// 1 - interpolant -	if (1.0f - cos_t < 0.00001f) -	{ -		beta = 1.0f - u; -		alpha = u; - 	} -	else -	{ - 		F32 theta = acosf(cos_t); - 		F32 sin_t = sinf(theta); - 		beta = sinf(theta - u*theta) / sin_t; - 		alpha = sinf(u*theta) / sin_t; - 	} - -	if (bflip) -		beta = -beta; - -	// interpolate -	LLQuaternion ret; -	ret.mQ[0] = beta*a.mQ[0] + alpha*b.mQ[0]; - 	ret.mQ[1] = beta*a.mQ[1] + alpha*b.mQ[1]; - 	ret.mQ[2] = beta*a.mQ[2] + alpha*b.mQ[2]; - 	ret.mQ[3] = beta*a.mQ[3] + alpha*b.mQ[3]; - -	return ret; +    // cosine theta = dot product of a and b +    F32 cos_t = a.mQ[0]*b.mQ[0] + a.mQ[1]*b.mQ[1] + a.mQ[2]*b.mQ[2] + a.mQ[3]*b.mQ[3]; + +    // if b is on opposite hemisphere from a, use -a instead +    int bflip; +    if (cos_t < 0.0f) +    { +        cos_t = -cos_t; +        bflip = TRUE; +    } +    else +        bflip = FALSE; + +    // if B is (within precision limits) the same as A, +    // just linear interpolate between A and B. +    F32 alpha;  // interpolant +    F32 beta;       // 1 - interpolant +    if (1.0f - cos_t < 0.00001f) +    { +        beta = 1.0f - u; +        alpha = u; +    } +    else +    { +        F32 theta = acosf(cos_t); +        F32 sin_t = sinf(theta); +        beta = sinf(theta - u*theta) / sin_t; +        alpha = sinf(u*theta) / sin_t; +    } + +    if (bflip) +        beta = -beta; + +    // interpolate +    LLQuaternion ret; +    ret.mQ[0] = beta*a.mQ[0] + alpha*b.mQ[0]; +    ret.mQ[1] = beta*a.mQ[1] + alpha*b.mQ[1]; +    ret.mQ[2] = beta*a.mQ[2] + alpha*b.mQ[2]; +    ret.mQ[3] = beta*a.mQ[3] + alpha*b.mQ[3]; + +    return ret;  }  // lerp whenever possible  LLQuaternion nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b)  { -	if (dot(a, b) < 0.f) -	{ -		return slerp(t, a, b); -	} -	else -	{ -		return lerp(t, a, b); -	} +    if (dot(a, b) < 0.f) +    { +        return slerp(t, a, b); +    } +    else +    { +        return lerp(t, a, b); +    }  }  LLQuaternion nlerp(F32 t, const LLQuaternion &q)  { -	if (q.mQ[VW] < 0.f) -	{ -		return slerp(t, q); -	} -	else -	{ -		return lerp(t, q); -	} +    if (q.mQ[VW] < 0.f) +    { +        return slerp(t, q); +    } +    else +    { +        return lerp(t, q); +    }  }  // slerp from identity quaternion to another quaternion  LLQuaternion slerp(F32 t, const LLQuaternion &q)  { -	F32 c = q.mQ[VW]; -	if (1.0f == t  ||  1.0f == c) -	{ -		// the trivial cases -		return q; -	} +    F32 c = q.mQ[VW]; +    if (1.0f == t  ||  1.0f == c) +    { +        // the trivial cases +        return q; +    } -	LLQuaternion r; -	F32 s, angle, stq, stp; +    LLQuaternion r; +    F32 s, angle, stq, stp; -	s = (F32) sqrt(1.f - c*c); +    s = (F32) sqrt(1.f - c*c);      if (c < 0.0f)      { -        // when c < 0.0 then theta > PI/2  -        // since quat and -quat are the same rotation we invert one of   +        // when c < 0.0 then theta > PI/2 +        // since quat and -quat are the same rotation we invert one of          // p or q to reduce unecessary spins -        // A equivalent way to do it is to convert acos(c) as if it had  -		// been negative, and to negate stp  -        angle   = (F32) acos(-c);  +        // A equivalent way to do it is to convert acos(c) as if it had +        // been negative, and to negate stp +        angle   = (F32) acos(-c);          stp     = -(F32) sin(angle * (1.f - t));          stq     = (F32) sin(angle * t); -    }    +    }      else      { -		angle 	= (F32) acos(c); +        angle   = (F32) acos(c);          stp     = (F32) sin(angle * (1.f - t));          stq     = (F32) sin(angle * t);      } -	r.mQ[VX] = (q.mQ[VX] * stq) / s; -	r.mQ[VY] = (q.mQ[VY] * stq) / s; -	r.mQ[VZ] = (q.mQ[VZ] * stq) / s; -	r.mQ[VW] = (stp + q.mQ[VW] * stq) / s; +    r.mQ[VX] = (q.mQ[VX] * stq) / s; +    r.mQ[VY] = (q.mQ[VY] * stq) / s; +    r.mQ[VZ] = (q.mQ[VZ] * stq) / s; +    r.mQ[VW] = (stp + q.mQ[VW] * stq) / s; -	return r; +    return r;  }  LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order)  { -	LLQuaternion xQ( xRot*DEG_TO_RAD, LLVector3(1.0f, 0.0f, 0.0f) ); -	LLQuaternion yQ( yRot*DEG_TO_RAD, LLVector3(0.0f, 1.0f, 0.0f) ); -	LLQuaternion zQ( zRot*DEG_TO_RAD, LLVector3(0.0f, 0.0f, 1.0f) ); -	LLQuaternion ret; -	switch( order ) -	{ -	case LLQuaternion::XYZ: -		ret = xQ * yQ * zQ; -		break; -	case LLQuaternion::YZX: -		ret = yQ * zQ * xQ; -		break; -	case LLQuaternion::ZXY: -		ret = zQ * xQ * yQ; -		break; -	case LLQuaternion::XZY: -		ret = xQ * zQ * yQ; -		break; -	case LLQuaternion::YXZ: -		ret = yQ * xQ * zQ; -		break; -	case LLQuaternion::ZYX: -		ret = zQ * yQ * xQ; -		break; -	} -	return ret; +    LLQuaternion xQ( xRot*DEG_TO_RAD, LLVector3(1.0f, 0.0f, 0.0f) ); +    LLQuaternion yQ( yRot*DEG_TO_RAD, LLVector3(0.0f, 1.0f, 0.0f) ); +    LLQuaternion zQ( zRot*DEG_TO_RAD, LLVector3(0.0f, 0.0f, 1.0f) ); +    LLQuaternion ret; +    switch( order ) +    { +    case LLQuaternion::XYZ: +        ret = xQ * yQ * zQ; +        break; +    case LLQuaternion::YZX: +        ret = yQ * zQ * xQ; +        break; +    case LLQuaternion::ZXY: +        ret = zQ * xQ * yQ; +        break; +    case LLQuaternion::XZY: +        ret = xQ * zQ * yQ; +        break; +    case LLQuaternion::YXZ: +        ret = yQ * xQ * zQ; +        break; +    case LLQuaternion::ZYX: +        ret = zQ * yQ * xQ; +        break; +    } +    return ret;  }  const char *OrderToString( const LLQuaternion::Order order )  { -	const char *p = NULL; -	switch( order ) -	{ -	default: -	case LLQuaternion::XYZ: -		p = "XYZ"; -		break; -	case LLQuaternion::YZX: -		p = "YZX"; -		break; -	case LLQuaternion::ZXY: -		p = "ZXY"; -		break; -	case LLQuaternion::XZY: -		p = "XZY"; -		break; -	case LLQuaternion::YXZ: -		p = "YXZ"; -		break; -	case LLQuaternion::ZYX: -		p = "ZYX"; -		break; -	} -	return p; +    const char *p = NULL; +    switch( order ) +    { +    default: +    case LLQuaternion::XYZ: +        p = "XYZ"; +        break; +    case LLQuaternion::YZX: +        p = "YZX"; +        break; +    case LLQuaternion::ZXY: +        p = "ZXY"; +        break; +    case LLQuaternion::XZY: +        p = "XZY"; +        break; +    case LLQuaternion::YXZ: +        p = "YXZ"; +        break; +    case LLQuaternion::ZYX: +        p = "ZYX"; +        break; +    } +    return p;  }  LLQuaternion::Order StringToOrder( const char *str )  { -	if (strncmp(str, "XYZ", 3)==0 || strncmp(str, "xyz", 3)==0) -		return LLQuaternion::XYZ; +    if (strncmp(str, "XYZ", 3)==0 || strncmp(str, "xyz", 3)==0) +        return LLQuaternion::XYZ; -	if (strncmp(str, "YZX", 3)==0 || strncmp(str, "yzx", 3)==0) -		return LLQuaternion::YZX; +    if (strncmp(str, "YZX", 3)==0 || strncmp(str, "yzx", 3)==0) +        return LLQuaternion::YZX; -	if (strncmp(str, "ZXY", 3)==0 || strncmp(str, "zxy", 3)==0) -		return LLQuaternion::ZXY; +    if (strncmp(str, "ZXY", 3)==0 || strncmp(str, "zxy", 3)==0) +        return LLQuaternion::ZXY; -	if (strncmp(str, "XZY", 3)==0 || strncmp(str, "xzy", 3)==0) -		return LLQuaternion::XZY; +    if (strncmp(str, "XZY", 3)==0 || strncmp(str, "xzy", 3)==0) +        return LLQuaternion::XZY; -	if (strncmp(str, "YXZ", 3)==0 || strncmp(str, "yxz", 3)==0) -		return LLQuaternion::YXZ; +    if (strncmp(str, "YXZ", 3)==0 || strncmp(str, "yxz", 3)==0) +        return LLQuaternion::YXZ; -	if (strncmp(str, "ZYX", 3)==0 || strncmp(str, "zyx", 3)==0) -		return LLQuaternion::ZYX; +    if (strncmp(str, "ZYX", 3)==0 || strncmp(str, "zyx", 3)==0) +        return LLQuaternion::ZYX; -	return LLQuaternion::XYZ; +    return LLQuaternion::XYZ;  }  void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const  { -	F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]); // length of the vector-component -	if (v > FP_MAG_THRESHOLD) -	{ -		F32 oomag = 1.0f / v; -		F32 w = mQ[VW]; -		if (mQ[VW] < 0.0f) -		{ -			w = -w; // make VW positive -			oomag = -oomag; // invert the axis -		} -		vec.mV[VX] = mQ[VX] * oomag; // normalize the axis -		vec.mV[VY] = mQ[VY] * oomag; -		vec.mV[VZ] = mQ[VZ] * oomag; -		*angle = 2.0f * atan2f(v, w); // get the angle -	} -	else -	{ -		*angle = 0.0f; // no rotation -		vec.mV[VX] = 0.0f; // around some dummy axis -		vec.mV[VY] = 0.0f; -		vec.mV[VZ] = 1.0f; -	} +    F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]); // length of the vector-component +    if (v > FP_MAG_THRESHOLD) +    { +        F32 oomag = 1.0f / v; +        F32 w = mQ[VW]; +        if (mQ[VW] < 0.0f) +        { +            w = -w; // make VW positive +            oomag = -oomag; // invert the axis +        } +        vec.mV[VX] = mQ[VX] * oomag; // normalize the axis +        vec.mV[VY] = mQ[VY] * oomag; +        vec.mV[VZ] = mQ[VZ] * oomag; +        *angle = 2.0f * atan2f(v, w); // get the angle +    } +    else +    { +        *angle = 0.0f; // no rotation +        vec.mV[VX] = 0.0f; // around some dummy axis +        vec.mV[VY] = 0.0f; +        vec.mV[VZ] = 1.0f; +    }  }  const LLQuaternion& LLQuaternion::setFromAzimuthAndAltitude(F32 azimuthRadians, F32 altitudeRadians) @@ -888,93 +888,93 @@ void LLQuaternion::getAzimuthAndAltitude(F32 &azimuthRadians, F32 &altitudeRadia  // quaternion does not need to be normalized  void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const  { -	F32 sx = 2 * (mQ[VX] * mQ[VW] - mQ[VY] * mQ[VZ]); // sine of the roll -	F32 sy = 2 * (mQ[VY] * mQ[VW] + mQ[VX] * mQ[VZ]); // sine of the pitch -	F32 ys = mQ[VW] * mQ[VW] - mQ[VY] * mQ[VY]; // intermediate cosine 1 -	F32 xz = mQ[VX] * mQ[VX] - mQ[VZ] * mQ[VZ]; // intermediate cosine 2 -	F32 cx = ys - xz; // cosine of the roll -	F32 cy = sqrtf(sx * sx + cx * cx); // cosine of the pitch -	if (cy > GIMBAL_THRESHOLD) // no gimbal lock -	{ -		*roll  = atan2f(sx, cx); -		*pitch = atan2f(sy, cy); -		*yaw   = atan2f(2 * (mQ[VZ] * mQ[VW] - mQ[VX] * mQ[VY]), ys + xz); -	} -	else // gimbal lock -	{ -		if (sy > 0) -		{ -			*pitch = F_PI_BY_TWO; -			*yaw = 2 * atan2f(mQ[VZ] + mQ[VX], mQ[VW] + mQ[VY]); -		} -		else -		{ -			*pitch = -F_PI_BY_TWO; -			*yaw = 2 * atan2f(mQ[VZ] - mQ[VX], mQ[VW] - mQ[VY]); -		} -		*roll = 0; -	} +    F32 sx = 2 * (mQ[VX] * mQ[VW] - mQ[VY] * mQ[VZ]); // sine of the roll +    F32 sy = 2 * (mQ[VY] * mQ[VW] + mQ[VX] * mQ[VZ]); // sine of the pitch +    F32 ys = mQ[VW] * mQ[VW] - mQ[VY] * mQ[VY]; // intermediate cosine 1 +    F32 xz = mQ[VX] * mQ[VX] - mQ[VZ] * mQ[VZ]; // intermediate cosine 2 +    F32 cx = ys - xz; // cosine of the roll +    F32 cy = sqrtf(sx * sx + cx * cx); // cosine of the pitch +    if (cy > GIMBAL_THRESHOLD) // no gimbal lock +    { +        *roll  = atan2f(sx, cx); +        *pitch = atan2f(sy, cy); +        *yaw   = atan2f(2 * (mQ[VZ] * mQ[VW] - mQ[VX] * mQ[VY]), ys + xz); +    } +    else // gimbal lock +    { +        if (sy > 0) +        { +            *pitch = F_PI_BY_TWO; +            *yaw = 2 * atan2f(mQ[VZ] + mQ[VX], mQ[VW] + mQ[VY]); +        } +        else +        { +            *pitch = -F_PI_BY_TWO; +            *yaw = 2 * atan2f(mQ[VZ] - mQ[VX], mQ[VW] - mQ[VY]); +        } +        *roll = 0; +    }  }  // Saves space by using the fact that our quaternions are normalized  LLVector3 LLQuaternion::packToVector3() const  { -	F32 x = mQ[VX]; -	F32 y = mQ[VY]; -	F32 z = mQ[VZ]; -	F32 w = mQ[VW]; -	F32 mag = sqrtf(x * x + y * y + z * z + w * w); -	if (mag > FP_MAG_THRESHOLD) -	{ -		x /= mag; -		y /= mag; -		z /= mag; // no need to normalize w, it's not used -	} -	if( mQ[VW] >= 0 ) -	{ -		return LLVector3( x, y , z ); -	} -	else -	{ -		return LLVector3( -x, -y, -z ); -	} +    F32 x = mQ[VX]; +    F32 y = mQ[VY]; +    F32 z = mQ[VZ]; +    F32 w = mQ[VW]; +    F32 mag = sqrtf(x * x + y * y + z * z + w * w); +    if (mag > FP_MAG_THRESHOLD) +    { +        x /= mag; +        y /= mag; +        z /= mag; // no need to normalize w, it's not used +    } +    if( mQ[VW] >= 0 ) +    { +        return LLVector3( x, y , z ); +    } +    else +    { +        return LLVector3( -x, -y, -z ); +    }  }  // Saves space by using the fact that our quaternions are normalized  void LLQuaternion::unpackFromVector3( const LLVector3& vec )  { -	mQ[VX] = vec.mV[VX]; -	mQ[VY] = vec.mV[VY]; -	mQ[VZ] = vec.mV[VZ]; -	F32 t = 1.f - vec.magVecSquared(); -	if( t > 0 ) -	{ -		mQ[VW] = sqrt( t ); -	} -	else -	{ -		// Need this to avoid trying to find the square root of a negative number due -		// to floating point error. -		mQ[VW] = 0; -	} +    mQ[VX] = vec.mV[VX]; +    mQ[VY] = vec.mV[VY]; +    mQ[VZ] = vec.mV[VZ]; +    F32 t = 1.f - vec.magVecSquared(); +    if( t > 0 ) +    { +        mQ[VW] = sqrt( t ); +    } +    else +    { +        // Need this to avoid trying to find the square root of a negative number due +        // to floating point error. +        mQ[VW] = 0; +    }  }  BOOL LLQuaternion::parseQuat(const std::string& buf, LLQuaternion* value)  { -	if( buf.empty() || value == NULL) -	{ -		return FALSE; -	} +    if( buf.empty() || value == NULL) +    { +        return FALSE; +    } -	LLQuaternion quat; -	S32 count = sscanf( buf.c_str(), "%f %f %f %f", quat.mQ + 0, quat.mQ + 1, quat.mQ + 2, quat.mQ + 3 ); -	if( 4 == count ) -	{ -		value->set( quat ); -		return TRUE; -	} +    LLQuaternion quat; +    S32 count = sscanf( buf.c_str(), "%f %f %f %f", quat.mQ + 0, quat.mQ + 1, quat.mQ + 2, quat.mQ + 3 ); +    if( 4 == count ) +    { +        value->set( quat ); +        return TRUE; +    } -	return FALSE; +    return FALSE;  } diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h index 51ce163b4e..fbe4da97f7 100644 --- a/indra/llmath/llquaternion.h +++ b/indra/llmath/llquaternion.h @@ -5,21 +5,21 @@   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -40,137 +40,137 @@ class LLVector3d;  class LLMatrix4;  class LLMatrix3; -//	NOTA BENE: Quaternion code is written assuming Unit Quaternions!!!! -//			   Moreover, it is written assuming that all vectors and matricies -//			   passed as arguments are normalized and unitary respectively. -//			   VERY VERY VERY VERY BAD THINGS will happen if these assumptions fail. +//  NOTA BENE: Quaternion code is written assuming Unit Quaternions!!!! +//             Moreover, it is written assuming that all vectors and matricies +//             passed as arguments are normalized and unitary respectively. +//             VERY VERY VERY VERY BAD THINGS will happen if these assumptions fail.  static const U32 LENGTHOFQUAT = 4;  class LLQuaternion  {  public: -	F32 mQ[LENGTHOFQUAT]; - -	static const LLQuaternion DEFAULT; - -	LLQuaternion();									// Initializes Quaternion to (0,0,0,1) -	explicit LLQuaternion(const LLMatrix4 &mat);				// Initializes Quaternion from Matrix4 -	explicit LLQuaternion(const LLMatrix3 &mat);				// Initializes Quaternion from Matrix3 -	LLQuaternion(F32 x, F32 y, F32 z, F32 w);		// Initializes Quaternion to normalize(x, y, z, w) -	LLQuaternion(F32 angle, const LLVector4 &vec);	// Initializes Quaternion to axis_angle2quat(angle, vec) -	LLQuaternion(F32 angle, const LLVector3 &vec);	// Initializes Quaternion to axis_angle2quat(angle, vec) -	LLQuaternion(const F32 *q);						// Initializes Quaternion to normalize(x, y, z, w) -	LLQuaternion(const LLVector3 &x_axis, -				 const LLVector3 &y_axis, -				 const LLVector3 &z_axis);			// Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis] +    F32 mQ[LENGTHOFQUAT]; + +    static const LLQuaternion DEFAULT; + +    LLQuaternion();                                 // Initializes Quaternion to (0,0,0,1) +    explicit LLQuaternion(const LLMatrix4 &mat);                // Initializes Quaternion from Matrix4 +    explicit LLQuaternion(const LLMatrix3 &mat);                // Initializes Quaternion from Matrix3 +    LLQuaternion(F32 x, F32 y, F32 z, F32 w);       // Initializes Quaternion to normalize(x, y, z, w) +    LLQuaternion(F32 angle, const LLVector4 &vec);  // Initializes Quaternion to axis_angle2quat(angle, vec) +    LLQuaternion(F32 angle, const LLVector3 &vec);  // Initializes Quaternion to axis_angle2quat(angle, vec) +    LLQuaternion(const F32 *q);                     // Initializes Quaternion to normalize(x, y, z, w) +    LLQuaternion(const LLVector3 &x_axis, +                 const LLVector3 &y_axis, +                 const LLVector3 &z_axis);          // Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis]      explicit LLQuaternion(const LLSD &sd);          // Initializes Quaternion from LLSD array.      LLSD getValue() const;      void setValue(const LLSD& sd); -	BOOL isIdentity() const; -	BOOL isNotIdentity() const; -	BOOL isFinite() const;									// checks to see if all values of LLQuaternion are finite -	void quantize16(F32 lower, F32 upper);					// changes the vector to reflect quatization -	void quantize8(F32 lower, F32 upper);							// changes the vector to reflect quatization -	void loadIdentity();											// Loads the quaternion that represents the identity rotation - -	bool isEqualEps(const LLQuaternion &quat, F32 epsilon) const; -	bool isNotEqualEps(const LLQuaternion &quat, F32 epsilon) const; - -	const LLQuaternion&	set(F32 x, F32 y, F32 z, F32 w);		// Sets Quaternion to normalize(x, y, z, w) -	const LLQuaternion&	set(const LLQuaternion &quat);			// Copies Quaternion -	const LLQuaternion&	set(const F32 *q);						// Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW]) -	const LLQuaternion&	set(const LLMatrix3 &mat);				// Sets Quaternion to mat2quat(mat) -	const LLQuaternion&	set(const LLMatrix4 &mat);				// Sets Quaternion to mat2quat(mat) +    BOOL isIdentity() const; +    BOOL isNotIdentity() const; +    BOOL isFinite() const;                                  // checks to see if all values of LLQuaternion are finite +    void quantize16(F32 lower, F32 upper);                  // changes the vector to reflect quatization +    void quantize8(F32 lower, F32 upper);                           // changes the vector to reflect quatization +    void loadIdentity();                                            // Loads the quaternion that represents the identity rotation + +    bool isEqualEps(const LLQuaternion &quat, F32 epsilon) const; +    bool isNotEqualEps(const LLQuaternion &quat, F32 epsilon) const; + +    const LLQuaternion& set(F32 x, F32 y, F32 z, F32 w);        // Sets Quaternion to normalize(x, y, z, w) +    const LLQuaternion& set(const LLQuaternion &quat);          // Copies Quaternion +    const LLQuaternion& set(const F32 *q);                      // Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW]) +    const LLQuaternion& set(const LLMatrix3 &mat);              // Sets Quaternion to mat2quat(mat) +    const LLQuaternion& set(const LLMatrix4 &mat);              // Sets Quaternion to mat2quat(mat)      const LLQuaternion& setFromAzimuthAndAltitude(F32 azimuth, F32 altitude); -     -	const LLQuaternion&	setAngleAxis(F32 angle, F32 x, F32 y, F32 z);	// Sets Quaternion to axis_angle2quat(angle, x, y, z) -	const LLQuaternion&	setAngleAxis(F32 angle, const LLVector3 &vec);	// Sets Quaternion to axis_angle2quat(angle, vec) -	const LLQuaternion&	setAngleAxis(F32 angle, const LLVector4 &vec);	// Sets Quaternion to axis_angle2quat(angle, vec) -	const LLQuaternion&	setEulerAngles(F32 roll, F32 pitch, F32 yaw);	// Sets Quaternion to euler2quat(pitch, yaw, roll) - -	const LLQuaternion&	setQuatInit(F32 x, F32 y, F32 z, F32 w);	// deprecated -	const LLQuaternion&	setQuat(const LLQuaternion &quat);			// deprecated -	const LLQuaternion&	setQuat(const F32 *q);						// deprecated -	const LLQuaternion&	setQuat(const LLMatrix3 &mat);				// deprecated -	const LLQuaternion&	setQuat(const LLMatrix4 &mat);				// deprecated -	const LLQuaternion&	setQuat(F32 angle, F32 x, F32 y, F32 z);	// deprecated -	const LLQuaternion&	setQuat(F32 angle, const LLVector3 &vec);	// deprecated -	const LLQuaternion&	setQuat(F32 angle, const LLVector4 &vec);	// deprecated -	const LLQuaternion&	setQuat(F32 roll, F32 pitch, F32 yaw);		// deprecated - -	LLMatrix4	getMatrix4(void) const;							// Returns the Matrix4 equivalent of Quaternion -	LLMatrix3	getMatrix3(void) const;							// Returns the Matrix3 equivalent of Quaternion -	void		getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const;	// returns rotation in radians about axis x,y,z -	void		getAngleAxis(F32* angle, LLVector3 &vec) const; -	void		getEulerAngles(F32 *roll, F32* pitch, F32 *yaw) const; + +    const LLQuaternion& setAngleAxis(F32 angle, F32 x, F32 y, F32 z);   // Sets Quaternion to axis_angle2quat(angle, x, y, z) +    const LLQuaternion& setAngleAxis(F32 angle, const LLVector3 &vec);  // Sets Quaternion to axis_angle2quat(angle, vec) +    const LLQuaternion& setAngleAxis(F32 angle, const LLVector4 &vec);  // Sets Quaternion to axis_angle2quat(angle, vec) +    const LLQuaternion& setEulerAngles(F32 roll, F32 pitch, F32 yaw);   // Sets Quaternion to euler2quat(pitch, yaw, roll) + +    const LLQuaternion& setQuatInit(F32 x, F32 y, F32 z, F32 w);    // deprecated +    const LLQuaternion& setQuat(const LLQuaternion &quat);          // deprecated +    const LLQuaternion& setQuat(const F32 *q);                      // deprecated +    const LLQuaternion& setQuat(const LLMatrix3 &mat);              // deprecated +    const LLQuaternion& setQuat(const LLMatrix4 &mat);              // deprecated +    const LLQuaternion& setQuat(F32 angle, F32 x, F32 y, F32 z);    // deprecated +    const LLQuaternion& setQuat(F32 angle, const LLVector3 &vec);   // deprecated +    const LLQuaternion& setQuat(F32 angle, const LLVector4 &vec);   // deprecated +    const LLQuaternion& setQuat(F32 roll, F32 pitch, F32 yaw);      // deprecated + +    LLMatrix4   getMatrix4(void) const;                         // Returns the Matrix4 equivalent of Quaternion +    LLMatrix3   getMatrix3(void) const;                         // Returns the Matrix3 equivalent of Quaternion +    void        getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const; // returns rotation in radians about axis x,y,z +    void        getAngleAxis(F32* angle, LLVector3 &vec) const; +    void        getEulerAngles(F32 *roll, F32* pitch, F32 *yaw) const;      void        getAzimuthAndAltitude(F32 &azimuth, F32 &altitude); -	F32	normalize();	// Normalizes Quaternion and returns magnitude -	F32	normQuat();		// deprecated - -	const LLQuaternion&	conjugate(void);	// Conjugates Quaternion and returns result -	const LLQuaternion&	conjQuat(void);		// deprecated - -	// Other useful methods -	const LLQuaternion&	transpose();		// transpose (same as conjugate) -	const LLQuaternion&	transQuat();		// deprecated - -	void			shortestArc(const LLVector3 &a, const LLVector3 &b);	// shortest rotation from a to b -	const LLQuaternion& constrain(F32 radians);						// constrains rotation to a cone angle specified in radians - -	// Standard operators -	friend std::ostream& operator<<(std::ostream &s, const LLQuaternion &a);					// Prints a -	friend LLQuaternion operator+(const LLQuaternion &a, const LLQuaternion &b);	// Addition -	friend LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b);	// Subtraction -	friend LLQuaternion operator-(const LLQuaternion &a);							// Negation -	friend LLQuaternion operator*(F32 a, const LLQuaternion &q);					// Scale -	friend LLQuaternion operator*(const LLQuaternion &q, F32 b);					// Scale -	friend LLQuaternion operator*(const LLQuaternion &a, const LLQuaternion &b);	// Returns a * b -	friend LLQuaternion operator~(const LLQuaternion &a);							// Returns a* (Conjugate of a) -	bool operator==(const LLQuaternion &b) const;			// Returns a == b -	bool operator!=(const LLQuaternion &b) const;			// Returns a != b - -	friend const LLQuaternion& operator*=(LLQuaternion &a, const LLQuaternion &b);	// Returns a * b - -	friend LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot);		// Rotates a by rot -	friend LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot);		// Rotates a by rot -	friend LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot);		// Rotates a by rot - -	// Non-standard operators -	friend F32 dot(const LLQuaternion &a, const LLQuaternion &b); -	friend LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q);		// linear interpolation (t = 0 to 1) from p to q -	friend LLQuaternion lerp(F32 t, const LLQuaternion &q);								// linear interpolation (t = 0 to 1) from identity to q -	friend LLQuaternion slerp(F32 t, const LLQuaternion &p, const LLQuaternion &q); 	// spherical linear interpolation from p to q -	friend LLQuaternion slerp(F32 t, const LLQuaternion &q);							// spherical linear interpolation from identity to q -	friend LLQuaternion nlerp(F32 t, const LLQuaternion &p, const LLQuaternion &q); 	// normalized linear interpolation from p to q -	friend LLQuaternion nlerp(F32 t, const LLQuaternion &q); 							// normalized linear interpolation from p to q - -	LLVector3	packToVector3() const;						// Saves space by using the fact that our quaternions are normalized -	void		unpackFromVector3(const LLVector3& vec);	// Saves space by using the fact that our quaternions are normalized - -	enum Order { -		XYZ = 0, -		YZX = 1, -		ZXY = 2, -		XZY = 3, -		YXZ = 4, -		ZYX = 5 -	}; -	// Creates a quaternions from maya's rotation representation, -	// which is 3 rotations (in DEGREES) in the specified order -	friend LLQuaternion mayaQ(F32 x, F32 y, F32 z, Order order); - -	// Conversions between Order and strings like "xyz" or "ZYX" -	friend const char *OrderToString( const Order order ); -	friend Order StringToOrder( const char *str ); - -	static BOOL parseQuat(const std::string& buf, LLQuaternion* value); - -	// For debugging, only -	//static U32 mMultCount; +    F32 normalize();    // Normalizes Quaternion and returns magnitude +    F32 normQuat();     // deprecated + +    const LLQuaternion& conjugate(void);    // Conjugates Quaternion and returns result +    const LLQuaternion& conjQuat(void);     // deprecated + +    // Other useful methods +    const LLQuaternion& transpose();        // transpose (same as conjugate) +    const LLQuaternion& transQuat();        // deprecated + +    void            shortestArc(const LLVector3 &a, const LLVector3 &b);    // shortest rotation from a to b +    const LLQuaternion& constrain(F32 radians);                     // constrains rotation to a cone angle specified in radians + +    // Standard operators +    friend std::ostream& operator<<(std::ostream &s, const LLQuaternion &a);                    // Prints a +    friend LLQuaternion operator+(const LLQuaternion &a, const LLQuaternion &b);    // Addition +    friend LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b);    // Subtraction +    friend LLQuaternion operator-(const LLQuaternion &a);                           // Negation +    friend LLQuaternion operator*(F32 a, const LLQuaternion &q);                    // Scale +    friend LLQuaternion operator*(const LLQuaternion &q, F32 b);                    // Scale +    friend LLQuaternion operator*(const LLQuaternion &a, const LLQuaternion &b);    // Returns a * b +    friend LLQuaternion operator~(const LLQuaternion &a);                           // Returns a* (Conjugate of a) +    bool operator==(const LLQuaternion &b) const;           // Returns a == b +    bool operator!=(const LLQuaternion &b) const;           // Returns a != b + +    friend const LLQuaternion& operator*=(LLQuaternion &a, const LLQuaternion &b);  // Returns a * b + +    friend LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot);        // Rotates a by rot +    friend LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot);        // Rotates a by rot +    friend LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot);      // Rotates a by rot + +    // Non-standard operators +    friend F32 dot(const LLQuaternion &a, const LLQuaternion &b); +    friend LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q);      // linear interpolation (t = 0 to 1) from p to q +    friend LLQuaternion lerp(F32 t, const LLQuaternion &q);                             // linear interpolation (t = 0 to 1) from identity to q +    friend LLQuaternion slerp(F32 t, const LLQuaternion &p, const LLQuaternion &q);     // spherical linear interpolation from p to q +    friend LLQuaternion slerp(F32 t, const LLQuaternion &q);                            // spherical linear interpolation from identity to q +    friend LLQuaternion nlerp(F32 t, const LLQuaternion &p, const LLQuaternion &q);     // normalized linear interpolation from p to q +    friend LLQuaternion nlerp(F32 t, const LLQuaternion &q);                            // normalized linear interpolation from p to q + +    LLVector3   packToVector3() const;                      // Saves space by using the fact that our quaternions are normalized +    void        unpackFromVector3(const LLVector3& vec);    // Saves space by using the fact that our quaternions are normalized + +    enum Order { +        XYZ = 0, +        YZX = 1, +        ZXY = 2, +        XZY = 3, +        YXZ = 4, +        ZYX = 5 +    }; +    // Creates a quaternions from maya's rotation representation, +    // which is 3 rotations (in DEGREES) in the specified order +    friend LLQuaternion mayaQ(F32 x, F32 y, F32 z, Order order); + +    // Conversions between Order and strings like "xyz" or "ZYX" +    friend const char *OrderToString( const Order order ); +    friend Order StringToOrder( const char *str ); + +    static BOOL parseQuat(const std::string& buf, LLQuaternion* value); + +    // For debugging, only +    //static U32 mMultCount;  };  inline LLSD LLQuaternion::getValue() const @@ -192,369 +192,369 @@ inline void LLQuaternion::setValue(const LLSD& sd)  }  // checker -inline BOOL	LLQuaternion::isFinite() const +inline BOOL LLQuaternion::isFinite() const  { -	return (llfinite(mQ[VX]) && llfinite(mQ[VY]) && llfinite(mQ[VZ]) && llfinite(mQ[VS])); +    return (llfinite(mQ[VX]) && llfinite(mQ[VY]) && llfinite(mQ[VZ]) && llfinite(mQ[VS]));  }  inline BOOL LLQuaternion::isIdentity() const  { -	return  -		( mQ[VX] == 0.f ) && -		( mQ[VY] == 0.f ) && -		( mQ[VZ] == 0.f ) && -		( mQ[VS] == 1.f ); +    return +        ( mQ[VX] == 0.f ) && +        ( mQ[VY] == 0.f ) && +        ( mQ[VZ] == 0.f ) && +        ( mQ[VS] == 1.f );  }  inline BOOL LLQuaternion::isNotIdentity() const  { -	return  -		( mQ[VX] != 0.f ) || -		( mQ[VY] != 0.f ) || -		( mQ[VZ] != 0.f ) || -		( mQ[VS] != 1.f ); +    return +        ( mQ[VX] != 0.f ) || +        ( mQ[VY] != 0.f ) || +        ( mQ[VZ] != 0.f ) || +        ( mQ[VS] != 1.f );  }  inline LLQuaternion::LLQuaternion(void)  { -	mQ[VX] = 0.f; -	mQ[VY] = 0.f; -	mQ[VZ] = 0.f; -	mQ[VS] = 1.f; +    mQ[VX] = 0.f; +    mQ[VY] = 0.f; +    mQ[VZ] = 0.f; +    mQ[VS] = 1.f;  }  inline LLQuaternion::LLQuaternion(F32 x, F32 y, F32 z, F32 w)  { -	mQ[VX] = x; -	mQ[VY] = y; -	mQ[VZ] = z; -	mQ[VS] = w; +    mQ[VX] = x; +    mQ[VY] = y; +    mQ[VZ] = z; +    mQ[VS] = w; -	//RN: don't normalize this case as its used mainly for temporaries during calculations -	//normalize(); -	/* -	F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); -	mag -= 1.f; -	mag = fabs(mag); -	llassert(mag < 10.f*FP_MAG_THRESHOLD); -	*/ +    //RN: don't normalize this case as its used mainly for temporaries during calculations +    //normalize(); +    /* +    F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); +    mag -= 1.f; +    mag = fabs(mag); +    llassert(mag < 10.f*FP_MAG_THRESHOLD); +    */  }  inline LLQuaternion::LLQuaternion(const F32 *q)  { -	mQ[VX] = q[VX]; -	mQ[VY] = q[VY]; -	mQ[VZ] = q[VZ]; -	mQ[VS] = q[VW]; +    mQ[VX] = q[VX]; +    mQ[VY] = q[VY]; +    mQ[VZ] = q[VZ]; +    mQ[VS] = q[VW]; -	normalize(); -	/* -	F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); -	mag -= 1.f; -	mag = fabs(mag); -	llassert(mag < FP_MAG_THRESHOLD); -	*/ +    normalize(); +    /* +    F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); +    mag -= 1.f; +    mag = fabs(mag); +    llassert(mag < FP_MAG_THRESHOLD); +    */  }  inline void LLQuaternion::loadIdentity()  { -	mQ[VX] = 0.0f; -	mQ[VY] = 0.0f; -	mQ[VZ] = 0.0f; -	mQ[VW] = 1.0f; +    mQ[VX] = 0.0f; +    mQ[VY] = 0.0f; +    mQ[VZ] = 0.0f; +    mQ[VW] = 1.0f;  }  inline bool LLQuaternion::isEqualEps(const LLQuaternion &quat, F32 epsilon) const  { -	return ( fabs(mQ[VX] - quat.mQ[VX]) < epsilon -		&&	 fabs(mQ[VY] - quat.mQ[VY]) < epsilon -		&&	 fabs(mQ[VZ] - quat.mQ[VZ]) < epsilon -		&&	 fabs(mQ[VS] - quat.mQ[VS]) < epsilon ); +    return ( fabs(mQ[VX] - quat.mQ[VX]) < epsilon +        &&   fabs(mQ[VY] - quat.mQ[VY]) < epsilon +        &&   fabs(mQ[VZ] - quat.mQ[VZ]) < epsilon +        &&   fabs(mQ[VS] - quat.mQ[VS]) < epsilon );  }  inline bool LLQuaternion::isNotEqualEps(const LLQuaternion &quat, F32 epsilon) const  { -	return (  fabs(mQ[VX] - quat.mQ[VX]) > epsilon -		||    fabs(mQ[VY] - quat.mQ[VY]) > epsilon -		||	  fabs(mQ[VZ] - quat.mQ[VZ]) > epsilon -		||    fabs(mQ[VS] - quat.mQ[VS]) > epsilon ); +    return (  fabs(mQ[VX] - quat.mQ[VX]) > epsilon +        ||    fabs(mQ[VY] - quat.mQ[VY]) > epsilon +        ||    fabs(mQ[VZ] - quat.mQ[VZ]) > epsilon +        ||    fabs(mQ[VS] - quat.mQ[VS]) > epsilon );  } -inline const LLQuaternion&	LLQuaternion::set(F32 x, F32 y, F32 z, F32 w) +inline const LLQuaternion&  LLQuaternion::set(F32 x, F32 y, F32 z, F32 w)  { -	mQ[VX] = x; -	mQ[VY] = y; -	mQ[VZ] = z; -	mQ[VS] = w; -	normalize(); -	return (*this); +    mQ[VX] = x; +    mQ[VY] = y; +    mQ[VZ] = z; +    mQ[VS] = w; +    normalize(); +    return (*this);  } -inline const LLQuaternion&	LLQuaternion::set(const LLQuaternion &quat) +inline const LLQuaternion&  LLQuaternion::set(const LLQuaternion &quat)  { -	mQ[VX] = quat.mQ[VX]; -	mQ[VY] = quat.mQ[VY]; -	mQ[VZ] = quat.mQ[VZ]; -	mQ[VW] = quat.mQ[VW]; -	normalize(); -	return (*this); +    mQ[VX] = quat.mQ[VX]; +    mQ[VY] = quat.mQ[VY]; +    mQ[VZ] = quat.mQ[VZ]; +    mQ[VW] = quat.mQ[VW]; +    normalize(); +    return (*this);  } -inline const LLQuaternion&	LLQuaternion::set(const F32 *q) +inline const LLQuaternion&  LLQuaternion::set(const F32 *q)  { -	mQ[VX] = q[VX]; -	mQ[VY] = q[VY]; -	mQ[VZ] = q[VZ]; -	mQ[VS] = q[VW]; -	normalize(); -	return (*this); +    mQ[VX] = q[VX]; +    mQ[VY] = q[VY]; +    mQ[VZ] = q[VZ]; +    mQ[VS] = q[VW]; +    normalize(); +    return (*this);  }  // deprecated -inline const LLQuaternion&	LLQuaternion::setQuatInit(F32 x, F32 y, F32 z, F32 w) +inline const LLQuaternion&  LLQuaternion::setQuatInit(F32 x, F32 y, F32 z, F32 w)  { -	mQ[VX] = x; -	mQ[VY] = y; -	mQ[VZ] = z; -	mQ[VS] = w; -	normalize(); -	return (*this); +    mQ[VX] = x; +    mQ[VY] = y; +    mQ[VZ] = z; +    mQ[VS] = w; +    normalize(); +    return (*this);  }  // deprecated -inline const LLQuaternion&	LLQuaternion::setQuat(const LLQuaternion &quat) +inline const LLQuaternion&  LLQuaternion::setQuat(const LLQuaternion &quat)  { -	mQ[VX] = quat.mQ[VX]; -	mQ[VY] = quat.mQ[VY]; -	mQ[VZ] = quat.mQ[VZ]; -	mQ[VW] = quat.mQ[VW]; -	normalize(); -	return (*this); +    mQ[VX] = quat.mQ[VX]; +    mQ[VY] = quat.mQ[VY]; +    mQ[VZ] = quat.mQ[VZ]; +    mQ[VW] = quat.mQ[VW]; +    normalize(); +    return (*this);  }  // deprecated -inline const LLQuaternion&	LLQuaternion::setQuat(const F32 *q) +inline const LLQuaternion&  LLQuaternion::setQuat(const F32 *q)  { -	mQ[VX] = q[VX]; -	mQ[VY] = q[VY]; -	mQ[VZ] = q[VZ]; -	mQ[VS] = q[VW]; -	normalize(); -	return (*this); +    mQ[VX] = q[VX]; +    mQ[VY] = q[VY]; +    mQ[VZ] = q[VZ]; +    mQ[VS] = q[VW]; +    normalize(); +    return (*this);  }  inline void LLQuaternion::getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const  { -	F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]); // length of the vector-component -	if (v > FP_MAG_THRESHOLD) -	{ -		F32 oomag = 1.0f / v; -		F32 w = mQ[VW]; -		if (w < 0.0f) -		{ -			w = -w; // make VW positive -			oomag = -oomag; // invert the axis -		} -		*x = mQ[VX] * oomag; // normalize the axis -		*y = mQ[VY] * oomag; -		*z = mQ[VZ] * oomag; -		*angle = 2.0f * atan2f(v, w); // get the angle -	} -	else -	{ -		*angle = 0.0f; // no rotation -		*x = 0.0f; // around some dummy axis -		*y = 0.0f; -		*z = 1.0f; -	} +    F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]); // length of the vector-component +    if (v > FP_MAG_THRESHOLD) +    { +        F32 oomag = 1.0f / v; +        F32 w = mQ[VW]; +        if (w < 0.0f) +        { +            w = -w; // make VW positive +            oomag = -oomag; // invert the axis +        } +        *x = mQ[VX] * oomag; // normalize the axis +        *y = mQ[VY] * oomag; +        *z = mQ[VZ] * oomag; +        *angle = 2.0f * atan2f(v, w); // get the angle +    } +    else +    { +        *angle = 0.0f; // no rotation +        *x = 0.0f; // around some dummy axis +        *y = 0.0f; +        *z = 1.0f; +    }  }  inline const LLQuaternion& LLQuaternion::conjugate()  { -	mQ[VX] *= -1.f; -	mQ[VY] *= -1.f; -	mQ[VZ] *= -1.f; -	return (*this); +    mQ[VX] *= -1.f; +    mQ[VY] *= -1.f; +    mQ[VZ] *= -1.f; +    return (*this);  }  inline const LLQuaternion& LLQuaternion::conjQuat()  { -	mQ[VX] *= -1.f; -	mQ[VY] *= -1.f; -	mQ[VZ] *= -1.f; -	return (*this); +    mQ[VX] *= -1.f; +    mQ[VY] *= -1.f; +    mQ[VZ] *= -1.f; +    return (*this);  }  // Transpose  inline const LLQuaternion& LLQuaternion::transpose()  { -	mQ[VX] *= -1.f; -	mQ[VY] *= -1.f; -	mQ[VZ] *= -1.f; -	return (*this); +    mQ[VX] *= -1.f; +    mQ[VY] *= -1.f; +    mQ[VZ] *= -1.f; +    return (*this);  }  // deprecated  inline const LLQuaternion& LLQuaternion::transQuat()  { -	mQ[VX] *= -1.f; -	mQ[VY] *= -1.f; -	mQ[VZ] *= -1.f; -	return (*this); +    mQ[VX] *= -1.f; +    mQ[VY] *= -1.f; +    mQ[VZ] *= -1.f; +    return (*this);  } -inline LLQuaternion 	operator+(const LLQuaternion &a, const LLQuaternion &b) +inline LLQuaternion     operator+(const LLQuaternion &a, const LLQuaternion &b)  { -	return LLQuaternion(  -		a.mQ[VX] + b.mQ[VX], -		a.mQ[VY] + b.mQ[VY], -		a.mQ[VZ] + b.mQ[VZ], -		a.mQ[VW] + b.mQ[VW] ); +    return LLQuaternion( +        a.mQ[VX] + b.mQ[VX], +        a.mQ[VY] + b.mQ[VY], +        a.mQ[VZ] + b.mQ[VZ], +        a.mQ[VW] + b.mQ[VW] );  } -inline LLQuaternion 	operator-(const LLQuaternion &a, const LLQuaternion &b) +inline LLQuaternion     operator-(const LLQuaternion &a, const LLQuaternion &b)  { -	return LLQuaternion(  -		a.mQ[VX] - b.mQ[VX], -		a.mQ[VY] - b.mQ[VY], -		a.mQ[VZ] - b.mQ[VZ], -		a.mQ[VW] - b.mQ[VW] ); +    return LLQuaternion( +        a.mQ[VX] - b.mQ[VX], +        a.mQ[VY] - b.mQ[VY], +        a.mQ[VZ] - b.mQ[VZ], +        a.mQ[VW] - b.mQ[VW] );  } -inline LLQuaternion 	operator-(const LLQuaternion &a) +inline LLQuaternion     operator-(const LLQuaternion &a)  { -	return LLQuaternion( -		-a.mQ[VX], -		-a.mQ[VY], -		-a.mQ[VZ], -		-a.mQ[VW] ); +    return LLQuaternion( +        -a.mQ[VX], +        -a.mQ[VY], +        -a.mQ[VZ], +        -a.mQ[VW] );  } -inline LLQuaternion 	operator*(F32 a, const LLQuaternion &q) +inline LLQuaternion     operator*(F32 a, const LLQuaternion &q)  { -	return LLQuaternion( -		a * q.mQ[VX], -		a * q.mQ[VY], -		a * q.mQ[VZ], -		a * q.mQ[VW] ); +    return LLQuaternion( +        a * q.mQ[VX], +        a * q.mQ[VY], +        a * q.mQ[VZ], +        a * q.mQ[VW] );  } -inline LLQuaternion 	operator*(const LLQuaternion &q, F32 a) +inline LLQuaternion     operator*(const LLQuaternion &q, F32 a)  { -	return LLQuaternion( -		a * q.mQ[VX], -		a * q.mQ[VY], -		a * q.mQ[VZ], -		a * q.mQ[VW] ); +    return LLQuaternion( +        a * q.mQ[VX], +        a * q.mQ[VY], +        a * q.mQ[VZ], +        a * q.mQ[VW] );  } -inline LLQuaternion	operator~(const LLQuaternion &a) +inline LLQuaternion operator~(const LLQuaternion &a)  { -	LLQuaternion q(a); -	q.conjQuat(); -	return q; +    LLQuaternion q(a); +    q.conjQuat(); +    return q;  } -inline bool	LLQuaternion::operator==(const LLQuaternion &b) const +inline bool LLQuaternion::operator==(const LLQuaternion &b) const  { -	return (  (mQ[VX] == b.mQ[VX]) -			&&(mQ[VY] == b.mQ[VY]) -			&&(mQ[VZ] == b.mQ[VZ]) -			&&(mQ[VS] == b.mQ[VS])); +    return (  (mQ[VX] == b.mQ[VX]) +            &&(mQ[VY] == b.mQ[VY]) +            &&(mQ[VZ] == b.mQ[VZ]) +            &&(mQ[VS] == b.mQ[VS]));  } -inline bool	LLQuaternion::operator!=(const LLQuaternion &b) const +inline bool LLQuaternion::operator!=(const LLQuaternion &b) const  { -	return (  (mQ[VX] != b.mQ[VX]) -			||(mQ[VY] != b.mQ[VY]) -			||(mQ[VZ] != b.mQ[VZ]) -			||(mQ[VS] != b.mQ[VS])); +    return (  (mQ[VX] != b.mQ[VX]) +            ||(mQ[VY] != b.mQ[VY]) +            ||(mQ[VZ] != b.mQ[VZ]) +            ||(mQ[VS] != b.mQ[VS]));  } -inline const LLQuaternion&	operator*=(LLQuaternion &a, const LLQuaternion &b) +inline const LLQuaternion&  operator*=(LLQuaternion &a, const LLQuaternion &b)  {  #if 1 -	LLQuaternion q( -		b.mQ[3] * a.mQ[0] + b.mQ[0] * a.mQ[3] + b.mQ[1] * a.mQ[2] - b.mQ[2] * a.mQ[1], -		b.mQ[3] * a.mQ[1] + b.mQ[1] * a.mQ[3] + b.mQ[2] * a.mQ[0] - b.mQ[0] * a.mQ[2], -		b.mQ[3] * a.mQ[2] + b.mQ[2] * a.mQ[3] + b.mQ[0] * a.mQ[1] - b.mQ[1] * a.mQ[0], -		b.mQ[3] * a.mQ[3] - b.mQ[0] * a.mQ[0] - b.mQ[1] * a.mQ[1] - b.mQ[2] * a.mQ[2] -	); -	a = q; +    LLQuaternion q( +        b.mQ[3] * a.mQ[0] + b.mQ[0] * a.mQ[3] + b.mQ[1] * a.mQ[2] - b.mQ[2] * a.mQ[1], +        b.mQ[3] * a.mQ[1] + b.mQ[1] * a.mQ[3] + b.mQ[2] * a.mQ[0] - b.mQ[0] * a.mQ[2], +        b.mQ[3] * a.mQ[2] + b.mQ[2] * a.mQ[3] + b.mQ[0] * a.mQ[1] - b.mQ[1] * a.mQ[0], +        b.mQ[3] * a.mQ[3] - b.mQ[0] * a.mQ[0] - b.mQ[1] * a.mQ[1] - b.mQ[2] * a.mQ[2] +    ); +    a = q;  #else -	a = a * b; +    a = a * b;  #endif -	return a; +    return a;  }  const F32 ONE_PART_IN_A_MILLION = 0.000001f; -inline F32	LLQuaternion::normalize() -{ -	F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); - -	if (mag > FP_MAG_THRESHOLD) -	{ -		// Floating point error can prevent some quaternions from achieving -		// exact unity length.  When trying to renormalize such quaternions we -		// can oscillate between multiple quantized states.  To prevent such -		// drifts we only renomalize if the length is far enough from unity. -		if (fabs(1.f - mag) > ONE_PART_IN_A_MILLION) -		{ -			F32 oomag = 1.f/mag; -			mQ[VX] *= oomag; -			mQ[VY] *= oomag; -			mQ[VZ] *= oomag; -			mQ[VS] *= oomag; -		} -	} -	else -	{ -		// we were given a very bad quaternion so we set it to identity -		mQ[VX] = 0.f; -		mQ[VY] = 0.f; -		mQ[VZ] = 0.f; -		mQ[VS] = 1.f; -	} - -	return mag; +inline F32  LLQuaternion::normalize() +{ +    F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); + +    if (mag > FP_MAG_THRESHOLD) +    { +        // Floating point error can prevent some quaternions from achieving +        // exact unity length.  When trying to renormalize such quaternions we +        // can oscillate between multiple quantized states.  To prevent such +        // drifts we only renomalize if the length is far enough from unity. +        if (fabs(1.f - mag) > ONE_PART_IN_A_MILLION) +        { +            F32 oomag = 1.f/mag; +            mQ[VX] *= oomag; +            mQ[VY] *= oomag; +            mQ[VZ] *= oomag; +            mQ[VS] *= oomag; +        } +    } +    else +    { +        // we were given a very bad quaternion so we set it to identity +        mQ[VX] = 0.f; +        mQ[VY] = 0.f; +        mQ[VZ] = 0.f; +        mQ[VS] = 1.f; +    } + +    return mag;  }  // deprecated -inline F32	LLQuaternion::normQuat() -{ -	F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); - -	if (mag > FP_MAG_THRESHOLD) -	{ -		if (fabs(1.f - mag) > ONE_PART_IN_A_MILLION) -		{ -			// only renormalize if length not close enough to 1.0 already -			F32 oomag = 1.f/mag; -			mQ[VX] *= oomag; -			mQ[VY] *= oomag; -			mQ[VZ] *= oomag; -			mQ[VS] *= oomag; -		} -	} -	else -	{ -		mQ[VX] = 0.f; -		mQ[VY] = 0.f; -		mQ[VZ] = 0.f; -		mQ[VS] = 1.f; -	} - -	return mag; +inline F32  LLQuaternion::normQuat() +{ +    F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]); + +    if (mag > FP_MAG_THRESHOLD) +    { +        if (fabs(1.f - mag) > ONE_PART_IN_A_MILLION) +        { +            // only renormalize if length not close enough to 1.0 already +            F32 oomag = 1.f/mag; +            mQ[VX] *= oomag; +            mQ[VY] *= oomag; +            mQ[VZ] *= oomag; +            mQ[VS] *= oomag; +        } +    } +    else +    { +        mQ[VX] = 0.f; +        mQ[VY] = 0.f; +        mQ[VZ] = 0.f; +        mQ[VS] = 1.f; +    } + +    return mag;  }  LLQuaternion::Order StringToOrder( const char *str ); @@ -565,11 +565,11 @@ LLQuaternion::Order StringToOrder( const char *str );  // ---------------------  // A quaternion is a point in 4-dimensional complex space.  // Q = { Qx, Qy, Qz, Qw } -//  +//  //  // Why Quaternions?  // ---------------- -// The set of quaternions that make up the the 4-D unit sphere  +// The set of quaternions that make up the the 4-D unit sphere  // can be mapped to the set of all rotations in 3-D space.  Sometimes  // it is easier to describe/manipulate rotations in quaternion space  // than rotation-matrix space. @@ -580,22 +580,22 @@ LLQuaternion::Order StringToOrder( const char *str );  // In order to take advantage of quaternions we need to know how to  // go from rotation-matricies to quaternions and back.  We also have  // to agree what variety of rotations we're generating. -//  -// Consider the equation...   v' = v * R  +// +// Consider the equation...   v' = v * R  //  // There are two ways to think about rotations of vectors.  // 1) v' is the same vector in a different reference frame  // 2) v' is a new vector in the same reference frame  //  // bookmark -- which way are we using? -//  -//  +// +//  // Quaternion from Angle-Axis:  // --------------------------- -// Suppose we wanted to represent a rotation of some angle (theta)  +// Suppose we wanted to represent a rotation of some angle (theta)  // about some axis ({Ax, Ay, Az})...  // -// axis of rotation = {Ax, Ay, Az}  +// axis of rotation = {Ax, Ay, Az}  // angle_of_rotation = theta  //  // s = sin(0.5 * theta) diff --git a/indra/llmath/llquaternion2.h b/indra/llmath/llquaternion2.h index fd9c0cf3ab..902bfb7134 100644 --- a/indra/llmath/llquaternion2.h +++ b/indra/llmath/llquaternion2.h @@ -1,31 +1,31 @@ -/**  +/**   * @file llquaternion2.h   * @brief LLQuaternion2 class header file - SIMD-enabled quaternion class   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -#ifndef	LL_QUATERNION2_H -#define	LL_QUATERNION2_H +#ifndef LL_QUATERNION2_H +#define LL_QUATERNION2_H  /////////////////////////////  // LLQuaternion2 @@ -44,61 +44,61 @@ class LLQuaternion2  {  public: -	////////////////////////// -	// Ctors -	////////////////////////// -	 -	// Ctor -	LLQuaternion2() {} +    ////////////////////////// +    // Ctors +    ////////////////////////// + +    // Ctor +    LLQuaternion2() {} + +    // Ctor from LLQuaternion +    explicit LLQuaternion2( const class LLQuaternion& quat ); -	// Ctor from LLQuaternion -	explicit LLQuaternion2( const class LLQuaternion& quat ); +    ////////////////////////// +    // Get/Set +    ////////////////////////// -	////////////////////////// -	// Get/Set -	////////////////////////// +    // Load from an LLQuaternion +    inline void operator=( const LLQuaternion& quat ) +    { +        mQ.loadua( quat.mQ ); +    } -	// Load from an LLQuaternion -	inline void operator=( const LLQuaternion& quat ) -	{ -		mQ.loadua( quat.mQ ); -	} +    // Return the internal LLVector4a representation of the quaternion +    inline const LLVector4a& getVector4a() const; +    inline LLVector4a& getVector4aRw(); -	// Return the internal LLVector4a representation of the quaternion -	inline const LLVector4a& getVector4a() const; -	inline LLVector4a& getVector4aRw(); +    ///////////////////////// +    // Quaternion modification +    ///////////////////////// -	///////////////////////// -	// Quaternion modification -	///////////////////////// -	 -	// Set this quaternion to the conjugate of src -	inline void setConjugate(const LLQuaternion2& src); +    // Set this quaternion to the conjugate of src +    inline void setConjugate(const LLQuaternion2& src); -	// Renormalizes the quaternion. Assumes it has nonzero length. -	inline void normalize(); +    // Renormalizes the quaternion. Assumes it has nonzero length. +    inline void normalize(); -	// Quantize this quaternion to 8 bit precision -	inline void quantize8(); +    // Quantize this quaternion to 8 bit precision +    inline void quantize8(); -	// Quantize this quaternion to 16 bit precision -	inline void quantize16(); +    // Quantize this quaternion to 16 bit precision +    inline void quantize16(); -	///////////////////////// -	// Quaternion inspection -	///////////////////////// +    ///////////////////////// +    // Quaternion inspection +    ///////////////////////// -	// Return true if this quaternion is equal to 'rhs'.  -	// Note! Quaternions exhibit "double-cover", so any rotation has two equally valid -	// quaternion representations and they will NOT compare equal. -	inline bool equals(const LLQuaternion2& rhs, F32 tolerance = F_APPROXIMATELY_ZERO ) const; +    // Return true if this quaternion is equal to 'rhs'. +    // Note! Quaternions exhibit "double-cover", so any rotation has two equally valid +    // quaternion representations and they will NOT compare equal. +    inline bool equals(const LLQuaternion2& rhs, F32 tolerance = F_APPROXIMATELY_ZERO ) const; -	// Return true if all components are finite and the quaternion is normalized -	inline bool isOkRotation() const; +    // Return true if all components are finite and the quaternion is normalized +    inline bool isOkRotation() const;  protected: -	LLVector4a mQ; +    LLVector4a mQ;  }; diff --git a/indra/llmath/llquaternion2.inl b/indra/llmath/llquaternion2.inl index 2a6987552d..ce5ed73926 100644 --- a/indra/llmath/llquaternion2.inl +++ b/indra/llmath/llquaternion2.inl @@ -1,25 +1,25 @@ -/**  +/**   * @file llquaternion2.inl   * @brief LLQuaternion2 inline definitions   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -32,7 +32,7 @@ static const LLQuad LL_V4A_MINUS_ONE = {-1.f, -1.f, -1.f, -1.f};  // Ctor from LLQuaternion  inline LLQuaternion2::LLQuaternion2( const LLQuaternion& quat )  { -	mQ.set(quat.mQ[VX], quat.mQ[VY], quat.mQ[VZ], quat.mQ[VW]); +    mQ.set(quat.mQ[VX], quat.mQ[VY], quat.mQ[VZ], quat.mQ[VW]);  }  ////////////////////////// @@ -42,12 +42,12 @@ inline LLQuaternion2::LLQuaternion2( const LLQuaternion& quat )  // Return the internal LLVector4a representation of the quaternion  inline const LLVector4a& LLQuaternion2::getVector4a() const  { -	return mQ; +    return mQ;  }  inline LLVector4a& LLQuaternion2::getVector4aRw()  { -	return mQ; +    return mQ;  }  ///////////////////////// @@ -57,28 +57,28 @@ inline LLVector4a& LLQuaternion2::getVector4aRw()  // Set this quaternion to the conjugate of src  inline void LLQuaternion2::setConjugate(const LLQuaternion2& src)  { -	static LL_ALIGN_16( const U32 F_QUAT_INV_MASK_4A[4] ) = { 0x80000000, 0x80000000, 0x80000000, 0x00000000 }; -	mQ = _mm_xor_ps(src.mQ, *reinterpret_cast<const LLQuad*>(&F_QUAT_INV_MASK_4A));	 +    static LL_ALIGN_16( const U32 F_QUAT_INV_MASK_4A[4] ) = { 0x80000000, 0x80000000, 0x80000000, 0x00000000 }; +    mQ = _mm_xor_ps(src.mQ, *reinterpret_cast<const LLQuad*>(&F_QUAT_INV_MASK_4A));  }  // Renormalizes the quaternion. Assumes it has nonzero length.  inline void LLQuaternion2::normalize()  { -	mQ.normalize4(); +    mQ.normalize4();  }  // Quantize this quaternion to 8 bit precision  inline void LLQuaternion2::quantize8()  { -	mQ.quantize8( LL_V4A_MINUS_ONE, LL_V4A_PLUS_ONE ); -	normalize(); +    mQ.quantize8( LL_V4A_MINUS_ONE, LL_V4A_PLUS_ONE ); +    normalize();  }  // Quantize this quaternion to 16 bit precision  inline void LLQuaternion2::quantize16()  { -	mQ.quantize16( LL_V4A_MINUS_ONE, LL_V4A_PLUS_ONE ); -	normalize(); +    mQ.quantize16( LL_V4A_MINUS_ONE, LL_V4A_PLUS_ONE ); +    normalize();  } @@ -86,17 +86,17 @@ inline void LLQuaternion2::quantize16()  // Quaternion inspection  ///////////////////////// -// Return true if this quaternion is equal to 'rhs'.  +// Return true if this quaternion is equal to 'rhs'.  // Note! Quaternions exhibit "double-cover", so any rotation has two equally valid  // quaternion representations and they will NOT compare equal.  inline bool LLQuaternion2::equals(const LLQuaternion2 &rhs, F32 tolerance/* = F_APPROXIMATELY_ZERO*/) const  { -	return mQ.equals4(rhs.mQ, tolerance); +    return mQ.equals4(rhs.mQ, tolerance);  }  // Return true if all components are finite and the quaternion is normalized  inline bool LLQuaternion2::isOkRotation() const  { -	return mQ.isFinite4() && mQ.isNormalized4(); +    return mQ.isFinite4() && mQ.isNormalized4();  } diff --git a/indra/llmath/llrect.cpp b/indra/llmath/llrect.cpp index 4083c99768..2a40dc69dd 100644 --- a/indra/llmath/llrect.cpp +++ b/indra/llmath/llrect.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file llrect.cpp   * @brief LLRect class implementation   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h index 58f02d4d2b..6c872611ba 100644 --- a/indra/llmath/llrect.h +++ b/indra/llmath/llrect.h @@ -1,25 +1,25 @@ -/**  +/**   * @file llrect.h   * @brief A rectangle in GL coordinates, with bottom,left = 0,0   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -36,258 +36,258 @@  template <class Type> class LLRectBase  {  public: -	typedef	Type tCoordType; -	Type		mLeft; -	Type		mTop; -	Type		mRight; -	Type		mBottom; - -	// Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect -	Type		getWidth()	const { return mRight - mLeft; } -	Type		getHeight()	const { return mTop - mBottom; } -	Type		getCenterX() const { return (mLeft + mRight) / 2; } -	Type		getCenterY() const { return (mTop + mBottom) / 2; } - -	LLRectBase():	mLeft(0), mTop(0), mRight(0), mBottom(0) -	{} - -	LLRectBase(const LLRectBase &r): -	mLeft(r.mLeft), mTop(r.mTop), mRight(r.mRight), mBottom(r.mBottom) -	{} - -	LLRectBase(Type left, Type top, Type right, Type bottom): -	mLeft(left), mTop(top), mRight(right), mBottom(bottom) -	{} - -	explicit LLRectBase(const LLSD& sd) -	{ -		setValue(sd); -	} - -	void setValue(const LLSD& sd) -	{ -		mLeft = (Type)sd[0].asInteger();  -		mTop = (Type)sd[1].asInteger(); -		mRight = (Type)sd[2].asInteger(); -		mBottom = (Type)sd[3].asInteger(); -	} - -	LLSD getValue() const -	{ -		LLSD ret; -		ret[0] = mLeft; -		ret[1] = mTop; -		ret[2] = mRight; -		ret[3] = mBottom; -		return ret; -	} - -	// Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect -	BOOL		pointInRect(const Type x, const Type y) const -	{ -		return  mLeft <= x && x < mRight && -				mBottom <= y && y < mTop; -	} - -	//// Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect -	BOOL		localPointInRect(const Type x, const Type y) const -	{ -		return  0 <= x && x < getWidth() && -				0 <= y && y < getHeight(); -	} - -	void		clampPointToRect(Type& x, Type& y) -	{ -		x = llclamp(x, mLeft, mRight); -		y = llclamp(y, mBottom, mTop); -	} - -	void		clipPointToRect(const Type start_x, const Type start_y, Type& end_x, Type& end_y) -	{ -		if (!pointInRect(start_x, start_y)) -		{ -			return; -		} -		Type clip_x = 0; -		Type clip_y = 0; -		Type delta_x = end_x - start_x; -		Type delta_y = end_y - start_y; -		if (end_x > mRight) clip_x = end_x - mRight; -		if (end_x < mLeft) clip_x = end_x - mLeft; -		if (end_y > mTop) clip_y = end_y - mTop; -		if (end_y < mBottom) clip_y = end_y - mBottom; -		// clip_? and delta_? should have same sign, since starting point is in rect -		// so ratios will be positive +    typedef Type tCoordType; +    Type        mLeft; +    Type        mTop; +    Type        mRight; +    Type        mBottom; + +    // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect +    Type        getWidth()  const { return mRight - mLeft; } +    Type        getHeight() const { return mTop - mBottom; } +    Type        getCenterX() const { return (mLeft + mRight) / 2; } +    Type        getCenterY() const { return (mTop + mBottom) / 2; } + +    LLRectBase():   mLeft(0), mTop(0), mRight(0), mBottom(0) +    {} + +    LLRectBase(const LLRectBase &r): +    mLeft(r.mLeft), mTop(r.mTop), mRight(r.mRight), mBottom(r.mBottom) +    {} + +    LLRectBase(Type left, Type top, Type right, Type bottom): +    mLeft(left), mTop(top), mRight(right), mBottom(bottom) +    {} + +    explicit LLRectBase(const LLSD& sd) +    { +        setValue(sd); +    } + +    void setValue(const LLSD& sd) +    { +        mLeft = (Type)sd[0].asInteger(); +        mTop = (Type)sd[1].asInteger(); +        mRight = (Type)sd[2].asInteger(); +        mBottom = (Type)sd[3].asInteger(); +    } + +    LLSD getValue() const +    { +        LLSD ret; +        ret[0] = mLeft; +        ret[1] = mTop; +        ret[2] = mRight; +        ret[3] = mBottom; +        return ret; +    } + +    // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect +    BOOL        pointInRect(const Type x, const Type y) const +    { +        return  mLeft <= x && x < mRight && +                mBottom <= y && y < mTop; +    } + +    //// Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect +    BOOL        localPointInRect(const Type x, const Type y) const +    { +        return  0 <= x && x < getWidth() && +                0 <= y && y < getHeight(); +    } + +    void        clampPointToRect(Type& x, Type& y) +    { +        x = llclamp(x, mLeft, mRight); +        y = llclamp(y, mBottom, mTop); +    } + +    void        clipPointToRect(const Type start_x, const Type start_y, Type& end_x, Type& end_y) +    { +        if (!pointInRect(start_x, start_y)) +        { +            return; +        } +        Type clip_x = 0; +        Type clip_y = 0; +        Type delta_x = end_x - start_x; +        Type delta_y = end_y - start_y; +        if (end_x > mRight) clip_x = end_x - mRight; +        if (end_x < mLeft) clip_x = end_x - mLeft; +        if (end_y > mTop) clip_y = end_y - mTop; +        if (end_y < mBottom) clip_y = end_y - mBottom; +        // clip_? and delta_? should have same sign, since starting point is in rect +        // so ratios will be positive          F32 ratio_x = 0;          F32 ratio_y = 0;          if (delta_x != 0) ratio_x = ((F32)clip_x / (F32)delta_x);          if (delta_y != 0) ratio_y = ((F32)clip_y / (F32)delta_y); -		if (ratio_x > ratio_y) -		{ -			// clip along x direction -			end_x -= (Type)(clip_x); -			end_y -= (Type)(delta_y * ratio_x); -		} -		else -		{ -			// clip along y direction -			end_x -= (Type)(delta_x * ratio_y); -			end_y -= (Type)clip_y; -		} -	} - -	// Note: Does NOT follow GL_QUAD conventions: the top and right edges ARE considered part of the rect -	// returns TRUE if any part of rect is is inside this LLRect -	BOOL		overlaps(const LLRectBase& rect) const -	{ -		return !(mLeft > rect.mRight  -			|| mRight < rect.mLeft -			|| mBottom > rect.mTop  -			|| mTop < rect.mBottom); -	} - -	BOOL		contains(const LLRectBase& rect) const -	{ -		return mLeft <= rect.mLeft -			&& mRight >= rect.mRight -			&& mBottom <= rect.mBottom -			&& mTop >= rect.mTop; -	} - -	LLRectBase& set(Type left, Type top, Type right, Type bottom) -	{ -		mLeft = left; -		mTop = top; -		mRight = right; -		mBottom = bottom; -		return *this; -	} - -	// Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect -	LLRectBase& setOriginAndSize( Type left, Type bottom, Type width, Type height) -	{ -		mLeft = left; -		mTop = bottom + height; -		mRight = left + width; -		mBottom = bottom; -		return *this; -	} - -	// Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect -	LLRectBase& setLeftTopAndSize( Type left, Type top, Type width, Type height) -	{ -		mLeft = left; -		mTop = top; -		mRight = left + width; -		mBottom = top - height; -		return *this; -	} - -	LLRectBase& setCenterAndSize(Type x, Type y, Type width, Type height) -	{ -		// width and height could be odd, so favor top, right with extra pixel -		mLeft = x - width/2; -		mBottom = y - height/2; -		mTop = mBottom + height; -		mRight = mLeft + width; -		return *this; -	} - - -	LLRectBase& translate(Type horiz, Type vertical) -	{ -		mLeft += horiz; -		mRight += horiz; -		mTop += vertical; -		mBottom += vertical; -		return *this; -	} - -	LLRectBase& stretch( Type dx, Type dy) -	{ -		mLeft -= dx; -		mRight += dx; -		mTop += dy; -		mBottom -= dy; -		return makeValid(); -	} -	 -	LLRectBase& stretch( Type delta ) -	{ -		stretch(delta, delta); -		return *this; -	} -	 -	LLRectBase& makeValid() -	{ -		mLeft = llmin(mLeft, mRight); -		mBottom = llmin(mBottom, mTop); -		return *this; -	} - -	bool isValid() const -	{ -		return mLeft <= mRight && mBottom <= mTop; -	} - -	bool isEmpty() const -	{ -		return mLeft == mRight || mBottom == mTop; -	} - -	bool notEmpty() const -	{ -		return !isEmpty(); -	} - -	void unionWith(const LLRectBase &other) -	{ -		mLeft = llmin(mLeft, other.mLeft); -		mRight = llmax(mRight, other.mRight); -		mBottom = llmin(mBottom, other.mBottom); -		mTop = llmax(mTop, other.mTop); -	} - -	void intersectWith(const LLRectBase &other) -	{ -		mLeft = llmax(mLeft, other.mLeft); -		mRight = llmin(mRight, other.mRight); -		mBottom = llmax(mBottom, other.mBottom); -		mTop = llmin(mTop, other.mTop); -		if (mLeft > mRight) -		{ -			mLeft = mRight; -		} -		if (mBottom > mTop) -		{ -			mBottom = mTop; -		} -	} - -	friend std::ostream &operator<<(std::ostream &s, const LLRectBase &rect) -	{ -		s << "{ L " << rect.mLeft << " B " << rect.mBottom -			<< " W " << rect.getWidth() << " H " << rect.getHeight() << " }"; -		return s; -	} -	 -	bool operator==(const LLRectBase &b) const -	{ -		return ((mLeft == b.mLeft) && -				(mTop == b.mTop) && -				(mRight == b.mRight) && -				(mBottom == b.mBottom)); -	} - -	bool operator!=(const LLRectBase &b) const -	{ -		return ((mLeft != b.mLeft) || -				(mTop != b.mTop) || -				(mRight != b.mRight) || -				(mBottom != b.mBottom)); -	} - -	static LLRectBase<Type> null; +        if (ratio_x > ratio_y) +        { +            // clip along x direction +            end_x -= (Type)(clip_x); +            end_y -= (Type)(delta_y * ratio_x); +        } +        else +        { +            // clip along y direction +            end_x -= (Type)(delta_x * ratio_y); +            end_y -= (Type)clip_y; +        } +    } + +    // Note: Does NOT follow GL_QUAD conventions: the top and right edges ARE considered part of the rect +    // returns TRUE if any part of rect is is inside this LLRect +    BOOL        overlaps(const LLRectBase& rect) const +    { +        return !(mLeft > rect.mRight +            || mRight < rect.mLeft +            || mBottom > rect.mTop +            || mTop < rect.mBottom); +    } + +    BOOL        contains(const LLRectBase& rect) const +    { +        return mLeft <= rect.mLeft +            && mRight >= rect.mRight +            && mBottom <= rect.mBottom +            && mTop >= rect.mTop; +    } + +    LLRectBase& set(Type left, Type top, Type right, Type bottom) +    { +        mLeft = left; +        mTop = top; +        mRight = right; +        mBottom = bottom; +        return *this; +    } + +    // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect +    LLRectBase& setOriginAndSize( Type left, Type bottom, Type width, Type height) +    { +        mLeft = left; +        mTop = bottom + height; +        mRight = left + width; +        mBottom = bottom; +        return *this; +    } + +    // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect +    LLRectBase& setLeftTopAndSize( Type left, Type top, Type width, Type height) +    { +        mLeft = left; +        mTop = top; +        mRight = left + width; +        mBottom = top - height; +        return *this; +    } + +    LLRectBase& setCenterAndSize(Type x, Type y, Type width, Type height) +    { +        // width and height could be odd, so favor top, right with extra pixel +        mLeft = x - width/2; +        mBottom = y - height/2; +        mTop = mBottom + height; +        mRight = mLeft + width; +        return *this; +    } + + +    LLRectBase& translate(Type horiz, Type vertical) +    { +        mLeft += horiz; +        mRight += horiz; +        mTop += vertical; +        mBottom += vertical; +        return *this; +    } + +    LLRectBase& stretch( Type dx, Type dy) +    { +        mLeft -= dx; +        mRight += dx; +        mTop += dy; +        mBottom -= dy; +        return makeValid(); +    } + +    LLRectBase& stretch( Type delta ) +    { +        stretch(delta, delta); +        return *this; +    } + +    LLRectBase& makeValid() +    { +        mLeft = llmin(mLeft, mRight); +        mBottom = llmin(mBottom, mTop); +        return *this; +    } + +    bool isValid() const +    { +        return mLeft <= mRight && mBottom <= mTop; +    } + +    bool isEmpty() const +    { +        return mLeft == mRight || mBottom == mTop; +    } + +    bool notEmpty() const +    { +        return !isEmpty(); +    } + +    void unionWith(const LLRectBase &other) +    { +        mLeft = llmin(mLeft, other.mLeft); +        mRight = llmax(mRight, other.mRight); +        mBottom = llmin(mBottom, other.mBottom); +        mTop = llmax(mTop, other.mTop); +    } + +    void intersectWith(const LLRectBase &other) +    { +        mLeft = llmax(mLeft, other.mLeft); +        mRight = llmin(mRight, other.mRight); +        mBottom = llmax(mBottom, other.mBottom); +        mTop = llmin(mTop, other.mTop); +        if (mLeft > mRight) +        { +            mLeft = mRight; +        } +        if (mBottom > mTop) +        { +            mBottom = mTop; +        } +    } + +    friend std::ostream &operator<<(std::ostream &s, const LLRectBase &rect) +    { +        s << "{ L " << rect.mLeft << " B " << rect.mBottom +            << " W " << rect.getWidth() << " H " << rect.getHeight() << " }"; +        return s; +    } + +    bool operator==(const LLRectBase &b) const +    { +        return ((mLeft == b.mLeft) && +                (mTop == b.mTop) && +                (mRight == b.mRight) && +                (mBottom == b.mBottom)); +    } + +    bool operator!=(const LLRectBase &b) const +    { +        return ((mLeft != b.mLeft) || +                (mTop != b.mTop) || +                (mRight != b.mRight) || +                (mBottom != b.mBottom)); +    } + +    static LLRectBase<Type> null;  };  template <class Type> LLRectBase<Type> LLRectBase<Type>::null(0,0,0,0); diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp index 0de07950c1..23dbddd78e 100644 --- a/indra/llmath/llrigginginfo.cpp +++ b/indra/llmath/llrigginginfo.cpp @@ -46,7 +46,7 @@ void LLJointRiggingInfo::setIsRiggedTo(bool val)  {      mIsRiggedTo = val;  } -     +  LLVector4a *LLJointRiggingInfo::getRiggedExtents()  {      return mRiggedExtents; @@ -120,8 +120,8 @@ void LLJointRiggingInfoTab::clear()  void showDetails(const LLJointRiggingInfoTab& src, const std::string& str)  { -	S32 count_rigged = 0; -	S32 count_box = 0; +    S32 count_rigged = 0; +    S32 count_box = 0;      LLVector4a zero_vec;      zero_vec.clear();      for (S32 i=0; i<src.size(); i++) diff --git a/indra/llmath/llrigginginfo.h b/indra/llmath/llrigginginfo.h index 059c6ae082..fb550d013f 100644 --- a/indra/llmath/llrigginginfo.h +++ b/indra/llmath/llrigginginfo.h @@ -27,8 +27,8 @@  // Stores information related to associated rigged mesh vertices  // This lives in llmath because llvolume lives in llmath. -#ifndef	LL_LLRIGGINGINFO_H -#define	LL_LLRIGGINGINFO_H +#ifndef LL_LLRIGGINGINFO_H +#define LL_LLRIGGINGINFO_H  #include "llvector4a.h" @@ -46,7 +46,7 @@ public:      void merge(const LLJointRiggingInfo& other);  private: -	LLVector4a mRiggedExtents[2]; +    LLVector4a mRiggedExtents[2];      bool mIsRiggedTo;  }; diff --git a/indra/llmath/llsdutil_math.cpp b/indra/llmath/llsdutil_math.cpp index 51e5e3764f..0ea1a9c77a 100644 --- a/indra/llmath/llsdutil_math.cpp +++ b/indra/llmath/llsdutil_math.cpp @@ -1,4 +1,4 @@ -/**  +/**   * @file llsdutil_math.cpp   * @author Phoenix   * @date 2006-05-24 @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2006&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -38,12 +38,12 @@  #include "v4color.h"  #if LL_WINDOWS -#	define WIN32_LEAN_AND_MEAN -#	include <winsock2.h>	// for htonl +#   define WIN32_LEAN_AND_MEAN +#   include <winsock2.h>    // for htonl  #elif LL_LINUX -#	include <netinet/in.h> +#   include <netinet/in.h>  #elif LL_DARWIN -#	include <arpa/inet.h> +#   include <arpa/inet.h>  #endif  #include "llsdserialize.h" @@ -51,114 +51,114 @@  // vector3  LLSD ll_sd_from_vector3(const LLVector3& vec)  { -	LLSD rv; -	rv.append((F64)vec.mV[VX]); -	rv.append((F64)vec.mV[VY]); -	rv.append((F64)vec.mV[VZ]); -	return rv; +    LLSD rv; +    rv.append((F64)vec.mV[VX]); +    rv.append((F64)vec.mV[VY]); +    rv.append((F64)vec.mV[VZ]); +    return rv;  }  LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index)  { -	LLVector3 rv; -	rv.mV[VX] = (F32)sd[start_index].asReal(); -	rv.mV[VY] = (F32)sd[++start_index].asReal(); -	rv.mV[VZ] = (F32)sd[++start_index].asReal(); -	return rv; +    LLVector3 rv; +    rv.mV[VX] = (F32)sd[start_index].asReal(); +    rv.mV[VY] = (F32)sd[++start_index].asReal(); +    rv.mV[VZ] = (F32)sd[++start_index].asReal(); +    return rv;  }  // vector4  LLSD ll_sd_from_vector4(const LLVector4& vec)  { -	LLSD rv; -	rv.append((F64)vec.mV[VX]); -	rv.append((F64)vec.mV[VY]); -	rv.append((F64)vec.mV[VZ]); -	rv.append((F64)vec.mV[VW]); -	return rv; +    LLSD rv; +    rv.append((F64)vec.mV[VX]); +    rv.append((F64)vec.mV[VY]); +    rv.append((F64)vec.mV[VZ]); +    rv.append((F64)vec.mV[VW]); +    return rv;  }  LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index)  { -	LLVector4 rv; -	rv.mV[VX] = (F32)sd[start_index].asReal(); -	rv.mV[VY] = (F32)sd[++start_index].asReal(); -	rv.mV[VZ] = (F32)sd[++start_index].asReal(); -	rv.mV[VW] = (F32)sd[++start_index].asReal(); -	return rv; +    LLVector4 rv; +    rv.mV[VX] = (F32)sd[start_index].asReal(); +    rv.mV[VY] = (F32)sd[++start_index].asReal(); +    rv.mV[VZ] = (F32)sd[++start_index].asReal(); +    rv.mV[VW] = (F32)sd[++start_index].asReal(); +    return rv;  }  // vector3d  LLSD ll_sd_from_vector3d(const LLVector3d& vec)  { -	LLSD rv; -	rv.append(vec.mdV[VX]); -	rv.append(vec.mdV[VY]); -	rv.append(vec.mdV[VZ]); -	return rv; +    LLSD rv; +    rv.append(vec.mdV[VX]); +    rv.append(vec.mdV[VY]); +    rv.append(vec.mdV[VZ]); +    return rv;  }  LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index)  { -	LLVector3d rv; -	rv.mdV[VX] = sd[start_index].asReal(); -	rv.mdV[VY] = sd[++start_index].asReal(); -	rv.mdV[VZ] = sd[++start_index].asReal(); -	return rv; +    LLVector3d rv; +    rv.mdV[VX] = sd[start_index].asReal(); +    rv.mdV[VY] = sd[++start_index].asReal(); +    rv.mdV[VZ] = sd[++start_index].asReal(); +    return rv;  }  //vector2  LLSD ll_sd_from_vector2(const LLVector2& vec)  { -	LLSD rv; -	rv.append((F64)vec.mV[VX]); -	rv.append((F64)vec.mV[VY]); -	return rv; +    LLSD rv; +    rv.append((F64)vec.mV[VX]); +    rv.append((F64)vec.mV[VY]); +    return rv;  }  LLVector2 ll_vector2_from_sd(const LLSD& sd)  { -	LLVector2 rv; -	rv.mV[VX] = (F32)sd[0].asReal(); -	rv.mV[VY] = (F32)sd[1].asReal(); -	return rv; +    LLVector2 rv; +    rv.mV[VX] = (F32)sd[0].asReal(); +    rv.mV[VY] = (F32)sd[1].asReal(); +    return rv;  }  // Quaternion  LLSD ll_sd_from_quaternion(const LLQuaternion& quat)  { -	LLSD rv; -	rv.append((F64)quat.mQ[VX]); -	rv.append((F64)quat.mQ[VY]); -	rv.append((F64)quat.mQ[VZ]); -	rv.append((F64)quat.mQ[VW]); -	return rv; +    LLSD rv; +    rv.append((F64)quat.mQ[VX]); +    rv.append((F64)quat.mQ[VY]); +    rv.append((F64)quat.mQ[VZ]); +    rv.append((F64)quat.mQ[VW]); +    return rv;  }  LLQuaternion ll_quaternion_from_sd(const LLSD& sd)  { -	LLQuaternion quat; -	quat.mQ[VX] = (F32)sd[0].asReal(); -	quat.mQ[VY] = (F32)sd[1].asReal(); -	quat.mQ[VZ] = (F32)sd[2].asReal(); -	quat.mQ[VW] = (F32)sd[3].asReal(); -	return quat; +    LLQuaternion quat; +    quat.mQ[VX] = (F32)sd[0].asReal(); +    quat.mQ[VY] = (F32)sd[1].asReal(); +    quat.mQ[VZ] = (F32)sd[2].asReal(); +    quat.mQ[VW] = (F32)sd[3].asReal(); +    return quat;  }  // color4  LLSD ll_sd_from_color4(const LLColor4& c)  { -	LLSD rv; -	rv.append(c.mV[0]); -	rv.append(c.mV[1]); -	rv.append(c.mV[2]); -	rv.append(c.mV[3]); -	return rv; +    LLSD rv; +    rv.append(c.mV[0]); +    rv.append(c.mV[1]); +    rv.append(c.mV[2]); +    rv.append(c.mV[3]); +    return rv;  }  LLColor4 ll_color4_from_sd(const LLSD& sd)  { -	LLColor4 c; -	c.setValue(sd); -	return c; +    LLColor4 c; +    c.setValue(sd); +    return c;  } diff --git a/indra/llmath/llsdutil_math.h b/indra/llmath/llsdutil_math.h index 0ea78cd231..8f8852f7c3 100644 --- a/indra/llmath/llsdutil_math.h +++ b/indra/llmath/llsdutil_math.h @@ -1,4 +1,4 @@ -/**  +/**   * @file llsdutil_math.h   * @author Brad   * @date 2009-05-19 @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2009&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ diff --git a/indra/llmath/llsimdmath.h b/indra/llmath/llsimdmath.h index 54a275633f..40953dc2e8 100644 --- a/indra/llmath/llsimdmath.h +++ b/indra/llmath/llsimdmath.h @@ -1,31 +1,31 @@ -/**  +/**   * @file llsimdmath.h   * @brief Common header for SIMD-based math library (llvector4a, llmatrix3a, etc.)   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -#ifndef	LL_SIMD_MATH_H -#define	LL_SIMD_MATH_H +#ifndef LL_SIMD_MATH_H +#define LL_SIMD_MATH_H  #ifndef LLMATH_H  #error "Please include llmath.h before this file." diff --git a/indra/llmath/llsimdtypes.h b/indra/llmath/llsimdtypes.h index bd991d0e71..9db152adf8 100644 --- a/indra/llmath/llsimdtypes.h +++ b/indra/llmath/llsimdtypes.h @@ -1,25 +1,25 @@ -/**  +/**   * @file llsimdtypes.h   * @brief Declaration of basic SIMD math related types   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -31,7 +31,7 @@  #error "Please include llmath.h before this file."  #endif -typedef __m128	LLQuad; +typedef __m128  LLQuad;  #if LL_WINDOWS @@ -50,17 +50,17 @@ __forceinline const __m128i _mm_castps_si128( const __m128 a ) { return reinterp  class LLBool32  {  public: -	inline LLBool32() {} -	inline LLBool32(int rhs) : m_bool(rhs) {} -	inline LLBool32(unsigned int rhs) : m_bool(rhs) {} -	inline LLBool32(bool rhs) { m_bool = static_cast<const int>(rhs); } -	inline LLBool32& operator= (bool rhs) { m_bool = (int)rhs; return *this; } -	inline bool operator== (bool rhs) const { return static_cast<const bool&>(m_bool) == rhs; } -	inline bool operator!= (bool rhs) const { return !operator==(rhs); } -	inline operator bool() const { return static_cast<const bool&>(m_bool); } +    inline LLBool32() {} +    inline LLBool32(int rhs) : m_bool(rhs) {} +    inline LLBool32(unsigned int rhs) : m_bool(rhs) {} +    inline LLBool32(bool rhs) { m_bool = static_cast<const int>(rhs); } +    inline LLBool32& operator= (bool rhs) { m_bool = (int)rhs; return *this; } +    inline bool operator== (bool rhs) const { return static_cast<const bool&>(m_bool) == rhs; } +    inline bool operator!= (bool rhs) const { return !operator==(rhs); } +    inline operator bool() const { return static_cast<const bool&>(m_bool); }  private: -	int m_bool; +    int m_bool;  };  #if LL_WINDOWS @@ -70,55 +70,55 @@ private:  class LLSimdScalar  {  public: -	inline LLSimdScalar() {} -	inline LLSimdScalar(LLQuad q)  -	{  -		mQ = q;  -	} +    inline LLSimdScalar() {} +    inline LLSimdScalar(LLQuad q) +    { +        mQ = q; +    } + +    inline LLSimdScalar(F32 f) +    { +        mQ = _mm_set_ss(f); +    } + +    static inline const LLSimdScalar& getZero() +    { +        extern const LLQuad F_ZERO_4A; +        return reinterpret_cast<const LLSimdScalar&>(F_ZERO_4A); +    } -	inline LLSimdScalar(F32 f)  -	{  -		mQ = _mm_set_ss(f);  -	} +    inline F32 getF32() const; -	static inline const LLSimdScalar& getZero() -	{ -		extern const LLQuad F_ZERO_4A; -		return reinterpret_cast<const LLSimdScalar&>(F_ZERO_4A); -	} +    inline LLBool32 isApproximatelyEqual(const LLSimdScalar& rhs, F32 tolerance = F_APPROXIMATELY_ZERO) const; -	inline F32 getF32() const; +    inline LLSimdScalar getAbs() const; -	inline LLBool32 isApproximatelyEqual(const LLSimdScalar& rhs, F32 tolerance = F_APPROXIMATELY_ZERO) const; +    inline void setMax( const LLSimdScalar& a, const LLSimdScalar& b ); -	inline LLSimdScalar getAbs() const; +    inline void setMin( const LLSimdScalar& a, const LLSimdScalar& b ); -	inline void setMax( const LLSimdScalar& a, const LLSimdScalar& b ); -	 -	inline void setMin( const LLSimdScalar& a, const LLSimdScalar& b ); +    inline LLSimdScalar& operator=(F32 rhs); -	inline LLSimdScalar& operator=(F32 rhs); +    inline LLSimdScalar& operator+=(const LLSimdScalar& rhs); -	inline LLSimdScalar& operator+=(const LLSimdScalar& rhs); +    inline LLSimdScalar& operator-=(const LLSimdScalar& rhs); -	inline LLSimdScalar& operator-=(const LLSimdScalar& rhs); +    inline LLSimdScalar& operator*=(const LLSimdScalar& rhs); -	inline LLSimdScalar& operator*=(const LLSimdScalar& rhs); +    inline LLSimdScalar& operator/=(const LLSimdScalar& rhs); -	inline LLSimdScalar& operator/=(const LLSimdScalar& rhs); +    inline operator LLQuad() const +    { +        return mQ; +    } -	inline operator LLQuad() const -	{  -		return mQ;  -	} -	 -	inline const LLQuad& getQuad() const  -	{  -		return mQ;  -	} +    inline const LLQuad& getQuad() const +    { +        return mQ; +    }  private: -	LLQuad mQ; +    LLQuad mQ;  };  #endif //LL_SIMD_TYPES_H diff --git a/indra/llmath/llsimdtypes.inl b/indra/llmath/llsimdtypes.inl index e905c84954..125f4b9df5 100644 --- a/indra/llmath/llsimdtypes.inl +++ b/indra/llmath/llsimdtypes.inl @@ -1,25 +1,25 @@ -/**  +/**   * @file llsimdtypes.inl   * @brief Inlined definitions of basic SIMD math related types   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -33,127 +33,127 @@  inline LLSimdScalar operator+(const LLSimdScalar& a, const LLSimdScalar& b)  { -	LLSimdScalar t(a); -	t += b; -	return t; +    LLSimdScalar t(a); +    t += b; +    return t;  }  inline LLSimdScalar operator-(const LLSimdScalar& a, const LLSimdScalar& b)  { -	LLSimdScalar t(a); -	t -= b; -	return t; +    LLSimdScalar t(a); +    t -= b; +    return t;  }  inline LLSimdScalar operator*(const LLSimdScalar& a, const LLSimdScalar& b)  { -	LLSimdScalar t(a); -	t *= b; -	return t; +    LLSimdScalar t(a); +    t *= b; +    return t;  }  inline LLSimdScalar operator/(const LLSimdScalar& a, const LLSimdScalar& b)  { -	LLSimdScalar t(a); -	t /= b; -	return t; +    LLSimdScalar t(a); +    t /= b; +    return t;  }  inline LLSimdScalar operator-(const LLSimdScalar& a)  { -	static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 }; -	ll_assert_aligned(signMask,16); -	return _mm_xor_ps(*reinterpret_cast<const LLQuad*>(signMask), a); +    static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 }; +    ll_assert_aligned(signMask,16); +    return _mm_xor_ps(*reinterpret_cast<const LLQuad*>(signMask), a);  }  inline LLBool32 operator==(const LLSimdScalar& a, const LLSimdScalar& b)  { -	return _mm_comieq_ss(a, b); +    return _mm_comieq_ss(a, b);  }  inline LLBool32 operator!=(const LLSimdScalar& a, const LLSimdScalar& b)  { -	return _mm_comineq_ss(a, b); +    return _mm_comineq_ss(a, b);  }  inline LLBool32 operator<(const LLSimdScalar& a, const LLSimdScalar& b)  { -	return _mm_comilt_ss(a, b); +    return _mm_comilt_ss(a, b);  }  inline LLBool32 operator<=(const LLSimdScalar& a, const LLSimdScalar& b)  { -	return _mm_comile_ss(a, b); +    return _mm_comile_ss(a, b);  }  inline LLBool32 operator>(const LLSimdScalar& a, const LLSimdScalar& b)  { -	return _mm_comigt_ss(a, b); +    return _mm_comigt_ss(a, b);  }  inline LLBool32 operator>=(const LLSimdScalar& a, const LLSimdScalar& b)  { -	return _mm_comige_ss(a, b); +    return _mm_comige_ss(a, b);  }  inline LLBool32 LLSimdScalar::isApproximatelyEqual(const LLSimdScalar& rhs, F32 tolerance /* = F_APPROXIMATELY_ZERO */) const  { -	const LLSimdScalar tol( tolerance ); -	const LLSimdScalar diff = _mm_sub_ss( mQ, rhs.mQ ); -	const LLSimdScalar absDiff = diff.getAbs(); -	return absDiff <= tol; +    const LLSimdScalar tol( tolerance ); +    const LLSimdScalar diff = _mm_sub_ss( mQ, rhs.mQ ); +    const LLSimdScalar absDiff = diff.getAbs(); +    return absDiff <= tol;  }  inline void LLSimdScalar::setMax( const LLSimdScalar& a, const LLSimdScalar& b )  { -	mQ = _mm_max_ss( a, b ); +    mQ = _mm_max_ss( a, b );  }  inline void LLSimdScalar::setMin( const LLSimdScalar& a, const LLSimdScalar& b )  { -	mQ = _mm_min_ss( a, b ); +    mQ = _mm_min_ss( a, b );  } -inline LLSimdScalar& LLSimdScalar::operator=(F32 rhs)  -{  -	mQ = _mm_set_ss(rhs);  -	return *this;  +inline LLSimdScalar& LLSimdScalar::operator=(F32 rhs) +{ +    mQ = _mm_set_ss(rhs); +    return *this;  } -inline LLSimdScalar& LLSimdScalar::operator+=(const LLSimdScalar& rhs)  +inline LLSimdScalar& LLSimdScalar::operator+=(const LLSimdScalar& rhs)  { -	mQ = _mm_add_ss( mQ, rhs ); -	return *this; +    mQ = _mm_add_ss( mQ, rhs ); +    return *this;  }  inline LLSimdScalar& LLSimdScalar::operator-=(const LLSimdScalar& rhs)  { -	mQ = _mm_sub_ss( mQ, rhs ); -	return *this; +    mQ = _mm_sub_ss( mQ, rhs ); +    return *this;  }  inline LLSimdScalar& LLSimdScalar::operator*=(const LLSimdScalar& rhs)  { -	mQ = _mm_mul_ss( mQ, rhs ); -	return *this; +    mQ = _mm_mul_ss( mQ, rhs ); +    return *this;  }  inline LLSimdScalar& LLSimdScalar::operator/=(const LLSimdScalar& rhs)  { -	mQ = _mm_div_ss( mQ, rhs ); -	return *this; +    mQ = _mm_div_ss( mQ, rhs ); +    return *this;  }  inline LLSimdScalar LLSimdScalar::getAbs() const  { -	static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; -	ll_assert_aligned(F_ABS_MASK_4A,16); -	return _mm_and_ps( mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A)); +    static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; +    ll_assert_aligned(F_ABS_MASK_4A,16); +    return _mm_and_ps( mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A));  }  inline F32 LLSimdScalar::getF32() const -{  -	F32 ret;  -	_mm_store_ss(&ret, mQ);  -	return ret;  +{ +    F32 ret; +    _mm_store_ss(&ret, mQ); +    return ret;  } diff --git a/indra/llmath/llsphere.cpp b/indra/llmath/llsphere.cpp index a8d6200488..75f9ef1772 100644 --- a/indra/llmath/llsphere.cpp +++ b/indra/llmath/llsphere.cpp @@ -1,4 +1,4 @@ -/**  +/**   * @file llsphere.cpp   * @author Andrew Meadows   * @brief Simple line class that can compute nearest approach between two lines @@ -6,21 +6,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -30,342 +30,342 @@  #include "llsphere.h"  LLSphere::LLSphere() -:	mCenter(0.f, 0.f, 0.f), -	mRadius(0.f) +:   mCenter(0.f, 0.f, 0.f), +    mRadius(0.f)  { }  LLSphere::LLSphere( const LLVector3& center, F32 radius)  { -	set(center, radius); +    set(center, radius);  }  void LLSphere::set( const LLVector3& center, F32 radius )  { -	mCenter = center; -	setRadius(radius); +    mCenter = center; +    setRadius(radius);  }  void LLSphere::setCenter( const LLVector3& center)  { -	mCenter = center; +    mCenter = center;  }  void LLSphere::setRadius( F32 radius)  { -	if (radius < 0.f) -	{ -		radius = -radius; -	} -	mRadius = radius; +    if (radius < 0.f) +    { +        radius = -radius; +    } +    mRadius = radius;  } -	 +  const LLVector3& LLSphere::getCenter() const  { -	return mCenter; +    return mCenter;  }  F32 LLSphere::getRadius() const  { -	return mRadius; +    return mRadius;  }  // returns 'TRUE' if this sphere completely contains other_sphere  BOOL LLSphere::contains(const LLSphere& other_sphere) const  { -	F32 separation = (mCenter - other_sphere.mCenter).length(); -	return (mRadius >= separation + other_sphere.mRadius) ? TRUE : FALSE; +    F32 separation = (mCenter - other_sphere.mCenter).length(); +    return (mRadius >= separation + other_sphere.mRadius) ? TRUE : FALSE;  }  // returns 'TRUE' if this sphere completely contains other_sphere  BOOL LLSphere::overlaps(const LLSphere& other_sphere) const  { -	F32 separation = (mCenter - other_sphere.mCenter).length(); -	return (separation <= mRadius + other_sphere.mRadius) ? TRUE : FALSE; +    F32 separation = (mCenter - other_sphere.mCenter).length(); +    return (separation <= mRadius + other_sphere.mRadius) ? TRUE : FALSE;  }  // returns overlap  // negative overlap is closest approach  F32 LLSphere::getOverlap(const LLSphere& other_sphere) const  { -	// separation is distance from other_sphere's edge and this center -	return (mCenter - other_sphere.mCenter).length() - mRadius - other_sphere.mRadius; +    // separation is distance from other_sphere's edge and this center +    return (mCenter - other_sphere.mCenter).length() - mRadius - other_sphere.mRadius;  }  bool LLSphere::operator==(const LLSphere& rhs) const  { -	// TODO? -- use approximate equality for centers? -	return (mRadius == rhs.mRadius -			&& mCenter == rhs.mCenter); +    // TODO? -- use approximate equality for centers? +    return (mRadius == rhs.mRadius +            && mCenter == rhs.mCenter);  }  std::ostream& operator<<( std::ostream& output_stream, const LLSphere& sphere)  { -	output_stream << "{center=" << sphere.mCenter << "," << "radius=" << sphere.mRadius << "}"; -	return output_stream; +    output_stream << "{center=" << sphere.mCenter << "," << "radius=" << sphere.mRadius << "}"; +    return output_stream;  } -// static  +// static  // removes any spheres that are contained in others  void LLSphere::collapse(std::vector<LLSphere>& sphere_list)  { -	std::vector<LLSphere>::iterator first_itr = sphere_list.begin(); -	while (first_itr != sphere_list.end()) -	{ -		bool delete_from_front = false; - -		std::vector<LLSphere>::iterator second_itr = first_itr; -		++second_itr; -		while (second_itr != sphere_list.end()) -		{ -			if (second_itr->contains(*first_itr)) -			{ -				delete_from_front = true; -				break; -			} -			else if (first_itr->contains(*second_itr)) -			{ -				sphere_list.erase(second_itr++); -			} -			else -			{ -				++second_itr; -			} -		} - -		if (delete_from_front) -		{ -			sphere_list.erase(first_itr++); -		} -		else -		{ -			++first_itr; -		} -	} +    std::vector<LLSphere>::iterator first_itr = sphere_list.begin(); +    while (first_itr != sphere_list.end()) +    { +        bool delete_from_front = false; + +        std::vector<LLSphere>::iterator second_itr = first_itr; +        ++second_itr; +        while (second_itr != sphere_list.end()) +        { +            if (second_itr->contains(*first_itr)) +            { +                delete_from_front = true; +                break; +            } +            else if (first_itr->contains(*second_itr)) +            { +                sphere_list.erase(second_itr++); +            } +            else +            { +                ++second_itr; +            } +        } + +        if (delete_from_front) +        { +            sphere_list.erase(first_itr++); +        } +        else +        { +            ++first_itr; +        } +    }  }  // static  // returns the bounding sphere that contains both spheres  LLSphere LLSphere::getBoundingSphere(const LLSphere& first_sphere, const LLSphere& second_sphere)  { -	LLVector3 direction = second_sphere.mCenter - first_sphere.mCenter; - -	// HACK -- it is possible to get enough floating point error in the  -	// other getBoundingSphere() method that we have to add some slop -	// at the end.  Unfortunately, this breaks the link-order invarience -	// for the linkability tests... unless we also apply the same slop -	// here. -	F32 half_milimeter = 0.0005f; - -	F32 distance = direction.length(); -	if (0.f == distance) -	{ -		direction.setVec(1.f, 0.f, 0.f); -	} -	else -	{ -		direction.normVec(); -	} -	// the 'edge' is measured from the first_sphere's center -	F32 max_edge = 0.f; -	F32 min_edge = 0.f; - -	max_edge = llmax(max_edge + first_sphere.getRadius(), max_edge + distance + second_sphere.getRadius() + half_milimeter); -	min_edge = llmin(min_edge - first_sphere.getRadius(), min_edge + distance - second_sphere.getRadius() - half_milimeter); -	F32 radius = 0.5f * (max_edge - min_edge); -	LLVector3 center = first_sphere.mCenter + (0.5f * (max_edge + min_edge)) * direction; -	return LLSphere(center, radius); +    LLVector3 direction = second_sphere.mCenter - first_sphere.mCenter; + +    // HACK -- it is possible to get enough floating point error in the +    // other getBoundingSphere() method that we have to add some slop +    // at the end.  Unfortunately, this breaks the link-order invarience +    // for the linkability tests... unless we also apply the same slop +    // here. +    F32 half_milimeter = 0.0005f; + +    F32 distance = direction.length(); +    if (0.f == distance) +    { +        direction.setVec(1.f, 0.f, 0.f); +    } +    else +    { +        direction.normVec(); +    } +    // the 'edge' is measured from the first_sphere's center +    F32 max_edge = 0.f; +    F32 min_edge = 0.f; + +    max_edge = llmax(max_edge + first_sphere.getRadius(), max_edge + distance + second_sphere.getRadius() + half_milimeter); +    min_edge = llmin(min_edge - first_sphere.getRadius(), min_edge + distance - second_sphere.getRadius() - half_milimeter); +    F32 radius = 0.5f * (max_edge - min_edge); +    LLVector3 center = first_sphere.mCenter + (0.5f * (max_edge + min_edge)) * direction; +    return LLSphere(center, radius);  }  // static  // returns the bounding sphere that contains an arbitrary set of spheres  LLSphere LLSphere::getBoundingSphere(const std::vector<LLSphere>& sphere_list)  { -	// this algorithm can get relatively inaccurate when the sphere  -	// collection is 'small' (contained within a bounding sphere of about  -	// 2 meters or less) -	// TODO -- improve the accuracy for small collections of spheres - -	LLSphere bounding_sphere( LLVector3(0.f, 0.f, 0.f), 0.f ); -	S32 sphere_count = sphere_list.size(); -	if (1 == sphere_count) -	{ -		// trivial case -- single sphere -		std::vector<LLSphere>::const_iterator sphere_itr = sphere_list.begin(); -		bounding_sphere = *sphere_itr; -	} -	else if (2 == sphere_count) -	{ -		// trivial case -- two spheres -		std::vector<LLSphere>::const_iterator first_sphere = sphere_list.begin(); -		std::vector<LLSphere>::const_iterator second_sphere = first_sphere; -		++second_sphere; -		bounding_sphere = LLSphere::getBoundingSphere(*first_sphere, *second_sphere); -	} -	else if (sphere_count > 0) -	{ -		// non-trivial case -- we will approximate the solution -		// -		// NOTE -- there is a fancy/fast way to do this for large  -		// numbers of arbirary N-dimensional spheres -- you can look it -		// up on the net.  We're dealing with 3D spheres at collection -		// sizes of 256 spheres or smaller, so we just use this -		// brute force method. - -		// TODO -- perhaps would be worthwile to test for the solution where -		// the largest spanning radius just happens to work.  That is, where -		// there are really two spheres that determine the bounding sphere, -		// and all others are contained therein. - -		// compute the AABB -		std::vector<LLSphere>::const_iterator first_itr = sphere_list.begin(); -		LLVector3 max_corner = first_itr->getCenter() + first_itr->getRadius() * LLVector3(1.f, 1.f, 1.f); -		LLVector3 min_corner = first_itr->getCenter() - first_itr->getRadius() * LLVector3(1.f, 1.f, 1.f); -		{ -			std::vector<LLSphere>::const_iterator sphere_itr = sphere_list.begin(); -			for (++sphere_itr; sphere_itr != sphere_list.end(); ++sphere_itr) -			{ -				LLVector3 center = sphere_itr->getCenter(); -				F32 radius = sphere_itr->getRadius(); -				for (S32 i=0; i<3; ++i) -				{ -					if (center.mV[i] + radius > max_corner.mV[i]) -					{ -						max_corner.mV[i] = center.mV[i] + radius; -					} -					if (center.mV[i] - radius < min_corner.mV[i]) -					{ -						min_corner.mV[i] = center.mV[i] - radius; -					} -				} -			} -		} - -		// get the starting center and radius from the AABB -		LLVector3 diagonal = max_corner - min_corner; -		F32 bounding_radius = 0.5f * diagonal.length(); -		LLVector3 bounding_center = 0.5f * (max_corner + min_corner); - -		// compute the starting step-size -		F32 minimum_radius = 0.5f * llmin(diagonal.mV[VX], llmin(diagonal.mV[VY], diagonal.mV[VZ])); -		F32 step_length = bounding_radius - minimum_radius; -		//S32 step_count = 0; -		//S32 max_step_count = 12; -		F32 half_milimeter = 0.0005f; - -		// wander the center around in search of tighter solutions -		S32 last_dx = 2;	// 2 is out of bounds --> no match -		S32 last_dy = 2; -		S32 last_dz = 2; - -		while (step_length > half_milimeter -				/*&& step_count < max_step_count*/) -		{ -			// the algorithm for testing the maximum radius could be expensive enough -			// that it makes sense to NOT duplicate testing when possible, so we keep -			// track of where we last tested, and only test the new points - -			S32 best_dx = 0; -			S32 best_dy = 0; -			S32 best_dz = 0; - -			// sample near the center of the box -			bool found_better_center = false; -			for (S32 dx = -1; dx < 2; ++dx) -			{ -				for (S32 dy = -1; dy < 2; ++dy) -				{ -					for (S32 dz = -1; dz < 2; ++dz) -					{ -						if (dx == 0 && dy == 0 && dz == 0) -						{ -							continue; -						} - -						// count the number of indecies that match the last_*'s -						S32 match_count = 0; -						if (last_dx == dx) ++match_count; -						if (last_dy == dy) ++match_count; -						if (last_dz == dz) ++match_count; -						if (match_count == 2) -						{ -							// we've already tested this point -							continue; -						} - -						LLVector3 center = bounding_center; -						center.mV[VX] += (F32) dx * step_length; -						center.mV[VY] += (F32) dy * step_length; -						center.mV[VZ] += (F32) dz * step_length; - -						// compute the radius of the bounding sphere -						F32 max_radius = 0.f; -						std::vector<LLSphere>::const_iterator sphere_itr; -						for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) -						{ -							F32 radius = (sphere_itr->getCenter() - center).length() + sphere_itr->getRadius(); -							if (radius > max_radius) -							{ -								max_radius = radius; -							} -						} -						if (max_radius < bounding_radius) -						{ -							best_dx = dx; -							best_dy = dy; -							best_dz = dz; -							bounding_center = center; -							bounding_radius = max_radius; -							found_better_center = true; -						} -					} -				} -			} -			if (found_better_center) -			{ -				// remember where we came from so we can avoid retesting -				last_dx = -best_dx; -				last_dy = -best_dy; -				last_dz = -best_dz; -			} -			else -			{ -				// reduce the step size -				step_length *= 0.5f; -				//++step_count; -				// reset the last_*'s -				last_dx = 2;	// 2 is out of bounds --> no match -				last_dy = 2; -				last_dz = 2; -			} -		} - -		// HACK -- it is possible to get enough floating point error for the -		// bounding sphere to too small on the order of 10e-6, but we only need -		// it to be accurate to within about half a millimeter -		bounding_radius += half_milimeter; - -		// this algorithm can get relatively inaccurate when the sphere  -		// collection is 'small' (contained within a bounding sphere of about  -		// 2 meters or less) -		// TODO -- fix this -		/* debug code -		{ -			std::vector<LLSphere>::const_iterator sphere_itr; -			for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) -			{ -				F32 radius = (sphere_itr->getCenter() - bounding_center).length() + sphere_itr->getRadius(); -				if (radius + 0.1f > bounding_radius) -				{ -					std::cout << " rad = " << radius << "  bounding - rad = " << (bounding_radius - radius) << std::endl; -				} -			} -			std::cout << "\n" << std::endl; -		} -		*/  - -		bounding_sphere.set(bounding_center, bounding_radius); -	} -	return bounding_sphere; +    // this algorithm can get relatively inaccurate when the sphere +    // collection is 'small' (contained within a bounding sphere of about +    // 2 meters or less) +    // TODO -- improve the accuracy for small collections of spheres + +    LLSphere bounding_sphere( LLVector3(0.f, 0.f, 0.f), 0.f ); +    S32 sphere_count = sphere_list.size(); +    if (1 == sphere_count) +    { +        // trivial case -- single sphere +        std::vector<LLSphere>::const_iterator sphere_itr = sphere_list.begin(); +        bounding_sphere = *sphere_itr; +    } +    else if (2 == sphere_count) +    { +        // trivial case -- two spheres +        std::vector<LLSphere>::const_iterator first_sphere = sphere_list.begin(); +        std::vector<LLSphere>::const_iterator second_sphere = first_sphere; +        ++second_sphere; +        bounding_sphere = LLSphere::getBoundingSphere(*first_sphere, *second_sphere); +    } +    else if (sphere_count > 0) +    { +        // non-trivial case -- we will approximate the solution +        // +        // NOTE -- there is a fancy/fast way to do this for large +        // numbers of arbirary N-dimensional spheres -- you can look it +        // up on the net.  We're dealing with 3D spheres at collection +        // sizes of 256 spheres or smaller, so we just use this +        // brute force method. + +        // TODO -- perhaps would be worthwile to test for the solution where +        // the largest spanning radius just happens to work.  That is, where +        // there are really two spheres that determine the bounding sphere, +        // and all others are contained therein. + +        // compute the AABB +        std::vector<LLSphere>::const_iterator first_itr = sphere_list.begin(); +        LLVector3 max_corner = first_itr->getCenter() + first_itr->getRadius() * LLVector3(1.f, 1.f, 1.f); +        LLVector3 min_corner = first_itr->getCenter() - first_itr->getRadius() * LLVector3(1.f, 1.f, 1.f); +        { +            std::vector<LLSphere>::const_iterator sphere_itr = sphere_list.begin(); +            for (++sphere_itr; sphere_itr != sphere_list.end(); ++sphere_itr) +            { +                LLVector3 center = sphere_itr->getCenter(); +                F32 radius = sphere_itr->getRadius(); +                for (S32 i=0; i<3; ++i) +                { +                    if (center.mV[i] + radius > max_corner.mV[i]) +                    { +                        max_corner.mV[i] = center.mV[i] + radius; +                    } +                    if (center.mV[i] - radius < min_corner.mV[i]) +                    { +                        min_corner.mV[i] = center.mV[i] - radius; +                    } +                } +            } +        } + +        // get the starting center and radius from the AABB +        LLVector3 diagonal = max_corner - min_corner; +        F32 bounding_radius = 0.5f * diagonal.length(); +        LLVector3 bounding_center = 0.5f * (max_corner + min_corner); + +        // compute the starting step-size +        F32 minimum_radius = 0.5f * llmin(diagonal.mV[VX], llmin(diagonal.mV[VY], diagonal.mV[VZ])); +        F32 step_length = bounding_radius - minimum_radius; +        //S32 step_count = 0; +        //S32 max_step_count = 12; +        F32 half_milimeter = 0.0005f; + +        // wander the center around in search of tighter solutions +        S32 last_dx = 2;    // 2 is out of bounds --> no match +        S32 last_dy = 2; +        S32 last_dz = 2; + +        while (step_length > half_milimeter +                /*&& step_count < max_step_count*/) +        { +            // the algorithm for testing the maximum radius could be expensive enough +            // that it makes sense to NOT duplicate testing when possible, so we keep +            // track of where we last tested, and only test the new points + +            S32 best_dx = 0; +            S32 best_dy = 0; +            S32 best_dz = 0; + +            // sample near the center of the box +            bool found_better_center = false; +            for (S32 dx = -1; dx < 2; ++dx) +            { +                for (S32 dy = -1; dy < 2; ++dy) +                { +                    for (S32 dz = -1; dz < 2; ++dz) +                    { +                        if (dx == 0 && dy == 0 && dz == 0) +                        { +                            continue; +                        } + +                        // count the number of indecies that match the last_*'s +                        S32 match_count = 0; +                        if (last_dx == dx) ++match_count; +                        if (last_dy == dy) ++match_count; +                        if (last_dz == dz) ++match_count; +                        if (match_count == 2) +                        { +                            // we've already tested this point +                            continue; +                        } + +                        LLVector3 center = bounding_center; +                        center.mV[VX] += (F32) dx * step_length; +                        center.mV[VY] += (F32) dy * step_length; +                        center.mV[VZ] += (F32) dz * step_length; + +                        // compute the radius of the bounding sphere +                        F32 max_radius = 0.f; +                        std::vector<LLSphere>::const_iterator sphere_itr; +                        for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) +                        { +                            F32 radius = (sphere_itr->getCenter() - center).length() + sphere_itr->getRadius(); +                            if (radius > max_radius) +                            { +                                max_radius = radius; +                            } +                        } +                        if (max_radius < bounding_radius) +                        { +                            best_dx = dx; +                            best_dy = dy; +                            best_dz = dz; +                            bounding_center = center; +                            bounding_radius = max_radius; +                            found_better_center = true; +                        } +                    } +                } +            } +            if (found_better_center) +            { +                // remember where we came from so we can avoid retesting +                last_dx = -best_dx; +                last_dy = -best_dy; +                last_dz = -best_dz; +            } +            else +            { +                // reduce the step size +                step_length *= 0.5f; +                //++step_count; +                // reset the last_*'s +                last_dx = 2;    // 2 is out of bounds --> no match +                last_dy = 2; +                last_dz = 2; +            } +        } + +        // HACK -- it is possible to get enough floating point error for the +        // bounding sphere to too small on the order of 10e-6, but we only need +        // it to be accurate to within about half a millimeter +        bounding_radius += half_milimeter; + +        // this algorithm can get relatively inaccurate when the sphere +        // collection is 'small' (contained within a bounding sphere of about +        // 2 meters or less) +        // TODO -- fix this +        /* debug code +        { +            std::vector<LLSphere>::const_iterator sphere_itr; +            for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) +            { +                F32 radius = (sphere_itr->getCenter() - bounding_center).length() + sphere_itr->getRadius(); +                if (radius + 0.1f > bounding_radius) +                { +                    std::cout << " rad = " << radius << "  bounding - rad = " << (bounding_radius - radius) << std::endl; +                } +            } +            std::cout << "\n" << std::endl; +        } +        */ + +        bounding_sphere.set(bounding_center, bounding_radius); +    } +    return bounding_sphere;  } diff --git a/indra/llmath/llsphere.h b/indra/llmath/llsphere.h index 7c60a11406..62bcadf16d 100644 --- a/indra/llmath/llsphere.h +++ b/indra/llmath/llsphere.h @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -37,40 +37,40 @@  class LLSphere  {  public: -	LLSphere(); -	LLSphere( const LLVector3& center, F32 radius ); +    LLSphere(); +    LLSphere( const LLVector3& center, F32 radius ); -	void set( const LLVector3& center, F32 radius ); -	void setCenter( const LLVector3& center ); -	void setRadius( F32 radius ); +    void set( const LLVector3& center, F32 radius ); +    void setCenter( const LLVector3& center ); +    void setRadius( F32 radius ); -	const LLVector3& getCenter() const; -	F32 getRadius() const; +    const LLVector3& getCenter() const; +    F32 getRadius() const; -	// returns TRUE if this sphere completely contains other_sphere -	BOOL contains(const LLSphere& other_sphere) const; +    // returns TRUE if this sphere completely contains other_sphere +    BOOL contains(const LLSphere& other_sphere) const; -	// returns TRUE if this sphere overlaps other_sphere -	BOOL overlaps(const LLSphere& other_sphere) const; +    // returns TRUE if this sphere overlaps other_sphere +    BOOL overlaps(const LLSphere& other_sphere) const; -	// returns overlap distance -	// negative overlap is closest approach -	F32 getOverlap(const LLSphere& other_sphere) const; +    // returns overlap distance +    // negative overlap is closest approach +    F32 getOverlap(const LLSphere& other_sphere) const; -	// removes any spheres that are contained in others -	static void collapse(std::vector<LLSphere>& sphere_list); +    // removes any spheres that are contained in others +    static void collapse(std::vector<LLSphere>& sphere_list); -	// returns minimum sphere bounding sphere for a set of spheres -	static LLSphere getBoundingSphere(const LLSphere& first_sphere, const LLSphere& second_sphere); -	static LLSphere getBoundingSphere(const std::vector<LLSphere>& sphere_list); +    // returns minimum sphere bounding sphere for a set of spheres +    static LLSphere getBoundingSphere(const LLSphere& first_sphere, const LLSphere& second_sphere); +    static LLSphere getBoundingSphere(const std::vector<LLSphere>& sphere_list); -	bool operator==(const LLSphere& rhs) const; +    bool operator==(const LLSphere& rhs) const; -	friend std::ostream& operator<<( std::ostream& output_stream, const LLSphere& line ); +    friend std::ostream& operator<<( std::ostream& output_stream, const LLSphere& line );  protected: -	LLVector3 mCenter; -	F32 mRadius; +    LLVector3 mCenter; +    F32 mRadius;  }; diff --git a/indra/llmath/lltreenode.h b/indra/llmath/lltreenode.h index 0b479c4564..a0b90e3511 100644 --- a/indra/llmath/lltreenode.h +++ b/indra/llmath/lltreenode.h @@ -1,24 +1,24 @@ -/**  +/**   * @file lltreenode.h   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -41,84 +41,84 @@ template <class T>  class LLTreeListener: public LLRefCount  {  public: -	virtual void handleInsertion(const LLTreeNode<T>* node, T* data) = 0; -	virtual void handleRemoval(const LLTreeNode<T>* node, T* data) = 0; -	virtual void handleDestruction(const LLTreeNode<T>* node) = 0; -	virtual void handleStateChange(const LLTreeNode<T>* node) = 0; +    virtual void handleInsertion(const LLTreeNode<T>* node, T* data) = 0; +    virtual void handleRemoval(const LLTreeNode<T>* node, T* data) = 0; +    virtual void handleDestruction(const LLTreeNode<T>* node) = 0; +    virtual void handleStateChange(const LLTreeNode<T>* node) = 0;  };  template <class T> -class LLTreeNode  +class LLTreeNode  {  public: -	virtual ~LLTreeNode(); -	 -	virtual bool insert(T* data); -	virtual bool remove(T* data); -	virtual void notifyRemoval(T* data); -	virtual U32 getListenerCount()					{ return mListeners.size(); } -	virtual LLTreeListener<T>* getListener(U32 index) const  -	{ -		if(index < mListeners.size()) -		{ -			return mListeners[index];  -		} -		return NULL; -	} -	virtual void addListener(LLTreeListener<T>* listener) { mListeners.push_back(listener); } +    virtual ~LLTreeNode(); + +    virtual bool insert(T* data); +    virtual bool remove(T* data); +    virtual void notifyRemoval(T* data); +    virtual U32 getListenerCount()                  { return mListeners.size(); } +    virtual LLTreeListener<T>* getListener(U32 index) const +    { +        if(index < mListeners.size()) +        { +            return mListeners[index]; +        } +        return NULL; +    } +    virtual void addListener(LLTreeListener<T>* listener) { mListeners.push_back(listener); }  protected: -	void destroyListeners() -	{ -		for (U32 i = 0; i < mListeners.size(); i++) -		{ -			mListeners[i]->handleDestruction(this); -		} -		mListeners.clear(); -	} -	 +    void destroyListeners() +    { +        for (U32 i = 0; i < mListeners.size(); i++) +        { +            mListeners[i]->handleDestruction(this); +        } +        mListeners.clear(); +    } +  public: -	std::vector<LLPointer<LLTreeListener<T> > > mListeners; +    std::vector<LLPointer<LLTreeListener<T> > > mListeners;  };  template <class T>  class LLTreeTraveler  {  public: -	virtual ~LLTreeTraveler() { };  -	virtual void traverse(const LLTreeNode<T>* node) = 0; -	virtual void visit(const LLTreeNode<T>* node) = 0; +    virtual ~LLTreeTraveler() { }; +    virtual void traverse(const LLTreeNode<T>* node) = 0; +    virtual void visit(const LLTreeNode<T>* node) = 0;  };  template <class T>  LLTreeNode<T>::~LLTreeNode() -{  -	destroyListeners(); +{ +    destroyListeners();  };  template <class T>  bool LLTreeNode<T>::insert(T* data) -{  -	for (U32 i = 0; i < mListeners.size(); i++) -	{ -		mListeners[i]->handleInsertion(this, data); -	} -	return true; +{ +    for (U32 i = 0; i < mListeners.size(); i++) +    { +        mListeners[i]->handleInsertion(this, data); +    } +    return true;  };  template <class T>  bool LLTreeNode<T>::remove(T* data)  { -	return true; +    return true;  };  template <class T>  void LLTreeNode<T>::notifyRemoval(T* data)  { -	for (U32 i = 0; i < mListeners.size(); i++) -	{ -		mListeners[i]->handleRemoval(this, data); -	} +    for (U32 i = 0; i < mListeners.size(); i++) +    { +        mListeners[i]->handleRemoval(this, data); +    }  }  #endif diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp index 570fa41a43..0ac91366b6 100644 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file llvector4a.cpp   * @brief SIMD vector implementation   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -28,12 +28,12 @@  #include "llmath.h"  #include "llquantize.h" -extern const LLQuad F_ZERO_4A		= { 0, 0, 0, 0 }; -extern const LLQuad F_APPROXIMATELY_ZERO_4A = {  -	F_APPROXIMATELY_ZERO, -	F_APPROXIMATELY_ZERO, -	F_APPROXIMATELY_ZERO, -	F_APPROXIMATELY_ZERO +extern const LLQuad F_ZERO_4A       = { 0, 0, 0, 0 }; +extern const LLQuad F_APPROXIMATELY_ZERO_4A = { +    F_APPROXIMATELY_ZERO, +    F_APPROXIMATELY_ZERO, +    F_APPROXIMATELY_ZERO, +    F_APPROXIMATELY_ZERO  };  extern const LLVector4a LL_V4A_ZERO = reinterpret_cast<const LLVector4a&> ( F_ZERO_4A ); @@ -46,135 +46,135 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast<const LLVector4a&> ( F  void LLVector4a::setRotated( const LLRotation& rot, const LLVector4a& vec )  { -	const LLVector4a col0 = rot.getColumn(0); -	const LLVector4a col1 = rot.getColumn(1); -	const LLVector4a col2 = rot.getColumn(2); - -	LLVector4a result = _mm_load_ss( vec.getF32ptr() ); -	result.splat<0>( result ); -	result.mul( col0 ); - -	{ -		LLVector4a yyyy = _mm_load_ss( vec.getF32ptr() +  1 ); -		yyyy.splat<0>( yyyy ); -		yyyy.mul( col1 );  -		result.add( yyyy ); -	} - -	{ -		LLVector4a zzzz = _mm_load_ss( vec.getF32ptr() +  2 ); -		zzzz.splat<0>( zzzz ); -		zzzz.mul( col2 ); -		result.add( zzzz ); -	} - -	*this = result; +    const LLVector4a col0 = rot.getColumn(0); +    const LLVector4a col1 = rot.getColumn(1); +    const LLVector4a col2 = rot.getColumn(2); + +    LLVector4a result = _mm_load_ss( vec.getF32ptr() ); +    result.splat<0>( result ); +    result.mul( col0 ); + +    { +        LLVector4a yyyy = _mm_load_ss( vec.getF32ptr() +  1 ); +        yyyy.splat<0>( yyyy ); +        yyyy.mul( col1 ); +        result.add( yyyy ); +    } + +    { +        LLVector4a zzzz = _mm_load_ss( vec.getF32ptr() +  2 ); +        zzzz.splat<0>( zzzz ); +        zzzz.mul( col2 ); +        result.add( zzzz ); +    } + +    *this = result;  }  void LLVector4a::setRotated( const LLQuaternion2& quat, const LLVector4a& vec )  { -	const LLVector4a& quatVec = quat.getVector4a(); -	LLVector4a temp; temp.setCross3(quatVec, vec); -	temp.add( temp ); -	 -	const LLVector4a realPart( quatVec.getScalarAt<3>() ); -	LLVector4a tempTimesReal; tempTimesReal.setMul( temp, realPart ); - -	mQ = vec; -	add( tempTimesReal ); -	 -	LLVector4a imagCrossTemp; imagCrossTemp.setCross3( quatVec, temp ); -	add(imagCrossTemp); +    const LLVector4a& quatVec = quat.getVector4a(); +    LLVector4a temp; temp.setCross3(quatVec, vec); +    temp.add( temp ); + +    const LLVector4a realPart( quatVec.getScalarAt<3>() ); +    LLVector4a tempTimesReal; tempTimesReal.setMul( temp, realPart ); + +    mQ = vec; +    add( tempTimesReal ); + +    LLVector4a imagCrossTemp; imagCrossTemp.setCross3( quatVec, temp ); +    add(imagCrossTemp);  }  void LLVector4a::quantize8( const LLVector4a& low, const LLVector4a& high )  { -	LLVector4a val(mQ); -	LLVector4a delta; delta.setSub( high, low ); - -	{ -		val.clamp(low, high); -		val.sub(low); - -		// 8-bit quantization means we can do with just 12 bits of reciprocal accuracy -		const LLVector4a oneOverDelta = _mm_rcp_ps(delta.mQ); -// 		{ -// 			static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f }; -// 			LLVector4a two; two.load4a( F_TWO_4A ); -//  -// 			// Here we use _mm_rcp_ps plus one round of newton-raphson -// 			// We wish to find 'x' such that x = 1/delta -// 			// As a first approximation, we take x0 = _mm_rcp_ps(delta) -// 			// Then x1 = 2 * x0 - a * x0^2 or x1 = x0 * ( 2 - a * x0 ) -// 			// See Intel AP-803 http://ompf.org/!/Intel_application_note_AP-803.pdf -// 			const LLVector4a recipApprox = _mm_rcp_ps(delta.mQ); -// 			oneOverDelta.setMul( delta, recipApprox ); -// 			oneOverDelta.setSub( two, oneOverDelta ); -// 			oneOverDelta.mul( recipApprox ); -// 		} - -		val.mul(oneOverDelta); -		val.mul(*reinterpret_cast<const LLVector4a*>(F_U8MAX_4A)); -	} - -	val = _mm_cvtepi32_ps(_mm_cvtps_epi32( val.mQ )); - -	{ -		val.mul(*reinterpret_cast<const LLVector4a*>(F_OOU8MAX_4A)); -		val.mul(delta); -		val.add(low); -	} - -	{ -		LLVector4a maxError; maxError.setMul(delta, *reinterpret_cast<const LLVector4a*>(F_OOU8MAX_4A)); -		LLVector4a absVal; absVal.setAbs( val ); -		setSelectWithMask( absVal.lessThan( maxError ), F_ZERO_4A, val ); -	}	 +    LLVector4a val(mQ); +    LLVector4a delta; delta.setSub( high, low ); + +    { +        val.clamp(low, high); +        val.sub(low); + +        // 8-bit quantization means we can do with just 12 bits of reciprocal accuracy +        const LLVector4a oneOverDelta = _mm_rcp_ps(delta.mQ); +//      { +//          static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f }; +//          LLVector4a two; two.load4a( F_TWO_4A ); +// +//          // Here we use _mm_rcp_ps plus one round of newton-raphson +//          // We wish to find 'x' such that x = 1/delta +//          // As a first approximation, we take x0 = _mm_rcp_ps(delta) +//          // Then x1 = 2 * x0 - a * x0^2 or x1 = x0 * ( 2 - a * x0 ) +//          // See Intel AP-803 http://ompf.org/!/Intel_application_note_AP-803.pdf +//          const LLVector4a recipApprox = _mm_rcp_ps(delta.mQ); +//          oneOverDelta.setMul( delta, recipApprox ); +//          oneOverDelta.setSub( two, oneOverDelta ); +//          oneOverDelta.mul( recipApprox ); +//      } + +        val.mul(oneOverDelta); +        val.mul(*reinterpret_cast<const LLVector4a*>(F_U8MAX_4A)); +    } + +    val = _mm_cvtepi32_ps(_mm_cvtps_epi32( val.mQ )); + +    { +        val.mul(*reinterpret_cast<const LLVector4a*>(F_OOU8MAX_4A)); +        val.mul(delta); +        val.add(low); +    } + +    { +        LLVector4a maxError; maxError.setMul(delta, *reinterpret_cast<const LLVector4a*>(F_OOU8MAX_4A)); +        LLVector4a absVal; absVal.setAbs( val ); +        setSelectWithMask( absVal.lessThan( maxError ), F_ZERO_4A, val ); +    }  }  void LLVector4a::quantize16( const LLVector4a& low, const LLVector4a& high )  { -	LLVector4a val(mQ); -	LLVector4a delta; delta.setSub( high, low ); - -	{ -		val.clamp(low, high); -		val.sub(low); - -		// 16-bit quantization means we need a round of Newton-Raphson -		LLVector4a oneOverDelta; -		{ -			static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f }; -			ll_assert_aligned(F_TWO_4A,16); -			 -			LLVector4a two; two.load4a( F_TWO_4A ); - -			// Here we use _mm_rcp_ps plus one round of newton-raphson -			// We wish to find 'x' such that x = 1/delta -			// As a first approximation, we take x0 = _mm_rcp_ps(delta) -			// Then x1 = 2 * x0 - a * x0^2 or x1 = x0 * ( 2 - a * x0 ) -			// See Intel AP-803 http://ompf.org/!/Intel_application_note_AP-803.pdf -			const LLVector4a recipApprox = _mm_rcp_ps(delta.mQ); -			oneOverDelta.setMul( delta, recipApprox ); -			oneOverDelta.setSub( two, oneOverDelta ); -			oneOverDelta.mul( recipApprox ); -		} - -		val.mul(oneOverDelta); -		val.mul(*reinterpret_cast<const LLVector4a*>(F_U16MAX_4A)); -	} - -	val = _mm_cvtepi32_ps(_mm_cvtps_epi32( val.mQ )); - -	{ -		val.mul(*reinterpret_cast<const LLVector4a*>(F_OOU16MAX_4A)); -		val.mul(delta); -		val.add(low); -	} - -	{ -		LLVector4a maxError; maxError.setMul(delta, *reinterpret_cast<const LLVector4a*>(F_OOU16MAX_4A)); -		LLVector4a absVal; absVal.setAbs( val ); -		setSelectWithMask( absVal.lessThan( maxError ), F_ZERO_4A, val ); -	}	 +    LLVector4a val(mQ); +    LLVector4a delta; delta.setSub( high, low ); + +    { +        val.clamp(low, high); +        val.sub(low); + +        // 16-bit quantization means we need a round of Newton-Raphson +        LLVector4a oneOverDelta; +        { +            static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f }; +            ll_assert_aligned(F_TWO_4A,16); + +            LLVector4a two; two.load4a( F_TWO_4A ); + +            // Here we use _mm_rcp_ps plus one round of newton-raphson +            // We wish to find 'x' such that x = 1/delta +            // As a first approximation, we take x0 = _mm_rcp_ps(delta) +            // Then x1 = 2 * x0 - a * x0^2 or x1 = x0 * ( 2 - a * x0 ) +            // See Intel AP-803 http://ompf.org/!/Intel_application_note_AP-803.pdf +            const LLVector4a recipApprox = _mm_rcp_ps(delta.mQ); +            oneOverDelta.setMul( delta, recipApprox ); +            oneOverDelta.setSub( two, oneOverDelta ); +            oneOverDelta.mul( recipApprox ); +        } + +        val.mul(oneOverDelta); +        val.mul(*reinterpret_cast<const LLVector4a*>(F_U16MAX_4A)); +    } + +    val = _mm_cvtepi32_ps(_mm_cvtps_epi32( val.mQ )); + +    { +        val.mul(*reinterpret_cast<const LLVector4a*>(F_OOU16MAX_4A)); +        val.mul(delta); +        val.add(low); +    } + +    { +        LLVector4a maxError; maxError.setMul(delta, *reinterpret_cast<const LLVector4a*>(F_OOU16MAX_4A)); +        LLVector4a absVal; absVal.setAbs( val ); +        setSelectWithMask( absVal.lessThan( maxError ), F_ZERO_4A, val ); +    }  } diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 53c8f604f6..8f0ee4b739 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -1,31 +1,31 @@ -/**  +/**   * @file llvector4a.h   * @brief LLVector4a class header file - memory aligned and vectorized 4 component vector   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -#ifndef	LL_LLVECTOR4A_H -#define	LL_LLVECTOR4A_H +#ifndef LL_LLVECTOR4A_H +#define LL_LLVECTOR4A_H  class LLRotation; @@ -40,11 +40,11 @@ class LLRotation;  // This is just the beginning of LLVector4a. There are many more useful functions  // yet to be implemented. For example, setNeg to negate a vector, rotate() to apply  // a matrix rotation, various functions to manipulate only the X, Y, and Z elements -// and many others (including a whole variety of accessors). So if you don't see a  -// function here that you need, please contact Falcon or someone else with SSE  -// experience (Richard, I think, has some and davep has a little as of the time  +// and many others (including a whole variety of accessors). So if you don't see a +// function here that you need, please contact Falcon or someone else with SSE +// experience (Richard, I think, has some and davep has a little as of the time  // of this writing, July 08, 2010) about getting it implemented before you resort to -// LLVector3/LLVector4.  +// LLVector3/LLVector4.  /////////////////////////////////  class alignas(16) LLVector4a @@ -52,283 +52,283 @@ class alignas(16) LLVector4a      LL_ALIGN_NEW  public: -	/////////////////////////////////// -	// STATIC METHODS -	/////////////////////////////////// -	 -	// Call initClass() at startup to avoid 15,000+ cycle penalties from denormalized numbers -	static void initClass() -	{ -		_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); -		_MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST); -	} - -	// Return a vector of all zeros -	static inline const LLVector4a& getZero() -	{ -		extern const LLVector4a LL_V4A_ZERO; -		return LL_V4A_ZERO; -	} -	 -	// Return a vector of all epsilon, where epsilon is a small float suitable for approximate equality checks -	static inline const LLVector4a& getEpsilon() -	{ -		extern const LLVector4a LL_V4A_EPSILON; -		return LL_V4A_EPSILON; -	} - -	// Copy 16 bytes from src to dst. Source and destination must be 16-byte aligned -	static inline void copy4a(F32* dst, const F32* src) -	{ -		_mm_store_ps(dst, _mm_load_ps(src)); -	} - -	// Copy words 16-byte blocks from src to dst. Source and destination must not overlap.  -	// Source and dest must be 16-byte aligned and size must be multiple of 16. -	static void memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes); - -	//////////////////////////////////// -	// CONSTRUCTORS  -	//////////////////////////////////// -	 -	//LLVector4a is plain data which should never have a default constructor or destructor(malloc&free won't trigger it) -	LLVector4a() -	{ //DO NOT INITIALIZE -- The overhead is completely unnecessary -		ll_assert_aligned(this,16); -	} -	 -	LLVector4a(F32 x, F32 y, F32 z, F32 w = 0.f) -	{ -		set(x,y,z,w); -	} -	 -	LLVector4a(F32 x) -	{ -		splat(x); -	} -	 -	LLVector4a(const LLSimdScalar& x) -	{ -		splat(x); -	} - -	LLVector4a(LLQuad q) -	{ -		mQ = q; -	} - -	//////////////////////////////////// -	// LOAD/STORE -	//////////////////////////////////// -	 -	// Load from 16-byte aligned src array (preferred method of loading) -	inline void load4a(const F32* src); -	 -	// Load from unaligned src array (NB: Significantly slower than load4a) -	inline void loadua(const F32* src); -	 -	// Load only three floats beginning at address 'src'. Slowest method. -	inline void load3(const F32* src); -	 -	// Store to a 16-byte aligned memory address -	inline void store4a(F32* dst) const; -	 -	//////////////////////////////////// -	// BASIC GET/SET  -	//////////////////////////////////// -	 -	// Return a "this" as an F32 pointer. -	inline F32* getF32ptr(); -	 -	// Return a "this" as a const F32 pointer. -	inline const F32* const getF32ptr() const; -	 -	// Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates -	// the data at the whole vector level or you will incur a substantial penalty. Consider using the splat functions instead -	inline F32 operator[](const S32 idx) const; - -	// Prefer this method for read-only access to a single element. Prefer the templated version if the elem is known at compile time. -	inline LLSimdScalar getScalarAt(const S32 idx) const; - -	// Prefer this method for read-only access to a single element. Prefer the templated version if the elem is known at compile time. -	template <int N> LL_FORCE_INLINE LLSimdScalar getScalarAt() const; - -	// Set to an x, y, z and optional w provided -	inline void set(F32 x, F32 y, F32 z, F32 w = 0.f); -	 -	// Set to all zeros. This is preferred to using ::getZero() -	inline void clear(); -	 -	// Set all elements to 'x' -	inline void splat(const F32 x); - -	// Set all elements to 'x' -	inline void splat(const LLSimdScalar& x); -	 -	// Set all 4 elements to element N of src, with N known at compile time -	template <int N> void splat(const LLVector4a& src); -	 -	// Set all 4 elements to element i of v, with i NOT known at compile time -	inline void splat(const LLVector4a& v, U32 i); -	 -	// Select bits from sourceIfTrue and sourceIfFalse according to bits in mask -	inline void setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse ); -	 -	//////////////////////////////////// -	// ALGEBRAIC -	//////////////////////////////////// -	 -	// Set this to the element-wise (a + b) -	inline void setAdd(const LLVector4a& a, const LLVector4a& b); -	 -	// Set this to element-wise (a - b) -	inline void setSub(const LLVector4a& a, const LLVector4a& b); -	 -	// Set this to element-wise multiply (a * b) -	inline void setMul(const LLVector4a& a, const LLVector4a& b); -	 -	// Set this to element-wise quotient (a / b) -	inline void setDiv(const LLVector4a& a, const LLVector4a& b); -	 -	// Set this to the element-wise absolute value of src -	inline void setAbs(const LLVector4a& src); -	 -	// Add to each component in this vector the corresponding component in rhs -	inline void add(const LLVector4a& rhs); -	 -	// Subtract from each component in this vector the corresponding component in rhs -	inline void sub(const LLVector4a& rhs); -	 -	// Multiply each component in this vector by the corresponding component in rhs -	inline void mul(const LLVector4a& rhs); -	 -	// Divide each component in this vector by the corresponding component in rhs -	inline void div(const LLVector4a& rhs); -	 -	// Multiply this vector by x in a scalar fashion -	inline void mul(const F32 x); - -	// Set this to (a x b) (geometric cross-product) -	inline void setCross3(const LLVector4a& a, const LLVector4a& b); -	 -	// Set all elements to the dot product of the x, y, and z elements in a and b -	inline void setAllDot3(const LLVector4a& a, const LLVector4a& b); - -	// Set all elements to the dot product of the x, y, z, and w elements in a and b -	inline void setAllDot4(const LLVector4a& a, const LLVector4a& b); - -	// Return the 3D dot product of this vector and b -	inline LLSimdScalar dot3(const LLVector4a& b) const; - -	// Return the 4D dot product of this vector and b -	inline LLSimdScalar dot4(const LLVector4a& b) const; - -	// Normalize this vector with respect to the x, y, and z components only. Accurate to 22 bites of precision. W component is destroyed -	// Note that this does not consider zero length vectors! -	inline void normalize3(); - -	// Same as normalize3() but with respect to all 4 components -	inline void normalize4(); - -	// Same as normalize3(), but returns length as a SIMD scalar -	inline LLSimdScalar normalize3withLength(); - -	// Normalize this vector with respect to the x, y, and z components only. Accurate only to 10-12 bits of precision. W component is destroyed -	// Note that this does not consider zero length vectors! -	inline void normalize3fast(); - -	// Normalize this vector with respect to the x, y, and z components only. Accurate only to 10-12 bits of precision. W component is destroyed -	// Same as above except substitutes default vector contents if the vector is non-finite or degenerate due to zero length. -	// -	inline void normalize3fast_checked(LLVector4a* d = 0); - -	// Return true if this vector is normalized with respect to x,y,z up to tolerance -	inline LLBool32 isNormalized3( F32 tolerance = 1e-3 ) const; - -	// Return true if this vector is normalized with respect to all components up to tolerance -	inline LLBool32 isNormalized4( F32 tolerance = 1e-3 ) const; - -	// Set all elements to the length of vector 'v'  -	inline void setAllLength3( const LLVector4a& v ); - -	// Get this vector's length -	inline LLSimdScalar getLength3() const; -	 -	// Set the components of this vector to the minimum of the corresponding components of lhs and rhs -	inline void setMin(const LLVector4a& lhs, const LLVector4a& rhs); -	 -	// Set the components of this vector to the maximum of the corresponding components of lhs and rhs -	inline void setMax(const LLVector4a& lhs, const LLVector4a& rhs); -	 -	// Clamps this vector to be within the component-wise range low to high (inclusive) -	inline void clamp( const LLVector4a& low, const LLVector4a& high ); - -	// Set this to  (c * lhs) + rhs * ( 1 - c) -	inline void setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F32 c); -	 -	// Return true (nonzero) if x, y, z (and w for Finite4) are all finite floats -	inline LLBool32 isFinite3() const;	 -	inline LLBool32 isFinite4() const; - -	// Set this vector to 'vec' rotated by the LLRotation or LLQuaternion2 provided -	void setRotated( const LLRotation& rot, const LLVector4a& vec ); -	void setRotated( const class LLQuaternion2& quat, const LLVector4a& vec ); - -	// Set this vector to 'vec' rotated by the INVERSE of the LLRotation or LLQuaternion2 provided -	inline void setRotatedInv( const LLRotation& rot, const LLVector4a& vec ); -	inline void setRotatedInv( const class LLQuaternion2& quat, const LLVector4a& vec ); - -	// Quantize this vector to 8 or 16 bit precision -	void quantize8( const LLVector4a& low, const LLVector4a& high ); -	void quantize16( const LLVector4a& low, const LLVector4a& high ); - -	//////////////////////////////////// -	// LOGICAL -	////////////////////////////////////	 -	// The functions in this section will compare the elements in this vector -	// to those in rhs and return an LLVector4Logical with all bits set in elements -	// where the comparison was true and all bits unset in elements where the comparison -	// was false. See llvector4logica.h -	//////////////////////////////////// -	// WARNING: Other than equals3 and equals4, these functions do NOT account -	// for floating point tolerance. You should include the appropriate tolerance -	// in the inputs. -	//////////////////////////////////// -	 -	inline LLVector4Logical greaterThan(const LLVector4a& rhs) const; - -	inline LLVector4Logical lessThan(const LLVector4a& rhs) const; -	 -	inline LLVector4Logical greaterEqual(const LLVector4a& rhs) const; - -	inline LLVector4Logical lessEqual(const LLVector4a& rhs) const; -	 -	inline LLVector4Logical equal(const LLVector4a& rhs) const; - -	// Returns true if this and rhs are componentwise equal up to the specified absolute tolerance -	inline bool equals4(const LLVector4a& rhs, F32 tolerance = F_APPROXIMATELY_ZERO ) const; - -	inline bool equals3(const LLVector4a& rhs, F32 tolerance = F_APPROXIMATELY_ZERO ) const; - -	//////////////////////////////////// -	// OPERATORS -	////////////////////////////////////	 -	 -	// Do NOT add aditional operators without consulting someone with SSE experience -	inline const LLVector4a& operator= ( const LLVector4a& rhs ); -	 -	inline const LLVector4a& operator= ( const LLQuad& rhs ); - -	inline operator LLQuad() const;	 -     +    /////////////////////////////////// +    // STATIC METHODS +    /////////////////////////////////// + +    // Call initClass() at startup to avoid 15,000+ cycle penalties from denormalized numbers +    static void initClass() +    { +        _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); +        _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST); +    } + +    // Return a vector of all zeros +    static inline const LLVector4a& getZero() +    { +        extern const LLVector4a LL_V4A_ZERO; +        return LL_V4A_ZERO; +    } + +    // Return a vector of all epsilon, where epsilon is a small float suitable for approximate equality checks +    static inline const LLVector4a& getEpsilon() +    { +        extern const LLVector4a LL_V4A_EPSILON; +        return LL_V4A_EPSILON; +    } + +    // Copy 16 bytes from src to dst. Source and destination must be 16-byte aligned +    static inline void copy4a(F32* dst, const F32* src) +    { +        _mm_store_ps(dst, _mm_load_ps(src)); +    } + +    // Copy words 16-byte blocks from src to dst. Source and destination must not overlap. +    // Source and dest must be 16-byte aligned and size must be multiple of 16. +    static void memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes); + +    //////////////////////////////////// +    // CONSTRUCTORS +    //////////////////////////////////// + +    //LLVector4a is plain data which should never have a default constructor or destructor(malloc&free won't trigger it) +    LLVector4a() +    { //DO NOT INITIALIZE -- The overhead is completely unnecessary +        ll_assert_aligned(this,16); +    } + +    LLVector4a(F32 x, F32 y, F32 z, F32 w = 0.f) +    { +        set(x,y,z,w); +    } + +    LLVector4a(F32 x) +    { +        splat(x); +    } + +    LLVector4a(const LLSimdScalar& x) +    { +        splat(x); +    } + +    LLVector4a(LLQuad q) +    { +        mQ = q; +    } + +    //////////////////////////////////// +    // LOAD/STORE +    //////////////////////////////////// + +    // Load from 16-byte aligned src array (preferred method of loading) +    inline void load4a(const F32* src); + +    // Load from unaligned src array (NB: Significantly slower than load4a) +    inline void loadua(const F32* src); + +    // Load only three floats beginning at address 'src'. Slowest method. +    inline void load3(const F32* src); + +    // Store to a 16-byte aligned memory address +    inline void store4a(F32* dst) const; + +    //////////////////////////////////// +    // BASIC GET/SET +    //////////////////////////////////// + +    // Return a "this" as an F32 pointer. +    inline F32* getF32ptr(); + +    // Return a "this" as a const F32 pointer. +    inline const F32* const getF32ptr() const; + +    // Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates +    // the data at the whole vector level or you will incur a substantial penalty. Consider using the splat functions instead +    inline F32 operator[](const S32 idx) const; + +    // Prefer this method for read-only access to a single element. Prefer the templated version if the elem is known at compile time. +    inline LLSimdScalar getScalarAt(const S32 idx) const; + +    // Prefer this method for read-only access to a single element. Prefer the templated version if the elem is known at compile time. +    template <int N> LL_FORCE_INLINE LLSimdScalar getScalarAt() const; + +    // Set to an x, y, z and optional w provided +    inline void set(F32 x, F32 y, F32 z, F32 w = 0.f); + +    // Set to all zeros. This is preferred to using ::getZero() +    inline void clear(); + +    // Set all elements to 'x' +    inline void splat(const F32 x); + +    // Set all elements to 'x' +    inline void splat(const LLSimdScalar& x); + +    // Set all 4 elements to element N of src, with N known at compile time +    template <int N> void splat(const LLVector4a& src); + +    // Set all 4 elements to element i of v, with i NOT known at compile time +    inline void splat(const LLVector4a& v, U32 i); + +    // Select bits from sourceIfTrue and sourceIfFalse according to bits in mask +    inline void setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse ); + +    //////////////////////////////////// +    // ALGEBRAIC +    //////////////////////////////////// + +    // Set this to the element-wise (a + b) +    inline void setAdd(const LLVector4a& a, const LLVector4a& b); + +    // Set this to element-wise (a - b) +    inline void setSub(const LLVector4a& a, const LLVector4a& b); + +    // Set this to element-wise multiply (a * b) +    inline void setMul(const LLVector4a& a, const LLVector4a& b); + +    // Set this to element-wise quotient (a / b) +    inline void setDiv(const LLVector4a& a, const LLVector4a& b); + +    // Set this to the element-wise absolute value of src +    inline void setAbs(const LLVector4a& src); + +    // Add to each component in this vector the corresponding component in rhs +    inline void add(const LLVector4a& rhs); + +    // Subtract from each component in this vector the corresponding component in rhs +    inline void sub(const LLVector4a& rhs); + +    // Multiply each component in this vector by the corresponding component in rhs +    inline void mul(const LLVector4a& rhs); + +    // Divide each component in this vector by the corresponding component in rhs +    inline void div(const LLVector4a& rhs); + +    // Multiply this vector by x in a scalar fashion +    inline void mul(const F32 x); + +    // Set this to (a x b) (geometric cross-product) +    inline void setCross3(const LLVector4a& a, const LLVector4a& b); + +    // Set all elements to the dot product of the x, y, and z elements in a and b +    inline void setAllDot3(const LLVector4a& a, const LLVector4a& b); + +    // Set all elements to the dot product of the x, y, z, and w elements in a and b +    inline void setAllDot4(const LLVector4a& a, const LLVector4a& b); + +    // Return the 3D dot product of this vector and b +    inline LLSimdScalar dot3(const LLVector4a& b) const; + +    // Return the 4D dot product of this vector and b +    inline LLSimdScalar dot4(const LLVector4a& b) const; + +    // Normalize this vector with respect to the x, y, and z components only. Accurate to 22 bites of precision. W component is destroyed +    // Note that this does not consider zero length vectors! +    inline void normalize3(); + +    // Same as normalize3() but with respect to all 4 components +    inline void normalize4(); + +    // Same as normalize3(), but returns length as a SIMD scalar +    inline LLSimdScalar normalize3withLength(); + +    // Normalize this vector with respect to the x, y, and z components only. Accurate only to 10-12 bits of precision. W component is destroyed +    // Note that this does not consider zero length vectors! +    inline void normalize3fast(); + +    // Normalize this vector with respect to the x, y, and z components only. Accurate only to 10-12 bits of precision. W component is destroyed +    // Same as above except substitutes default vector contents if the vector is non-finite or degenerate due to zero length. +    // +    inline void normalize3fast_checked(LLVector4a* d = 0); + +    // Return true if this vector is normalized with respect to x,y,z up to tolerance +    inline LLBool32 isNormalized3( F32 tolerance = 1e-3 ) const; + +    // Return true if this vector is normalized with respect to all components up to tolerance +    inline LLBool32 isNormalized4( F32 tolerance = 1e-3 ) const; + +    // Set all elements to the length of vector 'v' +    inline void setAllLength3( const LLVector4a& v ); + +    // Get this vector's length +    inline LLSimdScalar getLength3() const; + +    // Set the components of this vector to the minimum of the corresponding components of lhs and rhs +    inline void setMin(const LLVector4a& lhs, const LLVector4a& rhs); + +    // Set the components of this vector to the maximum of the corresponding components of lhs and rhs +    inline void setMax(const LLVector4a& lhs, const LLVector4a& rhs); + +    // Clamps this vector to be within the component-wise range low to high (inclusive) +    inline void clamp( const LLVector4a& low, const LLVector4a& high ); + +    // Set this to  (c * lhs) + rhs * ( 1 - c) +    inline void setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F32 c); + +    // Return true (nonzero) if x, y, z (and w for Finite4) are all finite floats +    inline LLBool32 isFinite3() const; +    inline LLBool32 isFinite4() const; + +    // Set this vector to 'vec' rotated by the LLRotation or LLQuaternion2 provided +    void setRotated( const LLRotation& rot, const LLVector4a& vec ); +    void setRotated( const class LLQuaternion2& quat, const LLVector4a& vec ); + +    // Set this vector to 'vec' rotated by the INVERSE of the LLRotation or LLQuaternion2 provided +    inline void setRotatedInv( const LLRotation& rot, const LLVector4a& vec ); +    inline void setRotatedInv( const class LLQuaternion2& quat, const LLVector4a& vec ); + +    // Quantize this vector to 8 or 16 bit precision +    void quantize8( const LLVector4a& low, const LLVector4a& high ); +    void quantize16( const LLVector4a& low, const LLVector4a& high ); + +    //////////////////////////////////// +    // LOGICAL +    //////////////////////////////////// +    // The functions in this section will compare the elements in this vector +    // to those in rhs and return an LLVector4Logical with all bits set in elements +    // where the comparison was true and all bits unset in elements where the comparison +    // was false. See llvector4logica.h +    //////////////////////////////////// +    // WARNING: Other than equals3 and equals4, these functions do NOT account +    // for floating point tolerance. You should include the appropriate tolerance +    // in the inputs. +    //////////////////////////////////// + +    inline LLVector4Logical greaterThan(const LLVector4a& rhs) const; + +    inline LLVector4Logical lessThan(const LLVector4a& rhs) const; + +    inline LLVector4Logical greaterEqual(const LLVector4a& rhs) const; + +    inline LLVector4Logical lessEqual(const LLVector4a& rhs) const; + +    inline LLVector4Logical equal(const LLVector4a& rhs) const; + +    // Returns true if this and rhs are componentwise equal up to the specified absolute tolerance +    inline bool equals4(const LLVector4a& rhs, F32 tolerance = F_APPROXIMATELY_ZERO ) const; + +    inline bool equals3(const LLVector4a& rhs, F32 tolerance = F_APPROXIMATELY_ZERO ) const; + +    //////////////////////////////////// +    // OPERATORS +    //////////////////////////////////// + +    // Do NOT add aditional operators without consulting someone with SSE experience +    inline const LLVector4a& operator= ( const LLVector4a& rhs ); + +    inline const LLVector4a& operator= ( const LLQuad& rhs ); + +    inline operator LLQuad() const; +  private: -	LLQuad mQ; +    LLQuad mQ;  };  inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p)  { -	min.setMin(min, p); -	max.setMax(max, p); +    min.setMin(min, p); +    max.setMax(max, p);  }  inline std::ostream& operator<<(std::ostream& s, const LLVector4a& v) diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl index 8be1c1b114..36dbec078c 100644 --- a/indra/llmath/llvector4a.inl +++ b/indra/llmath/llvector4a.inl @@ -1,25 +1,25 @@ -/**  +/**   * @file llvector4a.inl   * @brief LLVector4a inline function implementations   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -31,138 +31,138 @@  // Load from 16-byte aligned src array (preferred method of loading)  inline void LLVector4a::load4a(const F32* src)  { -	mQ = _mm_load_ps(src); +    mQ = _mm_load_ps(src);  }  // Load from unaligned src array (NB: Significantly slower than load4a)  inline void LLVector4a::loadua(const F32* src)  { -	mQ = _mm_loadu_ps(src); +    mQ = _mm_loadu_ps(src);  }  // Load only three floats beginning at address 'src'. Slowest method.  inline void LLVector4a::load3(const F32* src)  { -	// mQ = { 0.f, src[2], src[1], src[0] } = { W, Z, Y, X } -	// NB: This differs from the convention of { Z, Y, X, W } -	mQ = _mm_set_ps(0.f, src[2], src[1], src[0]); -}	 +    // mQ = { 0.f, src[2], src[1], src[0] } = { W, Z, Y, X } +    // NB: This differs from the convention of { Z, Y, X, W } +    mQ = _mm_set_ps(0.f, src[2], src[1], src[0]); +}  // Store to a 16-byte aligned memory address  inline void LLVector4a::store4a(F32* dst) const  { -	_mm_store_ps(dst, mQ); +    _mm_store_ps(dst, mQ);  }  //////////////////////////////////// -// BASIC GET/SET  +// BASIC GET/SET  ////////////////////////////////////  // Return a "this" as an F32 pointer.  F32* LLVector4a::getF32ptr()  { -	return (F32*) &mQ; +    return (F32*) &mQ;  }  // Return a "this" as a const F32 pointer.  const F32* const LLVector4a::getF32ptr() const  { -	return (const F32* const) &mQ; +    return (const F32* const) &mQ;  }  // Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates  // the data at the whole vector level or you will incur a substantial penalty. Consider using the splat functions instead  inline F32 LLVector4a::operator[](const S32 idx) const  { -	return ((F32*)&mQ)[idx]; -}	 +    return ((F32*)&mQ)[idx]; +}  // Prefer this method for read-only access to a single element. Prefer the templated version if the elem is known at compile time.  inline LLSimdScalar LLVector4a::getScalarAt(const S32 idx) const  { -	// Return appropriate LLQuad. It will be cast to LLSimdScalar automatically (should be effectively a nop) -	switch (idx) -	{ -		case 0: -			return mQ; -		case 1: -			return _mm_shuffle_ps(mQ, mQ, _MM_SHUFFLE(1, 1, 1, 1)); -		case 2: -			return _mm_shuffle_ps(mQ, mQ, _MM_SHUFFLE(2, 2, 2, 2)); -		case 3: -		default: -			return _mm_shuffle_ps(mQ, mQ, _MM_SHUFFLE(3, 3, 3, 3)); -	} +    // Return appropriate LLQuad. It will be cast to LLSimdScalar automatically (should be effectively a nop) +    switch (idx) +    { +        case 0: +            return mQ; +        case 1: +            return _mm_shuffle_ps(mQ, mQ, _MM_SHUFFLE(1, 1, 1, 1)); +        case 2: +            return _mm_shuffle_ps(mQ, mQ, _MM_SHUFFLE(2, 2, 2, 2)); +        case 3: +        default: +            return _mm_shuffle_ps(mQ, mQ, _MM_SHUFFLE(3, 3, 3, 3)); +    }  }  // Prefer this method for read-only access to a single element. Prefer the templated version if the elem is known at compile time.  template <int N> LL_FORCE_INLINE LLSimdScalar LLVector4a::getScalarAt() const  { -	return _mm_shuffle_ps(mQ, mQ, _MM_SHUFFLE(N, N, N, N)); +    return _mm_shuffle_ps(mQ, mQ, _MM_SHUFFLE(N, N, N, N));  }  template<> LL_FORCE_INLINE LLSimdScalar LLVector4a::getScalarAt<0>() const  { -	return mQ; +    return mQ;  }  // Set to an x, y, z and optional w provided  inline void LLVector4a::set(F32 x, F32 y, F32 z, F32 w)  { -	mQ = _mm_set_ps(w, z, y, x); +    mQ = _mm_set_ps(w, z, y, x);  }  // Set to all zeros  inline void LLVector4a::clear()  { -	mQ = LLVector4a::getZero().mQ; +    mQ = LLVector4a::getZero().mQ;  }  inline void LLVector4a::splat(const F32 x)  { -	mQ = _mm_set1_ps(x);	 +    mQ = _mm_set1_ps(x);  }  inline void LLVector4a::splat(const LLSimdScalar& x)  { -	mQ = _mm_shuffle_ps( x.getQuad(), x.getQuad(), _MM_SHUFFLE(0,0,0,0) ); +    mQ = _mm_shuffle_ps( x.getQuad(), x.getQuad(), _MM_SHUFFLE(0,0,0,0) );  }  // Set all 4 elements to element N of src, with N known at compile time  template <int N> void LLVector4a::splat(const LLVector4a& src)  { -	mQ = _mm_shuffle_ps(src.mQ, src.mQ, _MM_SHUFFLE(N, N, N, N) ); +    mQ = _mm_shuffle_ps(src.mQ, src.mQ, _MM_SHUFFLE(N, N, N, N) );  }  // Set all 4 elements to element i of v, with i NOT known at compile time  inline void LLVector4a::splat(const LLVector4a& v, U32 i)  { -	switch (i) -	{ -		case 0: -			mQ = _mm_shuffle_ps(v.mQ, v.mQ, _MM_SHUFFLE(0, 0, 0, 0)); -			break; -		case 1: -			mQ = _mm_shuffle_ps(v.mQ, v.mQ, _MM_SHUFFLE(1, 1, 1, 1)); -			break; -		case 2: -			mQ = _mm_shuffle_ps(v.mQ, v.mQ, _MM_SHUFFLE(2, 2, 2, 2)); -			break; -		case 3: -			mQ = _mm_shuffle_ps(v.mQ, v.mQ, _MM_SHUFFLE(3, 3, 3, 3)); -			break; -	} +    switch (i) +    { +        case 0: +            mQ = _mm_shuffle_ps(v.mQ, v.mQ, _MM_SHUFFLE(0, 0, 0, 0)); +            break; +        case 1: +            mQ = _mm_shuffle_ps(v.mQ, v.mQ, _MM_SHUFFLE(1, 1, 1, 1)); +            break; +        case 2: +            mQ = _mm_shuffle_ps(v.mQ, v.mQ, _MM_SHUFFLE(2, 2, 2, 2)); +            break; +        case 3: +            mQ = _mm_shuffle_ps(v.mQ, v.mQ, _MM_SHUFFLE(3, 3, 3, 3)); +            break; +    }  }  // Select bits from sourceIfTrue and sourceIfFalse according to bits in mask  inline void LLVector4a::setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse )  { -	// ((( sourceIfTrue ^ sourceIfFalse ) & mask) ^ sourceIfFalse ) -	// E.g., sourceIfFalse = 1010b, sourceIfTrue = 0101b, mask = 1100b -	// (sourceIfTrue ^ sourceIfFalse) = 1111b --> & mask = 1100b --> ^ sourceIfFalse = 0110b,  -	// as expected (01 from sourceIfTrue, 10 from sourceIfFalse) -	// Courtesy of Mark++, http://markplusplus.wordpress.com/2007/03/14/fast-sse-select-operation/ -	mQ = _mm_xor_ps( sourceIfFalse, _mm_and_ps( mask, _mm_xor_ps( sourceIfTrue, sourceIfFalse ) ) ); +    // ((( sourceIfTrue ^ sourceIfFalse ) & mask) ^ sourceIfFalse ) +    // E.g., sourceIfFalse = 1010b, sourceIfTrue = 0101b, mask = 1100b +    // (sourceIfTrue ^ sourceIfFalse) = 1111b --> & mask = 1100b --> ^ sourceIfFalse = 0110b, +    // as expected (01 from sourceIfTrue, 10 from sourceIfFalse) +    // Courtesy of Mark++, http://markplusplus.wordpress.com/2007/03/14/fast-sse-select-operation/ +    mQ = _mm_xor_ps( sourceIfFalse, _mm_and_ps( mask, _mm_xor_ps( sourceIfTrue, sourceIfFalse ) ) );  }  //////////////////////////////////// @@ -172,84 +172,84 @@ inline void LLVector4a::setSelectWithMask( const LLVector4Logical& mask, const L  // Set this to the element-wise (a + b)  inline void LLVector4a::setAdd(const LLVector4a& a, const LLVector4a& b)  { -	mQ = _mm_add_ps(a.mQ, b.mQ); +    mQ = _mm_add_ps(a.mQ, b.mQ);  }  // Set this to element-wise (a - b)  inline void LLVector4a::setSub(const LLVector4a& a, const LLVector4a& b)  { -	mQ = _mm_sub_ps(a.mQ, b.mQ); +    mQ = _mm_sub_ps(a.mQ, b.mQ);  }  // Set this to element-wise multiply (a * b)  inline void LLVector4a::setMul(const LLVector4a& a, const LLVector4a& b)  { -	mQ = _mm_mul_ps(a.mQ, b.mQ); +    mQ = _mm_mul_ps(a.mQ, b.mQ);  }  // Set this to element-wise quotient (a / b)  inline void LLVector4a::setDiv(const LLVector4a& a, const LLVector4a& b)  { -	mQ = _mm_div_ps( a.mQ, b.mQ ); +    mQ = _mm_div_ps( a.mQ, b.mQ );  }  // Set this to the element-wise absolute value of src  inline void LLVector4a::setAbs(const LLVector4a& src)  { -	static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; -	mQ = _mm_and_ps(src.mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A)); +    static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; +    mQ = _mm_and_ps(src.mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A));  }  // Add to each component in this vector the corresponding component in rhs  inline void LLVector4a::add(const LLVector4a& rhs)  { -	mQ = _mm_add_ps(mQ, rhs.mQ);	 +    mQ = _mm_add_ps(mQ, rhs.mQ);  }  // Subtract from each component in this vector the corresponding component in rhs  inline void LLVector4a::sub(const LLVector4a& rhs)  { -	mQ = _mm_sub_ps(mQ, rhs.mQ); +    mQ = _mm_sub_ps(mQ, rhs.mQ);  }  // Multiply each component in this vector by the corresponding component in rhs  inline void LLVector4a::mul(const LLVector4a& rhs)  { -	mQ = _mm_mul_ps(mQ, rhs.mQ);	 +    mQ = _mm_mul_ps(mQ, rhs.mQ);  }  // Divide each component in this vector by the corresponding component in rhs  inline void LLVector4a::div(const LLVector4a& rhs)  { -	// TODO: Check accuracy, maybe add divFast -	mQ = _mm_div_ps(mQ, rhs.mQ); +    // TODO: Check accuracy, maybe add divFast +    mQ = _mm_div_ps(mQ, rhs.mQ);  }  // Multiply this vector by x in a scalar fashion -inline void LLVector4a::mul(const F32 x)  +inline void LLVector4a::mul(const F32 x)  { -	LLVector4a t; -	t.splat(x); -	 -	mQ = _mm_mul_ps(mQ, t.mQ); +    LLVector4a t; +    t.splat(x); + +    mQ = _mm_mul_ps(mQ, t.mQ);  }  // Set this to (a x b) (geometric cross-product)  inline void LLVector4a::setCross3(const LLVector4a& a, const LLVector4a& b)  { -	// Vectors are stored in memory in w, z, y, x order from high to low -	// Set vector1 = { a[W], a[X], a[Z], a[Y] } -	const LLQuad vector1 = _mm_shuffle_ps( a.mQ, a.mQ, _MM_SHUFFLE( 3, 0, 2, 1 )); -	// Set vector2 = { b[W], b[Y], b[X], b[Z] } -	const LLQuad vector2 = _mm_shuffle_ps( b.mQ, b.mQ, _MM_SHUFFLE( 3, 1, 0, 2 )); -	// mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] } -	mQ = _mm_mul_ps( vector1, vector2 ); -	// vector3 = { a[W], a[Y], a[X], a[Z] } -	const LLQuad vector3 = _mm_shuffle_ps( a.mQ, a.mQ, _MM_SHUFFLE( 3, 1, 0, 2 )); -	// vector4 = { b[W], b[X], b[Z], b[Y] } -	const LLQuad vector4 = _mm_shuffle_ps( b.mQ, b.mQ, _MM_SHUFFLE( 3, 0, 2, 1 )); -	// mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] } -	mQ = _mm_sub_ps( mQ, _mm_mul_ps( vector3, vector4 )); +    // Vectors are stored in memory in w, z, y, x order from high to low +    // Set vector1 = { a[W], a[X], a[Z], a[Y] } +    const LLQuad vector1 = _mm_shuffle_ps( a.mQ, a.mQ, _MM_SHUFFLE( 3, 0, 2, 1 )); +    // Set vector2 = { b[W], b[Y], b[X], b[Z] } +    const LLQuad vector2 = _mm_shuffle_ps( b.mQ, b.mQ, _MM_SHUFFLE( 3, 1, 0, 2 )); +    // mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] } +    mQ = _mm_mul_ps( vector1, vector2 ); +    // vector3 = { a[W], a[Y], a[X], a[Z] } +    const LLQuad vector3 = _mm_shuffle_ps( a.mQ, a.mQ, _MM_SHUFFLE( 3, 1, 0, 2 )); +    // vector4 = { b[W], b[X], b[Z], b[Y] } +    const LLQuad vector4 = _mm_shuffle_ps( b.mQ, b.mQ, _MM_SHUFFLE( 3, 0, 2, 1 )); +    // mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] } +    mQ = _mm_sub_ps( mQ, _mm_mul_ps( vector3, vector4 ));  }  /* This function works, but may be slightly slower than the one below on older machines @@ -261,7 +261,7 @@ inline void LLVector4a::setCross3(const LLVector4a& a, const LLVector4a& b)   const LLQuad wzxy = _mm_shuffle_ps( ab, ab, _MM_SHUFFLE(3, 2, 0, 1 ));   // xPlusY = { 2*a[W]*b[W], 2 * a[Z] * b[Z], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] }   const LLQuad xPlusY = _mm_add_ps(ab, wzxy); - // xPlusYSplat = { a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] }  + // xPlusYSplat = { a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] }   const LLQuad xPlusYSplat = _mm_movelh_ps(xPlusY, xPlusY);   // zSplat = { a[Z]*b[Z], a[Z]*b[Z], a[Z]*b[Z], a[Z]*b[Z] }   const LLQuad zSplat = _mm_shuffle_ps( ab, ab, _MM_SHUFFLE( 2, 2, 2, 2 )); @@ -272,267 +272,267 @@ inline void LLVector4a::setCross3(const LLVector4a& a, const LLVector4a& b)  // Set all elements to the dot product of the x, y, and z elements in a and b  inline void LLVector4a::setAllDot3(const LLVector4a& a, const LLVector4a& b)  { -	// ab = { a[W]*b[W], a[Z]*b[Z], a[Y]*b[Y], a[X]*b[X] } -	const LLQuad ab = _mm_mul_ps( a.mQ, b.mQ ); -	// yzxw = { a[W]*b[W], a[Z]*b[Z], a[X]*b[X], a[Y]*b[Y] } -	const __m128i wzxy = _mm_shuffle_epi32(_mm_castps_si128(ab), _MM_SHUFFLE(3, 2, 0, 1 )); -	// xPlusY = { 2*a[W]*b[W], 2 * a[Z] * b[Z], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] } -	const LLQuad xPlusY = _mm_add_ps(ab, _mm_castsi128_ps(wzxy)); -	// xPlusYSplat = { a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] }  -	const LLQuad xPlusYSplat = _mm_movelh_ps(xPlusY, xPlusY); -	// zSplat = { a[Z]*b[Z], a[Z]*b[Z], a[Z]*b[Z], a[Z]*b[Z] } -	const __m128i zSplat = _mm_shuffle_epi32(_mm_castps_si128(ab), _MM_SHUFFLE( 2, 2, 2, 2 )); -	// mQ = { a[Z] * b[Z] + a[Y] * b[Y] + a[X] * b[X], same, same, same } -	mQ = _mm_add_ps(_mm_castsi128_ps(zSplat), xPlusYSplat); +    // ab = { a[W]*b[W], a[Z]*b[Z], a[Y]*b[Y], a[X]*b[X] } +    const LLQuad ab = _mm_mul_ps( a.mQ, b.mQ ); +    // yzxw = { a[W]*b[W], a[Z]*b[Z], a[X]*b[X], a[Y]*b[Y] } +    const __m128i wzxy = _mm_shuffle_epi32(_mm_castps_si128(ab), _MM_SHUFFLE(3, 2, 0, 1 )); +    // xPlusY = { 2*a[W]*b[W], 2 * a[Z] * b[Z], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] } +    const LLQuad xPlusY = _mm_add_ps(ab, _mm_castsi128_ps(wzxy)); +    // xPlusYSplat = { a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] } +    const LLQuad xPlusYSplat = _mm_movelh_ps(xPlusY, xPlusY); +    // zSplat = { a[Z]*b[Z], a[Z]*b[Z], a[Z]*b[Z], a[Z]*b[Z] } +    const __m128i zSplat = _mm_shuffle_epi32(_mm_castps_si128(ab), _MM_SHUFFLE( 2, 2, 2, 2 )); +    // mQ = { a[Z] * b[Z] + a[Y] * b[Y] + a[X] * b[X], same, same, same } +    mQ = _mm_add_ps(_mm_castsi128_ps(zSplat), xPlusYSplat);  }  // Set all elements to the dot product of the x, y, z, and w elements in a and b  inline void LLVector4a::setAllDot4(const LLVector4a& a, const LLVector4a& b)  { -	// ab = { a[W]*b[W], a[Z]*b[Z], a[Y]*b[Y], a[X]*b[X] } -	const LLQuad ab = _mm_mul_ps( a.mQ, b.mQ ); -	// yzxw = { a[W]*b[W], a[Z]*b[Z], a[X]*b[X], a[Y]*b[Y] } -	const __m128i zwxy = _mm_shuffle_epi32(_mm_castps_si128(ab), _MM_SHUFFLE(2, 3, 0, 1 )); -	// zPlusWandXplusY = { a[W]*b[W] + a[Z]*b[Z], a[Z] * b[Z] + a[W]*b[W], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] } -	const LLQuad zPlusWandXplusY = _mm_add_ps(ab, _mm_castsi128_ps(zwxy)); -	// xPlusYSplat = { a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] }  -	const LLQuad xPlusYSplat = _mm_movelh_ps(zPlusWandXplusY, zPlusWandXplusY); -	const LLQuad zPlusWSplat = _mm_movehl_ps(zPlusWandXplusY, zPlusWandXplusY); +    // ab = { a[W]*b[W], a[Z]*b[Z], a[Y]*b[Y], a[X]*b[X] } +    const LLQuad ab = _mm_mul_ps( a.mQ, b.mQ ); +    // yzxw = { a[W]*b[W], a[Z]*b[Z], a[X]*b[X], a[Y]*b[Y] } +    const __m128i zwxy = _mm_shuffle_epi32(_mm_castps_si128(ab), _MM_SHUFFLE(2, 3, 0, 1 )); +    // zPlusWandXplusY = { a[W]*b[W] + a[Z]*b[Z], a[Z] * b[Z] + a[W]*b[W], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] } +    const LLQuad zPlusWandXplusY = _mm_add_ps(ab, _mm_castsi128_ps(zwxy)); +    // xPlusYSplat = { a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y], a[Y]*b[Y] + a[X] * b[X], a[X] * b[X] + a[Y] * b[Y] } +    const LLQuad xPlusYSplat = _mm_movelh_ps(zPlusWandXplusY, zPlusWandXplusY); +    const LLQuad zPlusWSplat = _mm_movehl_ps(zPlusWandXplusY, zPlusWandXplusY); -	// mQ = { a[W]*b[W] + a[Z] * b[Z] + a[Y] * b[Y] + a[X] * b[X], same, same, same } -	mQ = _mm_add_ps(xPlusYSplat, zPlusWSplat); +    // mQ = { a[W]*b[W] + a[Z] * b[Z] + a[Y] * b[Y] + a[X] * b[X], same, same, same } +    mQ = _mm_add_ps(xPlusYSplat, zPlusWSplat);  }  // Return the 3D dot product of this vector and b  inline LLSimdScalar LLVector4a::dot3(const LLVector4a& b) const  { -	const LLQuad ab = _mm_mul_ps( mQ, b.mQ ); -	const LLQuad splatY = _mm_castsi128_ps( _mm_shuffle_epi32( _mm_castps_si128(ab), _MM_SHUFFLE(1, 1, 1, 1) ) ); -	const LLQuad splatZ = _mm_castsi128_ps( _mm_shuffle_epi32( _mm_castps_si128(ab), _MM_SHUFFLE(2, 2, 2, 2) ) ); -	const LLQuad xPlusY = _mm_add_ps( ab, splatY ); -	return _mm_add_ps( xPlusY, splatZ );	 +    const LLQuad ab = _mm_mul_ps( mQ, b.mQ ); +    const LLQuad splatY = _mm_castsi128_ps( _mm_shuffle_epi32( _mm_castps_si128(ab), _MM_SHUFFLE(1, 1, 1, 1) ) ); +    const LLQuad splatZ = _mm_castsi128_ps( _mm_shuffle_epi32( _mm_castps_si128(ab), _MM_SHUFFLE(2, 2, 2, 2) ) ); +    const LLQuad xPlusY = _mm_add_ps( ab, splatY ); +    return _mm_add_ps( xPlusY, splatZ );  }  // Return the 4D dot product of this vector and b  inline LLSimdScalar LLVector4a::dot4(const LLVector4a& b) const  { -	// ab = { w, z, y, x } - 	const LLQuad ab = _mm_mul_ps( mQ, b.mQ ); - 	// upperProdsInLowerElems = { y, x, y, x } -	const LLQuad upperProdsInLowerElems = _mm_movehl_ps( ab, ab ); -	// sumOfPairs = { w+y, z+x, 2y, 2x } - 	const LLQuad sumOfPairs = _mm_add_ps( upperProdsInLowerElems, ab ); -	// shuffled = { z+x, z+x, z+x, z+x } -	const LLQuad shuffled = _mm_castsi128_ps( _mm_shuffle_epi32( _mm_castps_si128( sumOfPairs ), _MM_SHUFFLE(1, 1, 1, 1) ) ); -	return _mm_add_ss( sumOfPairs, shuffled ); +    // ab = { w, z, y, x } +    const LLQuad ab = _mm_mul_ps( mQ, b.mQ ); +    // upperProdsInLowerElems = { y, x, y, x } +    const LLQuad upperProdsInLowerElems = _mm_movehl_ps( ab, ab ); +    // sumOfPairs = { w+y, z+x, 2y, 2x } +    const LLQuad sumOfPairs = _mm_add_ps( upperProdsInLowerElems, ab ); +    // shuffled = { z+x, z+x, z+x, z+x } +    const LLQuad shuffled = _mm_castsi128_ps( _mm_shuffle_epi32( _mm_castps_si128( sumOfPairs ), _MM_SHUFFLE(1, 1, 1, 1) ) ); +    return _mm_add_ss( sumOfPairs, shuffled );  }  // Normalize this vector with respect to the x, y, and z components only. Accurate to 22 bites of precision. W component is destroyed  // Note that this does not consider zero length vectors!  inline void LLVector4a::normalize3()  { -	// lenSqrd = a dot a -	LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this ); -	// rsqrt = approximate reciprocal square (i.e., { ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2 } -	const LLQuad rsqrt = _mm_rsqrt_ps(lenSqrd.mQ); -	static const LLQuad half = { 0.5f, 0.5f, 0.5f, 0.5f }; -	static const LLQuad three = {3.f, 3.f, 3.f, 3.f }; -	// Now we do one round of Newton-Raphson approximation to get full accuracy -	// According to the Newton-Raphson method, given a first 'w' for the root of f(x) = 1/x^2 - a (i.e., x = 1/sqrt(a)) -	// the next better approximation w[i+1] = w - f(w)/f'(w) = w - (1/w^2 - a)/(-2*w^(-3)) -	// w[i+1] = w + 0.5 * (1/w^2 - a) * w^3 = w + 0.5 * (w - a*w^3) = 1.5 * w - 0.5 * a * w^3 -	// = 0.5 * w * (3 - a*w^2) -	// Our first approx is w = rsqrt. We need out = a * w[i+1] (this is the input vector 'a', not the 'a' from the above formula -	// which is actually lenSqrd). So out = a * [0.5*rsqrt * (3 - lenSqrd*rsqrt*rsqrt)] -	const LLQuad AtimesRsqrt = _mm_mul_ps( lenSqrd.mQ, rsqrt ); -	const LLQuad AtimesRsqrtTimesRsqrt = _mm_mul_ps( AtimesRsqrt, rsqrt ); -	const LLQuad threeMinusAtimesRsqrtTimesRsqrt = _mm_sub_ps(three, AtimesRsqrtTimesRsqrt ); -	const LLQuad nrApprox = _mm_mul_ps(half, _mm_mul_ps(rsqrt, threeMinusAtimesRsqrtTimesRsqrt)); -	mQ = _mm_mul_ps( mQ, nrApprox ); +    // lenSqrd = a dot a +    LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this ); +    // rsqrt = approximate reciprocal square (i.e., { ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2 } +    const LLQuad rsqrt = _mm_rsqrt_ps(lenSqrd.mQ); +    static const LLQuad half = { 0.5f, 0.5f, 0.5f, 0.5f }; +    static const LLQuad three = {3.f, 3.f, 3.f, 3.f }; +    // Now we do one round of Newton-Raphson approximation to get full accuracy +    // According to the Newton-Raphson method, given a first 'w' for the root of f(x) = 1/x^2 - a (i.e., x = 1/sqrt(a)) +    // the next better approximation w[i+1] = w - f(w)/f'(w) = w - (1/w^2 - a)/(-2*w^(-3)) +    // w[i+1] = w + 0.5 * (1/w^2 - a) * w^3 = w + 0.5 * (w - a*w^3) = 1.5 * w - 0.5 * a * w^3 +    // = 0.5 * w * (3 - a*w^2) +    // Our first approx is w = rsqrt. We need out = a * w[i+1] (this is the input vector 'a', not the 'a' from the above formula +    // which is actually lenSqrd). So out = a * [0.5*rsqrt * (3 - lenSqrd*rsqrt*rsqrt)] +    const LLQuad AtimesRsqrt = _mm_mul_ps( lenSqrd.mQ, rsqrt ); +    const LLQuad AtimesRsqrtTimesRsqrt = _mm_mul_ps( AtimesRsqrt, rsqrt ); +    const LLQuad threeMinusAtimesRsqrtTimesRsqrt = _mm_sub_ps(three, AtimesRsqrtTimesRsqrt ); +    const LLQuad nrApprox = _mm_mul_ps(half, _mm_mul_ps(rsqrt, threeMinusAtimesRsqrtTimesRsqrt)); +    mQ = _mm_mul_ps( mQ, nrApprox );  }  // Normalize this vector with respect to all components. Accurate to 22 bites of precision.  // Note that this does not consider zero length vectors!  inline void LLVector4a::normalize4()  { -	// lenSqrd = a dot a -	LLVector4a lenSqrd; lenSqrd.setAllDot4( *this, *this ); -	// rsqrt = approximate reciprocal square (i.e., { ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2 } -	const LLQuad rsqrt = _mm_rsqrt_ps(lenSqrd.mQ); -	static const LLQuad half = { 0.5f, 0.5f, 0.5f, 0.5f }; -	static const LLQuad three = {3.f, 3.f, 3.f, 3.f }; -	// Now we do one round of Newton-Raphson approximation to get full accuracy -	// According to the Newton-Raphson method, given a first 'w' for the root of f(x) = 1/x^2 - a (i.e., x = 1/sqrt(a)) -	// the next better approximation w[i+1] = w - f(w)/f'(w) = w - (1/w^2 - a)/(-2*w^(-3)) -	// w[i+1] = w + 0.5 * (1/w^2 - a) * w^3 = w + 0.5 * (w - a*w^3) = 1.5 * w - 0.5 * a * w^3 -	// = 0.5 * w * (3 - a*w^2) -	// Our first approx is w = rsqrt. We need out = a * w[i+1] (this is the input vector 'a', not the 'a' from the above formula -	// which is actually lenSqrd). So out = a * [0.5*rsqrt * (3 - lenSqrd*rsqrt*rsqrt)] -	const LLQuad AtimesRsqrt = _mm_mul_ps( lenSqrd.mQ, rsqrt ); -	const LLQuad AtimesRsqrtTimesRsqrt = _mm_mul_ps( AtimesRsqrt, rsqrt ); -	const LLQuad threeMinusAtimesRsqrtTimesRsqrt = _mm_sub_ps(three, AtimesRsqrtTimesRsqrt ); -	const LLQuad nrApprox = _mm_mul_ps(half, _mm_mul_ps(rsqrt, threeMinusAtimesRsqrtTimesRsqrt)); -	mQ = _mm_mul_ps( mQ, nrApprox ); +    // lenSqrd = a dot a +    LLVector4a lenSqrd; lenSqrd.setAllDot4( *this, *this ); +    // rsqrt = approximate reciprocal square (i.e., { ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2 } +    const LLQuad rsqrt = _mm_rsqrt_ps(lenSqrd.mQ); +    static const LLQuad half = { 0.5f, 0.5f, 0.5f, 0.5f }; +    static const LLQuad three = {3.f, 3.f, 3.f, 3.f }; +    // Now we do one round of Newton-Raphson approximation to get full accuracy +    // According to the Newton-Raphson method, given a first 'w' for the root of f(x) = 1/x^2 - a (i.e., x = 1/sqrt(a)) +    // the next better approximation w[i+1] = w - f(w)/f'(w) = w - (1/w^2 - a)/(-2*w^(-3)) +    // w[i+1] = w + 0.5 * (1/w^2 - a) * w^3 = w + 0.5 * (w - a*w^3) = 1.5 * w - 0.5 * a * w^3 +    // = 0.5 * w * (3 - a*w^2) +    // Our first approx is w = rsqrt. We need out = a * w[i+1] (this is the input vector 'a', not the 'a' from the above formula +    // which is actually lenSqrd). So out = a * [0.5*rsqrt * (3 - lenSqrd*rsqrt*rsqrt)] +    const LLQuad AtimesRsqrt = _mm_mul_ps( lenSqrd.mQ, rsqrt ); +    const LLQuad AtimesRsqrtTimesRsqrt = _mm_mul_ps( AtimesRsqrt, rsqrt ); +    const LLQuad threeMinusAtimesRsqrtTimesRsqrt = _mm_sub_ps(three, AtimesRsqrtTimesRsqrt ); +    const LLQuad nrApprox = _mm_mul_ps(half, _mm_mul_ps(rsqrt, threeMinusAtimesRsqrtTimesRsqrt)); +    mQ = _mm_mul_ps( mQ, nrApprox );  }  // Normalize this vector with respect to the x, y, and z components only. Accurate to 22 bites of precision. W component is destroyed  // Note that this does not consider zero length vectors!  inline LLSimdScalar LLVector4a::normalize3withLength()  { -	// lenSqrd = a dot a -	LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this ); -	// rsqrt = approximate reciprocal square (i.e., { ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2 } -	const LLQuad rsqrt = _mm_rsqrt_ps(lenSqrd.mQ); -	static const LLQuad half = { 0.5f, 0.5f, 0.5f, 0.5f }; -	static const LLQuad three = {3.f, 3.f, 3.f, 3.f }; -	// Now we do one round of Newton-Raphson approximation to get full accuracy -	// According to the Newton-Raphson method, given a first 'w' for the root of f(x) = 1/x^2 - a (i.e., x = 1/sqrt(a)) -	// the next better approximation w[i+1] = w - f(w)/f'(w) = w - (1/w^2 - a)/(-2*w^(-3)) -	// w[i+1] = w + 0.5 * (1/w^2 - a) * w^3 = w + 0.5 * (w - a*w^3) = 1.5 * w - 0.5 * a * w^3 -	// = 0.5 * w * (3 - a*w^2) -	// Our first approx is w = rsqrt. We need out = a * w[i+1] (this is the input vector 'a', not the 'a' from the above formula -	// which is actually lenSqrd). So out = a * [0.5*rsqrt * (3 - lenSqrd*rsqrt*rsqrt)] -	const LLQuad AtimesRsqrt = _mm_mul_ps( lenSqrd.mQ, rsqrt ); -	const LLQuad AtimesRsqrtTimesRsqrt = _mm_mul_ps( AtimesRsqrt, rsqrt ); -	const LLQuad threeMinusAtimesRsqrtTimesRsqrt = _mm_sub_ps(three, AtimesRsqrtTimesRsqrt ); -	const LLQuad nrApprox = _mm_mul_ps(half, _mm_mul_ps(rsqrt, threeMinusAtimesRsqrtTimesRsqrt)); -	mQ = _mm_mul_ps( mQ, nrApprox ); -	return _mm_sqrt_ss(lenSqrd); +    // lenSqrd = a dot a +    LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this ); +    // rsqrt = approximate reciprocal square (i.e., { ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2, ~1/len(a)^2 } +    const LLQuad rsqrt = _mm_rsqrt_ps(lenSqrd.mQ); +    static const LLQuad half = { 0.5f, 0.5f, 0.5f, 0.5f }; +    static const LLQuad three = {3.f, 3.f, 3.f, 3.f }; +    // Now we do one round of Newton-Raphson approximation to get full accuracy +    // According to the Newton-Raphson method, given a first 'w' for the root of f(x) = 1/x^2 - a (i.e., x = 1/sqrt(a)) +    // the next better approximation w[i+1] = w - f(w)/f'(w) = w - (1/w^2 - a)/(-2*w^(-3)) +    // w[i+1] = w + 0.5 * (1/w^2 - a) * w^3 = w + 0.5 * (w - a*w^3) = 1.5 * w - 0.5 * a * w^3 +    // = 0.5 * w * (3 - a*w^2) +    // Our first approx is w = rsqrt. We need out = a * w[i+1] (this is the input vector 'a', not the 'a' from the above formula +    // which is actually lenSqrd). So out = a * [0.5*rsqrt * (3 - lenSqrd*rsqrt*rsqrt)] +    const LLQuad AtimesRsqrt = _mm_mul_ps( lenSqrd.mQ, rsqrt ); +    const LLQuad AtimesRsqrtTimesRsqrt = _mm_mul_ps( AtimesRsqrt, rsqrt ); +    const LLQuad threeMinusAtimesRsqrtTimesRsqrt = _mm_sub_ps(three, AtimesRsqrtTimesRsqrt ); +    const LLQuad nrApprox = _mm_mul_ps(half, _mm_mul_ps(rsqrt, threeMinusAtimesRsqrtTimesRsqrt)); +    mQ = _mm_mul_ps( mQ, nrApprox ); +    return _mm_sqrt_ss(lenSqrd);  }  // Normalize this vector with respect to the x, y, and z components only. Accurate only to 10-12 bits of precision. W component is destroyed  // Note that this does not consider zero length vectors!  inline void LLVector4a::normalize3fast()  { -	LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this ); -	const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ); -	mQ = _mm_mul_ps( mQ, approxRsqrt ); +    LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this ); +    const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ); +    mQ = _mm_mul_ps( mQ, approxRsqrt );  }  inline void LLVector4a::normalize3fast_checked(LLVector4a* d)  { -	if (!isFinite3()) -	{ -		*this = d ? *d : LLVector4a(0,1,0,1); -		return; -	} +    if (!isFinite3()) +    { +        *this = d ? *d : LLVector4a(0,1,0,1); +        return; +    } -	LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this ); +    LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this ); -	if (lenSqrd.getF32ptr()[0] <= FLT_EPSILON) -	{ -		*this = d ? *d : LLVector4a(0,1,0,1); -		return; -	} +    if (lenSqrd.getF32ptr()[0] <= FLT_EPSILON) +    { +        *this = d ? *d : LLVector4a(0,1,0,1); +        return; +    } -	const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ); -	mQ = _mm_mul_ps( mQ, approxRsqrt ); +    const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ); +    mQ = _mm_mul_ps( mQ, approxRsqrt );  }  // Return true if this vector is normalized with respect to x,y,z up to tolerance  inline LLBool32 LLVector4a::isNormalized3( F32 tolerance ) const  { -	static LL_ALIGN_16(const U32 ones[4]) = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 }; -	LLSimdScalar tol = _mm_load_ss( &tolerance ); -	tol = _mm_mul_ss( tol, tol ); -	LLVector4a lenSquared; lenSquared.setAllDot3( *this, *this ); -	lenSquared.sub( *reinterpret_cast<const LLVector4a*>(ones) ); -	lenSquared.setAbs(lenSquared); -	return _mm_comile_ss( lenSquared, tol );		 +    static LL_ALIGN_16(const U32 ones[4]) = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 }; +    LLSimdScalar tol = _mm_load_ss( &tolerance ); +    tol = _mm_mul_ss( tol, tol ); +    LLVector4a lenSquared; lenSquared.setAllDot3( *this, *this ); +    lenSquared.sub( *reinterpret_cast<const LLVector4a*>(ones) ); +    lenSquared.setAbs(lenSquared); +    return _mm_comile_ss( lenSquared, tol );  }  // Return true if this vector is normalized with respect to all components up to tolerance  inline LLBool32 LLVector4a::isNormalized4( F32 tolerance ) const  { -	static LL_ALIGN_16(const U32 ones[4]) = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 }; -	LLSimdScalar tol = _mm_load_ss( &tolerance ); -	tol = _mm_mul_ss( tol, tol ); -	LLVector4a lenSquared; lenSquared.setAllDot4( *this, *this ); -	lenSquared.sub( *reinterpret_cast<const LLVector4a*>(ones) ); -	lenSquared.setAbs(lenSquared); -	return _mm_comile_ss( lenSquared, tol );		 +    static LL_ALIGN_16(const U32 ones[4]) = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 }; +    LLSimdScalar tol = _mm_load_ss( &tolerance ); +    tol = _mm_mul_ss( tol, tol ); +    LLVector4a lenSquared; lenSquared.setAllDot4( *this, *this ); +    lenSquared.sub( *reinterpret_cast<const LLVector4a*>(ones) ); +    lenSquared.setAbs(lenSquared); +    return _mm_comile_ss( lenSquared, tol );  } -// Set all elements to the length of vector 'v'  +// Set all elements to the length of vector 'v'  inline void LLVector4a::setAllLength3( const LLVector4a& v )  { -	LLVector4a lenSqrd; -	lenSqrd.setAllDot3(v, v); -	 -	mQ = _mm_sqrt_ps(lenSqrd.mQ); +    LLVector4a lenSqrd; +    lenSqrd.setAllDot3(v, v); + +    mQ = _mm_sqrt_ps(lenSqrd.mQ);  }  // Get this vector's length  inline LLSimdScalar LLVector4a::getLength3() const  { -	return _mm_sqrt_ss( dot3( (const LLVector4a)mQ ) ); +    return _mm_sqrt_ss( dot3( (const LLVector4a)mQ ) );  }  // Set the components of this vector to the minimum of the corresponding components of lhs and rhs  inline void LLVector4a::setMin(const LLVector4a& lhs, const LLVector4a& rhs)  { -	mQ = _mm_min_ps(lhs.mQ, rhs.mQ); +    mQ = _mm_min_ps(lhs.mQ, rhs.mQ);  }  // Set the components of this vector to the maximum of the corresponding components of lhs and rhs  inline void LLVector4a::setMax(const LLVector4a& lhs, const LLVector4a& rhs)  { -	mQ = _mm_max_ps(lhs.mQ, rhs.mQ); +    mQ = _mm_max_ps(lhs.mQ, rhs.mQ);  }  // Set this to  lhs + (rhs-lhs)*c  inline void LLVector4a::setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F32 c)  { -	LLVector4a t; -	t.setSub(rhs,lhs); -	t.mul(c); -	setAdd(lhs, t); +    LLVector4a t; +    t.setSub(rhs,lhs); +    t.mul(c); +    setAdd(lhs, t);  }  inline LLBool32 LLVector4a::isFinite3() const  { -	static LL_ALIGN_16(const U32 nanOrInfMask[4]) = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 }; -	ll_assert_aligned(nanOrInfMask,16); -	const __m128i nanOrInfMaskV = *reinterpret_cast<const __m128i*> (nanOrInfMask); -	const __m128i maskResult = _mm_and_si128( _mm_castps_si128(mQ), nanOrInfMaskV ); -	const LLVector4Logical equalityCheck = _mm_castsi128_ps(_mm_cmpeq_epi32( maskResult, nanOrInfMaskV )); -	return !equalityCheck.areAnySet( LLVector4Logical::MASK_XYZ ); +    static LL_ALIGN_16(const U32 nanOrInfMask[4]) = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 }; +    ll_assert_aligned(nanOrInfMask,16); +    const __m128i nanOrInfMaskV = *reinterpret_cast<const __m128i*> (nanOrInfMask); +    const __m128i maskResult = _mm_and_si128( _mm_castps_si128(mQ), nanOrInfMaskV ); +    const LLVector4Logical equalityCheck = _mm_castsi128_ps(_mm_cmpeq_epi32( maskResult, nanOrInfMaskV )); +    return !equalityCheck.areAnySet( LLVector4Logical::MASK_XYZ );  } -	 +  inline LLBool32 LLVector4a::isFinite4() const  { -	static LL_ALIGN_16(const U32 nanOrInfMask[4]) = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 }; -	const __m128i nanOrInfMaskV = *reinterpret_cast<const __m128i*> (nanOrInfMask); -	const __m128i maskResult = _mm_and_si128( _mm_castps_si128(mQ), nanOrInfMaskV ); -	const LLVector4Logical equalityCheck = _mm_castsi128_ps(_mm_cmpeq_epi32( maskResult, nanOrInfMaskV )); -	return !equalityCheck.areAnySet( LLVector4Logical::MASK_XYZW ); +    static LL_ALIGN_16(const U32 nanOrInfMask[4]) = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 }; +    const __m128i nanOrInfMaskV = *reinterpret_cast<const __m128i*> (nanOrInfMask); +    const __m128i maskResult = _mm_and_si128( _mm_castps_si128(mQ), nanOrInfMaskV ); +    const LLVector4Logical equalityCheck = _mm_castsi128_ps(_mm_cmpeq_epi32( maskResult, nanOrInfMaskV )); +    return !equalityCheck.areAnySet( LLVector4Logical::MASK_XYZW );  }  inline void LLVector4a::setRotatedInv( const LLRotation& rot, const LLVector4a& vec )  { -	LLRotation inv; inv.setTranspose( rot ); -	setRotated( inv, vec ); +    LLRotation inv; inv.setTranspose( rot ); +    setRotated( inv, vec );  }  inline void LLVector4a::setRotatedInv( const LLQuaternion2& quat, const LLVector4a& vec )  { -	LLQuaternion2 invRot; invRot.setConjugate( quat ); -	setRotated(invRot, vec); +    LLQuaternion2 invRot; invRot.setConjugate( quat ); +    setRotated(invRot, vec);  }  inline void LLVector4a::clamp( const LLVector4a& low, const LLVector4a& high )  { -	const LLVector4Logical highMask = greaterThan( high ); -	const LLVector4Logical lowMask = lessThan( low ); +    const LLVector4Logical highMask = greaterThan( high ); +    const LLVector4Logical lowMask = lessThan( low ); -	setSelectWithMask( highMask, high, *this ); -	setSelectWithMask( lowMask, low, *this ); +    setSelectWithMask( highMask, high, *this ); +    setSelectWithMask( lowMask, low, *this );  }  ////////////////////////////////////  // LOGICAL -////////////////////////////////////	 +////////////////////////////////////  // The functions in this section will compare the elements in this vector  // to those in rhs and return an LLVector4Logical with all bits set in elements  // where the comparison was true and all bits unset in elements where the comparison @@ -544,68 +544,68 @@ inline void LLVector4a::clamp( const LLVector4a& low, const LLVector4a& high )  ////////////////////////////////////  inline LLVector4Logical LLVector4a::greaterThan(const LLVector4a& rhs) const -{	 -	return _mm_cmpgt_ps(mQ, rhs.mQ); +{ +    return _mm_cmpgt_ps(mQ, rhs.mQ);  }  inline LLVector4Logical LLVector4a::lessThan(const LLVector4a& rhs) const  { -	return _mm_cmplt_ps(mQ, rhs.mQ); +    return _mm_cmplt_ps(mQ, rhs.mQ);  }  inline LLVector4Logical LLVector4a::greaterEqual(const LLVector4a& rhs) const  { -	return _mm_cmpge_ps(mQ, rhs.mQ); +    return _mm_cmpge_ps(mQ, rhs.mQ);  }  inline LLVector4Logical LLVector4a::lessEqual(const LLVector4a& rhs) const  { -	return _mm_cmple_ps(mQ, rhs.mQ); +    return _mm_cmple_ps(mQ, rhs.mQ);  }  inline LLVector4Logical LLVector4a::equal(const LLVector4a& rhs) const  { -	return _mm_cmpeq_ps(mQ, rhs.mQ); +    return _mm_cmpeq_ps(mQ, rhs.mQ);  }  // Returns true if this and rhs are componentwise equal up to the specified absolute tolerance  inline bool LLVector4a::equals4(const LLVector4a& rhs, F32 tolerance ) const  { -	LLVector4a diff; diff.setSub( *this, rhs ); -	diff.setAbs( diff ); -	const LLQuad tol = _mm_set1_ps( tolerance ); -	const LLQuad cmp = _mm_cmplt_ps( diff, tol ); -	return (_mm_movemask_ps( cmp ) & LLVector4Logical::MASK_XYZW) == LLVector4Logical::MASK_XYZW; +    LLVector4a diff; diff.setSub( *this, rhs ); +    diff.setAbs( diff ); +    const LLQuad tol = _mm_set1_ps( tolerance ); +    const LLQuad cmp = _mm_cmplt_ps( diff, tol ); +    return (_mm_movemask_ps( cmp ) & LLVector4Logical::MASK_XYZW) == LLVector4Logical::MASK_XYZW;  }  inline bool LLVector4a::equals3(const LLVector4a& rhs, F32 tolerance ) const  { -	LLVector4a diff; diff.setSub( *this, rhs ); -	diff.setAbs( diff ); -	const LLQuad tol = _mm_set1_ps( tolerance ); -	const LLQuad t = _mm_cmplt_ps( diff, tol );  -	return (_mm_movemask_ps( t ) & LLVector4Logical::MASK_XYZ) == LLVector4Logical::MASK_XYZ; -	 +    LLVector4a diff; diff.setSub( *this, rhs ); +    diff.setAbs( diff ); +    const LLQuad tol = _mm_set1_ps( tolerance ); +    const LLQuad t = _mm_cmplt_ps( diff, tol ); +    return (_mm_movemask_ps( t ) & LLVector4Logical::MASK_XYZ) == LLVector4Logical::MASK_XYZ; +  }  ////////////////////////////////////  // OPERATORS -////////////////////////////////////	 +////////////////////////////////////  // Do NOT add aditional operators without consulting someone with SSE experience  inline const LLVector4a& LLVector4a::operator= ( const LLVector4a& rhs )  { -	mQ = rhs.mQ; -	return *this; +    mQ = rhs.mQ; +    return *this;  }  inline const LLVector4a& LLVector4a::operator= ( const LLQuad& rhs )  { -	mQ = rhs; -	return *this; +    mQ = rhs; +    return *this;  }  inline LLVector4a::operator LLQuad() const  { -	return mQ; +    return mQ;  } diff --git a/indra/llmath/llvector4logical.h b/indra/llmath/llvector4logical.h index c5698f7cea..d08b5513d9 100644 --- a/indra/llmath/llvector4logical.h +++ b/indra/llmath/llvector4logical.h @@ -1,31 +1,31 @@ -/**  +/**   * @file llvector4logical.h   * @brief LLVector4Logical class header file - Companion class to LLVector4a for logical and bit-twiddling operations   *   * $LicenseInfo:firstyear=2010&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -#ifndef	LL_VECTOR4LOGICAL_H -#define	LL_VECTOR4LOGICAL_H +#ifndef LL_VECTOR4LOGICAL_H +#define LL_VECTOR4LOGICAL_H  #include "llmemory.h" @@ -41,86 +41,86 @@  static LL_ALIGN_16(const U32 S_V4LOGICAL_MASK_TABLE[4*4]) =  { -	0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, -	0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, -	0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000, -	0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF +    0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, +    0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, +    0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000, +    0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF  };  class LLVector4Logical  {  public: -	 -	enum { -		MASK_X = 1, -		MASK_Y = 1 << 1, -		MASK_Z = 1 << 2, -		MASK_W = 1 << 3, -		MASK_XYZ = MASK_X | MASK_Y | MASK_Z, -		MASK_XYZW = MASK_XYZ | MASK_W -	}; -	 -	// Empty default ctor -	LLVector4Logical() {} -	 -	LLVector4Logical( const LLQuad& quad ) -	{ -		mQ = quad; -	} -	 -	// Create and return a mask consisting of the lowest order bit of each element -	inline U32 getGatheredBits() const -	{ -		return _mm_movemask_ps(mQ); -	};	 -	 -	// Invert this mask -	inline LLVector4Logical& invert() -	{ -		static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; -		ll_assert_aligned(allOnes,16); -		mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) ); -		return *this; -	} -	 -	inline LLBool32 areAllSet( U32 mask ) const -	{ -		return ( getGatheredBits() & mask) == mask; -	} -	 -	inline LLBool32 areAllSet() const -	{ -		return areAllSet( MASK_XYZW ); -	} -		 -	inline LLBool32 areAnySet( U32 mask ) const -	{ -		return getGatheredBits() & mask; -	} -	 -	inline LLBool32 areAnySet() const -	{ -		return areAnySet( MASK_XYZW ); -	} -	 -	inline operator LLQuad() const -	{ -		return mQ; -	} - -	inline void clear()  -	{ -		mQ = _mm_setzero_ps(); -	} - -	template<int N> void setElement() -	{ -		mQ = _mm_or_ps( mQ, *reinterpret_cast<const LLQuad*>(S_V4LOGICAL_MASK_TABLE + 4*N) ); -	} -	 + +    enum { +        MASK_X = 1, +        MASK_Y = 1 << 1, +        MASK_Z = 1 << 2, +        MASK_W = 1 << 3, +        MASK_XYZ = MASK_X | MASK_Y | MASK_Z, +        MASK_XYZW = MASK_XYZ | MASK_W +    }; + +    // Empty default ctor +    LLVector4Logical() {} + +    LLVector4Logical( const LLQuad& quad ) +    { +        mQ = quad; +    } + +    // Create and return a mask consisting of the lowest order bit of each element +    inline U32 getGatheredBits() const +    { +        return _mm_movemask_ps(mQ); +    }; + +    // Invert this mask +    inline LLVector4Logical& invert() +    { +        static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; +        ll_assert_aligned(allOnes,16); +        mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) ); +        return *this; +    } + +    inline LLBool32 areAllSet( U32 mask ) const +    { +        return ( getGatheredBits() & mask) == mask; +    } + +    inline LLBool32 areAllSet() const +    { +        return areAllSet( MASK_XYZW ); +    } + +    inline LLBool32 areAnySet( U32 mask ) const +    { +        return getGatheredBits() & mask; +    } + +    inline LLBool32 areAnySet() const +    { +        return areAnySet( MASK_XYZW ); +    } + +    inline operator LLQuad() const +    { +        return mQ; +    } + +    inline void clear() +    { +        mQ = _mm_setzero_ps(); +    } + +    template<int N> void setElement() +    { +        mQ = _mm_or_ps( mQ, *reinterpret_cast<const LLQuad*>(S_V4LOGICAL_MASK_TABLE + 4*N) ); +    } +  private: -	 -	LLQuad mQ; + +    LLQuad mQ;  };  #endif //LL_VECTOR4ALOGICAL_H diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index e694732da2..9375a5dfca 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1,24 +1,24 @@ -/**  +/**   * @file llvolume.cpp   *   * $LicenseInfo:firstyear=2002&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -66,7 +66,7 @@ const F32 MIN_CUT_DELTA = 0.02f;  const F32 HOLLOW_MIN = 0.f;  const F32 HOLLOW_MAX = 0.95f; -const F32 HOLLOW_MAX_SQUARE	= 0.7f; +const F32 HOLLOW_MAX_SQUARE = 0.7f;  const F32 TWIST_MIN = -1.f;  const F32 TWIST_MAX =  1.f; @@ -89,8 +89,8 @@ const F32 REV_MAX = 4.f;  const F32 TAPER_MIN = -1.f;  const F32 TAPER_MAX =  1.f; -const F32 SKEW_MIN	= -0.95f; -const F32 SKEW_MAX	=  0.95f; +const F32 SKEW_MIN  = -0.95f; +const F32 SKEW_MAX  =  0.95f;  const F32 SCULPT_MIN_AREA = 0.002f;  const S32 SCULPT_MIN_AREA_DETAIL = 1; @@ -98,354 +98,354 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1;  BOOL gDebugGL = FALSE; // See settings.xml "RenderDebugGL"  BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) -{     -	LLVector3 test = (pt2-pt1)%(pt3-pt2); - -	//answer -	if(test * norm < 0)  -	{ -		return FALSE; -	} -	else  -	{ -		return TRUE; -	} -}  +{ +    LLVector3 test = (pt2-pt1)%(pt3-pt2); + +    //answer +    if(test * norm < 0) +    { +        return FALSE; +    } +    else +    { +        return TRUE; +    } +}  BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size)  { -	return LLLineSegmentBoxIntersect(start.mV, end.mV, center.mV, size.mV); +    return LLLineSegmentBoxIntersect(start.mV, end.mV, center.mV, size.mV);  }  BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size)  { -	F32 fAWdU[3]; -	F32 dir[3]; -	F32 diff[3]; +    F32 fAWdU[3]; +    F32 dir[3]; +    F32 diff[3]; -	for (U32 i = 0; i < 3; i++) -	{ -		dir[i] = 0.5f * (end[i] - start[i]); -		diff[i] = (0.5f * (end[i] + start[i])) - center[i]; -		fAWdU[i] = fabsf(dir[i]); -		if(fabsf(diff[i])>size[i] + fAWdU[i]) return false; -	} +    for (U32 i = 0; i < 3; i++) +    { +        dir[i] = 0.5f * (end[i] - start[i]); +        diff[i] = (0.5f * (end[i] + start[i])) - center[i]; +        fAWdU[i] = fabsf(dir[i]); +        if(fabsf(diff[i])>size[i] + fAWdU[i]) return false; +    } -	float f; -	f = dir[1] * diff[2] - dir[2] * diff[1];    if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1])  return false; -	f = dir[2] * diff[0] - dir[0] * diff[2];    if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0])  return false; -	f = dir[0] * diff[1] - dir[1] * diff[0];    if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0])  return false; -	 -	return true; +    float f; +    f = dir[1] * diff[2] - dir[2] * diff[1];    if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1])  return false; +    f = dir[2] * diff[0] - dir[0] * diff[2];    if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0])  return false; +    f = dir[0] * diff[1] - dir[1] * diff[0];    if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0])  return false; + +    return true;  }  // Finds tangent vec based on three vertices with texture coordinates.  // Fills in dummy values if the triangle has degenerate texture coordinates.  void calc_tangent_from_triangle( -	LLVector4a&			normal, -	LLVector4a&			tangent_out, -	const LLVector4a& v1, -	const LLVector2&  w1, -	const LLVector4a& v2, -	const LLVector2&  w2, -	const LLVector4a& v3, -	const LLVector2&  w3) -{ -	const F32* v1ptr = v1.getF32ptr(); -	const F32* v2ptr = v2.getF32ptr(); -	const F32* v3ptr = v3.getF32ptr(); +    LLVector4a&         normal, +    LLVector4a&         tangent_out, +    const LLVector4a& v1, +    const LLVector2&  w1, +    const LLVector4a& v2, +    const LLVector2&  w2, +    const LLVector4a& v3, +    const LLVector2&  w3) +{ +    const F32* v1ptr = v1.getF32ptr(); +    const F32* v2ptr = v2.getF32ptr(); +    const F32* v3ptr = v3.getF32ptr(); + +    float x1 = v2ptr[0] - v1ptr[0]; +    float x2 = v3ptr[0] - v1ptr[0]; +    float y1 = v2ptr[1] - v1ptr[1]; +    float y2 = v3ptr[1] - v1ptr[1]; +    float z1 = v2ptr[2] - v1ptr[2]; +    float z2 = v3ptr[2] - v1ptr[2]; + +    float s1 = w2.mV[0] - w1.mV[0]; +    float s2 = w3.mV[0] - w1.mV[0]; +    float t1 = w2.mV[1] - w1.mV[1]; +    float t2 = w3.mV[1] - w1.mV[1]; + +    F32 rd = s1*t2-s2*t1; + +    float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd) +                                                : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero + +    llassert(llfinite(r)); +    llassert(!llisnan(r)); + +    LLVector4a sdir( +        (t2 * x1 - t1 * x2) * r, +        (t2 * y1 - t1 * y2) * r, +        (t2 * z1 - t1 * z2) * r); + +    LLVector4a tdir( +        (s1 * x2 - s2 * x1) * r, +        (s1 * y2 - s2 * y1) * r, +        (s1 * z2 - s2 * z1) * r); + +    LLVector4a  n = normal; +    LLVector4a  t = sdir; + +    LLVector4a ncrosst; +    ncrosst.setCross3(n,t); + +    // Gram-Schmidt orthogonalize +    n.mul(n.dot3(t).getF32()); + +    LLVector4a tsubn; +    tsubn.setSub(t,n); + +    if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) +    { +        tsubn.normalize3fast_checked(); -	float x1 = v2ptr[0] - v1ptr[0]; -	float x2 = v3ptr[0] - v1ptr[0]; -	float y1 = v2ptr[1] - v1ptr[1]; -	float y2 = v3ptr[1] - v1ptr[1]; -	float z1 = v2ptr[2] - v1ptr[2]; -	float z2 = v3ptr[2] - v1ptr[2]; +        // Calculate handedness +        F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f; -	float s1 = w2.mV[0] - w1.mV[0]; -	float s2 = w3.mV[0] - w1.mV[0]; -	float t1 = w2.mV[1] - w1.mV[1]; -	float t2 = w3.mV[1] - w1.mV[1]; +        tsubn.getF32ptr()[3] = handedness; -	F32 rd = s1*t2-s2*t1; +        tangent_out = tsubn; +    } +    else +    { +        // degenerate, make up a value +        // +        tangent_out.set(0,0,1,1); +    } -	float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd) -											    : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero +} -	llassert(llfinite(r)); -	llassert(!llisnan(r)); -	LLVector4a sdir( -		(t2 * x1 - t1 * x2) * r, -		(t2 * y1 - t1 * y2) * r, -		(t2 * z1 - t1 * z2) * r); +// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. +// returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b, +// and returns the intersection point along dir in intersection_t. -	LLVector4a tdir( -		(s1 * x2 - s2 * x1) * r, -		(s1 * y2 - s2 * y1) * r, -		(s1 * z2 - s2 * z1) * r); +// Moller-Trumbore algorithm +BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, +                            F32& intersection_a, F32& intersection_b, F32& intersection_t) +{ -	LLVector4a	n = normal; -	LLVector4a	t = sdir; +    /* find vectors for two edges sharing vert0 */ +    LLVector4a edge1; +    edge1.setSub(vert1, vert0); -	LLVector4a ncrosst; -	ncrosst.setCross3(n,t); +    LLVector4a edge2; +    edge2.setSub(vert2, vert0); -	// Gram-Schmidt orthogonalize -	n.mul(n.dot3(t).getF32()); +    /* begin calculating determinant - also used to calculate U parameter */ +    LLVector4a pvec; +    pvec.setCross3(dir, edge2); -	LLVector4a tsubn; -	tsubn.setSub(t,n); +    /* if determinant is near zero, ray lies in plane of triangle */ +    LLVector4a det; +    det.setAllDot3(edge1, pvec); -	if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) -	{ -		tsubn.normalize3fast_checked(); +    if (det.greaterEqual(LLVector4a::getEpsilon()).getGatheredBits() & 0x7) +    { +        /* calculate distance from vert0 to ray origin */ +        LLVector4a tvec; +        tvec.setSub(orig, vert0); -		// Calculate handedness -		F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f; +        /* calculate U parameter and test bounds */ +        LLVector4a u; +        u.setAllDot3(tvec,pvec); -		tsubn.getF32ptr()[3] = handedness; +        if ((u.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7) && +            (u.lessEqual(det).getGatheredBits() & 0x7)) +        { +            /* prepare to test V parameter */ +            LLVector4a qvec; +            qvec.setCross3(tvec, edge1); -		tangent_out = tsubn; -	} -	else -	{ -		// degenerate, make up a value -		// -		tangent_out.set(0,0,1,1); -	} +            /* calculate V parameter and test bounds */ +            LLVector4a v; +            v.setAllDot3(dir, qvec); -} +            //if (!(v < 0.f || u + v > det)) -// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. -// returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b, -// and returns the intersection point along dir in intersection_t. +            LLVector4a sum_uv; +            sum_uv.setAdd(u, v); -// Moller-Trumbore algorithm -BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, -							F32& intersection_a, F32& intersection_b, F32& intersection_t) -{ -	 -	/* find vectors for two edges sharing vert0 */ -	LLVector4a edge1; -	edge1.setSub(vert1, vert0); -	 -	LLVector4a edge2; -	edge2.setSub(vert2, vert0); - -	/* begin calculating determinant - also used to calculate U parameter */ -	LLVector4a pvec; -	pvec.setCross3(dir, edge2); - -	/* if determinant is near zero, ray lies in plane of triangle */ -	LLVector4a det; -	det.setAllDot3(edge1, pvec); -	 -	if (det.greaterEqual(LLVector4a::getEpsilon()).getGatheredBits() & 0x7) -	{ -		/* calculate distance from vert0 to ray origin */ -		LLVector4a tvec; -		tvec.setSub(orig, vert0); - -		/* calculate U parameter and test bounds */ -		LLVector4a u; -		u.setAllDot3(tvec,pvec); - -		if ((u.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7) && -			(u.lessEqual(det).getGatheredBits() & 0x7)) -		{ -			/* prepare to test V parameter */ -			LLVector4a qvec; -			qvec.setCross3(tvec, edge1); -			 -			/* calculate V parameter and test bounds */ -			LLVector4a v; -			v.setAllDot3(dir, qvec); - -			 -			//if (!(v < 0.f || u + v > det)) - -			LLVector4a sum_uv; -			sum_uv.setAdd(u, v); - -			S32 v_gequal = v.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7; -			S32 sum_lequal = sum_uv.lessEqual(det).getGatheredBits() & 0x7; - -			if (v_gequal  && sum_lequal) -			{ -				/* calculate t, scale parameters, ray intersects triangle */ -				LLVector4a t; -				t.setAllDot3(edge2,qvec); - -				t.div(det); -				u.div(det); -				v.div(det); -				 -				intersection_a = u[0]; -				intersection_b = v[0]; -				intersection_t = t[0]; -				return TRUE; -			} -		} -	} -		 -	return FALSE; -}  +            S32 v_gequal = v.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7; +            S32 sum_lequal = sum_uv.lessEqual(det).getGatheredBits() & 0x7; + +            if (v_gequal  && sum_lequal) +            { +                /* calculate t, scale parameters, ray intersects triangle */ +                LLVector4a t; +                t.setAllDot3(edge2,qvec); + +                t.div(det); +                u.div(det); +                v.div(det); + +                intersection_a = u[0]; +                intersection_b = v[0]; +                intersection_t = t[0]; +                return TRUE; +            } +        } +    } + +    return FALSE; +}  BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, -							F32& intersection_a, F32& intersection_b, F32& intersection_t) -{ -	F32 u, v, t; -	 -	/* find vectors for two edges sharing vert0 */ -	LLVector4a edge1; -	edge1.setSub(vert1, vert0); -	 -	 -	LLVector4a edge2; -	edge2.setSub(vert2, vert0); - -	/* begin calculating determinant - also used to calculate U parameter */ -	LLVector4a pvec; -	pvec.setCross3(dir, edge2); - -	/* if determinant is near zero, ray lies in plane of triangle */ -	F32 det = edge1.dot3(pvec).getF32(); - -	 -	if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO) -	{ -		return FALSE; -	} - -	F32 inv_det = 1.f / det; - -	/* calculate distance from vert0 to ray origin */ -	LLVector4a tvec; -	tvec.setSub(orig, vert0); -	 -	/* calculate U parameter and test bounds */ -	u = (tvec.dot3(pvec).getF32()) * inv_det; -	if (u < 0.f || u > 1.f) -	{ -		return FALSE; -	} - -	/* prepare to test V parameter */ -	tvec.sub(edge1); -		 -	/* calculate V parameter and test bounds */ -	v = (dir.dot3(tvec).getF32()) * inv_det; -	 -	if (v < 0.f || u + v > 1.f) -	{ -		return FALSE; -	} - -	/* calculate t, ray intersects triangle */ -	t = (edge2.dot3(tvec).getF32()) * inv_det; -	 -	intersection_a = u; -	intersection_b = v; -	intersection_t = t; -	 -	 -	return TRUE; -}  +                            F32& intersection_a, F32& intersection_b, F32& intersection_t) +{ +    F32 u, v, t; + +    /* find vectors for two edges sharing vert0 */ +    LLVector4a edge1; +    edge1.setSub(vert1, vert0); + + +    LLVector4a edge2; +    edge2.setSub(vert2, vert0); + +    /* begin calculating determinant - also used to calculate U parameter */ +    LLVector4a pvec; +    pvec.setCross3(dir, edge2); + +    /* if determinant is near zero, ray lies in plane of triangle */ +    F32 det = edge1.dot3(pvec).getF32(); + + +    if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO) +    { +        return FALSE; +    } + +    F32 inv_det = 1.f / det; + +    /* calculate distance from vert0 to ray origin */ +    LLVector4a tvec; +    tvec.setSub(orig, vert0); + +    /* calculate U parameter and test bounds */ +    u = (tvec.dot3(pvec).getF32()) * inv_det; +    if (u < 0.f || u > 1.f) +    { +        return FALSE; +    } + +    /* prepare to test V parameter */ +    tvec.sub(edge1); + +    /* calculate V parameter and test bounds */ +    v = (dir.dot3(tvec).getF32()) * inv_det; + +    if (v < 0.f || u + v > 1.f) +    { +        return FALSE; +    } + +    /* calculate t, ray intersects triangle */ +    t = (edge2.dot3(tvec).getF32()) * inv_det; + +    intersection_a = u; +    intersection_b = v; +    intersection_t = t; + + +    return TRUE; +}  //helper for non-aligned vectors  BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, -							F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided) -{ -	LLVector4a vert0a, vert1a, vert2a, origa, dira; -	vert0a.load3(vert0.mV); -	vert1a.load3(vert1.mV); -	vert2a.load3(vert2.mV); -	origa.load3(orig.mV); -	dira.load3(dir.mV); - -	if (two_sided) -	{ -		return LLTriangleRayIntersectTwoSided(vert0a, vert1a, vert2a, origa, dira,  -				intersection_a, intersection_b, intersection_t); -	} -	else -	{ -		return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira,  -				intersection_a, intersection_b, intersection_t); -	} +                            F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided) +{ +    LLVector4a vert0a, vert1a, vert2a, origa, dira; +    vert0a.load3(vert0.mV); +    vert1a.load3(vert1.mV); +    vert2a.load3(vert2.mV); +    origa.load3(orig.mV); +    dira.load3(dir.mV); + +    if (two_sided) +    { +        return LLTriangleRayIntersectTwoSided(vert0a, vert1a, vert2a, origa, dira, +                intersection_a, intersection_b, intersection_t); +    } +    else +    { +        return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira, +                intersection_a, intersection_b, intersection_t); +    }  }  class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*>  {  public: -	const LLVolumeFace* mFace; +    const LLVolumeFace* mFace; -	LLVolumeOctreeRebound(const LLVolumeFace* face) -	{ -		mFace = face; -	} +    LLVolumeOctreeRebound(const LLVolumeFace* face) +    { +        mFace = face; +    }      virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch) -	{ //this is a depth first traversal, so it's safe to assum all children have complete -		//bounding data -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - -		LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); - -		LLVector4a& min = node->mExtents[0]; -		LLVector4a& max = node->mExtents[1]; - -		if (!branch->isEmpty()) -		{ //node has data, find AABB that binds data set -			const LLVolumeTriangle* tri = *(branch->getDataBegin()); -			 -			//initialize min/max to first available vertex -			min = *(tri->mV[0]); -			max = *(tri->mV[0]); -			 +    { //this is a depth first traversal, so it's safe to assum all children have complete +        //bounding data +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + +        LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); + +        LLVector4a& min = node->mExtents[0]; +        LLVector4a& max = node->mExtents[1]; + +        if (!branch->isEmpty()) +        { //node has data, find AABB that binds data set +            const LLVolumeTriangle* tri = *(branch->getDataBegin()); + +            //initialize min/max to first available vertex +            min = *(tri->mV[0]); +            max = *(tri->mV[0]); +              for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) -			{ //for each triangle in node - -				//stretch by triangles in node -				tri = *iter; -				 -				min.setMin(min, *tri->mV[0]); -				min.setMin(min, *tri->mV[1]); -				min.setMin(min, *tri->mV[2]); - -				max.setMax(max, *tri->mV[0]); -				max.setMax(max, *tri->mV[1]); -				max.setMax(max, *tri->mV[2]); -			} -		} -		else if (branch->getChildCount() > 0) -		{ //no data, but child nodes exist -			LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0); - -			//initialize min/max to extents of first child -			min = child->mExtents[0]; -			max = child->mExtents[1]; -		} -		else -		{ +            { //for each triangle in node + +                //stretch by triangles in node +                tri = *iter; + +                min.setMin(min, *tri->mV[0]); +                min.setMin(min, *tri->mV[1]); +                min.setMin(min, *tri->mV[2]); + +                max.setMax(max, *tri->mV[0]); +                max.setMax(max, *tri->mV[1]); +                max.setMax(max, *tri->mV[2]); +            } +        } +        else if (branch->getChildCount() > 0) +        { //no data, but child nodes exist +            LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0); + +            //initialize min/max to extents of first child +            min = child->mExtents[0]; +            max = child->mExtents[1]; +        } +        else +        {              llassert(!branch->isLeaf()); // Empty leaf -		} +        } -		for (S32 i = 0; i < branch->getChildCount(); ++i) -		{  //stretch by child extents -			LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0); -			min.setMin(min, child->mExtents[0]); -			max.setMax(max, child->mExtents[1]); -		} +        for (S32 i = 0; i < branch->getChildCount(); ++i) +        {  //stretch by child extents +            LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0); +            min.setMin(min, child->mExtents[0]); +            max.setMax(max, child->mExtents[1]); +        } -		node->mBounds[0].setAdd(min, max); -		node->mBounds[0].mul(0.5f); +        node->mBounds[0].setAdd(min, max); +        node->mBounds[0].mul(0.5f); -		node->mBounds[1].setSub(max,min); -		node->mBounds[1].mul(0.5f); -	} +        node->mBounds[1].setSub(max,min); +        node->mBounds[1].mul(0.5f); +    }  };  //------------------------------------------------------------------- @@ -457,91 +457,91 @@ public:  LLProfile::Face* LLProfile::addCap(S16 faceID)  { -	Face *face   = vector_append(mFaces, 1); -	 -	face->mIndex = 0; -	face->mCount = mTotal; -	face->mScaleU= 1.0f; -	face->mCap   = TRUE; -	face->mFaceID = faceID; -	return face; +    Face *face   = vector_append(mFaces, 1); + +    face->mIndex = 0; +    face->mCount = mTotal; +    face->mScaleU= 1.0f; +    face->mCap   = TRUE; +    face->mFaceID = faceID; +    return face;  }  LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BOOL flat)  { -	Face *face   = vector_append(mFaces, 1); -	 -	face->mIndex = i; -	face->mCount = count; -	face->mScaleU= scaleU; +    Face *face   = vector_append(mFaces, 1); -	face->mFlat = flat; -	face->mCap   = FALSE; -	face->mFaceID = faceID; -	return face; +    face->mIndex = i; +    face->mCount = count; +    face->mScaleU= scaleU; + +    face->mFlat = flat; +    face->mCap   = FALSE; +    face->mFaceID = faceID; +    return face;  }  //static  S32 LLProfile::getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split)  { // this is basically LLProfile::genNGon stripped down to only the operations that influence the number of points -	S32 np = 0; - -	// Generate an n-sided "circular" path. -	// 0 is (1,0), and we go counter-clockwise along a circular path from there. -	F32 t, t_step, t_first, t_fraction; -	 -	F32 begin  = params.getBegin(); -	F32 end    = params.getEnd(); - -	t_step = 1.0f / sides; -	 -	t_first = floor(begin * sides) / (F32)sides; - -	// pt1 is the first point on the fractional face. -	// Starting t and ang values for the first face -	t = t_first; -	 -	// Increment to the next point. -	// pt2 is the end point on the fractional face -	t += t_step; -	 -	t_fraction = (begin - t_first)*sides; - -	// Only use if it's not almost exactly on an edge. -	if (t_fraction < 0.9999f) -	{ -		np++; -	} - -	// There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02 -	while (t < end) -	{ -		// Iterate through all the integer steps of t. -		np++; - -		t += t_step; -	} - -	t_fraction = (end - (t - t_step))*sides; - -	// Find the fraction that we need to add to the end point. -	t_fraction = (end - (t - t_step))*sides; -	if (t_fraction > 0.0001f) -	{ -		np++; -	} - -	// If we're sliced, the profile is open. -	if ((end - begin)*ang_scale < 0.99f) -	{ -		if (params.getHollow() <= 0) -		{ -			// put center point if not hollow. -			np++; -		} -	} -	 -	return np; +    S32 np = 0; + +    // Generate an n-sided "circular" path. +    // 0 is (1,0), and we go counter-clockwise along a circular path from there. +    F32 t, t_step, t_first, t_fraction; + +    F32 begin  = params.getBegin(); +    F32 end    = params.getEnd(); + +    t_step = 1.0f / sides; + +    t_first = floor(begin * sides) / (F32)sides; + +    // pt1 is the first point on the fractional face. +    // Starting t and ang values for the first face +    t = t_first; + +    // Increment to the next point. +    // pt2 is the end point on the fractional face +    t += t_step; + +    t_fraction = (begin - t_first)*sides; + +    // Only use if it's not almost exactly on an edge. +    if (t_fraction < 0.9999f) +    { +        np++; +    } + +    // There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02 +    while (t < end) +    { +        // Iterate through all the integer steps of t. +        np++; + +        t += t_step; +    } + +    t_fraction = (end - (t - t_step))*sides; + +    // Find the fraction that we need to add to the end point. +    t_fraction = (end - (t - t_step))*sides; +    if (t_fraction > 0.0001f) +    { +        np++; +    } + +    // If we're sliced, the profile is open. +    if ((end - begin)*ang_scale < 0.99f) +    { +        if (params.getHollow() <= 0) +        { +            // put center point if not hollow. +            np++; +        } +    } + +    return np;  }  // What is the bevel parameter used for? - DJS 04/05/02 @@ -549,129 +549,129 @@ S32 LLProfile::getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 of  // filleted and chamfered corners  void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split)  { -	// Generate an n-sided "circular" path. -	// 0 is (1,0), and we go counter-clockwise along a circular path from there. -	static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; -	F32 scale = 0.5f; -	F32 t, t_step, t_first, t_fraction, ang, ang_step; -	LLVector4a pt1,pt2; - -	F32 begin  = params.getBegin(); -	F32 end    = params.getEnd(); - -	t_step = 1.0f / sides; -	ang_step = 2.0f*F_PI*t_step*ang_scale; - -	// Scale to have size "match" scale.  Compensates to get object to generally fill bounding box. - -	S32 total_sides = ll_round(sides / ang_scale);	// Total number of sides all around - -	if (total_sides < 8) -	{ -		scale = tableScale[total_sides]; -	} - -	t_first = floor(begin * sides) / (F32)sides; - -	// pt1 is the first point on the fractional face. -	// Starting t and ang values for the first face -	t = t_first; -	ang = 2.0f*F_PI*(t*ang_scale + offset); -	pt1.set(cos(ang)*scale,sin(ang)*scale, t); - -	// Increment to the next point. -	// pt2 is the end point on the fractional face -	t += t_step; -	ang += ang_step; -	pt2.set(cos(ang)*scale,sin(ang)*scale,t); - -	t_fraction = (begin - t_first)*sides; - -	// Only use if it's not almost exactly on an edge. -	if (t_fraction < 0.9999f) -	{ -		LLVector4a new_pt; -		new_pt.setLerp(pt1, pt2, t_fraction); -		mProfile.push_back(new_pt); -	} - -	// There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02 -	while (t < end) -	{ -		// Iterate through all the integer steps of t. -		pt1.set(cos(ang)*scale,sin(ang)*scale,t); - -		if (mProfile.size() > 0) { -			LLVector4a p = mProfile[mProfile.size()-1]; -			for (S32 i = 0; i < split && mProfile.size() > 0; i++) { -				//mProfile.push_back(p+(pt1-p) * 1.0f/(float)(split+1) * (float)(i+1)); -				LLVector4a new_pt; -				new_pt.setSub(pt1, p); -				new_pt.mul(1.0f/(float)(split+1) * (float)(i+1)); -				new_pt.add(p); -				mProfile.push_back(new_pt); -			} -		} -		mProfile.push_back(pt1); - -		t += t_step; -		ang += ang_step; -	} - -	t_fraction = (end - (t - t_step))*sides; - -	// pt1 is the first point on the fractional face -	// pt2 is the end point on the fractional face -	pt2.set(cos(ang)*scale,sin(ang)*scale,t); - -	// Find the fraction that we need to add to the end point. -	t_fraction = (end - (t - t_step))*sides; -	if (t_fraction > 0.0001f) -	{ -		LLVector4a new_pt; -		new_pt.setLerp(pt1, pt2, t_fraction); -		 -		if (mProfile.size() > 0) { -			LLVector4a p = mProfile[mProfile.size()-1]; -			for (S32 i = 0; i < split && mProfile.size() > 0; i++) { -				//mProfile.push_back(p+(new_pt-p) * 1.0f/(float)(split+1) * (float)(i+1)); - -				LLVector4a pt1; -				pt1.setSub(new_pt, p); -				pt1.mul(1.0f/(float)(split+1) * (float)(i+1)); -				pt1.add(p); -				mProfile.push_back(pt1); -			} -		} -		mProfile.push_back(new_pt); -	} - -	// If we're sliced, the profile is open. -	if ((end - begin)*ang_scale < 0.99f) -	{ -		if ((end - begin)*ang_scale > 0.5f) -		{ -			mConcave = TRUE; -		} -		else -		{ -			mConcave = FALSE; -		} -		mOpen = TRUE; -		if (params.getHollow() <= 0) -		{ -			// put center point if not hollow. -			mProfile.push_back(LLVector4a(0,0,0)); -		} -	} -	else -	{ -		// The profile isn't open. -		mOpen = FALSE; -		mConcave = FALSE; -	} - -	mTotal = mProfile.size(); +    // Generate an n-sided "circular" path. +    // 0 is (1,0), and we go counter-clockwise along a circular path from there. +    static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; +    F32 scale = 0.5f; +    F32 t, t_step, t_first, t_fraction, ang, ang_step; +    LLVector4a pt1,pt2; + +    F32 begin  = params.getBegin(); +    F32 end    = params.getEnd(); + +    t_step = 1.0f / sides; +    ang_step = 2.0f*F_PI*t_step*ang_scale; + +    // Scale to have size "match" scale.  Compensates to get object to generally fill bounding box. + +    S32 total_sides = ll_round(sides / ang_scale);  // Total number of sides all around + +    if (total_sides < 8) +    { +        scale = tableScale[total_sides]; +    } + +    t_first = floor(begin * sides) / (F32)sides; + +    // pt1 is the first point on the fractional face. +    // Starting t and ang values for the first face +    t = t_first; +    ang = 2.0f*F_PI*(t*ang_scale + offset); +    pt1.set(cos(ang)*scale,sin(ang)*scale, t); + +    // Increment to the next point. +    // pt2 is the end point on the fractional face +    t += t_step; +    ang += ang_step; +    pt2.set(cos(ang)*scale,sin(ang)*scale,t); + +    t_fraction = (begin - t_first)*sides; + +    // Only use if it's not almost exactly on an edge. +    if (t_fraction < 0.9999f) +    { +        LLVector4a new_pt; +        new_pt.setLerp(pt1, pt2, t_fraction); +        mProfile.push_back(new_pt); +    } + +    // There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02 +    while (t < end) +    { +        // Iterate through all the integer steps of t. +        pt1.set(cos(ang)*scale,sin(ang)*scale,t); + +        if (mProfile.size() > 0) { +            LLVector4a p = mProfile[mProfile.size()-1]; +            for (S32 i = 0; i < split && mProfile.size() > 0; i++) { +                //mProfile.push_back(p+(pt1-p) * 1.0f/(float)(split+1) * (float)(i+1)); +                LLVector4a new_pt; +                new_pt.setSub(pt1, p); +                new_pt.mul(1.0f/(float)(split+1) * (float)(i+1)); +                new_pt.add(p); +                mProfile.push_back(new_pt); +            } +        } +        mProfile.push_back(pt1); + +        t += t_step; +        ang += ang_step; +    } + +    t_fraction = (end - (t - t_step))*sides; + +    // pt1 is the first point on the fractional face +    // pt2 is the end point on the fractional face +    pt2.set(cos(ang)*scale,sin(ang)*scale,t); + +    // Find the fraction that we need to add to the end point. +    t_fraction = (end - (t - t_step))*sides; +    if (t_fraction > 0.0001f) +    { +        LLVector4a new_pt; +        new_pt.setLerp(pt1, pt2, t_fraction); + +        if (mProfile.size() > 0) { +            LLVector4a p = mProfile[mProfile.size()-1]; +            for (S32 i = 0; i < split && mProfile.size() > 0; i++) { +                //mProfile.push_back(p+(new_pt-p) * 1.0f/(float)(split+1) * (float)(i+1)); + +                LLVector4a pt1; +                pt1.setSub(new_pt, p); +                pt1.mul(1.0f/(float)(split+1) * (float)(i+1)); +                pt1.add(p); +                mProfile.push_back(pt1); +            } +        } +        mProfile.push_back(new_pt); +    } + +    // If we're sliced, the profile is open. +    if ((end - begin)*ang_scale < 0.99f) +    { +        if ((end - begin)*ang_scale > 0.5f) +        { +            mConcave = TRUE; +        } +        else +        { +            mConcave = FALSE; +        } +        mOpen = TRUE; +        if (params.getHollow() <= 0) +        { +            // put center point if not hollow. +            mProfile.push_back(LLVector4a(0,0,0)); +        } +    } +    else +    { +        // The profile isn't open. +        mOpen = FALSE; +        mConcave = FALSE; +    } + +    mTotal = mProfile.size();  }  // Hollow is percent of the original bounding box, not of this particular @@ -679,603 +679,603 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3  // a swept square.  LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split)  { -	// Note that addHole will NOT work for non-"circular" profiles, if we ever decide to use them. +    // Note that addHole will NOT work for non-"circular" profiles, if we ever decide to use them. -	// Total add has number of vertices on outside. -	mTotalOut = mTotal; +    // Total add has number of vertices on outside. +    mTotalOut = mTotal; -	// Why is the "bevel" parameter -1? DJS 04/05/02 -	genNGon(params, llfloor(sides),offset,-1, ang_scale, split); +    // Why is the "bevel" parameter -1? DJS 04/05/02 +    genNGon(params, llfloor(sides),offset,-1, ang_scale, split); -	Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat); +    Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat); -	static thread_local LLAlignedArray<LLVector4a,64> pt; -	pt.resize(mTotal) ; +    static thread_local LLAlignedArray<LLVector4a,64> pt; +    pt.resize(mTotal) ; -	for (S32 i=mTotalOut;i<mTotal;i++) -	{ -		pt[i] = mProfile[i]; -		pt[i].mul(box_hollow); -	} +    for (S32 i=mTotalOut;i<mTotal;i++) +    { +        pt[i] = mProfile[i]; +        pt[i].mul(box_hollow); +    } -	S32 j=mTotal-1; -	for (S32 i=mTotalOut;i<mTotal;i++) -	{ -		mProfile[i] = pt[j--]; -	} +    S32 j=mTotal-1; +    for (S32 i=mTotalOut;i<mTotal;i++) +    { +        mProfile[i] = pt[j--]; +    } -	for (S32 i=0;i<(S32)mFaces.size();i++)  -	{ -		if (mFaces[i].mCap) -		{ -			mFaces[i].mCount *= 2; -		} -	} +    for (S32 i=0;i<(S32)mFaces.size();i++) +    { +        if (mFaces[i].mCap) +        { +            mFaces[i].mCount *= 2; +        } +    } -	return face; +    return face;  }  //static  S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, -						 BOOL is_sculpted, S32 sculpt_size) +                         BOOL is_sculpted, S32 sculpt_size)  { // this is basically LLProfile::generate stripped down to only operations that influence the number of points -	if (detail < MIN_LOD) -	{ -		detail = MIN_LOD; -	} - -	// Generate the face data -	F32 hollow = params.getHollow(); - -	S32 np = 0; - -	switch (params.getCurveType() & LL_PCODE_PROFILE_MASK) -	{ -	case LL_PCODE_PROFILE_SQUARE: -		{ -			np = getNumNGonPoints(params, 4,-0.375, 0, 1, split); -		 -			if (hollow) -			{ -				np *= 2; -			} -		} -		break; -	case  LL_PCODE_PROFILE_ISOTRI: -	case  LL_PCODE_PROFILE_RIGHTTRI: -	case  LL_PCODE_PROFILE_EQUALTRI: -		{ -			np = getNumNGonPoints(params, 3,0, 0, 1, split); -						 -			if (hollow) -			{ -				np *= 2; -			} -		} -		break; -	case LL_PCODE_PROFILE_CIRCLE: -		{ -			// If this has a square hollow, we should adjust the -			// number of faces a bit so that the geometry lines up. -			U8 hole_type=0; -			F32 circle_detail = MIN_DETAIL_FACES * detail; -			if (hollow) -			{ -				hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; -				if (hole_type == LL_PCODE_HOLE_SQUARE) -				{ -					// Snap to the next multiple of four sides, -					// so that corners line up. -					circle_detail = llceil(circle_detail / 4.0f) * 4.0f; -				} -			} - -			S32 sides = (S32)circle_detail; - -			if (is_sculpted) -				sides = sculpt_size; -			 -			np = getNumNGonPoints(params, sides); -			 -			if (hollow) -			{ -				np *= 2; -			} -		} -		break; -	case LL_PCODE_PROFILE_CIRCLE_HALF: -		{ -			// If this has a square hollow, we should adjust the -			// number of faces a bit so that the geometry lines up. -			U8 hole_type=0; -			// Number of faces is cut in half because it's only a half-circle. -			F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f; -			if (hollow) -			{ -				hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; -				if (hole_type == LL_PCODE_HOLE_SQUARE) -				{ -					// Snap to the next multiple of four sides (div 2), -					// so that corners line up. -					circle_detail = llceil(circle_detail / 2.0f) * 2.0f; -				} -			} -			np = getNumNGonPoints(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f); -			 -			if (hollow) -			{ -				np *= 2; -			} - -			// Special case for openness of sphere -			if ((params.getEnd() - params.getBegin()) < 1.f) -			{ -			} -			else if (!hollow) -			{ -				np++; -			} -		} -		break; -	default: -	   break; -	}; - -	 -	return np; +    if (detail < MIN_LOD) +    { +        detail = MIN_LOD; +    } + +    // Generate the face data +    F32 hollow = params.getHollow(); + +    S32 np = 0; + +    switch (params.getCurveType() & LL_PCODE_PROFILE_MASK) +    { +    case LL_PCODE_PROFILE_SQUARE: +        { +            np = getNumNGonPoints(params, 4,-0.375, 0, 1, split); + +            if (hollow) +            { +                np *= 2; +            } +        } +        break; +    case  LL_PCODE_PROFILE_ISOTRI: +    case  LL_PCODE_PROFILE_RIGHTTRI: +    case  LL_PCODE_PROFILE_EQUALTRI: +        { +            np = getNumNGonPoints(params, 3,0, 0, 1, split); + +            if (hollow) +            { +                np *= 2; +            } +        } +        break; +    case LL_PCODE_PROFILE_CIRCLE: +        { +            // If this has a square hollow, we should adjust the +            // number of faces a bit so that the geometry lines up. +            U8 hole_type=0; +            F32 circle_detail = MIN_DETAIL_FACES * detail; +            if (hollow) +            { +                hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; +                if (hole_type == LL_PCODE_HOLE_SQUARE) +                { +                    // Snap to the next multiple of four sides, +                    // so that corners line up. +                    circle_detail = llceil(circle_detail / 4.0f) * 4.0f; +                } +            } + +            S32 sides = (S32)circle_detail; + +            if (is_sculpted) +                sides = sculpt_size; + +            np = getNumNGonPoints(params, sides); + +            if (hollow) +            { +                np *= 2; +            } +        } +        break; +    case LL_PCODE_PROFILE_CIRCLE_HALF: +        { +            // If this has a square hollow, we should adjust the +            // number of faces a bit so that the geometry lines up. +            U8 hole_type=0; +            // Number of faces is cut in half because it's only a half-circle. +            F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f; +            if (hollow) +            { +                hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; +                if (hole_type == LL_PCODE_HOLE_SQUARE) +                { +                    // Snap to the next multiple of four sides (div 2), +                    // so that corners line up. +                    circle_detail = llceil(circle_detail / 2.0f) * 2.0f; +                } +            } +            np = getNumNGonPoints(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f); + +            if (hollow) +            { +                np *= 2; +            } + +            // Special case for openness of sphere +            if ((params.getEnd() - params.getBegin()) < 1.f) +            { +            } +            else if (!hollow) +            { +                np++; +            } +        } +        break; +    default: +       break; +    }; + + +    return np;  }  BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, -						 BOOL is_sculpted, S32 sculpt_size) -{ -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - -	if ((!mDirty) && (!is_sculpted)) -	{ -		return FALSE; -	} -	mDirty = FALSE; - -	if (detail < MIN_LOD) -	{ -		LL_INFOS() << "Generating profile with LOD < MIN_LOD.  CLAMPING" << LL_ENDL; -		detail = MIN_LOD; -	} - -	mProfile.resize(0); -	mFaces.resize(0); - -	// Generate the face data -	S32 i; -	F32 begin = params.getBegin(); -	F32 end = params.getEnd(); -	F32 hollow = params.getHollow(); - -	// Quick validation to eliminate some server crashes. -	if (begin > end - 0.01f) -	{ -		LL_WARNS() << "LLProfile::generate() assertion failed (begin >= end)" << LL_ENDL; -		return FALSE; -	} - -	S32 face_num = 0; - -	switch (params.getCurveType() & LL_PCODE_PROFILE_MASK) -	{ -	case LL_PCODE_PROFILE_SQUARE: -		{ -			genNGon(params, 4,-0.375, 0, 1, split); -			if (path_open) -			{ -				addCap (LL_FACE_PATH_BEGIN); -			} - -			for (i = llfloor(begin * 4.f); i < llfloor(end * 4.f + .999f); i++) -			{ -				addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE); -			} - -			LLVector4a scale(1,1,4,1); - -			for (i = 0; i <(S32) mProfile.size(); i++) -			{ -				// Scale by 4 to generate proper tex coords. -				mProfile[i].mul(scale); -				llassert(mProfile[i].isFinite3()); -			} - -			if (hollow) -			{ -				switch (params.getCurveType() & LL_PCODE_HOLE_MASK) -				{ -				case LL_PCODE_HOLE_TRIANGLE: -					// This offset is not correct, but we can't change it now... DK 11/17/04 -				  	addHole(params, TRUE, 3, -0.375f, hollow, 1.f, split); -					break; -				case LL_PCODE_HOLE_CIRCLE: -					// TODO: Compute actual detail levels for cubes -				  	addHole(params, FALSE, MIN_DETAIL_FACES * detail, -0.375f, hollow, 1.f); -					break; -				case LL_PCODE_HOLE_SAME: -				case LL_PCODE_HOLE_SQUARE: -				default: -					addHole(params, TRUE, 4, -0.375f, hollow, 1.f, split); -					break; -				} -			} -			 -			if (path_open) { -				mFaces[0].mCount = mTotal; -			} -		} -		break; -	case  LL_PCODE_PROFILE_ISOTRI: -	case  LL_PCODE_PROFILE_RIGHTTRI: -	case  LL_PCODE_PROFILE_EQUALTRI: -		{ -			genNGon(params, 3,0, 0, 1, split); -			LLVector4a scale(1,1,3,1); -			for (i = 0; i <(S32) mProfile.size(); i++) -			{ -				// Scale by 3 to generate proper tex coords. -				mProfile[i].mul(scale); -				llassert(mProfile[i].isFinite3()); -			} - -			if (path_open) -			{ -				addCap(LL_FACE_PATH_BEGIN); -			} - -			for (i = llfloor(begin * 3.f); i < llfloor(end * 3.f + .999f); i++) -			{ -				addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE); -			} -			if (hollow) -			{ -				// Swept triangles need smaller hollowness values, -				// because the triangle doesn't fill the bounding box. -				F32 triangle_hollow = hollow / 2.f; - -				switch (params.getCurveType() & LL_PCODE_HOLE_MASK) -				{ -				case LL_PCODE_HOLE_CIRCLE: -					// TODO: Actually generate level of detail for triangles -					addHole(params, FALSE, MIN_DETAIL_FACES * detail, 0, triangle_hollow, 1.f); -					break; -				case LL_PCODE_HOLE_SQUARE: -					addHole(params, TRUE, 4, 0, triangle_hollow, 1.f, split); -					break; -				case LL_PCODE_HOLE_SAME: -				case LL_PCODE_HOLE_TRIANGLE: -				default: -					addHole(params, TRUE, 3, 0, triangle_hollow, 1.f, split); -					break; -				} -			} -		} -		break; -	case LL_PCODE_PROFILE_CIRCLE: -		{ -			// If this has a square hollow, we should adjust the -			// number of faces a bit so that the geometry lines up. -			U8 hole_type=0; -			F32 circle_detail = MIN_DETAIL_FACES * detail; -			if (hollow) -			{ -				hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; -				if (hole_type == LL_PCODE_HOLE_SQUARE) -				{ -					// Snap to the next multiple of four sides, -					// so that corners line up. -					circle_detail = llceil(circle_detail / 4.0f) * 4.0f; -				} -			} - -			S32 sides = (S32)circle_detail; - -			if (is_sculpted) -				sides = sculpt_size; -			 -			genNGon(params, sides); -			 -			if (path_open) -			{ -				addCap (LL_FACE_PATH_BEGIN); -			} - -			if (mOpen && !hollow) -			{ -				addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE); -			} -			else -			{ -				addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE); -			} - -			if (hollow) -			{ -				switch (hole_type) -				{ -				case LL_PCODE_HOLE_SQUARE: -					addHole(params, TRUE, 4, 0, hollow, 1.f, split); -					break; -				case LL_PCODE_HOLE_TRIANGLE: -					addHole(params, TRUE, 3, 0, hollow, 1.f, split); -					break; -				case LL_PCODE_HOLE_CIRCLE: -				case LL_PCODE_HOLE_SAME: -				default: -					addHole(params, FALSE, circle_detail, 0, hollow, 1.f); -					break; -				} -			} -		} -		break; -	case LL_PCODE_PROFILE_CIRCLE_HALF: -		{ -			// If this has a square hollow, we should adjust the -			// number of faces a bit so that the geometry lines up. -			U8 hole_type=0; -			// Number of faces is cut in half because it's only a half-circle. -			F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f; -			if (hollow) -			{ -				hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; -				if (hole_type == LL_PCODE_HOLE_SQUARE) -				{ -					// Snap to the next multiple of four sides (div 2), -					// so that corners line up. -					circle_detail = llceil(circle_detail / 2.0f) * 2.0f; -				} -			} -			genNGon(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f); -			if (path_open) -			{ -				addCap(LL_FACE_PATH_BEGIN); -			} -			if (mOpen && !params.getHollow()) -			{ -				addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE); -			} -			else -			{ -				addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE); -			} - -			if (hollow) -			{ -				switch (hole_type) -				{ -				case LL_PCODE_HOLE_SQUARE: -					addHole(params, TRUE, 2, 0.5f, hollow, 0.5f, split); -					break; -				case LL_PCODE_HOLE_TRIANGLE: -					addHole(params, TRUE, 3,  0.5f, hollow, 0.5f, split); -					break; -				case LL_PCODE_HOLE_CIRCLE: -				case LL_PCODE_HOLE_SAME: -				default: -					addHole(params, FALSE, circle_detail,  0.5f, hollow, 0.5f); -					break; -				} -			} - -			// Special case for openness of sphere -			if ((params.getEnd() - params.getBegin()) < 1.f) -			{ -				mOpen = TRUE; -			} -			else if (!hollow) -			{ -				mOpen = FALSE; -				mProfile.push_back(mProfile[0]); -				mTotal++; -			} -		} -		break; -	default: -	    LL_ERRS() << "Unknown profile: getCurveType()=" << params.getCurveType() << LL_ENDL; -		break; -	}; - -	if (path_open) -	{ -		addCap(LL_FACE_PATH_END); // bottom -	} -	 -	if ( mOpen) // interior edge caps -	{ -		addFace(mTotal-1, 2,0.5,LL_FACE_PROFILE_BEGIN, TRUE);  - -		if (hollow) -		{ -			addFace(mTotalOut-1, 2,0.5,LL_FACE_PROFILE_END, TRUE); -		} -		else -		{ -			addFace(mTotal-2, 2,0.5,LL_FACE_PROFILE_END, TRUE); -		} -	} -	 -	return TRUE; +                         BOOL is_sculpted, S32 sculpt_size) +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + +    if ((!mDirty) && (!is_sculpted)) +    { +        return FALSE; +    } +    mDirty = FALSE; + +    if (detail < MIN_LOD) +    { +        LL_INFOS() << "Generating profile with LOD < MIN_LOD.  CLAMPING" << LL_ENDL; +        detail = MIN_LOD; +    } + +    mProfile.resize(0); +    mFaces.resize(0); + +    // Generate the face data +    S32 i; +    F32 begin = params.getBegin(); +    F32 end = params.getEnd(); +    F32 hollow = params.getHollow(); + +    // Quick validation to eliminate some server crashes. +    if (begin > end - 0.01f) +    { +        LL_WARNS() << "LLProfile::generate() assertion failed (begin >= end)" << LL_ENDL; +        return FALSE; +    } + +    S32 face_num = 0; + +    switch (params.getCurveType() & LL_PCODE_PROFILE_MASK) +    { +    case LL_PCODE_PROFILE_SQUARE: +        { +            genNGon(params, 4,-0.375, 0, 1, split); +            if (path_open) +            { +                addCap (LL_FACE_PATH_BEGIN); +            } + +            for (i = llfloor(begin * 4.f); i < llfloor(end * 4.f + .999f); i++) +            { +                addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE); +            } + +            LLVector4a scale(1,1,4,1); + +            for (i = 0; i <(S32) mProfile.size(); i++) +            { +                // Scale by 4 to generate proper tex coords. +                mProfile[i].mul(scale); +                llassert(mProfile[i].isFinite3()); +            } + +            if (hollow) +            { +                switch (params.getCurveType() & LL_PCODE_HOLE_MASK) +                { +                case LL_PCODE_HOLE_TRIANGLE: +                    // This offset is not correct, but we can't change it now... DK 11/17/04 +                    addHole(params, TRUE, 3, -0.375f, hollow, 1.f, split); +                    break; +                case LL_PCODE_HOLE_CIRCLE: +                    // TODO: Compute actual detail levels for cubes +                    addHole(params, FALSE, MIN_DETAIL_FACES * detail, -0.375f, hollow, 1.f); +                    break; +                case LL_PCODE_HOLE_SAME: +                case LL_PCODE_HOLE_SQUARE: +                default: +                    addHole(params, TRUE, 4, -0.375f, hollow, 1.f, split); +                    break; +                } +            } + +            if (path_open) { +                mFaces[0].mCount = mTotal; +            } +        } +        break; +    case  LL_PCODE_PROFILE_ISOTRI: +    case  LL_PCODE_PROFILE_RIGHTTRI: +    case  LL_PCODE_PROFILE_EQUALTRI: +        { +            genNGon(params, 3,0, 0, 1, split); +            LLVector4a scale(1,1,3,1); +            for (i = 0; i <(S32) mProfile.size(); i++) +            { +                // Scale by 3 to generate proper tex coords. +                mProfile[i].mul(scale); +                llassert(mProfile[i].isFinite3()); +            } + +            if (path_open) +            { +                addCap(LL_FACE_PATH_BEGIN); +            } + +            for (i = llfloor(begin * 3.f); i < llfloor(end * 3.f + .999f); i++) +            { +                addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE); +            } +            if (hollow) +            { +                // Swept triangles need smaller hollowness values, +                // because the triangle doesn't fill the bounding box. +                F32 triangle_hollow = hollow / 2.f; + +                switch (params.getCurveType() & LL_PCODE_HOLE_MASK) +                { +                case LL_PCODE_HOLE_CIRCLE: +                    // TODO: Actually generate level of detail for triangles +                    addHole(params, FALSE, MIN_DETAIL_FACES * detail, 0, triangle_hollow, 1.f); +                    break; +                case LL_PCODE_HOLE_SQUARE: +                    addHole(params, TRUE, 4, 0, triangle_hollow, 1.f, split); +                    break; +                case LL_PCODE_HOLE_SAME: +                case LL_PCODE_HOLE_TRIANGLE: +                default: +                    addHole(params, TRUE, 3, 0, triangle_hollow, 1.f, split); +                    break; +                } +            } +        } +        break; +    case LL_PCODE_PROFILE_CIRCLE: +        { +            // If this has a square hollow, we should adjust the +            // number of faces a bit so that the geometry lines up. +            U8 hole_type=0; +            F32 circle_detail = MIN_DETAIL_FACES * detail; +            if (hollow) +            { +                hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; +                if (hole_type == LL_PCODE_HOLE_SQUARE) +                { +                    // Snap to the next multiple of four sides, +                    // so that corners line up. +                    circle_detail = llceil(circle_detail / 4.0f) * 4.0f; +                } +            } + +            S32 sides = (S32)circle_detail; + +            if (is_sculpted) +                sides = sculpt_size; + +            genNGon(params, sides); + +            if (path_open) +            { +                addCap (LL_FACE_PATH_BEGIN); +            } + +            if (mOpen && !hollow) +            { +                addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE); +            } +            else +            { +                addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE); +            } + +            if (hollow) +            { +                switch (hole_type) +                { +                case LL_PCODE_HOLE_SQUARE: +                    addHole(params, TRUE, 4, 0, hollow, 1.f, split); +                    break; +                case LL_PCODE_HOLE_TRIANGLE: +                    addHole(params, TRUE, 3, 0, hollow, 1.f, split); +                    break; +                case LL_PCODE_HOLE_CIRCLE: +                case LL_PCODE_HOLE_SAME: +                default: +                    addHole(params, FALSE, circle_detail, 0, hollow, 1.f); +                    break; +                } +            } +        } +        break; +    case LL_PCODE_PROFILE_CIRCLE_HALF: +        { +            // If this has a square hollow, we should adjust the +            // number of faces a bit so that the geometry lines up. +            U8 hole_type=0; +            // Number of faces is cut in half because it's only a half-circle. +            F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f; +            if (hollow) +            { +                hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; +                if (hole_type == LL_PCODE_HOLE_SQUARE) +                { +                    // Snap to the next multiple of four sides (div 2), +                    // so that corners line up. +                    circle_detail = llceil(circle_detail / 2.0f) * 2.0f; +                } +            } +            genNGon(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f); +            if (path_open) +            { +                addCap(LL_FACE_PATH_BEGIN); +            } +            if (mOpen && !params.getHollow()) +            { +                addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE); +            } +            else +            { +                addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE); +            } + +            if (hollow) +            { +                switch (hole_type) +                { +                case LL_PCODE_HOLE_SQUARE: +                    addHole(params, TRUE, 2, 0.5f, hollow, 0.5f, split); +                    break; +                case LL_PCODE_HOLE_TRIANGLE: +                    addHole(params, TRUE, 3,  0.5f, hollow, 0.5f, split); +                    break; +                case LL_PCODE_HOLE_CIRCLE: +                case LL_PCODE_HOLE_SAME: +                default: +                    addHole(params, FALSE, circle_detail,  0.5f, hollow, 0.5f); +                    break; +                } +            } + +            // Special case for openness of sphere +            if ((params.getEnd() - params.getBegin()) < 1.f) +            { +                mOpen = TRUE; +            } +            else if (!hollow) +            { +                mOpen = FALSE; +                mProfile.push_back(mProfile[0]); +                mTotal++; +            } +        } +        break; +    default: +        LL_ERRS() << "Unknown profile: getCurveType()=" << params.getCurveType() << LL_ENDL; +        break; +    }; + +    if (path_open) +    { +        addCap(LL_FACE_PATH_END); // bottom +    } + +    if ( mOpen) // interior edge caps +    { +        addFace(mTotal-1, 2,0.5,LL_FACE_PROFILE_BEGIN, TRUE); + +        if (hollow) +        { +            addFace(mTotalOut-1, 2,0.5,LL_FACE_PROFILE_END, TRUE); +        } +        else +        { +            addFace(mTotal-2, 2,0.5,LL_FACE_PROFILE_END, TRUE); +        } +    } + +    return TRUE;  }  BOOL LLProfileParams::importFile(LLFILE *fp)  { -	const S32 BUFSIZE = 16384; -	char buffer[BUFSIZE];	/* Flawfinder: ignore */ -	// *NOTE: changing the size or type of these buffers will require -	// changing the sscanf below. -	char keyword[256];	/* Flawfinder: ignore */ -	char valuestr[256];	/* Flawfinder: ignore */ -	keyword[0] = 0; -	valuestr[0] = 0; -	F32 tempF32; -	U32 tempU32; - -	while (!feof(fp)) -	{ -		if (fgets(buffer, BUFSIZE, fp) == NULL) -		{ -			buffer[0] = '\0'; -		} -		 -		sscanf(	/* Flawfinder: ignore */ -			buffer, -			" %255s %255s", -			keyword, valuestr); -		if (!strcmp("{", keyword)) -		{ -			continue; -		} -		if (!strcmp("}",keyword)) -		{ -			break; -		} -		else if (!strcmp("curve", keyword)) -		{ -			sscanf(valuestr,"%d",&tempU32); -			setCurveType((U8) tempU32); -		} -		else if (!strcmp("begin",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setBegin(tempF32); -		} -		else if (!strcmp("end",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setEnd(tempF32); -		} -		else if (!strcmp("hollow",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setHollow(tempF32); -		} -		else -		{ -			LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL; -		} -	} - -	return TRUE; +    const S32 BUFSIZE = 16384; +    char buffer[BUFSIZE];   /* Flawfinder: ignore */ +    // *NOTE: changing the size or type of these buffers will require +    // changing the sscanf below. +    char keyword[256];  /* Flawfinder: ignore */ +    char valuestr[256]; /* Flawfinder: ignore */ +    keyword[0] = 0; +    valuestr[0] = 0; +    F32 tempF32; +    U32 tempU32; + +    while (!feof(fp)) +    { +        if (fgets(buffer, BUFSIZE, fp) == NULL) +        { +            buffer[0] = '\0'; +        } + +        sscanf( /* Flawfinder: ignore */ +            buffer, +            " %255s %255s", +            keyword, valuestr); +        if (!strcmp("{", keyword)) +        { +            continue; +        } +        if (!strcmp("}",keyword)) +        { +            break; +        } +        else if (!strcmp("curve", keyword)) +        { +            sscanf(valuestr,"%d",&tempU32); +            setCurveType((U8) tempU32); +        } +        else if (!strcmp("begin",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setBegin(tempF32); +        } +        else if (!strcmp("end",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setEnd(tempF32); +        } +        else if (!strcmp("hollow",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setHollow(tempF32); +        } +        else +        { +            LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL; +        } +    } + +    return TRUE;  }  BOOL LLProfileParams::exportFile(LLFILE *fp) const  { -	fprintf(fp,"\t\tprofile 0\n"); -	fprintf(fp,"\t\t{\n"); -	fprintf(fp,"\t\t\tcurve\t%d\n", getCurveType()); -	fprintf(fp,"\t\t\tbegin\t%g\n", getBegin()); -	fprintf(fp,"\t\t\tend\t%g\n", getEnd()); -	fprintf(fp,"\t\t\thollow\t%g\n", getHollow()); -	fprintf(fp, "\t\t}\n"); -	return TRUE; +    fprintf(fp,"\t\tprofile 0\n"); +    fprintf(fp,"\t\t{\n"); +    fprintf(fp,"\t\t\tcurve\t%d\n", getCurveType()); +    fprintf(fp,"\t\t\tbegin\t%g\n", getBegin()); +    fprintf(fp,"\t\t\tend\t%g\n", getEnd()); +    fprintf(fp,"\t\t\thollow\t%g\n", getHollow()); +    fprintf(fp, "\t\t}\n"); +    return TRUE;  }  BOOL LLProfileParams::importLegacyStream(std::istream& input_stream)  { -	const S32 BUFSIZE = 16384; -	char buffer[BUFSIZE];	/* Flawfinder: ignore */ -	// *NOTE: changing the size or type of these buffers will require -	// changing the sscanf below. -	char keyword[256];	/* Flawfinder: ignore */ -	char valuestr[256];	/* Flawfinder: ignore */ -	keyword[0] = 0; -	valuestr[0] = 0; -	F32 tempF32; -	U32 tempU32; - -	while (input_stream.good()) -	{ -		input_stream.getline(buffer, BUFSIZE); -		sscanf(	/* Flawfinder: ignore */ -			buffer, -			" %255s %255s", -			keyword, -			valuestr); -		if (!strcmp("{", keyword)) -		{ -			continue; -		} -		if (!strcmp("}",keyword)) -		{ -			break; -		} -		else if (!strcmp("curve", keyword)) -		{ -			sscanf(valuestr,"%d",&tempU32); -			setCurveType((U8) tempU32); -		} -		else if (!strcmp("begin",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setBegin(tempF32); -		} -		else if (!strcmp("end",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setEnd(tempF32); -		} -		else if (!strcmp("hollow",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setHollow(tempF32); -		} -		else -		{ - 		LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL; -		} -	} - -	return TRUE; +    const S32 BUFSIZE = 16384; +    char buffer[BUFSIZE];   /* Flawfinder: ignore */ +    // *NOTE: changing the size or type of these buffers will require +    // changing the sscanf below. +    char keyword[256];  /* Flawfinder: ignore */ +    char valuestr[256]; /* Flawfinder: ignore */ +    keyword[0] = 0; +    valuestr[0] = 0; +    F32 tempF32; +    U32 tempU32; + +    while (input_stream.good()) +    { +        input_stream.getline(buffer, BUFSIZE); +        sscanf( /* Flawfinder: ignore */ +            buffer, +            " %255s %255s", +            keyword, +            valuestr); +        if (!strcmp("{", keyword)) +        { +            continue; +        } +        if (!strcmp("}",keyword)) +        { +            break; +        } +        else if (!strcmp("curve", keyword)) +        { +            sscanf(valuestr,"%d",&tempU32); +            setCurveType((U8) tempU32); +        } +        else if (!strcmp("begin",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setBegin(tempF32); +        } +        else if (!strcmp("end",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setEnd(tempF32); +        } +        else if (!strcmp("hollow",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setHollow(tempF32); +        } +        else +        { +        LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL; +        } +    } + +    return TRUE;  }  BOOL LLProfileParams::exportLegacyStream(std::ostream& output_stream) const  { -	output_stream <<"\t\tprofile 0\n"; -	output_stream <<"\t\t{\n"; -	output_stream <<"\t\t\tcurve\t" << (S32) getCurveType() << "\n"; -	output_stream <<"\t\t\tbegin\t" << getBegin() << "\n"; -	output_stream <<"\t\t\tend\t" << getEnd() << "\n"; -	output_stream <<"\t\t\thollow\t" << getHollow() << "\n"; -	output_stream << "\t\t}\n"; -	return TRUE; +    output_stream <<"\t\tprofile 0\n"; +    output_stream <<"\t\t{\n"; +    output_stream <<"\t\t\tcurve\t" << (S32) getCurveType() << "\n"; +    output_stream <<"\t\t\tbegin\t" << getBegin() << "\n"; +    output_stream <<"\t\t\tend\t" << getEnd() << "\n"; +    output_stream <<"\t\t\thollow\t" << getHollow() << "\n"; +    output_stream << "\t\t}\n"; +    return TRUE;  }  LLSD LLProfileParams::asLLSD() const  { -	LLSD sd; +    LLSD sd; -	sd["curve"] = getCurveType(); -	sd["begin"] = getBegin(); -	sd["end"] = getEnd(); -	sd["hollow"] = getHollow(); -	return sd; +    sd["curve"] = getCurveType(); +    sd["begin"] = getBegin(); +    sd["end"] = getEnd(); +    sd["hollow"] = getHollow(); +    return sd;  }  bool LLProfileParams::fromLLSD(LLSD& sd)  { -	setCurveType(sd["curve"].asInteger()); -	setBegin((F32)sd["begin"].asReal()); -	setEnd((F32)sd["end"].asReal()); -	setHollow((F32)sd["hollow"].asReal()); -	return true; +    setCurveType(sd["curve"].asInteger()); +    setBegin((F32)sd["begin"].asReal()); +    setEnd((F32)sd["end"].asReal()); +    setHollow((F32)sd["hollow"].asReal()); +    return true;  }  void LLProfileParams::copyParams(const LLProfileParams ¶ms)  { -	setCurveType(params.getCurveType()); -	setBegin(params.getBegin()); -	setEnd(params.getEnd()); -	setHollow(params.getHollow()); +    setCurveType(params.getCurveType()); +    setBegin(params.getBegin()); +    setEnd(params.getEnd()); +    setHollow(params.getHollow());  } @@ -1285,760 +1285,760 @@ LLPath::~LLPath()  S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)  { //this is basically LLPath::genNGon stripped down to only operations that influence the number of points added -	S32 ret = 0; +    S32 ret = 0; -	F32 step= 1.0f / sides; -	F32 t	= params.getBegin(); -	ret = 1; -	 -	t+=step; +    F32 step= 1.0f / sides; +    F32 t   = params.getBegin(); +    ret = 1; -	// Snap to a quantized parameter, so that cut does not -	// affect most sample points. -	t = ((S32)(t * sides)) / (F32)sides; +    t+=step; -	// Run through the non-cut dependent points. -	while (t < params.getEnd()) -	{ -		ret++; -		t+=step; -	} +    // Snap to a quantized parameter, so that cut does not +    // affect most sample points. +    t = ((S32)(t * sides)) / (F32)sides; -	ret++; +    // Run through the non-cut dependent points. +    while (t < params.getEnd()) +    { +        ret++; +        t+=step; +    } + +    ret++; -	return ret; +    return ret;  }  void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)  { -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - -	// Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. -	static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; - -	F32 revolutions = params.getRevolutions(); -	F32 skew		= params.getSkew(); -	F32 skew_mag	= fabs(skew); -	F32 hole_x		= params.getScaleX() * (1.0f - skew_mag); -	F32 hole_y		= params.getScaleY(); - -	// Calculate taper begin/end for x,y (Negative means taper the beginning) -	F32 taper_x_begin	= 1.0f; -	F32 taper_x_end		= 1.0f - params.getTaperX(); -	F32	taper_y_begin	= 1.0f; -	F32	taper_y_end		= 1.0f - params.getTaperY(); - -	if ( taper_x_end > 1.0f ) -	{ -		// Flip tapering. -		taper_x_begin	= 2.0f - taper_x_end; -		taper_x_end		= 1.0f; -	} -	if ( taper_y_end > 1.0f ) -	{ -		// Flip tapering. -		taper_y_begin	= 2.0f - taper_y_end; -		taper_y_end		= 1.0f; -	} - -	// For spheres, the radius is usually zero. -	F32 radius_start = 0.5f; -	if (sides < 8) -	{ -		radius_start = tableScale[sides]; -	} - -	// Scale the radius to take the hole size into account. -	radius_start *= 1.0f - hole_y; -	 -	// Now check the radius offset to calculate the start,end radius.  (Negative means -	// decrease the start radius instead). -	F32 radius_end    = radius_start; -	F32 radius_offset = params.getRadiusOffset(); -	if (radius_offset < 0.f) -	{ -		radius_start *= 1.f + radius_offset; -	} -	else -	{ -		radius_end   *= 1.f - radius_offset; -	}	 - -	// Is the path NOT a closed loop? -	mOpen = ( (params.getEnd()*end_scale - params.getBegin() < 1.0f) || -		      (skew_mag > 0.001f) || -			  (fabs(taper_x_end - taper_x_begin) > 0.001f) || -			  (fabs(taper_y_end - taper_y_begin) > 0.001f) || -			  (fabs(radius_end - radius_start) > 0.001f) ); - -	F32 ang, c, s; -	LLQuaternion twist, qang; -	PathPt *pt; -	LLVector3 path_axis (1.f, 0.f, 0.f); -	//LLVector3 twist_axis(0.f, 0.f, 1.f); -	F32 twist_begin = params.getTwistBegin() * twist_scale; -	F32 twist_end	= params.getTwist() * twist_scale; - -	// We run through this once before the main loop, to make sure -	// the path begins at the correct cut. -	F32 step= 1.0f / sides; -	F32 t	= params.getBegin(); -	pt		= mPath.append(1); -	ang		= 2.0f*F_PI*revolutions * t; -	s		= sin(ang)*lerp(radius_start, radius_end, t);	 -	c		= cos(ang)*lerp(radius_start, radius_end, t); - - -	pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) -					  + lerp(-skew ,skew, t) * 0.5f, -					c + lerp(0,params.getShear().mV[1],s),  -					s); -	pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), -		hole_y * lerp(taper_y_begin, taper_y_end, t), -		0,1); -	pt->mTexT  = t; - -	// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 -	twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); -	// Rotate the point around the circle's center. -	qang.setQuat   (ang,path_axis); - -	LLMatrix3 rot(twist * qang); - -	pt->mRot.loadu(rot); - -	t+=step; - -	// Snap to a quantized parameter, so that cut does not -	// affect most sample points. -	t = ((S32)(t * sides)) / (F32)sides; - -	// Run through the non-cut dependent points. -	while (t < params.getEnd()) -	{ -		pt		= mPath.append(1); - -		ang = 2.0f*F_PI*revolutions * t; -		c   = cos(ang)*lerp(radius_start, radius_end, t); -		s   = sin(ang)*lerp(radius_start, radius_end, t); - -		pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) -					      + lerp(-skew ,skew, t) * 0.5f, -						c + lerp(0,params.getShear().mV[1],s),  -						s); - -		pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), -					hole_y * lerp(taper_y_begin, taper_y_end, t), -					0,1); -		pt->mTexT  = t; - -		// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 -		twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); -		// Rotate the point around the circle's center. -		qang.setQuat   (ang,path_axis); -		LLMatrix3 tmp(twist*qang); -		pt->mRot.loadu(tmp); - -		t+=step; -	} - -	// Make one final pass for the end cut. -	t = params.getEnd(); -	pt		= mPath.append(1); -	ang = 2.0f*F_PI*revolutions * t; -	c   = cos(ang)*lerp(radius_start, radius_end, t); -	s   = sin(ang)*lerp(radius_start, radius_end, t); - -	pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) -					  + lerp(-skew ,skew, t) * 0.5f, -					c + lerp(0,params.getShear().mV[1],s),  -					s); -	pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), -				   hole_y * lerp(taper_y_begin, taper_y_end, t), -				   0,1); -	pt->mTexT  = t; - -	// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 -	twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); -	// Rotate the point around the circle's center. -	qang.setQuat   (ang,path_axis); -	LLMatrix3 tmp(twist*qang); -	pt->mRot.loadu(tmp); - -	mTotal = mPath.size(); +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + +    // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. +    static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; + +    F32 revolutions = params.getRevolutions(); +    F32 skew        = params.getSkew(); +    F32 skew_mag    = fabs(skew); +    F32 hole_x      = params.getScaleX() * (1.0f - skew_mag); +    F32 hole_y      = params.getScaleY(); + +    // Calculate taper begin/end for x,y (Negative means taper the beginning) +    F32 taper_x_begin   = 1.0f; +    F32 taper_x_end     = 1.0f - params.getTaperX(); +    F32 taper_y_begin   = 1.0f; +    F32 taper_y_end     = 1.0f - params.getTaperY(); + +    if ( taper_x_end > 1.0f ) +    { +        // Flip tapering. +        taper_x_begin   = 2.0f - taper_x_end; +        taper_x_end     = 1.0f; +    } +    if ( taper_y_end > 1.0f ) +    { +        // Flip tapering. +        taper_y_begin   = 2.0f - taper_y_end; +        taper_y_end     = 1.0f; +    } + +    // For spheres, the radius is usually zero. +    F32 radius_start = 0.5f; +    if (sides < 8) +    { +        radius_start = tableScale[sides]; +    } + +    // Scale the radius to take the hole size into account. +    radius_start *= 1.0f - hole_y; + +    // Now check the radius offset to calculate the start,end radius.  (Negative means +    // decrease the start radius instead). +    F32 radius_end    = radius_start; +    F32 radius_offset = params.getRadiusOffset(); +    if (radius_offset < 0.f) +    { +        radius_start *= 1.f + radius_offset; +    } +    else +    { +        radius_end   *= 1.f - radius_offset; +    } + +    // Is the path NOT a closed loop? +    mOpen = ( (params.getEnd()*end_scale - params.getBegin() < 1.0f) || +              (skew_mag > 0.001f) || +              (fabs(taper_x_end - taper_x_begin) > 0.001f) || +              (fabs(taper_y_end - taper_y_begin) > 0.001f) || +              (fabs(radius_end - radius_start) > 0.001f) ); + +    F32 ang, c, s; +    LLQuaternion twist, qang; +    PathPt *pt; +    LLVector3 path_axis (1.f, 0.f, 0.f); +    //LLVector3 twist_axis(0.f, 0.f, 1.f); +    F32 twist_begin = params.getTwistBegin() * twist_scale; +    F32 twist_end   = params.getTwist() * twist_scale; + +    // We run through this once before the main loop, to make sure +    // the path begins at the correct cut. +    F32 step= 1.0f / sides; +    F32 t   = params.getBegin(); +    pt      = mPath.append(1); +    ang     = 2.0f*F_PI*revolutions * t; +    s       = sin(ang)*lerp(radius_start, radius_end, t); +    c       = cos(ang)*lerp(radius_start, radius_end, t); + + +    pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) +                      + lerp(-skew ,skew, t) * 0.5f, +                    c + lerp(0,params.getShear().mV[1],s), +                    s); +    pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), +        hole_y * lerp(taper_y_begin, taper_y_end, t), +        0,1); +    pt->mTexT  = t; + +    // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 +    twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); +    // Rotate the point around the circle's center. +    qang.setQuat   (ang,path_axis); + +    LLMatrix3 rot(twist * qang); + +    pt->mRot.loadu(rot); + +    t+=step; + +    // Snap to a quantized parameter, so that cut does not +    // affect most sample points. +    t = ((S32)(t * sides)) / (F32)sides; + +    // Run through the non-cut dependent points. +    while (t < params.getEnd()) +    { +        pt      = mPath.append(1); + +        ang = 2.0f*F_PI*revolutions * t; +        c   = cos(ang)*lerp(radius_start, radius_end, t); +        s   = sin(ang)*lerp(radius_start, radius_end, t); + +        pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) +                          + lerp(-skew ,skew, t) * 0.5f, +                        c + lerp(0,params.getShear().mV[1],s), +                        s); + +        pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), +                    hole_y * lerp(taper_y_begin, taper_y_end, t), +                    0,1); +        pt->mTexT  = t; + +        // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 +        twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); +        // Rotate the point around the circle's center. +        qang.setQuat   (ang,path_axis); +        LLMatrix3 tmp(twist*qang); +        pt->mRot.loadu(tmp); + +        t+=step; +    } + +    // Make one final pass for the end cut. +    t = params.getEnd(); +    pt      = mPath.append(1); +    ang = 2.0f*F_PI*revolutions * t; +    c   = cos(ang)*lerp(radius_start, radius_end, t); +    s   = sin(ang)*lerp(radius_start, radius_end, t); + +    pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) +                      + lerp(-skew ,skew, t) * 0.5f, +                    c + lerp(0,params.getShear().mV[1],s), +                    s); +    pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), +                   hole_y * lerp(taper_y_begin, taper_y_end, t), +                   0,1); +    pt->mTexT  = t; + +    // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02 +    twist.setQuat  (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1); +    // Rotate the point around the circle's center. +    qang.setQuat   (ang,path_axis); +    LLMatrix3 tmp(twist*qang); +    pt->mRot.loadu(tmp); + +    mTotal = mPath.size();  }  const LLVector2 LLPathParams::getBeginScale() const  { -	LLVector2 begin_scale(1.f, 1.f); -	if (getScaleX() > 1) -	{ -		begin_scale.mV[0] = 2-getScaleX(); -	} -	if (getScaleY() > 1) -	{ -		begin_scale.mV[1] = 2-getScaleY(); -	} -	return begin_scale; +    LLVector2 begin_scale(1.f, 1.f); +    if (getScaleX() > 1) +    { +        begin_scale.mV[0] = 2-getScaleX(); +    } +    if (getScaleY() > 1) +    { +        begin_scale.mV[1] = 2-getScaleY(); +    } +    return begin_scale;  }  const LLVector2 LLPathParams::getEndScale() const  { -	LLVector2 end_scale(1.f, 1.f); -	if (getScaleX() < 1) -	{ -		end_scale.mV[0] = getScaleX(); -	} -	if (getScaleY() < 1) -	{ -		end_scale.mV[1] = getScaleY(); -	} -	return end_scale; +    LLVector2 end_scale(1.f, 1.f); +    if (getScaleX() < 1) +    { +        end_scale.mV[0] = getScaleX(); +    } +    if (getScaleY() < 1) +    { +        end_scale.mV[1] = getScaleY(); +    } +    return end_scale;  }  S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail)  { // this is basically LLPath::generate stripped down to only the operations that influence the number of points -	if (detail < MIN_LOD) -	{ -		detail = MIN_LOD; -	} +    if (detail < MIN_LOD) +    { +        detail = MIN_LOD; +    } -	S32 np = 2; // hardcode for line +    S32 np = 2; // hardcode for line -	// Is this 0xf0 mask really necessary?  DK 03/02/05 +    // Is this 0xf0 mask really necessary?  DK 03/02/05 -	switch (params.getCurveType() & 0xf0) -	{ -	default: -	case LL_PCODE_PATH_LINE: -		{ -			// Take the begin/end twist into account for detail. -			np    = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2; -		} -		break; +    switch (params.getCurveType() & 0xf0) +    { +    default: +    case LL_PCODE_PATH_LINE: +        { +            // Take the begin/end twist into account for detail. +            np    = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2; +        } +        break; -	case LL_PCODE_PATH_CIRCLE: -		{ -			// Increase the detail as the revolutions and twist increase. -			F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist()); +    case LL_PCODE_PATH_CIRCLE: +        { +            // Increase the detail as the revolutions and twist increase. +            F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist()); -			S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions()); +            S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions()); -			np = sides; -		} -		break; +            np = sides; +        } +        break; -	case LL_PCODE_PATH_CIRCLE2: -		{ -			//genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); -			np = getNumNGonPoints(params, llfloor(MIN_DETAIL_FACES * detail)); -		} -		break; +    case LL_PCODE_PATH_CIRCLE2: +        { +            //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); +            np = getNumNGonPoints(params, llfloor(MIN_DETAIL_FACES * detail)); +        } +        break; -	case LL_PCODE_PATH_TEST: +    case LL_PCODE_PATH_TEST: -		np     = 5; -		break; -	}; +        np     = 5; +        break; +    }; -	return np; +    return np;  }  BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, -					  BOOL is_sculpted, S32 sculpt_size) -{ -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - -	if ((!mDirty) && (!is_sculpted)) -	{ -		return FALSE; -	} - -	if (detail < MIN_LOD) -	{ -		LL_INFOS() << "Generating path with LOD < MIN!  Clamping to 1" << LL_ENDL; -		detail = MIN_LOD; -	} - -	mDirty = FALSE; -	S32 np = 2; // hardcode for line - -	mPath.resize(0); -	mOpen = TRUE; - -	// Is this 0xf0 mask really necessary?  DK 03/02/05 -	switch (params.getCurveType() & 0xf0) -	{ -	default: -	case LL_PCODE_PATH_LINE: -		{ -			// Take the begin/end twist into account for detail. -			np    = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2; -			if (np < split+2) -			{ -				np = split+2; -			} - -			mStep = 1.0f / (np-1); -			 -			mPath.resize(np); - -			LLVector2 start_scale = params.getBeginScale(); -			LLVector2 end_scale = params.getEndScale(); - -			for (S32 i=0;i<np;i++) -			{ -				F32 t = lerp(params.getBegin(),params.getEnd(),(F32)i * mStep); -				mPath[i].mPos.set(lerp(0,params.getShear().mV[0],t), -									 lerp(0,params.getShear().mV[1],t), -									 t - 0.5f); -				LLQuaternion quat; -				quat.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1); -				LLMatrix3 tmp(quat); -				mPath[i].mRot.loadu(tmp); -				mPath[i].mScale.set(lerp(start_scale.mV[0],end_scale.mV[0],t), -									lerp(start_scale.mV[1],end_scale.mV[1],t), -									0,1); -				mPath[i].mTexT        = t; -			} -		} -		break; - -	case LL_PCODE_PATH_CIRCLE: -		{ -			// Increase the detail as the revolutions and twist increase. -			F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist()); - -			S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions()); - -			if (is_sculpted) -				sides = llmax(sculpt_size, 1); -			 -			if (0 < sides) -				genNGon(params, sides); -		} -		break; - -	case LL_PCODE_PATH_CIRCLE2: -		{ -			if (params.getEnd() - params.getBegin() >= 0.99f && -				params.getScaleX() >= .99f) -			{ -				mOpen = FALSE; -			} - -			//genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); -			genNGon(params, llfloor(MIN_DETAIL_FACES * detail)); - -			F32 toggle = 0.5f; -			for (S32 i=0;i<(S32)mPath.size();i++) -			{ -				mPath[i].mPos.getF32ptr()[0] = toggle; -				if (toggle == 0.5f) -					toggle = -0.5f; -				else -					toggle = 0.5f; -			} -		} - -		break; - -	case LL_PCODE_PATH_TEST: - -		np     = 5; -		mStep = 1.0f / (np-1); -		 -		mPath.resize(np); - -		for (S32 i=0;i<np;i++) -		{ -			F32 t = (F32)i * mStep; -			mPath[i].mPos.set(0, -								lerp(0,   -sin(F_PI*params.getTwist()*t)*0.5f,t), -								lerp(-0.5f, cos(F_PI*params.getTwist()*t)*0.5f,t)); -			mPath[i].mScale.set(lerp(1,params.getScale().mV[0],t), -								lerp(1,params.getScale().mV[1],t), 0,1); -			mPath[i].mTexT  = t; -			LLQuaternion quat; -			quat.setQuat(F_PI * params.getTwist() * t,1,0,0); -			LLMatrix3 tmp(quat); -			mPath[i].mRot.loadu(tmp); -		} - -		break; -	}; - -	if (params.getTwist() != params.getTwistBegin()) mOpen = TRUE; - -	//if ((int(fabsf(params.getTwist() - params.getTwistBegin())*100))%100 != 0) { -	//	mOpen = TRUE; -	//} -	 -	return TRUE; +                      BOOL is_sculpted, S32 sculpt_size) +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + +    if ((!mDirty) && (!is_sculpted)) +    { +        return FALSE; +    } + +    if (detail < MIN_LOD) +    { +        LL_INFOS() << "Generating path with LOD < MIN!  Clamping to 1" << LL_ENDL; +        detail = MIN_LOD; +    } + +    mDirty = FALSE; +    S32 np = 2; // hardcode for line + +    mPath.resize(0); +    mOpen = TRUE; + +    // Is this 0xf0 mask really necessary?  DK 03/02/05 +    switch (params.getCurveType() & 0xf0) +    { +    default: +    case LL_PCODE_PATH_LINE: +        { +            // Take the begin/end twist into account for detail. +            np    = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2; +            if (np < split+2) +            { +                np = split+2; +            } + +            mStep = 1.0f / (np-1); + +            mPath.resize(np); + +            LLVector2 start_scale = params.getBeginScale(); +            LLVector2 end_scale = params.getEndScale(); + +            for (S32 i=0;i<np;i++) +            { +                F32 t = lerp(params.getBegin(),params.getEnd(),(F32)i * mStep); +                mPath[i].mPos.set(lerp(0,params.getShear().mV[0],t), +                                     lerp(0,params.getShear().mV[1],t), +                                     t - 0.5f); +                LLQuaternion quat; +                quat.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1); +                LLMatrix3 tmp(quat); +                mPath[i].mRot.loadu(tmp); +                mPath[i].mScale.set(lerp(start_scale.mV[0],end_scale.mV[0],t), +                                    lerp(start_scale.mV[1],end_scale.mV[1],t), +                                    0,1); +                mPath[i].mTexT        = t; +            } +        } +        break; + +    case LL_PCODE_PATH_CIRCLE: +        { +            // Increase the detail as the revolutions and twist increase. +            F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist()); + +            S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions()); + +            if (is_sculpted) +                sides = llmax(sculpt_size, 1); + +            if (0 < sides) +                genNGon(params, sides); +        } +        break; + +    case LL_PCODE_PATH_CIRCLE2: +        { +            if (params.getEnd() - params.getBegin() >= 0.99f && +                params.getScaleX() >= .99f) +            { +                mOpen = FALSE; +            } + +            //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); +            genNGon(params, llfloor(MIN_DETAIL_FACES * detail)); + +            F32 toggle = 0.5f; +            for (S32 i=0;i<(S32)mPath.size();i++) +            { +                mPath[i].mPos.getF32ptr()[0] = toggle; +                if (toggle == 0.5f) +                    toggle = -0.5f; +                else +                    toggle = 0.5f; +            } +        } + +        break; + +    case LL_PCODE_PATH_TEST: + +        np     = 5; +        mStep = 1.0f / (np-1); + +        mPath.resize(np); + +        for (S32 i=0;i<np;i++) +        { +            F32 t = (F32)i * mStep; +            mPath[i].mPos.set(0, +                                lerp(0,   -sin(F_PI*params.getTwist()*t)*0.5f,t), +                                lerp(-0.5f, cos(F_PI*params.getTwist()*t)*0.5f,t)); +            mPath[i].mScale.set(lerp(1,params.getScale().mV[0],t), +                                lerp(1,params.getScale().mV[1],t), 0,1); +            mPath[i].mTexT  = t; +            LLQuaternion quat; +            quat.setQuat(F_PI * params.getTwist() * t,1,0,0); +            LLMatrix3 tmp(quat); +            mPath[i].mRot.loadu(tmp); +        } + +        break; +    }; + +    if (params.getTwist() != params.getTwistBegin()) mOpen = TRUE; + +    //if ((int(fabsf(params.getTwist() - params.getTwistBegin())*100))%100 != 0) { +    //  mOpen = TRUE; +    //} + +    return TRUE;  }  BOOL LLDynamicPath::generate(const LLPathParams& params, F32 detail, S32 split, -							 BOOL is_sculpted, S32 sculpt_size) +                             BOOL is_sculpted, S32 sculpt_size)  { -	mOpen = TRUE; // Draw end caps -	if (getPathLength() == 0) -	{ -		// Path hasn't been generated yet. -		// Some algorithms later assume at least TWO path points. -		resizePath(2); -		LLQuaternion quat; -		quat.setQuat(0,0,0); -		LLMatrix3 tmp(quat); - -		for (U32 i = 0; i < 2; i++) -		{ -			mPath[i].mPos.set(0, 0, 0); -			mPath[i].mRot.loadu(tmp); -			mPath[i].mScale.set(1, 1, 0, 1); -			mPath[i].mTexT = 0; -		} -	} +    mOpen = TRUE; // Draw end caps +    if (getPathLength() == 0) +    { +        // Path hasn't been generated yet. +        // Some algorithms later assume at least TWO path points. +        resizePath(2); +        LLQuaternion quat; +        quat.setQuat(0,0,0); +        LLMatrix3 tmp(quat); + +        for (U32 i = 0; i < 2; i++) +        { +            mPath[i].mPos.set(0, 0, 0); +            mPath[i].mRot.loadu(tmp); +            mPath[i].mScale.set(1, 1, 0, 1); +            mPath[i].mTexT = 0; +        } +    } -	return TRUE; +    return TRUE;  }  BOOL LLPathParams::importFile(LLFILE *fp)  { -	const S32 BUFSIZE = 16384; -	char buffer[BUFSIZE];	/* Flawfinder: ignore */ -	// *NOTE: changing the size or type of these buffers will require -	// changing the sscanf below. -	char keyword[256];	/* Flawfinder: ignore */ -	char valuestr[256];	/* Flawfinder: ignore */ -	keyword[0] = 0; -	valuestr[0] = 0; - -	F32 tempF32; -	F32 x, y; -	U32 tempU32; - -	while (!feof(fp)) -	{ -		if (fgets(buffer, BUFSIZE, fp) == NULL) -		{ -			buffer[0] = '\0'; -		} -		 -		sscanf(	/* Flawfinder: ignore */ -			buffer, -			" %255s %255s", -			keyword, valuestr); -		if (!strcmp("{", keyword)) -		{ -			continue; -		} -		if (!strcmp("}",keyword)) -		{ -			break; -		} -		else if (!strcmp("curve", keyword)) -		{ -			sscanf(valuestr,"%d",&tempU32); -			setCurveType((U8) tempU32); -		} -		else if (!strcmp("begin",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setBegin(tempF32); -		} -		else if (!strcmp("end",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setEnd(tempF32); -		} -		else if (!strcmp("scale",keyword)) -		{ -			// Legacy for one dimensional scale per path -			sscanf(valuestr,"%g",&tempF32); -			setScale(tempF32, tempF32); -		} -		else if (!strcmp("scale_x", keyword)) -		{ -			sscanf(valuestr, "%g", &x); -			setScaleX(x); -		} -		else if (!strcmp("scale_y", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setScaleY(y); -		} -		else if (!strcmp("shear_x", keyword)) -		{ -			sscanf(valuestr, "%g", &x); -			setShearX(x); -		} -		else if (!strcmp("shear_y", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setShearY(y); -		} -		else if (!strcmp("twist",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setTwist(tempF32); -		} -		else if (!strcmp("twist_begin", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setTwistBegin(y); -		} -		else if (!strcmp("radius_offset", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setRadiusOffset(y); -		} -		else if (!strcmp("taper_x", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setTaperX(y); -		} -		else if (!strcmp("taper_y", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setTaperY(y); -		} -		else if (!strcmp("revolutions", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setRevolutions(y); -		} -		else if (!strcmp("skew", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setSkew(y); -		} -		else -		{ -			LL_WARNS() << "unknown keyword " << " in path import" << LL_ENDL; -		} -	} -	return TRUE; +    const S32 BUFSIZE = 16384; +    char buffer[BUFSIZE];   /* Flawfinder: ignore */ +    // *NOTE: changing the size or type of these buffers will require +    // changing the sscanf below. +    char keyword[256];  /* Flawfinder: ignore */ +    char valuestr[256]; /* Flawfinder: ignore */ +    keyword[0] = 0; +    valuestr[0] = 0; + +    F32 tempF32; +    F32 x, y; +    U32 tempU32; + +    while (!feof(fp)) +    { +        if (fgets(buffer, BUFSIZE, fp) == NULL) +        { +            buffer[0] = '\0'; +        } + +        sscanf( /* Flawfinder: ignore */ +            buffer, +            " %255s %255s", +            keyword, valuestr); +        if (!strcmp("{", keyword)) +        { +            continue; +        } +        if (!strcmp("}",keyword)) +        { +            break; +        } +        else if (!strcmp("curve", keyword)) +        { +            sscanf(valuestr,"%d",&tempU32); +            setCurveType((U8) tempU32); +        } +        else if (!strcmp("begin",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setBegin(tempF32); +        } +        else if (!strcmp("end",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setEnd(tempF32); +        } +        else if (!strcmp("scale",keyword)) +        { +            // Legacy for one dimensional scale per path +            sscanf(valuestr,"%g",&tempF32); +            setScale(tempF32, tempF32); +        } +        else if (!strcmp("scale_x", keyword)) +        { +            sscanf(valuestr, "%g", &x); +            setScaleX(x); +        } +        else if (!strcmp("scale_y", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setScaleY(y); +        } +        else if (!strcmp("shear_x", keyword)) +        { +            sscanf(valuestr, "%g", &x); +            setShearX(x); +        } +        else if (!strcmp("shear_y", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setShearY(y); +        } +        else if (!strcmp("twist",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setTwist(tempF32); +        } +        else if (!strcmp("twist_begin", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setTwistBegin(y); +        } +        else if (!strcmp("radius_offset", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setRadiusOffset(y); +        } +        else if (!strcmp("taper_x", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setTaperX(y); +        } +        else if (!strcmp("taper_y", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setTaperY(y); +        } +        else if (!strcmp("revolutions", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setRevolutions(y); +        } +        else if (!strcmp("skew", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setSkew(y); +        } +        else +        { +            LL_WARNS() << "unknown keyword " << " in path import" << LL_ENDL; +        } +    } +    return TRUE;  }  BOOL LLPathParams::exportFile(LLFILE *fp) const  { -	fprintf(fp, "\t\tpath 0\n"); -	fprintf(fp, "\t\t{\n"); -	fprintf(fp, "\t\t\tcurve\t%d\n", getCurveType()); -	fprintf(fp, "\t\t\tbegin\t%g\n", getBegin()); -	fprintf(fp, "\t\t\tend\t%g\n", getEnd()); -	fprintf(fp, "\t\t\tscale_x\t%g\n", getScaleX() ); -	fprintf(fp, "\t\t\tscale_y\t%g\n", getScaleY() ); -	fprintf(fp, "\t\t\tshear_x\t%g\n", getShearX() ); -	fprintf(fp, "\t\t\tshear_y\t%g\n", getShearY() ); -	fprintf(fp,"\t\t\ttwist\t%g\n", getTwist()); -	 -	fprintf(fp,"\t\t\ttwist_begin\t%g\n", getTwistBegin()); -	fprintf(fp,"\t\t\tradius_offset\t%g\n", getRadiusOffset()); -	fprintf(fp,"\t\t\ttaper_x\t%g\n", getTaperX()); -	fprintf(fp,"\t\t\ttaper_y\t%g\n", getTaperY()); -	fprintf(fp,"\t\t\trevolutions\t%g\n", getRevolutions()); -	fprintf(fp,"\t\t\tskew\t%g\n", getSkew()); - -	fprintf(fp, "\t\t}\n"); -	return TRUE; +    fprintf(fp, "\t\tpath 0\n"); +    fprintf(fp, "\t\t{\n"); +    fprintf(fp, "\t\t\tcurve\t%d\n", getCurveType()); +    fprintf(fp, "\t\t\tbegin\t%g\n", getBegin()); +    fprintf(fp, "\t\t\tend\t%g\n", getEnd()); +    fprintf(fp, "\t\t\tscale_x\t%g\n", getScaleX() ); +    fprintf(fp, "\t\t\tscale_y\t%g\n", getScaleY() ); +    fprintf(fp, "\t\t\tshear_x\t%g\n", getShearX() ); +    fprintf(fp, "\t\t\tshear_y\t%g\n", getShearY() ); +    fprintf(fp,"\t\t\ttwist\t%g\n", getTwist()); + +    fprintf(fp,"\t\t\ttwist_begin\t%g\n", getTwistBegin()); +    fprintf(fp,"\t\t\tradius_offset\t%g\n", getRadiusOffset()); +    fprintf(fp,"\t\t\ttaper_x\t%g\n", getTaperX()); +    fprintf(fp,"\t\t\ttaper_y\t%g\n", getTaperY()); +    fprintf(fp,"\t\t\trevolutions\t%g\n", getRevolutions()); +    fprintf(fp,"\t\t\tskew\t%g\n", getSkew()); + +    fprintf(fp, "\t\t}\n"); +    return TRUE;  }  BOOL LLPathParams::importLegacyStream(std::istream& input_stream)  { -	const S32 BUFSIZE = 16384; -	char buffer[BUFSIZE];	/* Flawfinder: ignore */ -	// *NOTE: changing the size or type of these buffers will require -	// changing the sscanf below. -	char keyword[256];	/* Flawfinder: ignore */ -	char valuestr[256];	/* Flawfinder: ignore */ -	keyword[0] = 0; -	valuestr[0] = 0; - -	F32 tempF32; -	F32 x, y; -	U32 tempU32; - -	while (input_stream.good()) -	{ -		input_stream.getline(buffer, BUFSIZE); -		sscanf(	/* Flawfinder: ignore */ -			buffer, -			" %255s %255s", -			keyword, valuestr); -		if (!strcmp("{", keyword)) -		{ -			continue; -		} -		if (!strcmp("}",keyword)) -		{ -			break; -		} -		else if (!strcmp("curve", keyword)) -		{ -			sscanf(valuestr,"%d",&tempU32); -			setCurveType((U8) tempU32); -		} -		else if (!strcmp("begin",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setBegin(tempF32); -		} -		else if (!strcmp("end",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setEnd(tempF32); -		} -		else if (!strcmp("scale",keyword)) -		{ -			// Legacy for one dimensional scale per path -			sscanf(valuestr,"%g",&tempF32); -			setScale(tempF32, tempF32); -		} -		else if (!strcmp("scale_x", keyword)) -		{ -			sscanf(valuestr, "%g", &x); -			setScaleX(x); -		} -		else if (!strcmp("scale_y", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setScaleY(y); -		} -		else if (!strcmp("shear_x", keyword)) -		{ -			sscanf(valuestr, "%g", &x); -			setShearX(x); -		} -		else if (!strcmp("shear_y", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setShearY(y); -		} -		else if (!strcmp("twist",keyword)) -		{ -			sscanf(valuestr,"%g",&tempF32); -			setTwist(tempF32); -		} -		else if (!strcmp("twist_begin", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setTwistBegin(y); -		} -		else if (!strcmp("radius_offset", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setRadiusOffset(y); -		} -		else if (!strcmp("taper_x", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setTaperX(y); -		} -		else if (!strcmp("taper_y", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setTaperY(y); -		} -		else if (!strcmp("revolutions", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setRevolutions(y); -		} -		else if (!strcmp("skew", keyword)) -		{ -			sscanf(valuestr, "%g", &y); -			setSkew(y); -		} -		else -		{ -			LL_WARNS() << "unknown keyword " << " in path import" << LL_ENDL; -		} -	} -	return TRUE; +    const S32 BUFSIZE = 16384; +    char buffer[BUFSIZE];   /* Flawfinder: ignore */ +    // *NOTE: changing the size or type of these buffers will require +    // changing the sscanf below. +    char keyword[256];  /* Flawfinder: ignore */ +    char valuestr[256]; /* Flawfinder: ignore */ +    keyword[0] = 0; +    valuestr[0] = 0; + +    F32 tempF32; +    F32 x, y; +    U32 tempU32; + +    while (input_stream.good()) +    { +        input_stream.getline(buffer, BUFSIZE); +        sscanf( /* Flawfinder: ignore */ +            buffer, +            " %255s %255s", +            keyword, valuestr); +        if (!strcmp("{", keyword)) +        { +            continue; +        } +        if (!strcmp("}",keyword)) +        { +            break; +        } +        else if (!strcmp("curve", keyword)) +        { +            sscanf(valuestr,"%d",&tempU32); +            setCurveType((U8) tempU32); +        } +        else if (!strcmp("begin",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setBegin(tempF32); +        } +        else if (!strcmp("end",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setEnd(tempF32); +        } +        else if (!strcmp("scale",keyword)) +        { +            // Legacy for one dimensional scale per path +            sscanf(valuestr,"%g",&tempF32); +            setScale(tempF32, tempF32); +        } +        else if (!strcmp("scale_x", keyword)) +        { +            sscanf(valuestr, "%g", &x); +            setScaleX(x); +        } +        else if (!strcmp("scale_y", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setScaleY(y); +        } +        else if (!strcmp("shear_x", keyword)) +        { +            sscanf(valuestr, "%g", &x); +            setShearX(x); +        } +        else if (!strcmp("shear_y", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setShearY(y); +        } +        else if (!strcmp("twist",keyword)) +        { +            sscanf(valuestr,"%g",&tempF32); +            setTwist(tempF32); +        } +        else if (!strcmp("twist_begin", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setTwistBegin(y); +        } +        else if (!strcmp("radius_offset", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setRadiusOffset(y); +        } +        else if (!strcmp("taper_x", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setTaperX(y); +        } +        else if (!strcmp("taper_y", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setTaperY(y); +        } +        else if (!strcmp("revolutions", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setRevolutions(y); +        } +        else if (!strcmp("skew", keyword)) +        { +            sscanf(valuestr, "%g", &y); +            setSkew(y); +        } +        else +        { +            LL_WARNS() << "unknown keyword " << " in path import" << LL_ENDL; +        } +    } +    return TRUE;  }  BOOL LLPathParams::exportLegacyStream(std::ostream& output_stream) const  { -	output_stream << "\t\tpath 0\n"; -	output_stream << "\t\t{\n"; -	output_stream << "\t\t\tcurve\t" << (S32) getCurveType() << "\n"; -	output_stream << "\t\t\tbegin\t" << getBegin() << "\n"; -	output_stream << "\t\t\tend\t" << getEnd() << "\n"; -	output_stream << "\t\t\tscale_x\t" << getScaleX()  << "\n"; -	output_stream << "\t\t\tscale_y\t" << getScaleY()  << "\n"; -	output_stream << "\t\t\tshear_x\t" << getShearX()  << "\n"; -	output_stream << "\t\t\tshear_y\t" << getShearY()  << "\n"; -	output_stream <<"\t\t\ttwist\t" << getTwist() << "\n"; -	 -	output_stream <<"\t\t\ttwist_begin\t" << getTwistBegin() << "\n"; -	output_stream <<"\t\t\tradius_offset\t" << getRadiusOffset() << "\n"; -	output_stream <<"\t\t\ttaper_x\t" << getTaperX() << "\n"; -	output_stream <<"\t\t\ttaper_y\t" << getTaperY() << "\n"; -	output_stream <<"\t\t\trevolutions\t" << getRevolutions() << "\n"; -	output_stream <<"\t\t\tskew\t" << getSkew() << "\n"; - -	output_stream << "\t\t}\n"; -	return TRUE; +    output_stream << "\t\tpath 0\n"; +    output_stream << "\t\t{\n"; +    output_stream << "\t\t\tcurve\t" << (S32) getCurveType() << "\n"; +    output_stream << "\t\t\tbegin\t" << getBegin() << "\n"; +    output_stream << "\t\t\tend\t" << getEnd() << "\n"; +    output_stream << "\t\t\tscale_x\t" << getScaleX()  << "\n"; +    output_stream << "\t\t\tscale_y\t" << getScaleY()  << "\n"; +    output_stream << "\t\t\tshear_x\t" << getShearX()  << "\n"; +    output_stream << "\t\t\tshear_y\t" << getShearY()  << "\n"; +    output_stream <<"\t\t\ttwist\t" << getTwist() << "\n"; + +    output_stream <<"\t\t\ttwist_begin\t" << getTwistBegin() << "\n"; +    output_stream <<"\t\t\tradius_offset\t" << getRadiusOffset() << "\n"; +    output_stream <<"\t\t\ttaper_x\t" << getTaperX() << "\n"; +    output_stream <<"\t\t\ttaper_y\t" << getTaperY() << "\n"; +    output_stream <<"\t\t\trevolutions\t" << getRevolutions() << "\n"; +    output_stream <<"\t\t\tskew\t" << getSkew() << "\n"; + +    output_stream << "\t\t}\n"; +    return TRUE;  }  LLSD LLPathParams::asLLSD() const  { -	LLSD sd = LLSD(); -	sd["curve"] = getCurveType(); -	sd["begin"] = getBegin(); -	sd["end"] = getEnd(); -	sd["scale_x"] = getScaleX(); -	sd["scale_y"] = getScaleY(); -	sd["shear_x"] = getShearX(); -	sd["shear_y"] = getShearY(); -	sd["twist"] = getTwist(); -	sd["twist_begin"] = getTwistBegin(); -	sd["radius_offset"] = getRadiusOffset(); -	sd["taper_x"] = getTaperX(); -	sd["taper_y"] = getTaperY(); -	sd["revolutions"] = getRevolutions(); -	sd["skew"] = getSkew(); - -	return sd; +    LLSD sd = LLSD(); +    sd["curve"] = getCurveType(); +    sd["begin"] = getBegin(); +    sd["end"] = getEnd(); +    sd["scale_x"] = getScaleX(); +    sd["scale_y"] = getScaleY(); +    sd["shear_x"] = getShearX(); +    sd["shear_y"] = getShearY(); +    sd["twist"] = getTwist(); +    sd["twist_begin"] = getTwistBegin(); +    sd["radius_offset"] = getRadiusOffset(); +    sd["taper_x"] = getTaperX(); +    sd["taper_y"] = getTaperY(); +    sd["revolutions"] = getRevolutions(); +    sd["skew"] = getSkew(); + +    return sd;  }  bool LLPathParams::fromLLSD(LLSD& sd)  { -	setCurveType(sd["curve"].asInteger()); -	setBegin((F32)sd["begin"].asReal()); -	setEnd((F32)sd["end"].asReal()); -	setScaleX((F32)sd["scale_x"].asReal()); -	setScaleY((F32)sd["scale_y"].asReal()); -	setShearX((F32)sd["shear_x"].asReal()); -	setShearY((F32)sd["shear_y"].asReal()); -	setTwist((F32)sd["twist"].asReal()); -	setTwistBegin((F32)sd["twist_begin"].asReal()); -	setRadiusOffset((F32)sd["radius_offset"].asReal()); -	setTaperX((F32)sd["taper_x"].asReal()); -	setTaperY((F32)sd["taper_y"].asReal()); -	setRevolutions((F32)sd["revolutions"].asReal()); -	setSkew((F32)sd["skew"].asReal()); -	return true; +    setCurveType(sd["curve"].asInteger()); +    setBegin((F32)sd["begin"].asReal()); +    setEnd((F32)sd["end"].asReal()); +    setScaleX((F32)sd["scale_x"].asReal()); +    setScaleY((F32)sd["scale_y"].asReal()); +    setShearX((F32)sd["shear_x"].asReal()); +    setShearY((F32)sd["shear_y"].asReal()); +    setTwist((F32)sd["twist"].asReal()); +    setTwistBegin((F32)sd["twist_begin"].asReal()); +    setRadiusOffset((F32)sd["radius_offset"].asReal()); +    setTaperX((F32)sd["taper_x"].asReal()); +    setTaperY((F32)sd["taper_y"].asReal()); +    setRevolutions((F32)sd["revolutions"].asReal()); +    setSkew((F32)sd["skew"].asReal()); +    return true;  }  void LLPathParams::copyParams(const LLPathParams ¶ms)  { -	setCurveType(params.getCurveType()); -	setBegin(params.getBegin()); -	setEnd(params.getEnd()); -	setScale(params.getScaleX(), params.getScaleY() ); -	setShear(params.getShearX(), params.getShearY() ); -	setTwist(params.getTwist()); -	setTwistBegin(params.getTwistBegin()); -	setRadiusOffset(params.getRadiusOffset()); -	setTaper( params.getTaperX(), params.getTaperY() ); -	setRevolutions(params.getRevolutions()); -	setSkew(params.getSkew()); +    setCurveType(params.getCurveType()); +    setBegin(params.getBegin()); +    setEnd(params.getEnd()); +    setScale(params.getScaleX(), params.getScaleY() ); +    setShear(params.getShearX(), params.getShearY() ); +    setTwist(params.getTwist()); +    setTwistBegin(params.getTwistBegin()); +    setRadiusOffset(params.getRadiusOffset()); +    setTaper( params.getTaperX(), params.getTaperY() ); +    setRevolutions(params.getRevolutions()); +    setSkew(params.getSkew());  }  LLProfile::~LLProfile() @@ -2049,53 +2049,53 @@ LLProfile::~LLProfile()  S32 LLVolume::sNumMeshPoints = 0;  LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL generate_single_face, const BOOL is_unique) -	: mParams(params) -{ -	mUnique = is_unique; -	mFaceMask = 0x0; -	mDetail = detail; -	mSculptLevel = -2; -	mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims -	mIsMeshAssetLoaded = false; +    : mParams(params) +{ +    mUnique = is_unique; +    mFaceMask = 0x0; +    mDetail = detail; +    mSculptLevel = -2; +    mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims +    mIsMeshAssetLoaded = false;      mIsMeshAssetUnavaliable = false; -	mLODScaleBias.setVec(1,1,1); -	mHullPoints = NULL; -	mHullIndices = NULL; -	mNumHullPoints = 0; -	mNumHullIndices = 0; - -	// set defaults -	if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE) -	{ -		mPathp = new LLDynamicPath(); -	} -	else -	{ -		mPathp = new LLPath(); -	} -	mProfilep = new LLProfile(); - -	mGenerateSingleFace = generate_single_face; - -	generate(); -	 -	if ((mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) || mParams.getSculptType() == LL_SCULPT_TYPE_MESH) -	{ -		createVolumeFaces(); -	} +    mLODScaleBias.setVec(1,1,1); +    mHullPoints = NULL; +    mHullIndices = NULL; +    mNumHullPoints = 0; +    mNumHullIndices = 0; + +    // set defaults +    if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE) +    { +        mPathp = new LLDynamicPath(); +    } +    else +    { +        mPathp = new LLPath(); +    } +    mProfilep = new LLProfile(); + +    mGenerateSingleFace = generate_single_face; + +    generate(); + +    if ((mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) || mParams.getSculptType() == LL_SCULPT_TYPE_MESH) +    { +        createVolumeFaces(); +    }  }  void LLVolume::resizePath(S32 length)  { -	mPathp->resizePath(length); -	mVolumeFaces.clear(); -	setDirty(); +    mPathp->resizePath(length); +    mVolumeFaces.clear(); +    setDirty();  }  void LLVolume::regen()  { -	generate(); -	createVolumeFaces(); +    generate(); +    createVolumeFaces();  }  void LLVolume::genTangents(S32 face) @@ -2107,103 +2107,103 @@ void LLVolume::genTangents(S32 face)  LLVolume::~LLVolume()  { -	sNumMeshPoints -= mMesh.size(); -	delete mPathp; +    sNumMeshPoints -= mMesh.size(); +    delete mPathp; -	delete mProfilep; +    delete mProfilep; -	mPathp = NULL; -	mProfilep = NULL; -	mVolumeFaces.clear(); +    mPathp = NULL; +    mProfilep = NULL; +    mVolumeFaces.clear(); -	ll_aligned_free_16(mHullPoints); -	mHullPoints = NULL; -	ll_aligned_free_16(mHullIndices); -	mHullIndices = NULL; +    ll_aligned_free_16(mHullPoints); +    mHullPoints = NULL; +    ll_aligned_free_16(mHullIndices); +    mHullIndices = NULL;  }  BOOL LLVolume::generate()  { -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - -	LL_CHECK_MEMORY -	llassert_always(mProfilep); -	 -	//Added 10.03.05 Dave Parks -	// Split is a parameter to LLProfile::generate that tesselates edges on the profile  -	// to prevent lighting and texture interpolation errors on triangles that are  -	// stretched due to twisting or scaling on the path.   -	S32 split = (S32) ((mDetail)*0.66f); -	 -	if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_LINE && -		(mParams.getPathParams().getScale().mV[0] != 1.0f || -		 mParams.getPathParams().getScale().mV[1] != 1.0f) && -		(mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_SQUARE || -		 mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_ISOTRI || -		 mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_EQUALTRI || -		 mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_RIGHTTRI)) -	{ -		split = 0; -	} -		  -	mLODScaleBias.setVec(0.5f, 0.5f, 0.5f); -	 -	F32 profile_detail = mDetail; -	F32 path_detail = mDetail; - -	if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) -	{ -		U8 path_type = mParams.getPathParams().getCurveType(); -		U8 profile_type = mParams.getProfileParams().getCurveType(); -		if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE) -		{ -			//cylinders don't care about Z-Axis -			mLODScaleBias.setVec(0.6f, 0.6f, 0.0f); -		} -		else if (path_type == LL_PCODE_PATH_CIRCLE) -		{ -			mLODScaleBias.setVec(0.6f, 0.6f, 0.6f); -		} -	} - -	BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split); -	BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split); - -	if (regenPath || regenProf )  -	{ -		S32 sizeS = mPathp->mPath.size(); -		S32 sizeT = mProfilep->mProfile.size(); - -		sNumMeshPoints -= mMesh.size(); -		mMesh.resize(sizeT * sizeS); -		sNumMeshPoints += mMesh.size();		 - -		//generate vertex positions - -		// Run along the path. -		LLVector4a* dst = mMesh.mArray; - -		for (S32 s = 0; s < sizeS; ++s) -		{ -			F32* scale = mPathp->mPath[s].mScale.getF32ptr(); -			 -			F32 sc [] =  -			{ scale[0], 0, 0, 0, -				0, scale[1], 0, 0, -				0, 0, scale[2], 0, -					0, 0, 0, 1 }; -			 -			LLMatrix4 rot((F32*) mPathp->mPath[s].mRot.mMatrix); -			LLMatrix4 scale_mat(sc); -			 -			scale_mat *= rot; -			 -			LLMatrix4a rot_mat; -			rot_mat.loadu(scale_mat); -			 -			LLVector4a* profile = mProfilep->mProfile.mArray; -			LLVector4a* end_profile = profile+sizeT; -			LLVector4a offset = mPathp->mPath[s].mPos; +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + +    LL_CHECK_MEMORY +    llassert_always(mProfilep); + +    //Added 10.03.05 Dave Parks +    // Split is a parameter to LLProfile::generate that tesselates edges on the profile +    // to prevent lighting and texture interpolation errors on triangles that are +    // stretched due to twisting or scaling on the path. +    S32 split = (S32) ((mDetail)*0.66f); + +    if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_LINE && +        (mParams.getPathParams().getScale().mV[0] != 1.0f || +         mParams.getPathParams().getScale().mV[1] != 1.0f) && +        (mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_SQUARE || +         mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_ISOTRI || +         mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_EQUALTRI || +         mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_RIGHTTRI)) +    { +        split = 0; +    } + +    mLODScaleBias.setVec(0.5f, 0.5f, 0.5f); + +    F32 profile_detail = mDetail; +    F32 path_detail = mDetail; + +    if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) +    { +        U8 path_type = mParams.getPathParams().getCurveType(); +        U8 profile_type = mParams.getProfileParams().getCurveType(); +        if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE) +        { +            //cylinders don't care about Z-Axis +            mLODScaleBias.setVec(0.6f, 0.6f, 0.0f); +        } +        else if (path_type == LL_PCODE_PATH_CIRCLE) +        { +            mLODScaleBias.setVec(0.6f, 0.6f, 0.6f); +        } +    } + +    BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split); +    BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split); + +    if (regenPath || regenProf ) +    { +        S32 sizeS = mPathp->mPath.size(); +        S32 sizeT = mProfilep->mProfile.size(); + +        sNumMeshPoints -= mMesh.size(); +        mMesh.resize(sizeT * sizeS); +        sNumMeshPoints += mMesh.size(); + +        //generate vertex positions + +        // Run along the path. +        LLVector4a* dst = mMesh.mArray; + +        for (S32 s = 0; s < sizeS; ++s) +        { +            F32* scale = mPathp->mPath[s].mScale.getF32ptr(); + +            F32 sc [] = +            { scale[0], 0, 0, 0, +                0, scale[1], 0, 0, +                0, 0, scale[2], 0, +                    0, 0, 0, 1 }; + +            LLMatrix4 rot((F32*) mPathp->mPath[s].mRot.mMatrix); +            LLMatrix4 scale_mat(sc); + +            scale_mat *= rot; + +            LLMatrix4a rot_mat; +            rot_mat.loadu(scale_mat); + +            LLVector4a* profile = mProfilep->mProfile.mArray; +            LLVector4a* end_profile = profile+sizeT; +            LLVector4a offset = mPathp->mPath[s].mPos;              // hack to work around MAINT-5660 for debug until we can suss out              // what is wrong with the path generated that inserts NaNs... @@ -2212,241 +2212,241 @@ BOOL LLVolume::generate()                  offset.clear();              } -			LLVector4a tmp; +            LLVector4a tmp; -			// Run along the profile. -			while (profile < end_profile) -			{ -				rot_mat.rotate(*profile++, tmp); -				dst->setAdd(tmp,offset); -				++dst; -			} -		} +            // Run along the profile. +            while (profile < end_profile) +            { +                rot_mat.rotate(*profile++, tmp); +                dst->setAdd(tmp,offset); +                ++dst; +            } +        } -		for (std::vector<LLProfile::Face>::iterator iter = mProfilep->mFaces.begin(); -			 iter != mProfilep->mFaces.end(); ++iter) -		{ -			LLFaceID id = iter->mFaceID; -			mFaceMask |= id; -		} -		LL_CHECK_MEMORY -		return TRUE; -	} +        for (std::vector<LLProfile::Face>::iterator iter = mProfilep->mFaces.begin(); +             iter != mProfilep->mFaces.end(); ++iter) +        { +            LLFaceID id = iter->mFaceID; +            mFaceMask |= id; +        } +        LL_CHECK_MEMORY +        return TRUE; +    } -	LL_CHECK_MEMORY -	return FALSE; +    LL_CHECK_MEMORY +    return FALSE;  }  void LLVolumeFace::VertexData::init()  { -	if (!mData) -	{ -		mData = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*2); -	} +    if (!mData) +    { +        mData = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*2); +    }  }  LLVolumeFace::VertexData::VertexData()  { -	mData = NULL; -	init(); +    mData = NULL; +    init();  } -	 +  LLVolumeFace::VertexData::VertexData(const VertexData& rhs)  { -	mData = NULL; -	*this = rhs; +    mData = NULL; +    *this = rhs;  }  const LLVolumeFace::VertexData& LLVolumeFace::VertexData::operator=(const LLVolumeFace::VertexData& rhs)  { -	if (this != &rhs) -	{ -		init(); -		LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 2*sizeof(LLVector4a)); -		mTexCoord = rhs.mTexCoord; -	} -	return *this; +    if (this != &rhs) +    { +        init(); +        LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 2*sizeof(LLVector4a)); +        mTexCoord = rhs.mTexCoord; +    } +    return *this;  }  LLVolumeFace::VertexData::~VertexData()  { -	ll_aligned_free_16(mData); -	mData = NULL; +    ll_aligned_free_16(mData); +    mData = NULL;  }  LLVector4a& LLVolumeFace::VertexData::getPosition()  { -	return mData[POSITION]; +    return mData[POSITION];  }  LLVector4a& LLVolumeFace::VertexData::getNormal()  { -	return mData[NORMAL]; +    return mData[NORMAL];  }  const LLVector4a& LLVolumeFace::VertexData::getPosition() const  { -	return mData[POSITION]; +    return mData[POSITION];  }  const LLVector4a& LLVolumeFace::VertexData::getNormal() const  { -	return mData[NORMAL]; +    return mData[NORMAL];  }  void LLVolumeFace::VertexData::setPosition(const LLVector4a& pos)  { -	mData[POSITION] = pos; +    mData[POSITION] = pos;  }  void LLVolumeFace::VertexData::setNormal(const LLVector4a& norm)  { -	mData[NORMAL] = norm; +    mData[NORMAL] = norm;  }  bool LLVolumeFace::VertexData::operator<(const LLVolumeFace::VertexData& rhs)const  { -	const F32* lp = this->getPosition().getF32ptr(); -	const F32* rp = rhs.getPosition().getF32ptr(); +    const F32* lp = this->getPosition().getF32ptr(); +    const F32* rp = rhs.getPosition().getF32ptr(); -	if (lp[0] != rp[0]) -	{ -		return lp[0] < rp[0]; -	} +    if (lp[0] != rp[0]) +    { +        return lp[0] < rp[0]; +    } -	if (rp[1] != lp[1]) -	{ -		return lp[1] < rp[1]; -	} +    if (rp[1] != lp[1]) +    { +        return lp[1] < rp[1]; +    } -	if (rp[2] != lp[2]) -	{ -		return lp[2] < rp[2]; -	} +    if (rp[2] != lp[2]) +    { +        return lp[2] < rp[2]; +    } -	lp = getNormal().getF32ptr(); -	rp = rhs.getNormal().getF32ptr(); +    lp = getNormal().getF32ptr(); +    rp = rhs.getNormal().getF32ptr(); -	if (lp[0] != rp[0]) -	{ -		return lp[0] < rp[0]; -	} +    if (lp[0] != rp[0]) +    { +        return lp[0] < rp[0]; +    } -	if (rp[1] != lp[1]) -	{ -		return lp[1] < rp[1]; -	} +    if (rp[1] != lp[1]) +    { +        return lp[1] < rp[1]; +    } -	if (rp[2] != lp[2]) -	{ -		return lp[2] < rp[2]; -	} +    if (rp[2] != lp[2]) +    { +        return lp[2] < rp[2]; +    } -	if (mTexCoord.mV[0] != rhs.mTexCoord.mV[0]) -	{ -		return mTexCoord.mV[0] < rhs.mTexCoord.mV[0]; -	} +    if (mTexCoord.mV[0] != rhs.mTexCoord.mV[0]) +    { +        return mTexCoord.mV[0] < rhs.mTexCoord.mV[0]; +    } -	return mTexCoord.mV[1] < rhs.mTexCoord.mV[1]; +    return mTexCoord.mV[1] < rhs.mTexCoord.mV[1];  }  bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)const  { -	return mData[POSITION].equals3(rhs.getPosition()) && -			mData[NORMAL].equals3(rhs.getNormal()) && -			mTexCoord == rhs.mTexCoord; +    return mData[POSITION].equals3(rhs.getPosition()) && +            mData[NORMAL].equals3(rhs.getNormal()) && +            mTexCoord == rhs.mTexCoord;  }  bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const  { -	bool retval = false; +    bool retval = false; -	const F32 epsilon = 0.00001f; +    const F32 epsilon = 0.00001f; -	if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) &&  -		fabs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && -		fabs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon) -	{ -		if (angle_cutoff > 1.f) -		{ -			retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon)); -		} -		else -		{ -			F32 cur_angle = rhs.mData[NORMAL].dot3(mData[NORMAL]).getF32(); -			retval = cur_angle > angle_cutoff; -		} -	} +    if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) && +        fabs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && +        fabs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon) +    { +        if (angle_cutoff > 1.f) +        { +            retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon)); +        } +        else +        { +            F32 cur_angle = rhs.mData[NORMAL].dot3(mData[NORMAL]).getF32(); +            retval = cur_angle > angle_cutoff; +        } +    } -	return retval; +    return retval;  }  bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  { -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME -	//input stream is now pointing at a zlib compressed block of LLSD -	//decompress block -	LLSD mdl; -	U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, is, size); -	if (uzip_result != LLUZipHelper::ZR_OK) -	{ -		LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; -		return false; -	} -	return unpackVolumeFacesInternal(mdl); +    //input stream is now pointing at a zlib compressed block of LLSD +    //decompress block +    LLSD mdl; +    U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, is, size); +    if (uzip_result != LLUZipHelper::ZR_OK) +    { +        LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; +        return false; +    } +    return unpackVolumeFacesInternal(mdl);  }  bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size)  { -	//input data is now pointing at a zlib compressed block of LLSD -	//decompress block -	LLSD mdl; -	U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size); -	if (uzip_result != LLUZipHelper::ZR_OK) -	{ -		LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; -		return false; -	} -	return unpackVolumeFacesInternal(mdl); +    //input data is now pointing at a zlib compressed block of LLSD +    //decompress block +    LLSD mdl; +    U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size); +    if (uzip_result != LLUZipHelper::ZR_OK) +    { +        LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; +        return false; +    } +    return unpackVolumeFacesInternal(mdl);  }  bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)  { -	{ -		U32 face_count = mdl.size(); - -		if (face_count == 0) -		{ //no faces unpacked, treat as failed decode -			LL_WARNS() << "found no faces!" << LL_ENDL; -			return false; -		} - -		mVolumeFaces.resize(face_count); - -		for (size_t i = 0; i < face_count; ++i) -		{ -			LLVolumeFace& face = mVolumeFaces[i]; - -			if (mdl[i].has("NoGeometry")) -			{ //face has no geometry, continue -				face.resizeIndices(3); -				face.resizeVertices(1); -				face.mPositions->clear(); -				face.mNormals->clear(); -				face.mTexCoords->setZero(); -				memset(face.mIndices, 0, sizeof(U16)*3); -				continue; -			} - -			LLSD::Binary pos = mdl[i]["Position"]; -			LLSD::Binary norm = mdl[i]["Normal"]; +    { +        U32 face_count = mdl.size(); + +        if (face_count == 0) +        { //no faces unpacked, treat as failed decode +            LL_WARNS() << "found no faces!" << LL_ENDL; +            return false; +        } + +        mVolumeFaces.resize(face_count); + +        for (size_t i = 0; i < face_count; ++i) +        { +            LLVolumeFace& face = mVolumeFaces[i]; + +            if (mdl[i].has("NoGeometry")) +            { //face has no geometry, continue +                face.resizeIndices(3); +                face.resizeVertices(1); +                face.mPositions->clear(); +                face.mNormals->clear(); +                face.mTexCoords->setZero(); +                memset(face.mIndices, 0, sizeof(U16)*3); +                continue; +            } + +            LLSD::Binary pos = mdl[i]["Position"]; +            LLSD::Binary norm = mdl[i]["Normal"];              LLSD::Binary tangent = mdl[i]["Tangent"]; -			LLSD::Binary tc = mdl[i]["TexCoord0"]; -			LLSD::Binary idx = mdl[i]["TriangleList"]; +            LLSD::Binary tc = mdl[i]["TexCoord0"]; +            LLSD::Binary idx = mdl[i]["TriangleList"]; -			//copy out indices +            //copy out indices              S32 num_indices = idx.size() / 2;              const S32 indices_to_discard = num_indices % 3;              if (indices_to_discard > 0) @@ -2462,22 +2462,22 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)                  LL_WARNS() << "Failed to allocate " << num_indices << " indices for face index: " << i << " Total: " << face_count << LL_ENDL;                  continue;              } -			 -			if (idx.empty() || face.mNumIndices < 3) -			{ //why is there an empty index list? -				LL_WARNS() << "Empty face present! Face index: " << i << " Total: " << face_count << LL_ENDL; -				continue; -			} - -			U16* indices = (U16*) &(idx[0]); + +            if (idx.empty() || face.mNumIndices < 3) +            { //why is there an empty index list? +                LL_WARNS() << "Empty face present! Face index: " << i << " Total: " << face_count << LL_ENDL; +                continue; +            } + +            U16* indices = (U16*) &(idx[0]);              for (U32 j = 0; j < num_indices; ++j) -			{ -				face.mIndices[j] = indices[j]; -			} +            { +                face.mIndices[j] = indices[j]; +            } -			//copy out vertices -			U32 num_verts = pos.size()/(3*2); -			face.resizeVertices(num_verts); +            //copy out vertices +            U32 num_verts = pos.size()/(3*2); +            face.resizeVertices(num_verts);              if (num_verts > 0 && !face.mPositions)              { @@ -2486,19 +2486,19 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)                  continue;              } -			LLVector3 minp; -			LLVector3 maxp; -			LLVector2 min_tc;  -			LLVector2 max_tc;  -		 -			minp.setValue(mdl[i]["PositionDomain"]["Min"]); -			maxp.setValue(mdl[i]["PositionDomain"]["Max"]); -			LLVector4a min_pos, max_pos; -			min_pos.load3(minp.mV); -			max_pos.load3(maxp.mV); +            LLVector3 minp; +            LLVector3 maxp; +            LLVector2 min_tc; +            LLVector2 max_tc; -			min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); -			max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]); +            minp.setValue(mdl[i]["PositionDomain"]["Min"]); +            maxp.setValue(mdl[i]["PositionDomain"]["Max"]); +            LLVector4a min_pos, max_pos; +            min_pos.load3(minp.mV); +            max_pos.load3(maxp.mV); + +            min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); +            max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]);              //unpack normalized scale/translation              if (mdl[i].has("NormalizedScale")) @@ -2509,56 +2509,56 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)              {                  face.mNormalizedScale.set(1, 1, 1);              } -             -			LLVector4a pos_range; -			pos_range.setSub(max_pos, min_pos); -			LLVector2 tc_range2 = max_tc - min_tc; - -			LLVector4a tc_range; -			tc_range.set(tc_range2[0], tc_range2[1], tc_range2[0], tc_range2[1]); -			LLVector4a min_tc4(min_tc[0], min_tc[1], min_tc[0], min_tc[1]); - -			LLVector4a* pos_out = face.mPositions; -			LLVector4a* norm_out = face.mNormals; -			LLVector4a* tc_out = (LLVector4a*) face.mTexCoords; - -			{ -				U16* v = (U16*) &(pos[0]); -				for (U32 j = 0; j < num_verts; ++j) -				{ -					pos_out->set((F32) v[0], (F32) v[1], (F32) v[2]); -					pos_out->div(65535.f); -					pos_out->mul(pos_range); -					pos_out->add(min_pos); -					pos_out++; -					v += 3; -				} - -			} - -			{ -				if (!norm.empty()) -				{ -					U16* n = (U16*) &(norm[0]); -					for (U32 j = 0; j < num_verts; ++j) -					{ -						norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); -						norm_out->div(65535.f); -						norm_out->mul(2.f); -						norm_out->sub(1.f); -						norm_out++; -						n += 3; -					} -				} -				else -				{ -					for (U32 j = 0; j < num_verts; ++j) -					{ -						norm_out->clear(); -						norm_out++; // or just norm_out[j].clear(); -					} -				} -			} + +            LLVector4a pos_range; +            pos_range.setSub(max_pos, min_pos); +            LLVector2 tc_range2 = max_tc - min_tc; + +            LLVector4a tc_range; +            tc_range.set(tc_range2[0], tc_range2[1], tc_range2[0], tc_range2[1]); +            LLVector4a min_tc4(min_tc[0], min_tc[1], min_tc[0], min_tc[1]); + +            LLVector4a* pos_out = face.mPositions; +            LLVector4a* norm_out = face.mNormals; +            LLVector4a* tc_out = (LLVector4a*) face.mTexCoords; + +            { +                U16* v = (U16*) &(pos[0]); +                for (U32 j = 0; j < num_verts; ++j) +                { +                    pos_out->set((F32) v[0], (F32) v[1], (F32) v[2]); +                    pos_out->div(65535.f); +                    pos_out->mul(pos_range); +                    pos_out->add(min_pos); +                    pos_out++; +                    v += 3; +                } + +            } + +            { +                if (!norm.empty()) +                { +                    U16* n = (U16*) &(norm[0]); +                    for (U32 j = 0; j < num_verts; ++j) +                    { +                        norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); +                        norm_out->div(65535.f); +                        norm_out->mul(2.f); +                        norm_out->sub(1.f); +                        norm_out++; +                        n += 3; +                    } +                } +                else +                { +                    for (U32 j = 0; j < num_verts; ++j) +                    { +                        norm_out->clear(); +                        norm_out++; // or just norm_out[j].clear(); +                    } +                } +            }  #if 0 // keep this code for now in case we decide to add support for on-the-wire tangents              { @@ -2567,9 +2567,9 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)                      face.allocateTangents(face.mNumVertices);                      U16* t = (U16*)&(tangent[0]); -                    // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to  +                    // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to                      // maintain compliance with the GLTF spec -                    LLVector4a* t_out = face.mTangents;  +                    LLVector4a* t_out = face.mTangents;                      for (U32 j = 0; j < num_verts; ++j)                      { @@ -2588,43 +2588,43 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)              }  #endif -			{ -				if (!tc.empty()) -				{ -					U16* t = (U16*) &(tc[0]); -					for (U32 j = 0; j < num_verts; j+=2) -					{ -						if (j < num_verts-1) -						{ -							tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]); -						} -						else -						{ -							tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f); -						} - -						t += 4; - -						tc_out->div(65535.f); -						tc_out->mul(tc_range); -						tc_out->add(min_tc4); - -						tc_out++; -					} -				} -				else -				{ -					for (U32 j = 0; j < num_verts; j += 2) -					{ -						tc_out->clear(); -						tc_out++; -					} -				} -			} - -			if (mdl[i].has("Weights")) -			{ -				face.allocateWeights(num_verts); +            { +                if (!tc.empty()) +                { +                    U16* t = (U16*) &(tc[0]); +                    for (U32 j = 0; j < num_verts; j+=2) +                    { +                        if (j < num_verts-1) +                        { +                            tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]); +                        } +                        else +                        { +                            tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f); +                        } + +                        t += 4; + +                        tc_out->div(65535.f); +                        tc_out->mul(tc_range); +                        tc_out->add(min_tc4); + +                        tc_out++; +                    } +                } +                else +                { +                    for (U32 j = 0; j < num_verts; j += 2) +                    { +                        tc_out->clear(); +                        tc_out++; +                    } +                } +            } + +            if (mdl[i].has("Weights")) +            { +                face.allocateWeights(num_verts);                  if (!face.mWeights && num_verts)                  {                      LL_WARNS() << "Failed to allocate " << num_verts << " weights for face index: " << i << " Total: " << face_count << LL_ENDL; @@ -2633,40 +2633,40 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)                      continue;                  } -				LLSD::Binary weights = mdl[i]["Weights"]; +                LLSD::Binary weights = mdl[i]["Weights"]; -				U32 idx = 0; +                U32 idx = 0; -				U32 cur_vertex = 0; -				while (idx < weights.size() && cur_vertex < num_verts) -				{ -					const U8 END_INFLUENCES = 0xFF; -					U8 joint = weights[idx++]; +                U32 cur_vertex = 0; +                while (idx < weights.size() && cur_vertex < num_verts) +                { +                    const U8 END_INFLUENCES = 0xFF; +                    U8 joint = weights[idx++]; -					U32 cur_influence = 0; -					LLVector4 wght(0,0,0,0); +                    U32 cur_influence = 0; +                    LLVector4 wght(0,0,0,0);                      U32 joints[4] = {0,0,0,0}; -					LLVector4 joints_with_weights(0,0,0,0); - -					while (joint != END_INFLUENCES && idx < weights.size()) -					{ -						U16 influence = weights[idx++]; -						influence |= ((U16) weights[idx++] << 8); - -						F32 w = llclamp((F32) influence / 65535.f, 0.001f, 0.999f); -						wght.mV[cur_influence] = w; -						joints[cur_influence] = joint; -						cur_influence++; - -						if (cur_influence >= 4) -						{ -							joint = END_INFLUENCES; -						} -						else -						{ -							joint = weights[idx++]; -						} -					} +                    LLVector4 joints_with_weights(0,0,0,0); + +                    while (joint != END_INFLUENCES && idx < weights.size()) +                    { +                        U16 influence = weights[idx++]; +                        influence |= ((U16) weights[idx++] << 8); + +                        F32 w = llclamp((F32) influence / 65535.f, 0.001f, 0.999f); +                        wght.mV[cur_influence] = w; +                        joints[cur_influence] = joint; +                        cur_influence++; + +                        if (cur_influence >= 4) +                        { +                            joint = END_INFLUENCES; +                        } +                        else +                        { +                            joint = weights[idx++]; +                        } +                    }                      F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW];                      if (wsum <= 0.f)                      { @@ -2680,139 +2680,139 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)                          // A failure here would indicate a floating point precision error in the math.                          llassert((k >= cur_influence) || (f_combined - S32(f_combined) > 0.0f));                      } -					face.mWeights[cur_vertex].loadua(joints_with_weights.mV); - -					cur_vertex++; -				} - -				if (cur_vertex != num_verts || idx != weights.size()) -				{ -					LL_WARNS() << "Vertex weight count does not match vertex count!" << LL_ENDL; -				} -					 -			} - -			// modifier flags? -			bool do_mirror = (mParams.getSculptType() & LL_SCULPT_FLAG_MIRROR); -			bool do_invert = (mParams.getSculptType() &LL_SCULPT_FLAG_INVERT); -			 -			 -			// translate to actions: -			bool do_reflect_x = false; -			bool do_reverse_triangles = false; -			bool do_invert_normals = false; -			 -			if (do_mirror) -			{ -				do_reflect_x = true; -				do_reverse_triangles = !do_reverse_triangles; -			} -			 -			if (do_invert) -			{ -				do_invert_normals = true; -				do_reverse_triangles = !do_reverse_triangles; -			} -			 -			// now do the work - -			if (do_reflect_x) -			{ -				LLVector4a* p = (LLVector4a*) face.mPositions; -				LLVector4a* n = (LLVector4a*) face.mNormals; -				 -				for (S32 i = 0; i < face.mNumVertices; i++) -				{ -					p[i].mul(-1.0f); -					n[i].mul(-1.0f); -				} -			} - -			if (do_invert_normals) -			{ -				LLVector4a* n = (LLVector4a*) face.mNormals; -				 -				for (S32 i = 0; i < face.mNumVertices; i++) -				{ -					n[i].mul(-1.0f); -				} -			} - -			if (do_reverse_triangles) -			{ -				for (U32 j = 0; j < face.mNumIndices; j += 3) -				{ -					// swap the 2nd and 3rd index -					S32 swap = face.mIndices[j+1]; -					face.mIndices[j+1] = face.mIndices[j+2]; -					face.mIndices[j+2] = swap; -				} -			} - -			//calculate bounding box -			// VFExtents change -			LLVector4a& min = face.mExtents[0]; -			LLVector4a& max = face.mExtents[1]; - -			if (face.mNumVertices < 3) -			{ //empty face, use a dummy 1cm (at 1m scale) bounding box -				min.splat(-0.005f); -				max.splat(0.005f); -			} -			else -			{ -				min = max = face.mPositions[0]; - -				for (S32 i = 1; i < face.mNumVertices; ++i) -				{ -					min.setMin(min, face.mPositions[i]); -					max.setMax(max, face.mPositions[i]); -				} - -				if (face.mTexCoords) -				{ -					LLVector2& min_tc = face.mTexCoordExtents[0]; -					LLVector2& max_tc = face.mTexCoordExtents[1]; - -					min_tc = face.mTexCoords[0]; -					max_tc = face.mTexCoords[0]; - -					for (U32 j = 1; j < face.mNumVertices; ++j) -					{ -						update_min_max(min_tc, max_tc, face.mTexCoords[j]); -					} -				} -				else -				{ -					face.mTexCoordExtents[0].set(0,0); -					face.mTexCoordExtents[1].set(1,1); -				} -			} -		} -	} - -	if (!cacheOptimize(true)) -	{ -		// Out of memory? -		LL_WARNS() << "Failed to optimize!" << LL_ENDL; -		mVolumeFaces.clear(); -		return false; -	} -	 -	mSculptLevel = 0;  // success! - -	return true; +                    face.mWeights[cur_vertex].loadua(joints_with_weights.mV); + +                    cur_vertex++; +                } + +                if (cur_vertex != num_verts || idx != weights.size()) +                { +                    LL_WARNS() << "Vertex weight count does not match vertex count!" << LL_ENDL; +                } + +            } + +            // modifier flags? +            bool do_mirror = (mParams.getSculptType() & LL_SCULPT_FLAG_MIRROR); +            bool do_invert = (mParams.getSculptType() &LL_SCULPT_FLAG_INVERT); + + +            // translate to actions: +            bool do_reflect_x = false; +            bool do_reverse_triangles = false; +            bool do_invert_normals = false; + +            if (do_mirror) +            { +                do_reflect_x = true; +                do_reverse_triangles = !do_reverse_triangles; +            } + +            if (do_invert) +            { +                do_invert_normals = true; +                do_reverse_triangles = !do_reverse_triangles; +            } + +            // now do the work + +            if (do_reflect_x) +            { +                LLVector4a* p = (LLVector4a*) face.mPositions; +                LLVector4a* n = (LLVector4a*) face.mNormals; + +                for (S32 i = 0; i < face.mNumVertices; i++) +                { +                    p[i].mul(-1.0f); +                    n[i].mul(-1.0f); +                } +            } + +            if (do_invert_normals) +            { +                LLVector4a* n = (LLVector4a*) face.mNormals; + +                for (S32 i = 0; i < face.mNumVertices; i++) +                { +                    n[i].mul(-1.0f); +                } +            } + +            if (do_reverse_triangles) +            { +                for (U32 j = 0; j < face.mNumIndices; j += 3) +                { +                    // swap the 2nd and 3rd index +                    S32 swap = face.mIndices[j+1]; +                    face.mIndices[j+1] = face.mIndices[j+2]; +                    face.mIndices[j+2] = swap; +                } +            } + +            //calculate bounding box +            // VFExtents change +            LLVector4a& min = face.mExtents[0]; +            LLVector4a& max = face.mExtents[1]; + +            if (face.mNumVertices < 3) +            { //empty face, use a dummy 1cm (at 1m scale) bounding box +                min.splat(-0.005f); +                max.splat(0.005f); +            } +            else +            { +                min = max = face.mPositions[0]; + +                for (S32 i = 1; i < face.mNumVertices; ++i) +                { +                    min.setMin(min, face.mPositions[i]); +                    max.setMax(max, face.mPositions[i]); +                } + +                if (face.mTexCoords) +                { +                    LLVector2& min_tc = face.mTexCoordExtents[0]; +                    LLVector2& max_tc = face.mTexCoordExtents[1]; + +                    min_tc = face.mTexCoords[0]; +                    max_tc = face.mTexCoords[0]; + +                    for (U32 j = 1; j < face.mNumVertices; ++j) +                    { +                        update_min_max(min_tc, max_tc, face.mTexCoords[j]); +                    } +                } +                else +                { +                    face.mTexCoordExtents[0].set(0,0); +                    face.mTexCoordExtents[1].set(1,1); +                } +            } +        } +    } + +    if (!cacheOptimize(true)) +    { +        // Out of memory? +        LL_WARNS() << "Failed to optimize!" << LL_ENDL; +        mVolumeFaces.clear(); +        return false; +    } + +    mSculptLevel = 0;  // success! + +    return true;  }  bool LLVolume::isMeshAssetLoaded()  { -	return mIsMeshAssetLoaded; +    return mIsMeshAssetLoaded;  }  void LLVolume::setMeshAssetLoaded(bool loaded)  { -	mIsMeshAssetLoaded = loaded; +    mIsMeshAssetLoaded = loaded;      if (loaded)      {          mIsMeshAssetUnavaliable = false; @@ -2833,375 +2833,375 @@ bool LLVolume::isMeshAssetUnavaliable()      return mIsMeshAssetUnavaliable;  } -void LLVolume::copyFacesTo(std::vector<LLVolumeFace> &faces) const  +void LLVolume::copyFacesTo(std::vector<LLVolumeFace> &faces) const  { -	faces = mVolumeFaces; +    faces = mVolumeFaces;  }  void LLVolume::copyFacesFrom(const std::vector<LLVolumeFace> &faces)  { -	mVolumeFaces = faces; -	mSculptLevel = 0; +    mVolumeFaces = faces; +    mSculptLevel = 0;  }  void LLVolume::copyVolumeFaces(const LLVolume* volume)  { -	mVolumeFaces = volume->mVolumeFaces; -	mSculptLevel = 0; +    mVolumeFaces = volume->mVolumeFaces; +    mSculptLevel = 0;  }  bool LLVolume::cacheOptimize(bool gen_tangents)  { -	for (S32 i = 0; i < mVolumeFaces.size(); ++i) -	{ -		if (!mVolumeFaces[i].cacheOptimize(gen_tangents)) -		{ -			return false; -		} -	} -	return true; +    for (S32 i = 0; i < mVolumeFaces.size(); ++i) +    { +        if (!mVolumeFaces[i].cacheOptimize(gen_tangents)) +        { +            return false; +        } +    } +    return true;  } -S32	LLVolume::getNumFaces() const +S32 LLVolume::getNumFaces() const  { -	return mIsMeshAssetLoaded ? getNumVolumeFaces() : (S32)mProfilep->mFaces.size(); +    return mIsMeshAssetLoaded ? getNumVolumeFaces() : (S32)mProfilep->mFaces.size();  }  void LLVolume::createVolumeFaces()  { -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - -	if (mGenerateSingleFace) -	{ -		// do nothing -	} -	else -	{ -		S32 num_faces = getNumFaces(); -		BOOL partial_build = TRUE; -		if (num_faces != mVolumeFaces.size()) -		{ -			partial_build = FALSE; -			mVolumeFaces.resize(num_faces); -		} -		// Initialize volume faces with parameter data -		for (S32 i = 0; i < (S32)mVolumeFaces.size(); i++) -		{ -			LLVolumeFace& vf = mVolumeFaces[i]; -			LLProfile::Face& face = mProfilep->mFaces[i]; -			vf.mBeginS = face.mIndex; -			vf.mNumS = face.mCount; -			if (vf.mNumS < 0) -			{ -				LL_ERRS() << "Volume face corruption detected." << LL_ENDL; -			} - -			vf.mBeginT = 0; -			vf.mNumT= getPath().mPath.size(); -			vf.mID = i; - -			// Set the type mask bits correctly -			if (mParams.getProfileParams().getHollow() > 0) -			{ -				vf.mTypeMask |= LLVolumeFace::HOLLOW_MASK; -			} -			if (mProfilep->isOpen()) -			{ -				vf.mTypeMask |= LLVolumeFace::OPEN_MASK; -			} -			if (face.mCap) -			{ -				vf.mTypeMask |= LLVolumeFace::CAP_MASK; -				if (face.mFaceID == LL_FACE_PATH_BEGIN) -				{ -					vf.mTypeMask |= LLVolumeFace::TOP_MASK; -				} -				else -				{ -					llassert(face.mFaceID == LL_FACE_PATH_END); -					vf.mTypeMask |= LLVolumeFace::BOTTOM_MASK; -				} -			} -			else if (face.mFaceID & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) -			{ -				vf.mTypeMask |= LLVolumeFace::FLAT_MASK | LLVolumeFace::END_MASK; -			} -			else -			{ -				vf.mTypeMask |= LLVolumeFace::SIDE_MASK; -				if (face.mFlat) -				{ -					vf.mTypeMask |= LLVolumeFace::FLAT_MASK; -				} -				if (face.mFaceID & LL_FACE_INNER_SIDE) -				{ -					vf.mTypeMask |= LLVolumeFace::INNER_MASK; -					if (face.mFlat && vf.mNumS > 2) -					{ //flat inner faces have to copy vert normals -						vf.mNumS = vf.mNumS*2; -						if (vf.mNumS < 0) -						{ -							LL_ERRS() << "Volume face corruption detected." << LL_ENDL; -						} -					} -				} -				else -				{ -					vf.mTypeMask |= LLVolumeFace::OUTER_MASK; -				} -			} -		} - -		for (face_list_t::iterator iter = mVolumeFaces.begin(); -			 iter != mVolumeFaces.end(); ++iter) -		{ -			(*iter).create(this, partial_build); -		} -	} +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + +    if (mGenerateSingleFace) +    { +        // do nothing +    } +    else +    { +        S32 num_faces = getNumFaces(); +        BOOL partial_build = TRUE; +        if (num_faces != mVolumeFaces.size()) +        { +            partial_build = FALSE; +            mVolumeFaces.resize(num_faces); +        } +        // Initialize volume faces with parameter data +        for (S32 i = 0; i < (S32)mVolumeFaces.size(); i++) +        { +            LLVolumeFace& vf = mVolumeFaces[i]; +            LLProfile::Face& face = mProfilep->mFaces[i]; +            vf.mBeginS = face.mIndex; +            vf.mNumS = face.mCount; +            if (vf.mNumS < 0) +            { +                LL_ERRS() << "Volume face corruption detected." << LL_ENDL; +            } + +            vf.mBeginT = 0; +            vf.mNumT= getPath().mPath.size(); +            vf.mID = i; + +            // Set the type mask bits correctly +            if (mParams.getProfileParams().getHollow() > 0) +            { +                vf.mTypeMask |= LLVolumeFace::HOLLOW_MASK; +            } +            if (mProfilep->isOpen()) +            { +                vf.mTypeMask |= LLVolumeFace::OPEN_MASK; +            } +            if (face.mCap) +            { +                vf.mTypeMask |= LLVolumeFace::CAP_MASK; +                if (face.mFaceID == LL_FACE_PATH_BEGIN) +                { +                    vf.mTypeMask |= LLVolumeFace::TOP_MASK; +                } +                else +                { +                    llassert(face.mFaceID == LL_FACE_PATH_END); +                    vf.mTypeMask |= LLVolumeFace::BOTTOM_MASK; +                } +            } +            else if (face.mFaceID & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) +            { +                vf.mTypeMask |= LLVolumeFace::FLAT_MASK | LLVolumeFace::END_MASK; +            } +            else +            { +                vf.mTypeMask |= LLVolumeFace::SIDE_MASK; +                if (face.mFlat) +                { +                    vf.mTypeMask |= LLVolumeFace::FLAT_MASK; +                } +                if (face.mFaceID & LL_FACE_INNER_SIDE) +                { +                    vf.mTypeMask |= LLVolumeFace::INNER_MASK; +                    if (face.mFlat && vf.mNumS > 2) +                    { //flat inner faces have to copy vert normals +                        vf.mNumS = vf.mNumS*2; +                        if (vf.mNumS < 0) +                        { +                            LL_ERRS() << "Volume face corruption detected." << LL_ENDL; +                        } +                    } +                } +                else +                { +                    vf.mTypeMask |= LLVolumeFace::OUTER_MASK; +                } +            } +        } + +        for (face_list_t::iterator iter = mVolumeFaces.begin(); +             iter != mVolumeFaces.end(); ++iter) +        { +            (*iter).create(this, partial_build); +        } +    }  }  inline LLVector4a sculpt_rgb_to_vector(U8 r, U8 g, U8 b)  { -	// maps RGB values to vector values [0..255] -> [-0.5..0.5] -	LLVector4a value; -	LLVector4a sub(0.5f, 0.5f, 0.5f); +    // maps RGB values to vector values [0..255] -> [-0.5..0.5] +    LLVector4a value; +    LLVector4a sub(0.5f, 0.5f, 0.5f); -	value.set(r,g,b); -	value.mul(1.f/255.f); -	value.sub(sub); +    value.set(r,g,b); +    value.mul(1.f/255.f); +    value.sub(sub); -	return value; +    return value;  }  inline U32 sculpt_xy_to_index(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components)  { -	U32 index = (x + y * sculpt_width) * sculpt_components; -	return index; +    U32 index = (x + y * sculpt_width) * sculpt_components; +    return index;  }  inline U32 sculpt_st_to_index(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components)  { -	U32 x = (U32) ((F32)s/(size_s) * (F32) sculpt_width); -	U32 y = (U32) ((F32)t/(size_t) * (F32) sculpt_height); +    U32 x = (U32) ((F32)s/(size_s) * (F32) sculpt_width); +    U32 y = (U32) ((F32)t/(size_t) * (F32) sculpt_height); -	return sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); +    return sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components);  }  inline LLVector4a sculpt_index_to_vector(U32 index, const U8* sculpt_data)  { -	LLVector4a v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); +    LLVector4a v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); -	return v; +    return v;  }  inline LLVector4a sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)  { -	U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components); +    U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components); -	return sculpt_index_to_vector(index, sculpt_data); +    return sculpt_index_to_vector(index, sculpt_data);  }  inline LLVector4a sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)  { -	U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); +    U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); -	return sculpt_index_to_vector(index, sculpt_data); +    return sculpt_index_to_vector(index, sculpt_data);  }  F32 LLVolume::sculptGetSurfaceArea()  { -	// test to see if image has enough variation to create non-degenerate geometry - -	F32 area = 0; - -	S32 sizeS = mPathp->mPath.size(); -	S32 sizeT = mProfilep->mProfile.size(); -			 -	for (S32 s = 0; s < sizeS-1; s++) -	{ -		for (S32 t = 0; t < sizeT-1; t++) -		{ -			// get four corners of quad -			LLVector4a& p1 = mMesh[(s  )*sizeT + (t  )]; -			LLVector4a& p2 = mMesh[(s+1)*sizeT + (t  )]; -			LLVector4a& p3 = mMesh[(s  )*sizeT + (t+1)]; -			LLVector4a& p4 = mMesh[(s+1)*sizeT + (t+1)]; +    // test to see if image has enough variation to create non-degenerate geometry -			// compute the area of the quad by taking the length of the cross product of the two triangles -			LLVector4a v0,v1,v2,v3; -			v0.setSub(p1,p2); -			v1.setSub(p1,p3); -			v2.setSub(p4,p2); -			v3.setSub(p4,p3); +    F32 area = 0; -			LLVector4a cross1, cross2; -			cross1.setCross3(v0,v1); -			cross2.setCross3(v2,v3); +    S32 sizeS = mPathp->mPath.size(); +    S32 sizeT = mProfilep->mProfile.size(); -			//LLVector3 cross1 = (p1 - p2) % (p1 - p3); -			//LLVector3 cross2 = (p4 - p2) % (p4 - p3); -			 -			area += (cross1.getLength3() + cross2.getLength3()).getF32() / 2.f; -		} -	} +    for (S32 s = 0; s < sizeS-1; s++) +    { +        for (S32 t = 0; t < sizeT-1; t++) +        { +            // get four corners of quad +            LLVector4a& p1 = mMesh[(s  )*sizeT + (t  )]; +            LLVector4a& p2 = mMesh[(s+1)*sizeT + (t  )]; +            LLVector4a& p3 = mMesh[(s  )*sizeT + (t+1)]; +            LLVector4a& p4 = mMesh[(s+1)*sizeT + (t+1)]; + +            // compute the area of the quad by taking the length of the cross product of the two triangles +            LLVector4a v0,v1,v2,v3; +            v0.setSub(p1,p2); +            v1.setSub(p1,p3); +            v2.setSub(p4,p2); +            v3.setSub(p4,p3); + +            LLVector4a cross1, cross2; +            cross1.setCross3(v0,v1); +            cross2.setCross3(v2,v3); + +            //LLVector3 cross1 = (p1 - p2) % (p1 - p3); +            //LLVector3 cross2 = (p4 - p2) % (p4 - p3); + +            area += (cross1.getLength3() + cross2.getLength3()).getF32() / 2.f; +        } +    } -	return area; +    return area;  }  // create empty placeholder shape  void LLVolume::sculptGenerateEmptyPlaceholder()  { -	S32 sizeS = mPathp->mPath.size(); -	S32 sizeT = mProfilep->mProfile.size(); +    S32 sizeS = mPathp->mPath.size(); +    S32 sizeT = mProfilep->mProfile.size(); -	S32 line = 0; +    S32 line = 0; -	for (S32 s = 0; s < sizeS; s++) -	{ -		for (S32 t = 0; t < sizeT; t++) -		{ -			S32 i = t + line; -			LLVector4a& pt = mMesh[i]; -					 -			F32* p = pt.getF32ptr(); +    for (S32 s = 0; s < sizeS; s++) +    { +        for (S32 t = 0; t < sizeT; t++) +        { +            S32 i = t + line; +            LLVector4a& pt = mMesh[i]; -			p[0] = 0; -			p[1] = 0; -			p[2] = 0; +            F32* p = pt.getF32ptr(); -			llassert(pt.isFinite3()); -		} -		line += sizeT; -	} +            p[0] = 0; +            p[1] = 0; +            p[2] = 0; + +            llassert(pt.isFinite3()); +        } +        line += sizeT; +    }  }  // create sphere placeholder shape  void LLVolume::sculptGenerateSpherePlaceholder()  { -	S32 sizeS = mPathp->mPath.size(); -	S32 sizeT = mProfilep->mProfile.size(); +    S32 sizeS = mPathp->mPath.size(); +    S32 sizeT = mProfilep->mProfile.size(); -	S32 line = 0; +    S32 line = 0; -	for (S32 s = 0; s < sizeS; s++) -	{ -		for (S32 t = 0; t < sizeT; t++) -		{ -			S32 i = t + line; -			LLVector4a& pt = mMesh[i]; +    for (S32 s = 0; s < sizeS; s++) +    { +        for (S32 t = 0; t < sizeT; t++) +        { +            S32 i = t + line; +            LLVector4a& pt = mMesh[i]; -			F32 u = (F32)s / (sizeS - 1); -			F32 v = (F32)t / (sizeT - 1); +            F32 u = (F32)s / (sizeS - 1); +            F32 v = (F32)t / (sizeT - 1); -			const F32 RADIUS = (F32) 0.3; +            const F32 RADIUS = (F32) 0.3; -			F32* p = pt.getF32ptr(); +            F32* p = pt.getF32ptr(); -			p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); -			p[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); -			p[2] = (F32)(cos(F_PI * v) * RADIUS); +            p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); +            p[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); +            p[2] = (F32)(cos(F_PI * v) * RADIUS); -			llassert(pt.isFinite3()); -		} -		line += sizeT; -	} +            llassert(pt.isFinite3()); +        } +        line += sizeT; +    }  }  // create the vertices from the map  void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type)  { -	U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; -	BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT; -	BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR; -	BOOL reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror);  // XOR -	 -	S32 sizeS = mPathp->mPath.size(); -	S32 sizeT = mProfilep->mProfile.size(); -	 -	S32 line = 0; -	for (S32 s = 0; s < sizeS; s++) -	{ -		// Run along the profile. -		for (S32 t = 0; t < sizeT; t++) -		{ -			S32 i = t + line; -			LLVector4a& pt = mMesh[i]; - -			S32 reversed_t = t; - -			if (reverse_horizontal) -			{ -				reversed_t = sizeT - t - 1; -			} -			 -			U32 x = (U32) ((F32)reversed_t/(sizeT-1) * (F32) sculpt_width); -			U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); - -			 -			if (y == 0)  // top row stitching -			{ -				// pinch? -				if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) -				{ -					x = sculpt_width / 2; -				} -			} - -			if (y == sculpt_height)  // bottom row stitching -			{ -				// wrap? -				if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) -				{ -					y = 0; -				} -				else -				{ -					y = sculpt_height - 1; -				} - -				// pinch? -				if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) -				{ -					x = sculpt_width / 2; -				} -			} - -			if (x == sculpt_width)   // side stitching -			{ -				// wrap? -				if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || -					(sculpt_stitching == LL_SCULPT_TYPE_TORUS) || -					(sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) -				{ -					x = 0; -				} -					 -				else -				{ -					x = sculpt_width - 1; -				} -			} - -			pt = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data); - -			if (sculpt_mirror) -			{ -				LLVector4a scale(-1.f,1,1,1); -				pt.mul(scale); -			} - -			llassert(pt.isFinite3()); -		} -		 -		line += sizeT; -	} +    U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; +    BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT; +    BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR; +    BOOL reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror);  // XOR + +    S32 sizeS = mPathp->mPath.size(); +    S32 sizeT = mProfilep->mProfile.size(); + +    S32 line = 0; +    for (S32 s = 0; s < sizeS; s++) +    { +        // Run along the profile. +        for (S32 t = 0; t < sizeT; t++) +        { +            S32 i = t + line; +            LLVector4a& pt = mMesh[i]; + +            S32 reversed_t = t; + +            if (reverse_horizontal) +            { +                reversed_t = sizeT - t - 1; +            } + +            U32 x = (U32) ((F32)reversed_t/(sizeT-1) * (F32) sculpt_width); +            U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); + + +            if (y == 0)  // top row stitching +            { +                // pinch? +                if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) +                { +                    x = sculpt_width / 2; +                } +            } + +            if (y == sculpt_height)  // bottom row stitching +            { +                // wrap? +                if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) +                { +                    y = 0; +                } +                else +                { +                    y = sculpt_height - 1; +                } + +                // pinch? +                if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) +                { +                    x = sculpt_width / 2; +                } +            } + +            if (x == sculpt_width)   // side stitching +            { +                // wrap? +                if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || +                    (sculpt_stitching == LL_SCULPT_TYPE_TORUS) || +                    (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) +                { +                    x = 0; +                } + +                else +                { +                    x = sculpt_width - 1; +                } +            } + +            pt = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data); + +            if (sculpt_mirror) +            { +                LLVector4a scale(-1.f,1,1,1); +                pt.mul(scale); +            } + +            llassert(pt.isFinite3()); +        } + +        line += sizeT; +    }  } @@ -3213,24 +3213,24 @@ const S32 SCULPT_REZ_4 = 32;  S32 sculpt_sides(F32 detail)  { -	// detail is usually one of: 1, 1.5, 2.5, 4.0. -	 -	if (detail <= 1.0) -	{ -		return SCULPT_REZ_1; -	} -	if (detail <= 2.0) -	{ -		return SCULPT_REZ_2; -	} -	if (detail <= 3.0) -	{ -		return SCULPT_REZ_3; -	} -	else -	{ -		return SCULPT_REZ_4; -	} +    // detail is usually one of: 1, 1.5, 2.5, 4.0. + +    if (detail <= 1.0) +    { +        return SCULPT_REZ_1; +    } +    if (detail <= 2.0) +    { +        return SCULPT_REZ_2; +    } +    if (detail <= 3.0) +    { +        return SCULPT_REZ_3; +    } +    else +    { +        return SCULPT_REZ_4; +    }  } @@ -3238,120 +3238,120 @@ S32 sculpt_sides(F32 detail)  // determine the number of vertices in both s and t direction for this sculpt  void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32& s, S32& t)  { -	// this code has the following properties: -	// 1) the aspect ratio of the mesh is as close as possible to the ratio of the map -	//    while still using all available verts -	// 2) the mesh cannot have more verts than is allowed by LOD -	// 3) the mesh cannot have more verts than is allowed by the map -	 -	S32 max_vertices_lod = (S32)pow((double)sculpt_sides(detail), 2.0); -	S32 max_vertices_map = width * height / 4; -	 -	S32 vertices; -	if (max_vertices_map > 0) -		vertices = llmin(max_vertices_lod, max_vertices_map); -	else -		vertices = max_vertices_lod; -	 - -	F32 ratio; -	if ((width == 0) || (height == 0)) -		ratio = 1.f; -	else -		ratio = (F32) width / (F32) height; - -	 -	s = (S32)(F32) sqrt(((F32)vertices / ratio)); - -	s = llmax(s, 4);              // no degenerate sizes, please -	t = vertices / s; - -	t = llmax(t, 4);              // no degenerate sizes, please -	s = vertices / t; +    // this code has the following properties: +    // 1) the aspect ratio of the mesh is as close as possible to the ratio of the map +    //    while still using all available verts +    // 2) the mesh cannot have more verts than is allowed by LOD +    // 3) the mesh cannot have more verts than is allowed by the map + +    S32 max_vertices_lod = (S32)pow((double)sculpt_sides(detail), 2.0); +    S32 max_vertices_map = width * height / 4; + +    S32 vertices; +    if (max_vertices_map > 0) +        vertices = llmin(max_vertices_lod, max_vertices_map); +    else +        vertices = max_vertices_lod; + + +    F32 ratio; +    if ((width == 0) || (height == 0)) +        ratio = 1.f; +    else +        ratio = (F32) width / (F32) height; + + +    s = (S32)(F32) sqrt(((F32)vertices / ratio)); + +    s = llmax(s, 4);              // no degenerate sizes, please +    t = vertices / s; + +    t = llmax(t, 4);              // no degenerate sizes, please +    s = vertices / t;  }  // sculpt replaces generate() for sculpted surfaces  void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder)  { -	U8 sculpt_type = mParams.getSculptType(); +    U8 sculpt_type = mParams.getSculptType(); -	BOOL data_is_empty = FALSE; +    BOOL data_is_empty = FALSE; -	if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL) -	{ -		sculpt_level = -1; -		data_is_empty = TRUE; -	} +    if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL) +    { +        sculpt_level = -1; +        data_is_empty = TRUE; +    } -	S32 requested_sizeS = 0; -	S32 requested_sizeT = 0; +    S32 requested_sizeS = 0; +    S32 requested_sizeT = 0; -	sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, mDetail, requested_sizeS, requested_sizeT); +    sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, mDetail, requested_sizeS, requested_sizeT); -	mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE, requested_sizeS); -	mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE, requested_sizeT); +    mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE, requested_sizeS); +    mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE, requested_sizeT); -	S32 sizeS = mPathp->mPath.size();         // we requested a specific size, now see what we really got -	S32 sizeT = mProfilep->mProfile.size();   // we requested a specific size, now see what we really got +    S32 sizeS = mPathp->mPath.size();         // we requested a specific size, now see what we really got +    S32 sizeT = mProfilep->mProfile.size();   // we requested a specific size, now see what we really got -	// weird crash bug - DEV-11158 - trying to collect more data: -	if ((sizeS == 0) || (sizeT == 0)) -	{ -		LL_WARNS() << "sculpt bad mesh size " << sizeS << " " << sizeT << LL_ENDL; -	} -	 -	sNumMeshPoints -= mMesh.size(); -	mMesh.resize(sizeS * sizeT); -	sNumMeshPoints += mMesh.size(); +    // weird crash bug - DEV-11158 - trying to collect more data: +    if ((sizeS == 0) || (sizeT == 0)) +    { +        LL_WARNS() << "sculpt bad mesh size " << sizeS << " " << sizeT << LL_ENDL; +    } -	//generate vertex positions -	if (!data_is_empty) -	{ -		sculptGenerateMapVertices(sculpt_width, sculpt_height, sculpt_components, sculpt_data, sculpt_type); +    sNumMeshPoints -= mMesh.size(); +    mMesh.resize(sizeS * sizeT); +    sNumMeshPoints += mMesh.size(); -		// don't test lowest LOD to support legacy content DEV-33670 -		if (mDetail > SCULPT_MIN_AREA_DETAIL) -		{ -			F32 area = sculptGetSurfaceArea(); +    //generate vertex positions +    if (!data_is_empty) +    { +        sculptGenerateMapVertices(sculpt_width, sculpt_height, sculpt_components, sculpt_data, sculpt_type); -			mSurfaceArea = area; +        // don't test lowest LOD to support legacy content DEV-33670 +        if (mDetail > SCULPT_MIN_AREA_DETAIL) +        { +            F32 area = sculptGetSurfaceArea(); -			const F32 SCULPT_MAX_AREA = 384.f; +            mSurfaceArea = area; -			if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA) -			{ -				data_is_empty = TRUE; -				visible_placeholder = true; -			} -		} -	} +            const F32 SCULPT_MAX_AREA = 384.f; -	if (data_is_empty) -	{ -		if (visible_placeholder) -		{ -			// Object should be visible since there will be nothing else to display -			sculptGenerateSpherePlaceholder(); -		} -		else -		{ -			sculptGenerateEmptyPlaceholder(); -		} -	} +            if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA) +            { +                data_is_empty = TRUE; +                visible_placeholder = true; +            } +        } +    } +    if (data_is_empty) +    { +        if (visible_placeholder) +        { +            // Object should be visible since there will be nothing else to display +            sculptGenerateSpherePlaceholder(); +        } +        else +        { +            sculptGenerateEmptyPlaceholder(); +        } +    } + + + +    for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++) +    { +        mFaceMask |= mProfilep->mFaces[i].mFaceID; +    } -	 -	for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++) -	{ -		mFaceMask |= mProfilep->mFaces[i].mFaceID; -	} +    mSculptLevel = sculpt_level; -	mSculptLevel = sculpt_level; +    // Delete any existing faces so that they get regenerated +    mVolumeFaces.clear(); -	// Delete any existing faces so that they get regenerated -	mVolumeFaces.clear(); -	 -	createVolumeFaces(); +    createVolumeFaces();  } @@ -3359,12 +3359,12 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,  BOOL LLVolume::isCap(S32 face)  { -	return mProfilep->mFaces[face].mCap;  +    return mProfilep->mFaces[face].mCap;  }  BOOL LLVolume::isFlat(S32 face)  { -	return mProfilep->mFaces[face].mFlat; +    return mProfilep->mFaces[face].mFlat;  } @@ -3375,457 +3375,457 @@ bool LLVolumeParams::isSculpt() const  bool LLVolumeParams::isMeshSculpt() const  { -	return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH; +    return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH;  }  bool LLVolumeParams::operator==(const LLVolumeParams ¶ms) const  { -	return ( (getPathParams() == params.getPathParams()) && -			 (getProfileParams() == params.getProfileParams()) && -			 (mSculptID == params.mSculptID) && -			 (mSculptType == params.mSculptType) ); +    return ( (getPathParams() == params.getPathParams()) && +             (getProfileParams() == params.getProfileParams()) && +             (mSculptID == params.mSculptID) && +             (mSculptType == params.mSculptType) );  }  bool LLVolumeParams::operator!=(const LLVolumeParams ¶ms) const  { -	return ( (getPathParams() != params.getPathParams()) || -			 (getProfileParams() != params.getProfileParams()) || -			 (mSculptID != params.mSculptID) || -			 (mSculptType != params.mSculptType) ); +    return ( (getPathParams() != params.getPathParams()) || +             (getProfileParams() != params.getProfileParams()) || +             (mSculptID != params.mSculptID) || +             (mSculptType != params.mSculptType) );  }  bool LLVolumeParams::operator<(const LLVolumeParams ¶ms) const  { -	if( getPathParams() != params.getPathParams() ) -	{ -		return getPathParams() < params.getPathParams(); -	} -	 -	if (getProfileParams() != params.getProfileParams()) -	{ -		return getProfileParams() < params.getProfileParams(); -	} -	 -	if (mSculptID != params.mSculptID) -	{ -		return mSculptID < params.mSculptID; -	} +    if( getPathParams() != params.getPathParams() ) +    { +        return getPathParams() < params.getPathParams(); +    } -	return mSculptType < params.mSculptType; +    if (getProfileParams() != params.getProfileParams()) +    { +        return getProfileParams() < params.getProfileParams(); +    } + +    if (mSculptID != params.mSculptID) +    { +        return mSculptID < params.mSculptID; +    } + +    return mSculptType < params.mSculptType;  }  void LLVolumeParams::copyParams(const LLVolumeParams ¶ms)  { -	mProfileParams.copyParams(params.mProfileParams); -	mPathParams.copyParams(params.mPathParams); -	mSculptID = params.getSculptID(); -	mSculptType = params.getSculptType(); +    mProfileParams.copyParams(params.mProfileParams); +    mPathParams.copyParams(params.mPathParams); +    mSculptID = params.getSculptID(); +    mSculptType = params.getSculptType();  }  // Less restricitve approx 0 for volumes  const F32 APPROXIMATELY_ZERO = 0.001f;  bool approx_zero( F32 f, F32 tolerance = APPROXIMATELY_ZERO)  { -	return (f >= -tolerance) && (f <= tolerance); +    return (f >= -tolerance) && (f <= tolerance);  }  // return true if in range (or nearly so)  static bool limit_range(F32& v, F32 min, F32 max, F32 tolerance = APPROXIMATELY_ZERO)  { -	F32 min_delta = v - min; -	if (min_delta < 0.f) -	{ -		v = min; -		if (!approx_zero(min_delta, tolerance)) -			return false; -	} -	F32 max_delta = max - v; -	if (max_delta < 0.f) -	{ -		v = max; -		if (!approx_zero(max_delta, tolerance)) -			return false; -	} -	return true; +    F32 min_delta = v - min; +    if (min_delta < 0.f) +    { +        v = min; +        if (!approx_zero(min_delta, tolerance)) +            return false; +    } +    F32 max_delta = max - v; +    if (max_delta < 0.f) +    { +        v = max; +        if (!approx_zero(max_delta, tolerance)) +            return false; +    } +    return true;  }  bool LLVolumeParams::setBeginAndEndS(const F32 b, const F32 e)  { -	bool valid = true; +    bool valid = true; -	// First, clamp to valid ranges. -	F32 begin = b; -	valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA); +    // First, clamp to valid ranges. +    F32 begin = b; +    valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA); -	F32 end = e; -	if (end >= .0149f && end < MIN_CUT_DELTA) end = MIN_CUT_DELTA; // eliminate warning for common rounding error -	valid &= limit_range(end, MIN_CUT_DELTA, 1.f); +    F32 end = e; +    if (end >= .0149f && end < MIN_CUT_DELTA) end = MIN_CUT_DELTA; // eliminate warning for common rounding error +    valid &= limit_range(end, MIN_CUT_DELTA, 1.f); -	valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f); +    valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f); -	// Now set them. -	mProfileParams.setBegin(begin); -	mProfileParams.setEnd(end); +    // Now set them. +    mProfileParams.setBegin(begin); +    mProfileParams.setEnd(end); -	return valid; +    return valid;  }  bool LLVolumeParams::setBeginAndEndT(const F32 b, const F32 e)  { -	bool valid = true; +    bool valid = true; -	// First, clamp to valid ranges. -	F32 begin = b; -	valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA); +    // First, clamp to valid ranges. +    F32 begin = b; +    valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA); -	F32 end = e; -	valid &= limit_range(end, MIN_CUT_DELTA, 1.f); +    F32 end = e; +    valid &= limit_range(end, MIN_CUT_DELTA, 1.f); -	valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f); +    valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f); -	// Now set them. -	mPathParams.setBegin(begin); -	mPathParams.setEnd(end); +    // Now set them. +    mPathParams.setBegin(begin); +    mPathParams.setEnd(end); -	return valid; -}			 +    return valid; +}  bool LLVolumeParams::setHollow(const F32 h)  { -	// Validate the hollow based on path and profile. -	U8 profile 	= mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; -	U8 hole_type 	= mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK; -	 -	F32 max_hollow = HOLLOW_MAX; - -	// Only square holes have trouble. -	if (LL_PCODE_HOLE_SQUARE == hole_type) -	{ -		switch(profile) -		{ -		case LL_PCODE_PROFILE_CIRCLE: -		case LL_PCODE_PROFILE_CIRCLE_HALF: -		case LL_PCODE_PROFILE_EQUALTRI: -			max_hollow = HOLLOW_MAX_SQUARE; -		} -	} - -	F32 hollow = h; -	bool valid = limit_range(hollow, HOLLOW_MIN, max_hollow); -	mProfileParams.setHollow(hollow);  - -	return valid; -}	 +    // Validate the hollow based on path and profile. +    U8 profile  = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; +    U8 hole_type    = mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK; + +    F32 max_hollow = HOLLOW_MAX; + +    // Only square holes have trouble. +    if (LL_PCODE_HOLE_SQUARE == hole_type) +    { +        switch(profile) +        { +        case LL_PCODE_PROFILE_CIRCLE: +        case LL_PCODE_PROFILE_CIRCLE_HALF: +        case LL_PCODE_PROFILE_EQUALTRI: +            max_hollow = HOLLOW_MAX_SQUARE; +        } +    } + +    F32 hollow = h; +    bool valid = limit_range(hollow, HOLLOW_MIN, max_hollow); +    mProfileParams.setHollow(hollow); + +    return valid; +}  bool LLVolumeParams::setTwistBegin(const F32 b)  { -	F32 twist_begin = b; -	bool valid = limit_range(twist_begin, TWIST_MIN, TWIST_MAX); -	mPathParams.setTwistBegin(twist_begin); -	return valid; +    F32 twist_begin = b; +    bool valid = limit_range(twist_begin, TWIST_MIN, TWIST_MAX); +    mPathParams.setTwistBegin(twist_begin); +    return valid;  }  bool LLVolumeParams::setTwistEnd(const F32 e) -{	 -	F32 twist_end = e; -	bool valid = limit_range(twist_end, TWIST_MIN, TWIST_MAX); -	mPathParams.setTwistEnd(twist_end); -	return valid; +{ +    F32 twist_end = e; +    bool valid = limit_range(twist_end, TWIST_MIN, TWIST_MAX); +    mPathParams.setTwistEnd(twist_end); +    return valid;  }  bool LLVolumeParams::setRatio(const F32 x, const F32 y)  { -	F32 min_x = RATIO_MIN; -	F32 max_x = RATIO_MAX; -	F32 min_y = RATIO_MIN; -	F32 max_y = RATIO_MAX; -	// If this is a circular path (and not a sphere) then 'ratio' is actually hole size. -	U8 path_type 	= mPathParams.getCurveType(); -	U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; -	if ( LL_PCODE_PATH_CIRCLE == path_type && -		 LL_PCODE_PROFILE_CIRCLE_HALF != profile_type) -	{ -		// Holes are more restricted... -		min_x = HOLE_X_MIN; -		max_x = HOLE_X_MAX; -		min_y = HOLE_Y_MIN; -		max_y = HOLE_Y_MAX; -	} - -	F32 ratio_x = x; -	bool valid = limit_range(ratio_x, min_x, max_x); -	F32 ratio_y = y; -	valid &= limit_range(ratio_y, min_y, max_y); - -	mPathParams.setScale(ratio_x, ratio_y); - -	return valid; +    F32 min_x = RATIO_MIN; +    F32 max_x = RATIO_MAX; +    F32 min_y = RATIO_MIN; +    F32 max_y = RATIO_MAX; +    // If this is a circular path (and not a sphere) then 'ratio' is actually hole size. +    U8 path_type    = mPathParams.getCurveType(); +    U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; +    if ( LL_PCODE_PATH_CIRCLE == path_type && +         LL_PCODE_PROFILE_CIRCLE_HALF != profile_type) +    { +        // Holes are more restricted... +        min_x = HOLE_X_MIN; +        max_x = HOLE_X_MAX; +        min_y = HOLE_Y_MIN; +        max_y = HOLE_Y_MAX; +    } + +    F32 ratio_x = x; +    bool valid = limit_range(ratio_x, min_x, max_x); +    F32 ratio_y = y; +    valid &= limit_range(ratio_y, min_y, max_y); + +    mPathParams.setScale(ratio_x, ratio_y); + +    return valid;  }  bool LLVolumeParams::setShear(const F32 x, const F32 y)  { -	F32 shear_x = x; -	bool valid = limit_range(shear_x, SHEAR_MIN, SHEAR_MAX); -	F32 shear_y = y; -	valid &= limit_range(shear_y, SHEAR_MIN, SHEAR_MAX); -	mPathParams.setShear(shear_x, shear_y); -	return valid; +    F32 shear_x = x; +    bool valid = limit_range(shear_x, SHEAR_MIN, SHEAR_MAX); +    F32 shear_y = y; +    valid &= limit_range(shear_y, SHEAR_MIN, SHEAR_MAX); +    mPathParams.setShear(shear_x, shear_y); +    return valid;  }  bool LLVolumeParams::setTaperX(const F32 v)  { -	F32 taper = v; -	bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX); -	mPathParams.setTaperX(taper); -	return valid; +    F32 taper = v; +    bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX); +    mPathParams.setTaperX(taper); +    return valid;  }  bool LLVolumeParams::setTaperY(const F32 v)  { -	F32 taper = v; -	bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX); -	mPathParams.setTaperY(taper); -	return valid; +    F32 taper = v; +    bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX); +    mPathParams.setTaperY(taper); +    return valid;  }  bool LLVolumeParams::setRevolutions(const F32 r)  { -	F32 revolutions = r; -	bool valid = limit_range(revolutions, REV_MIN, REV_MAX); -	mPathParams.setRevolutions(revolutions); -	return valid; +    F32 revolutions = r; +    bool valid = limit_range(revolutions, REV_MIN, REV_MAX); +    mPathParams.setRevolutions(revolutions); +    return valid;  }  bool LLVolumeParams::setRadiusOffset(const F32 offset)  { -	bool valid = true; - -	// If this is a sphere, just set it to 0 and get out. -	U8 path_type 	= mPathParams.getCurveType(); -	U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; -	if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type || -		LL_PCODE_PATH_CIRCLE != path_type ) -	{ -		mPathParams.setRadiusOffset(0.f); -		return true; -	} - -	// Limit radius offset, based on taper and hole size y. -	F32 radius_offset	= offset; -	F32 taper_y    		= getTaperY(); -	F32 radius_mag		= fabs(radius_offset); -	F32 hole_y_mag 		= fabs(getRatioY()); -	F32 taper_y_mag		= fabs(taper_y); -	// Check to see if the taper effects us. -	if ( (radius_offset > 0.f && taper_y < 0.f) || -			(radius_offset < 0.f && taper_y > 0.f) ) -	{ -		// The taper does not help increase the radius offset range. -		taper_y_mag = 0.f; -	} -	F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag); - -	// Enforce the maximum magnitude. -	F32 delta = max_radius_mag - radius_mag; -	if (delta < 0.f) -	{ -		// Check radius offset sign. -		if (radius_offset < 0.f) -		{ -			radius_offset = -max_radius_mag; -		} -		else -		{ -			radius_offset = max_radius_mag; -		} -		valid = approx_zero(delta, .1f); -	} - -	mPathParams.setRadiusOffset(radius_offset); -	return valid; +    bool valid = true; + +    // If this is a sphere, just set it to 0 and get out. +    U8 path_type    = mPathParams.getCurveType(); +    U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; +    if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type || +        LL_PCODE_PATH_CIRCLE != path_type ) +    { +        mPathParams.setRadiusOffset(0.f); +        return true; +    } + +    // Limit radius offset, based on taper and hole size y. +    F32 radius_offset   = offset; +    F32 taper_y         = getTaperY(); +    F32 radius_mag      = fabs(radius_offset); +    F32 hole_y_mag      = fabs(getRatioY()); +    F32 taper_y_mag     = fabs(taper_y); +    // Check to see if the taper effects us. +    if ( (radius_offset > 0.f && taper_y < 0.f) || +            (radius_offset < 0.f && taper_y > 0.f) ) +    { +        // The taper does not help increase the radius offset range. +        taper_y_mag = 0.f; +    } +    F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag); + +    // Enforce the maximum magnitude. +    F32 delta = max_radius_mag - radius_mag; +    if (delta < 0.f) +    { +        // Check radius offset sign. +        if (radius_offset < 0.f) +        { +            radius_offset = -max_radius_mag; +        } +        else +        { +            radius_offset = max_radius_mag; +        } +        valid = approx_zero(delta, .1f); +    } + +    mPathParams.setRadiusOffset(radius_offset); +    return valid;  }  bool LLVolumeParams::setSkew(const F32 skew_value)  { -	bool valid = true; - -	// Check the skew value against the revolutions. -	F32 skew		= llclamp(skew_value, SKEW_MIN, SKEW_MAX); -	F32 skew_mag	= fabs(skew); -	F32 revolutions = getRevolutions(); -	F32 scale_x		= getRatioX(); -	F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f); -	// Discontinuity; A revolution of 1 allows skews below 0.5. -	if ( fabs(revolutions - 1.0f) < 0.001) -		min_skew_mag = 0.0f; - -	// Clip skew. -	F32 delta = skew_mag - min_skew_mag; -	if (delta < 0.f) -	{ -		// Check skew sign. -		if (skew < 0.0f) -		{ -			skew = -min_skew_mag; -		} -		else  -		{ -			skew = min_skew_mag; -		} -		valid = approx_zero(delta, .01f); -	} - -	mPathParams.setSkew(skew); -	return valid; +    bool valid = true; + +    // Check the skew value against the revolutions. +    F32 skew        = llclamp(skew_value, SKEW_MIN, SKEW_MAX); +    F32 skew_mag    = fabs(skew); +    F32 revolutions = getRevolutions(); +    F32 scale_x     = getRatioX(); +    F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f); +    // Discontinuity; A revolution of 1 allows skews below 0.5. +    if ( fabs(revolutions - 1.0f) < 0.001) +        min_skew_mag = 0.0f; + +    // Clip skew. +    F32 delta = skew_mag - min_skew_mag; +    if (delta < 0.f) +    { +        // Check skew sign. +        if (skew < 0.0f) +        { +            skew = -min_skew_mag; +        } +        else +        { +            skew = min_skew_mag; +        } +        valid = approx_zero(delta, .01f); +    } + +    mPathParams.setSkew(skew); +    return valid;  }  bool LLVolumeParams::setSculptID(const LLUUID sculpt_id, U8 sculpt_type)  { -	mSculptID = sculpt_id; -	mSculptType = sculpt_type; -	return true; +    mSculptID = sculpt_id; +    mSculptType = sculpt_type; +    return true;  }  bool LLVolumeParams::setType(U8 profile, U8 path)  { -	bool result = true; -	// First, check profile and path for validity. -	U8 profile_type	= profile & LL_PCODE_PROFILE_MASK; -	U8 hole_type 	= (profile & LL_PCODE_HOLE_MASK) >> 4; -	U8 path_type	= path >> 4; - -	if (profile_type > LL_PCODE_PROFILE_MAX) -	{ -		// Bad profile.  Make it square. -		profile = LL_PCODE_PROFILE_SQUARE; -		result = false; -		LL_WARNS() << "LLVolumeParams::setType changing bad profile type (" << profile_type -			 	<< ") to be LL_PCODE_PROFILE_SQUARE" << LL_ENDL; -	} -	else if (hole_type > LL_PCODE_HOLE_MAX) -	{ -		// Bad hole.  Make it the same. -		profile = profile_type; -		result = false; -		LL_WARNS() << "LLVolumeParams::setType changing bad hole type (" << hole_type -			 	<< ") to be LL_PCODE_HOLE_SAME" << LL_ENDL; -	} - -	if (path_type < LL_PCODE_PATH_MIN || -		path_type > LL_PCODE_PATH_MAX) -	{ -		// Bad path.  Make it linear. -		result = false; -		LL_WARNS() << "LLVolumeParams::setType changing bad path (" << path -			 	<< ") to be LL_PCODE_PATH_LINE" << LL_ENDL; -		path = LL_PCODE_PATH_LINE; -	} - -	mProfileParams.setCurveType(profile); -	mPathParams.setCurveType(path); -	return result; -} - -// static  +    bool result = true; +    // First, check profile and path for validity. +    U8 profile_type = profile & LL_PCODE_PROFILE_MASK; +    U8 hole_type    = (profile & LL_PCODE_HOLE_MASK) >> 4; +    U8 path_type    = path >> 4; + +    if (profile_type > LL_PCODE_PROFILE_MAX) +    { +        // Bad profile.  Make it square. +        profile = LL_PCODE_PROFILE_SQUARE; +        result = false; +        LL_WARNS() << "LLVolumeParams::setType changing bad profile type (" << profile_type +                << ") to be LL_PCODE_PROFILE_SQUARE" << LL_ENDL; +    } +    else if (hole_type > LL_PCODE_HOLE_MAX) +    { +        // Bad hole.  Make it the same. +        profile = profile_type; +        result = false; +        LL_WARNS() << "LLVolumeParams::setType changing bad hole type (" << hole_type +                << ") to be LL_PCODE_HOLE_SAME" << LL_ENDL; +    } + +    if (path_type < LL_PCODE_PATH_MIN || +        path_type > LL_PCODE_PATH_MAX) +    { +        // Bad path.  Make it linear. +        result = false; +        LL_WARNS() << "LLVolumeParams::setType changing bad path (" << path +                << ") to be LL_PCODE_PATH_LINE" << LL_ENDL; +        path = LL_PCODE_PATH_LINE; +    } + +    mProfileParams.setCurveType(profile); +    mPathParams.setCurveType(path); +    return result; +} + +// static  bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow, -		U8 path_curve, F32 path_begin, F32 path_end, -		F32 scx, F32 scy, F32 shx, F32 shy, -		F32 twistend, F32 twistbegin, F32 radiusoffset, -		F32 tx, F32 ty, F32 revolutions, F32 skew) -{ -	LLVolumeParams test_params; -	if (!test_params.setType		(prof_curve, path_curve)) -	{ -	    	return false; -	} -	if (!test_params.setBeginAndEndS	(prof_begin, prof_end)) -	{ -	    	return false; -	} -	if (!test_params.setBeginAndEndT	(path_begin, path_end)) -	{ -	    	return false; -	} -	if (!test_params.setHollow		(hollow)) -	{ -	    	return false; -	} -	if (!test_params.setTwistBegin		(twistbegin)) -	{ -	    	return false; -	} -	if (!test_params.setTwistEnd		(twistend)) -	{ -	    	return false; -	} -	if (!test_params.setRatio		(scx, scy)) -	{ -	    	return false; -	} -	if (!test_params.setShear		(shx, shy)) -	{ -	    	return false; -	} -	if (!test_params.setTaper		(tx, ty)) -	{ -	    	return false; -	} -	if (!test_params.setRevolutions		(revolutions)) -	{ -	    	return false; -	} -	if (!test_params.setRadiusOffset	(radiusoffset)) -	{ -	    	return false; -	} -	if (!test_params.setSkew		(skew)) -	{ -	    	return false; -	} -	return true; +        U8 path_curve, F32 path_begin, F32 path_end, +        F32 scx, F32 scy, F32 shx, F32 shy, +        F32 twistend, F32 twistbegin, F32 radiusoffset, +        F32 tx, F32 ty, F32 revolutions, F32 skew) +{ +    LLVolumeParams test_params; +    if (!test_params.setType        (prof_curve, path_curve)) +    { +            return false; +    } +    if (!test_params.setBeginAndEndS    (prof_begin, prof_end)) +    { +            return false; +    } +    if (!test_params.setBeginAndEndT    (path_begin, path_end)) +    { +            return false; +    } +    if (!test_params.setHollow      (hollow)) +    { +            return false; +    } +    if (!test_params.setTwistBegin      (twistbegin)) +    { +            return false; +    } +    if (!test_params.setTwistEnd        (twistend)) +    { +            return false; +    } +    if (!test_params.setRatio       (scx, scy)) +    { +            return false; +    } +    if (!test_params.setShear       (shx, shy)) +    { +            return false; +    } +    if (!test_params.setTaper       (tx, ty)) +    { +            return false; +    } +    if (!test_params.setRevolutions     (revolutions)) +    { +            return false; +    } +    if (!test_params.setRadiusOffset    (radiusoffset)) +    { +            return false; +    } +    if (!test_params.setSkew        (skew)) +    { +            return false; +    } +    return true;  }  void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts) -{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the  -	//supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost +{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the +    //supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost      LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; -	F32 detail[] = {1.f, 1.5f, 2.5f, 4.f};	 -	for (S32 i = 0; i < 4; i++) -	{ -		S32 count = 0; -		S32 path_points = LLPath::getNumPoints(params.getPathParams(), detail[i]); -		S32 profile_points = LLProfile::getNumPoints(params.getProfileParams(), false, detail[i]); +    F32 detail[] = {1.f, 1.5f, 2.5f, 4.f}; +    for (S32 i = 0; i < 4; i++) +    { +        S32 count = 0; +        S32 path_points = LLPath::getNumPoints(params.getPathParams(), detail[i]); +        S32 profile_points = LLProfile::getNumPoints(params.getProfileParams(), false, detail[i]); -		count = (profile_points-1)*2*(path_points-1); -		count += profile_points*2; +        count = (profile_points-1)*2*(path_points-1); +        count += profile_points*2; -		counts[i] = count; -	} +        counts[i] = count; +    }  }  S32 LLVolume::getNumTriangles(S32* vcount) const  { -	U32 triangle_count = 0; -	U32 vertex_count = 0; +    U32 triangle_count = 0; +    U32 vertex_count = 0; -	for (S32 i = 0; i < getNumVolumeFaces(); ++i) -	{ -		const LLVolumeFace& face = getVolumeFace(i); -		triangle_count += face.mNumIndices/3; +    for (S32 i = 0; i < getNumVolumeFaces(); ++i) +    { +        const LLVolumeFace& face = getVolumeFace(i); +        triangle_count += face.mNumIndices/3; -		vertex_count += face.mNumVertices; -	} +        vertex_count += face.mNumVertices; +    } -	if (vcount) -	{ -		*vcount = vertex_count; -	} -	 -	return triangle_count; +    if (vcount) +    { +        *vcount = vertex_count; +    } + +    return triangle_count;  } @@ -3833,989 +3833,989 @@ S32 LLVolume::getNumTriangles(S32* vcount) const  // generateSilhouetteVertices()  //-----------------------------------------------------------------------------  void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices, -										  std::vector<LLVector3> &normals, -										  const LLVector3& obj_cam_vec_in, -										  const LLMatrix4& mat_in, -										  const LLMatrix3& norm_mat_in, -										  S32 face_mask) -{ -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - -	LLMatrix4a mat; -	mat.loadu(mat_in); - -	LLMatrix4a norm_mat; -	norm_mat.loadu(norm_mat_in); -		 -	LLVector4a obj_cam_vec; -	obj_cam_vec.load3(obj_cam_vec_in.mV); - -	vertices.clear(); -	normals.clear(); - -	if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) -	{ -		return; -	} -	 -	S32 cur_index = 0; -	//for each face -	for (face_list_t::iterator iter = mVolumeFaces.begin(); -		 iter != mVolumeFaces.end(); ++iter) -	{ -		LLVolumeFace& face = *iter; -	 -		if (!(face_mask & (0x1 << cur_index++)) || -		     face.mNumIndices == 0 || face.mEdge.empty()) -		{ -			continue; -		} - -		if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) -		{ -			LLVector4a* v = (LLVector4a*)face.mPositions; -			LLVector4a* n = (LLVector4a*)face.mNormals; - -			for (U32 j = 0; j < face.mNumIndices / 3; j++) -			{ -				for (S32 k = 0; k < 3; k++) -				{ -					S32 index = face.mEdge[j * 3 + k]; - -					if (index == -1) -					{ -						// silhouette edge, currently only cubes, so no other conditions - -						S32 v1 = face.mIndices[j * 3 + k]; -						S32 v2 = face.mIndices[j * 3 + ((k + 1) % 3)]; - -						LLVector4a t; -						mat.affineTransform(v[v1], t); -						vertices.push_back(LLVector3(t[0], t[1], t[2])); - -						norm_mat.rotate(n[v1], t); - -						t.normalize3fast(); -						normals.push_back(LLVector3(t[0], t[1], t[2])); - -						mat.affineTransform(v[v2], t); -						vertices.push_back(LLVector3(t[0], t[1], t[2])); - -						norm_mat.rotate(n[v2], t); -						t.normalize3fast(); -						normals.push_back(LLVector3(t[0], t[1], t[2])); -					} -				} -			} -	 -		} -		else -		{ - -			//============================================== -			//DEBUG draw edge map instead of silhouette edge -			//============================================== +                                          std::vector<LLVector3> &normals, +                                          const LLVector3& obj_cam_vec_in, +                                          const LLMatrix4& mat_in, +                                          const LLMatrix3& norm_mat_in, +                                          S32 face_mask) +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + +    LLMatrix4a mat; +    mat.loadu(mat_in); + +    LLMatrix4a norm_mat; +    norm_mat.loadu(norm_mat_in); + +    LLVector4a obj_cam_vec; +    obj_cam_vec.load3(obj_cam_vec_in.mV); + +    vertices.clear(); +    normals.clear(); + +    if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) +    { +        return; +    } + +    S32 cur_index = 0; +    //for each face +    for (face_list_t::iterator iter = mVolumeFaces.begin(); +         iter != mVolumeFaces.end(); ++iter) +    { +        LLVolumeFace& face = *iter; + +        if (!(face_mask & (0x1 << cur_index++)) || +             face.mNumIndices == 0 || face.mEdge.empty()) +        { +            continue; +        } + +        if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) +        { +            LLVector4a* v = (LLVector4a*)face.mPositions; +            LLVector4a* n = (LLVector4a*)face.mNormals; + +            for (U32 j = 0; j < face.mNumIndices / 3; j++) +            { +                for (S32 k = 0; k < 3; k++) +                { +                    S32 index = face.mEdge[j * 3 + k]; + +                    if (index == -1) +                    { +                        // silhouette edge, currently only cubes, so no other conditions + +                        S32 v1 = face.mIndices[j * 3 + k]; +                        S32 v2 = face.mIndices[j * 3 + ((k + 1) % 3)]; + +                        LLVector4a t; +                        mat.affineTransform(v[v1], t); +                        vertices.push_back(LLVector3(t[0], t[1], t[2])); + +                        norm_mat.rotate(n[v1], t); + +                        t.normalize3fast(); +                        normals.push_back(LLVector3(t[0], t[1], t[2])); + +                        mat.affineTransform(v[v2], t); +                        vertices.push_back(LLVector3(t[0], t[1], t[2])); + +                        norm_mat.rotate(n[v2], t); +                        t.normalize3fast(); +                        normals.push_back(LLVector3(t[0], t[1], t[2])); +                    } +                } +            } + +        } +        else +        { + +            //============================================== +            //DEBUG draw edge map instead of silhouette edge +            //==============================================  #if DEBUG_SILHOUETTE_EDGE_MAP -			//for each triangle +            //for each triangle              U32 tri_count = face.mNumIndices / 3;              for (U32 j = 0; j < tri_count; j++) { -				//get vertices -				S32 v1 = face.mIndices[j*3+0]; -				S32 v2 = face.mIndices[j*3+1]; -				S32 v3 = face.mIndices[j*3+2]; - -				//get current face center -				LLVector3 cCenter = (face.mVertices[v1].getPosition() +  -									face.mVertices[v2].getPosition() +  -									face.mVertices[v3].getPosition()) / 3.0f; - -				//for each edge -				for (S32 k = 0; k < 3; k++) { +                //get vertices +                S32 v1 = face.mIndices[j*3+0]; +                S32 v2 = face.mIndices[j*3+1]; +                S32 v3 = face.mIndices[j*3+2]; + +                //get current face center +                LLVector3 cCenter = (face.mVertices[v1].getPosition() + +                                    face.mVertices[v2].getPosition() + +                                    face.mVertices[v3].getPosition()) / 3.0f; + +                //for each edge +                for (S32 k = 0; k < 3; k++) {                      S32 nIndex = face.mEdge[j*3+k]; -					if (nIndex <= -1) { -						continue; -					} +                    if (nIndex <= -1) { +                        continue; +                    }                      if (nIndex >= (S32)tri_count) { -						continue; -					} -					//get neighbor vertices -					v1 = face.mIndices[nIndex*3+0]; -					v2 = face.mIndices[nIndex*3+1]; -					v3 = face.mIndices[nIndex*3+2]; - -					//get neighbor face center -					LLVector3 nCenter = (face.mVertices[v1].getPosition() +  -									face.mVertices[v2].getPosition() +  -									face.mVertices[v3].getPosition()) / 3.0f; - -					//draw line -					vertices.push_back(cCenter); -					vertices.push_back(nCenter); -					normals.push_back(LLVector3(1,1,1)); -					normals.push_back(LLVector3(1,1,1)); -					segments.push_back(vertices.size()); -				} -			} -		 -			continue; - -			//============================================== -			//DEBUG -			//============================================== - -			//============================================== -			//DEBUG draw normals instead of silhouette edge -			//============================================== +                        continue; +                    } +                    //get neighbor vertices +                    v1 = face.mIndices[nIndex*3+0]; +                    v2 = face.mIndices[nIndex*3+1]; +                    v3 = face.mIndices[nIndex*3+2]; + +                    //get neighbor face center +                    LLVector3 nCenter = (face.mVertices[v1].getPosition() + +                                    face.mVertices[v2].getPosition() + +                                    face.mVertices[v3].getPosition()) / 3.0f; + +                    //draw line +                    vertices.push_back(cCenter); +                    vertices.push_back(nCenter); +                    normals.push_back(LLVector3(1,1,1)); +                    normals.push_back(LLVector3(1,1,1)); +                    segments.push_back(vertices.size()); +                } +            } + +            continue; + +            //============================================== +            //DEBUG +            //============================================== + +            //============================================== +            //DEBUG draw normals instead of silhouette edge +            //==============================================  #elif DEBUG_SILHOUETTE_NORMALS -			//for each vertex -			for (U32 j = 0; j < face.mNumVertices; j++) { -				vertices.push_back(face.mVertices[j].getPosition()); -				vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].getNormal()*0.1f); -				normals.push_back(LLVector3(0,0,1)); -				normals.push_back(LLVector3(0,0,1)); -				segments.push_back(vertices.size()); +            //for each vertex +            for (U32 j = 0; j < face.mNumVertices; j++) { +                vertices.push_back(face.mVertices[j].getPosition()); +                vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].getNormal()*0.1f); +                normals.push_back(LLVector3(0,0,1)); +                normals.push_back(LLVector3(0,0,1)); +                segments.push_back(vertices.size());  #if DEBUG_SILHOUETTE_BINORMALS -				vertices.push_back(face.mVertices[j].getPosition()); -				vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f); -				normals.push_back(LLVector3(0,0,1)); -				normals.push_back(LLVector3(0,0,1)); -				segments.push_back(vertices.size()); +                vertices.push_back(face.mVertices[j].getPosition()); +                vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f); +                normals.push_back(LLVector3(0,0,1)); +                normals.push_back(LLVector3(0,0,1)); +                segments.push_back(vertices.size());  #endif -			} -						 -			continue; +            } + +            continue;  #else -			//============================================== -			//DEBUG -			//============================================== - -			static const U8 AWAY = 0x01, -							TOWARDS = 0x02; - -			//for each triangle -			std::vector<U8> fFacing; -			vector_append(fFacing, face.mNumIndices/3); - -			LLVector4a* v = (LLVector4a*) face.mPositions; -			LLVector4a* n = (LLVector4a*) face.mNormals; - -			for (U32 j = 0; j < face.mNumIndices/3; j++)  -			{ -				//approximate normal -				S32 v1 = face.mIndices[j*3+0]; -				S32 v2 = face.mIndices[j*3+1]; -				S32 v3 = face.mIndices[j*3+2]; - -				LLVector4a c1,c2; -				c1.setSub(v[v1], v[v2]); -				c2.setSub(v[v2], v[v3]); - -				LLVector4a norm; - -				norm.setCross3(c1, c2); - -				if (norm.dot3(norm) < 0.00000001f)  -				{ -					fFacing[j] = AWAY | TOWARDS; -				} -				else  -				{ -					//get view vector -					LLVector4a view; -					view.setSub(obj_cam_vec, v[v1]); -					bool away = view.dot3(norm) > 0.0f;  -					if (away)  -					{ -						fFacing[j] = AWAY; -					} -					else  -					{ -						fFacing[j] = TOWARDS; -					} -				} -			} -			 -			//for each triangle -			for (U32 j = 0; j < face.mNumIndices/3; j++)  -			{ -				if (fFacing[j] == (AWAY | TOWARDS))  -				{ //this is a degenerate triangle -					//take neighbor facing (degenerate faces get facing of one of their neighbors) -					// *FIX IF NEEDED:  this does not deal with neighboring degenerate faces -					for (S32 k = 0; k < 3; k++)  -					{ -						S32 index = face.mEdge[j*3+k]; -						if (index != -1)  -						{ -							fFacing[j] = fFacing[index]; -							break; -						} -					} -					continue; //skip degenerate face -				} - -				//for each edge -				for (S32 k = 0; k < 3; k++) { -					S32 index = face.mEdge[j*3+k]; -					if (index != -1 && fFacing[index] == (AWAY | TOWARDS)) { -						//our neighbor is degenerate, make him face our direction -						fFacing[face.mEdge[j*3+k]] = fFacing[j]; -						continue; -					} - -					if (index == -1 ||		//edge has no neighbor, MUST be a silhouette edge -						(fFacing[index] & fFacing[j]) == 0) { 	//we found a silhouette edge - -						S32 v1 = face.mIndices[j*3+k]; -						S32 v2 = face.mIndices[j*3+((k+1)%3)]; -						 -						LLVector4a t; -						mat.affineTransform(v[v1], t); -						vertices.push_back(LLVector3(t[0], t[1], t[2])); - -						norm_mat.rotate(n[v1], t); - -						t.normalize3fast(); -						normals.push_back(LLVector3(t[0], t[1], t[2])); - -						mat.affineTransform(v[v2], t); -						vertices.push_back(LLVector3(t[0], t[1], t[2])); -						 -						norm_mat.rotate(n[v2], t); -						t.normalize3fast(); -						normals.push_back(LLVector3(t[0], t[1], t[2])); -					} -				}		 -			} +            //============================================== +            //DEBUG +            //============================================== + +            static const U8 AWAY = 0x01, +                            TOWARDS = 0x02; + +            //for each triangle +            std::vector<U8> fFacing; +            vector_append(fFacing, face.mNumIndices/3); + +            LLVector4a* v = (LLVector4a*) face.mPositions; +            LLVector4a* n = (LLVector4a*) face.mNormals; + +            for (U32 j = 0; j < face.mNumIndices/3; j++) +            { +                //approximate normal +                S32 v1 = face.mIndices[j*3+0]; +                S32 v2 = face.mIndices[j*3+1]; +                S32 v3 = face.mIndices[j*3+2]; + +                LLVector4a c1,c2; +                c1.setSub(v[v1], v[v2]); +                c2.setSub(v[v2], v[v3]); + +                LLVector4a norm; + +                norm.setCross3(c1, c2); + +                if (norm.dot3(norm) < 0.00000001f) +                { +                    fFacing[j] = AWAY | TOWARDS; +                } +                else +                { +                    //get view vector +                    LLVector4a view; +                    view.setSub(obj_cam_vec, v[v1]); +                    bool away = view.dot3(norm) > 0.0f; +                    if (away) +                    { +                        fFacing[j] = AWAY; +                    } +                    else +                    { +                        fFacing[j] = TOWARDS; +                    } +                } +            } + +            //for each triangle +            for (U32 j = 0; j < face.mNumIndices/3; j++) +            { +                if (fFacing[j] == (AWAY | TOWARDS)) +                { //this is a degenerate triangle +                    //take neighbor facing (degenerate faces get facing of one of their neighbors) +                    // *FIX IF NEEDED:  this does not deal with neighboring degenerate faces +                    for (S32 k = 0; k < 3; k++) +                    { +                        S32 index = face.mEdge[j*3+k]; +                        if (index != -1) +                        { +                            fFacing[j] = fFacing[index]; +                            break; +                        } +                    } +                    continue; //skip degenerate face +                } + +                //for each edge +                for (S32 k = 0; k < 3; k++) { +                    S32 index = face.mEdge[j*3+k]; +                    if (index != -1 && fFacing[index] == (AWAY | TOWARDS)) { +                        //our neighbor is degenerate, make him face our direction +                        fFacing[face.mEdge[j*3+k]] = fFacing[j]; +                        continue; +                    } + +                    if (index == -1 ||      //edge has no neighbor, MUST be a silhouette edge +                        (fFacing[index] & fFacing[j]) == 0) {   //we found a silhouette edge + +                        S32 v1 = face.mIndices[j*3+k]; +                        S32 v2 = face.mIndices[j*3+((k+1)%3)]; + +                        LLVector4a t; +                        mat.affineTransform(v[v1], t); +                        vertices.push_back(LLVector3(t[0], t[1], t[2])); + +                        norm_mat.rotate(n[v1], t); + +                        t.normalize3fast(); +                        normals.push_back(LLVector3(t[0], t[1], t[2])); + +                        mat.affineTransform(v[v2], t); +                        vertices.push_back(LLVector3(t[0], t[1], t[2])); + +                        norm_mat.rotate(n[v2], t); +                        t.normalize3fast(); +                        normals.push_back(LLVector3(t[0], t[1], t[2])); +                    } +                } +            }  #endif -		} -	} -} - -S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  -								   S32 face, -								   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out) -{ -	S32 hit_face = -1; -	 -	S32 start_face; -	S32 end_face; -	 -	if (face == -1) // ALL_SIDES -	{ -		start_face = 0; -		end_face = getNumVolumeFaces() - 1; -	} -	else -	{ -		start_face = face; -		end_face = face; -	} - -	LLVector4a dir; -	dir.setSub(end, start); - -	F32 closest_t = 2.f; // must be larger than 1 -	 -	end_face = llmin(end_face, getNumVolumeFaces()-1); - -	for (S32 i = start_face; i <= end_face; i++) -	{ -		LLVolumeFace &face = mVolumeFaces[i]; - -		LLVector4a box_center; -		box_center.setAdd(face.mExtents[0], face.mExtents[1]); -		box_center.mul(0.5f); - -		LLVector4a box_size; -		box_size.setSub(face.mExtents[1], face.mExtents[0]); +        } +    } +} + +S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, +                                   S32 face, +                                   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out) +{ +    S32 hit_face = -1; + +    S32 start_face; +    S32 end_face; + +    if (face == -1) // ALL_SIDES +    { +        start_face = 0; +        end_face = getNumVolumeFaces() - 1; +    } +    else +    { +        start_face = face; +        end_face = face; +    } + +    LLVector4a dir; +    dir.setSub(end, start); + +    F32 closest_t = 2.f; // must be larger than 1 + +    end_face = llmin(end_face, getNumVolumeFaces()-1); + +    for (S32 i = start_face; i <= end_face; i++) +    { +        LLVolumeFace &face = mVolumeFaces[i]; + +        LLVector4a box_center; +        box_center.setAdd(face.mExtents[0], face.mExtents[1]); +        box_center.mul(0.5f); + +        LLVector4a box_size; +        box_size.setSub(face.mExtents[1], face.mExtents[0]);          if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) -		{ -			if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them -			{ +        { +            if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them +            {                  genTangents(i); -			} - -			if (isUnique()) -			{ //don't bother with an octree for flexi volumes -				U32 tri_count = face.mNumIndices/3; - -				for (U32 j = 0; j < tri_count; ++j) -				{ -					U16 idx0 = face.mIndices[j*3+0]; -					U16 idx1 = face.mIndices[j*3+1]; -					U16 idx2 = face.mIndices[j*3+2]; - -					const LLVector4a& v0 = face.mPositions[idx0]; -					const LLVector4a& v1 = face.mPositions[idx1]; -					const LLVector4a& v2 = face.mPositions[idx2]; -				 -					F32 a,b,t; - -					if (LLTriangleRayIntersect(v0, v1, v2, -							start, dir, a, b, t)) -					{ -						if ((t >= 0.f) &&      // if hit is after start -							(t <= 1.f) &&      // and before end -							(t < closest_t))   // and this hit is closer -						{ -							closest_t = t; -							hit_face = i; - -							if (intersection != NULL) -							{ -								LLVector4a intersect = dir; -								intersect.mul(closest_t); -								intersect.add(start); -								*intersection = intersect; -							} - - -							if (tex_coord != NULL) -							{ -								LLVector2* tc = (LLVector2*) face.mTexCoords; -								*tex_coord = ((1.f - a - b)  * tc[idx0] + -									a              * tc[idx1] + -									b              * tc[idx2]); - -							} - -							if (normal!= NULL) -							{ -								LLVector4a* norm = face.mNormals; -								 -								LLVector4a n1,n2,n3; -								n1 = norm[idx0]; -								n1.mul(1.f-a-b); -								 -								n2 = norm[idx1]; -								n2.mul(a); -								 -								n3 = norm[idx2]; -								n3.mul(b); - -								n1.add(n2); -								n1.add(n3); -								 -								*normal		= n1;  -							} - -							if (tangent_out != NULL) -							{ -								LLVector4a* tangents = face.mTangents; -								 -								LLVector4a t1,t2,t3; -								t1 = tangents[idx0]; -								t1.mul(1.f-a-b); -								 -								t2 = tangents[idx1]; -								t2.mul(a); -								 -								t3 = tangents[idx2]; -								t3.mul(b); - -								t1.add(t2); -								t1.add(t3); -								 -								*tangent_out = t1;  -							} -						} -					} -				} -			} -			else -			{ +            } + +            if (isUnique()) +            { //don't bother with an octree for flexi volumes +                U32 tri_count = face.mNumIndices/3; + +                for (U32 j = 0; j < tri_count; ++j) +                { +                    U16 idx0 = face.mIndices[j*3+0]; +                    U16 idx1 = face.mIndices[j*3+1]; +                    U16 idx2 = face.mIndices[j*3+2]; + +                    const LLVector4a& v0 = face.mPositions[idx0]; +                    const LLVector4a& v1 = face.mPositions[idx1]; +                    const LLVector4a& v2 = face.mPositions[idx2]; + +                    F32 a,b,t; + +                    if (LLTriangleRayIntersect(v0, v1, v2, +                            start, dir, a, b, t)) +                    { +                        if ((t >= 0.f) &&      // if hit is after start +                            (t <= 1.f) &&      // and before end +                            (t < closest_t))   // and this hit is closer +                        { +                            closest_t = t; +                            hit_face = i; + +                            if (intersection != NULL) +                            { +                                LLVector4a intersect = dir; +                                intersect.mul(closest_t); +                                intersect.add(start); +                                *intersection = intersect; +                            } + + +                            if (tex_coord != NULL) +                            { +                                LLVector2* tc = (LLVector2*) face.mTexCoords; +                                *tex_coord = ((1.f - a - b)  * tc[idx0] + +                                    a              * tc[idx1] + +                                    b              * tc[idx2]); + +                            } + +                            if (normal!= NULL) +                            { +                                LLVector4a* norm = face.mNormals; + +                                LLVector4a n1,n2,n3; +                                n1 = norm[idx0]; +                                n1.mul(1.f-a-b); + +                                n2 = norm[idx1]; +                                n2.mul(a); + +                                n3 = norm[idx2]; +                                n3.mul(b); + +                                n1.add(n2); +                                n1.add(n3); + +                                *normal     = n1; +                            } + +                            if (tangent_out != NULL) +                            { +                                LLVector4a* tangents = face.mTangents; + +                                LLVector4a t1,t2,t3; +                                t1 = tangents[idx0]; +                                t1.mul(1.f-a-b); + +                                t2 = tangents[idx1]; +                                t2.mul(a); + +                                t3 = tangents[idx2]; +                                t3.mul(b); + +                                t1.add(t2); +                                t1.add(t3); + +                                *tangent_out = t1; +                            } +                        } +                    } +                } +            } +            else +            {                  if (!face.getOctree()) -				{ -					face.createOctree(); -				} -			 -				LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out); +                { +                    face.createOctree(); +                } + +                LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);                  intersect.traverse(face.getOctree()); -				if (intersect.mHitFace) -				{ -					hit_face = i; -				} -			} -		}		 -	} -	 -	 -	return hit_face; +                if (intersect.mHitFace) +                { +                    hit_face = i; +                } +            } +        } +    } + + +    return hit_face;  }  class LLVertexIndexPair  {  public: -	LLVertexIndexPair(const LLVector3 &vertex, const S32 index); +    LLVertexIndexPair(const LLVector3 &vertex, const S32 index); -	LLVector3 mVertex; -	S32	mIndex; +    LLVector3 mVertex; +    S32 mIndex;  };  LLVertexIndexPair::LLVertexIndexPair(const LLVector3 &vertex, const S32 index)  { -	mVertex = vertex; -	mIndex = index; +    mVertex = vertex; +    mIndex = index;  }  const F32 VERTEX_SLOP = 0.00001f;  struct lessVertex  { -	bool operator()(const LLVertexIndexPair *a, const LLVertexIndexPair *b) -	{ -		const F32 slop = VERTEX_SLOP; - -		if (a->mVertex.mV[0] + slop < b->mVertex.mV[0]) -		{ -			return TRUE; -		} -		else if (a->mVertex.mV[0] - slop > b->mVertex.mV[0]) -		{ -			return FALSE; -		} -		 -		if (a->mVertex.mV[1] + slop < b->mVertex.mV[1]) -		{ -			return TRUE; -		} -		else if (a->mVertex.mV[1] - slop > b->mVertex.mV[1]) -		{ -			return FALSE; -		} -		 -		if (a->mVertex.mV[2] + slop < b->mVertex.mV[2]) -		{ -			return TRUE; -		} -		else if (a->mVertex.mV[2] - slop > b->mVertex.mV[2]) -		{ -			return FALSE; -		} -		 -		return FALSE; -	} +    bool operator()(const LLVertexIndexPair *a, const LLVertexIndexPair *b) +    { +        const F32 slop = VERTEX_SLOP; + +        if (a->mVertex.mV[0] + slop < b->mVertex.mV[0]) +        { +            return TRUE; +        } +        else if (a->mVertex.mV[0] - slop > b->mVertex.mV[0]) +        { +            return FALSE; +        } + +        if (a->mVertex.mV[1] + slop < b->mVertex.mV[1]) +        { +            return TRUE; +        } +        else if (a->mVertex.mV[1] - slop > b->mVertex.mV[1]) +        { +            return FALSE; +        } + +        if (a->mVertex.mV[2] + slop < b->mVertex.mV[2]) +        { +            return TRUE; +        } +        else if (a->mVertex.mV[2] - slop > b->mVertex.mV[2]) +        { +            return FALSE; +        } + +        return FALSE; +    }  };  struct lessTriangle  { -	bool operator()(const S32 *a, const S32 *b) -	{ -		if (*a < *b) -		{ -			return TRUE; -		} -		else if (*a > *b) -		{ -			return FALSE; -		} - -		if (*(a+1) < *(b+1)) -		{ -			return TRUE; -		} -		else if (*(a+1) > *(b+1)) -		{ -			return FALSE; -		} - -		if (*(a+2) < *(b+2)) -		{ -			return TRUE; -		} -		else if (*(a+2) > *(b+2)) -		{ -			return FALSE; -		} - -		return FALSE; -	} +    bool operator()(const S32 *a, const S32 *b) +    { +        if (*a < *b) +        { +            return TRUE; +        } +        else if (*a > *b) +        { +            return FALSE; +        } + +        if (*(a+1) < *(b+1)) +        { +            return TRUE; +        } +        else if (*(a+1) > *(b+1)) +        { +            return FALSE; +        } + +        if (*(a+2) < *(b+2)) +        { +            return TRUE; +        } +        else if (*(a+2) > *(b+2)) +        { +            return FALSE; +        } + +        return FALSE; +    }  };  BOOL equalTriangle(const S32 *a, const S32 *b)  { -	if ((*a == *b) && (*(a+1) == *(b+1)) && (*(a+2) == *(b+2))) -	{ -		return TRUE; -	} -	return FALSE; +    if ((*a == *b) && (*(a+1) == *(b+1)) && (*(a+2) == *(b+2))) +    { +        return TRUE; +    } +    return FALSE;  }  BOOL LLVolumeParams::importFile(LLFILE *fp)  { -	//LL_INFOS() << "importing volume" << LL_ENDL; -	const S32 BUFSIZE = 16384; -	char buffer[BUFSIZE];	/* Flawfinder: ignore */ -	// *NOTE: changing the size or type of this buffer will require -	// changing the sscanf below. -	char keyword[256];	/* Flawfinder: ignore */ -	keyword[0] = 0; - -	while (!feof(fp)) -	{ -		if (fgets(buffer, BUFSIZE, fp) == NULL) -		{ -			buffer[0] = '\0'; -		} -		 -		sscanf(buffer, " %255s", keyword);	/* Flawfinder: ignore */ -		if (!strcmp("{", keyword)) -		{ -			continue; -		} -		if (!strcmp("}",keyword)) -		{ -			break; -		} -		else if (!strcmp("profile", keyword)) -		{ -			mProfileParams.importFile(fp); -		} -		else if (!strcmp("path",keyword)) -		{ -			mPathParams.importFile(fp); -		} -		else -		{ -			LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL; -		} -	} - -	return TRUE; +    //LL_INFOS() << "importing volume" << LL_ENDL; +    const S32 BUFSIZE = 16384; +    char buffer[BUFSIZE];   /* Flawfinder: ignore */ +    // *NOTE: changing the size or type of this buffer will require +    // changing the sscanf below. +    char keyword[256];  /* Flawfinder: ignore */ +    keyword[0] = 0; + +    while (!feof(fp)) +    { +        if (fgets(buffer, BUFSIZE, fp) == NULL) +        { +            buffer[0] = '\0'; +        } + +        sscanf(buffer, " %255s", keyword);  /* Flawfinder: ignore */ +        if (!strcmp("{", keyword)) +        { +            continue; +        } +        if (!strcmp("}",keyword)) +        { +            break; +        } +        else if (!strcmp("profile", keyword)) +        { +            mProfileParams.importFile(fp); +        } +        else if (!strcmp("path",keyword)) +        { +            mPathParams.importFile(fp); +        } +        else +        { +            LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL; +        } +    } + +    return TRUE;  }  BOOL LLVolumeParams::exportFile(LLFILE *fp) const  { -	fprintf(fp,"\tshape 0\n"); -	fprintf(fp,"\t{\n"); -	mPathParams.exportFile(fp); -	mProfileParams.exportFile(fp); -	fprintf(fp, "\t}\n"); -	return TRUE; +    fprintf(fp,"\tshape 0\n"); +    fprintf(fp,"\t{\n"); +    mPathParams.exportFile(fp); +    mProfileParams.exportFile(fp); +    fprintf(fp, "\t}\n"); +    return TRUE;  }  BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream)  { -	//LL_INFOS() << "importing volume" << LL_ENDL; -	const S32 BUFSIZE = 16384; -	// *NOTE: changing the size or type of this buffer will require -	// changing the sscanf below. -	char buffer[BUFSIZE];		/* Flawfinder: ignore */ -	char keyword[256];		/* Flawfinder: ignore */ -	keyword[0] = 0; - -	while (input_stream.good()) -	{ -		input_stream.getline(buffer, BUFSIZE); -		sscanf(buffer, " %255s", keyword); -		if (!strcmp("{", keyword)) -		{ -			continue; -		} -		if (!strcmp("}",keyword)) -		{ -			break; -		} -		else if (!strcmp("profile", keyword)) -		{ -			mProfileParams.importLegacyStream(input_stream); -		} -		else if (!strcmp("path",keyword)) -		{ -			mPathParams.importLegacyStream(input_stream); -		} -		else -		{ -			LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL; -		} -	} - -	return TRUE; +    //LL_INFOS() << "importing volume" << LL_ENDL; +    const S32 BUFSIZE = 16384; +    // *NOTE: changing the size or type of this buffer will require +    // changing the sscanf below. +    char buffer[BUFSIZE];       /* Flawfinder: ignore */ +    char keyword[256];      /* Flawfinder: ignore */ +    keyword[0] = 0; + +    while (input_stream.good()) +    { +        input_stream.getline(buffer, BUFSIZE); +        sscanf(buffer, " %255s", keyword); +        if (!strcmp("{", keyword)) +        { +            continue; +        } +        if (!strcmp("}",keyword)) +        { +            break; +        } +        else if (!strcmp("profile", keyword)) +        { +            mProfileParams.importLegacyStream(input_stream); +        } +        else if (!strcmp("path",keyword)) +        { +            mPathParams.importLegacyStream(input_stream); +        } +        else +        { +            LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL; +        } +    } + +    return TRUE;  }  BOOL LLVolumeParams::exportLegacyStream(std::ostream& output_stream) const  { -	output_stream <<"\tshape 0\n"; -	output_stream <<"\t{\n"; -	mPathParams.exportLegacyStream(output_stream); -	mProfileParams.exportLegacyStream(output_stream); -	output_stream << "\t}\n"; -	return TRUE; +    output_stream <<"\tshape 0\n"; +    output_stream <<"\t{\n"; +    mPathParams.exportLegacyStream(output_stream); +    mProfileParams.exportLegacyStream(output_stream); +    output_stream << "\t}\n"; +    return TRUE;  }  LLSD LLVolumeParams::sculptAsLLSD() const  { -	LLSD sd = LLSD(); -	sd["id"] = getSculptID(); -	sd["type"] = getSculptType(); +    LLSD sd = LLSD(); +    sd["id"] = getSculptID(); +    sd["type"] = getSculptType(); -	return sd; +    return sd;  }  bool LLVolumeParams::sculptFromLLSD(LLSD& sd)  { -	setSculptID(sd["id"].asUUID(), (U8)sd["type"].asInteger()); -	return true; +    setSculptID(sd["id"].asUUID(), (U8)sd["type"].asInteger()); +    return true;  }  LLSD LLVolumeParams::asLLSD() const  { -	LLSD sd = LLSD(); -	sd["path"] = mPathParams; -	sd["profile"] = mProfileParams; -	sd["sculpt"] = sculptAsLLSD(); -	 -	return sd; +    LLSD sd = LLSD(); +    sd["path"] = mPathParams; +    sd["profile"] = mProfileParams; +    sd["sculpt"] = sculptAsLLSD(); + +    return sd;  }  bool LLVolumeParams::fromLLSD(LLSD& sd)  { -	mPathParams.fromLLSD(sd["path"]); -	mProfileParams.fromLLSD(sd["profile"]); -	sculptFromLLSD(sd["sculpt"]); -		 -	return true; +    mPathParams.fromLLSD(sd["path"]); +    mProfileParams.fromLLSD(sd["profile"]); +    sculptFromLLSD(sd["sculpt"]); + +    return true;  }  void LLVolumeParams::reduceS(F32 begin, F32 end)  { -	begin = llclampf(begin); -	end = llclampf(end); -	if (begin > end) -	{ -		F32 temp = begin; -		begin = end; -		end = temp; -	} -	F32 a = mProfileParams.getBegin(); -	F32 b = mProfileParams.getEnd(); -	mProfileParams.setBegin(a + begin * (b - a)); -	mProfileParams.setEnd(a + end * (b - a)); +    begin = llclampf(begin); +    end = llclampf(end); +    if (begin > end) +    { +        F32 temp = begin; +        begin = end; +        end = temp; +    } +    F32 a = mProfileParams.getBegin(); +    F32 b = mProfileParams.getEnd(); +    mProfileParams.setBegin(a + begin * (b - a)); +    mProfileParams.setEnd(a + end * (b - a));  }  void LLVolumeParams::reduceT(F32 begin, F32 end)  { -	begin = llclampf(begin); -	end = llclampf(end); -	if (begin > end) -	{ -		F32 temp = begin; -		begin = end; -		end = temp; -	} -	F32 a = mPathParams.getBegin(); -	F32 b = mPathParams.getEnd(); -	mPathParams.setBegin(a + begin * (b - a)); -	mPathParams.setEnd(a + end * (b - a)); +    begin = llclampf(begin); +    end = llclampf(end); +    if (begin > end) +    { +        F32 temp = begin; +        begin = end; +        end = temp; +    } +    F32 a = mPathParams.getBegin(); +    F32 b = mPathParams.getEnd(); +    mPathParams.setBegin(a + begin * (b - a)); +    mPathParams.setEnd(a + end * (b - a));  } -const F32 MIN_CONCAVE_PROFILE_WEDGE = 0.125f;	// 1/8 unity -const F32 MIN_CONCAVE_PATH_WEDGE = 0.111111f;	// 1/9 unity +const F32 MIN_CONCAVE_PROFILE_WEDGE = 0.125f;   // 1/8 unity +const F32 MIN_CONCAVE_PATH_WEDGE = 0.111111f;   // 1/9 unity -// returns TRUE if the shape can be approximated with a convex shape  +// returns TRUE if the shape can be approximated with a convex shape  // for collison purposes  BOOL LLVolumeParams::isConvex() const  { -	if (!getSculptID().isNull()) -	{ -		// can't determine, be safe and say no: -		return FALSE; -	} -	 -	F32 path_length = mPathParams.getEnd() - mPathParams.getBegin(); -	F32 hollow = mProfileParams.getHollow(); -	  -	U8 path_type = mPathParams.getCurveType(); -	if ( path_length > MIN_CONCAVE_PATH_WEDGE -		&& ( mPathParams.getTwist() != mPathParams.getTwistBegin() -		     || (hollow > 0.f  -				 && LL_PCODE_PATH_LINE != path_type) ) ) -	{ -		// twist along a "not too short" path is concave -		return FALSE; -	} - -	F32 profile_length = mProfileParams.getEnd() - mProfileParams.getBegin(); -	BOOL same_hole = hollow == 0.f  -					 || (mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK) == LL_PCODE_HOLE_SAME; - -	F32 min_profile_wedge = MIN_CONCAVE_PROFILE_WEDGE; -	U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; -	if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ) -	{ -		// it is a sphere and spheres get twice the minimum profile wedge -		min_profile_wedge = 2.f * MIN_CONCAVE_PROFILE_WEDGE; -	} - -	BOOL convex_profile = ( ( profile_length == 1.f -						     || profile_length <= 0.5f ) -						   && hollow == 0.f )						// trivially convex -						  || ( profile_length <= min_profile_wedge -							  && same_hole );						// effectvely convex (even when hollow) - -	if (!convex_profile) -	{ -		// profile is concave -		return FALSE; -	} - -	if ( LL_PCODE_PATH_LINE == path_type ) -	{ -		// straight paths with convex profile -		return TRUE; -	} - -	BOOL concave_path = (path_length < 1.0f) && (path_length > 0.5f); -	if (concave_path) -	{ -		return FALSE; -	} - -	// we're left with spheres, toroids and tubes -	if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ) -	{ -		// at this stage all spheres must be convex -		return TRUE; -	} - -	// it's a toroid or tube		 -	if ( path_length <= MIN_CONCAVE_PATH_WEDGE ) -	{ -		// effectively convex -		return TRUE; -	} - -	return FALSE; +    if (!getSculptID().isNull()) +    { +        // can't determine, be safe and say no: +        return FALSE; +    } + +    F32 path_length = mPathParams.getEnd() - mPathParams.getBegin(); +    F32 hollow = mProfileParams.getHollow(); + +    U8 path_type = mPathParams.getCurveType(); +    if ( path_length > MIN_CONCAVE_PATH_WEDGE +        && ( mPathParams.getTwist() != mPathParams.getTwistBegin() +             || (hollow > 0.f +                 && LL_PCODE_PATH_LINE != path_type) ) ) +    { +        // twist along a "not too short" path is concave +        return FALSE; +    } + +    F32 profile_length = mProfileParams.getEnd() - mProfileParams.getBegin(); +    BOOL same_hole = hollow == 0.f +                     || (mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK) == LL_PCODE_HOLE_SAME; + +    F32 min_profile_wedge = MIN_CONCAVE_PROFILE_WEDGE; +    U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK; +    if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ) +    { +        // it is a sphere and spheres get twice the minimum profile wedge +        min_profile_wedge = 2.f * MIN_CONCAVE_PROFILE_WEDGE; +    } + +    BOOL convex_profile = ( ( profile_length == 1.f +                             || profile_length <= 0.5f ) +                           && hollow == 0.f )                       // trivially convex +                          || ( profile_length <= min_profile_wedge +                              && same_hole );                       // effectvely convex (even when hollow) + +    if (!convex_profile) +    { +        // profile is concave +        return FALSE; +    } + +    if ( LL_PCODE_PATH_LINE == path_type ) +    { +        // straight paths with convex profile +        return TRUE; +    } + +    BOOL concave_path = (path_length < 1.0f) && (path_length > 0.5f); +    if (concave_path) +    { +        return FALSE; +    } + +    // we're left with spheres, toroids and tubes +    if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ) +    { +        // at this stage all spheres must be convex +        return TRUE; +    } + +    // it's a toroid or tube +    if ( path_length <= MIN_CONCAVE_PATH_WEDGE ) +    { +        // effectively convex +        return TRUE; +    } + +    return FALSE;  }  // debug  void LLVolumeParams::setCube()  { -	mProfileParams.setCurveType(LL_PCODE_PROFILE_SQUARE); -	mProfileParams.setBegin(0.f); -	mProfileParams.setEnd(1.f); -	mProfileParams.setHollow(0.f); +    mProfileParams.setCurveType(LL_PCODE_PROFILE_SQUARE); +    mProfileParams.setBegin(0.f); +    mProfileParams.setEnd(1.f); +    mProfileParams.setHollow(0.f); -	mPathParams.setBegin(0.f); -	mPathParams.setEnd(1.f); -	mPathParams.setScale(1.f, 1.f); -	mPathParams.setShear(0.f, 0.f); -	mPathParams.setCurveType(LL_PCODE_PATH_LINE); -	mPathParams.setTwistBegin(0.f); -	mPathParams.setTwistEnd(0.f); -	mPathParams.setRadiusOffset(0.f); -	mPathParams.setTaper(0.f, 0.f); -	mPathParams.setRevolutions(0.f); -	mPathParams.setSkew(0.f); +    mPathParams.setBegin(0.f); +    mPathParams.setEnd(1.f); +    mPathParams.setScale(1.f, 1.f); +    mPathParams.setShear(0.f, 0.f); +    mPathParams.setCurveType(LL_PCODE_PATH_LINE); +    mPathParams.setTwistBegin(0.f); +    mPathParams.setTwistEnd(0.f); +    mPathParams.setRadiusOffset(0.f); +    mPathParams.setTaper(0.f, 0.f); +    mPathParams.setRevolutions(0.f); +    mPathParams.setSkew(0.f);  }  LLFaceID LLVolume::generateFaceMask()  { -	LLFaceID new_mask = 0x0000; - -	switch(mParams.getProfileParams().getCurveType() & LL_PCODE_PROFILE_MASK) -	{ -	case LL_PCODE_PROFILE_CIRCLE: -	case LL_PCODE_PROFILE_CIRCLE_HALF: -		new_mask |= LL_FACE_OUTER_SIDE_0; -		break; -	case LL_PCODE_PROFILE_SQUARE: -		{ -			for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 4.f); side < llceil(mParams.getProfileParams().getEnd() * 4.f); side++) -			{ -				new_mask |= LL_FACE_OUTER_SIDE_0 << side; -			} -		} -		break; -	case LL_PCODE_PROFILE_ISOTRI: -	case LL_PCODE_PROFILE_EQUALTRI: -	case LL_PCODE_PROFILE_RIGHTTRI: -		{ -			for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 3.f); side < llceil(mParams.getProfileParams().getEnd() * 3.f); side++) -			{ -				new_mask |= LL_FACE_OUTER_SIDE_0 << side; -			} -		} -		break; -	default: -		LL_ERRS() << "Unknown profile!" << LL_ENDL; -		break; -	} - -	// handle hollow objects -	if (mParams.getProfileParams().getHollow() > 0) -	{ -		new_mask |= LL_FACE_INNER_SIDE; -	} - -	// handle open profile curves -	if (mProfilep->isOpen()) -	{ -		new_mask |= LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END; -	} - -	// handle open path curves -	if (mPathp->isOpen()) -	{ -		new_mask |= LL_FACE_PATH_BEGIN | LL_FACE_PATH_END; -	} - -	return new_mask; +    LLFaceID new_mask = 0x0000; + +    switch(mParams.getProfileParams().getCurveType() & LL_PCODE_PROFILE_MASK) +    { +    case LL_PCODE_PROFILE_CIRCLE: +    case LL_PCODE_PROFILE_CIRCLE_HALF: +        new_mask |= LL_FACE_OUTER_SIDE_0; +        break; +    case LL_PCODE_PROFILE_SQUARE: +        { +            for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 4.f); side < llceil(mParams.getProfileParams().getEnd() * 4.f); side++) +            { +                new_mask |= LL_FACE_OUTER_SIDE_0 << side; +            } +        } +        break; +    case LL_PCODE_PROFILE_ISOTRI: +    case LL_PCODE_PROFILE_EQUALTRI: +    case LL_PCODE_PROFILE_RIGHTTRI: +        { +            for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 3.f); side < llceil(mParams.getProfileParams().getEnd() * 3.f); side++) +            { +                new_mask |= LL_FACE_OUTER_SIDE_0 << side; +            } +        } +        break; +    default: +        LL_ERRS() << "Unknown profile!" << LL_ENDL; +        break; +    } + +    // handle hollow objects +    if (mParams.getProfileParams().getHollow() > 0) +    { +        new_mask |= LL_FACE_INNER_SIDE; +    } + +    // handle open profile curves +    if (mProfilep->isOpen()) +    { +        new_mask |= LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END; +    } + +    // handle open path curves +    if (mPathp->isOpen()) +    { +        new_mask |= LL_FACE_PATH_BEGIN | LL_FACE_PATH_END; +    } + +    return new_mask;  }  BOOL LLVolume::isFaceMaskValid(LLFaceID face_mask)  { -	LLFaceID test_mask = 0; -	for(S32 i = 0; i < getNumFaces(); i++) -	{ -		test_mask |= mProfilep->mFaces[i].mFaceID; -	} +    LLFaceID test_mask = 0; +    for(S32 i = 0; i < getNumFaces(); i++) +    { +        test_mask |= mProfilep->mFaces[i].mFaceID; +    } -	return test_mask == face_mask; +    return test_mask == face_mask;  }  BOOL LLVolume::isConvex() const  { -	// mParams.isConvex() may return FALSE even though the final -	// geometry is actually convex due to LOD approximations. -	// TODO -- provide LLPath and LLProfile with isConvex() methods -	// that correctly determine convexity. -- Leviathan -	return mParams.isConvex(); +    // mParams.isConvex() may return FALSE even though the final +    // geometry is actually convex due to LOD approximations. +    // TODO -- provide LLPath and LLProfile with isConvex() methods +    // that correctly determine convexity. -- Leviathan +    return mParams.isConvex();  }  std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params)  { -	s << "{type=" << (U32) profile_params.mCurveType; -	s << ", begin=" << profile_params.mBegin; -	s << ", end=" << profile_params.mEnd; -	s << ", hollow=" << profile_params.mHollow; -	s << "}"; -	return s; +    s << "{type=" << (U32) profile_params.mCurveType; +    s << ", begin=" << profile_params.mBegin; +    s << ", end=" << profile_params.mEnd; +    s << ", hollow=" << profile_params.mHollow; +    s << "}"; +    return s;  }  std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params)  { -	s << "{type=" << (U32) path_params.mCurveType; -	s << ", begin=" << path_params.mBegin; -	s << ", end=" << path_params.mEnd; -	s << ", twist=" << path_params.mTwistEnd; -	s << ", scale=" << path_params.mScale; -	s << ", shear=" << path_params.mShear; -	s << ", twist_begin=" << path_params.mTwistBegin; -	s << ", radius_offset=" << path_params.mRadiusOffset; -	s << ", taper=" << path_params.mTaper; -	s << ", revolutions=" << path_params.mRevolutions; -	s << ", skew=" << path_params.mSkew; -	s << "}"; -	return s; +    s << "{type=" << (U32) path_params.mCurveType; +    s << ", begin=" << path_params.mBegin; +    s << ", end=" << path_params.mEnd; +    s << ", twist=" << path_params.mTwistEnd; +    s << ", scale=" << path_params.mScale; +    s << ", shear=" << path_params.mShear; +    s << ", twist_begin=" << path_params.mTwistBegin; +    s << ", radius_offset=" << path_params.mRadiusOffset; +    s << ", taper=" << path_params.mTaper; +    s << ", revolutions=" << path_params.mRevolutions; +    s << ", skew=" << path_params.mSkew; +    s << "}"; +    return s;  }  std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params)  { -	s << "{profileparams = " << volume_params.mProfileParams; -	s << ", pathparams = " << volume_params.mPathParams; -	s << "}"; -	return s; +    s << "{profileparams = " << volume_params.mProfileParams; +    s << ", pathparams = " << volume_params.mPathParams; +    s << "}"; +    return s;  }  std::ostream& operator<<(std::ostream &s, const LLProfile &profile)  { -	s << " {open=" << (U32) profile.mOpen; -	s << ", dirty=" << profile.mDirty; -	s << ", totalout=" << profile.mTotalOut; -	s << ", total=" << profile.mTotal; -	s << "}"; -	return s; +    s << " {open=" << (U32) profile.mOpen; +    s << ", dirty=" << profile.mDirty; +    s << ", totalout=" << profile.mTotalOut; +    s << ", total=" << profile.mTotal; +    s << "}"; +    return s;  }  std::ostream& operator<<(std::ostream &s, const LLPath &path)  { -	s << "{open=" << (U32) path.mOpen; -	s << ", dirty=" << path.mDirty; -	s << ", step=" << path.mStep; -	s << ", total=" << path.mTotal; -	s << "}"; -	return s; +    s << "{open=" << (U32) path.mOpen; +    s << ", dirty=" << path.mDirty; +    s << ", step=" << path.mStep; +    s << ", total=" << path.mTotal; +    s << "}"; +    return s;  }  std::ostream& operator<<(std::ostream &s, const LLVolume &volume)  { -	s << "{params = " << volume.getParams(); -	s << ", path = " << *volume.mPathp; -	s << ", profile = " << *volume.mProfilep; -	s << "}"; -	return s; +    s << "{params = " << volume.getParams(); +    s << ", path = " << *volume.mPathp; +    s << ", profile = " << *volume.mProfilep; +    s << "}"; +    return s;  }  std::ostream& operator<<(std::ostream &s, const LLVolume *volumep)  { -	s << "{params = " << volumep->getParams(); -	s << ", path = " << *(volumep->mPathp); -	s << ", profile = " << *(volumep->mProfilep); -	s << "}"; -	return s; -} - -LLVolumeFace::LLVolumeFace() :  -	mID(0), -	mTypeMask(0), -	mBeginS(0), -	mBeginT(0), -	mNumS(0), -	mNumT(0), -	mNumVertices(0), -	mNumAllocatedVertices(0), -	mNumIndices(0), -	mPositions(NULL), -	mNormals(NULL), -	mTangents(NULL), -	mTexCoords(NULL), -	mIndices(NULL), -	mWeights(NULL), +    s << "{params = " << volumep->getParams(); +    s << ", path = " << *(volumep->mPathp); +    s << ", profile = " << *(volumep->mProfilep); +    s << "}"; +    return s; +} + +LLVolumeFace::LLVolumeFace() : +    mID(0), +    mTypeMask(0), +    mBeginS(0), +    mBeginT(0), +    mNumS(0), +    mNumT(0), +    mNumVertices(0), +    mNumAllocatedVertices(0), +    mNumIndices(0), +    mPositions(NULL), +    mNormals(NULL), +    mTangents(NULL), +    mTexCoords(NULL), +    mIndices(NULL), +    mWeights(NULL),  #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS      mJustWeights(NULL),      mJointIndices(NULL),  #endif      mWeightsScrubbed(FALSE), -	mOctree(NULL), +    mOctree(NULL),      mOctreeTriangles(NULL), -	mOptimized(FALSE) +    mOptimized(FALSE)  { -	mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); -	mExtents[0].splat(-0.5f); -	mExtents[1].splat(0.5f); -	mCenter = mExtents+2; +    mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); +    mExtents[0].splat(-0.5f); +    mExtents[1].splat(0.5f); +    mCenter = mExtents+2;  }  LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) -:	mID(0), -	mTypeMask(0), -	mBeginS(0), -	mBeginT(0), -	mNumS(0), -	mNumT(0), -	mNumVertices(0), -	mNumAllocatedVertices(0), -	mNumIndices(0), -	mPositions(NULL), -	mNormals(NULL), -	mTangents(NULL), -	mTexCoords(NULL), -	mIndices(NULL), -	mWeights(NULL), +:   mID(0), +    mTypeMask(0), +    mBeginS(0), +    mBeginT(0), +    mNumS(0), +    mNumT(0), +    mNumVertices(0), +    mNumAllocatedVertices(0), +    mNumIndices(0), +    mPositions(NULL), +    mNormals(NULL), +    mTangents(NULL), +    mTexCoords(NULL), +    mIndices(NULL), +    mWeights(NULL),  #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS      mJustWeights(NULL),      mJointIndices(NULL), @@ -4824,78 +4824,78 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)      mOctree(NULL),      mOctreeTriangles(NULL)  { -	mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); -	mCenter = mExtents+2; -	*this = src; +    mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); +    mCenter = mExtents+2; +    *this = src;  }  LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  { -	if (&src == this) -	{ //self assignment, do nothing -		return *this; -	} - -	mID = src.mID; -	mTypeMask = src.mTypeMask; -	mBeginS = src.mBeginS; -	mBeginT = src.mBeginT; -	mNumS = src.mNumS; -	mNumT = src.mNumT; - -	mExtents[0] = src.mExtents[0]; -	mExtents[1] = src.mExtents[1]; -	*mCenter = *src.mCenter; - -	mNumVertices = 0; -	mNumIndices = 0; - -	freeData(); -	 -	resizeVertices(src.mNumVertices); -	resizeIndices(src.mNumIndices); - -	if (mNumVertices) -	{ -		S32 vert_size = mNumVertices*sizeof(LLVector4a); -		S32 tc_size = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF; -			 -		LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); - -		if (src.mNormals) -		{ -		LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); -		} - -		if(src.mTexCoords) -		{ -			LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); -		} - -		if (src.mTangents) -		{ -			allocateTangents(src.mNumVertices); -			LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size); -		} -		else -		{ -			ll_aligned_free_16(mTangents); -			mTangents = NULL; -		} - -		if (src.mWeights) -		{ +    if (&src == this) +    { //self assignment, do nothing +        return *this; +    } + +    mID = src.mID; +    mTypeMask = src.mTypeMask; +    mBeginS = src.mBeginS; +    mBeginT = src.mBeginT; +    mNumS = src.mNumS; +    mNumT = src.mNumT; + +    mExtents[0] = src.mExtents[0]; +    mExtents[1] = src.mExtents[1]; +    *mCenter = *src.mCenter; + +    mNumVertices = 0; +    mNumIndices = 0; + +    freeData(); + +    resizeVertices(src.mNumVertices); +    resizeIndices(src.mNumIndices); + +    if (mNumVertices) +    { +        S32 vert_size = mNumVertices*sizeof(LLVector4a); +        S32 tc_size = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF; + +        LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); + +        if (src.mNormals) +        { +        LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); +        } + +        if(src.mTexCoords) +        { +            LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); +        } + +        if (src.mTangents) +        { +            allocateTangents(src.mNumVertices); +            LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size); +        } +        else +        { +            ll_aligned_free_16(mTangents); +            mTangents = NULL; +        } + +        if (src.mWeights) +        {              llassert(!mWeights); // don't orphan an old alloc here accidentally -			allocateWeights(src.mNumVertices); -			LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size);             +            allocateWeights(src.mNumVertices); +            LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size);              mWeightsScrubbed = src.mWeightsScrubbed; -		} -		else -		{ -			ll_aligned_free_16(mWeights);             -			mWeights = NULL;             +        } +        else +        { +            ll_aligned_free_16(mWeights); +            mWeights = NULL;              mWeightsScrubbed = FALSE; -		}    +        }      #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS          if (src.mJointIndices) @@ -4908,60 +4908,60 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)          {              ll_aligned_free_16(mJointIndices);              mJointIndices = NULL; -        }      +        }      #endif -	} -     -	if (mNumIndices) -	{ -		S32 idx_size = (mNumIndices*sizeof(U16)+0xF) & ~0xF; -		 -		LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size); -	} -	else +    } + +    if (mNumIndices) +    { +        S32 idx_size = (mNumIndices*sizeof(U16)+0xF) & ~0xF; + +        LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size); +    } +    else      {          ll_aligned_free_16(mIndices);          mIndices = NULL;      } -	mOptimized = src.mOptimized; +    mOptimized = src.mOptimized;      mNormalizedScale = src.mNormalizedScale; -	//delete  -	return *this; +    //delete +    return *this;  }  LLVolumeFace::~LLVolumeFace()  { -	ll_aligned_free_16(mExtents); -	mExtents = NULL; -	mCenter = NULL; +    ll_aligned_free_16(mExtents); +    mExtents = NULL; +    mCenter = NULL; -	freeData(); +    freeData();  }  void LLVolumeFace::freeData()  { -	ll_aligned_free<64>(mPositions); -	mPositions = NULL; +    ll_aligned_free<64>(mPositions); +    mPositions = NULL; -	//normals and texture coordinates are part of the same buffer as mPositions, do not free them separately -	mNormals = NULL; -	mTexCoords = NULL; +    //normals and texture coordinates are part of the same buffer as mPositions, do not free them separately +    mNormals = NULL; +    mTexCoords = NULL; -	ll_aligned_free_16(mIndices); -	mIndices = NULL; -	ll_aligned_free_16(mTangents); -	mTangents = NULL; -	ll_aligned_free_16(mWeights); -	mWeights = NULL; +    ll_aligned_free_16(mIndices); +    mIndices = NULL; +    ll_aligned_free_16(mTangents); +    mTangents = NULL; +    ll_aligned_free_16(mWeights); +    mWeights = NULL;  #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS      ll_aligned_free_16(mJointIndices); -	mJointIndices = NULL; +    mJointIndices = NULL;      ll_aligned_free_16(mJustWeights); -	mJustWeights = NULL; +    mJustWeights = NULL;  #endif      destroyOctree(); @@ -4969,73 +4969,73 @@ void LLVolumeFace::freeData()  BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)  { -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME -	//tree for this face is no longer valid +    //tree for this face is no longer valid      destroyOctree(); -	LL_CHECK_MEMORY -	BOOL ret = FALSE ; -	if (mTypeMask & CAP_MASK) -	{ -		ret = createCap(volume, partial_build); -		LL_CHECK_MEMORY -	} -	else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK)) -	{ -		ret = createSide(volume, partial_build); -		LL_CHECK_MEMORY -	} -	else -	{ -		LL_ERRS() << "Unknown/uninitialized face type!" << LL_ENDL; -	} - -	return ret ; +    LL_CHECK_MEMORY +    BOOL ret = FALSE ; +    if (mTypeMask & CAP_MASK) +    { +        ret = createCap(volume, partial_build); +        LL_CHECK_MEMORY +    } +    else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK)) +    { +        ret = createSide(volume, partial_build); +        LL_CHECK_MEMORY +    } +    else +    { +        LL_ERRS() << "Unknown/uninitialized face type!" << LL_ENDL; +    } + +    return ret ;  }  void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv)  { -	cv.setPosition(mPositions[index]); -	if (mNormals) -	{ -		cv.setNormal(mNormals[index]); -	} -	else -	{ -		cv.getNormal().clear(); -	} - -	if (mTexCoords) -	{ -		cv.mTexCoord = mTexCoords[index]; -	} -	else -	{ -		cv.mTexCoord.clear(); -	} +    cv.setPosition(mPositions[index]); +    if (mNormals) +    { +        cv.setNormal(mNormals[index]); +    } +    else +    { +        cv.getNormal().clear(); +    } + +    if (mTexCoords) +    { +        cv.mTexCoord = mTexCoords[index]; +    } +    else +    { +        cv.mTexCoord.clear(); +    }  }  bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const  { -	return getPosition().equals3(rhs.getPosition()) && -		mTexCoord == rhs.mTexCoord && -		getNormal().equals3(rhs.getNormal()); +    return getPosition().equals3(rhs.getPosition()) && +        mTexCoord == rhs.mTexCoord && +        getNormal().equals3(rhs.getNormal());  }  bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a, const LLVector3& b) const  { -	if (a.mV[0] != b.mV[0]) -	{ -		return a.mV[0] < b.mV[0]; -	} -	 -	if (a.mV[1] != b.mV[1]) -	{ -		return a.mV[1] < b.mV[1]; -	} -	 -	return a.mV[2] < b.mV[2]; +    if (a.mV[0] != b.mV[0]) +    { +        return a.mV[0] < b.mV[0]; +    } + +    if (a.mV[1] != b.mV[1]) +    { +        return a.mV[1] < b.mV[1]; +    } + +    return a.mV[2] < b.mV[2];  }  void LLVolumeFace::remap() @@ -5084,18 +5084,18 @@ void LLVolumeFace::remap()  void LLVolumeFace::optimize(F32 angle_cutoff)  { -	LLVolumeFace new_face; +    LLVolumeFace new_face; -	//map of points to vector of vertices at that point -	std::map<U64, std::vector<VertexMapData> > point_map; +    //map of points to vector of vertices at that point +    std::map<U64, std::vector<VertexMapData> > point_map; -	LLVector4a range; -	range.setSub(mExtents[1],mExtents[0]); +    LLVector4a range; +    range.setSub(mExtents[1],mExtents[0]); -	//remove redundant vertices -	for (U32 i = 0; i < mNumIndices; ++i) -	{ -		U16 index = mIndices[i]; +    //remove redundant vertices +    for (U32 i = 0; i < mNumIndices; ++i) +    { +        U16 index = mIndices[i];          if (index >= mNumVertices)          { @@ -5108,81 +5108,81 @@ void LLVolumeFace::optimize(F32 angle_cutoff)              LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL;          } -		LLVolumeFace::VertexData cv; -		getVertexData(index, cv); -		 -		BOOL found = FALSE; - -		LLVector4a pos; -		pos.setSub(mPositions[index], mExtents[0]); -		pos.div(range); - -		U64 pos64 = 0; - -		pos64 = (U16) (pos[0]*65535); -		pos64 = pos64 | (((U64) (pos[1]*65535)) << 16); -		pos64 = pos64 | (((U64) (pos[2]*65535)) << 32); - -		std::map<U64, std::vector<VertexMapData> >::iterator point_iter = point_map.find(pos64); -		 -		if (point_iter != point_map.end()) -		{ //duplicate point might exist -			for (U32 j = 0; j < point_iter->second.size(); ++j) -			{ -				LLVolumeFace::VertexData& tv = (point_iter->second)[j]; -				if (tv.compareNormal(cv, angle_cutoff)) -				{ -					found = TRUE; -					new_face.pushIndex((point_iter->second)[j].mIndex); -					break; -				} -			} -		} - -		if (!found) -		{ -			new_face.pushVertex(cv); -			U16 index = (U16) new_face.mNumVertices-1; -			new_face.pushIndex(index); - -			VertexMapData d; -			d.setPosition(cv.getPosition()); -			d.mTexCoord = cv.mTexCoord; -			d.setNormal(cv.getNormal()); -			d.mIndex = index; -			if (point_iter != point_map.end()) -			{ -				point_iter->second.push_back(d); -			} -			else -			{ -				point_map[pos64].push_back(d); -			} -		} -	} - - -	if (angle_cutoff > 1.f && !mNormals) -	{ -		// Now alloc'd with positions -		//ll_aligned_free_16(new_face.mNormals); -		new_face.mNormals = NULL; -	} - -	if (!mTexCoords) -	{ -		// Now alloc'd with positions -		//ll_aligned_free_16(new_face.mTexCoords); -		new_face.mTexCoords = NULL; -	} - -	// Only swap data if we've actually optimized the mesh -	// -	if (new_face.mNumVertices <= mNumVertices) -	{ +        LLVolumeFace::VertexData cv; +        getVertexData(index, cv); + +        BOOL found = FALSE; + +        LLVector4a pos; +        pos.setSub(mPositions[index], mExtents[0]); +        pos.div(range); + +        U64 pos64 = 0; + +        pos64 = (U16) (pos[0]*65535); +        pos64 = pos64 | (((U64) (pos[1]*65535)) << 16); +        pos64 = pos64 | (((U64) (pos[2]*65535)) << 32); + +        std::map<U64, std::vector<VertexMapData> >::iterator point_iter = point_map.find(pos64); + +        if (point_iter != point_map.end()) +        { //duplicate point might exist +            for (U32 j = 0; j < point_iter->second.size(); ++j) +            { +                LLVolumeFace::VertexData& tv = (point_iter->second)[j]; +                if (tv.compareNormal(cv, angle_cutoff)) +                { +                    found = TRUE; +                    new_face.pushIndex((point_iter->second)[j].mIndex); +                    break; +                } +            } +        } + +        if (!found) +        { +            new_face.pushVertex(cv); +            U16 index = (U16) new_face.mNumVertices-1; +            new_face.pushIndex(index); + +            VertexMapData d; +            d.setPosition(cv.getPosition()); +            d.mTexCoord = cv.mTexCoord; +            d.setNormal(cv.getNormal()); +            d.mIndex = index; +            if (point_iter != point_map.end()) +            { +                point_iter->second.push_back(d); +            } +            else +            { +                point_map[pos64].push_back(d); +            } +        } +    } + + +    if (angle_cutoff > 1.f && !mNormals) +    { +        // Now alloc'd with positions +        //ll_aligned_free_16(new_face.mNormals); +        new_face.mNormals = NULL; +    } + +    if (!mTexCoords) +    { +        // Now alloc'd with positions +        //ll_aligned_free_16(new_face.mTexCoords); +        new_face.mTexCoords = NULL; +    } + +    // Only swap data if we've actually optimized the mesh +    // +    if (new_face.mNumVertices <= mNumVertices) +    {          llassert(new_face.mNumIndices == mNumIndices); -		swapData(new_face); -	} +        swapData(new_face); +    }  } @@ -5191,52 +5191,52 @@ class LLVCacheTriangleData;  class LLVCacheVertexData  {  public: -	S32 mIdx; -	S32 mCacheTag; -	F64 mScore; -	U32 mActiveTriangles; -	std::vector<LLVCacheTriangleData*> mTriangles; - -	LLVCacheVertexData() -	{ -		mCacheTag = -1; -		mScore = 0.0; -		mActiveTriangles = 0; -		mIdx = -1; -	} +    S32 mIdx; +    S32 mCacheTag; +    F64 mScore; +    U32 mActiveTriangles; +    std::vector<LLVCacheTriangleData*> mTriangles; + +    LLVCacheVertexData() +    { +        mCacheTag = -1; +        mScore = 0.0; +        mActiveTriangles = 0; +        mIdx = -1; +    }  };  class LLVCacheTriangleData  {  public: -	bool mActive; -	F64 mScore; -	LLVCacheVertexData* mVertex[3]; - -	LLVCacheTriangleData() -	{ -		mActive = true; -		mScore = 0.0; -		mVertex[0] = mVertex[1] = mVertex[2] = NULL; -	} - -	void complete() -	{ -		mActive = false; -		for (S32 i = 0; i < 3; ++i) -		{ -			if (mVertex[i]) -			{ -				llassert(mVertex[i]->mActiveTriangles > 0); -				mVertex[i]->mActiveTriangles--; -			} -		} -	} - -	bool operator<(const LLVCacheTriangleData& rhs) const -	{ //highest score first -		return rhs.mScore < mScore; -	} +    bool mActive; +    F64 mScore; +    LLVCacheVertexData* mVertex[3]; + +    LLVCacheTriangleData() +    { +        mActive = true; +        mScore = 0.0; +        mVertex[0] = mVertex[1] = mVertex[2] = NULL; +    } + +    void complete() +    { +        mActive = false; +        for (S32 i = 0; i < 3; ++i) +        { +            if (mVertex[i]) +            { +                llassert(mVertex[i]->mActiveTriangles > 0); +                mVertex[i]->mActiveTriangles--; +            } +        } +    } + +    bool operator<(const LLVCacheTriangleData& rhs) const +    { //highest score first +        return rhs.mScore < mScore; +    }  };  const F64 FindVertexScore_CacheDecayPower = 1.5; @@ -5248,205 +5248,205 @@ const F64 FindVertexScore_Scaler = 1.0/(MaxSizeVertexCache-3);  F64 find_vertex_score(LLVCacheVertexData& data)  { -	F64 score = -1.0; +    F64 score = -1.0; -	score = 0.0; +    score = 0.0; -	S32 cache_idx = data.mCacheTag; +    S32 cache_idx = data.mCacheTag; -	if (cache_idx < 0) -	{ -		//not in cache -	} -	else -	{ -		if (cache_idx < 3) -		{ //vertex was in the last triangle -			score = FindVertexScore_LastTriScore; -		} -		else -		{ //more points for being higher in the cache -				score = 1.0-((cache_idx-3)*FindVertexScore_Scaler); -				score = pow(score, FindVertexScore_CacheDecayPower); -		} -	} +    if (cache_idx < 0) +    { +        //not in cache +    } +    else +    { +        if (cache_idx < 3) +        { //vertex was in the last triangle +            score = FindVertexScore_LastTriScore; +        } +        else +        { //more points for being higher in the cache +                score = 1.0-((cache_idx-3)*FindVertexScore_Scaler); +                score = pow(score, FindVertexScore_CacheDecayPower); +        } +    } -	//bonus points for having low valence -	F64 valence_boost = pow((F64)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower); -	score += FindVertexScore_ValenceBoostScale * valence_boost; +    //bonus points for having low valence +    F64 valence_boost = pow((F64)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower); +    score += FindVertexScore_ValenceBoostScale * valence_boost; -	return score; +    return score;  }  class LLVCacheFIFO  {  public: -	LLVCacheVertexData* mCache[MaxSizeVertexCache]; -	U32 mMisses; - -	LLVCacheFIFO() -	{ -		mMisses = 0; -		for (U32 i = 0; i < MaxSizeVertexCache; ++i) -		{ -			mCache[i] = NULL; -		} -	} - -	void addVertex(LLVCacheVertexData* data) -	{ -		if (data->mCacheTag == -1) -		{ -			mMisses++; - -			S32 end = MaxSizeVertexCache-1; - -			if (mCache[end]) -			{ -				mCache[end]->mCacheTag = -1; -			} - -			for (S32 i = end; i > 0; --i) -			{ -				mCache[i] = mCache[i-1]; -				if (mCache[i]) -				{ -					mCache[i]->mCacheTag = i; -				} -			} - -			mCache[0] = data; -			data->mCacheTag = 0; -		} -	} +    LLVCacheVertexData* mCache[MaxSizeVertexCache]; +    U32 mMisses; + +    LLVCacheFIFO() +    { +        mMisses = 0; +        for (U32 i = 0; i < MaxSizeVertexCache; ++i) +        { +            mCache[i] = NULL; +        } +    } + +    void addVertex(LLVCacheVertexData* data) +    { +        if (data->mCacheTag == -1) +        { +            mMisses++; + +            S32 end = MaxSizeVertexCache-1; + +            if (mCache[end]) +            { +                mCache[end]->mCacheTag = -1; +            } + +            for (S32 i = end; i > 0; --i) +            { +                mCache[i] = mCache[i-1]; +                if (mCache[i]) +                { +                    mCache[i]->mCacheTag = i; +                } +            } + +            mCache[0] = data; +            data->mCacheTag = 0; +        } +    }  };  class LLVCacheLRU  {  public: -	LLVCacheVertexData* mCache[MaxSizeVertexCache+3]; - -	LLVCacheTriangleData* mBestTriangle; -	 -	U32 mMisses; - -	LLVCacheLRU() -	{ -		for (U32 i = 0; i < MaxSizeVertexCache+3; ++i) -		{ -			mCache[i] = NULL; -		} - -		mBestTriangle = NULL; -		mMisses = 0; -	} - -	void addVertex(LLVCacheVertexData* data) -	{ -		S32 end = MaxSizeVertexCache+2; -		if (data->mCacheTag != -1) -		{ //just moving a vertex to the front of the cache -			end = data->mCacheTag; -		} -		else -		{ -			mMisses++; -			if (mCache[end]) -			{ //adding a new vertex, vertex at end of cache falls off -				mCache[end]->mCacheTag = -1; -			} -		} - -		for (S32 i = end; i > 0; --i) -		{ //adjust cache pointers and tags -			mCache[i] = mCache[i-1]; - -			if (mCache[i]) -			{ -				mCache[i]->mCacheTag = i;			 -			} -		} - -		mCache[0] = data; -		mCache[0]->mCacheTag = 0; -	} - -	void addTriangle(LLVCacheTriangleData* data) -	{ -		addVertex(data->mVertex[0]); -		addVertex(data->mVertex[1]); -		addVertex(data->mVertex[2]); -	} - -	void updateScores() -	{ -		LLVCacheVertexData** data_iter = mCache+MaxSizeVertexCache; -		LLVCacheVertexData** end_data = mCache+MaxSizeVertexCache+3; - -		while(data_iter != end_data) -		{ -			LLVCacheVertexData* data = *data_iter++; -			//trailing 3 vertices aren't actually in the cache for scoring purposes -			if (data) -			{ -				data->mCacheTag = -1; -			} -		} - -		data_iter = mCache; -		end_data = mCache+MaxSizeVertexCache; - -		while (data_iter != end_data) -		{ //update scores of vertices in cache -			LLVCacheVertexData* data = *data_iter++; -			if (data) -			{ -				data->mScore = find_vertex_score(*data); -			} -		} - -		mBestTriangle = NULL; -		//update triangle scores -		data_iter = mCache; -		end_data = mCache+MaxSizeVertexCache+3; - -		while (data_iter != end_data) -		{ -			LLVCacheVertexData* data = *data_iter++; -			if (data) -			{ -				for (std::vector<LLVCacheTriangleData*>::iterator iter = data->mTriangles.begin(), end_iter = data->mTriangles.end(); iter != end_iter; ++iter) -				{ -					LLVCacheTriangleData* tri = *iter; -					if (tri->mActive) -					{ -						tri->mScore = tri->mVertex[0] ? tri->mVertex[0]->mScore : 0; -						tri->mScore += tri->mVertex[1] ? tri->mVertex[1]->mScore : 0; -						tri->mScore += tri->mVertex[2] ? tri->mVertex[2]->mScore : 0; - -						if (!mBestTriangle || mBestTriangle->mScore < tri->mScore) -						{ -							mBestTriangle = tri; -						} -					} -				} -			} -		} - -		//knock trailing 3 vertices off the cache -		data_iter = mCache+MaxSizeVertexCache; -		end_data = mCache+MaxSizeVertexCache+3; -		while (data_iter != end_data) -		{ -			LLVCacheVertexData* data = *data_iter; -			if (data) -			{ -				llassert(data->mCacheTag == -1); -				*data_iter = NULL; -			} -			++data_iter; -		} -	} +    LLVCacheVertexData* mCache[MaxSizeVertexCache+3]; + +    LLVCacheTriangleData* mBestTriangle; + +    U32 mMisses; + +    LLVCacheLRU() +    { +        for (U32 i = 0; i < MaxSizeVertexCache+3; ++i) +        { +            mCache[i] = NULL; +        } + +        mBestTriangle = NULL; +        mMisses = 0; +    } + +    void addVertex(LLVCacheVertexData* data) +    { +        S32 end = MaxSizeVertexCache+2; +        if (data->mCacheTag != -1) +        { //just moving a vertex to the front of the cache +            end = data->mCacheTag; +        } +        else +        { +            mMisses++; +            if (mCache[end]) +            { //adding a new vertex, vertex at end of cache falls off +                mCache[end]->mCacheTag = -1; +            } +        } + +        for (S32 i = end; i > 0; --i) +        { //adjust cache pointers and tags +            mCache[i] = mCache[i-1]; + +            if (mCache[i]) +            { +                mCache[i]->mCacheTag = i; +            } +        } + +        mCache[0] = data; +        mCache[0]->mCacheTag = 0; +    } + +    void addTriangle(LLVCacheTriangleData* data) +    { +        addVertex(data->mVertex[0]); +        addVertex(data->mVertex[1]); +        addVertex(data->mVertex[2]); +    } + +    void updateScores() +    { +        LLVCacheVertexData** data_iter = mCache+MaxSizeVertexCache; +        LLVCacheVertexData** end_data = mCache+MaxSizeVertexCache+3; + +        while(data_iter != end_data) +        { +            LLVCacheVertexData* data = *data_iter++; +            //trailing 3 vertices aren't actually in the cache for scoring purposes +            if (data) +            { +                data->mCacheTag = -1; +            } +        } + +        data_iter = mCache; +        end_data = mCache+MaxSizeVertexCache; + +        while (data_iter != end_data) +        { //update scores of vertices in cache +            LLVCacheVertexData* data = *data_iter++; +            if (data) +            { +                data->mScore = find_vertex_score(*data); +            } +        } + +        mBestTriangle = NULL; +        //update triangle scores +        data_iter = mCache; +        end_data = mCache+MaxSizeVertexCache+3; + +        while (data_iter != end_data) +        { +            LLVCacheVertexData* data = *data_iter++; +            if (data) +            { +                for (std::vector<LLVCacheTriangleData*>::iterator iter = data->mTriangles.begin(), end_iter = data->mTriangles.end(); iter != end_iter; ++iter) +                { +                    LLVCacheTriangleData* tri = *iter; +                    if (tri->mActive) +                    { +                        tri->mScore = tri->mVertex[0] ? tri->mVertex[0]->mScore : 0; +                        tri->mScore += tri->mVertex[1] ? tri->mVertex[1]->mScore : 0; +                        tri->mScore += tri->mVertex[2] ? tri->mVertex[2]->mScore : 0; + +                        if (!mBestTriangle || mBestTriangle->mScore < tri->mScore) +                        { +                            mBestTriangle = tri; +                        } +                    } +                } +            } +        } + +        //knock trailing 3 vertices off the cache +        data_iter = mCache+MaxSizeVertexCache; +        end_data = mCache+MaxSizeVertexCache+3; +        while (data_iter != end_data) +        { +            LLVCacheVertexData* data = *data_iter; +            if (data) +            { +                llassert(data->mCacheTag == -1); +                *data_iter = NULL; +            } +            ++data_iter; +        } +    }  };  // data structures for tangent generation @@ -5477,7 +5477,7 @@ struct MikktData          LLVector3 inv_scale(1.f / face->mNormalizedScale.mV[0], 1.f / face->mNormalizedScale.mV[1], 1.f / face->mNormalizedScale.mV[2]); -         +          for (int i = 0; i < face->mNumIndices; ++i)          { @@ -5511,10 +5511,10 @@ struct MikktData  bool LLVolumeFace::cacheOptimize(bool gen_tangents) -{ //optimize for vertex cache according to Forsyth method:  +{ //optimize for vertex cache according to Forsyth method:      LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; -	llassert(!mOptimized); -	mOptimized = TRUE; +    llassert(!mOptimized); +    mOptimized = TRUE;      if (gen_tangents && mNormals && mTexCoords)      { // generate mikkt space tangents before cache optimizing since the index buffer may change @@ -5564,7 +5564,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)          {              MikktData* data = (MikktData*)pContext->m_pUserData;              S32 i = iFace * 3 + iVert; -             +              data->t[i].set(fvTangent);              data->t[i].mV[3] = fSign;          }; @@ -5670,87 +5670,87 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)      resizeIndices(mNumIndices);      meshopt_optimizeVertexCache<U16>(mIndices, src_indices, mNumIndices, mNumVertices); -     +      ll_aligned_free_16(src_indices); -	return true; +    return true;  }  void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size)  { -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME      if (getOctree()) -	{ -		return; -	} +    { +        return; +    }      llassert(mNumIndices % 3 == 0);      mOctree = new LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(center, size, NULL); -	new LLVolumeOctreeListener(mOctree); +    new LLVolumeOctreeListener(mOctree);      const U32 num_triangles = mNumIndices / 3;      // Initialize all the triangles we need      mOctreeTriangles = new LLVolumeTriangle[num_triangles];      for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index) -	{ //for each triangle +    { //for each triangle          const U32 index = triangle_index * 3;          LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index]; -				 -		const LLVector4a& v0 = mPositions[mIndices[index]]; -		const LLVector4a& v1 = mPositions[mIndices[index + 1]]; -		const LLVector4a& v2 = mPositions[mIndices[index + 2]]; - -		//store pointers to vertex data -		tri->mV[0] = &v0; -		tri->mV[1] = &v1; -		tri->mV[2] = &v2; - -		//store indices -		tri->mIndex[0] = mIndices[index]; -		tri->mIndex[1] = mIndices[index + 1]; -		tri->mIndex[2] = mIndices[index + 2]; - -		//get minimum point -		LLVector4a min = v0; -		min.setMin(min, v1); -		min.setMin(min, v2); - -		//get maximum point -		LLVector4a max = v0; -		max.setMax(max, v1); -		max.setMax(max, v2); - -		//compute center -		LLVector4a center; -		center.setAdd(min, max); -		center.mul(0.5f); - -		tri->mPositionGroup = center; - -		//compute "radius" -		LLVector4a size; -		size.setSub(max,min); -		 -		tri->mRadius = size.getLength3().getF32() * scaler; -		 -		//insert -		mOctree->insert(tri); -	} - -	//remove unneeded octree layers -	while (!mOctree->balance())	{ } - -	//calculate AABB for each node -	LLVolumeOctreeRebound rebound(this); -	rebound.traverse(mOctree); - -	if (gDebugGL) -	{ -		LLVolumeOctreeValidate validate; -		validate.traverse(mOctree); -	} + +        const LLVector4a& v0 = mPositions[mIndices[index]]; +        const LLVector4a& v1 = mPositions[mIndices[index + 1]]; +        const LLVector4a& v2 = mPositions[mIndices[index + 2]]; + +        //store pointers to vertex data +        tri->mV[0] = &v0; +        tri->mV[1] = &v1; +        tri->mV[2] = &v2; + +        //store indices +        tri->mIndex[0] = mIndices[index]; +        tri->mIndex[1] = mIndices[index + 1]; +        tri->mIndex[2] = mIndices[index + 2]; + +        //get minimum point +        LLVector4a min = v0; +        min.setMin(min, v1); +        min.setMin(min, v2); + +        //get maximum point +        LLVector4a max = v0; +        max.setMax(max, v1); +        max.setMax(max, v2); + +        //compute center +        LLVector4a center; +        center.setAdd(min, max); +        center.mul(0.5f); + +        tri->mPositionGroup = center; + +        //compute "radius" +        LLVector4a size; +        size.setSub(max,min); + +        tri->mRadius = size.getLength3().getF32() * scaler; + +        //insert +        mOctree->insert(tri); +    } + +    //remove unneeded octree layers +    while (!mOctree->balance()) { } + +    //calculate AABB for each node +    LLVolumeOctreeRebound rebound(this); +    rebound.traverse(mOctree); + +    if (gDebugGL) +    { +        LLVolumeOctreeValidate validate; +        validate.traverse(mOctree); +    }  }  void LLVolumeFace::destroyOctree() @@ -5769,145 +5769,145 @@ const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* LLVolumeFace::getOctree  void LLVolumeFace::swapData(LLVolumeFace& rhs)  { -	llswap(rhs.mPositions, mPositions); -	llswap(rhs.mNormals, mNormals); -	llswap(rhs.mTangents, mTangents); -	llswap(rhs.mTexCoords, mTexCoords); -	llswap(rhs.mIndices,mIndices); -	llswap(rhs.mNumVertices, mNumVertices); -	llswap(rhs.mNumIndices, mNumIndices); +    llswap(rhs.mPositions, mPositions); +    llswap(rhs.mNormals, mNormals); +    llswap(rhs.mTangents, mTangents); +    llswap(rhs.mTexCoords, mTexCoords); +    llswap(rhs.mIndices,mIndices); +    llswap(rhs.mNumVertices, mNumVertices); +    llswap(rhs.mNumIndices, mNumIndices);  } -void	LerpPlanarVertex(LLVolumeFace::VertexData& v0, -				   LLVolumeFace::VertexData& v1, -				   LLVolumeFace::VertexData& v2, -				   LLVolumeFace::VertexData& vout, -				   F32	coef01, -				   F32	coef02) +void    LerpPlanarVertex(LLVolumeFace::VertexData& v0, +                   LLVolumeFace::VertexData& v1, +                   LLVolumeFace::VertexData& v2, +                   LLVolumeFace::VertexData& vout, +                   F32  coef01, +                   F32  coef02)  { -	LLVector4a lhs; -	lhs.setSub(v1.getPosition(), v0.getPosition()); -	lhs.mul(coef01); -	LLVector4a rhs; -	rhs.setSub(v2.getPosition(), v0.getPosition()); -	rhs.mul(coef02); +    LLVector4a lhs; +    lhs.setSub(v1.getPosition(), v0.getPosition()); +    lhs.mul(coef01); +    LLVector4a rhs; +    rhs.setSub(v2.getPosition(), v0.getPosition()); +    rhs.mul(coef02); + +    rhs.add(lhs); +    rhs.add(v0.getPosition()); -	rhs.add(lhs); -	rhs.add(v0.getPosition()); +    vout.setPosition(rhs); -	vout.setPosition(rhs); -		 -	vout.mTexCoord = v0.mTexCoord + ((v1.mTexCoord-v0.mTexCoord)*coef01)+((v2.mTexCoord-v0.mTexCoord)*coef02); -	vout.setNormal(v0.getNormal()); +    vout.mTexCoord = v0.mTexCoord + ((v1.mTexCoord-v0.mTexCoord)*coef01)+((v2.mTexCoord-v0.mTexCoord)*coef02); +    vout.setNormal(v0.getNormal());  }  BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  { -	LL_CHECK_MEMORY		 - -	const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh(); -	const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile; -	S32 max_s = volume->getProfile().getTotal(); -	S32 max_t = volume->getPath().mPath.size(); - -	// S32 i; -	S32	grid_size = (profile.size()-1)/4; -	// VFExtents change -	LLVector4a& min = mExtents[0]; -	LLVector4a& max = mExtents[1]; - -	S32 offset = 0; -	if (mTypeMask & TOP_MASK) -	{ -		offset = (max_t-1) * max_s; -	} -	else -	{ -		offset = mBeginS; -	} - -	{ -		VertexData	corners[4]; -		VertexData baseVert; -		for(S32 t = 0; t < 4; t++) -		{ -			corners[t].getPosition().load4a(mesh[offset + (grid_size*t)].getF32ptr()); -			corners[t].mTexCoord.mV[0] = profile[grid_size*t][0]+0.5f; -			corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t][1]; -		} - -		{ -			LLVector4a lhs; -			lhs.setSub(corners[1].getPosition(), corners[0].getPosition()); -			LLVector4a rhs; -			rhs.setSub(corners[2].getPosition(), corners[1].getPosition()); -			baseVert.getNormal().setCross3(lhs, rhs);  -			baseVert.getNormal().normalize3fast(); -		} - -		if(!(mTypeMask & TOP_MASK)) -		{ -			baseVert.getNormal().mul(-1.0f); -		} -		else -		{ -			//Swap the UVs on the U(X) axis for top face -			LLVector2 swap; -			swap = corners[0].mTexCoord; -			corners[0].mTexCoord=corners[3].mTexCoord; -			corners[3].mTexCoord=swap; -			swap = corners[1].mTexCoord; -			corners[1].mTexCoord=corners[2].mTexCoord; -			corners[2].mTexCoord=swap; -		} - -		S32 size = (grid_size+1)*(grid_size+1); -		resizeVertices(size); -		 -		LLVector4a* pos = (LLVector4a*) mPositions; -		LLVector4a* norm = (LLVector4a*) mNormals; -		LLVector2* tc = (LLVector2*) mTexCoords; - -		for(int gx = 0;gx<grid_size+1;gx++) -		{ -			for(int gy = 0;gy<grid_size+1;gy++) -			{ -				VertexData newVert; -				LerpPlanarVertex( -					corners[0], -					corners[1], -					corners[3], -					newVert, -					(F32)gx/(F32)grid_size, -					(F32)gy/(F32)grid_size); - -				*pos++ = newVert.getPosition(); -				*norm++ = baseVert.getNormal(); -				*tc++ = newVert.mTexCoord; -				 -				if (gx == 0 && gy == 0) -				{ -					min = newVert.getPosition(); -					max = min; -				} -				else -				{ -					min.setMin(min, newVert.getPosition()); -					max.setMax(max, newVert.getPosition()); -				} -			} -		} -	 -		mCenter->setAdd(min, max); -		mCenter->mul(0.5f);  -	} - -	if (!partial_build) -	{ -		resizeIndices(grid_size*grid_size*6); -		if (!volume->isMeshAssetLoaded()) -		{ +    LL_CHECK_MEMORY + +    const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh(); +    const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile; +    S32 max_s = volume->getProfile().getTotal(); +    S32 max_t = volume->getPath().mPath.size(); + +    // S32 i; +    S32 grid_size = (profile.size()-1)/4; +    // VFExtents change +    LLVector4a& min = mExtents[0]; +    LLVector4a& max = mExtents[1]; + +    S32 offset = 0; +    if (mTypeMask & TOP_MASK) +    { +        offset = (max_t-1) * max_s; +    } +    else +    { +        offset = mBeginS; +    } + +    { +        VertexData  corners[4]; +        VertexData baseVert; +        for(S32 t = 0; t < 4; t++) +        { +            corners[t].getPosition().load4a(mesh[offset + (grid_size*t)].getF32ptr()); +            corners[t].mTexCoord.mV[0] = profile[grid_size*t][0]+0.5f; +            corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t][1]; +        } + +        { +            LLVector4a lhs; +            lhs.setSub(corners[1].getPosition(), corners[0].getPosition()); +            LLVector4a rhs; +            rhs.setSub(corners[2].getPosition(), corners[1].getPosition()); +            baseVert.getNormal().setCross3(lhs, rhs); +            baseVert.getNormal().normalize3fast(); +        } + +        if(!(mTypeMask & TOP_MASK)) +        { +            baseVert.getNormal().mul(-1.0f); +        } +        else +        { +            //Swap the UVs on the U(X) axis for top face +            LLVector2 swap; +            swap = corners[0].mTexCoord; +            corners[0].mTexCoord=corners[3].mTexCoord; +            corners[3].mTexCoord=swap; +            swap = corners[1].mTexCoord; +            corners[1].mTexCoord=corners[2].mTexCoord; +            corners[2].mTexCoord=swap; +        } + +        S32 size = (grid_size+1)*(grid_size+1); +        resizeVertices(size); + +        LLVector4a* pos = (LLVector4a*) mPositions; +        LLVector4a* norm = (LLVector4a*) mNormals; +        LLVector2* tc = (LLVector2*) mTexCoords; + +        for(int gx = 0;gx<grid_size+1;gx++) +        { +            for(int gy = 0;gy<grid_size+1;gy++) +            { +                VertexData newVert; +                LerpPlanarVertex( +                    corners[0], +                    corners[1], +                    corners[3], +                    newVert, +                    (F32)gx/(F32)grid_size, +                    (F32)gy/(F32)grid_size); + +                *pos++ = newVert.getPosition(); +                *norm++ = baseVert.getNormal(); +                *tc++ = newVert.mTexCoord; + +                if (gx == 0 && gy == 0) +                { +                    min = newVert.getPosition(); +                    max = min; +                } +                else +                { +                    min.setMin(min, newVert.getPosition()); +                    max.setMax(max, newVert.getPosition()); +                } +            } +        } + +        mCenter->setAdd(min, max); +        mCenter->mul(0.5f); +    } + +    if (!partial_build) +    { +        resizeIndices(grid_size*grid_size*6); +        if (!volume->isMeshAssetLoaded()) +        {              S32 size = grid_size * grid_size * 6;              try              { @@ -5918,562 +5918,562 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)                  LL_WARNS("LLVOLUME") << "Resize of mEdge to " << size << " failed" << LL_ENDL;                  return false;              } -		} - -		U16* out = mIndices; - -		S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0}; - -		int cur_edge = 0; - -		for(S32 gx = 0;gx<grid_size;gx++) -		{ -			 -			for(S32 gy = 0;gy<grid_size;gy++) -			{ -				if (mTypeMask & TOP_MASK) -				{ -					for(S32 i=5;i>=0;i--) -					{ -						*out++ = ((gy*(grid_size+1))+gx+idxs[i]); -					} - -					S32 edge_value = grid_size * 2 * gy + gx * 2; - -					if (gx > 0) -					{ -						mEdge[cur_edge++] = edge_value; -					} -					else -					{ -						mEdge[cur_edge++] = -1; // Mark face to higlight it -					} - -					if (gy < grid_size - 1) -					{ -						mEdge[cur_edge++] = edge_value; -					} -					else -					{ -						mEdge[cur_edge++] = -1; -					} - -					mEdge[cur_edge++] = edge_value; - -					if (gx < grid_size - 1) -					{ -						mEdge[cur_edge++] = edge_value; -					} -					else -					{ -						mEdge[cur_edge++] = -1; -					} - -					if (gy > 0) -					{ -						mEdge[cur_edge++] = edge_value; -					} -					else -					{ -						mEdge[cur_edge++] = -1; -					} - -					mEdge[cur_edge++] = edge_value; -				} -				else -				{ -					for(S32 i=0;i<6;i++) -					{ -						*out++ = ((gy*(grid_size+1))+gx+idxs[i]); -					} - -					S32 edge_value = grid_size * 2 * gy + gx * 2; - -					if (gy > 0) -					{ -						mEdge[cur_edge++] = edge_value; -					} -					else -					{ -						mEdge[cur_edge++] = -1; -					} - -					if (gx < grid_size - 1) -					{ -						mEdge[cur_edge++] = edge_value; -					} -					else -					{ -						mEdge[cur_edge++] = -1; -					} - -					mEdge[cur_edge++] = edge_value; - -					if (gy < grid_size - 1) -					{ -						mEdge[cur_edge++] = edge_value; -					} -					else -					{ -						mEdge[cur_edge++] = -1; -					} - -					if (gx > 0) -					{ -						mEdge[cur_edge++] = edge_value; -					} -					else -					{ -						mEdge[cur_edge++] = -1; -					} - -					mEdge[cur_edge++] = edge_value; -				} -			} -		} -	} -		 -	LL_CHECK_MEMORY -	return TRUE; +        } + +        U16* out = mIndices; + +        S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0}; + +        int cur_edge = 0; + +        for(S32 gx = 0;gx<grid_size;gx++) +        { + +            for(S32 gy = 0;gy<grid_size;gy++) +            { +                if (mTypeMask & TOP_MASK) +                { +                    for(S32 i=5;i>=0;i--) +                    { +                        *out++ = ((gy*(grid_size+1))+gx+idxs[i]); +                    } + +                    S32 edge_value = grid_size * 2 * gy + gx * 2; + +                    if (gx > 0) +                    { +                        mEdge[cur_edge++] = edge_value; +                    } +                    else +                    { +                        mEdge[cur_edge++] = -1; // Mark face to higlight it +                    } + +                    if (gy < grid_size - 1) +                    { +                        mEdge[cur_edge++] = edge_value; +                    } +                    else +                    { +                        mEdge[cur_edge++] = -1; +                    } + +                    mEdge[cur_edge++] = edge_value; + +                    if (gx < grid_size - 1) +                    { +                        mEdge[cur_edge++] = edge_value; +                    } +                    else +                    { +                        mEdge[cur_edge++] = -1; +                    } + +                    if (gy > 0) +                    { +                        mEdge[cur_edge++] = edge_value; +                    } +                    else +                    { +                        mEdge[cur_edge++] = -1; +                    } + +                    mEdge[cur_edge++] = edge_value; +                } +                else +                { +                    for(S32 i=0;i<6;i++) +                    { +                        *out++ = ((gy*(grid_size+1))+gx+idxs[i]); +                    } + +                    S32 edge_value = grid_size * 2 * gy + gx * 2; + +                    if (gy > 0) +                    { +                        mEdge[cur_edge++] = edge_value; +                    } +                    else +                    { +                        mEdge[cur_edge++] = -1; +                    } + +                    if (gx < grid_size - 1) +                    { +                        mEdge[cur_edge++] = edge_value; +                    } +                    else +                    { +                        mEdge[cur_edge++] = -1; +                    } + +                    mEdge[cur_edge++] = edge_value; + +                    if (gy < grid_size - 1) +                    { +                        mEdge[cur_edge++] = edge_value; +                    } +                    else +                    { +                        mEdge[cur_edge++] = -1; +                    } + +                    if (gx > 0) +                    { +                        mEdge[cur_edge++] = edge_value; +                    } +                    else +                    { +                        mEdge[cur_edge++] = -1; +                    } + +                    mEdge[cur_edge++] = edge_value; +                } +            } +        } +    } + +    LL_CHECK_MEMORY +    return TRUE;  }  BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  { -	if (!(mTypeMask & HOLLOW_MASK) &&  -		!(mTypeMask & OPEN_MASK) &&  -		((volume->getParams().getPathParams().getBegin()==0.0f)&& -		(volume->getParams().getPathParams().getEnd()==1.0f))&& -		(volume->getParams().getProfileParams().getCurveType()==LL_PCODE_PROFILE_SQUARE && -		 volume->getParams().getPathParams().getCurveType()==LL_PCODE_PATH_LINE)	 -		){ -		return createUnCutCubeCap(volume, partial_build); -	} - -	S32 num_vertices = 0, num_indices = 0; - -	const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh(); -	const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile; - -	// All types of caps have the same number of vertices and indices -	num_vertices = profile.size(); -	num_indices = (profile.size() - 2)*3; - -	if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) -	{ -		resizeVertices(num_vertices+1); -		 -		//if (!partial_build) -		{ -			resizeIndices(num_indices+3); -		} -	} -	else -	{ -		resizeVertices(num_vertices); -		//if (!partial_build) -		{ -			resizeIndices(num_indices); -		} -	} - -	LL_CHECK_MEMORY; - -	S32 max_s = volume->getProfile().getTotal(); -	S32 max_t = volume->getPath().mPath.size(); - -	mCenter->clear(); - -	S32 offset = 0; -	if (mTypeMask & TOP_MASK) -	{ -		offset = (max_t-1) * max_s; -	} -	else -	{ -		offset = mBeginS; -	} - -	// Figure out the normal, assume all caps are flat faces. -	// Cross product to get normals. -	 -	LLVector2 cuv; -	LLVector2 min_uv, max_uv; -	// VFExtents change -	LLVector4a& min = mExtents[0]; -	LLVector4a& max = mExtents[1]; - -	LLVector2* tc = (LLVector2*) mTexCoords; -	LLVector4a* pos = (LLVector4a*) mPositions; -	LLVector4a* norm = (LLVector4a*) mNormals; -	 -	// Copy the vertices into the array - -	const LLVector4a* src = mesh.mArray+offset; -	const LLVector4a* end = src+num_vertices; -	 -	min = *src; -	max = min; -	 -	 -	const LLVector4a* p = profile.mArray; - -	if (mTypeMask & TOP_MASK) -	{ -		min_uv.set((*p)[0]+0.5f, -					(*p)[1]+0.5f); - -		max_uv = min_uv; - -		while(src < end) -		{ -			tc->mV[0] = (*p)[0]+0.5f; -			tc->mV[1] = (*p)[1]+0.5f; - -			llassert(src->isFinite3()); // MAINT-5660; don't know why this happens, does not affect Release builds -			update_min_max(min,max,*src); -			update_min_max(min_uv, max_uv, *tc); -		 -			*pos = *src; -		 -			llassert(pos->isFinite3()); - -			++p; -			++tc; -			++src; -			++pos; -		} -		} -		else -		{ - -		min_uv.set((*p)[0]+0.5f, -				   0.5f - (*p)[1]); -		max_uv = min_uv; - -		while(src < end) -		{ -			// Mirror for underside. -			tc->mV[0] = (*p)[0]+0.5f; -			tc->mV[1] = 0.5f - (*p)[1]; -		 -			llassert(src->isFinite3()); -			update_min_max(min,max,*src); -			update_min_max(min_uv, max_uv, *tc); - -			*pos = *src; -		 -			llassert(pos->isFinite3()); -		 -			++p; -			++tc; -			++src; -			++pos; -		} -	} - -	LL_CHECK_MEMORY - -	mCenter->setAdd(min, max); -	mCenter->mul(0.5f);  - -	cuv = (min_uv + max_uv)*0.5f; - - -	VertexData vd; -	vd.setPosition(*mCenter); -	vd.mTexCoord = cuv; -	 -	if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) -	{ -		*pos++ = *mCenter; -		*tc++ = cuv; -		num_vertices++; -	} -		 -	LL_CHECK_MEMORY -		 -	//if (partial_build) -	//{ -	//	return TRUE; -	//} - -	if (mTypeMask & HOLLOW_MASK) -	{ -		if (mTypeMask & TOP_MASK) -		{ -			// HOLLOW TOP -			// Does it matter if it's open or closed? - djs - -			S32 pt1 = 0, pt2 = num_vertices - 1; -			S32 i = 0; -			while (pt2 - pt1 > 1) -			{ -				// Use the profile points instead of the mesh, since you want -				// the un-transformed profile distances. -				const LLVector4a& p1 = profile[pt1]; -				const LLVector4a& p2 = profile[pt2]; -				const LLVector4a& pa = profile[pt1+1]; -				const LLVector4a& pb = profile[pt2-1]; - -				const F32* p1V = p1.getF32ptr(); -				const F32* p2V = p2.getF32ptr(); -				const F32* paV = pa.getF32ptr(); -				const F32* pbV = pb.getF32ptr(); - -				//p1.mV[VZ] = 0.f; -				//p2.mV[VZ] = 0.f; -				//pa.mV[VZ] = 0.f; -				//pb.mV[VZ] = 0.f; - -				// Use area of triangle to determine backfacing -				F32 area_1a2, area_1ba, area_21b, area_2ab; -				area_1a2 =  (p1V[0]*paV[1] - paV[0]*p1V[1]) + -							(paV[0]*p2V[1] - p2V[0]*paV[1]) + -							(p2V[0]*p1V[1] - p1V[0]*p2V[1]); - -				area_1ba =  (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + -							(pbV[0]*paV[1] - paV[0]*pbV[1]) + -							(paV[0]*p1V[1] - p1V[0]*paV[1]); - -				area_21b =  (p2V[0]*p1V[1] - p1V[0]*p2V[1]) + -							(p1V[0]*pbV[1] - pbV[0]*p1V[1]) + -							(pbV[0]*p2V[1] - p2V[0]*pbV[1]); - -				area_2ab =  (p2V[0]*paV[1] - paV[0]*p2V[1]) + -							(paV[0]*pbV[1] - pbV[0]*paV[1]) + -							(pbV[0]*p2V[1] - p2V[0]*pbV[1]); - -				BOOL use_tri1a2 = TRUE; -				BOOL tri_1a2 = TRUE; -				BOOL tri_21b = TRUE; - -				if (area_1a2 < 0) -				{ -					tri_1a2 = FALSE; -				} -				if (area_2ab < 0) -				{ -					// Can't use, because it contains point b -					tri_1a2 = FALSE; -				} -				if (area_21b < 0) -				{ -					tri_21b = FALSE; -				} -				if (area_1ba < 0) -				{ -					// Can't use, because it contains point b -					tri_21b = FALSE; -				} - -				if (!tri_1a2) -				{ -					use_tri1a2 = FALSE; -				} -				else if (!tri_21b) -				{ -					use_tri1a2 = TRUE; -				} -				else -				{ -					LLVector4a d1; -					d1.setSub(p1, pa); -					 -					LLVector4a d2;  -					d2.setSub(p2, pb); - -					if (d1.dot3(d1) < d2.dot3(d2)) -					{ -						use_tri1a2 = TRUE; -					} -					else -					{ -						use_tri1a2 = FALSE; -					} -				} - -				if (use_tri1a2) -				{ -					mIndices[i++] = pt1; -					mIndices[i++] = pt1 + 1; -					mIndices[i++] = pt2; -					pt1++; -				} -				else -				{ -					mIndices[i++] = pt1; -					mIndices[i++] = pt2 - 1; -					mIndices[i++] = pt2; -					pt2--; -				} -			} -		} -		else -		{ -			// HOLLOW BOTTOM -			// Does it matter if it's open or closed? - djs - -			llassert(mTypeMask & BOTTOM_MASK); -			S32 pt1 = 0, pt2 = num_vertices - 1; - -			S32 i = 0; -			while (pt2 - pt1 > 1) -			{ -				// Use the profile points instead of the mesh, since you want -				// the un-transformed profile distances. -				const LLVector4a& p1 = profile[pt1]; -				const LLVector4a& p2 = profile[pt2]; -				const LLVector4a& pa = profile[pt1+1]; -				const LLVector4a& pb = profile[pt2-1]; - -				const F32* p1V = p1.getF32ptr(); -				const F32* p2V = p2.getF32ptr(); -				const F32* paV = pa.getF32ptr(); -				const F32* pbV = pb.getF32ptr(); - -				// Use area of triangle to determine backfacing -				F32 area_1a2, area_1ba, area_21b, area_2ab; -				area_1a2 =  (p1V[0]*paV[1] - paV[0]*p1V[1]) + -							(paV[0]*p2V[1] - p2V[0]*paV[1]) + -							(p2V[0]*p1V[1] - p1V[0]*p2V[1]); - -				area_1ba =  (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + -							(pbV[0]*paV[1] - paV[0]*pbV[1]) + -							(paV[0]*p1V[1] - p1V[0]*paV[1]); - -				area_21b =  (p2V[0]*p1V[1] - p1V[0]*p2V[1]) + -							(p1V[0]*pbV[1] - pbV[0]*p1V[1]) + -							(pbV[0]*p2V[1] - p2V[0]*pbV[1]); - -				area_2ab =  (p2V[0]*paV[1] - paV[0]*p2V[1]) + -							(paV[0]*pbV[1] - pbV[0]*paV[1]) + -							(pbV[0]*p2V[1] - p2V[0]*pbV[1]); - -				BOOL use_tri1a2 = TRUE; -				BOOL tri_1a2 = TRUE; -				BOOL tri_21b = TRUE; - -				if (area_1a2 < 0) -				{ -					tri_1a2 = FALSE; -				} -				if (area_2ab < 0) -				{ -					// Can't use, because it contains point b -					tri_1a2 = FALSE; -				} -				if (area_21b < 0) -				{ -					tri_21b = FALSE; -				} -				if (area_1ba < 0) -				{ -					// Can't use, because it contains point b -					tri_21b = FALSE; -				} - -				if (!tri_1a2) -				{ -					use_tri1a2 = FALSE; -				} -				else if (!tri_21b) -				{ -					use_tri1a2 = TRUE; -				} -				else -				{ -					LLVector4a d1; -					d1.setSub(p1,pa); -					LLVector4a d2; -					d2.setSub(p2,pb); - -					if (d1.dot3(d1) < d2.dot3(d2)) -					{ -						use_tri1a2 = TRUE; -					} -					else -					{ -						use_tri1a2 = FALSE; -					} -				} - -				// Flipped backfacing from top -				if (use_tri1a2) -				{ -					mIndices[i++] = pt1; -					mIndices[i++] = pt2; -					mIndices[i++] = pt1 + 1; -					pt1++; -				} -				else -				{ -					mIndices[i++] = pt1; -					mIndices[i++] = pt2; -					mIndices[i++] = pt2 - 1; -					pt2--; -				} -			} -		} -	} -	else -	{ -		// Not hollow, generate the triangle fan. -		U16 v1 = 2; -		U16 v2 = 1; - -		if (mTypeMask & TOP_MASK) -		{ -			v1 = 1; -			v2 = 2; -		} - -		for (S32 i = 0; i < (num_vertices - 2); i++) -		{ -			mIndices[3*i] = num_vertices - 1; -			mIndices[3*i+v1] = i; -			mIndices[3*i+v2] = i + 1; -		} - - -	} - -	LLVector4a d0,d1; -	LL_CHECK_MEMORY -		 - -	d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]); -	d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]); - -	LLVector4a normal; -	normal.setCross3(d0,d1); - -	if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO) -	{ -		normal.normalize3fast(); -	} -	else -	{ //degenerate, make up a value -		if(normal.getF32ptr()[2] >= 0) -			normal.set(0.f,0.f,1.f); -		else -			normal.set(0.f,0.f,-1.f); -	} - -	llassert(llfinite(normal.getF32ptr()[0])); -	llassert(llfinite(normal.getF32ptr()[1])); -	llassert(llfinite(normal.getF32ptr()[2])); - -	llassert(!llisnan(normal.getF32ptr()[0])); -	llassert(!llisnan(normal.getF32ptr()[1])); -	llassert(!llisnan(normal.getF32ptr()[2])); -	 -	for (S32 i = 0; i < num_vertices; i++) -	{ -		norm[i].load4a(normal.getF32ptr()); -	} - -	return TRUE; +    if (!(mTypeMask & HOLLOW_MASK) && +        !(mTypeMask & OPEN_MASK) && +        ((volume->getParams().getPathParams().getBegin()==0.0f)&& +        (volume->getParams().getPathParams().getEnd()==1.0f))&& +        (volume->getParams().getProfileParams().getCurveType()==LL_PCODE_PROFILE_SQUARE && +         volume->getParams().getPathParams().getCurveType()==LL_PCODE_PATH_LINE) +        ){ +        return createUnCutCubeCap(volume, partial_build); +    } + +    S32 num_vertices = 0, num_indices = 0; + +    const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh(); +    const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile; + +    // All types of caps have the same number of vertices and indices +    num_vertices = profile.size(); +    num_indices = (profile.size() - 2)*3; + +    if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) +    { +        resizeVertices(num_vertices+1); + +        //if (!partial_build) +        { +            resizeIndices(num_indices+3); +        } +    } +    else +    { +        resizeVertices(num_vertices); +        //if (!partial_build) +        { +            resizeIndices(num_indices); +        } +    } + +    LL_CHECK_MEMORY; + +    S32 max_s = volume->getProfile().getTotal(); +    S32 max_t = volume->getPath().mPath.size(); + +    mCenter->clear(); + +    S32 offset = 0; +    if (mTypeMask & TOP_MASK) +    { +        offset = (max_t-1) * max_s; +    } +    else +    { +        offset = mBeginS; +    } + +    // Figure out the normal, assume all caps are flat faces. +    // Cross product to get normals. + +    LLVector2 cuv; +    LLVector2 min_uv, max_uv; +    // VFExtents change +    LLVector4a& min = mExtents[0]; +    LLVector4a& max = mExtents[1]; + +    LLVector2* tc = (LLVector2*) mTexCoords; +    LLVector4a* pos = (LLVector4a*) mPositions; +    LLVector4a* norm = (LLVector4a*) mNormals; + +    // Copy the vertices into the array + +    const LLVector4a* src = mesh.mArray+offset; +    const LLVector4a* end = src+num_vertices; + +    min = *src; +    max = min; + + +    const LLVector4a* p = profile.mArray; + +    if (mTypeMask & TOP_MASK) +    { +        min_uv.set((*p)[0]+0.5f, +                    (*p)[1]+0.5f); + +        max_uv = min_uv; + +        while(src < end) +        { +            tc->mV[0] = (*p)[0]+0.5f; +            tc->mV[1] = (*p)[1]+0.5f; + +            llassert(src->isFinite3()); // MAINT-5660; don't know why this happens, does not affect Release builds +            update_min_max(min,max,*src); +            update_min_max(min_uv, max_uv, *tc); + +            *pos = *src; + +            llassert(pos->isFinite3()); + +            ++p; +            ++tc; +            ++src; +            ++pos; +        } +        } +        else +        { + +        min_uv.set((*p)[0]+0.5f, +                   0.5f - (*p)[1]); +        max_uv = min_uv; + +        while(src < end) +        { +            // Mirror for underside. +            tc->mV[0] = (*p)[0]+0.5f; +            tc->mV[1] = 0.5f - (*p)[1]; + +            llassert(src->isFinite3()); +            update_min_max(min,max,*src); +            update_min_max(min_uv, max_uv, *tc); + +            *pos = *src; + +            llassert(pos->isFinite3()); + +            ++p; +            ++tc; +            ++src; +            ++pos; +        } +    } + +    LL_CHECK_MEMORY + +    mCenter->setAdd(min, max); +    mCenter->mul(0.5f); + +    cuv = (min_uv + max_uv)*0.5f; + + +    VertexData vd; +    vd.setPosition(*mCenter); +    vd.mTexCoord = cuv; + +    if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) +    { +        *pos++ = *mCenter; +        *tc++ = cuv; +        num_vertices++; +    } + +    LL_CHECK_MEMORY + +    //if (partial_build) +    //{ +    //  return TRUE; +    //} + +    if (mTypeMask & HOLLOW_MASK) +    { +        if (mTypeMask & TOP_MASK) +        { +            // HOLLOW TOP +            // Does it matter if it's open or closed? - djs + +            S32 pt1 = 0, pt2 = num_vertices - 1; +            S32 i = 0; +            while (pt2 - pt1 > 1) +            { +                // Use the profile points instead of the mesh, since you want +                // the un-transformed profile distances. +                const LLVector4a& p1 = profile[pt1]; +                const LLVector4a& p2 = profile[pt2]; +                const LLVector4a& pa = profile[pt1+1]; +                const LLVector4a& pb = profile[pt2-1]; + +                const F32* p1V = p1.getF32ptr(); +                const F32* p2V = p2.getF32ptr(); +                const F32* paV = pa.getF32ptr(); +                const F32* pbV = pb.getF32ptr(); + +                //p1.mV[VZ] = 0.f; +                //p2.mV[VZ] = 0.f; +                //pa.mV[VZ] = 0.f; +                //pb.mV[VZ] = 0.f; + +                // Use area of triangle to determine backfacing +                F32 area_1a2, area_1ba, area_21b, area_2ab; +                area_1a2 =  (p1V[0]*paV[1] - paV[0]*p1V[1]) + +                            (paV[0]*p2V[1] - p2V[0]*paV[1]) + +                            (p2V[0]*p1V[1] - p1V[0]*p2V[1]); + +                area_1ba =  (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + +                            (pbV[0]*paV[1] - paV[0]*pbV[1]) + +                            (paV[0]*p1V[1] - p1V[0]*paV[1]); + +                area_21b =  (p2V[0]*p1V[1] - p1V[0]*p2V[1]) + +                            (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + +                            (pbV[0]*p2V[1] - p2V[0]*pbV[1]); + +                area_2ab =  (p2V[0]*paV[1] - paV[0]*p2V[1]) + +                            (paV[0]*pbV[1] - pbV[0]*paV[1]) + +                            (pbV[0]*p2V[1] - p2V[0]*pbV[1]); + +                BOOL use_tri1a2 = TRUE; +                BOOL tri_1a2 = TRUE; +                BOOL tri_21b = TRUE; + +                if (area_1a2 < 0) +                { +                    tri_1a2 = FALSE; +                } +                if (area_2ab < 0) +                { +                    // Can't use, because it contains point b +                    tri_1a2 = FALSE; +                } +                if (area_21b < 0) +                { +                    tri_21b = FALSE; +                } +                if (area_1ba < 0) +                { +                    // Can't use, because it contains point b +                    tri_21b = FALSE; +                } + +                if (!tri_1a2) +                { +                    use_tri1a2 = FALSE; +                } +                else if (!tri_21b) +                { +                    use_tri1a2 = TRUE; +                } +                else +                { +                    LLVector4a d1; +                    d1.setSub(p1, pa); + +                    LLVector4a d2; +                    d2.setSub(p2, pb); + +                    if (d1.dot3(d1) < d2.dot3(d2)) +                    { +                        use_tri1a2 = TRUE; +                    } +                    else +                    { +                        use_tri1a2 = FALSE; +                    } +                } + +                if (use_tri1a2) +                { +                    mIndices[i++] = pt1; +                    mIndices[i++] = pt1 + 1; +                    mIndices[i++] = pt2; +                    pt1++; +                } +                else +                { +                    mIndices[i++] = pt1; +                    mIndices[i++] = pt2 - 1; +                    mIndices[i++] = pt2; +                    pt2--; +                } +            } +        } +        else +        { +            // HOLLOW BOTTOM +            // Does it matter if it's open or closed? - djs + +            llassert(mTypeMask & BOTTOM_MASK); +            S32 pt1 = 0, pt2 = num_vertices - 1; + +            S32 i = 0; +            while (pt2 - pt1 > 1) +            { +                // Use the profile points instead of the mesh, since you want +                // the un-transformed profile distances. +                const LLVector4a& p1 = profile[pt1]; +                const LLVector4a& p2 = profile[pt2]; +                const LLVector4a& pa = profile[pt1+1]; +                const LLVector4a& pb = profile[pt2-1]; + +                const F32* p1V = p1.getF32ptr(); +                const F32* p2V = p2.getF32ptr(); +                const F32* paV = pa.getF32ptr(); +                const F32* pbV = pb.getF32ptr(); + +                // Use area of triangle to determine backfacing +                F32 area_1a2, area_1ba, area_21b, area_2ab; +                area_1a2 =  (p1V[0]*paV[1] - paV[0]*p1V[1]) + +                            (paV[0]*p2V[1] - p2V[0]*paV[1]) + +                            (p2V[0]*p1V[1] - p1V[0]*p2V[1]); + +                area_1ba =  (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + +                            (pbV[0]*paV[1] - paV[0]*pbV[1]) + +                            (paV[0]*p1V[1] - p1V[0]*paV[1]); + +                area_21b =  (p2V[0]*p1V[1] - p1V[0]*p2V[1]) + +                            (p1V[0]*pbV[1] - pbV[0]*p1V[1]) + +                            (pbV[0]*p2V[1] - p2V[0]*pbV[1]); + +                area_2ab =  (p2V[0]*paV[1] - paV[0]*p2V[1]) + +                            (paV[0]*pbV[1] - pbV[0]*paV[1]) + +                            (pbV[0]*p2V[1] - p2V[0]*pbV[1]); + +                BOOL use_tri1a2 = TRUE; +                BOOL tri_1a2 = TRUE; +                BOOL tri_21b = TRUE; + +                if (area_1a2 < 0) +                { +                    tri_1a2 = FALSE; +                } +                if (area_2ab < 0) +                { +                    // Can't use, because it contains point b +                    tri_1a2 = FALSE; +                } +                if (area_21b < 0) +                { +                    tri_21b = FALSE; +                } +                if (area_1ba < 0) +                { +                    // Can't use, because it contains point b +                    tri_21b = FALSE; +                } + +                if (!tri_1a2) +                { +                    use_tri1a2 = FALSE; +                } +                else if (!tri_21b) +                { +                    use_tri1a2 = TRUE; +                } +                else +                { +                    LLVector4a d1; +                    d1.setSub(p1,pa); +                    LLVector4a d2; +                    d2.setSub(p2,pb); + +                    if (d1.dot3(d1) < d2.dot3(d2)) +                    { +                        use_tri1a2 = TRUE; +                    } +                    else +                    { +                        use_tri1a2 = FALSE; +                    } +                } + +                // Flipped backfacing from top +                if (use_tri1a2) +                { +                    mIndices[i++] = pt1; +                    mIndices[i++] = pt2; +                    mIndices[i++] = pt1 + 1; +                    pt1++; +                } +                else +                { +                    mIndices[i++] = pt1; +                    mIndices[i++] = pt2; +                    mIndices[i++] = pt2 - 1; +                    pt2--; +                } +            } +        } +    } +    else +    { +        // Not hollow, generate the triangle fan. +        U16 v1 = 2; +        U16 v2 = 1; + +        if (mTypeMask & TOP_MASK) +        { +            v1 = 1; +            v2 = 2; +        } + +        for (S32 i = 0; i < (num_vertices - 2); i++) +        { +            mIndices[3*i] = num_vertices - 1; +            mIndices[3*i+v1] = i; +            mIndices[3*i+v2] = i + 1; +        } + + +    } + +    LLVector4a d0,d1; +    LL_CHECK_MEMORY + + +    d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]); +    d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]); + +    LLVector4a normal; +    normal.setCross3(d0,d1); + +    if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO) +    { +        normal.normalize3fast(); +    } +    else +    { //degenerate, make up a value +        if(normal.getF32ptr()[2] >= 0) +            normal.set(0.f,0.f,1.f); +        else +            normal.set(0.f,0.f,-1.f); +    } + +    llassert(llfinite(normal.getF32ptr()[0])); +    llassert(llfinite(normal.getF32ptr()[1])); +    llassert(llfinite(normal.getF32ptr()[2])); + +    llassert(!llisnan(normal.getF32ptr()[0])); +    llassert(!llisnan(normal.getF32ptr()[1])); +    llassert(!llisnan(normal.getF32ptr()[2])); + +    for (S32 i = 0; i < num_vertices; i++) +    { +        norm[i].load4a(normal.getF32ptr()); +    } + +    return TRUE;  }  void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, @@ -6486,7 +6486,7 @@ void LLVolumeFace::createTangents()      if (!mTangents)      {          allocateTangents(mNumVertices); -         +          //generate tangents          LLVector4a* ptr = (LLVector4a*)mTangents; @@ -6510,29 +6510,29 @@ void LLVolumeFace::createTangents()  void LLVolumeFace::resizeVertices(S32 num_verts)  { -	ll_aligned_free<64>(mPositions); -	//DO NOT free mNormals and mTexCoords as they are part of mPositions buffer -	ll_aligned_free_16(mTangents); +    ll_aligned_free<64>(mPositions); +    //DO NOT free mNormals and mTexCoords as they are part of mPositions buffer +    ll_aligned_free_16(mTangents); -	mTangents = NULL; +    mTangents = NULL; -	if (num_verts) -	{ -		//pad texture coordinate block end to allow for QWORD reads -		S32 tc_size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; +    if (num_verts) +    { +        //pad texture coordinate block end to allow for QWORD reads +        S32 tc_size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; -		mPositions = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+tc_size); -		mNormals = mPositions+num_verts; -		mTexCoords = (LLVector2*) (mNormals+num_verts); +        mPositions = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+tc_size); +        mNormals = mPositions+num_verts; +        mTexCoords = (LLVector2*) (mNormals+num_verts); -		ll_assert_aligned(mPositions, 64); -	} -	else -	{ -		mPositions = NULL; -		mNormals = NULL; -		mTexCoords = NULL; -	} +        ll_assert_aligned(mPositions, 64); +    } +    else +    { +        mPositions = NULL; +        mNormals = NULL; +        mTexCoords = NULL; +    }      if (mPositions) @@ -6553,70 +6553,70 @@ void LLVolumeFace::resizeVertices(S32 num_verts)  void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv)  { -	pushVertex(cv.getPosition(), cv.getNormal(), cv.mTexCoord); +    pushVertex(cv.getPosition(), cv.getNormal(), cv.mTexCoord);  }  void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc)  { -	S32 new_verts = mNumVertices+1; +    S32 new_verts = mNumVertices+1; + +    if (new_verts > mNumAllocatedVertices) +    { +        // double buffer size on expansion +        new_verts *= 2; -	if (new_verts > mNumAllocatedVertices) -	{  -		// double buffer size on expansion -		new_verts *= 2; +        S32 new_tc_size = ((new_verts*8)+0xF) & ~0xF; +        S32 old_tc_size = ((mNumVertices*8)+0xF) & ~0xF; -		S32 new_tc_size = ((new_verts*8)+0xF) & ~0xF; -		S32 old_tc_size = ((mNumVertices*8)+0xF) & ~0xF; +        S32 old_vsize = mNumVertices*16; -		S32 old_vsize = mNumVertices*16; -		 -		S32 new_size = new_verts*16*2+new_tc_size; +        S32 new_size = new_verts*16*2+new_tc_size; -		LLVector4a* old_buf = mPositions; +        LLVector4a* old_buf = mPositions; -		mPositions = (LLVector4a*) ll_aligned_malloc<64>(new_size); -		mNormals = mPositions+new_verts; -		mTexCoords = (LLVector2*) (mNormals+new_verts); +        mPositions = (LLVector4a*) ll_aligned_malloc<64>(new_size); +        mNormals = mPositions+new_verts; +        mTexCoords = (LLVector2*) (mNormals+new_verts); -		if (old_buf != NULL) -		{ -			// copy old positions into new buffer -			LLVector4a::memcpyNonAliased16((F32*)mPositions, (F32*)old_buf, old_vsize); +        if (old_buf != NULL) +        { +            // copy old positions into new buffer +            LLVector4a::memcpyNonAliased16((F32*)mPositions, (F32*)old_buf, old_vsize); -			// normals -			LLVector4a::memcpyNonAliased16((F32*)mNormals, (F32*)(old_buf + mNumVertices), old_vsize); +            // normals +            LLVector4a::memcpyNonAliased16((F32*)mNormals, (F32*)(old_buf + mNumVertices), old_vsize); -			// tex coords -			LLVector4a::memcpyNonAliased16((F32*)mTexCoords, (F32*)(old_buf + mNumVertices * 2), old_tc_size); -		} +            // tex coords +            LLVector4a::memcpyNonAliased16((F32*)mTexCoords, (F32*)(old_buf + mNumVertices * 2), old_tc_size); +        } -		// just clear tangents -		ll_aligned_free_16(mTangents); -		mTangents = NULL; -		ll_aligned_free<64>(old_buf); +        // just clear tangents +        ll_aligned_free_16(mTangents); +        mTangents = NULL; +        ll_aligned_free<64>(old_buf); -		mNumAllocatedVertices = new_verts; +        mNumAllocatedVertices = new_verts; -	} +    } -	mPositions[mNumVertices] = pos; -	mNormals[mNumVertices] = norm; -	mTexCoords[mNumVertices] = tc; +    mPositions[mNumVertices] = pos; +    mNormals[mNumVertices] = norm; +    mTexCoords[mNumVertices] = tc; -	mNumVertices++;	 +    mNumVertices++;  }  void LLVolumeFace::allocateTangents(S32 num_verts)  { -	ll_aligned_free_16(mTangents); -	mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); +    ll_aligned_free_16(mTangents); +    mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);  }  void LLVolumeFace::allocateWeights(S32 num_verts)  { -	ll_aligned_free_16(mWeights); -	mWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); -     +    ll_aligned_free_16(mWeights); +    mWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); +  }  void LLVolumeFace::allocateJointIndices(S32 num_verts) @@ -6625,27 +6625,27 @@ void LLVolumeFace::allocateJointIndices(S32 num_verts)      ll_aligned_free_16(mJointIndices);      ll_aligned_free_16(mJustWeights); -    mJointIndices = (U8*)ll_aligned_malloc_16(sizeof(U8) * 4 * num_verts);     -    mJustWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a) * num_verts);     +    mJointIndices = (U8*)ll_aligned_malloc_16(sizeof(U8) * 4 * num_verts); +    mJustWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a) * num_verts);  #endif  }  void LLVolumeFace::resizeIndices(S32 num_indices)  { -	ll_aligned_free_16(mIndices); +    ll_aligned_free_16(mIndices);      llassert(num_indices % 3 == 0); -	 -	if (num_indices) -	{ -		//pad index block end to allow for QWORD reads -		S32 size = ((num_indices*sizeof(U16)) + 0xF) & ~0xF; -		 -		mIndices = (U16*) ll_aligned_malloc_16(size); -	} -	else -	{ -		mIndices = NULL; -	} + +    if (num_indices) +    { +        //pad index block end to allow for QWORD reads +        S32 size = ((num_indices*sizeof(U16)) + 0xF) & ~0xF; + +        mIndices = (U16*) ll_aligned_malloc_16(size); +    } +    else +    { +        mIndices = NULL; +    }      if (mIndices)      { @@ -6660,73 +6660,73 @@ void LLVolumeFace::resizeIndices(S32 num_indices)  void LLVolumeFace::pushIndex(const U16& idx)  { -	S32 new_count = mNumIndices + 1; -	S32 new_size = ((new_count*2)+0xF) & ~0xF; +    S32 new_count = mNumIndices + 1; +    S32 new_size = ((new_count*2)+0xF) & ~0xF; -	S32 old_size = ((mNumIndices*2)+0xF) & ~0xF; -	if (new_size != old_size) -	{ -		mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size); -		ll_assert_aligned(mIndices,16); -	} -	 -	mIndices[mNumIndices++] = idx; +    S32 old_size = ((mNumIndices*2)+0xF) & ~0xF; +    if (new_size != old_size) +    { +        mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size); +        ll_assert_aligned(mIndices,16); +    } + +    mIndices[mNumIndices++] = idx;  }  void LLVolumeFace::fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx)  { -	resizeVertices(v.size()); -	resizeIndices(idx.size()); +    resizeVertices(v.size()); +    resizeIndices(idx.size()); -	for (U32 i = 0; i < v.size(); ++i) -	{ -		mPositions[i] = v[i].getPosition(); -		mNormals[i] = v[i].getNormal(); -		mTexCoords[i] = v[i].mTexCoord; -	} +    for (U32 i = 0; i < v.size(); ++i) +    { +        mPositions[i] = v[i].getPosition(); +        mNormals[i] = v[i].getNormal(); +        mTexCoords[i] = v[i].mTexCoord; +    } -	for (U32 i = 0; i < idx.size(); ++i) -	{ -		mIndices[i] = idx[i]; -	} +    for (U32 i = 0; i < idx.size(); ++i) +    { +        mIndices[i] = idx[i]; +    }  }  BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  { -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME -	LL_CHECK_MEMORY -	BOOL flat = mTypeMask & FLAT_MASK; +    LL_CHECK_MEMORY +    BOOL flat = mTypeMask & FLAT_MASK; -	U8 sculpt_type = volume->getParams().getSculptType(); -	U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; -	BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT; -	BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR; -	BOOL sculpt_reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror);  // XOR -	 -	S32 num_vertices, num_indices; +    U8 sculpt_type = volume->getParams().getSculptType(); +    U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; +    BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT; +    BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR; +    BOOL sculpt_reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror);  // XOR -	const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh(); -	const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile; -	const LLAlignedArray<LLPath::PathPt,64>& path_data = volume->getPath().mPath; +    S32 num_vertices, num_indices; -	S32 max_s = volume->getProfile().getTotal(); +    const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh(); +    const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile; +    const LLAlignedArray<LLPath::PathPt,64>& path_data = volume->getPath().mPath; -	S32 s, t, i; -	F32 ss, tt; +    S32 max_s = volume->getProfile().getTotal(); -	num_vertices = mNumS*mNumT; -	num_indices = (mNumS-1)*(mNumT-1)*6; +    S32 s, t, i; +    F32 ss, tt; -	partial_build = (num_vertices > mNumVertices || num_indices > mNumIndices) ? FALSE : partial_build; +    num_vertices = mNumS*mNumT; +    num_indices = (mNumS-1)*(mNumT-1)*6; -	if (!partial_build) -	{ -		resizeVertices(num_vertices); -		resizeIndices(num_indices); +    partial_build = (num_vertices > mNumVertices || num_indices > mNumIndices) ? FALSE : partial_build; + +    if (!partial_build) +    { +        resizeVertices(num_vertices); +        resizeIndices(num_indices); -		if (!volume->isMeshAssetLoaded()) -		{ +        if (!volume->isMeshAssetLoaded()) +        {              try              {                  mEdge.resize(num_indices); @@ -6736,237 +6736,237 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)                  LL_WARNS("LLVOLUME") << "Resize of mEdge to " << num_indices << " failed" << LL_ENDL;                  return false;              } -		} -	} - -	LL_CHECK_MEMORY - -	LLVector4a* pos = (LLVector4a*) mPositions; -	LLVector2* tc = (LLVector2*) mTexCoords; -	F32 begin_stex = floorf(profile[mBeginS][2]); -	S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS; - -	S32 cur_vertex = 0; -	S32 end_t = mBeginT+mNumT; -	bool test = (mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2; - -	// Copy the vertices into the array -	for (t = mBeginT; t < end_t; t++) -	{ -		tt = path_data[t].mTexT; -		for (s = 0; s < num_s; s++) -		{ -			if (mTypeMask & END_MASK) -			{ -				if (s) -				{ -					ss = 1.f; -				} -				else -				{ -					ss = 0.f; -				} -			} -			else -			{ -				// Get s value for tex-coord. +        } +    } + +    LL_CHECK_MEMORY + +    LLVector4a* pos = (LLVector4a*) mPositions; +    LLVector2* tc = (LLVector2*) mTexCoords; +    F32 begin_stex = floorf(profile[mBeginS][2]); +    S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS; + +    S32 cur_vertex = 0; +    S32 end_t = mBeginT+mNumT; +    bool test = (mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2; + +    // Copy the vertices into the array +    for (t = mBeginT; t < end_t; t++) +    { +        tt = path_data[t].mTexT; +        for (s = 0; s < num_s; s++) +        { +            if (mTypeMask & END_MASK) +            { +                if (s) +                { +                    ss = 1.f; +                } +                else +                { +                    ss = 0.f; +                } +            } +            else +            { +                // Get s value for tex-coord.                  S32 index = mBeginS + s;                  if (index >= profile.size())                  {                      // edge?                      ss = flat ? 1.f - begin_stex : 1.f;                  } -				else if (!flat) -				{ -					ss = profile[index][2]; -				} -				else -				{ -					ss = profile[index][2] - begin_stex; -				} -			} - -			if (sculpt_reverse_horizontal) -			{ -				ss = 1.f - ss; -			} -			 -			// Check to see if this triangle wraps around the array. -			if (mBeginS + s >= max_s) -			{ -				// We're wrapping -				i = mBeginS + s + max_s*(t-1); -			} -			else -			{ -				i = mBeginS + s + max_s*t; -			} - -			mesh[i].store4a((F32*)(pos+cur_vertex)); -			tc[cur_vertex].set(ss,tt); -		 -			cur_vertex++; - -			if (test && s > 0) -			{ -				mesh[i].store4a((F32*)(pos+cur_vertex)); -				tc[cur_vertex].set(ss,tt); -				cur_vertex++; -			} -		} -		 -		if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) -		{ -			if (mTypeMask & OPEN_MASK) -			{ -				s = num_s-1; -			} -			else -			{ -				s = 0; -			} - -			i = mBeginS + s + max_s*t; -			ss = profile[mBeginS + s][2] - begin_stex; - -			mesh[i].store4a((F32*)(pos+cur_vertex)); -			tc[cur_vertex].set(ss,tt); -			 -			cur_vertex++; -		} -	}	 -	LL_CHECK_MEMORY -	 -	mCenter->clear(); - -	LLVector4a* cur_pos = pos; -	LLVector4a* end_pos = pos + mNumVertices; - -	//get bounding box for this side -	LLVector4a face_min; -	LLVector4a face_max; -	 -	face_min = face_max = *cur_pos++; -		 -	while (cur_pos < end_pos) -	{ -		update_min_max(face_min, face_max, *cur_pos++); -	} -	// VFExtents change -	mExtents[0] = face_min; -	mExtents[1] = face_max; - -	U32 tc_count = mNumVertices; -	if (tc_count%2 == 1) -	{ //odd number of texture coordinates, duplicate last entry to padded end of array -		tc_count++; -		mTexCoords[mNumVertices] = mTexCoords[mNumVertices-1]; -	} - -	LLVector4a* cur_tc = (LLVector4a*) mTexCoords; -	LLVector4a* end_tc = (LLVector4a*) (mTexCoords+tc_count); - -	LLVector4a tc_min;  -	LLVector4a tc_max;  - -	tc_min = tc_max = *cur_tc++; - -	while (cur_tc < end_tc) -	{ -		update_min_max(tc_min, tc_max, *cur_tc++); -	} - -	F32* minp = tc_min.getF32ptr(); -	F32* maxp = tc_max.getF32ptr(); - -	mTexCoordExtents[0].mV[0] = llmin(minp[0], minp[2]); -	mTexCoordExtents[0].mV[1] = llmin(minp[1], minp[3]); -	mTexCoordExtents[1].mV[0] = llmax(maxp[0], maxp[2]); -	mTexCoordExtents[1].mV[1] = llmax(maxp[1], maxp[3]); - -	mCenter->setAdd(face_min, face_max); -	mCenter->mul(0.5f); - -	S32 cur_index = 0; -	S32 cur_edge = 0; -	BOOL flat_face = mTypeMask & FLAT_MASK; - -	if (!partial_build) -	{ -		// Now we generate the indices. -		for (t = 0; t < (mNumT-1); t++) -		{ -			for (s = 0; s < (mNumS-1); s++) -			{	 -				mIndices[cur_index++] = s   + mNumS*t;			//bottom left -				mIndices[cur_index++] = s+1 + mNumS*(t+1);		//top right -				mIndices[cur_index++] = s   + mNumS*(t+1);		//top left -				mIndices[cur_index++] = s   + mNumS*t;			//bottom left -				mIndices[cur_index++] = s+1 + mNumS*t;			//bottom right -				mIndices[cur_index++] = s+1 + mNumS*(t+1);		//top right - -				mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1;						//bottom left/top right neighbor face  -				if (t < mNumT-2) {												//top right/top left neighbor face  -					mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; -				} -				else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor -					mEdge[cur_edge++] = -1; -				} -				else { //wrap on T -					mEdge[cur_edge++] = s*2+1; -				} -				if (s > 0) {													//top left/bottom left neighbor face -					mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1; -				} -				else if (flat_face ||  volume->getProfile().isOpen() == TRUE) { //no neighbor -					mEdge[cur_edge++] = -1; -				} -				else {	//wrap on S -					mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1; -				} -				 -				if (t > 0) {													//bottom left/bottom right neighbor face -					mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2; -				} -				else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor -					mEdge[cur_edge++] = -1; -				} -				else { //wrap on T -					mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2; -				} -				if (s < mNumS-2) {												//bottom right/top right neighbor face -					mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2; -				} -				else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor -					mEdge[cur_edge++] = -1; -				} -				else { //wrap on S -					mEdge[cur_edge++] = (mNumS-1)*2*t; -				} -				mEdge[cur_edge++] = (mNumS-1)*2*t+s*2;							//top right/bottom left neighbor face	 -			} -		} -	} - -	LL_CHECK_MEMORY - -	//clear normals -	F32* dst = (F32*) mNormals; -	F32* end = (F32*) (mNormals+mNumVertices); -	LLVector4a zero = LLVector4a::getZero(); - -	while (dst < end) -	{ -		zero.store4a(dst); -		dst += 4; -	} - -	LL_CHECK_MEMORY - -	//generate normals  -	U32 count = mNumIndices/3; - -	LLVector4a* norm = mNormals; +                else if (!flat) +                { +                    ss = profile[index][2]; +                } +                else +                { +                    ss = profile[index][2] - begin_stex; +                } +            } + +            if (sculpt_reverse_horizontal) +            { +                ss = 1.f - ss; +            } + +            // Check to see if this triangle wraps around the array. +            if (mBeginS + s >= max_s) +            { +                // We're wrapping +                i = mBeginS + s + max_s*(t-1); +            } +            else +            { +                i = mBeginS + s + max_s*t; +            } + +            mesh[i].store4a((F32*)(pos+cur_vertex)); +            tc[cur_vertex].set(ss,tt); + +            cur_vertex++; + +            if (test && s > 0) +            { +                mesh[i].store4a((F32*)(pos+cur_vertex)); +                tc[cur_vertex].set(ss,tt); +                cur_vertex++; +            } +        } + +        if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) +        { +            if (mTypeMask & OPEN_MASK) +            { +                s = num_s-1; +            } +            else +            { +                s = 0; +            } + +            i = mBeginS + s + max_s*t; +            ss = profile[mBeginS + s][2] - begin_stex; + +            mesh[i].store4a((F32*)(pos+cur_vertex)); +            tc[cur_vertex].set(ss,tt); + +            cur_vertex++; +        } +    } +    LL_CHECK_MEMORY + +    mCenter->clear(); + +    LLVector4a* cur_pos = pos; +    LLVector4a* end_pos = pos + mNumVertices; + +    //get bounding box for this side +    LLVector4a face_min; +    LLVector4a face_max; + +    face_min = face_max = *cur_pos++; + +    while (cur_pos < end_pos) +    { +        update_min_max(face_min, face_max, *cur_pos++); +    } +    // VFExtents change +    mExtents[0] = face_min; +    mExtents[1] = face_max; + +    U32 tc_count = mNumVertices; +    if (tc_count%2 == 1) +    { //odd number of texture coordinates, duplicate last entry to padded end of array +        tc_count++; +        mTexCoords[mNumVertices] = mTexCoords[mNumVertices-1]; +    } + +    LLVector4a* cur_tc = (LLVector4a*) mTexCoords; +    LLVector4a* end_tc = (LLVector4a*) (mTexCoords+tc_count); + +    LLVector4a tc_min; +    LLVector4a tc_max; + +    tc_min = tc_max = *cur_tc++; + +    while (cur_tc < end_tc) +    { +        update_min_max(tc_min, tc_max, *cur_tc++); +    } + +    F32* minp = tc_min.getF32ptr(); +    F32* maxp = tc_max.getF32ptr(); + +    mTexCoordExtents[0].mV[0] = llmin(minp[0], minp[2]); +    mTexCoordExtents[0].mV[1] = llmin(minp[1], minp[3]); +    mTexCoordExtents[1].mV[0] = llmax(maxp[0], maxp[2]); +    mTexCoordExtents[1].mV[1] = llmax(maxp[1], maxp[3]); + +    mCenter->setAdd(face_min, face_max); +    mCenter->mul(0.5f); + +    S32 cur_index = 0; +    S32 cur_edge = 0; +    BOOL flat_face = mTypeMask & FLAT_MASK; + +    if (!partial_build) +    { +        // Now we generate the indices. +        for (t = 0; t < (mNumT-1); t++) +        { +            for (s = 0; s < (mNumS-1); s++) +            { +                mIndices[cur_index++] = s   + mNumS*t;          //bottom left +                mIndices[cur_index++] = s+1 + mNumS*(t+1);      //top right +                mIndices[cur_index++] = s   + mNumS*(t+1);      //top left +                mIndices[cur_index++] = s   + mNumS*t;          //bottom left +                mIndices[cur_index++] = s+1 + mNumS*t;          //bottom right +                mIndices[cur_index++] = s+1 + mNumS*(t+1);      //top right + +                mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1;                        //bottom left/top right neighbor face +                if (t < mNumT-2) {                                              //top right/top left neighbor face +                    mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; +                } +                else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor +                    mEdge[cur_edge++] = -1; +                } +                else { //wrap on T +                    mEdge[cur_edge++] = s*2+1; +                } +                if (s > 0) {                                                    //top left/bottom left neighbor face +                    mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1; +                } +                else if (flat_face ||  volume->getProfile().isOpen() == TRUE) { //no neighbor +                    mEdge[cur_edge++] = -1; +                } +                else {  //wrap on S +                    mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1; +                } + +                if (t > 0) {                                                    //bottom left/bottom right neighbor face +                    mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2; +                } +                else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor +                    mEdge[cur_edge++] = -1; +                } +                else { //wrap on T +                    mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2; +                } +                if (s < mNumS-2) {                                              //bottom right/top right neighbor face +                    mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2; +                } +                else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor +                    mEdge[cur_edge++] = -1; +                } +                else { //wrap on S +                    mEdge[cur_edge++] = (mNumS-1)*2*t; +                } +                mEdge[cur_edge++] = (mNumS-1)*2*t+s*2;                          //top right/bottom left neighbor face +            } +        } +    } + +    LL_CHECK_MEMORY + +    //clear normals +    F32* dst = (F32*) mNormals; +    F32* end = (F32*) (mNormals+mNumVertices); +    LLVector4a zero = LLVector4a::getZero(); + +    while (dst < end) +    { +        zero.store4a(dst); +        dst += 4; +    } + +    LL_CHECK_MEMORY + +    //generate normals +    U32 count = mNumIndices/3; + +    LLVector4a* norm = mNormals;      static thread_local LLAlignedArray<LLVector4a, 64> triangle_normals;      try @@ -6978,242 +6978,242 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)          LL_WARNS("LLVOLUME") << "Resize of triangle_normals to " << count << " failed" << LL_ENDL;          return false;      } -	LLVector4a* output = triangle_normals.mArray; -	LLVector4a* end_output = output+count; - -	U16* idx = mIndices; - -	while (output < end_output) -	{ -		LLVector4a b,v1,v2; -		b.load4a((F32*) (pos+idx[0])); -		v1.load4a((F32*) (pos+idx[1])); -		v2.load4a((F32*) (pos+idx[2])); -		 -		//calculate triangle normal -		LLVector4a a; -		 -		a.setSub(b, v1); -		b.sub(v2); - - -		LLQuad& vector1 = *((LLQuad*) &v1); -		LLQuad& vector2 = *((LLQuad*) &v2); -		 -		LLQuad& amQ = *((LLQuad*) &a); -		LLQuad& bmQ = *((LLQuad*) &b); - -		//v1.setCross3(t,v0); -		//setCross3(const LLVector4a& a, const LLVector4a& b) -		// Vectors are stored in memory in w, z, y, x order from high to low -		// Set vector1 = { a[W], a[X], a[Z], a[Y] } -		vector1 = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 0, 2, 1 )); -		// Set vector2 = { b[W], b[Y], b[X], b[Z] } -		vector2 = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 1, 0, 2 )); -		// mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] } -		vector2 = _mm_mul_ps( vector1, vector2 ); -		// vector3 = { a[W], a[Y], a[X], a[Z] } -		amQ = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 1, 0, 2 )); -		// vector4 = { b[W], b[X], b[Z], b[Y] } -		bmQ = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 0, 2, 1 )); -		// mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] } -		vector1 = _mm_sub_ps( vector2, _mm_mul_ps( amQ, bmQ )); - -		llassert(v1.isFinite3()); - -		v1.store4a((F32*) output); -		 -		 -		output++; -		idx += 3; -	} - -	idx = mIndices; - -	LLVector4a* src = triangle_normals.mArray; -	 -	for (U32 i = 0; i < count; i++) //for each triangle -	{ -		LLVector4a c; -		c.load4a((F32*) (src++)); - -		LLVector4a* n0p = norm+idx[0]; -		LLVector4a* n1p = norm+idx[1]; -		LLVector4a* n2p = norm+idx[2]; -		 -		idx += 3; - -		LLVector4a n0,n1,n2; -		n0.load4a((F32*) n0p); -		n1.load4a((F32*) n1p); -		n2.load4a((F32*) n2p); -		 -		n0.add(c); -		n1.add(c); -		n2.add(c); - -		llassert(c.isFinite3()); - -		//even out quad contributions -		switch (i%2+1) -		{ -			case 0: n0.add(c); break; -			case 1: n1.add(c); break; -			case 2: n2.add(c); break; -		}; - -		n0.store4a((F32*) n0p); -		n1.store4a((F32*) n1p); -		n2.store4a((F32*) n2p); -	} -	 -	LL_CHECK_MEMORY - -	// adjust normals based on wrapping and stitching -	 -	LLVector4a top; -	top.setSub(pos[0], pos[mNumS*(mNumT-2)]); -	BOOL s_bottom_converges = (top.dot3(top) < 0.000001f); - -	top.setSub(pos[mNumS-1], pos[mNumS*(mNumT-2)+mNumS-1]); -	BOOL s_top_converges = (top.dot3(top) < 0.000001f); - -	if (sculpt_stitching == LL_SCULPT_TYPE_NONE)  // logic for non-sculpt volumes -	{ -		if (volume->getPath().isOpen() == FALSE) -		{ //wrap normals on T -			for (S32 i = 0; i < mNumS; i++) -			{ -				LLVector4a n; -				n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); -				norm[i] = n; -				norm[mNumS*(mNumT-1)+i] = n; -			} -		} - -		if ((volume->getProfile().isOpen() == FALSE) && !(s_bottom_converges)) -		{ //wrap normals on S -			for (S32 i = 0; i < mNumT; i++) -			{ -				LLVector4a n; -				n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); -				norm[mNumS * i] = n; -				norm[mNumS * i+mNumS-1] = n; -			} -		} -	 -		if (volume->getPathType() == LL_PCODE_PATH_CIRCLE && -			((volume->getProfileType() & LL_PCODE_PROFILE_MASK) == LL_PCODE_PROFILE_CIRCLE_HALF)) -		{ -			if (s_bottom_converges) -			{ //all lower S have same normal -				for (S32 i = 0; i < mNumT; i++) -				{ -					norm[mNumS*i].set(1,0,0); -				} -			} - -			if (s_top_converges) -			{ //all upper S have same normal -				for (S32 i = 0; i < mNumT; i++) -				{ -					norm[mNumS*i+mNumS-1].set(-1,0,0); -				} -			} -		} -	} -	else  // logic for sculpt volumes -	{ -		BOOL average_poles = FALSE; -		BOOL wrap_s = FALSE; -		BOOL wrap_t = FALSE; - -		if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) -			average_poles = TRUE; - -		if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || -			(sculpt_stitching == LL_SCULPT_TYPE_TORUS) || -			(sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) -			wrap_s = TRUE; - -		if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) -			wrap_t = TRUE; -			 -		 -		if (average_poles) -		{ -			// average normals for north pole -		 -			LLVector4a average; -			average.clear(); - -			for (S32 i = 0; i < mNumS; i++) -			{ -				average.add(norm[i]); -			} - -			// set average -			for (S32 i = 0; i < mNumS; i++) -			{ -				norm[i] = average; -			} - -			// average normals for south pole -		 -			average.clear(); - -			for (S32 i = 0; i < mNumS; i++) -			{ -				average.add(norm[i + mNumS * (mNumT - 1)]); -			} - -			// set average -			for (S32 i = 0; i < mNumS; i++) -			{ -				norm[i + mNumS * (mNumT - 1)] = average; -			} - -		} - -		 -		if (wrap_s) -		{ -			for (S32 i = 0; i < mNumT; i++) -			{ -				LLVector4a n; -				n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); -				norm[mNumS * i] = n; -				norm[mNumS * i+mNumS-1] = n; -			} -		} - -		if (wrap_t) -		{ -			for (S32 i = 0; i < mNumS; i++) -			{ -				LLVector4a n; -				n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); -				norm[i] = n; -				norm[mNumS*(mNumT-1)+i] = n; -			} -		} - -	} - -	LL_CHECK_MEMORY - -	return TRUE; +    LLVector4a* output = triangle_normals.mArray; +    LLVector4a* end_output = output+count; + +    U16* idx = mIndices; + +    while (output < end_output) +    { +        LLVector4a b,v1,v2; +        b.load4a((F32*) (pos+idx[0])); +        v1.load4a((F32*) (pos+idx[1])); +        v2.load4a((F32*) (pos+idx[2])); + +        //calculate triangle normal +        LLVector4a a; + +        a.setSub(b, v1); +        b.sub(v2); + + +        LLQuad& vector1 = *((LLQuad*) &v1); +        LLQuad& vector2 = *((LLQuad*) &v2); + +        LLQuad& amQ = *((LLQuad*) &a); +        LLQuad& bmQ = *((LLQuad*) &b); + +        //v1.setCross3(t,v0); +        //setCross3(const LLVector4a& a, const LLVector4a& b) +        // Vectors are stored in memory in w, z, y, x order from high to low +        // Set vector1 = { a[W], a[X], a[Z], a[Y] } +        vector1 = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 0, 2, 1 )); +        // Set vector2 = { b[W], b[Y], b[X], b[Z] } +        vector2 = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 1, 0, 2 )); +        // mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] } +        vector2 = _mm_mul_ps( vector1, vector2 ); +        // vector3 = { a[W], a[Y], a[X], a[Z] } +        amQ = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 1, 0, 2 )); +        // vector4 = { b[W], b[X], b[Z], b[Y] } +        bmQ = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 0, 2, 1 )); +        // mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] } +        vector1 = _mm_sub_ps( vector2, _mm_mul_ps( amQ, bmQ )); + +        llassert(v1.isFinite3()); + +        v1.store4a((F32*) output); + + +        output++; +        idx += 3; +    } + +    idx = mIndices; + +    LLVector4a* src = triangle_normals.mArray; + +    for (U32 i = 0; i < count; i++) //for each triangle +    { +        LLVector4a c; +        c.load4a((F32*) (src++)); + +        LLVector4a* n0p = norm+idx[0]; +        LLVector4a* n1p = norm+idx[1]; +        LLVector4a* n2p = norm+idx[2]; + +        idx += 3; + +        LLVector4a n0,n1,n2; +        n0.load4a((F32*) n0p); +        n1.load4a((F32*) n1p); +        n2.load4a((F32*) n2p); + +        n0.add(c); +        n1.add(c); +        n2.add(c); + +        llassert(c.isFinite3()); + +        //even out quad contributions +        switch (i%2+1) +        { +            case 0: n0.add(c); break; +            case 1: n1.add(c); break; +            case 2: n2.add(c); break; +        }; + +        n0.store4a((F32*) n0p); +        n1.store4a((F32*) n1p); +        n2.store4a((F32*) n2p); +    } + +    LL_CHECK_MEMORY + +    // adjust normals based on wrapping and stitching + +    LLVector4a top; +    top.setSub(pos[0], pos[mNumS*(mNumT-2)]); +    BOOL s_bottom_converges = (top.dot3(top) < 0.000001f); + +    top.setSub(pos[mNumS-1], pos[mNumS*(mNumT-2)+mNumS-1]); +    BOOL s_top_converges = (top.dot3(top) < 0.000001f); + +    if (sculpt_stitching == LL_SCULPT_TYPE_NONE)  // logic for non-sculpt volumes +    { +        if (volume->getPath().isOpen() == FALSE) +        { //wrap normals on T +            for (S32 i = 0; i < mNumS; i++) +            { +                LLVector4a n; +                n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); +                norm[i] = n; +                norm[mNumS*(mNumT-1)+i] = n; +            } +        } + +        if ((volume->getProfile().isOpen() == FALSE) && !(s_bottom_converges)) +        { //wrap normals on S +            for (S32 i = 0; i < mNumT; i++) +            { +                LLVector4a n; +                n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); +                norm[mNumS * i] = n; +                norm[mNumS * i+mNumS-1] = n; +            } +        } + +        if (volume->getPathType() == LL_PCODE_PATH_CIRCLE && +            ((volume->getProfileType() & LL_PCODE_PROFILE_MASK) == LL_PCODE_PROFILE_CIRCLE_HALF)) +        { +            if (s_bottom_converges) +            { //all lower S have same normal +                for (S32 i = 0; i < mNumT; i++) +                { +                    norm[mNumS*i].set(1,0,0); +                } +            } + +            if (s_top_converges) +            { //all upper S have same normal +                for (S32 i = 0; i < mNumT; i++) +                { +                    norm[mNumS*i+mNumS-1].set(-1,0,0); +                } +            } +        } +    } +    else  // logic for sculpt volumes +    { +        BOOL average_poles = FALSE; +        BOOL wrap_s = FALSE; +        BOOL wrap_t = FALSE; + +        if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE) +            average_poles = TRUE; + +        if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) || +            (sculpt_stitching == LL_SCULPT_TYPE_TORUS) || +            (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER)) +            wrap_s = TRUE; + +        if (sculpt_stitching == LL_SCULPT_TYPE_TORUS) +            wrap_t = TRUE; + + +        if (average_poles) +        { +            // average normals for north pole + +            LLVector4a average; +            average.clear(); + +            for (S32 i = 0; i < mNumS; i++) +            { +                average.add(norm[i]); +            } + +            // set average +            for (S32 i = 0; i < mNumS; i++) +            { +                norm[i] = average; +            } + +            // average normals for south pole + +            average.clear(); + +            for (S32 i = 0; i < mNumS; i++) +            { +                average.add(norm[i + mNumS * (mNumT - 1)]); +            } + +            // set average +            for (S32 i = 0; i < mNumS; i++) +            { +                norm[i + mNumS * (mNumT - 1)] = average; +            } + +        } + + +        if (wrap_s) +        { +            for (S32 i = 0; i < mNumT; i++) +            { +                LLVector4a n; +                n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); +                norm[mNumS * i] = n; +                norm[mNumS * i+mNumS-1] = n; +            } +        } + +        if (wrap_t) +        { +            for (S32 i = 0; i < mNumS; i++) +            { +                LLVector4a n; +                n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); +                norm[i] = n; +                norm[mNumS*(mNumT-1)+i] = n; +            } +        } + +    } + +    LL_CHECK_MEMORY + +    return TRUE;  }  //adapted from Lengyel, Eric. "Computing Tangent Space Basis Vectors for an Arbitrary Mesh". Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html  void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,          const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)  { -	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME      //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; -	LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); -	// new(tan1) LLVector4a; +    LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); +    // new(tan1) LLVector4a;      LLVector4a* tan2 = tan1 + vertexCount; @@ -7228,86 +7228,86 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe          U32 i1 = *index_array++;          U32 i2 = *index_array++;          U32 i3 = *index_array++; -         +          const LLVector4a& v1 = vertex[i1];          const LLVector4a& v2 = vertex[i2];          const LLVector4a& v3 = vertex[i3]; -         +          const LLVector2& w1 = texcoord[i1];          const LLVector2& w2 = texcoord[i2];          const LLVector2& w3 = texcoord[i3]; -         -		const F32* v1ptr = v1.getF32ptr(); -		const F32* v2ptr = v2.getF32ptr(); -		const F32* v3ptr = v3.getF32ptr(); -		 + +        const F32* v1ptr = v1.getF32ptr(); +        const F32* v2ptr = v2.getF32ptr(); +        const F32* v3ptr = v3.getF32ptr(); +          float x1 = v2ptr[0] - v1ptr[0];          float x2 = v3ptr[0] - v1ptr[0];          float y1 = v2ptr[1] - v1ptr[1];          float y2 = v3ptr[1] - v1ptr[1];          float z1 = v2ptr[2] - v1ptr[2];          float z2 = v3ptr[2] - v1ptr[2]; -         +          float s1 = w2.mV[0] - w1.mV[0];          float s2 = w3.mV[0] - w1.mV[0];          float t1 = w2.mV[1] - w1.mV[1];          float t2 = w3.mV[1] - w1.mV[1]; -         -		F32 rd = s1*t2-s2*t1; - -		float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd) -													 : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero - -		llassert(llfinite(r)); -		llassert(!llisnan(r)); - -		LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, -				(t2 * z1 - t1 * z2) * r); -		LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, -				(s1 * z2 - s2 * z1) * r); -         -		tan1[i1].add(sdir); -		tan1[i2].add(sdir); -		tan1[i3].add(sdir); -         -		tan2[i1].add(tdir); -		tan2[i2].add(tdir); -		tan2[i3].add(tdir); -    } -     + +        F32 rd = s1*t2-s2*t1; + +        float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd) +                                                     : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero + +        llassert(llfinite(r)); +        llassert(!llisnan(r)); + +        LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, +                (t2 * z1 - t1 * z2) * r); +        LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, +                (s1 * z2 - s2 * z1) * r); + +        tan1[i1].add(sdir); +        tan1[i2].add(sdir); +        tan1[i3].add(sdir); + +        tan2[i1].add(tdir); +        tan2[i2].add(tdir); +        tan2[i3].add(tdir); +    } +      for (U32 a = 0; a < vertexCount; a++)      {          LLVector4a n = normal[a]; -		const LLVector4a& t = tan1[a]; +        const LLVector4a& t = tan1[a]; -		LLVector4a ncrosst; -		ncrosst.setCross3(n,t); +        LLVector4a ncrosst; +        ncrosst.setCross3(n,t);          // Gram-Schmidt orthogonalize          n.mul(n.dot3(t).getF32()); -		LLVector4a tsubn; -		tsubn.setSub(t,n); - -		if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) -		{ -			tsubn.normalize3fast(); -		 -			// Calculate handedness -			F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f; -		 -			tsubn.getF32ptr()[3] = handedness; - -			tangent[a] = tsubn; -		} -		else -		{ //degenerate, make up a value -			tangent[a].set(0,0,1,1); -		} -    } -     -	ll_aligned_free_16(tan1); +        LLVector4a tsubn; +        tsubn.setSub(t,n); + +        if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) +        { +            tsubn.normalize3fast(); + +            // Calculate handedness +            F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f; + +            tsubn.getF32ptr()[3] = handedness; + +            tangent[a] = tsubn; +        } +        else +        { //degenerate, make up a value +            tangent[a].set(0,0,1,1); +        } +    } + +    ll_aligned_free_16(tan1);  } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 71878b8cb6..917ad6030c 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1,25 +1,25 @@ -/**  +/**   * @file llvolume.h   * @brief LLVolume base class.   *   * $LicenseInfo:firstyear=2002&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -69,8 +69,8 @@ const S32 MAX_LOD = 3;  // These are defined here but are not enforced at this level,  // rather they are here for the convenience of code that uses  // the LLVolume class. -const F32 MIN_VOLUME_PROFILE_WIDTH 	= 0.05f; -const F32 MIN_VOLUME_PATH_WIDTH 	= 0.05f; +const F32 MIN_VOLUME_PROFILE_WIDTH  = 0.05f; +const F32 MIN_VOLUME_PATH_WIDTH     = 0.05f;  const F32 CUT_QUANTA    = 0.00002f;  const F32 SCALE_QUANTA  = 0.01f; @@ -84,100 +84,100 @@ const S32 MAX_VOLUME_TRIANGLE_INDICES = 10000;  //============================================================================  // useful masks -const LLPCode LL_PCODE_HOLLOW_MASK 	= 0x80;		// has a thickness -const LLPCode LL_PCODE_SEGMENT_MASK = 0x40;		// segments (1 angle) -const LLPCode LL_PCODE_PATCH_MASK 	= 0x20;		// segmented segments (2 angles) -const LLPCode LL_PCODE_HEMI_MASK 	= 0x10;		// half-primitives get their own type per PR's dictum -const LLPCode LL_PCODE_BASE_MASK 	= 0x0F; - -	// primitive shapes -const LLPCode	LL_PCODE_CUBE 			= 1; -const LLPCode	LL_PCODE_PRISM 			= 2; -const LLPCode	LL_PCODE_TETRAHEDRON 	= 3; -const LLPCode	LL_PCODE_PYRAMID 		= 4; -const LLPCode	LL_PCODE_CYLINDER 		= 5; -const LLPCode	LL_PCODE_CONE 			= 6; -const LLPCode	LL_PCODE_SPHERE 		= 7; -const LLPCode	LL_PCODE_TORUS 			= 8; -const LLPCode	LL_PCODE_VOLUME			= 9; - -	// surfaces -//const LLPCode	LL_PCODE_SURFACE_TRIANGLE 	= 10; -//const LLPCode	LL_PCODE_SURFACE_SQUARE 	= 11; -//const LLPCode	LL_PCODE_SURFACE_DISC 		= 12; - -const LLPCode	LL_PCODE_APP				= 14; // App specific pcode (for viewer/sim side only objects) -const LLPCode	LL_PCODE_LEGACY				= 15; +const LLPCode LL_PCODE_HOLLOW_MASK  = 0x80;     // has a thickness +const LLPCode LL_PCODE_SEGMENT_MASK = 0x40;     // segments (1 angle) +const LLPCode LL_PCODE_PATCH_MASK   = 0x20;     // segmented segments (2 angles) +const LLPCode LL_PCODE_HEMI_MASK    = 0x10;     // half-primitives get their own type per PR's dictum +const LLPCode LL_PCODE_BASE_MASK    = 0x0F; + +    // primitive shapes +const LLPCode   LL_PCODE_CUBE           = 1; +const LLPCode   LL_PCODE_PRISM          = 2; +const LLPCode   LL_PCODE_TETRAHEDRON    = 3; +const LLPCode   LL_PCODE_PYRAMID        = 4; +const LLPCode   LL_PCODE_CYLINDER       = 5; +const LLPCode   LL_PCODE_CONE           = 6; +const LLPCode   LL_PCODE_SPHERE         = 7; +const LLPCode   LL_PCODE_TORUS          = 8; +const LLPCode   LL_PCODE_VOLUME         = 9; + +    // surfaces +//const LLPCode LL_PCODE_SURFACE_TRIANGLE   = 10; +//const LLPCode LL_PCODE_SURFACE_SQUARE     = 11; +//const LLPCode LL_PCODE_SURFACE_DISC       = 12; + +const LLPCode   LL_PCODE_APP                = 14; // App specific pcode (for viewer/sim side only objects) +const LLPCode   LL_PCODE_LEGACY             = 15;  // Pcodes for legacy objects -//const LLPCode	LL_PCODE_LEGACY_ATOR =				0x10 | LL_PCODE_LEGACY; // ATOR -const LLPCode	LL_PCODE_LEGACY_AVATAR =			0x20 | LL_PCODE_LEGACY; // PLAYER -//const LLPCode	LL_PCODE_LEGACY_BIRD =				0x30 | LL_PCODE_LEGACY; // BIRD -//const LLPCode	LL_PCODE_LEGACY_DEMON =				0x40 | LL_PCODE_LEGACY; // DEMON -const LLPCode	LL_PCODE_LEGACY_GRASS =				0x50 | LL_PCODE_LEGACY; // GRASS -const LLPCode	LL_PCODE_TREE_NEW =					0x60 | LL_PCODE_LEGACY; // new trees -//const LLPCode	LL_PCODE_LEGACY_ORACLE =			0x70 | LL_PCODE_LEGACY; // ORACLE -const LLPCode	LL_PCODE_LEGACY_PART_SYS =			0x80 | LL_PCODE_LEGACY; // PART_SYS -const LLPCode	LL_PCODE_LEGACY_ROCK =				0x90 | LL_PCODE_LEGACY; // ROCK -//const LLPCode	LL_PCODE_LEGACY_SHOT =				0xA0 | LL_PCODE_LEGACY; // BASIC_SHOT -//const LLPCode	LL_PCODE_LEGACY_SHOT_BIG =			0xB0 | LL_PCODE_LEGACY; -//const LLPCode	LL_PCODE_LEGACY_SMOKE =				0xC0 | LL_PCODE_LEGACY; // SMOKE -//const LLPCode	LL_PCODE_LEGACY_SPARK =				0xD0 | LL_PCODE_LEGACY;// SPARK -const LLPCode	LL_PCODE_LEGACY_TEXT_BUBBLE =		0xE0 | LL_PCODE_LEGACY; // TEXTBUBBLE -const LLPCode	LL_PCODE_LEGACY_TREE =				0xF0 | LL_PCODE_LEGACY; // TREE - -	// hemis -const LLPCode	LL_PCODE_CYLINDER_HEMI =		LL_PCODE_CYLINDER	| LL_PCODE_HEMI_MASK; -const LLPCode	LL_PCODE_CONE_HEMI =			LL_PCODE_CONE		| LL_PCODE_HEMI_MASK; -const LLPCode	LL_PCODE_SPHERE_HEMI =			LL_PCODE_SPHERE		| LL_PCODE_HEMI_MASK; -const LLPCode	LL_PCODE_TORUS_HEMI =			LL_PCODE_TORUS		| LL_PCODE_HEMI_MASK; +//const LLPCode LL_PCODE_LEGACY_ATOR =              0x10 | LL_PCODE_LEGACY; // ATOR +const LLPCode   LL_PCODE_LEGACY_AVATAR =            0x20 | LL_PCODE_LEGACY; // PLAYER +//const LLPCode LL_PCODE_LEGACY_BIRD =              0x30 | LL_PCODE_LEGACY; // BIRD +//const LLPCode LL_PCODE_LEGACY_DEMON =             0x40 | LL_PCODE_LEGACY; // DEMON +const LLPCode   LL_PCODE_LEGACY_GRASS =             0x50 | LL_PCODE_LEGACY; // GRASS +const LLPCode   LL_PCODE_TREE_NEW =                 0x60 | LL_PCODE_LEGACY; // new trees +//const LLPCode LL_PCODE_LEGACY_ORACLE =            0x70 | LL_PCODE_LEGACY; // ORACLE +const LLPCode   LL_PCODE_LEGACY_PART_SYS =          0x80 | LL_PCODE_LEGACY; // PART_SYS +const LLPCode   LL_PCODE_LEGACY_ROCK =              0x90 | LL_PCODE_LEGACY; // ROCK +//const LLPCode LL_PCODE_LEGACY_SHOT =              0xA0 | LL_PCODE_LEGACY; // BASIC_SHOT +//const LLPCode LL_PCODE_LEGACY_SHOT_BIG =          0xB0 | LL_PCODE_LEGACY; +//const LLPCode LL_PCODE_LEGACY_SMOKE =             0xC0 | LL_PCODE_LEGACY; // SMOKE +//const LLPCode LL_PCODE_LEGACY_SPARK =             0xD0 | LL_PCODE_LEGACY;// SPARK +const LLPCode   LL_PCODE_LEGACY_TEXT_BUBBLE =       0xE0 | LL_PCODE_LEGACY; // TEXTBUBBLE +const LLPCode   LL_PCODE_LEGACY_TREE =              0xF0 | LL_PCODE_LEGACY; // TREE + +    // hemis +const LLPCode   LL_PCODE_CYLINDER_HEMI =        LL_PCODE_CYLINDER   | LL_PCODE_HEMI_MASK; +const LLPCode   LL_PCODE_CONE_HEMI =            LL_PCODE_CONE       | LL_PCODE_HEMI_MASK; +const LLPCode   LL_PCODE_SPHERE_HEMI =          LL_PCODE_SPHERE     | LL_PCODE_HEMI_MASK; +const LLPCode   LL_PCODE_TORUS_HEMI =           LL_PCODE_TORUS      | LL_PCODE_HEMI_MASK;  // Volumes consist of a profile at the base that is swept around  // a path to make a volume.  // The profile code -const U8	LL_PCODE_PROFILE_MASK		= 0x0f; -const U8	LL_PCODE_PROFILE_MIN		= 0x00; -const U8    LL_PCODE_PROFILE_CIRCLE		= 0x00; -const U8    LL_PCODE_PROFILE_SQUARE		= 0x01; -const U8	LL_PCODE_PROFILE_ISOTRI		= 0x02; -const U8    LL_PCODE_PROFILE_EQUALTRI	= 0x03; -const U8    LL_PCODE_PROFILE_RIGHTTRI	= 0x04; -const U8	LL_PCODE_PROFILE_CIRCLE_HALF = 0x05; -const U8	LL_PCODE_PROFILE_MAX		= 0x05; +const U8    LL_PCODE_PROFILE_MASK       = 0x0f; +const U8    LL_PCODE_PROFILE_MIN        = 0x00; +const U8    LL_PCODE_PROFILE_CIRCLE     = 0x00; +const U8    LL_PCODE_PROFILE_SQUARE     = 0x01; +const U8    LL_PCODE_PROFILE_ISOTRI     = 0x02; +const U8    LL_PCODE_PROFILE_EQUALTRI   = 0x03; +const U8    LL_PCODE_PROFILE_RIGHTTRI   = 0x04; +const U8    LL_PCODE_PROFILE_CIRCLE_HALF = 0x05; +const U8    LL_PCODE_PROFILE_MAX        = 0x05;  // Stored in the profile byte -const U8	LL_PCODE_HOLE_MASK		= 0xf0; -const U8	LL_PCODE_HOLE_MIN		= 0x00;	   -const U8	LL_PCODE_HOLE_SAME		= 0x00;		// same as outside profile -const U8	LL_PCODE_HOLE_CIRCLE	= 0x10; -const U8	LL_PCODE_HOLE_SQUARE	= 0x20; -const U8	LL_PCODE_HOLE_TRIANGLE	= 0x30; -const U8	LL_PCODE_HOLE_MAX		= 0x03;		// min/max needs to be >> 4 of real min/max +const U8    LL_PCODE_HOLE_MASK      = 0xf0; +const U8    LL_PCODE_HOLE_MIN       = 0x00; +const U8    LL_PCODE_HOLE_SAME      = 0x00;     // same as outside profile +const U8    LL_PCODE_HOLE_CIRCLE    = 0x10; +const U8    LL_PCODE_HOLE_SQUARE    = 0x20; +const U8    LL_PCODE_HOLE_TRIANGLE  = 0x30; +const U8    LL_PCODE_HOLE_MAX       = 0x03;     // min/max needs to be >> 4 of real min/max  const U8    LL_PCODE_PATH_IGNORE    = 0x00; -const U8	LL_PCODE_PATH_MIN		= 0x01;		// min/max needs to be >> 4 of real min/max +const U8    LL_PCODE_PATH_MIN       = 0x01;     // min/max needs to be >> 4 of real min/max  const U8    LL_PCODE_PATH_LINE      = 0x10;  const U8    LL_PCODE_PATH_CIRCLE    = 0x20;  const U8    LL_PCODE_PATH_CIRCLE2   = 0x30;  const U8    LL_PCODE_PATH_TEST      = 0x40;  const U8    LL_PCODE_PATH_FLEXIBLE  = 0x80; -const U8	LL_PCODE_PATH_MAX		= 0x08; +const U8    LL_PCODE_PATH_MAX       = 0x08;  //============================================================================  // face identifiers  typedef U16 LLFaceID; -const LLFaceID	LL_FACE_PATH_BEGIN		= 0x1 << 0; -const LLFaceID	LL_FACE_PATH_END		= 0x1 << 1; -const LLFaceID	LL_FACE_INNER_SIDE		= 0x1 << 2; -const LLFaceID	LL_FACE_PROFILE_BEGIN	= 0x1 << 3; -const LLFaceID	LL_FACE_PROFILE_END		= 0x1 << 4; -const LLFaceID	LL_FACE_OUTER_SIDE_0	= 0x1 << 5; -const LLFaceID	LL_FACE_OUTER_SIDE_1	= 0x1 << 6; -const LLFaceID	LL_FACE_OUTER_SIDE_2	= 0x1 << 7; -const LLFaceID	LL_FACE_OUTER_SIDE_3	= 0x1 << 8; +const LLFaceID  LL_FACE_PATH_BEGIN      = 0x1 << 0; +const LLFaceID  LL_FACE_PATH_END        = 0x1 << 1; +const LLFaceID  LL_FACE_INNER_SIDE      = 0x1 << 2; +const LLFaceID  LL_FACE_PROFILE_BEGIN   = 0x1 << 3; +const LLFaceID  LL_FACE_PROFILE_END     = 0x1 << 4; +const LLFaceID  LL_FACE_OUTER_SIDE_0    = 0x1 << 5; +const LLFaceID  LL_FACE_OUTER_SIDE_1    = 0x1 << 6; +const LLFaceID  LL_FACE_OUTER_SIDE_2    = 0x1 << 7; +const LLFaceID  LL_FACE_OUTER_SIDE_3    = 0x1 << 8;  //============================================================================ @@ -190,7 +190,7 @@ const U8 LL_SCULPT_TYPE_PLANE     = 3;  const U8 LL_SCULPT_TYPE_CYLINDER  = 4;  const U8 LL_SCULPT_TYPE_MESH      = 5;  const U8 LL_SCULPT_TYPE_MASK      = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE | -	LL_SCULPT_TYPE_CYLINDER | LL_SCULPT_TYPE_MESH; +    LL_SCULPT_TYPE_CYLINDER | LL_SCULPT_TYPE_MESH;  // for value checks, assign new value after adding new types  const U8 LL_SCULPT_TYPE_MAX = LL_SCULPT_TYPE_MESH; @@ -206,125 +206,125 @@ extern BOOL gDebugGL;  class LLProfileParams  {  public: -	LLProfileParams() -		: mCurveType(LL_PCODE_PROFILE_SQUARE), -		  mBegin(0.f), -		  mEnd(1.f), -		  mHollow(0.f), -		  mCRC(0) -	{ -	} - -	LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow) -		: mCurveType(curve), -		  mBegin(begin), -		  mEnd(end), -		  mHollow(hollow), -		  mCRC(0) -	{ -	} - -	LLProfileParams(U8 curve, U16 begin, U16 end, U16 hollow) -	{ -		mCurveType = curve; -		F32 temp_f32 = begin * CUT_QUANTA; -		if (temp_f32 > 1.f) -		{ -			temp_f32 = 1.f; -		} -		mBegin = temp_f32; -		temp_f32 = end * CUT_QUANTA; -		if (temp_f32 > 1.f) -		{ -			temp_f32 = 1.f; -		} -		mEnd = 1.f - temp_f32; -		temp_f32 = hollow * HOLLOW_QUANTA; -		if (temp_f32 > 1.f) -		{ -			temp_f32 = 1.f; -		} -		mHollow = temp_f32; -		mCRC = 0; -	} - -	bool operator==(const LLProfileParams ¶ms) const; -	bool operator!=(const LLProfileParams ¶ms) const; -	bool operator<(const LLProfileParams ¶ms) const; -	 -	void copyParams(const LLProfileParams ¶ms); - -	BOOL importFile(LLFILE *fp); -	BOOL exportFile(LLFILE *fp) const; - -	BOOL importLegacyStream(std::istream& input_stream); -	BOOL exportLegacyStream(std::ostream& output_stream) const; - -	LLSD asLLSD() const; -	operator LLSD() const { return asLLSD(); } -	bool fromLLSD(LLSD& sd); - -	const F32&  getBegin () const				{ return mBegin; } -	const F32&  getEnd   () const				{ return mEnd;   } -	const F32&  getHollow() const				{ return mHollow; } -	const U8&   getCurveType () const			{ return mCurveType; } - -	void setCurveType(const U32 type)			{ mCurveType = type;} -	void setBegin(const F32 begin)				{ mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 100000))/100000.0f;} -	void setEnd(const F32 end)					{ mEnd   = (end   <= 0.0f) ? 1.0f : ((int) (end * 100000))/100000.0f;} -	void setHollow(const F32 hollow)			{ mHollow = ((int) (hollow * 100000))/100000.0f;} - -	friend std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params); +    LLProfileParams() +        : mCurveType(LL_PCODE_PROFILE_SQUARE), +          mBegin(0.f), +          mEnd(1.f), +          mHollow(0.f), +          mCRC(0) +    { +    } + +    LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow) +        : mCurveType(curve), +          mBegin(begin), +          mEnd(end), +          mHollow(hollow), +          mCRC(0) +    { +    } + +    LLProfileParams(U8 curve, U16 begin, U16 end, U16 hollow) +    { +        mCurveType = curve; +        F32 temp_f32 = begin * CUT_QUANTA; +        if (temp_f32 > 1.f) +        { +            temp_f32 = 1.f; +        } +        mBegin = temp_f32; +        temp_f32 = end * CUT_QUANTA; +        if (temp_f32 > 1.f) +        { +            temp_f32 = 1.f; +        } +        mEnd = 1.f - temp_f32; +        temp_f32 = hollow * HOLLOW_QUANTA; +        if (temp_f32 > 1.f) +        { +            temp_f32 = 1.f; +        } +        mHollow = temp_f32; +        mCRC = 0; +    } + +    bool operator==(const LLProfileParams ¶ms) const; +    bool operator!=(const LLProfileParams ¶ms) const; +    bool operator<(const LLProfileParams ¶ms) const; + +    void copyParams(const LLProfileParams ¶ms); + +    BOOL importFile(LLFILE *fp); +    BOOL exportFile(LLFILE *fp) const; + +    BOOL importLegacyStream(std::istream& input_stream); +    BOOL exportLegacyStream(std::ostream& output_stream) const; + +    LLSD asLLSD() const; +    operator LLSD() const { return asLLSD(); } +    bool fromLLSD(LLSD& sd); + +    const F32&  getBegin () const               { return mBegin; } +    const F32&  getEnd   () const               { return mEnd;   } +    const F32&  getHollow() const               { return mHollow; } +    const U8&   getCurveType () const           { return mCurveType; } + +    void setCurveType(const U32 type)           { mCurveType = type;} +    void setBegin(const F32 begin)              { mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 100000))/100000.0f;} +    void setEnd(const F32 end)                  { mEnd   = (end   <= 0.0f) ? 1.0f : ((int) (end * 100000))/100000.0f;} +    void setHollow(const F32 hollow)            { mHollow = ((int) (hollow * 100000))/100000.0f;} + +    friend std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params);  protected: -	// Profile params -	U8			  mCurveType; -	F32           mBegin; -	F32           mEnd; -	F32			  mHollow; +    // Profile params +    U8            mCurveType; +    F32           mBegin; +    F32           mEnd; +    F32           mHollow; -	U32           mCRC; +    U32           mCRC;  };  inline bool LLProfileParams::operator==(const LLProfileParams ¶ms) const  { -	return  -		(getCurveType() == params.getCurveType()) && -		(getBegin() == params.getBegin()) && -		(getEnd() == params.getEnd()) && -		(getHollow() == params.getHollow()); +    return +        (getCurveType() == params.getCurveType()) && +        (getBegin() == params.getBegin()) && +        (getEnd() == params.getEnd()) && +        (getHollow() == params.getHollow());  }  inline bool LLProfileParams::operator!=(const LLProfileParams ¶ms) const  { -	return  -		(getCurveType() != params.getCurveType()) || -		(getBegin() != params.getBegin()) || -		(getEnd() != params.getEnd()) || -		(getHollow() != params.getHollow()); +    return +        (getCurveType() != params.getCurveType()) || +        (getBegin() != params.getBegin()) || +        (getEnd() != params.getEnd()) || +        (getHollow() != params.getHollow());  }  inline bool LLProfileParams::operator<(const LLProfileParams ¶ms) const  { -	if (getCurveType() != params.getCurveType()) -	{ -		return getCurveType() < params.getCurveType(); -	} -	else -	if (getBegin() != params.getBegin()) -	{ -		return getBegin() < params.getBegin(); -	} -	else -	if (getEnd() != params.getEnd()) -	{ -		return getEnd() < params.getEnd(); -	} -	else -	{ -		return getHollow() < params.getHollow(); -	} +    if (getCurveType() != params.getCurveType()) +    { +        return getCurveType() < params.getCurveType(); +    } +    else +    if (getBegin() != params.getBegin()) +    { +        return getBegin() < params.getBegin(); +    } +    else +    if (getEnd() != params.getEnd()) +    { +        return getEnd() < params.getEnd(); +    } +    else +    { +        return getHollow() < params.getHollow(); +    }  }  #define U8_TO_F32(x) (F32)(*((S8 *)&x)) @@ -332,225 +332,225 @@ inline bool LLProfileParams::operator<(const LLProfileParams ¶ms) const  class LLPathParams  {  public: -	LLPathParams() -		: -		mCurveType(LL_PCODE_PATH_LINE), -		mBegin(0.f), -		mEnd(1.f), -		mScale(1.f,1.f), -		mShear(0.f,0.f), -		mTwistBegin(0.f), -		mTwistEnd(0.f), -		mRadiusOffset(0.f), -		mTaper(0.f,0.f), -		mRevolutions(1.f), -		mSkew(0.f), -		mCRC(0) -	{ -	} - -	LLPathParams(U8 curve, F32 begin, F32 end, F32 scx, F32 scy, F32 shx, F32 shy, F32 twistend, F32 twistbegin, F32 radiusoffset, F32 tx, F32 ty, F32 revolutions, F32 skew) -		: mCurveType(curve), -		  mBegin(begin), -		  mEnd(end), -		  mScale(scx,scy), -		  mShear(shx,shy), -		  mTwistBegin(twistbegin), -		  mTwistEnd(twistend),  -		  mRadiusOffset(radiusoffset), -		  mTaper(tx,ty), -		  mRevolutions(revolutions), -		  mSkew(skew), -		  mCRC(0) -	{ -	} - -	LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew) -	{ -		mCurveType = curve; -		mBegin = (F32)(begin * CUT_QUANTA); -		mEnd = (F32)(100.f - end) * CUT_QUANTA; -		if (mEnd > 1.f) -			mEnd = 1.f; -		mScale.setVec((F32) (200 - scx) * SCALE_QUANTA,(F32) (200 - scy) * SCALE_QUANTA); -		mShear.setVec(U8_TO_F32(shx) * SHEAR_QUANTA,U8_TO_F32(shy) * SHEAR_QUANTA); -		mTwistBegin = U8_TO_F32(twistbegin) * SCALE_QUANTA; -		mTwistEnd = U8_TO_F32(twistend) * SCALE_QUANTA; -		mRadiusOffset = U8_TO_F32(radiusoffset) * SCALE_QUANTA; -		mTaper.setVec(U8_TO_F32(tx) * TAPER_QUANTA,U8_TO_F32(ty) * TAPER_QUANTA); -		mRevolutions = ((F32)revolutions) * REV_QUANTA + 1.0f; -		mSkew = U8_TO_F32(skew) * SCALE_QUANTA; - -		mCRC = 0; -	} - -	bool operator==(const LLPathParams ¶ms) const; -	bool operator!=(const LLPathParams ¶ms) const; -	bool operator<(const LLPathParams ¶ms) const; - -	void copyParams(const LLPathParams ¶ms); - -	BOOL importFile(LLFILE *fp); -	BOOL exportFile(LLFILE *fp) const; - -	BOOL importLegacyStream(std::istream& input_stream); -	BOOL exportLegacyStream(std::ostream& output_stream) const; - -	LLSD asLLSD() const; -	operator LLSD() const { return asLLSD(); } -	bool fromLLSD(LLSD& sd); - -	const F32& getBegin() const			{ return mBegin; } -	const F32& getEnd() const			{ return mEnd; } -	const LLVector2 &getScale() const	{ return mScale; } -	const F32& getScaleX() const		{ return mScale.mV[0]; } -	const F32& getScaleY() const		{ return mScale.mV[1]; } -	const LLVector2 getBeginScale() const; -	const LLVector2 getEndScale() const; -	const LLVector2 &getShear() const	{ return mShear; } -	const F32& getShearX() const		{ return mShear.mV[0]; } -	const F32& getShearY() const		{ return mShear.mV[1]; } -	const U8& getCurveType () const		{ return mCurveType; } - -	const F32& getTwistBegin() const	{ return mTwistBegin;	} -	const F32& getTwistEnd() const		{ return mTwistEnd;	} -	const F32& getTwist() const			{ return mTwistEnd; }	// deprecated -	const F32& getRadiusOffset() const	{ return mRadiusOffset; } -	const LLVector2 &getTaper() const	{ return mTaper;		} -	const F32& getTaperX() const		{ return mTaper.mV[0];	} -	const F32& getTaperY() const		{ return mTaper.mV[1];	} -	const F32& getRevolutions() const	{ return mRevolutions;	} -	const F32& getSkew() const			{ return mSkew;			} - -	void setCurveType(const U8 type)	{ mCurveType = type;	} -	void setBegin(const F32 begin)		{ mBegin     = begin;	} -	void setEnd(const F32 end)			{ mEnd       = end;	} - -	void setScale(const F32 x, const F32 y)		{ mScale.setVec(x,y); } -	void setScaleX(const F32 v)					{ mScale.mV[VX] = v; } -	void setScaleY(const F32 v)					{ mScale.mV[VY] = v; } -	void setShear(const F32 x, const F32 y)		{ mShear.setVec(x,y); } -	void setShearX(const F32 v)					{ mShear.mV[VX] = v; } -	void setShearY(const F32 v)					{ mShear.mV[VY] = v; } - -	void setTwistBegin(const F32 twist_begin)	{ mTwistBegin	= twist_begin;	} -	void setTwistEnd(const F32 twist_end)		{ mTwistEnd		= twist_end;	} -	void setTwist(const F32 twist)				{ setTwistEnd(twist); }	// deprecated -	void setRadiusOffset(const F32 radius_offset){ mRadiusOffset	= radius_offset; } -	void setTaper(const F32 x, const F32 y)		{ mTaper.setVec(x,y);			} -	void setTaperX(const F32 v)					{ mTaper.mV[VX]	= v;			} -	void setTaperY(const F32 v)					{ mTaper.mV[VY]	= v;			} -	void setRevolutions(const F32 revolutions)	{ mRevolutions	= revolutions;	} -	void setSkew(const F32 skew)				{ mSkew			= skew;			} - -	friend std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params); +    LLPathParams() +        : +        mCurveType(LL_PCODE_PATH_LINE), +        mBegin(0.f), +        mEnd(1.f), +        mScale(1.f,1.f), +        mShear(0.f,0.f), +        mTwistBegin(0.f), +        mTwistEnd(0.f), +        mRadiusOffset(0.f), +        mTaper(0.f,0.f), +        mRevolutions(1.f), +        mSkew(0.f), +        mCRC(0) +    { +    } + +    LLPathParams(U8 curve, F32 begin, F32 end, F32 scx, F32 scy, F32 shx, F32 shy, F32 twistend, F32 twistbegin, F32 radiusoffset, F32 tx, F32 ty, F32 revolutions, F32 skew) +        : mCurveType(curve), +          mBegin(begin), +          mEnd(end), +          mScale(scx,scy), +          mShear(shx,shy), +          mTwistBegin(twistbegin), +          mTwistEnd(twistend), +          mRadiusOffset(radiusoffset), +          mTaper(tx,ty), +          mRevolutions(revolutions), +          mSkew(skew), +          mCRC(0) +    { +    } + +    LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew) +    { +        mCurveType = curve; +        mBegin = (F32)(begin * CUT_QUANTA); +        mEnd = (F32)(100.f - end) * CUT_QUANTA; +        if (mEnd > 1.f) +            mEnd = 1.f; +        mScale.setVec((F32) (200 - scx) * SCALE_QUANTA,(F32) (200 - scy) * SCALE_QUANTA); +        mShear.setVec(U8_TO_F32(shx) * SHEAR_QUANTA,U8_TO_F32(shy) * SHEAR_QUANTA); +        mTwistBegin = U8_TO_F32(twistbegin) * SCALE_QUANTA; +        mTwistEnd = U8_TO_F32(twistend) * SCALE_QUANTA; +        mRadiusOffset = U8_TO_F32(radiusoffset) * SCALE_QUANTA; +        mTaper.setVec(U8_TO_F32(tx) * TAPER_QUANTA,U8_TO_F32(ty) * TAPER_QUANTA); +        mRevolutions = ((F32)revolutions) * REV_QUANTA + 1.0f; +        mSkew = U8_TO_F32(skew) * SCALE_QUANTA; + +        mCRC = 0; +    } + +    bool operator==(const LLPathParams ¶ms) const; +    bool operator!=(const LLPathParams ¶ms) const; +    bool operator<(const LLPathParams ¶ms) const; + +    void copyParams(const LLPathParams ¶ms); + +    BOOL importFile(LLFILE *fp); +    BOOL exportFile(LLFILE *fp) const; + +    BOOL importLegacyStream(std::istream& input_stream); +    BOOL exportLegacyStream(std::ostream& output_stream) const; + +    LLSD asLLSD() const; +    operator LLSD() const { return asLLSD(); } +    bool fromLLSD(LLSD& sd); + +    const F32& getBegin() const         { return mBegin; } +    const F32& getEnd() const           { return mEnd; } +    const LLVector2 &getScale() const   { return mScale; } +    const F32& getScaleX() const        { return mScale.mV[0]; } +    const F32& getScaleY() const        { return mScale.mV[1]; } +    const LLVector2 getBeginScale() const; +    const LLVector2 getEndScale() const; +    const LLVector2 &getShear() const   { return mShear; } +    const F32& getShearX() const        { return mShear.mV[0]; } +    const F32& getShearY() const        { return mShear.mV[1]; } +    const U8& getCurveType () const     { return mCurveType; } + +    const F32& getTwistBegin() const    { return mTwistBegin;   } +    const F32& getTwistEnd() const      { return mTwistEnd; } +    const F32& getTwist() const         { return mTwistEnd; }   // deprecated +    const F32& getRadiusOffset() const  { return mRadiusOffset; } +    const LLVector2 &getTaper() const   { return mTaper;        } +    const F32& getTaperX() const        { return mTaper.mV[0];  } +    const F32& getTaperY() const        { return mTaper.mV[1];  } +    const F32& getRevolutions() const   { return mRevolutions;  } +    const F32& getSkew() const          { return mSkew;         } + +    void setCurveType(const U8 type)    { mCurveType = type;    } +    void setBegin(const F32 begin)      { mBegin     = begin;   } +    void setEnd(const F32 end)          { mEnd       = end; } + +    void setScale(const F32 x, const F32 y)     { mScale.setVec(x,y); } +    void setScaleX(const F32 v)                 { mScale.mV[VX] = v; } +    void setScaleY(const F32 v)                 { mScale.mV[VY] = v; } +    void setShear(const F32 x, const F32 y)     { mShear.setVec(x,y); } +    void setShearX(const F32 v)                 { mShear.mV[VX] = v; } +    void setShearY(const F32 v)                 { mShear.mV[VY] = v; } + +    void setTwistBegin(const F32 twist_begin)   { mTwistBegin   = twist_begin;  } +    void setTwistEnd(const F32 twist_end)       { mTwistEnd     = twist_end;    } +    void setTwist(const F32 twist)              { setTwistEnd(twist); } // deprecated +    void setRadiusOffset(const F32 radius_offset){ mRadiusOffset    = radius_offset; } +    void setTaper(const F32 x, const F32 y)     { mTaper.setVec(x,y);           } +    void setTaperX(const F32 v)                 { mTaper.mV[VX] = v;            } +    void setTaperY(const F32 v)                 { mTaper.mV[VY] = v;            } +    void setRevolutions(const F32 revolutions)  { mRevolutions  = revolutions;  } +    void setSkew(const F32 skew)                { mSkew         = skew;         } + +    friend std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params);  protected: -	// Path params -	U8			  mCurveType; -	F32           mBegin; -	F32           mEnd; -	LLVector2	  mScale; -	LLVector2     mShear; - -	F32			  mTwistBegin; -	F32			  mTwistEnd; -	F32			  mRadiusOffset; -	LLVector2	  mTaper; -	F32			  mRevolutions; -	F32			  mSkew; - -	U32           mCRC; +    // Path params +    U8            mCurveType; +    F32           mBegin; +    F32           mEnd; +    LLVector2     mScale; +    LLVector2     mShear; + +    F32           mTwistBegin; +    F32           mTwistEnd; +    F32           mRadiusOffset; +    LLVector2     mTaper; +    F32           mRevolutions; +    F32           mSkew; + +    U32           mCRC;  };  inline bool LLPathParams::operator==(const LLPathParams ¶ms) const  { -	return -		(getCurveType() == params.getCurveType()) &&  -		(getScale() == params.getScale()) && -		(getBegin() == params.getBegin()) &&  -		(getEnd() == params.getEnd()) &&  -		(getShear() == params.getShear()) && -		(getTwist() == params.getTwist()) && -		(getTwistBegin() == params.getTwistBegin()) && -		(getRadiusOffset() == params.getRadiusOffset()) && -		(getTaper() == params.getTaper()) && -		(getRevolutions() == params.getRevolutions()) && -		(getSkew() == params.getSkew()); +    return +        (getCurveType() == params.getCurveType()) && +        (getScale() == params.getScale()) && +        (getBegin() == params.getBegin()) && +        (getEnd() == params.getEnd()) && +        (getShear() == params.getShear()) && +        (getTwist() == params.getTwist()) && +        (getTwistBegin() == params.getTwistBegin()) && +        (getRadiusOffset() == params.getRadiusOffset()) && +        (getTaper() == params.getTaper()) && +        (getRevolutions() == params.getRevolutions()) && +        (getSkew() == params.getSkew());  }  inline bool LLPathParams::operator!=(const LLPathParams ¶ms) const  { -	return -		(getCurveType() != params.getCurveType()) || -		(getScale() != params.getScale()) || -		(getBegin() != params.getBegin()) ||  -		(getEnd() != params.getEnd()) ||  -		(getShear() != params.getShear()) || -		(getTwist() != params.getTwist()) || -		(getTwistBegin() !=params.getTwistBegin()) || -		(getRadiusOffset() != params.getRadiusOffset()) || -		(getTaper() != params.getTaper()) || -		(getRevolutions() != params.getRevolutions()) || -		(getSkew() != params.getSkew()); +    return +        (getCurveType() != params.getCurveType()) || +        (getScale() != params.getScale()) || +        (getBegin() != params.getBegin()) || +        (getEnd() != params.getEnd()) || +        (getShear() != params.getShear()) || +        (getTwist() != params.getTwist()) || +        (getTwistBegin() !=params.getTwistBegin()) || +        (getRadiusOffset() != params.getRadiusOffset()) || +        (getTaper() != params.getTaper()) || +        (getRevolutions() != params.getRevolutions()) || +        (getSkew() != params.getSkew());  }  inline bool LLPathParams::operator<(const LLPathParams ¶ms) const  { -	if( getCurveType() != params.getCurveType())  -	{ -		return getCurveType() < params.getCurveType(); -	} -	else -	if( getScale() != params.getScale())  -	{ -		return getScale() < params.getScale(); -	} -	else -	if( getBegin() != params.getBegin())  -	{ -		return getBegin() < params.getBegin(); -	} -	else -	if( getEnd() != params.getEnd())  -	{ -		return getEnd() < params.getEnd(); -	} -	else -	if( getShear() != params.getShear())  -	{ -		return getShear() < params.getShear(); -	} -	else -	if( getTwist() != params.getTwist()) -	{ -		return getTwist() < params.getTwist(); -	} -	else -	if( getTwistBegin() != params.getTwistBegin()) -	{ -		return getTwistBegin() < params.getTwistBegin(); -	} -	else -	if( getRadiusOffset() != params.getRadiusOffset()) -	{ -		return getRadiusOffset() < params.getRadiusOffset(); -	} -	else -	if( getTaper() != params.getTaper()) -	{ -		return getTaper() < params.getTaper(); -	} -	else -	if( getRevolutions() != params.getRevolutions()) -	{ -		return getRevolutions() < params.getRevolutions(); -	} -	else -	{ -		return getSkew() < params.getSkew(); -	} +    if( getCurveType() != params.getCurveType()) +    { +        return getCurveType() < params.getCurveType(); +    } +    else +    if( getScale() != params.getScale()) +    { +        return getScale() < params.getScale(); +    } +    else +    if( getBegin() != params.getBegin()) +    { +        return getBegin() < params.getBegin(); +    } +    else +    if( getEnd() != params.getEnd()) +    { +        return getEnd() < params.getEnd(); +    } +    else +    if( getShear() != params.getShear()) +    { +        return getShear() < params.getShear(); +    } +    else +    if( getTwist() != params.getTwist()) +    { +        return getTwist() < params.getTwist(); +    } +    else +    if( getTwistBegin() != params.getTwistBegin()) +    { +        return getTwistBegin() < params.getTwistBegin(); +    } +    else +    if( getRadiusOffset() != params.getRadiusOffset()) +    { +        return getRadiusOffset() < params.getRadiusOffset(); +    } +    else +    if( getTaper() != params.getTaper()) +    { +        return getTaper() < params.getTaper(); +    } +    else +    if( getRevolutions() != params.getRevolutions()) +    { +        return getRevolutions() < params.getRevolutions(); +    } +    else +    { +        return getSkew() < params.getSkew(); +    }  }  typedef LLVolumeParams* LLVolumeParamsPtr; @@ -559,190 +559,190 @@ typedef const LLVolumeParams* const_LLVolumeParamsPtr;  class LLVolumeParams  {  public: -	LLVolumeParams() -		: mSculptType(LL_SCULPT_TYPE_NONE) -	{ -	} - -	LLVolumeParams(LLProfileParams &profile, LLPathParams &path, -				   LLUUID sculpt_id = LLUUID::null, U8 sculpt_type = LL_SCULPT_TYPE_NONE) -		: mProfileParams(profile), mPathParams(path), mSculptID(sculpt_id), mSculptType(sculpt_type) -	{ -	} - -	bool operator==(const LLVolumeParams ¶ms) const; -	bool operator!=(const LLVolumeParams ¶ms) const; -	bool operator<(const LLVolumeParams ¶ms) const; - - -	void copyParams(const LLVolumeParams ¶ms); -	 -	const LLProfileParams &getProfileParams() const {return mProfileParams;} -	LLProfileParams &getProfileParams() {return mProfileParams;} -	const LLPathParams &getPathParams() const {return mPathParams;} -	LLPathParams &getPathParams() {return mPathParams;} - -	BOOL importFile(LLFILE *fp); -	BOOL exportFile(LLFILE *fp) const; - -	BOOL importLegacyStream(std::istream& input_stream); -	BOOL exportLegacyStream(std::ostream& output_stream) const; - -	LLSD sculptAsLLSD() const; -	bool sculptFromLLSD(LLSD& sd); -	 -	LLSD asLLSD() const; -	operator LLSD() const { return asLLSD(); } -	bool fromLLSD(LLSD& sd); - -	bool setType(U8 profile, U8 path); - -	//void setBeginS(const F32 beginS)			{ mProfileParams.setBegin(beginS); }	// range 0 to 1 -	//void setBeginT(const F32 beginT)			{ mPathParams.setBegin(beginT); }		// range 0 to 1 -	//void setEndS(const F32 endS)				{ mProfileParams.setEnd(endS); }		// range 0 to 1, must be greater than begin -	//void setEndT(const F32 endT)				{ mPathParams.setEnd(endT); }			// range 0 to 1, must be greater than begin - -	bool setBeginAndEndS(const F32 begin, const F32 end);			// both range from 0 to 1, begin must be less than end -	bool setBeginAndEndT(const F32 begin, const F32 end);			// both range from 0 to 1, begin must be less than end - -	bool setHollow(const F32 hollow);	// range 0 to 1 -	bool setRatio(const F32 x)					{ return setRatio(x,x); }			// 0 = point, 1 = same as base -	bool setShear(const F32 x)					{ return setShear(x,x); }			// 0 = no movement,  -	bool setRatio(const F32 x, const F32 y);			// 0 = point, 1 = same as base -	bool setShear(const F32 x, const F32 y);			// 0 = no movement - -	bool setTwistBegin(const F32 twist_begin);	// range -1 to 1 -	bool setTwistEnd(const F32 twist_end);		// range -1 to 1 -	bool setTwist(const F32 twist)				{ return setTwistEnd(twist); }		// deprecated -	bool setTaper(const F32 x, const F32 y)		{ bool pass_x = setTaperX(x); bool pass_y = setTaperY(y); return pass_x && pass_y; } -	bool setTaperX(const F32 v);				// -1 to 1 -	bool setTaperY(const F32 v);				// -1 to 1 -	bool setRevolutions(const F32 revolutions);	// 1 to 4 -	bool setRadiusOffset(const F32 radius_offset); -	bool setSkew(const F32 skew); -	bool setSculptID(const LLUUID sculpt_id, U8 sculpt_type); - -	static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow, -		U8 path_curve, F32 path_begin, F32 path_end, -		F32 scx, F32 scy, F32 shx, F32 shy, -		F32 twistend, F32 twistbegin, F32 radiusoffset, -		F32 tx, F32 ty, F32 revolutions, F32 skew); -	 -	const F32&  getBeginS() 	const	{ return mProfileParams.getBegin(); } - 	const F32&  getBeginT() 	const	{ return mPathParams.getBegin(); } - 	const F32&  getEndS() 		const	{ return mProfileParams.getEnd(); } - 	const F32&  getEndT() 		const	{ return mPathParams.getEnd(); } -  - 	const F32&  getHollow() 	const   { return mProfileParams.getHollow(); } - 	const F32&  getTwist() 	const   	{ return mPathParams.getTwist(); } - 	const F32&  getRatio() 	const		{ return mPathParams.getScaleX(); } - 	const F32&  getRatioX() 	const   { return mPathParams.getScaleX(); } - 	const F32&  getRatioY() 	const   { return mPathParams.getScaleY(); } - 	const F32&  getShearX() 	const   { return mPathParams.getShearX(); } - 	const F32&  getShearY() 	const   { return mPathParams.getShearY(); } - -	const F32&	getTwistBegin()const	{ return mPathParams.getTwistBegin();	} -	const F32&  getRadiusOffset() const	{ return mPathParams.getRadiusOffset();	} -	const F32&  getTaper() const		{ return mPathParams.getTaperX();		} -	const F32&	getTaperX() const		{ return mPathParams.getTaperX();		} -	const F32&  getTaperY() const		{ return mPathParams.getTaperY();		} -	const F32&  getRevolutions() const	{ return mPathParams.getRevolutions();	} -	const F32&  getSkew() const			{ return mPathParams.getSkew();			} -	const LLUUID& getSculptID() const	{ return mSculptID;						} -	const U8& getSculptType() const     { return mSculptType;                   } -	bool isSculpt() const; -	bool isMeshSculpt() const; -	BOOL isConvex() const; - -	// 'begin' and 'end' should be in range [0, 1] (they will be clamped) -	// (begin, end) = (0, 1) will not change the volume -	// (begin, end) = (0, 0.5) will reduce the volume to the first half of its profile/path (S/T) -	void reduceS(F32 begin, F32 end); -	void reduceT(F32 begin, F32 end); - -	struct compare -	{ -		bool operator()( const const_LLVolumeParamsPtr& first, const const_LLVolumeParamsPtr& second) const -		{ -			return (*first < *second); -		} -	}; -	 -	friend std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); - -	// debug helper functions -	void setCube(); +    LLVolumeParams() +        : mSculptType(LL_SCULPT_TYPE_NONE) +    { +    } + +    LLVolumeParams(LLProfileParams &profile, LLPathParams &path, +                   LLUUID sculpt_id = LLUUID::null, U8 sculpt_type = LL_SCULPT_TYPE_NONE) +        : mProfileParams(profile), mPathParams(path), mSculptID(sculpt_id), mSculptType(sculpt_type) +    { +    } + +    bool operator==(const LLVolumeParams ¶ms) const; +    bool operator!=(const LLVolumeParams ¶ms) const; +    bool operator<(const LLVolumeParams ¶ms) const; + + +    void copyParams(const LLVolumeParams ¶ms); + +    const LLProfileParams &getProfileParams() const {return mProfileParams;} +    LLProfileParams &getProfileParams() {return mProfileParams;} +    const LLPathParams &getPathParams() const {return mPathParams;} +    LLPathParams &getPathParams() {return mPathParams;} + +    BOOL importFile(LLFILE *fp); +    BOOL exportFile(LLFILE *fp) const; + +    BOOL importLegacyStream(std::istream& input_stream); +    BOOL exportLegacyStream(std::ostream& output_stream) const; + +    LLSD sculptAsLLSD() const; +    bool sculptFromLLSD(LLSD& sd); + +    LLSD asLLSD() const; +    operator LLSD() const { return asLLSD(); } +    bool fromLLSD(LLSD& sd); + +    bool setType(U8 profile, U8 path); + +    //void setBeginS(const F32 beginS)          { mProfileParams.setBegin(beginS); }    // range 0 to 1 +    //void setBeginT(const F32 beginT)          { mPathParams.setBegin(beginT); }       // range 0 to 1 +    //void setEndS(const F32 endS)              { mProfileParams.setEnd(endS); }        // range 0 to 1, must be greater than begin +    //void setEndT(const F32 endT)              { mPathParams.setEnd(endT); }           // range 0 to 1, must be greater than begin + +    bool setBeginAndEndS(const F32 begin, const F32 end);           // both range from 0 to 1, begin must be less than end +    bool setBeginAndEndT(const F32 begin, const F32 end);           // both range from 0 to 1, begin must be less than end + +    bool setHollow(const F32 hollow);   // range 0 to 1 +    bool setRatio(const F32 x)                  { return setRatio(x,x); }           // 0 = point, 1 = same as base +    bool setShear(const F32 x)                  { return setShear(x,x); }           // 0 = no movement, +    bool setRatio(const F32 x, const F32 y);            // 0 = point, 1 = same as base +    bool setShear(const F32 x, const F32 y);            // 0 = no movement + +    bool setTwistBegin(const F32 twist_begin);  // range -1 to 1 +    bool setTwistEnd(const F32 twist_end);      // range -1 to 1 +    bool setTwist(const F32 twist)              { return setTwistEnd(twist); }      // deprecated +    bool setTaper(const F32 x, const F32 y)     { bool pass_x = setTaperX(x); bool pass_y = setTaperY(y); return pass_x && pass_y; } +    bool setTaperX(const F32 v);                // -1 to 1 +    bool setTaperY(const F32 v);                // -1 to 1 +    bool setRevolutions(const F32 revolutions); // 1 to 4 +    bool setRadiusOffset(const F32 radius_offset); +    bool setSkew(const F32 skew); +    bool setSculptID(const LLUUID sculpt_id, U8 sculpt_type); + +    static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow, +        U8 path_curve, F32 path_begin, F32 path_end, +        F32 scx, F32 scy, F32 shx, F32 shy, +        F32 twistend, F32 twistbegin, F32 radiusoffset, +        F32 tx, F32 ty, F32 revolutions, F32 skew); + +    const F32&  getBeginS()     const   { return mProfileParams.getBegin(); } +    const F32&  getBeginT()     const   { return mPathParams.getBegin(); } +    const F32&  getEndS()       const   { return mProfileParams.getEnd(); } +    const F32&  getEndT()       const   { return mPathParams.getEnd(); } + +    const F32&  getHollow()     const   { return mProfileParams.getHollow(); } +    const F32&  getTwist()  const       { return mPathParams.getTwist(); } +    const F32&  getRatio()  const       { return mPathParams.getScaleX(); } +    const F32&  getRatioX()     const   { return mPathParams.getScaleX(); } +    const F32&  getRatioY()     const   { return mPathParams.getScaleY(); } +    const F32&  getShearX()     const   { return mPathParams.getShearX(); } +    const F32&  getShearY()     const   { return mPathParams.getShearY(); } + +    const F32&  getTwistBegin()const    { return mPathParams.getTwistBegin();   } +    const F32&  getRadiusOffset() const { return mPathParams.getRadiusOffset(); } +    const F32&  getTaper() const        { return mPathParams.getTaperX();       } +    const F32&  getTaperX() const       { return mPathParams.getTaperX();       } +    const F32&  getTaperY() const       { return mPathParams.getTaperY();       } +    const F32&  getRevolutions() const  { return mPathParams.getRevolutions();  } +    const F32&  getSkew() const         { return mPathParams.getSkew();         } +    const LLUUID& getSculptID() const   { return mSculptID;                     } +    const U8& getSculptType() const     { return mSculptType;                   } +    bool isSculpt() const; +    bool isMeshSculpt() const; +    BOOL isConvex() const; + +    // 'begin' and 'end' should be in range [0, 1] (they will be clamped) +    // (begin, end) = (0, 1) will not change the volume +    // (begin, end) = (0, 0.5) will reduce the volume to the first half of its profile/path (S/T) +    void reduceS(F32 begin, F32 end); +    void reduceT(F32 begin, F32 end); + +    struct compare +    { +        bool operator()( const const_LLVolumeParamsPtr& first, const const_LLVolumeParamsPtr& second) const +        { +            return (*first < *second); +        } +    }; + +    friend std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); + +    // debug helper functions +    void setCube();  protected: -	LLProfileParams mProfileParams; -	LLPathParams	mPathParams; -	LLUUID mSculptID; -	U8 mSculptType; +    LLProfileParams mProfileParams; +    LLPathParams    mPathParams; +    LLUUID mSculptID; +    U8 mSculptType;  };  class LLProfile  { -	friend class LLVolume; +    friend class LLVolume;  public: -	LLProfile() -		: mOpen(FALSE), -		  mConcave(FALSE), -		  mDirty(TRUE), -		  mTotalOut(0), -		  mTotal(2) -	{ -	} - -	S32	 getTotal() const								{ return mTotal; } -	S32	 getTotalOut() const							{ return mTotalOut; }	// Total number of outside points -	BOOL isFlat(S32 face) const							{ return (mFaces[face].mCount == 2); } -	BOOL isOpen() const									{ return mOpen; } -	void setDirty()										{ mDirty     = TRUE; } - -	static S32 getNumPoints(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, -				  BOOL is_sculpted = FALSE, S32 sculpt_size = 0); -	BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, -				  BOOL is_sculpted = FALSE, S32 sculpt_size = 0); -	BOOL isConcave() const								{ return mConcave; } +    LLProfile() +        : mOpen(FALSE), +          mConcave(FALSE), +          mDirty(TRUE), +          mTotalOut(0), +          mTotal(2) +    { +    } + +    S32  getTotal() const                               { return mTotal; } +    S32  getTotalOut() const                            { return mTotalOut; }   // Total number of outside points +    BOOL isFlat(S32 face) const                         { return (mFaces[face].mCount == 2); } +    BOOL isOpen() const                                 { return mOpen; } +    void setDirty()                                     { mDirty     = TRUE; } + +    static S32 getNumPoints(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, +                  BOOL is_sculpted = FALSE, S32 sculpt_size = 0); +    BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, +                  BOOL is_sculpted = FALSE, S32 sculpt_size = 0); +    BOOL isConcave() const                              { return mConcave; }  public: -	struct Face -	{ -		S32       mIndex; -		S32       mCount; -		F32       mScaleU; -		BOOL      mCap; -		BOOL      mFlat; -		LLFaceID  mFaceID; -	}; -	 -	LLAlignedArray<LLVector4a, 64> mProfile;	 -	//LLAlignedArray<LLVector4a, 64> mNormals; -	std::vector<Face>      mFaces; - -	//LLAlignedArray<LLVector4a, 64> mEdgeNormals; -	//LLAlignedArray<LLVector4a, 64> mEdgeCenters; - -	friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile); +    struct Face +    { +        S32       mIndex; +        S32       mCount; +        F32       mScaleU; +        BOOL      mCap; +        BOOL      mFlat; +        LLFaceID  mFaceID; +    }; + +    LLAlignedArray<LLVector4a, 64> mProfile; +    //LLAlignedArray<LLVector4a, 64> mNormals; +    std::vector<Face>      mFaces; + +    //LLAlignedArray<LLVector4a, 64> mEdgeNormals; +    //LLAlignedArray<LLVector4a, 64> mEdgeCenters; + +    friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);  protected: -	~LLProfile(); +    ~LLProfile(); -	static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); -	void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); +    static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); +    void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); -	Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0); -	Face* addCap (S16 faceID); -	Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat); +    Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0); +    Face* addCap (S16 faceID); +    Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat);  protected: -	BOOL		  mOpen; -	BOOL		  mConcave; -	BOOL          mDirty; +    BOOL          mOpen; +    BOOL          mConcave; +    BOOL          mDirty; -	S32			  mTotalOut; -	S32			  mTotal; +    S32           mTotalOut; +    S32           mTotal;  };  //------------------------------------------------------------------- @@ -752,220 +752,220 @@ protected:  class LLPath  {  public: -	class PathPt -	{ -	public: -		LLMatrix4a   mRot; -		LLVector4a	 mPos; -		 -		LLVector4a   mScale; -		F32			 mTexT; -		F32 pad[3]; //for alignment -		PathPt()  -		{  -			mPos.clear();  -			mTexT = 0;  -			mScale.clear();  -			mRot.setRows(LLVector4a(1,0,0,0), -						LLVector4a(0,1,0,0), -						LLVector4a(0,0,1,0)); - -			//distinguished data in the pad for debugging -			pad[0] = 3.14159f; -			pad[1] = -3.14159f; -			pad[2] = 0.585f; -		} -	}; +    class PathPt +    { +    public: +        LLMatrix4a   mRot; +        LLVector4a   mPos; + +        LLVector4a   mScale; +        F32          mTexT; +        F32 pad[3]; //for alignment +        PathPt() +        { +            mPos.clear(); +            mTexT = 0; +            mScale.clear(); +            mRot.setRows(LLVector4a(1,0,0,0), +                        LLVector4a(0,1,0,0), +                        LLVector4a(0,0,1,0)); + +            //distinguished data in the pad for debugging +            pad[0] = 3.14159f; +            pad[1] = -3.14159f; +            pad[2] = 0.585f; +        } +    };  public: -	LLPath() -		: mOpen(FALSE), -		  mTotal(0), -		  mDirty(TRUE), -		  mStep(1) -	{ -	} +    LLPath() +        : mOpen(FALSE), +          mTotal(0), +          mDirty(TRUE), +          mStep(1) +    { +    } -	virtual ~LLPath(); +    virtual ~LLPath(); -	static S32 getNumPoints(const LLPathParams& params, F32 detail); -	static S32 getNumNGonPoints(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); +    static S32 getNumPoints(const LLPathParams& params, F32 detail); +    static S32 getNumNGonPoints(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); -	void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); -	virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, -						  BOOL is_sculpted = FALSE, S32 sculpt_size = 0); +    void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); +    virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, +                          BOOL is_sculpted = FALSE, S32 sculpt_size = 0); -	BOOL isOpen() const						{ return mOpen; } -	F32 getStep() const						{ return mStep; } -	void setDirty()							{ mDirty     = TRUE; } +    BOOL isOpen() const                     { return mOpen; } +    F32 getStep() const                     { return mStep; } +    void setDirty()                         { mDirty     = TRUE; } -	S32 getPathLength() const				{ return (S32)mPath.size(); } +    S32 getPathLength() const               { return (S32)mPath.size(); } -	void resizePath(S32 length) { mPath.resize(length); } +    void resizePath(S32 length) { mPath.resize(length); } -	friend std::ostream& operator<<(std::ostream &s, const LLPath &path); +    friend std::ostream& operator<<(std::ostream &s, const LLPath &path);  public: -	LLAlignedArray<PathPt, 64> mPath; +    LLAlignedArray<PathPt, 64> mPath;  protected: -	BOOL		  mOpen; -	S32			  mTotal; -	BOOL          mDirty; -	F32           mStep; +    BOOL          mOpen; +    S32           mTotal; +    BOOL          mDirty; +    F32           mStep;  };  class LLDynamicPath : public LLPath  {  public: -	LLDynamicPath() : LLPath() { } -	/*virtual*/ BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, -							  BOOL is_sculpted = FALSE, S32 sculpt_size = 0); +    LLDynamicPath() : LLPath() { } +    /*virtual*/ BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, +                              BOOL is_sculpted = FALSE, S32 sculpt_size = 0);  };  // Yet another "face" class - caches volume-specific, but not instance-specific data for faces)  class LLVolumeFace  {  public: -	class VertexData -	{ -		enum  -		{ -			POSITION = 0, -			NORMAL = 1 -		}; - -	private: -		void init(); -	public: -		VertexData(); -		VertexData(const VertexData& rhs); -		const VertexData& operator=(const VertexData& rhs); - -		~VertexData(); -		LLVector4a& getPosition(); -		LLVector4a& getNormal(); -		const LLVector4a& getPosition() const; -		const LLVector4a& getNormal() const; -		void setPosition(const LLVector4a& pos); -		void setNormal(const LLVector4a& norm); -		 - -		LLVector2 mTexCoord; - -		bool operator<(const VertexData& rhs) const; -		bool operator==(const VertexData& rhs) const; -		bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; - -	private: -		LLVector4a* mData; -	}; - -	LLVolumeFace(); -	LLVolumeFace(const LLVolumeFace& src); -	LLVolumeFace& operator=(const LLVolumeFace& rhs); - -	~LLVolumeFace(); +    class VertexData +    { +        enum +        { +            POSITION = 0, +            NORMAL = 1 +        }; + +    private: +        void init(); +    public: +        VertexData(); +        VertexData(const VertexData& rhs); +        const VertexData& operator=(const VertexData& rhs); + +        ~VertexData(); +        LLVector4a& getPosition(); +        LLVector4a& getNormal(); +        const LLVector4a& getPosition() const; +        const LLVector4a& getNormal() const; +        void setPosition(const LLVector4a& pos); +        void setNormal(const LLVector4a& norm); + + +        LLVector2 mTexCoord; + +        bool operator<(const VertexData& rhs) const; +        bool operator==(const VertexData& rhs) const; +        bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; + +    private: +        LLVector4a* mData; +    }; + +    LLVolumeFace(); +    LLVolumeFace(const LLVolumeFace& src); +    LLVolumeFace& operator=(const LLVolumeFace& rhs); + +    ~LLVolumeFace();  private: -	void freeData(); +    void freeData();  public: -	BOOL create(LLVolume* volume, BOOL partial_build = FALSE); -	void createTangents(); -	 -	void resizeVertices(S32 num_verts); -	void allocateTangents(S32 num_verts); -	void allocateWeights(S32 num_verts); +    BOOL create(LLVolume* volume, BOOL partial_build = FALSE); +    void createTangents(); + +    void resizeVertices(S32 num_verts); +    void allocateTangents(S32 num_verts); +    void allocateWeights(S32 num_verts);      void allocateJointIndices(S32 num_verts); -	void resizeIndices(S32 num_indices); -	void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx); +    void resizeIndices(S32 num_indices); +    void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx); -	void pushVertex(const VertexData& cv); -	void pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc); -	void pushIndex(const U16& idx); +    void pushVertex(const VertexData& cv); +    void pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc); +    void pushIndex(const U16& idx); -	void swapData(LLVolumeFace& rhs); +    void swapData(LLVolumeFace& rhs); -	void getVertexData(U16 indx, LLVolumeFace::VertexData& cv); +    void getVertexData(U16 indx, LLVolumeFace::VertexData& cv); -	class VertexMapData : public LLVolumeFace::VertexData -	{ -	public: -		U16 mIndex; +    class VertexMapData : public LLVolumeFace::VertexData +    { +    public: +        U16 mIndex; -		bool operator==(const LLVolumeFace::VertexData& rhs) const; +        bool operator==(const LLVolumeFace::VertexData& rhs) const; -		struct ComparePosition -		{ -			bool operator()(const LLVector3& a, const LLVector3& b) const; -		}; +        struct ComparePosition +        { +            bool operator()(const LLVector3& a, const LLVector3& b) const; +        }; -		typedef std::map<LLVector3, std::vector<VertexMapData>, VertexMapData::ComparePosition > PointMap; -	}; +        typedef std::map<LLVector3, std::vector<VertexMapData>, VertexMapData::ComparePosition > PointMap; +    };      // Eliminates non unique triangles, takes positions,      // normals and texture coordinates into account.      void remap(); -	void optimize(F32 angle_cutoff = 2.f); -	bool cacheOptimize(bool gen_tangents = false); +    void optimize(F32 angle_cutoff = 2.f); +    bool cacheOptimize(bool gen_tangents = false); -	void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); +    void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f));      void destroyOctree();      // Get a reference to the octree, which may be null      const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* getOctree() const; -	enum -	{ -		SINGLE_MASK =	0x0001, -		CAP_MASK =		0x0002, -		END_MASK =		0x0004, -		SIDE_MASK =		0x0008, -		INNER_MASK =	0x0010, -		OUTER_MASK =	0x0020, -		HOLLOW_MASK =	0x0040, -		OPEN_MASK =		0x0080, -		FLAT_MASK =		0x0100, -		TOP_MASK =		0x0200, -		BOTTOM_MASK =	0x0400 -	}; -	 +    enum +    { +        SINGLE_MASK =   0x0001, +        CAP_MASK =      0x0002, +        END_MASK =      0x0004, +        SIDE_MASK =     0x0008, +        INNER_MASK =    0x0010, +        OUTER_MASK =    0x0020, +        HOLLOW_MASK =   0x0040, +        OPEN_MASK =     0x0080, +        FLAT_MASK =     0x0100, +        TOP_MASK =      0x0200, +        BOTTOM_MASK =   0x0400 +    }; +  public: -	S32 mID; -	U32 mTypeMask; -	 -	// Only used for INNER/OUTER faces -	S32 mBeginS; -	S32 mBeginT; -	S32 mNumS; -	S32 mNumT; - -	LLVector4a* mExtents; //minimum and maximum point of face -	LLVector4a* mCenter; -	LLVector2   mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face. - -	S32 mNumVertices; // num vertices == num normals == num texcoords -	S32 mNumAllocatedVertices; -	S32 mNumIndices; - -	LLVector4a* mPositions; // Contains vertices, nortmals and texcoords -	LLVector4a* mNormals; // pointer into mPositions -	LLVector4a* mTangents; -	LLVector2*  mTexCoords; // pointer into mPositions - -	// mIndices contains mNumIndices amount of elements. -	// It contains triangles, each 3 indices describe one triangle. +    S32 mID; +    U32 mTypeMask; + +    // Only used for INNER/OUTER faces +    S32 mBeginS; +    S32 mBeginT; +    S32 mNumS; +    S32 mNumT; + +    LLVector4a* mExtents; //minimum and maximum point of face +    LLVector4a* mCenter; +    LLVector2   mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face. + +    S32 mNumVertices; // num vertices == num normals == num texcoords +    S32 mNumAllocatedVertices; +    S32 mNumIndices; + +    LLVector4a* mPositions; // Contains vertices, nortmals and texcoords +    LLVector4a* mNormals; // pointer into mPositions +    LLVector4a* mTangents; +    LLVector2*  mTexCoords; // pointer into mPositions + +    // mIndices contains mNumIndices amount of elements. +    // It contains triangles, each 3 indices describe one triangle.      // If mIndices contains {0, 2, 3, 1, 2, 4}, it means there      // are two triangles {0, 2, 3} and {1, 2, 4} with values being      // indexes for mPositions/mNormals/mTexCoords -	U16* mIndices; +    U16* mIndices; -	std::vector<S32>	mEdge; +    std::vector<S32>    mEdge; -	//list of skin weights for rigged volumes -	// format is mWeights[vertex_index].mV[influence] = <joint_index>.<weight> -	// mWeights.size() should be empty or match mVertices.size()   -	LLVector4a* mWeights; +    //list of skin weights for rigged volumes +    // format is mWeights[vertex_index].mV[influence] = <joint_index>.<weight> +    // mWeights.size() should be empty or match mVertices.size() +    LLVector4a* mWeights;  #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS      LLVector4a* mJustWeights; @@ -978,8 +978,8 @@ public:      // vertices per joint.      LLJointRiggingInfoTab mJointRiggingInfoTab; -	//whether or not face has been cache optimized -	BOOL mOptimized; +    //whether or not face has been cache optimized +    BOOL mOptimized;      // if this is a mesh asset, scale and translation that were applied      // when encoding the source mesh into a unit cube @@ -990,154 +990,154 @@ private:      LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* mOctree;      LLVolumeTriangle* mOctreeTriangles; -	BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); -	BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); -	BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE); +    BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); +    BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); +    BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE);  };  class LLVolume : public LLRefCount  { -	friend class LLVolumeLODGroup; +    friend class LLVolumeLODGroup;  protected: -	virtual ~LLVolume(); // use unref +    virtual ~LLVolume(); // use unref  public: -	typedef std::vector<LLVolumeFace> face_list_t; -		 -	struct FaceParams -	{ -		LLFaceID mFaceID; -		S32 mBeginS; -		S32 mCountS; -		S32 mBeginT; -		S32 mCountT; -	}; - -	LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE); -	 -	U8 getProfileType()	const								{ return mParams.getProfileParams().getCurveType(); } -	U8 getPathType() const									{ return mParams.getPathParams().getCurveType(); } -	S32	getNumFaces() const; -	S32 getNumVolumeFaces() const							{ return mVolumeFaces.size(); } -	F32 getDetail() const									{ return mDetail; } -	F32 getSurfaceArea() const								{ return mSurfaceArea; } -	const LLVolumeParams& getParams() const					{ return mParams; } -	LLVolumeParams getCopyOfParams() const					{ return mParams; } -	const LLProfile& getProfile() const						{ return *mProfilep; } -	LLPath& getPath() const									{ return *mPathp; } -	void resizePath(S32 length); -	const LLAlignedArray<LLVector4a,64>&	getMesh() const				{ return mMesh; } -	const LLVector4a& getMeshPt(const U32 i) const			{ return mMesh[i]; } -	 - -	void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); } - -	void regen(); +    typedef std::vector<LLVolumeFace> face_list_t; + +    struct FaceParams +    { +        LLFaceID mFaceID; +        S32 mBeginS; +        S32 mCountS; +        S32 mBeginT; +        S32 mCountT; +    }; + +    LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE); + +    U8 getProfileType() const                               { return mParams.getProfileParams().getCurveType(); } +    U8 getPathType() const                                  { return mParams.getPathParams().getCurveType(); } +    S32 getNumFaces() const; +    S32 getNumVolumeFaces() const                           { return mVolumeFaces.size(); } +    F32 getDetail() const                                   { return mDetail; } +    F32 getSurfaceArea() const                              { return mSurfaceArea; } +    const LLVolumeParams& getParams() const                 { return mParams; } +    LLVolumeParams getCopyOfParams() const                  { return mParams; } +    const LLProfile& getProfile() const                     { return *mProfilep; } +    LLPath& getPath() const                                 { return *mPathp; } +    void resizePath(S32 length); +    const LLAlignedArray<LLVector4a,64>&    getMesh() const             { return mMesh; } +    const LLVector4a& getMeshPt(const U32 i) const          { return mMesh[i]; } + + +    void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); } + +    void regen();      void genTangents(S32 face); -	BOOL isConvex() const; -	BOOL isCap(S32 face); -	BOOL isFlat(S32 face); -	BOOL isUnique() const									{ return mUnique; } - -	S32 getSculptLevel() const                              { return mSculptLevel; } -	void setSculptLevel(S32 level)							{ mSculptLevel = level; } - -	 -	static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts); - -	S32 getNumTriangles(S32* vcount = NULL) const; - -	void generateSilhouetteVertices(std::vector<LLVector3> &vertices,  -									std::vector<LLVector3> &normals,  -									const LLVector3& view_vec, -									const LLMatrix4& mat, -									const LLMatrix3& norm_mat, -									S32 face_index); - -	//get the face index of the face that intersects with the given line segment at the point  -	//closest to start.  Moves end to the point of intersection.  Returns -1 if no intersection. -	//Line segment must be in volume space. -	S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, -							 S32 face = -1,                          // which face to check, -1 = ALL_SIDES -							 LLVector4a* intersection = NULL,         // return the intersection point -							 LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -							 LLVector4a* normal = NULL,               // return the surface normal at the intersection point -							 LLVector4a* tangent = NULL             // return the surface tangent at the intersection point -		); - -	LLFaceID generateFaceMask(); - -	BOOL isFaceMaskValid(LLFaceID face_mask); -	static S32 sNumMeshPoints; - -	friend std::ostream& operator<<(std::ostream &s, const LLVolume &volume); -	friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep);		// HACK to bypass Windoze confusion over  -																				// conversion if *(LLVolume*) to LLVolume& -	const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE -	 -	LLVolumeFace &getVolumeFace(const S32 f) {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE - -	face_list_t& getVolumeFaces() { return mVolumeFaces; } - -	U32					mFaceMask;			// bit array of which faces exist in this volume -	LLVector3			mLODScaleBias;		// vector for biasing LOD based on scale -	 -	void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder); -	void copyVolumeFaces(const LLVolume* volume); -	void copyFacesTo(std::vector<LLVolumeFace> &faces) const; -	void copyFacesFrom(const std::vector<LLVolumeFace> &faces); +    BOOL isConvex() const; +    BOOL isCap(S32 face); +    BOOL isFlat(S32 face); +    BOOL isUnique() const                                   { return mUnique; } + +    S32 getSculptLevel() const                              { return mSculptLevel; } +    void setSculptLevel(S32 level)                          { mSculptLevel = level; } + + +    static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts); + +    S32 getNumTriangles(S32* vcount = NULL) const; + +    void generateSilhouetteVertices(std::vector<LLVector3> &vertices, +                                    std::vector<LLVector3> &normals, +                                    const LLVector3& view_vec, +                                    const LLMatrix4& mat, +                                    const LLMatrix3& norm_mat, +                                    S32 face_index); + +    //get the face index of the face that intersects with the given line segment at the point +    //closest to start.  Moves end to the point of intersection.  Returns -1 if no intersection. +    //Line segment must be in volume space. +    S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, +                             S32 face = -1,                          // which face to check, -1 = ALL_SIDES +                             LLVector4a* intersection = NULL,         // return the intersection point +                             LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point +                             LLVector4a* normal = NULL,               // return the surface normal at the intersection point +                             LLVector4a* tangent = NULL             // return the surface tangent at the intersection point +        ); + +    LLFaceID generateFaceMask(); + +    BOOL isFaceMaskValid(LLFaceID face_mask); +    static S32 sNumMeshPoints; + +    friend std::ostream& operator<<(std::ostream &s, const LLVolume &volume); +    friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep);      // HACK to bypass Windoze confusion over +                                                                                // conversion if *(LLVolume*) to LLVolume& +    const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE + +    LLVolumeFace &getVolumeFace(const S32 f) {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE + +    face_list_t& getVolumeFaces() { return mVolumeFaces; } + +    U32                 mFaceMask;          // bit array of which faces exist in this volume +    LLVector3           mLODScaleBias;      // vector for biasing LOD based on scale + +    void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder); +    void copyVolumeFaces(const LLVolume* volume); +    void copyFacesTo(std::vector<LLVolumeFace> &faces) const; +    void copyFacesFrom(const std::vector<LLVolumeFace> &faces);      // use meshoptimizer to optimize index buffer for vertex shader cache      //  gen_tangents - if true, generate MikkTSpace tangents if needed before optimizing index buffer -	bool cacheOptimize(bool gen_tangents = false); +    bool cacheOptimize(bool gen_tangents = false);  private: -	void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); -	F32 sculptGetSurfaceArea(); -	void sculptGenerateEmptyPlaceholder(); -	void sculptGenerateSpherePlaceholder(); -	void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t); +    void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); +    F32 sculptGetSurfaceArea(); +    void sculptGenerateEmptyPlaceholder(); +    void sculptGenerateSpherePlaceholder(); +    void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t); + -	  protected: -	BOOL generate(); -	void createVolumeFaces(); +    BOOL generate(); +    void createVolumeFaces();  public: -	bool unpackVolumeFaces(std::istream& is, S32 size); -	bool unpackVolumeFaces(U8* in_data, S32 size); +    bool unpackVolumeFaces(std::istream& is, S32 size); +    bool unpackVolumeFaces(U8* in_data, S32 size);  private: -	bool unpackVolumeFacesInternal(const LLSD& mdl); +    bool unpackVolumeFacesInternal(const LLSD& mdl);  public: -	virtual void setMeshAssetLoaded(bool loaded); -	virtual bool isMeshAssetLoaded(); +    virtual void setMeshAssetLoaded(bool loaded); +    virtual bool isMeshAssetLoaded();      virtual void setMeshAssetUnavaliable(bool unavaliable);      virtual bool isMeshAssetUnavaliable();   protected: -	BOOL mUnique; -	F32 mDetail; -	S32 mSculptLevel; -	F32 mSurfaceArea; //unscaled surface area -	bool mIsMeshAssetLoaded; +    BOOL mUnique; +    F32 mDetail; +    S32 mSculptLevel; +    F32 mSurfaceArea; //unscaled surface area +    bool mIsMeshAssetLoaded;      bool mIsMeshAssetUnavaliable; -	 -	const LLVolumeParams mParams; -	LLPath *mPathp; -	LLProfile *mProfilep; -	LLAlignedArray<LLVector4a,64> mMesh; -	 -	 -	BOOL mGenerateSingleFace; -	face_list_t mVolumeFaces; + +    const LLVolumeParams mParams; +    LLPath *mPathp; +    LLProfile *mProfilep; +    LLAlignedArray<LLVector4a,64> mMesh; + + +    BOOL mGenerateSingleFace; +    face_list_t mVolumeFaces;  public: -	LLVector4a* mHullPoints; -	U16* mHullIndices; -	S32 mNumHullPoints; -	S32 mNumHullIndices; +    LLVector4a* mHullPoints; +    U16* mHullIndices; +    S32 mNumHullPoints; +    S32 mNumHullIndices;  };  std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); @@ -1147,13 +1147,13 @@ BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, con  BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size);  //BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, -//							F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided); +//                          F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);  BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, -							F32& intersection_a, F32& intersection_b, F32& intersection_t); +                            F32& intersection_a, F32& intersection_b, F32& intersection_t);  BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, -							F32& intersection_a, F32& intersection_b, F32& intersection_t); -	 -	 +                            F32& intersection_a, F32& intersection_b, F32& intersection_t); + +  #endif diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index 9399504529..6f82335b3f 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -1,24 +1,24 @@ -/**  +/**   * @file llvolumemgr.cpp   *   * $LicenseInfo:firstyear=2002&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -33,9 +33,9 @@ const F32 BASE_THRESHOLD = 0.03f;  //static  F32 LLVolumeLODGroup::mDetailThresholds[NUM_LODS] = {BASE_THRESHOLD, -													 2*BASE_THRESHOLD, -													 8*BASE_THRESHOLD, -													 100*BASE_THRESHOLD}; +                                                     2*BASE_THRESHOLD, +                                                     8*BASE_THRESHOLD, +                                                     100*BASE_THRESHOLD};  //static  F32 LLVolumeLODGroup::mDetailScales[NUM_LODS] = {1.f, 1.5f, 2.5f, 4.f}; @@ -44,45 +44,45 @@ F32 LLVolumeLODGroup::mDetailScales[NUM_LODS] = {1.f, 1.5f, 2.5f, 4.f};  //============================================================================  LLVolumeMgr::LLVolumeMgr() -:	mDataMutex(NULL) +:   mDataMutex(NULL)  { -	// the LLMutex magic interferes with easy unit testing, -	// so you now must manually call useMutex() to use it -	//mDataMutex = new LLMutex(); +    // the LLMutex magic interferes with easy unit testing, +    // so you now must manually call useMutex() to use it +    //mDataMutex = new LLMutex();  }  LLVolumeMgr::~LLVolumeMgr()  { -	cleanup(); +    cleanup(); -	delete mDataMutex; -	mDataMutex = NULL; +    delete mDataMutex; +    mDataMutex = NULL;  }  BOOL LLVolumeMgr::cleanup()  { -	BOOL no_refs = TRUE; -	if (mDataMutex) -	{ -		mDataMutex->lock(); -	} -	for (volume_lod_group_map_t::iterator iter = mVolumeLODGroups.begin(), -			 end = mVolumeLODGroups.end(); -		 iter != end; iter++) -	{ -		LLVolumeLODGroup *volgroupp = iter->second; -		if (volgroupp->cleanupRefs() == false) -		{ -			no_refs = FALSE; -		} - 		delete volgroupp; -	} -	mVolumeLODGroups.clear(); -	if (mDataMutex) -	{ -		mDataMutex->unlock(); -	} -	return no_refs; +    BOOL no_refs = TRUE; +    if (mDataMutex) +    { +        mDataMutex->lock(); +    } +    for (volume_lod_group_map_t::iterator iter = mVolumeLODGroups.begin(), +             end = mVolumeLODGroups.end(); +         iter != end; iter++) +    { +        LLVolumeLODGroup *volgroupp = iter->second; +        if (volgroupp->cleanupRefs() == false) +        { +            no_refs = FALSE; +        } +        delete volgroupp; +    } +    mVolumeLODGroups.clear(); +    if (mDataMutex) +    { +        mDataMutex->unlock(); +    } +    return no_refs;  }  // Always only ever store the results of refVolume in a LLPointer @@ -91,318 +91,318 @@ BOOL LLVolumeMgr::cleanup()  //  anything holding the volume and the LODGroup are destroyed  LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 lod)  { -	LLVolumeLODGroup* volgroupp; -	if (mDataMutex) -	{ -		mDataMutex->lock(); -	} -	volume_lod_group_map_t::iterator iter = mVolumeLODGroups.find(&volume_params); -	if( iter == mVolumeLODGroups.end() ) -	{ -		volgroupp = createNewGroup(volume_params); -	} -	else -	{ -		volgroupp = iter->second; -	} -	if (mDataMutex) -	{ -		mDataMutex->unlock(); -	} -	return volgroupp->refLOD(lod); +    LLVolumeLODGroup* volgroupp; +    if (mDataMutex) +    { +        mDataMutex->lock(); +    } +    volume_lod_group_map_t::iterator iter = mVolumeLODGroups.find(&volume_params); +    if( iter == mVolumeLODGroups.end() ) +    { +        volgroupp = createNewGroup(volume_params); +    } +    else +    { +        volgroupp = iter->second; +    } +    if (mDataMutex) +    { +        mDataMutex->unlock(); +    } +    return volgroupp->refLOD(lod);  }  // virtual  LLVolumeLODGroup* LLVolumeMgr::getGroup( const LLVolumeParams& volume_params ) const  { -	LLVolumeLODGroup* volgroupp = NULL; -	if (mDataMutex) -	{ -		mDataMutex->lock(); -	} -	volume_lod_group_map_t::const_iterator iter = mVolumeLODGroups.find(&volume_params); -	if( iter != mVolumeLODGroups.end() ) -	{ -		volgroupp = iter->second; -	} -	if (mDataMutex) -	{ -		mDataMutex->unlock(); -	} -	return volgroupp; +    LLVolumeLODGroup* volgroupp = NULL; +    if (mDataMutex) +    { +        mDataMutex->lock(); +    } +    volume_lod_group_map_t::const_iterator iter = mVolumeLODGroups.find(&volume_params); +    if( iter != mVolumeLODGroups.end() ) +    { +        volgroupp = iter->second; +    } +    if (mDataMutex) +    { +        mDataMutex->unlock(); +    } +    return volgroupp;  }  void LLVolumeMgr::unrefVolume(LLVolume *volumep)  { -	if (volumep->isUnique()) -	{ -		// TomY: Don't need to manage this volume. It is a unique instance. -		return; -	} -	const LLVolumeParams* params = &(volumep->getParams()); -	if (mDataMutex) -	{ -		mDataMutex->lock(); -	} -	volume_lod_group_map_t::iterator iter = mVolumeLODGroups.find(params); -	if( iter == mVolumeLODGroups.end() ) -	{ -		LL_ERRS() << "Warning! Tried to cleanup unknown volume type! " << *params << LL_ENDL; -		if (mDataMutex) -		{ -			mDataMutex->unlock(); -		} -		return; -	} -	else -	{ -		LLVolumeLODGroup* volgroupp = iter->second; - -		volgroupp->derefLOD(volumep); -		if (volgroupp->getNumRefs() == 0) -		{ -			mVolumeLODGroups.erase(params); -			delete volgroupp; -		} -	} -	if (mDataMutex) -	{ -		mDataMutex->unlock(); -	} +    if (volumep->isUnique()) +    { +        // TomY: Don't need to manage this volume. It is a unique instance. +        return; +    } +    const LLVolumeParams* params = &(volumep->getParams()); +    if (mDataMutex) +    { +        mDataMutex->lock(); +    } +    volume_lod_group_map_t::iterator iter = mVolumeLODGroups.find(params); +    if( iter == mVolumeLODGroups.end() ) +    { +        LL_ERRS() << "Warning! Tried to cleanup unknown volume type! " << *params << LL_ENDL; +        if (mDataMutex) +        { +            mDataMutex->unlock(); +        } +        return; +    } +    else +    { +        LLVolumeLODGroup* volgroupp = iter->second; + +        volgroupp->derefLOD(volumep); +        if (volgroupp->getNumRefs() == 0) +        { +            mVolumeLODGroups.erase(params); +            delete volgroupp; +        } +    } +    if (mDataMutex) +    { +        mDataMutex->unlock(); +    }  }  // protected  void LLVolumeMgr::insertGroup(LLVolumeLODGroup* volgroup)  { -	mVolumeLODGroups[volgroup->getVolumeParams()] = volgroup; +    mVolumeLODGroups[volgroup->getVolumeParams()] = volgroup;  }  // protected  LLVolumeLODGroup* LLVolumeMgr::createNewGroup(const LLVolumeParams& volume_params)  { -	LLVolumeLODGroup* volgroup = new LLVolumeLODGroup(volume_params); -	insertGroup(volgroup); -	return volgroup; +    LLVolumeLODGroup* volgroup = new LLVolumeLODGroup(volume_params); +    insertGroup(volgroup); +    return volgroup;  }  // virtual  void LLVolumeMgr::dump()  { -	F32 avg = 0.f; -	if (mDataMutex) -	{ -		mDataMutex->lock(); -	} -	for (volume_lod_group_map_t::iterator iter = mVolumeLODGroups.begin(), -			 end = mVolumeLODGroups.end(); -		 iter != end; iter++) -	{ -		LLVolumeLODGroup *volgroupp = iter->second; -		avg += volgroupp->dump(); -	} -	int count = (int)mVolumeLODGroups.size(); -	avg = count ? avg / (F32)count : 0.0f; -	if (mDataMutex) -	{ -		mDataMutex->unlock(); -	} -	LL_INFOS() << "Average usage of LODs " << avg << LL_ENDL; +    F32 avg = 0.f; +    if (mDataMutex) +    { +        mDataMutex->lock(); +    } +    for (volume_lod_group_map_t::iterator iter = mVolumeLODGroups.begin(), +             end = mVolumeLODGroups.end(); +         iter != end; iter++) +    { +        LLVolumeLODGroup *volgroupp = iter->second; +        avg += volgroupp->dump(); +    } +    int count = (int)mVolumeLODGroups.size(); +    avg = count ? avg / (F32)count : 0.0f; +    if (mDataMutex) +    { +        mDataMutex->unlock(); +    } +    LL_INFOS() << "Average usage of LODs " << avg << LL_ENDL;  }  void LLVolumeMgr::useMutex() -{  -	if (!mDataMutex) -	{ -		mDataMutex = new LLMutex(); -	} +{ +    if (!mDataMutex) +    { +        mDataMutex = new LLMutex(); +    }  }  std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr)  { -	s << "{ numLODgroups=" << volume_mgr.mVolumeLODGroups.size() << ", "; - -	S32 total_refs = 0; -	if (volume_mgr.mDataMutex) -	{ -		volume_mgr.mDataMutex->lock(); -	} - -	for (LLVolumeMgr::volume_lod_group_map_t::const_iterator iter = volume_mgr.mVolumeLODGroups.begin(); -		 iter != volume_mgr.mVolumeLODGroups.end(); ++iter) -	{ -		LLVolumeLODGroup *volgroupp = iter->second; -		total_refs += volgroupp->getNumRefs(); -		s << ", " << (*volgroupp); -	} - -	if (volume_mgr.mDataMutex) -	{ -		volume_mgr.mDataMutex->unlock(); -	} - -	s << ", total_refs=" << total_refs << " }"; -	return s; +    s << "{ numLODgroups=" << volume_mgr.mVolumeLODGroups.size() << ", "; + +    S32 total_refs = 0; +    if (volume_mgr.mDataMutex) +    { +        volume_mgr.mDataMutex->lock(); +    } + +    for (LLVolumeMgr::volume_lod_group_map_t::const_iterator iter = volume_mgr.mVolumeLODGroups.begin(); +         iter != volume_mgr.mVolumeLODGroups.end(); ++iter) +    { +        LLVolumeLODGroup *volgroupp = iter->second; +        total_refs += volgroupp->getNumRefs(); +        s << ", " << (*volgroupp); +    } + +    if (volume_mgr.mDataMutex) +    { +        volume_mgr.mDataMutex->unlock(); +    } + +    s << ", total_refs=" << total_refs << " }"; +    return s;  }  LLVolumeLODGroup::LLVolumeLODGroup(const LLVolumeParams ¶ms) -	: mVolumeParams(params), -	  mRefs(0) +    : mVolumeParams(params), +      mRefs(0)  { -	for (S32 i = 0; i < NUM_LODS; i++) -	{ -		mLODRefs[i] = 0; -		mAccessCount[i] = 0; -	} +    for (S32 i = 0; i < NUM_LODS; i++) +    { +        mLODRefs[i] = 0; +        mAccessCount[i] = 0; +    }  }  LLVolumeLODGroup::~LLVolumeLODGroup()  { -	for (S32 i = 0; i < NUM_LODS; i++) -	{ -		llassert_always(mLODRefs[i] == 0); -	} +    for (S32 i = 0; i < NUM_LODS; i++) +    { +        llassert_always(mLODRefs[i] == 0); +    }  }  // Called from LLVolumeMgr::cleanup  bool LLVolumeLODGroup::cleanupRefs()  { -	bool res = true; -	if (mRefs != 0) -	{ -		LL_WARNS() << "Volume group has remaining refs:" << getNumRefs() << LL_ENDL; -		mRefs = 0; -		for (S32 i = 0; i < NUM_LODS; i++) -		{ -			if (mLODRefs[i] > 0) -			{ -				LL_WARNS() << " LOD " << i << " refs = " << mLODRefs[i] << LL_ENDL; -				mLODRefs[i] = 0; -				mVolumeLODs[i] = NULL; -			} -		} -		LL_WARNS() << *getVolumeParams() << LL_ENDL; -		res = false; -	} -	return res; +    bool res = true; +    if (mRefs != 0) +    { +        LL_WARNS() << "Volume group has remaining refs:" << getNumRefs() << LL_ENDL; +        mRefs = 0; +        for (S32 i = 0; i < NUM_LODS; i++) +        { +            if (mLODRefs[i] > 0) +            { +                LL_WARNS() << " LOD " << i << " refs = " << mLODRefs[i] << LL_ENDL; +                mLODRefs[i] = 0; +                mVolumeLODs[i] = NULL; +            } +        } +        LL_WARNS() << *getVolumeParams() << LL_ENDL; +        res = false; +    } +    return res;  }  LLVolume* LLVolumeLODGroup::refLOD(const S32 lod)  { -	llassert(lod >=0 && lod < NUM_LODS); -	mAccessCount[lod]++; -	 -	mRefs++; -	if (mVolumeLODs[lod].isNull()) -	{ -		mVolumeLODs[lod] = new LLVolume(mVolumeParams, mDetailScales[lod]); -	} -	mLODRefs[lod]++; -	return mVolumeLODs[lod]; +    llassert(lod >=0 && lod < NUM_LODS); +    mAccessCount[lod]++; + +    mRefs++; +    if (mVolumeLODs[lod].isNull()) +    { +        mVolumeLODs[lod] = new LLVolume(mVolumeParams, mDetailScales[lod]); +    } +    mLODRefs[lod]++; +    return mVolumeLODs[lod];  }  BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep)  { -	llassert_always(mRefs > 0); -	mRefs--; -	for (S32 i = 0; i < NUM_LODS; i++) -	{ -		if (mVolumeLODs[i] == volumep) -		{ -			llassert_always(mLODRefs[i] > 0); -			mLODRefs[i]--; +    llassert_always(mRefs > 0); +    mRefs--; +    for (S32 i = 0; i < NUM_LODS; i++) +    { +        if (mVolumeLODs[i] == volumep) +        { +            llassert_always(mLODRefs[i] > 0); +            mLODRefs[i]--;  #if 0 // SJB: Possible opt: keep other lods around -			if (!mLODRefs[i]) -			{ -				mVolumeLODs[i] = NULL; -			} +            if (!mLODRefs[i]) +            { +                mVolumeLODs[i] = NULL; +            }  #endif -			return TRUE; -		} -	} -	LL_ERRS() << "Deref of non-matching LOD in volume LOD group" << LL_ENDL; -	return FALSE; +            return TRUE; +        } +    } +    LL_ERRS() << "Deref of non-matching LOD in volume LOD group" << LL_ENDL; +    return FALSE;  }  S32 LLVolumeLODGroup::getDetailFromTan(const F32 tan_angle)  { -	S32 i = 0; -	while (i < (NUM_LODS - 1)) -	{ -		if (tan_angle <= mDetailThresholds[i]) -		{ -			return i; -		} -		i++; -	} -	return NUM_LODS - 1; +    S32 i = 0; +    while (i < (NUM_LODS - 1)) +    { +        if (tan_angle <= mDetailThresholds[i]) +        { +            return i; +        } +        i++; +    } +    return NUM_LODS - 1;  }  void LLVolumeLODGroup::getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher)  { -	S32 detail = getDetailFromTan(tan_angle); -	 -	if (detail > 0) -	{ -		to_lower = tan_angle - mDetailThresholds[detail]; -	} -	else -	{ -		to_lower = 1024.f*1024.f; -	} - -	if (detail < NUM_LODS-1) -	{ -		to_higher = mDetailThresholds[detail+1] - tan_angle; -	} -	else -	{ -		to_higher = 1024.f*1024.f; -	} +    S32 detail = getDetailFromTan(tan_angle); + +    if (detail > 0) +    { +        to_lower = tan_angle - mDetailThresholds[detail]; +    } +    else +    { +        to_lower = 1024.f*1024.f; +    } + +    if (detail < NUM_LODS-1) +    { +        to_higher = mDetailThresholds[detail+1] - tan_angle; +    } +    else +    { +        to_higher = 1024.f*1024.f; +    }  }  F32 LLVolumeLODGroup::getVolumeScaleFromDetail(const S32 detail)  { -	return mDetailScales[detail]; +    return mDetailScales[detail];  }  S32 LLVolumeLODGroup::getVolumeDetailFromScale(const F32 detail)  { -	for (S32 i = 1; i < 4; i++) -	{ -		if (mDetailScales[i] > detail) -		{ -			return i-1; -		} -	} - -	return 3; +    for (S32 i = 1; i < 4; i++) +    { +        if (mDetailScales[i] > detail) +        { +            return i-1; +        } +    } + +    return 3;  }  F32 LLVolumeLODGroup::dump()  { -	F32 usage = 0.f; -	for (S32 i = 0; i < NUM_LODS; i++) -	{ -		if (mAccessCount[i] > 0) -		{ -			usage += 1.f; -		} -	} -	usage = usage / (F32)NUM_LODS; - -	std::string dump_str = llformat("%.3f %d %d %d %d", usage, mAccessCount[0], mAccessCount[1], mAccessCount[2], mAccessCount[3]); - -	LL_INFOS() << dump_str << LL_ENDL; -	return usage; +    F32 usage = 0.f; +    for (S32 i = 0; i < NUM_LODS; i++) +    { +        if (mAccessCount[i] > 0) +        { +            usage += 1.f; +        } +    } +    usage = usage / (F32)NUM_LODS; + +    std::string dump_str = llformat("%.3f %d %d %d %d", usage, mAccessCount[0], mAccessCount[1], mAccessCount[2], mAccessCount[3]); + +    LL_INFOS() << dump_str << LL_ENDL; +    return usage;  }  std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup)  { -	s << "{ numRefs=" << volgroup.getNumRefs(); -	s << ", mParams=" << volgroup.getVolumeParams(); -	s << " }"; -	  -	return s; +    s << "{ numRefs=" << volgroup.getNumRefs(); +    s << ", mParams=" << volgroup.getVolumeParams(); +    s << " }"; + +    return s;  } diff --git a/indra/llmath/llvolumemgr.h b/indra/llmath/llvolumemgr.h index c75906f675..b46e9aa725 100644 --- a/indra/llmath/llvolumemgr.h +++ b/indra/llmath/llvolumemgr.h @@ -1,25 +1,25 @@ -/**  +/**   * @file llvolumemgr.h   * @brief LLVolumeMgr class.   *   * $LicenseInfo:firstyear=2002&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -38,75 +38,75 @@ class LLVolumeLODGroup;  class LLVolumeLODGroup  { -	LOG_CLASS(LLVolumeLODGroup); -	 +    LOG_CLASS(LLVolumeLODGroup); +  public: -	enum -	{ -		NUM_LODS = 4 -	}; +    enum +    { +        NUM_LODS = 4 +    }; + +    LLVolumeLODGroup(const LLVolumeParams ¶ms); +    ~LLVolumeLODGroup(); +    bool cleanupRefs(); -	LLVolumeLODGroup(const LLVolumeParams ¶ms); -	~LLVolumeLODGroup(); -	bool cleanupRefs(); +    static S32 getDetailFromTan(const F32 tan_angle); +    static void getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher); +    static F32 getVolumeScaleFromDetail(const S32 detail); +    static S32 getVolumeDetailFromScale(F32 scale); -	static S32 getDetailFromTan(const F32 tan_angle); -	static void getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher); -	static F32 getVolumeScaleFromDetail(const S32 detail); -	static S32 getVolumeDetailFromScale(F32 scale); +    LLVolume* refLOD(const S32 detail); +    BOOL derefLOD(LLVolume *volumep); +    S32 getNumRefs() const { return mRefs; } -	LLVolume* refLOD(const S32 detail); -	BOOL derefLOD(LLVolume *volumep); -	S32 getNumRefs() const { return mRefs; } -	 -	const LLVolumeParams* getVolumeParams() const { return &mVolumeParams; }; +    const LLVolumeParams* getVolumeParams() const { return &mVolumeParams; }; -	F32	dump(); -	friend std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup); +    F32 dump(); +    friend std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup);  protected: -	LLVolumeParams mVolumeParams; - -	S32 mRefs; -	S32 mLODRefs[NUM_LODS]; -	LLPointer<LLVolume> mVolumeLODs[NUM_LODS]; -	static F32 mDetailThresholds[NUM_LODS]; -	static F32 mDetailScales[NUM_LODS]; -	S32		mAccessCount[NUM_LODS]; +    LLVolumeParams mVolumeParams; + +    S32 mRefs; +    S32 mLODRefs[NUM_LODS]; +    LLPointer<LLVolume> mVolumeLODs[NUM_LODS]; +    static F32 mDetailThresholds[NUM_LODS]; +    static F32 mDetailScales[NUM_LODS]; +    S32     mAccessCount[NUM_LODS];  };  class LLVolumeMgr  {  public: -	LLVolumeMgr(); -	virtual ~LLVolumeMgr(); -	BOOL cleanup();			// Cleanup all volumes being managed, returns TRUE if no dangling references +    LLVolumeMgr(); +    virtual ~LLVolumeMgr(); +    BOOL cleanup();         // Cleanup all volumes being managed, returns TRUE if no dangling references -	virtual LLVolumeLODGroup* getGroup( const LLVolumeParams& volume_params ) const; +    virtual LLVolumeLODGroup* getGroup( const LLVolumeParams& volume_params ) const; -	// whatever calls getVolume() never owns the LLVolume* and -	// cannot keep references for long since it may be deleted -	// later.  For best results hold it in an LLPointer<LLVolume>. -	virtual LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail); -	virtual void unrefVolume(LLVolume *volumep); +    // whatever calls getVolume() never owns the LLVolume* and +    // cannot keep references for long since it may be deleted +    // later.  For best results hold it in an LLPointer<LLVolume>. +    virtual LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail); +    virtual void unrefVolume(LLVolume *volumep); -	void dump(); +    void dump(); -	// manually call this for mutex magic -	void useMutex(); +    // manually call this for mutex magic +    void useMutex(); -	friend std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr); +    friend std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr);  protected: -	void insertGroup(LLVolumeLODGroup* volgroup); -	// Overridden in llphysics/abstract/utils/llphysicsvolumemanager.h -	virtual LLVolumeLODGroup* createNewGroup(const LLVolumeParams& volume_params); +    void insertGroup(LLVolumeLODGroup* volgroup); +    // Overridden in llphysics/abstract/utils/llphysicsvolumemanager.h +    virtual LLVolumeLODGroup* createNewGroup(const LLVolumeParams& volume_params);  protected: -	typedef std::map<const LLVolumeParams*, LLVolumeLODGroup*, LLVolumeParams::compare> volume_lod_group_map_t; -	volume_lod_group_map_t mVolumeLODGroups; +    typedef std::map<const LLVolumeParams*, LLVolumeLODGroup*, LLVolumeParams::compare> volume_lod_group_map_t; +    volume_lod_group_map_t mVolumeLODGroups; -	LLMutex* mDataMutex; +    LLMutex* mDataMutex;  };  #endif // LL_LLVOLUMEMGR_H diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index 6894d04d3c..343740692c 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file llvolumeoctree.cpp   *   * $LicenseInfo:firstyear=2002&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -29,190 +29,190 @@  BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size)  { -	LLVector4a fAWdU; -	LLVector4a dir; -	LLVector4a diff; +    LLVector4a fAWdU; +    LLVector4a dir; +    LLVector4a diff; -	dir.setSub(end, start); -	dir.mul(0.5f); +    dir.setSub(end, start); +    dir.mul(0.5f); -	diff.setAdd(end,start); -	diff.mul(0.5f); -	diff.sub(center); -	fAWdU.setAbs(dir);  +    diff.setAdd(end,start); +    diff.mul(0.5f); +    diff.sub(center); +    fAWdU.setAbs(dir); -	LLVector4a rhs; -	rhs.setAdd(size, fAWdU); +    LLVector4a rhs; +    rhs.setAdd(size, fAWdU); -	LLVector4a lhs; -	lhs.setAbs(diff); +    LLVector4a lhs; +    lhs.setAbs(diff); -	U32 grt = lhs.greaterThan(rhs).getGatheredBits(); +    U32 grt = lhs.greaterThan(rhs).getGatheredBits(); -	if (grt & 0x7) -	{ -		return false; -	} -	 -	LLVector4a f; -	f.setCross3(dir, diff); -	f.setAbs(f); +    if (grt & 0x7) +    { +        return false; +    } -	LLVector4a v0, v1; +    LLVector4a f; +    f.setCross3(dir, diff); +    f.setAbs(f); -	v0 = _mm_shuffle_ps(size, size,_MM_SHUFFLE(3,0,0,1)); -	v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,1,2,2)); -	lhs.setMul(v0, v1); +    LLVector4a v0, v1; -	v0 = _mm_shuffle_ps(size, size, _MM_SHUFFLE(3,1,2,2)); -	v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,0,0,1)); -	rhs.setMul(v0, v1); -	rhs.add(lhs); -	 -	grt = f.greaterThan(rhs).getGatheredBits(); +    v0 = _mm_shuffle_ps(size, size,_MM_SHUFFLE(3,0,0,1)); +    v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,1,2,2)); +    lhs.setMul(v0, v1); -	return (grt & 0x7) ? false : true; +    v0 = _mm_shuffle_ps(size, size, _MM_SHUFFLE(3,1,2,2)); +    v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,0,0,1)); +    rhs.setMul(v0, v1); +    rhs.add(lhs); + +    grt = f.greaterThan(rhs).getGatheredBits(); + +    return (grt & 0x7) ? false : true;  }  LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)  { -	node->addListener(this); +    node->addListener(this);  }  LLVolumeOctreeListener::~LLVolumeOctreeListener()  {  } -	 -void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent,  + +void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent,      LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child)  { -	new LLVolumeOctreeListener(child); +    new LLVolumeOctreeListener(child);  } -LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,  -							   const LLVolumeFace* face, F32* closest_t, -							   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) +LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, +                               const LLVolumeFace* face, F32* closest_t, +                               LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)     : mFace(face),       mStart(start), -	 mDir(dir), -	 mIntersection(intersection), -	 mTexCoord(tex_coord), -	 mNormal(normal), -	 mTangent(tangent), -	 mClosestT(closest_t), -	 mHitFace(false) +     mDir(dir), +     mIntersection(intersection), +     mTexCoord(tex_coord), +     mNormal(normal), +     mTangent(tangent), +     mClosestT(closest_t), +     mHitFace(false)  { -	mEnd.setAdd(mStart, mDir); +    mEnd.setAdd(mStart, mDir);  }  void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)  { -	LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); - -	if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1])) -	{ -		node->accept(this); -		for (S32 i = 0; i < node->getChildCount(); ++i) -		{ -			traverse(node->getChild(i)); -		} -	} +    LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); + +    if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1])) +    { +        node->accept(this); +        for (S32 i = 0; i < node->getChildCount(); ++i) +        { +            traverse(node->getChild(i)); +        } +    }  }  void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)  {      for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = -			node->getDataBegin(); iter != node->getDataEnd(); ++iter) -	{ -		const LLVolumeTriangle* tri = *iter; - -		F32 a, b, t; -		 -		if (LLTriangleRayIntersect(*tri->mV[0], *tri->mV[1], *tri->mV[2], -				mStart, mDir, a, b, t)) -		{ -			if ((t >= 0.f) &&      // if hit is after start -				(t <= 1.f) &&      // and before end -				(t < *mClosestT))   // and this hit is closer -			{ -				*mClosestT = t; -				mHitFace = true; - -				if (mIntersection != NULL) -				{ -					LLVector4a intersect = mDir; -					intersect.mul(*mClosestT); -					intersect.add(mStart); -					*mIntersection = intersect; -				} - -				U32 idx0 = tri->mIndex[0]; -				U32 idx1 = tri->mIndex[1]; -				U32 idx2 = tri->mIndex[2]; - -				if (mTexCoord != NULL) -				{ -					LLVector2* tc = (LLVector2*) mFace->mTexCoords; -					*mTexCoord = ((1.f - a - b)  * tc[idx0] + -						a              * tc[idx1] + -						b              * tc[idx2]); - -				} - -				if (mNormal != NULL) -				{ -					LLVector4a* norm = mFace->mNormals; -								 -					LLVector4a n1,n2,n3; -					n1 = norm[idx0]; -					n1.mul(1.f-a-b); -								 -					n2 = norm[idx1]; -					n2.mul(a); -								 -					n3 = norm[idx2]; -					n3.mul(b); - -					n1.add(n2); -					n1.add(n3); -								 -					*mNormal		= n1;  -				} - -				if (mTangent != NULL) -				{ -					LLVector4a* tangents = mFace->mTangents; -								 -					LLVector4a t1,t2,t3; -					t1 = tangents[idx0]; -					t1.mul(1.f-a-b); -								 -					t2 = tangents[idx1]; -					t2.mul(a); -								 -					t3 = tangents[idx2]; -					t3.mul(b); - -					t1.add(t2); -					t1.add(t3); -								 -					*mTangent = t1;  -				} -			} -		} -	} +            node->getDataBegin(); iter != node->getDataEnd(); ++iter) +    { +        const LLVolumeTriangle* tri = *iter; + +        F32 a, b, t; + +        if (LLTriangleRayIntersect(*tri->mV[0], *tri->mV[1], *tri->mV[2], +                mStart, mDir, a, b, t)) +        { +            if ((t >= 0.f) &&      // if hit is after start +                (t <= 1.f) &&      // and before end +                (t < *mClosestT))   // and this hit is closer +            { +                *mClosestT = t; +                mHitFace = true; + +                if (mIntersection != NULL) +                { +                    LLVector4a intersect = mDir; +                    intersect.mul(*mClosestT); +                    intersect.add(mStart); +                    *mIntersection = intersect; +                } + +                U32 idx0 = tri->mIndex[0]; +                U32 idx1 = tri->mIndex[1]; +                U32 idx2 = tri->mIndex[2]; + +                if (mTexCoord != NULL) +                { +                    LLVector2* tc = (LLVector2*) mFace->mTexCoords; +                    *mTexCoord = ((1.f - a - b)  * tc[idx0] + +                        a              * tc[idx1] + +                        b              * tc[idx2]); + +                } + +                if (mNormal != NULL) +                { +                    LLVector4a* norm = mFace->mNormals; + +                    LLVector4a n1,n2,n3; +                    n1 = norm[idx0]; +                    n1.mul(1.f-a-b); + +                    n2 = norm[idx1]; +                    n2.mul(a); + +                    n3 = norm[idx2]; +                    n3.mul(b); + +                    n1.add(n2); +                    n1.add(n3); + +                    *mNormal        = n1; +                } + +                if (mTangent != NULL) +                { +                    LLVector4a* tangents = mFace->mTangents; + +                    LLVector4a t1,t2,t3; +                    t1 = tangents[idx0]; +                    t1.mul(1.f-a-b); + +                    t2 = tangents[idx1]; +                    t2.mul(a); + +                    t3 = tangents[idx2]; +                    t3.mul(b); + +                    t1.add(t2); +                    t1.add(t3); + +                    *mTangent = t1; +                } +            } +        } +    }  }  const LLVector4a& LLVolumeTriangle::getPositionGroup() const  { -	return mPositionGroup; +    return mPositionGroup;  }  const F32& LLVolumeTriangle::getBinRadius() const  { -	return mRadius; +    return mRadius;  } @@ -220,55 +220,55 @@ const F32& LLVolumeTriangle::getBinRadius() const  void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)  { -	LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); +    LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); -	//make sure bounds matches extents -	LLVector4a& min = node->mExtents[0]; -	LLVector4a& max = node->mExtents[1]; +    //make sure bounds matches extents +    LLVector4a& min = node->mExtents[0]; +    LLVector4a& max = node->mExtents[1]; -	LLVector4a& center = node->mBounds[0]; -	LLVector4a& size = node->mBounds[1]; +    LLVector4a& center = node->mBounds[0]; +    LLVector4a& size = node->mBounds[1]; -	LLVector4a test_min, test_max; -	test_min.setSub(center, size); -	test_max.setAdd(center, size); +    LLVector4a test_min, test_max; +    test_min.setSub(center, size); +    test_max.setAdd(center, size); -	if (!test_min.equals3(min, 0.001f) || -		!test_max.equals3(max, 0.001f)) -	{ -		LL_ERRS() << "Bad bounding box data found." << LL_ENDL; -	} +    if (!test_min.equals3(min, 0.001f) || +        !test_max.equals3(max, 0.001f)) +    { +        LL_ERRS() << "Bad bounding box data found." << LL_ENDL; +    } -	test_min.sub(LLVector4a(0.001f)); -	test_max.add(LLVector4a(0.001f)); +    test_min.sub(LLVector4a(0.001f)); +    test_max.add(LLVector4a(0.001f)); -	for (U32 i = 0; i < branch->getChildCount(); ++i) -	{ -		LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0); +    for (U32 i = 0; i < branch->getChildCount(); ++i) +    { +        LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0); -		//make sure all children fit inside this node -		if (child->mExtents[0].lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ) || -			child->mExtents[1].greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ)) -		{ -			LL_ERRS() << "Child protrudes from bounding box." << LL_ENDL; -		} -	} +        //make sure all children fit inside this node +        if (child->mExtents[0].lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ) || +            child->mExtents[1].greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ)) +        { +            LL_ERRS() << "Child protrudes from bounding box." << LL_ENDL; +        } +    } -	//children fit, check data +    //children fit, check data      for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); -			iter != branch->getDataEnd(); ++iter) -	{ -		const LLVolumeTriangle* tri = *iter; - -		//validate triangle -		for (U32 i = 0; i < 3; i++) -		{ -			if (tri->mV[i]->greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ) || -				tri->mV[i]->lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ)) -			{ -				LL_ERRS() << "Triangle protrudes from node." << LL_ENDL; -			} -		} -	} +            iter != branch->getDataEnd(); ++iter) +    { +        const LLVolumeTriangle* tri = *iter; + +        //validate triangle +        for (U32 i = 0; i < 3; i++) +        { +            if (tri->mV[i]->greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ) || +                tri->mV[i]->lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ)) +            { +                LL_ERRS() << "Triangle protrudes from node." << LL_ENDL; +            } +        } +    }  } diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index d65bca5e52..96918912ed 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -1,25 +1,25 @@ -/**  +/**   * @file llvolumeoctree.h   * @brief LLVolume octree classes.   *   * $LicenseInfo:firstyear=2002&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -38,41 +38,41 @@ class alignas(16) LLVolumeTriangle : public LLRefCount  {      LL_ALIGN_NEW  public: -	LLVolumeTriangle() -	{ -		mBinIndex = -1;	 -	} +    LLVolumeTriangle() +    { +        mBinIndex = -1; +    } + +    LLVolumeTriangle(const LLVolumeTriangle& rhs) +    { +        *this = rhs; +    } -	LLVolumeTriangle(const LLVolumeTriangle& rhs) -	{ -		*this = rhs; -	} +    const LLVolumeTriangle& operator=(const LLVolumeTriangle& rhs) +    { +        LL_ERRS() << "Illegal operation!" << LL_ENDL; +        return *this; +    } -	const LLVolumeTriangle& operator=(const LLVolumeTriangle& rhs) -	{ -		LL_ERRS() << "Illegal operation!" << LL_ENDL; -		return *this; -	} +    ~LLVolumeTriangle() +    { -	~LLVolumeTriangle() -	{ -	 -	} +    } -	LL_ALIGN_16(LLVector4a mPositionGroup); +    LL_ALIGN_16(LLVector4a mPositionGroup); -	const LLVector4a* mV[3]; -	U16 mIndex[3]; +    const LLVector4a* mV[3]; +    U16 mIndex[3]; -	F32 mRadius; -	mutable S32 mBinIndex; +    F32 mRadius; +    mutable S32 mBinIndex; -	virtual const LLVector4a& getPositionGroup() const; -	virtual const F32& getBinRadius() const; -	 -	S32 getBinIndex() const { return mBinIndex; } -	void setBinIndex(S32 idx) const { mBinIndex = idx; } +    virtual const LLVector4a& getPositionGroup() const; +    virtual const F32& getBinRadius() const; + +    S32 getBinIndex() const { return mBinIndex; } +    void setBinIndex(S32 idx) const { mBinIndex = idx; }  }; @@ -82,50 +82,50 @@ class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTrian      LL_ALIGN_NEW  public:      LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node); -	~LLVolumeOctreeListener(); -	 -	LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs) -	{ -		*this = rhs; -	} - -	const LLVolumeOctreeListener& operator=(const LLVolumeOctreeListener& rhs) -	{ -		LL_ERRS() << "Illegal operation!" << LL_ENDL; -		return *this; -	} - -	 //LISTENER FUNCTIONS +    ~LLVolumeOctreeListener(); + +    LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs) +    { +        *this = rhs; +    } + +    const LLVolumeOctreeListener& operator=(const LLVolumeOctreeListener& rhs) +    { +        LL_ERRS() << "Illegal operation!" << LL_ENDL; +        return *this; +    } + +     //LISTENER FUNCTIONS      virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child); -	virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { } +    virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { }      virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child) { } -	virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { } -	virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { } -	virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) { } -	 +    virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { } +    virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { } +    virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) { } +  public: -	LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) -	LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children +    LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) +    LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children  };  class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>  {  public: -	const LLVolumeFace* mFace; -	LLVector4a mStart; -	LLVector4a mDir; -	LLVector4a mEnd; -	LLVector4a* mIntersection; -	LLVector2* mTexCoord; -	LLVector4a* mNormal; -	LLVector4a* mTangent; -	F32* mClosestT; -	bool mHitFace; - -	LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,  -								   const LLVolumeFace* face, F32* closest_t, -								   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent); +    const LLVolumeFace* mFace; +    LLVector4a mStart; +    LLVector4a mDir; +    LLVector4a mEnd; +    LLVector4a* mIntersection; +    LLVector2* mTexCoord; +    LLVector4a* mNormal; +    LLVector4a* mTangent; +    F32* mClosestT; +    bool mHitFace; + +    LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, +                                   const LLVolumeFace* face, F32* closest_t, +                                   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);      void traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node); diff --git a/indra/llmath/m3math.cpp b/indra/llmath/m3math.cpp index 65eb3348de..2cefc44da3 100644 --- a/indra/llmath/m3math.cpp +++ b/indra/llmath/m3math.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file m3math.cpp   * @brief LLMatrix3 class implementation.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -36,7 +36,7 @@  // LLMatrix3 -//              ji   +//              ji  // LLMatrix3 = |00 01 02 |  //             |10 11 12 |  //             |20 21 22 | @@ -51,266 +51,266 @@  LLMatrix3::LLMatrix3(const LLQuaternion &q)  { -	setRot(q); +    setRot(q);  }  LLMatrix3::LLMatrix3(const F32 angle, const LLVector3 &vec)  { -	LLQuaternion	quat(angle, vec); -	setRot(quat); +    LLQuaternion    quat(angle, vec); +    setRot(quat);  }  LLMatrix3::LLMatrix3(const F32 angle, const LLVector3d &vec)  { -	LLVector3 vec_f; -	vec_f.setVec(vec); -	LLQuaternion	quat(angle, vec_f); -	setRot(quat); +    LLVector3 vec_f; +    vec_f.setVec(vec); +    LLQuaternion    quat(angle, vec_f); +    setRot(quat);  }  LLMatrix3::LLMatrix3(const F32 angle, const LLVector4 &vec)  { -	LLQuaternion	quat(angle, vec); -	setRot(quat); +    LLQuaternion    quat(angle, vec); +    setRot(quat);  }  LLMatrix3::LLMatrix3(const F32 roll, const F32 pitch, const F32 yaw)  { -	setRot(roll,pitch,yaw); +    setRot(roll,pitch,yaw);  }  // From Matrix and Quaternion FAQ  void LLMatrix3::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const  { -	F64 angle_x, angle_y, angle_z; -	F64 cx, cy, cz;					// cosine of angle_x, angle_y, angle_z -	F64 sx,     sz;					// sine of angle_x, angle_y, angle_z +    F64 angle_x, angle_y, angle_z; +    F64 cx, cy, cz;                 // cosine of angle_x, angle_y, angle_z +    F64 sx,     sz;                 // sine of angle_x, angle_y, angle_z -	angle_y = asin(llclamp(mMatrix[2][0], -1.f, 1.f)); -	cy = cos(angle_y); +    angle_y = asin(llclamp(mMatrix[2][0], -1.f, 1.f)); +    cy = cos(angle_y); -	if (fabs(cy) > 0.005)		// non-zero -	{ -		// no gimbal lock -		cx = mMatrix[2][2] / cy; -		sx = - mMatrix[2][1] / cy; +    if (fabs(cy) > 0.005)       // non-zero +    { +        // no gimbal lock +        cx = mMatrix[2][2] / cy; +        sx = - mMatrix[2][1] / cy; -		angle_x = (F32) atan2(sx, cx); +        angle_x = (F32) atan2(sx, cx); -		cz = mMatrix[0][0] / cy; -		sz = - mMatrix[1][0] / cy; +        cz = mMatrix[0][0] / cy; +        sz = - mMatrix[1][0] / cy; -		angle_z = (F32) atan2(sz, cz); -	} -	else -	{ -		// yup, gimbal lock -		angle_x = 0; +        angle_z = (F32) atan2(sz, cz); +    } +    else +    { +        // yup, gimbal lock +        angle_x = 0; -		// some tricky math thereby avoided, see article +        // some tricky math thereby avoided, see article -		cz = mMatrix[1][1]; -		sz = mMatrix[0][1]; +        cz = mMatrix[1][1]; +        sz = mMatrix[0][1]; -		angle_z = atan2(sz, cz); -	} +        angle_z = atan2(sz, cz); +    } -	*roll = (F32)angle_x; -	*pitch = (F32)angle_y; -	*yaw = (F32)angle_z; +    *roll = (F32)angle_x; +    *pitch = (F32)angle_y; +    *yaw = (F32)angle_z;  } -	 +  // Clear and Assignment Functions -const LLMatrix3&	LLMatrix3::setIdentity() +const LLMatrix3&    LLMatrix3::setIdentity()  { -	mMatrix[0][0] = 1.f; -	mMatrix[0][1] = 0.f; -	mMatrix[0][2] = 0.f; +    mMatrix[0][0] = 1.f; +    mMatrix[0][1] = 0.f; +    mMatrix[0][2] = 0.f; -	mMatrix[1][0] = 0.f; -	mMatrix[1][1] = 1.f; -	mMatrix[1][2] = 0.f; +    mMatrix[1][0] = 0.f; +    mMatrix[1][1] = 1.f; +    mMatrix[1][2] = 0.f; -	mMatrix[2][0] = 0.f; -	mMatrix[2][1] = 0.f; -	mMatrix[2][2] = 1.f; -	return (*this); +    mMatrix[2][0] = 0.f; +    mMatrix[2][1] = 0.f; +    mMatrix[2][2] = 1.f; +    return (*this);  } -const LLMatrix3&	LLMatrix3::clear() +const LLMatrix3&    LLMatrix3::clear()  { -	mMatrix[0][0] = 0.f; -	mMatrix[0][1] = 0.f; -	mMatrix[0][2] = 0.f; +    mMatrix[0][0] = 0.f; +    mMatrix[0][1] = 0.f; +    mMatrix[0][2] = 0.f; -	mMatrix[1][0] = 0.f; -	mMatrix[1][1] = 0.f; -	mMatrix[1][2] = 0.f; +    mMatrix[1][0] = 0.f; +    mMatrix[1][1] = 0.f; +    mMatrix[1][2] = 0.f; -	mMatrix[2][0] = 0.f; -	mMatrix[2][1] = 0.f; -	mMatrix[2][2] = 0.f; -	return (*this); +    mMatrix[2][0] = 0.f; +    mMatrix[2][1] = 0.f; +    mMatrix[2][2] = 0.f; +    return (*this);  } -const LLMatrix3&	LLMatrix3::setZero() +const LLMatrix3&    LLMatrix3::setZero()  { -	mMatrix[0][0] = 0.f; -	mMatrix[0][1] = 0.f; -	mMatrix[0][2] = 0.f; +    mMatrix[0][0] = 0.f; +    mMatrix[0][1] = 0.f; +    mMatrix[0][2] = 0.f; -	mMatrix[1][0] = 0.f; -	mMatrix[1][1] = 0.f; -	mMatrix[1][2] = 0.f; +    mMatrix[1][0] = 0.f; +    mMatrix[1][1] = 0.f; +    mMatrix[1][2] = 0.f; -	mMatrix[2][0] = 0.f; -	mMatrix[2][1] = 0.f; -	mMatrix[2][2] = 0.f; -	return (*this); +    mMatrix[2][0] = 0.f; +    mMatrix[2][1] = 0.f; +    mMatrix[2][2] = 0.f; +    return (*this);  }  // various useful mMatrix functions -const LLMatrix3&	LLMatrix3::transpose()  +const LLMatrix3&    LLMatrix3::transpose()  { -	// transpose the matrix -	F32 temp; -	temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp; -	temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp; -	temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp; -	return *this; +    // transpose the matrix +    F32 temp; +    temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp; +    temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp; +    temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp; +    return *this;  } -F32		LLMatrix3::determinant() const +F32     LLMatrix3::determinant() const  { -	// Is this a useful method when we assume the matrices are valid rotation -	// matrices throughout this implementation? -	return	mMatrix[0][0] * (mMatrix[1][1] * mMatrix[2][2] - mMatrix[1][2] * mMatrix[2][1]) + -		  	mMatrix[0][1] * (mMatrix[1][2] * mMatrix[2][0] - mMatrix[1][0] * mMatrix[2][2]) + -		  	mMatrix[0][2] * (mMatrix[1][0] * mMatrix[2][1] - mMatrix[1][1] * mMatrix[2][0]);  +    // Is this a useful method when we assume the matrices are valid rotation +    // matrices throughout this implementation? +    return  mMatrix[0][0] * (mMatrix[1][1] * mMatrix[2][2] - mMatrix[1][2] * mMatrix[2][1]) + +            mMatrix[0][1] * (mMatrix[1][2] * mMatrix[2][0] - mMatrix[1][0] * mMatrix[2][2]) + +            mMatrix[0][2] * (mMatrix[1][0] * mMatrix[2][1] - mMatrix[1][1] * mMatrix[2][0]);  }  // inverts this matrix  void LLMatrix3::invert()  { -	// fails silently if determinant is zero too small -	F32 det = determinant(); -	const F32 VERY_SMALL_DETERMINANT = 0.000001f; -	if (fabs(det) > VERY_SMALL_DETERMINANT) -	{ -		// invertiable -		LLMatrix3 t(*this); -		mMatrix[VX][VX] = ( t.mMatrix[VY][VY] * t.mMatrix[VZ][VZ] - t.mMatrix[VY][VZ] * t.mMatrix[VZ][VY] ) / det; -		mMatrix[VY][VX] = ( t.mMatrix[VY][VZ] * t.mMatrix[VZ][VX] - t.mMatrix[VY][VX] * t.mMatrix[VZ][VZ] ) / det; -		mMatrix[VZ][VX] = ( t.mMatrix[VY][VX] * t.mMatrix[VZ][VY] - t.mMatrix[VY][VY] * t.mMatrix[VZ][VX] ) / det; -		mMatrix[VX][VY] = ( t.mMatrix[VZ][VY] * t.mMatrix[VX][VZ] - t.mMatrix[VZ][VZ] * t.mMatrix[VX][VY] ) / det; -		mMatrix[VY][VY] = ( t.mMatrix[VZ][VZ] * t.mMatrix[VX][VX] - t.mMatrix[VZ][VX] * t.mMatrix[VX][VZ] ) / det; -		mMatrix[VZ][VY] = ( t.mMatrix[VZ][VX] * t.mMatrix[VX][VY] - t.mMatrix[VZ][VY] * t.mMatrix[VX][VX] ) / det; -		mMatrix[VX][VZ] = ( t.mMatrix[VX][VY] * t.mMatrix[VY][VZ] - t.mMatrix[VX][VZ] * t.mMatrix[VY][VY] ) / det; -		mMatrix[VY][VZ] = ( t.mMatrix[VX][VZ] * t.mMatrix[VY][VX] - t.mMatrix[VX][VX] * t.mMatrix[VY][VZ] ) / det; -		mMatrix[VZ][VZ] = ( t.mMatrix[VX][VX] * t.mMatrix[VY][VY] - t.mMatrix[VX][VY] * t.mMatrix[VY][VX] ) / det; -	} +    // fails silently if determinant is zero too small +    F32 det = determinant(); +    const F32 VERY_SMALL_DETERMINANT = 0.000001f; +    if (fabs(det) > VERY_SMALL_DETERMINANT) +    { +        // invertiable +        LLMatrix3 t(*this); +        mMatrix[VX][VX] = ( t.mMatrix[VY][VY] * t.mMatrix[VZ][VZ] - t.mMatrix[VY][VZ] * t.mMatrix[VZ][VY] ) / det; +        mMatrix[VY][VX] = ( t.mMatrix[VY][VZ] * t.mMatrix[VZ][VX] - t.mMatrix[VY][VX] * t.mMatrix[VZ][VZ] ) / det; +        mMatrix[VZ][VX] = ( t.mMatrix[VY][VX] * t.mMatrix[VZ][VY] - t.mMatrix[VY][VY] * t.mMatrix[VZ][VX] ) / det; +        mMatrix[VX][VY] = ( t.mMatrix[VZ][VY] * t.mMatrix[VX][VZ] - t.mMatrix[VZ][VZ] * t.mMatrix[VX][VY] ) / det; +        mMatrix[VY][VY] = ( t.mMatrix[VZ][VZ] * t.mMatrix[VX][VX] - t.mMatrix[VZ][VX] * t.mMatrix[VX][VZ] ) / det; +        mMatrix[VZ][VY] = ( t.mMatrix[VZ][VX] * t.mMatrix[VX][VY] - t.mMatrix[VZ][VY] * t.mMatrix[VX][VX] ) / det; +        mMatrix[VX][VZ] = ( t.mMatrix[VX][VY] * t.mMatrix[VY][VZ] - t.mMatrix[VX][VZ] * t.mMatrix[VY][VY] ) / det; +        mMatrix[VY][VZ] = ( t.mMatrix[VX][VZ] * t.mMatrix[VY][VX] - t.mMatrix[VX][VX] * t.mMatrix[VY][VZ] ) / det; +        mMatrix[VZ][VZ] = ( t.mMatrix[VX][VX] * t.mMatrix[VY][VY] - t.mMatrix[VX][VY] * t.mMatrix[VY][VX] ) / det; +    }  }  // does not assume a rotation matrix, and does not divide by determinant, assuming results will be renormalized -const LLMatrix3&	LLMatrix3::adjointTranspose() +const LLMatrix3&    LLMatrix3::adjointTranspose()  { -	LLMatrix3 adjoint_transpose; -	adjoint_transpose.mMatrix[VX][VX] = mMatrix[VY][VY] * mMatrix[VZ][VZ] - mMatrix[VY][VZ] * mMatrix[VZ][VY] ; -	adjoint_transpose.mMatrix[VY][VX] = mMatrix[VY][VZ] * mMatrix[VZ][VX] - mMatrix[VY][VX] * mMatrix[VZ][VZ] ; -	adjoint_transpose.mMatrix[VZ][VX] = mMatrix[VY][VX] * mMatrix[VZ][VY] - mMatrix[VY][VY] * mMatrix[VZ][VX] ; -	adjoint_transpose.mMatrix[VX][VY] = mMatrix[VZ][VY] * mMatrix[VX][VZ] - mMatrix[VZ][VZ] * mMatrix[VX][VY] ; -	adjoint_transpose.mMatrix[VY][VY] = mMatrix[VZ][VZ] * mMatrix[VX][VX] - mMatrix[VZ][VX] * mMatrix[VX][VZ] ; -	adjoint_transpose.mMatrix[VZ][VY] = mMatrix[VZ][VX] * mMatrix[VX][VY] - mMatrix[VZ][VY] * mMatrix[VX][VX] ; -	adjoint_transpose.mMatrix[VX][VZ] = mMatrix[VX][VY] * mMatrix[VY][VZ] - mMatrix[VX][VZ] * mMatrix[VY][VY] ; -	adjoint_transpose.mMatrix[VY][VZ] = mMatrix[VX][VZ] * mMatrix[VY][VX] - mMatrix[VX][VX] * mMatrix[VY][VZ] ; -	adjoint_transpose.mMatrix[VZ][VZ] = mMatrix[VX][VX] * mMatrix[VY][VY] - mMatrix[VX][VY] * mMatrix[VY][VX] ; +    LLMatrix3 adjoint_transpose; +    adjoint_transpose.mMatrix[VX][VX] = mMatrix[VY][VY] * mMatrix[VZ][VZ] - mMatrix[VY][VZ] * mMatrix[VZ][VY] ; +    adjoint_transpose.mMatrix[VY][VX] = mMatrix[VY][VZ] * mMatrix[VZ][VX] - mMatrix[VY][VX] * mMatrix[VZ][VZ] ; +    adjoint_transpose.mMatrix[VZ][VX] = mMatrix[VY][VX] * mMatrix[VZ][VY] - mMatrix[VY][VY] * mMatrix[VZ][VX] ; +    adjoint_transpose.mMatrix[VX][VY] = mMatrix[VZ][VY] * mMatrix[VX][VZ] - mMatrix[VZ][VZ] * mMatrix[VX][VY] ; +    adjoint_transpose.mMatrix[VY][VY] = mMatrix[VZ][VZ] * mMatrix[VX][VX] - mMatrix[VZ][VX] * mMatrix[VX][VZ] ; +    adjoint_transpose.mMatrix[VZ][VY] = mMatrix[VZ][VX] * mMatrix[VX][VY] - mMatrix[VZ][VY] * mMatrix[VX][VX] ; +    adjoint_transpose.mMatrix[VX][VZ] = mMatrix[VX][VY] * mMatrix[VY][VZ] - mMatrix[VX][VZ] * mMatrix[VY][VY] ; +    adjoint_transpose.mMatrix[VY][VZ] = mMatrix[VX][VZ] * mMatrix[VY][VX] - mMatrix[VX][VX] * mMatrix[VY][VZ] ; +    adjoint_transpose.mMatrix[VZ][VZ] = mMatrix[VX][VX] * mMatrix[VY][VY] - mMatrix[VX][VY] * mMatrix[VY][VX] ; -	*this = adjoint_transpose; -	return *this; +    *this = adjoint_transpose; +    return *this;  }  // SJB: This code is correct for a logicly stored (non-transposed) matrix; -//		Our matrices are stored transposed, OpenGL style, so this generates the -//		INVERSE quaternion (-x, -y, -z, w)! -//		Because we use similar logic in LLQuaternion::getMatrix3, -//		we are internally consistant so everything works OK :) -LLQuaternion	LLMatrix3::quaternion() const -{ -	LLQuaternion	quat; -	F32		tr, s, q[4]; -	U32		i, j, k; -	U32		nxt[3] = {1, 2, 0}; - -	tr = mMatrix[0][0] + mMatrix[1][1] + mMatrix[2][2]; - -	// check the diagonal -	if (tr > 0.f)  -	{ -		s = (F32)sqrt (tr + 1.f); -		quat.mQ[VS] = s / 2.f; -		s = 0.5f / s; -		quat.mQ[VX] = (mMatrix[1][2] - mMatrix[2][1]) * s; -		quat.mQ[VY] = (mMatrix[2][0] - mMatrix[0][2]) * s; -		quat.mQ[VZ] = (mMatrix[0][1] - mMatrix[1][0]) * s; -	}  -	else -	{		 -		// diagonal is negative -		i = 0; -		if (mMatrix[1][1] > mMatrix[0][0])  -			i = 1; -		if (mMatrix[2][2] > mMatrix[i][i])  -			i = 2; - -		j = nxt[i]; -		k = nxt[j]; - - -		s = (F32)sqrt ((mMatrix[i][i] - (mMatrix[j][j] + mMatrix[k][k])) + 1.f); - -		q[i] = s * 0.5f; - -		if (s != 0.f)  -			s = 0.5f / s; - -		q[3] = (mMatrix[j][k] - mMatrix[k][j]) * s; -		q[j] = (mMatrix[i][j] + mMatrix[j][i]) * s; -		q[k] = (mMatrix[i][k] + mMatrix[k][i]) * s; - -		quat.setQuat(q); -	} -	return quat; -} - -const LLMatrix3&	LLMatrix3::setRot(const F32 angle, const LLVector3 &vec) -{ -	setRot(LLQuaternion(angle, vec)); -	return *this; -} - -const LLMatrix3&	LLMatrix3::setRot(const F32 roll, const F32 pitch, const F32 yaw) -{ -	// Rotates RH about x-axis by 'roll'  then -	// rotates RH about the old y-axis by 'pitch' then -	// rotates RH about the original z-axis by 'yaw'. -	//                . -	//               /|\ yaw axis -	//                |     __. -	//   ._        ___|      /| pitch axis -	//  _||\       \\ |-.   / -	//  \|| \_______\_|__\_/_______ -	//   | _ _   o o o_o_o_o o   /_\_  ________\ roll axis -	//   //  /_______/    /__________>         /    -	//  /_,-'       //   / -	//             /__,-' - -	F32		cx, sx, cy, sy, cz, sz; -	F32		cxsy, sxsy; +//      Our matrices are stored transposed, OpenGL style, so this generates the +//      INVERSE quaternion (-x, -y, -z, w)! +//      Because we use similar logic in LLQuaternion::getMatrix3, +//      we are internally consistant so everything works OK :) +LLQuaternion    LLMatrix3::quaternion() const +{ +    LLQuaternion    quat; +    F32     tr, s, q[4]; +    U32     i, j, k; +    U32     nxt[3] = {1, 2, 0}; + +    tr = mMatrix[0][0] + mMatrix[1][1] + mMatrix[2][2]; + +    // check the diagonal +    if (tr > 0.f) +    { +        s = (F32)sqrt (tr + 1.f); +        quat.mQ[VS] = s / 2.f; +        s = 0.5f / s; +        quat.mQ[VX] = (mMatrix[1][2] - mMatrix[2][1]) * s; +        quat.mQ[VY] = (mMatrix[2][0] - mMatrix[0][2]) * s; +        quat.mQ[VZ] = (mMatrix[0][1] - mMatrix[1][0]) * s; +    } +    else +    { +        // diagonal is negative +        i = 0; +        if (mMatrix[1][1] > mMatrix[0][0]) +            i = 1; +        if (mMatrix[2][2] > mMatrix[i][i]) +            i = 2; + +        j = nxt[i]; +        k = nxt[j]; + + +        s = (F32)sqrt ((mMatrix[i][i] - (mMatrix[j][j] + mMatrix[k][k])) + 1.f); + +        q[i] = s * 0.5f; + +        if (s != 0.f) +            s = 0.5f / s; + +        q[3] = (mMatrix[j][k] - mMatrix[k][j]) * s; +        q[j] = (mMatrix[i][j] + mMatrix[j][i]) * s; +        q[k] = (mMatrix[i][k] + mMatrix[k][i]) * s; + +        quat.setQuat(q); +    } +    return quat; +} + +const LLMatrix3&    LLMatrix3::setRot(const F32 angle, const LLVector3 &vec) +{ +    setRot(LLQuaternion(angle, vec)); +    return *this; +} + +const LLMatrix3&    LLMatrix3::setRot(const F32 roll, const F32 pitch, const F32 yaw) +{ +    // Rotates RH about x-axis by 'roll'  then +    // rotates RH about the old y-axis by 'pitch' then +    // rotates RH about the original z-axis by 'yaw'. +    //                . +    //               /|\ yaw axis +    //                |     __. +    //   ._        ___|      /| pitch axis +    //  _||\       \\ |-.   / +    //  \|| \_______\_|__\_/_______ +    //   | _ _   o o o_o_o_o o   /_\_  ________\ roll axis +    //   //  /_______/    /__________>         / +    //  /_,-'       //   / +    //             /__,-' + +    F32     cx, sx, cy, sy, cz, sz; +    F32     cxsy, sxsy;      cx = (F32)cos(roll); //A      sx = (F32)sin(roll); //B @@ -320,7 +320,7 @@ const LLMatrix3&	LLMatrix3::setRot(const F32 roll, const F32 pitch, const F32 ya      sz = (F32)sin(yaw); //F      cxsy = cx * sy; //AD -    sxsy = sx * sy; //BD  +    sxsy = sx * sy; //BD      mMatrix[0][0] =  cy * cz;      mMatrix[1][0] = -cy * sz; @@ -331,118 +331,118 @@ const LLMatrix3&	LLMatrix3::setRot(const F32 roll, const F32 pitch, const F32 ya      mMatrix[0][2] =  -cxsy * cz + sx * sz;      mMatrix[1][2] =  cxsy * sz + sx * cz;      mMatrix[2][2] =  cx * cy; -	return *this; +    return *this;  } -const LLMatrix3&	LLMatrix3::setRot(const LLQuaternion &q) +const LLMatrix3&    LLMatrix3::setRot(const LLQuaternion &q)  { -	*this = q.getMatrix3(); -	return *this; +    *this = q.getMatrix3(); +    return *this;  } -const LLMatrix3&	LLMatrix3::setRows(const LLVector3 &fwd, const LLVector3 &left, const LLVector3 &up) +const LLMatrix3&    LLMatrix3::setRows(const LLVector3 &fwd, const LLVector3 &left, const LLVector3 &up)  { -	mMatrix[0][0] = fwd.mV[0]; -	mMatrix[0][1] = fwd.mV[1]; -	mMatrix[0][2] = fwd.mV[2]; +    mMatrix[0][0] = fwd.mV[0]; +    mMatrix[0][1] = fwd.mV[1]; +    mMatrix[0][2] = fwd.mV[2]; -	mMatrix[1][0] = left.mV[0]; -	mMatrix[1][1] = left.mV[1]; -	mMatrix[1][2] = left.mV[2]; +    mMatrix[1][0] = left.mV[0]; +    mMatrix[1][1] = left.mV[1]; +    mMatrix[1][2] = left.mV[2]; -	mMatrix[2][0] = up.mV[0]; -	mMatrix[2][1] = up.mV[1]; -	mMatrix[2][2] = up.mV[2]; +    mMatrix[2][0] = up.mV[0]; +    mMatrix[2][1] = up.mV[1]; +    mMatrix[2][2] = up.mV[2]; -	return *this; +    return *this;  }  const LLMatrix3& LLMatrix3::setRow( U32 rowIndex, const LLVector3& row )  { -	llassert( rowIndex >= 0 && rowIndex < NUM_VALUES_IN_MAT3 ); +    llassert( rowIndex >= 0 && rowIndex < NUM_VALUES_IN_MAT3 ); -	mMatrix[rowIndex][0] = row[0]; -	mMatrix[rowIndex][1] = row[1]; -	mMatrix[rowIndex][2] = row[2]; +    mMatrix[rowIndex][0] = row[0]; +    mMatrix[rowIndex][1] = row[1]; +    mMatrix[rowIndex][2] = row[2]; -	return *this; +    return *this;  }  const LLMatrix3& LLMatrix3::setCol( U32 colIndex, const LLVector3& col )  { -	llassert( colIndex >= 0 && colIndex < NUM_VALUES_IN_MAT3 ); +    llassert( colIndex >= 0 && colIndex < NUM_VALUES_IN_MAT3 ); -	mMatrix[0][colIndex] = col[0]; -	mMatrix[1][colIndex] = col[1]; -	mMatrix[2][colIndex] = col[2]; +    mMatrix[0][colIndex] = col[0]; +    mMatrix[1][colIndex] = col[1]; +    mMatrix[2][colIndex] = col[2]; -	return *this; +    return *this;  } -const LLMatrix3&	LLMatrix3::rotate(const F32 angle, const LLVector3 &vec) +const LLMatrix3&    LLMatrix3::rotate(const F32 angle, const LLVector3 &vec)  { -	LLMatrix3	mat(angle, vec); -	*this *= mat; -	return *this; +    LLMatrix3   mat(angle, vec); +    *this *= mat; +    return *this;  } -const LLMatrix3&	LLMatrix3::rotate(const F32 roll, const F32 pitch, const F32 yaw) +const LLMatrix3&    LLMatrix3::rotate(const F32 roll, const F32 pitch, const F32 yaw)  { -	LLMatrix3	mat(roll, pitch, yaw);  -	*this *= mat; -	return *this; +    LLMatrix3   mat(roll, pitch, yaw); +    *this *= mat; +    return *this;  } -const LLMatrix3&	LLMatrix3::rotate(const LLQuaternion &q) +const LLMatrix3&    LLMatrix3::rotate(const LLQuaternion &q)  { -	LLMatrix3	mat(q); -	*this *= mat; -	return *this; +    LLMatrix3   mat(q); +    *this *= mat; +    return *this;  }  void LLMatrix3::add(const LLMatrix3& other_matrix)  { -	for (S32 i = 0; i < 3; ++i) -	{ -		for (S32 j = 0; j < 3; ++j) -		{ -			mMatrix[i][j] += other_matrix.mMatrix[i][j]; -		} -	} +    for (S32 i = 0; i < 3; ++i) +    { +        for (S32 j = 0; j < 3; ++j) +        { +            mMatrix[i][j] += other_matrix.mMatrix[i][j]; +        } +    }  } -LLVector3	LLMatrix3::getFwdRow() const +LLVector3   LLMatrix3::getFwdRow() const  { -	return LLVector3(mMatrix[VX]); +    return LLVector3(mMatrix[VX]);  } -LLVector3	LLMatrix3::getLeftRow() const +LLVector3   LLMatrix3::getLeftRow() const  { -	return LLVector3(mMatrix[VY]); +    return LLVector3(mMatrix[VY]);  } -LLVector3	LLMatrix3::getUpRow() const +LLVector3   LLMatrix3::getUpRow() const  { -	return LLVector3(mMatrix[VZ]); +    return LLVector3(mMatrix[VZ]);  } -const LLMatrix3&	LLMatrix3::orthogonalize() +const LLMatrix3&    LLMatrix3::orthogonalize()  { -	LLVector3 x_axis(mMatrix[VX]); -	LLVector3 y_axis(mMatrix[VY]); -	LLVector3 z_axis(mMatrix[VZ]); +    LLVector3 x_axis(mMatrix[VX]); +    LLVector3 y_axis(mMatrix[VY]); +    LLVector3 z_axis(mMatrix[VZ]); -	x_axis.normVec(); -	y_axis -= x_axis * (x_axis * y_axis); -	y_axis.normVec(); -	z_axis = x_axis % y_axis; -	setRows(x_axis, y_axis, z_axis); -	return (*this); +    x_axis.normVec(); +    y_axis -= x_axis * (x_axis * y_axis); +    y_axis.normVec(); +    z_axis = x_axis % y_axis; +    setRows(x_axis, y_axis, z_axis); +    return (*this);  } @@ -450,141 +450,141 @@ const LLMatrix3&	LLMatrix3::orthogonalize()  LLMatrix3 operator*(const LLMatrix3 &a, const LLMatrix3 &b)  { -	U32		i, j; -	LLMatrix3	mat; -	for (i = 0; i < NUM_VALUES_IN_MAT3; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT3; j++) -		{ -			mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] +  -							    a.mMatrix[j][1] * b.mMatrix[1][i] +  -							    a.mMatrix[j][2] * b.mMatrix[2][i]; -		} -	} -	return mat; -} - -/* Not implemented to help enforce code consistency with the syntax of  +    U32     i, j; +    LLMatrix3   mat; +    for (i = 0; i < NUM_VALUES_IN_MAT3; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT3; j++) +        { +            mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + +                                a.mMatrix[j][1] * b.mMatrix[1][i] + +                                a.mMatrix[j][2] * b.mMatrix[2][i]; +        } +    } +    return mat; +} + +/* Not implemented to help enforce code consistency with the syntax of     row-major notation.  This is a Good Thing.  LLVector3 operator*(const LLMatrix3 &a, const LLVector3 &b)  { -	LLVector3	vec; -	// matrix operates "from the left" on column vector -	vec.mV[VX] = a.mMatrix[VX][VX] * b.mV[VX] +  -				 a.mMatrix[VX][VY] * b.mV[VY] +  -				 a.mMatrix[VX][VZ] * b.mV[VZ]; -	 -	vec.mV[VY] = a.mMatrix[VY][VX] * b.mV[VX] +  -				 a.mMatrix[VY][VY] * b.mV[VY] +  -				 a.mMatrix[VY][VZ] * b.mV[VZ]; -	 -	vec.mV[VZ] = a.mMatrix[VZ][VX] * b.mV[VX] +  -				 a.mMatrix[VZ][VY] * b.mV[VY] +  -				 a.mMatrix[VZ][VZ] * b.mV[VZ]; -	return vec; +    LLVector3   vec; +    // matrix operates "from the left" on column vector +    vec.mV[VX] = a.mMatrix[VX][VX] * b.mV[VX] + +                 a.mMatrix[VX][VY] * b.mV[VY] + +                 a.mMatrix[VX][VZ] * b.mV[VZ]; + +    vec.mV[VY] = a.mMatrix[VY][VX] * b.mV[VX] + +                 a.mMatrix[VY][VY] * b.mV[VY] + +                 a.mMatrix[VY][VZ] * b.mV[VZ]; + +    vec.mV[VZ] = a.mMatrix[VZ][VX] * b.mV[VX] + +                 a.mMatrix[VZ][VY] * b.mV[VY] + +                 a.mMatrix[VZ][VZ] * b.mV[VZ]; +    return vec;  }  */  LLVector3 operator*(const LLVector3 &a, const LLMatrix3 &b)  { -	// matrix operates "from the right" on row vector -	return LLVector3( -				a.mV[VX] * b.mMatrix[VX][VX] +  -				a.mV[VY] * b.mMatrix[VY][VX] +  -				a.mV[VZ] * b.mMatrix[VZ][VX], -	 -				a.mV[VX] * b.mMatrix[VX][VY] +  -				a.mV[VY] * b.mMatrix[VY][VY] +  -				a.mV[VZ] * b.mMatrix[VZ][VY], -	 -				a.mV[VX] * b.mMatrix[VX][VZ] +  -				a.mV[VY] * b.mMatrix[VY][VZ] +  -				a.mV[VZ] * b.mMatrix[VZ][VZ] ); +    // matrix operates "from the right" on row vector +    return LLVector3( +                a.mV[VX] * b.mMatrix[VX][VX] + +                a.mV[VY] * b.mMatrix[VY][VX] + +                a.mV[VZ] * b.mMatrix[VZ][VX], + +                a.mV[VX] * b.mMatrix[VX][VY] + +                a.mV[VY] * b.mMatrix[VY][VY] + +                a.mV[VZ] * b.mMatrix[VZ][VY], + +                a.mV[VX] * b.mMatrix[VX][VZ] + +                a.mV[VY] * b.mMatrix[VY][VZ] + +                a.mV[VZ] * b.mMatrix[VZ][VZ] );  }  LLVector3d operator*(const LLVector3d &a, const LLMatrix3 &b)  { -	// matrix operates "from the right" on row vector -	return LLVector3d( -				a.mdV[VX] * b.mMatrix[VX][VX] +  -				a.mdV[VY] * b.mMatrix[VY][VX] +  -				a.mdV[VZ] * b.mMatrix[VZ][VX], -	 -				a.mdV[VX] * b.mMatrix[VX][VY] +  -				a.mdV[VY] * b.mMatrix[VY][VY] +  -				a.mdV[VZ] * b.mMatrix[VZ][VY], -	 -				a.mdV[VX] * b.mMatrix[VX][VZ] +  -				a.mdV[VY] * b.mMatrix[VY][VZ] +  -				a.mdV[VZ] * b.mMatrix[VZ][VZ] ); +    // matrix operates "from the right" on row vector +    return LLVector3d( +                a.mdV[VX] * b.mMatrix[VX][VX] + +                a.mdV[VY] * b.mMatrix[VY][VX] + +                a.mdV[VZ] * b.mMatrix[VZ][VX], + +                a.mdV[VX] * b.mMatrix[VX][VY] + +                a.mdV[VY] * b.mMatrix[VY][VY] + +                a.mdV[VZ] * b.mMatrix[VZ][VY], + +                a.mdV[VX] * b.mMatrix[VX][VZ] + +                a.mdV[VY] * b.mMatrix[VY][VZ] + +                a.mdV[VZ] * b.mMatrix[VZ][VZ] );  }  bool operator==(const LLMatrix3 &a, const LLMatrix3 &b)  { -	U32		i, j; -	for (i = 0; i < NUM_VALUES_IN_MAT3; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT3; j++) -		{ -			if (a.mMatrix[j][i] != b.mMatrix[j][i]) -				return FALSE; -		} -	} -	return TRUE; +    U32     i, j; +    for (i = 0; i < NUM_VALUES_IN_MAT3; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT3; j++) +        { +            if (a.mMatrix[j][i] != b.mMatrix[j][i]) +                return FALSE; +        } +    } +    return TRUE;  }  bool operator!=(const LLMatrix3 &a, const LLMatrix3 &b)  { -	U32		i, j; -	for (i = 0; i < NUM_VALUES_IN_MAT3; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT3; j++) -		{ -			if (a.mMatrix[j][i] != b.mMatrix[j][i]) -				return TRUE; -		} -	} -	return FALSE; +    U32     i, j; +    for (i = 0; i < NUM_VALUES_IN_MAT3; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT3; j++) +        { +            if (a.mMatrix[j][i] != b.mMatrix[j][i]) +                return TRUE; +        } +    } +    return FALSE;  }  const LLMatrix3& operator*=(LLMatrix3 &a, const LLMatrix3 &b)  { -	U32		i, j; -	LLMatrix3	mat; -	for (i = 0; i < NUM_VALUES_IN_MAT3; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT3; j++) -		{ -			mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] +  -							    a.mMatrix[j][1] * b.mMatrix[1][i] +  -							    a.mMatrix[j][2] * b.mMatrix[2][i]; -		} -	} -	a = mat; -	return a; +    U32     i, j; +    LLMatrix3   mat; +    for (i = 0; i < NUM_VALUES_IN_MAT3; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT3; j++) +        { +            mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + +                                a.mMatrix[j][1] * b.mMatrix[1][i] + +                                a.mMatrix[j][2] * b.mMatrix[2][i]; +        } +    } +    a = mat; +    return a;  }  const LLMatrix3& operator*=(LLMatrix3 &a, F32 scalar )  { -	for( U32 i = 0; i < NUM_VALUES_IN_MAT3; ++i ) -	{ -		for( U32 j = 0; j < NUM_VALUES_IN_MAT3; ++j ) -		{ -			a.mMatrix[i][j] *= scalar; -		} -	} +    for( U32 i = 0; i < NUM_VALUES_IN_MAT3; ++i ) +    { +        for( U32 j = 0; j < NUM_VALUES_IN_MAT3; ++j ) +        { +            a.mMatrix[i][j] *= scalar; +        } +    } -	return a; +    return a;  } -std::ostream& operator<<(std::ostream& s, const LLMatrix3 &a)  +std::ostream& operator<<(std::ostream& s, const LLMatrix3 &a)  { -	s << "{ "  -		<< a.mMatrix[VX][VX] << ", " << a.mMatrix[VX][VY] << ", " << a.mMatrix[VX][VZ] << "; " -		<< a.mMatrix[VY][VX] << ", " << a.mMatrix[VY][VY] << ", " << a.mMatrix[VY][VZ] << "; " -		<< a.mMatrix[VZ][VX] << ", " << a.mMatrix[VZ][VY] << ", " << a.mMatrix[VZ][VZ]  -	  << " }"; -	return s; +    s << "{ " +        << a.mMatrix[VX][VX] << ", " << a.mMatrix[VX][VY] << ", " << a.mMatrix[VX][VZ] << "; " +        << a.mMatrix[VY][VX] << ", " << a.mMatrix[VY][VY] << ", " << a.mMatrix[VY][VZ] << "; " +        << a.mMatrix[VZ][VX] << ", " << a.mMatrix[VZ][VY] << ", " << a.mMatrix[VZ][VZ] +      << " }"; +    return s;  } diff --git a/indra/llmath/m3math.h b/indra/llmath/m3math.h index bf38895855..cd14290246 100644 --- a/indra/llmath/m3math.h +++ b/indra/llmath/m3math.h @@ -1,25 +1,25 @@ -/**  +/**   * @file m3math.h   * @brief LLMatrix3 class header file.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -37,139 +37,139 @@ class LLQuaternion;  // NOTA BENE: Currently assuming a right-handed, z-up universe -//			     ji	 +//               ji  // LLMatrix3 = | 00 01 02 | -//			   | 10 11 12 | -//			   | 20 21 22 | +//             | 10 11 12 | +//             | 20 21 22 | -// LLMatrix3 = | fx fy fz |	forward-axis -//			   | lx ly lz |	left-axis -//			   | ux uy uz |	up-axis +// LLMatrix3 = | fx fy fz | forward-axis +//             | lx ly lz | left-axis +//             | ux uy uz | up-axis -// NOTE: The world of computer graphics uses column-vectors and matricies that  -// "operate to the left".  +// NOTE: The world of computer graphics uses column-vectors and matricies that +// "operate to the left". -static const U32 NUM_VALUES_IN_MAT3	= 3; +static const U32 NUM_VALUES_IN_MAT3 = 3;  class LLMatrix3  { -	public: -		F32	mMatrix[NUM_VALUES_IN_MAT3][NUM_VALUES_IN_MAT3]; - -		LLMatrix3(void);							// Initializes Matrix to identity matrix -		explicit LLMatrix3(const F32 *mat);					// Initializes Matrix to values in mat -		explicit LLMatrix3(const LLQuaternion &q);			// Initializes Matrix with rotation q - -		LLMatrix3(const F32 angle, const LLVector3 &vec);	// Initializes Matrix with axis angle -		LLMatrix3(const F32 angle, const LLVector3d &vec);	// Initializes Matrix with axis angle -		LLMatrix3(const F32 angle, const LLVector4 &vec);	// Initializes Matrix with axis angle -		LLMatrix3(const F32 roll, const F32 pitch, const F32 yaw);	// Initializes Matrix with Euler angles - -		////////////////////////////// -		// -		// Matrix initializers - these replace any existing values in the matrix -		// - -		// various useful matrix functions -		const LLMatrix3& setIdentity();				// Load identity matrix -		const LLMatrix3& clear();					// Clears Matrix to zero -		const LLMatrix3& setZero();					// Clears Matrix to zero - -		/////////////////////////// -		// -		// Matrix setters - set some properties without modifying others -		// - -		// These functions take Rotation arguments		 -		const LLMatrix3& setRot(const F32 angle, const LLVector3 &vec);	// Calculate rotation matrix for rotating angle radians about vec -		const LLMatrix3& setRot(const F32 roll, const F32 pitch, const F32 yaw);	// Calculate rotation matrix from Euler angles -		const LLMatrix3& setRot(const LLQuaternion &q);			// Transform matrix by Euler angles and translating by pos - -		const LLMatrix3& setRows(const LLVector3 &x_axis, const LLVector3 &y_axis, const LLVector3 &z_axis); -		const LLMatrix3& setRow( U32 rowIndex, const LLVector3& row ); -		const LLMatrix3& setCol( U32 colIndex, const LLVector3& col ); - -		 -		/////////////////////////// -		// -		// Get properties of a matrix -		// -		LLQuaternion quaternion() const;		// Returns quaternion from mat -		void getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const;	// Returns Euler angles, in radians - -		// Axis extraction routines -		LLVector3 getFwdRow() const; -		LLVector3 getLeftRow() const; -		LLVector3 getUpRow() const; -		F32	 determinant() const;			// Return determinant - - -		/////////////////////////// -		// -		// Operations on an existing matrix -		// -		const LLMatrix3& transpose();		// Transpose MAT4 -		const LLMatrix3& orthogonalize();	// Orthogonalizes X, then Y, then Z -		void invert();			// Invert MAT4 -		const LLMatrix3& adjointTranspose();// returns transpose of matrix adjoint, for multiplying normals - -		 -		// Rotate existing matrix   -		// Note: the two lines below are equivalent: -		//	foo.rotate(bar)  -		//	foo = foo * bar -		// That is, foo.rotate(bar) multiplies foo by bar FROM THE RIGHT -		const LLMatrix3& rotate(const F32 angle, const F32 x, const F32 y, const F32 z); 	// Rotate matrix by rotating angle radians about (x, y, z) -		const LLMatrix3& rotate(const F32 angle, const LLVector3 &vec);						// Rotate matrix by rotating angle radians about vec -		const LLMatrix3& rotate(const F32 roll, const F32 pitch, const F32 yaw); 			// Rotate matrix by roll (about x), pitch (about y), and yaw (about z) -		const LLMatrix3& rotate(const LLQuaternion &q);			// Transform matrix by Euler angles and translating by pos - -		void add(const LLMatrix3& other_matrix);	// add other_matrix to this one +    public: +        F32 mMatrix[NUM_VALUES_IN_MAT3][NUM_VALUES_IN_MAT3]; + +        LLMatrix3(void);                            // Initializes Matrix to identity matrix +        explicit LLMatrix3(const F32 *mat);                 // Initializes Matrix to values in mat +        explicit LLMatrix3(const LLQuaternion &q);          // Initializes Matrix with rotation q + +        LLMatrix3(const F32 angle, const LLVector3 &vec);   // Initializes Matrix with axis angle +        LLMatrix3(const F32 angle, const LLVector3d &vec);  // Initializes Matrix with axis angle +        LLMatrix3(const F32 angle, const LLVector4 &vec);   // Initializes Matrix with axis angle +        LLMatrix3(const F32 roll, const F32 pitch, const F32 yaw);  // Initializes Matrix with Euler angles + +        ////////////////////////////// +        // +        // Matrix initializers - these replace any existing values in the matrix +        // + +        // various useful matrix functions +        const LLMatrix3& setIdentity();             // Load identity matrix +        const LLMatrix3& clear();                   // Clears Matrix to zero +        const LLMatrix3& setZero();                 // Clears Matrix to zero + +        /////////////////////////// +        // +        // Matrix setters - set some properties without modifying others +        // + +        // These functions take Rotation arguments +        const LLMatrix3& setRot(const F32 angle, const LLVector3 &vec); // Calculate rotation matrix for rotating angle radians about vec +        const LLMatrix3& setRot(const F32 roll, const F32 pitch, const F32 yaw);    // Calculate rotation matrix from Euler angles +        const LLMatrix3& setRot(const LLQuaternion &q);         // Transform matrix by Euler angles and translating by pos + +        const LLMatrix3& setRows(const LLVector3 &x_axis, const LLVector3 &y_axis, const LLVector3 &z_axis); +        const LLMatrix3& setRow( U32 rowIndex, const LLVector3& row ); +        const LLMatrix3& setCol( U32 colIndex, const LLVector3& col ); + + +        /////////////////////////// +        // +        // Get properties of a matrix +        // +        LLQuaternion quaternion() const;        // Returns quaternion from mat +        void getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const; // Returns Euler angles, in radians + +        // Axis extraction routines +        LLVector3 getFwdRow() const; +        LLVector3 getLeftRow() const; +        LLVector3 getUpRow() const; +        F32  determinant() const;           // Return determinant + + +        /////////////////////////// +        // +        // Operations on an existing matrix +        // +        const LLMatrix3& transpose();       // Transpose MAT4 +        const LLMatrix3& orthogonalize();   // Orthogonalizes X, then Y, then Z +        void invert();          // Invert MAT4 +        const LLMatrix3& adjointTranspose();// returns transpose of matrix adjoint, for multiplying normals + + +        // Rotate existing matrix +        // Note: the two lines below are equivalent: +        //  foo.rotate(bar) +        //  foo = foo * bar +        // That is, foo.rotate(bar) multiplies foo by bar FROM THE RIGHT +        const LLMatrix3& rotate(const F32 angle, const F32 x, const F32 y, const F32 z);    // Rotate matrix by rotating angle radians about (x, y, z) +        const LLMatrix3& rotate(const F32 angle, const LLVector3 &vec);                     // Rotate matrix by rotating angle radians about vec +        const LLMatrix3& rotate(const F32 roll, const F32 pitch, const F32 yaw);            // Rotate matrix by roll (about x), pitch (about y), and yaw (about z) +        const LLMatrix3& rotate(const LLQuaternion &q);         // Transform matrix by Euler angles and translating by pos + +        void add(const LLMatrix3& other_matrix);    // add other_matrix to this one  // This operator is misleading as to operation direction -//		friend LLVector3 operator*(const LLMatrix3 &a, const LLVector3 &b);			// Apply rotation a to vector b +//      friend LLVector3 operator*(const LLMatrix3 &a, const LLVector3 &b);         // Apply rotation a to vector b -		friend LLVector3 operator*(const LLVector3 &a, const LLMatrix3 &b);			// Apply rotation b to vector a -		friend LLVector3d operator*(const LLVector3d &a, const LLMatrix3 &b);			// Apply rotation b to vector a -		friend LLMatrix3 operator*(const LLMatrix3 &a, const LLMatrix3 &b);			// Return a * b +        friend LLVector3 operator*(const LLVector3 &a, const LLMatrix3 &b);         // Apply rotation b to vector a +        friend LLVector3d operator*(const LLVector3d &a, const LLMatrix3 &b);           // Apply rotation b to vector a +        friend LLMatrix3 operator*(const LLMatrix3 &a, const LLMatrix3 &b);         // Return a * b -		friend bool operator==(const LLMatrix3 &a, const LLMatrix3 &b);				// Return a == b -		friend bool operator!=(const LLMatrix3 &a, const LLMatrix3 &b);				// Return a != b +        friend bool operator==(const LLMatrix3 &a, const LLMatrix3 &b);             // Return a == b +        friend bool operator!=(const LLMatrix3 &a, const LLMatrix3 &b);             // Return a != b -		friend const LLMatrix3& operator*=(LLMatrix3 &a, const LLMatrix3 &b);				// Return a * b -		friend const LLMatrix3& operator*=(LLMatrix3 &a, F32 scalar );						// Return a * scalar +        friend const LLMatrix3& operator*=(LLMatrix3 &a, const LLMatrix3 &b);               // Return a * b +        friend const LLMatrix3& operator*=(LLMatrix3 &a, F32 scalar );                      // Return a * scalar -		friend std::ostream&	 operator<<(std::ostream& s, const LLMatrix3 &a);	// Stream a +        friend std::ostream&     operator<<(std::ostream& s, const LLMatrix3 &a);   // Stream a  };  inline LLMatrix3::LLMatrix3(void)  { -	mMatrix[0][0] = 1.f; -	mMatrix[0][1] = 0.f; -	mMatrix[0][2] = 0.f; +    mMatrix[0][0] = 1.f; +    mMatrix[0][1] = 0.f; +    mMatrix[0][2] = 0.f; -	mMatrix[1][0] = 0.f; -	mMatrix[1][1] = 1.f; -	mMatrix[1][2] = 0.f; +    mMatrix[1][0] = 0.f; +    mMatrix[1][1] = 1.f; +    mMatrix[1][2] = 0.f; -	mMatrix[2][0] = 0.f; -	mMatrix[2][1] = 0.f; -	mMatrix[2][2] = 1.f; +    mMatrix[2][0] = 0.f; +    mMatrix[2][1] = 0.f; +    mMatrix[2][2] = 1.f;  }  inline LLMatrix3::LLMatrix3(const F32 *mat)  { -	mMatrix[0][0] = mat[0]; -	mMatrix[0][1] = mat[1]; -	mMatrix[0][2] = mat[2]; +    mMatrix[0][0] = mat[0]; +    mMatrix[0][1] = mat[1]; +    mMatrix[0][2] = mat[2]; -	mMatrix[1][0] = mat[3]; -	mMatrix[1][1] = mat[4]; -	mMatrix[1][2] = mat[5]; +    mMatrix[1][0] = mat[3]; +    mMatrix[1][1] = mat[4]; +    mMatrix[1][2] = mat[5]; -	mMatrix[2][0] = mat[6]; -	mMatrix[2][1] = mat[7]; -	mMatrix[2][2] = mat[8]; +    mMatrix[2][0] = mat[6]; +    mMatrix[2][1] = mat[7]; +    mMatrix[2][2] = mat[8];  } @@ -187,7 +187,7 @@ inline LLMatrix3::LLMatrix3(const F32 *mat)  // Creating Rotation Matricies From Object Axes  // --------------------------------------------  // Suppose you know the three axes of some object in some "absolute-frame". -// If you take those three vectors and throw them into the rows of  +// If you take those three vectors and throw them into the rows of  // a rotation matrix what do you get?  //  // R = | X0  X1  X2 | @@ -198,11 +198,11 @@ inline LLMatrix3::LLMatrix3(const F32 *mat)  //  // Transpose the matrix and have it operate on a vector...  // -// V * R_transpose = [ V0  V1  V2 ] * | X0  Y0  Z0 |  -//                                    | X1  Y1  Z1 |                        +// V * R_transpose = [ V0  V1  V2 ] * | X0  Y0  Z0 | +//                                    | X1  Y1  Z1 |  //                                    | X2  Y2  Z2 | -//  -//                 = [ V*X  V*Y  V*Z ]  +// +//                 = [ V*X  V*Y  V*Z ]  //  //                 = components of V that are parallel to the three object axes  // diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 6e40dae30b..16ce00d963 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file m4math.cpp   * @brief LLMatrix4 class implementation.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -42,119 +42,119 @@  LLMatrix4::LLMatrix4(const F32 *mat)  { -	mMatrix[0][0] = mat[0]; -	mMatrix[0][1] = mat[1]; -	mMatrix[0][2] = mat[2]; -	mMatrix[0][3] = mat[3]; +    mMatrix[0][0] = mat[0]; +    mMatrix[0][1] = mat[1]; +    mMatrix[0][2] = mat[2]; +    mMatrix[0][3] = mat[3]; -	mMatrix[1][0] = mat[4]; -	mMatrix[1][1] = mat[5]; -	mMatrix[1][2] = mat[6]; -	mMatrix[1][3] = mat[7]; +    mMatrix[1][0] = mat[4]; +    mMatrix[1][1] = mat[5]; +    mMatrix[1][2] = mat[6]; +    mMatrix[1][3] = mat[7]; -	mMatrix[2][0] = mat[8]; -	mMatrix[2][1] = mat[9]; -	mMatrix[2][2] = mat[10]; -	mMatrix[2][3] = mat[11]; +    mMatrix[2][0] = mat[8]; +    mMatrix[2][1] = mat[9]; +    mMatrix[2][2] = mat[10]; +    mMatrix[2][3] = mat[11]; -	mMatrix[3][0] = mat[12]; -	mMatrix[3][1] = mat[13]; -	mMatrix[3][2] = mat[14]; -	mMatrix[3][3] = mat[15]; +    mMatrix[3][0] = mat[12]; +    mMatrix[3][1] = mat[13]; +    mMatrix[3][2] = mat[14]; +    mMatrix[3][3] = mat[15];  }  LLMatrix4::LLMatrix4(const LLMatrix3 &mat, const LLVector4 &vec)  { -	mMatrix[0][0] = mat.mMatrix[0][0]; -	mMatrix[0][1] = mat.mMatrix[0][1]; -	mMatrix[0][2] = mat.mMatrix[0][2]; -	mMatrix[0][3] = 0.f; +    mMatrix[0][0] = mat.mMatrix[0][0]; +    mMatrix[0][1] = mat.mMatrix[0][1]; +    mMatrix[0][2] = mat.mMatrix[0][2]; +    mMatrix[0][3] = 0.f; -	mMatrix[1][0] = mat.mMatrix[1][0]; -	mMatrix[1][1] = mat.mMatrix[1][1]; -	mMatrix[1][2] = mat.mMatrix[1][2]; -	mMatrix[1][3] = 0.f; +    mMatrix[1][0] = mat.mMatrix[1][0]; +    mMatrix[1][1] = mat.mMatrix[1][1]; +    mMatrix[1][2] = mat.mMatrix[1][2]; +    mMatrix[1][3] = 0.f; -	mMatrix[2][0] = mat.mMatrix[2][0]; -	mMatrix[2][1] = mat.mMatrix[2][1]; -	mMatrix[2][2] = mat.mMatrix[2][2]; -	mMatrix[2][3] = 0.f; +    mMatrix[2][0] = mat.mMatrix[2][0]; +    mMatrix[2][1] = mat.mMatrix[2][1]; +    mMatrix[2][2] = mat.mMatrix[2][2]; +    mMatrix[2][3] = 0.f; -	mMatrix[3][0] = vec.mV[0]; -	mMatrix[3][1] = vec.mV[1]; -	mMatrix[3][2] = vec.mV[2]; -	mMatrix[3][3] = 1.f; +    mMatrix[3][0] = vec.mV[0]; +    mMatrix[3][1] = vec.mV[1]; +    mMatrix[3][2] = vec.mV[2]; +    mMatrix[3][3] = 1.f;  }  LLMatrix4::LLMatrix4(const LLMatrix3 &mat)  { -	mMatrix[0][0] = mat.mMatrix[0][0]; -	mMatrix[0][1] = mat.mMatrix[0][1]; -	mMatrix[0][2] = mat.mMatrix[0][2]; -	mMatrix[0][3] = 0.f; +    mMatrix[0][0] = mat.mMatrix[0][0]; +    mMatrix[0][1] = mat.mMatrix[0][1]; +    mMatrix[0][2] = mat.mMatrix[0][2]; +    mMatrix[0][3] = 0.f; -	mMatrix[1][0] = mat.mMatrix[1][0]; -	mMatrix[1][1] = mat.mMatrix[1][1]; -	mMatrix[1][2] = mat.mMatrix[1][2]; -	mMatrix[1][3] = 0.f; +    mMatrix[1][0] = mat.mMatrix[1][0]; +    mMatrix[1][1] = mat.mMatrix[1][1]; +    mMatrix[1][2] = mat.mMatrix[1][2]; +    mMatrix[1][3] = 0.f; -	mMatrix[2][0] = mat.mMatrix[2][0]; -	mMatrix[2][1] = mat.mMatrix[2][1]; -	mMatrix[2][2] = mat.mMatrix[2][2]; -	mMatrix[2][3] = 0.f; +    mMatrix[2][0] = mat.mMatrix[2][0]; +    mMatrix[2][1] = mat.mMatrix[2][1]; +    mMatrix[2][2] = mat.mMatrix[2][2]; +    mMatrix[2][3] = 0.f; -	mMatrix[3][0] = 0.f; -	mMatrix[3][1] = 0.f; -	mMatrix[3][2] = 0.f; -	mMatrix[3][3] = 1.f; +    mMatrix[3][0] = 0.f; +    mMatrix[3][1] = 0.f; +    mMatrix[3][2] = 0.f; +    mMatrix[3][3] = 1.f;  }  LLMatrix4::LLMatrix4(const LLQuaternion &q)  { -	*this = initRotation(q); +    *this = initRotation(q);  }  LLMatrix4::LLMatrix4(const LLMatrix4a& mat)      : LLMatrix4(mat.getF32ptr())  { -     +  }  LLMatrix4::LLMatrix4(const LLQuaternion &q, const LLVector4 &pos)  { -	*this = initRotTrans(q, pos); +    *this = initRotTrans(q, pos);  }  LLMatrix4::LLMatrix4(const F32 angle, const LLVector4 &vec, const LLVector4 &pos)  { -	initRotTrans(LLQuaternion(angle, vec), pos); +    initRotTrans(LLQuaternion(angle, vec), pos);  }  LLMatrix4::LLMatrix4(const F32 angle, const LLVector4 &vec)  { -	initRotation(LLQuaternion(angle, vec)); +    initRotation(LLQuaternion(angle, vec)); -	mMatrix[3][0] = 0.f; -	mMatrix[3][1] = 0.f; -	mMatrix[3][2] = 0.f; -	mMatrix[3][3] = 1.f; +    mMatrix[3][0] = 0.f; +    mMatrix[3][1] = 0.f; +    mMatrix[3][2] = 0.f; +    mMatrix[3][3] = 1.f;  }  LLMatrix4::LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos)  { -	LLMatrix3	mat(roll, pitch, yaw); -	initRotTrans(LLQuaternion(mat), pos); +    LLMatrix3   mat(roll, pitch, yaw); +    initRotTrans(LLQuaternion(mat), pos);  }  LLMatrix4::LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw)  { -	LLMatrix3	mat(roll, pitch, yaw); -	initRotation(LLQuaternion(mat)); +    LLMatrix3   mat(roll, pitch, yaw); +    initRotation(LLQuaternion(mat)); -	mMatrix[3][0] = 0.f; -	mMatrix[3][1] = 0.f; -	mMatrix[3][2] = 0.f; -	mMatrix[3][3] = 1.f; +    mMatrix[3][0] = 0.f; +    mMatrix[3][1] = 0.f; +    mMatrix[3][2] = 0.f; +    mMatrix[3][3] = 1.f;  }  LLMatrix4::~LLMatrix4(void) @@ -165,118 +165,118 @@ LLMatrix4::~LLMatrix4(void)  const LLMatrix4& LLMatrix4::setZero()  { -	mMatrix[0][0] = 0.f; -	mMatrix[0][1] = 0.f; -	mMatrix[0][2] = 0.f; -	mMatrix[0][3] = 0.f; +    mMatrix[0][0] = 0.f; +    mMatrix[0][1] = 0.f; +    mMatrix[0][2] = 0.f; +    mMatrix[0][3] = 0.f; -	mMatrix[1][0] = 0.f; -	mMatrix[1][1] = 0.f; -	mMatrix[1][2] = 0.f; -	mMatrix[1][3] = 0.f; +    mMatrix[1][0] = 0.f; +    mMatrix[1][1] = 0.f; +    mMatrix[1][2] = 0.f; +    mMatrix[1][3] = 0.f; -	mMatrix[2][0] = 0.f; -	mMatrix[2][1] = 0.f; -	mMatrix[2][2] = 0.f; -	mMatrix[2][3] = 0.f; +    mMatrix[2][0] = 0.f; +    mMatrix[2][1] = 0.f; +    mMatrix[2][2] = 0.f; +    mMatrix[2][3] = 0.f; -	mMatrix[3][0] = 0.f; -	mMatrix[3][1] = 0.f; -	mMatrix[3][2] = 0.f; -	mMatrix[3][3] = 0.f; -	return *this; +    mMatrix[3][0] = 0.f; +    mMatrix[3][1] = 0.f; +    mMatrix[3][2] = 0.f; +    mMatrix[3][3] = 0.f; +    return *this;  }  // various useful mMatrix functions -const LLMatrix4&	LLMatrix4::transpose() +const LLMatrix4&    LLMatrix4::transpose()  { -	LLMatrix4 mat; -	mat.mMatrix[0][0] = mMatrix[0][0]; -	mat.mMatrix[1][0] = mMatrix[0][1]; -	mat.mMatrix[2][0] = mMatrix[0][2]; -	mat.mMatrix[3][0] = mMatrix[0][3]; +    LLMatrix4 mat; +    mat.mMatrix[0][0] = mMatrix[0][0]; +    mat.mMatrix[1][0] = mMatrix[0][1]; +    mat.mMatrix[2][0] = mMatrix[0][2]; +    mat.mMatrix[3][0] = mMatrix[0][3]; -	mat.mMatrix[0][1] = mMatrix[1][0]; -	mat.mMatrix[1][1] = mMatrix[1][1]; -	mat.mMatrix[2][1] = mMatrix[1][2]; -	mat.mMatrix[3][1] = mMatrix[1][3]; +    mat.mMatrix[0][1] = mMatrix[1][0]; +    mat.mMatrix[1][1] = mMatrix[1][1]; +    mat.mMatrix[2][1] = mMatrix[1][2]; +    mat.mMatrix[3][1] = mMatrix[1][3]; -	mat.mMatrix[0][2] = mMatrix[2][0]; -	mat.mMatrix[1][2] = mMatrix[2][1]; -	mat.mMatrix[2][2] = mMatrix[2][2]; -	mat.mMatrix[3][2] = mMatrix[2][3]; +    mat.mMatrix[0][2] = mMatrix[2][0]; +    mat.mMatrix[1][2] = mMatrix[2][1]; +    mat.mMatrix[2][2] = mMatrix[2][2]; +    mat.mMatrix[3][2] = mMatrix[2][3]; -	mat.mMatrix[0][3] = mMatrix[3][0]; -	mat.mMatrix[1][3] = mMatrix[3][1]; -	mat.mMatrix[2][3] = mMatrix[3][2]; -	mat.mMatrix[3][3] = mMatrix[3][3]; +    mat.mMatrix[0][3] = mMatrix[3][0]; +    mat.mMatrix[1][3] = mMatrix[3][1]; +    mat.mMatrix[2][3] = mMatrix[3][2]; +    mat.mMatrix[3][3] = mMatrix[3][3]; -	*this = mat; -	return *this; +    *this = mat; +    return *this;  }  F32 LLMatrix4::determinant() const  { -	F32 value = -	    mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][0] - -	    mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][0] - -	    mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][0] + -	    mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][0] + -	    mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][0] - -	    mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][0] - -	    mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][1] + -	    mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][1] + -	    mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][1] - -	    mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][1] - -	    mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][1] + -	    mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][1] + -	    mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][2] - -	    mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][2] - -	    mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][2] + -	    mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][2] + -	    mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][2] - -	    mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][2] - -	    mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][3] + -	    mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][3] + -	    mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][3] - -	    mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][3] - -	    mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][3] + -		mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][3]; - -	return value; +    F32 value = +        mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][0] - +        mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][0] - +        mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][0] + +        mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][0] + +        mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][0] - +        mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][0] - +        mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][1] + +        mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][1] + +        mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][1] - +        mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][1] - +        mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][1] + +        mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][1] + +        mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][2] - +        mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][2] - +        mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][2] + +        mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][2] + +        mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][2] - +        mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][2] - +        mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][3] + +        mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][3] + +        mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][3] - +        mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][3] - +        mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][3] + +        mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][3]; + +    return value;  }  // Only works for pure orthonormal, homogeneous transform matrices. -const LLMatrix4&	LLMatrix4::invert(void)  -{ -	// transpose the rotation part -	F32 temp; -	temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp; -	temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp; -	temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp; - -	// rotate the translation part by the new rotation  -	// (temporarily store in empty column of matrix) -	U32 j; -	for (j=0; j<3; j++) -	{ -		mMatrix[j][VW] =  mMatrix[VW][VX] * mMatrix[VX][j] +  -						  mMatrix[VW][VY] * mMatrix[VY][j] + -						  mMatrix[VW][VZ] * mMatrix[VZ][j];  -	} - -	// negate and copy the temporary vector back to the tranlation row -	mMatrix[VW][VX] = -mMatrix[VX][VW]; -	mMatrix[VW][VY] = -mMatrix[VY][VW]; -	mMatrix[VW][VZ] = -mMatrix[VZ][VW]; - -   	// zero the empty column again -	mMatrix[VX][VW] = mMatrix[VY][VW] = mMatrix[VZ][VW] = 0.0f; -	 -	return *this; +const LLMatrix4&    LLMatrix4::invert(void) +{ +    // transpose the rotation part +    F32 temp; +    temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp; +    temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp; +    temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp; + +    // rotate the translation part by the new rotation +    // (temporarily store in empty column of matrix) +    U32 j; +    for (j=0; j<3; j++) +    { +        mMatrix[j][VW] =  mMatrix[VW][VX] * mMatrix[VX][j] + +                          mMatrix[VW][VY] * mMatrix[VY][j] + +                          mMatrix[VW][VZ] * mMatrix[VZ][j]; +    } + +    // negate and copy the temporary vector back to the tranlation row +    mMatrix[VW][VX] = -mMatrix[VX][VW]; +    mMatrix[VW][VY] = -mMatrix[VY][VW]; +    mMatrix[VW][VZ] = -mMatrix[VZ][VW]; + +    // zero the empty column again +    mMatrix[VX][VW] = mMatrix[VY][VW] = mMatrix[VZ][VW] = 0.0f; + +    return *this;  }  // Convenience func for simplifying comparison-heavy code by @@ -284,188 +284,188 @@ const LLMatrix4&	LLMatrix4::invert(void)  //  void LLMatrix4::condition(void)  { -	U32 i; -	U32 j; -	for (i = 0; i < 3;i++) -		for (j = 0; j < 3;j++) -			mMatrix[i][j] = ((mMatrix[i][j] > -FLT_EPSILON) -							  && (mMatrix[i][j] < FLT_EPSILON)) ? 0.0f : mMatrix[i][j]; +    U32 i; +    U32 j; +    for (i = 0; i < 3;i++) +        for (j = 0; j < 3;j++) +            mMatrix[i][j] = ((mMatrix[i][j] > -FLT_EPSILON) +                              && (mMatrix[i][j] < FLT_EPSILON)) ? 0.0f : mMatrix[i][j];  }  LLVector4 LLMatrix4::getFwdRow4() const  { -	return LLVector4(mMatrix[VX][VX], mMatrix[VX][VY], mMatrix[VX][VZ], mMatrix[VX][VW]); +    return LLVector4(mMatrix[VX][VX], mMatrix[VX][VY], mMatrix[VX][VZ], mMatrix[VX][VW]);  }  LLVector4 LLMatrix4::getLeftRow4() const  { -	return LLVector4(mMatrix[VY][VX], mMatrix[VY][VY], mMatrix[VY][VZ], mMatrix[VY][VW]); +    return LLVector4(mMatrix[VY][VX], mMatrix[VY][VY], mMatrix[VY][VZ], mMatrix[VY][VW]);  }  LLVector4 LLMatrix4::getUpRow4() const  { -	return LLVector4(mMatrix[VZ][VX], mMatrix[VZ][VY], mMatrix[VZ][VZ], mMatrix[VZ][VW]); +    return LLVector4(mMatrix[VZ][VX], mMatrix[VZ][VY], mMatrix[VZ][VZ], mMatrix[VZ][VW]);  }  // SJB: This code is correct for a logicly stored (non-transposed) matrix; -//		Our matrices are stored transposed, OpenGL style, so this generates the -//		INVERSE quaternion (-x, -y, -z, w)! -//		Because we use similar logic in LLQuaternion::getMatrix3, -//		we are internally consistant so everything works OK :) -LLQuaternion	LLMatrix4::quaternion() const +//      Our matrices are stored transposed, OpenGL style, so this generates the +//      INVERSE quaternion (-x, -y, -z, w)! +//      Because we use similar logic in LLQuaternion::getMatrix3, +//      we are internally consistant so everything works OK :) +LLQuaternion    LLMatrix4::quaternion() const  { -	LLQuaternion	quat; -	F32		tr, s, q[4]; -	U32		i, j, k; -	U32		nxt[3] = {1, 2, 0}; +    LLQuaternion    quat; +    F32     tr, s, q[4]; +    U32     i, j, k; +    U32     nxt[3] = {1, 2, 0}; -	tr = mMatrix[0][0] + mMatrix[1][1] + mMatrix[2][2]; +    tr = mMatrix[0][0] + mMatrix[1][1] + mMatrix[2][2]; -	// check the diagonal -	if (tr > 0.f)  -	{ -		s = (F32)sqrt (tr + 1.f); -		quat.mQ[VS] = s / 2.f; -		s = 0.5f / s; -		quat.mQ[VX] = (mMatrix[1][2] - mMatrix[2][1]) * s; -		quat.mQ[VY] = (mMatrix[2][0] - mMatrix[0][2]) * s; -		quat.mQ[VZ] = (mMatrix[0][1] - mMatrix[1][0]) * s; -	}  -	else -	{		 -		// diagonal is negative -		i = 0; -		if (mMatrix[1][1] > mMatrix[0][0])  -			i = 1; -		if (mMatrix[2][2] > mMatrix[i][i])  -			i = 2; +    // check the diagonal +    if (tr > 0.f) +    { +        s = (F32)sqrt (tr + 1.f); +        quat.mQ[VS] = s / 2.f; +        s = 0.5f / s; +        quat.mQ[VX] = (mMatrix[1][2] - mMatrix[2][1]) * s; +        quat.mQ[VY] = (mMatrix[2][0] - mMatrix[0][2]) * s; +        quat.mQ[VZ] = (mMatrix[0][1] - mMatrix[1][0]) * s; +    } +    else +    { +        // diagonal is negative +        i = 0; +        if (mMatrix[1][1] > mMatrix[0][0]) +            i = 1; +        if (mMatrix[2][2] > mMatrix[i][i]) +            i = 2; -		j = nxt[i]; -		k = nxt[j]; +        j = nxt[i]; +        k = nxt[j]; -		s = (F32)sqrt ((mMatrix[i][i] - (mMatrix[j][j] + mMatrix[k][k])) + 1.f); +        s = (F32)sqrt ((mMatrix[i][i] - (mMatrix[j][j] + mMatrix[k][k])) + 1.f); -		q[i] = s * 0.5f; +        q[i] = s * 0.5f; -		if (s != 0.f)  -			s = 0.5f / s; +        if (s != 0.f) +            s = 0.5f / s; -		q[3] = (mMatrix[j][k] - mMatrix[k][j]) * s; -		q[j] = (mMatrix[i][j] + mMatrix[j][i]) * s; -		q[k] = (mMatrix[i][k] + mMatrix[k][i]) * s; +        q[3] = (mMatrix[j][k] - mMatrix[k][j]) * s; +        q[j] = (mMatrix[i][j] + mMatrix[j][i]) * s; +        q[k] = (mMatrix[i][k] + mMatrix[k][i]) * s; -		quat.setQuat(q); -	} -	return quat; +        quat.setQuat(q); +    } +    return quat;  }  void LLMatrix4::initRows(const LLVector4 &row0, -						 const LLVector4 &row1, -						 const LLVector4 &row2, -						 const LLVector4 &row3) +                         const LLVector4 &row1, +                         const LLVector4 &row2, +                         const LLVector4 &row3)  { -	mMatrix[0][0] = row0.mV[0]; -	mMatrix[0][1] = row0.mV[1]; -	mMatrix[0][2] = row0.mV[2]; -	mMatrix[0][3] = row0.mV[3]; +    mMatrix[0][0] = row0.mV[0]; +    mMatrix[0][1] = row0.mV[1]; +    mMatrix[0][2] = row0.mV[2]; +    mMatrix[0][3] = row0.mV[3]; -	mMatrix[1][0] = row1.mV[0]; -	mMatrix[1][1] = row1.mV[1]; -	mMatrix[1][2] = row1.mV[2]; -	mMatrix[1][3] = row1.mV[3]; +    mMatrix[1][0] = row1.mV[0]; +    mMatrix[1][1] = row1.mV[1]; +    mMatrix[1][2] = row1.mV[2]; +    mMatrix[1][3] = row1.mV[3]; -	mMatrix[2][0] = row2.mV[0]; -	mMatrix[2][1] = row2.mV[1]; -	mMatrix[2][2] = row2.mV[2]; -	mMatrix[2][3] = row2.mV[3]; +    mMatrix[2][0] = row2.mV[0]; +    mMatrix[2][1] = row2.mV[1]; +    mMatrix[2][2] = row2.mV[2]; +    mMatrix[2][3] = row2.mV[3]; -	mMatrix[3][0] = row3.mV[0]; -	mMatrix[3][1] = row3.mV[1]; -	mMatrix[3][2] = row3.mV[2]; -	mMatrix[3][3] = row3.mV[3]; +    mMatrix[3][0] = row3.mV[0]; +    mMatrix[3][1] = row3.mV[1]; +    mMatrix[3][2] = row3.mV[2]; +    mMatrix[3][3] = row3.mV[3];  } -const LLMatrix4& 	LLMatrix4::initRotation(F32 angle, const LLVector4 &vec) +const LLMatrix4&    LLMatrix4::initRotation(F32 angle, const LLVector4 &vec)  { -	LLMatrix3	mat(angle, vec); -	return initMatrix(mat); +    LLMatrix3   mat(angle, vec); +    return initMatrix(mat);  } -const LLMatrix4& 	LLMatrix4::initRotation(const F32 roll, const F32 pitch, const F32 yaw) +const LLMatrix4&    LLMatrix4::initRotation(const F32 roll, const F32 pitch, const F32 yaw)  { -	LLMatrix3	mat(roll, pitch, yaw); -	return initMatrix(mat); +    LLMatrix3   mat(roll, pitch, yaw); +    return initMatrix(mat);  } -const LLMatrix4&  	LLMatrix4::initRotation(const LLQuaternion &q) +const LLMatrix4&    LLMatrix4::initRotation(const LLQuaternion &q)  { -	LLMatrix3	mat(q); -	return initMatrix(mat); +    LLMatrix3   mat(q); +    return initMatrix(mat);  } -const LLMatrix4&  	LLMatrix4::initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3&translation) +const LLMatrix4&    LLMatrix4::initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3&translation)  { -	LLMatrix3	mat(angle, axis); -	initMatrix(mat); -	setTranslation(translation); -	return (*this); +    LLMatrix3   mat(angle, axis); +    initMatrix(mat); +    setTranslation(translation); +    return (*this);  } -const LLMatrix4&  	LLMatrix4::initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &translation) +const LLMatrix4&    LLMatrix4::initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &translation)  { -	LLMatrix3	mat(roll, pitch, yaw); -	initMatrix(mat); -	setTranslation(translation); -	return (*this); +    LLMatrix3   mat(roll, pitch, yaw); +    initMatrix(mat); +    setTranslation(translation); +    return (*this);  }  /* -const LLMatrix4&  	LLMatrix4::initRotTrans(const LLVector4 &fwd,  -											const LLVector4 &left,  -											const LLVector4 &up,  -											const LLVector4 &translation) +const LLMatrix4&    LLMatrix4::initRotTrans(const LLVector4 &fwd, +                                            const LLVector4 &left, +                                            const LLVector4 &up, +                                            const LLVector4 &translation)  { -	LLMatrix3 mat(fwd, left, up); -	initMatrix(mat); -	setTranslation(translation); -	return (*this); +    LLMatrix3 mat(fwd, left, up); +    initMatrix(mat); +    setTranslation(translation); +    return (*this);  }  */ -const LLMatrix4&  	LLMatrix4::initRotTrans(const LLQuaternion &q, const LLVector4 &translation) +const LLMatrix4&    LLMatrix4::initRotTrans(const LLQuaternion &q, const LLVector4 &translation)  { -	LLMatrix3	mat(q); -	initMatrix(mat); -	setTranslation(translation); -	return (*this); +    LLMatrix3   mat(q); +    initMatrix(mat); +    setTranslation(translation); +    return (*this);  }  const LLMatrix4& LLMatrix4::initScale(const LLVector3 &scale)  { -	setIdentity(); +    setIdentity(); + +    mMatrix[VX][VX] = scale.mV[VX]; +    mMatrix[VY][VY] = scale.mV[VY]; +    mMatrix[VZ][VZ] = scale.mV[VZ]; -	mMatrix[VX][VX] = scale.mV[VX]; -	mMatrix[VY][VY] = scale.mV[VY]; -	mMatrix[VZ][VZ] = scale.mV[VZ]; -	 -	return (*this); +    return (*this);  }  const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos)  { -	F32		sx, sy, sz; -	F32		xx, xy, xz, xw, yy, yz, yw, zz, zw; +    F32     sx, sy, sz; +    F32     xx, xy, xz, xw, yy, yz, yw, zz, zw; -	sx      = scale.mV[0]; -	sy      = scale.mV[1]; -	sz      = scale.mV[2]; +    sx      = scale.mV[0]; +    sy      = scale.mV[1]; +    sz      = scale.mV[2];      xx      = q.mQ[VX] * q.mQ[VX];      xy      = q.mQ[VX] * q.mQ[VY]; @@ -480,394 +480,394 @@ const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &      zw      = q.mQ[VZ] * q.mQ[VW];      mMatrix[0][0]  = (1.f - 2.f * ( yy + zz )) *sx; -    mMatrix[0][1]  = (	    2.f * ( xy + zw )) *sx; -    mMatrix[0][2]  = (	    2.f * ( xz - yw )) *sx; +    mMatrix[0][1]  = (      2.f * ( xy + zw )) *sx; +    mMatrix[0][2]  = (      2.f * ( xz - yw )) *sx; -    mMatrix[1][0]  = ( 	    2.f * ( xy - zw )) *sy; +    mMatrix[1][0]  = (      2.f * ( xy - zw )) *sy;      mMatrix[1][1]  = (1.f - 2.f * ( xx + zz )) *sy;      mMatrix[1][2]  = (      2.f * ( yz + xw )) *sy; -    mMatrix[2][0]  = (	    2.f * ( xz + yw )) *sz; -    mMatrix[2][1]  = ( 	    2.f * ( yz - xw )) *sz; +    mMatrix[2][0]  = (      2.f * ( xz + yw )) *sz; +    mMatrix[2][1]  = (      2.f * ( yz - xw )) *sz;      mMatrix[2][2]  = (1.f - 2.f * ( xx + yy )) *sz; -	mMatrix[3][0]  = pos.mV[0]; -	mMatrix[3][1]  = pos.mV[1]; -	mMatrix[3][2]  = pos.mV[2]; -	mMatrix[3][3]  = 1.0; +    mMatrix[3][0]  = pos.mV[0]; +    mMatrix[3][1]  = pos.mV[1]; +    mMatrix[3][2]  = pos.mV[2]; +    mMatrix[3][3]  = 1.0; -	// TODO -- should we set the translation portion to zero? -	return (*this); +    // TODO -- should we set the translation portion to zero? +    return (*this);  } -const LLMatrix4&  	LLMatrix4::rotate(const F32 angle, const LLVector4 &vec) +const LLMatrix4&    LLMatrix4::rotate(const F32 angle, const LLVector4 &vec)  { -	LLMatrix4	mat(angle, vec); -	*this *= mat; -	return *this; +    LLMatrix4   mat(angle, vec); +    *this *= mat; +    return *this;  } -const LLMatrix4&  	LLMatrix4::rotate(const F32 roll, const F32 pitch, const F32 yaw) +const LLMatrix4&    LLMatrix4::rotate(const F32 roll, const F32 pitch, const F32 yaw)  { -	LLMatrix4	mat(roll, pitch, yaw); -	*this *= mat; -	return *this; +    LLMatrix4   mat(roll, pitch, yaw); +    *this *= mat; +    return *this;  } -const LLMatrix4&  	LLMatrix4::rotate(const LLQuaternion &q) +const LLMatrix4&    LLMatrix4::rotate(const LLQuaternion &q)  { -	LLMatrix4	mat(q); -	*this *= mat; -	return *this; +    LLMatrix4   mat(q); +    *this *= mat; +    return *this;  } -const LLMatrix4&  	LLMatrix4::translate(const LLVector3 &vec) +const LLMatrix4&    LLMatrix4::translate(const LLVector3 &vec)  { -	mMatrix[3][0] += vec.mV[0]; -	mMatrix[3][1] += vec.mV[1]; -	mMatrix[3][2] += vec.mV[2]; -	return (*this); +    mMatrix[3][0] += vec.mV[0]; +    mMatrix[3][1] += vec.mV[1]; +    mMatrix[3][2] += vec.mV[2]; +    return (*this);  }  void LLMatrix4::setFwdRow(const LLVector3 &row)  { -	mMatrix[VX][VX] = row.mV[VX]; -	mMatrix[VX][VY] = row.mV[VY]; -	mMatrix[VX][VZ] = row.mV[VZ]; +    mMatrix[VX][VX] = row.mV[VX]; +    mMatrix[VX][VY] = row.mV[VY]; +    mMatrix[VX][VZ] = row.mV[VZ];  }  void LLMatrix4::setLeftRow(const LLVector3 &row)  { -	mMatrix[VY][VX] = row.mV[VX]; -	mMatrix[VY][VY] = row.mV[VY]; -	mMatrix[VY][VZ] = row.mV[VZ]; +    mMatrix[VY][VX] = row.mV[VX]; +    mMatrix[VY][VY] = row.mV[VY]; +    mMatrix[VY][VZ] = row.mV[VZ];  }  void LLMatrix4::setUpRow(const LLVector3 &row)  { -	mMatrix[VZ][VX] = row.mV[VX]; -	mMatrix[VZ][VY] = row.mV[VY]; -	mMatrix[VZ][VZ] = row.mV[VZ]; +    mMatrix[VZ][VX] = row.mV[VX]; +    mMatrix[VZ][VY] = row.mV[VY]; +    mMatrix[VZ][VZ] = row.mV[VZ];  }  void LLMatrix4::setFwdCol(const LLVector3 &col)  { -	mMatrix[VX][VX] = col.mV[VX]; -	mMatrix[VY][VX] = col.mV[VY]; -	mMatrix[VZ][VX] = col.mV[VZ]; +    mMatrix[VX][VX] = col.mV[VX]; +    mMatrix[VY][VX] = col.mV[VY]; +    mMatrix[VZ][VX] = col.mV[VZ];  }  void LLMatrix4::setLeftCol(const LLVector3 &col)  { -	mMatrix[VX][VY] = col.mV[VX]; -	mMatrix[VY][VY] = col.mV[VY]; -	mMatrix[VZ][VY] = col.mV[VZ]; +    mMatrix[VX][VY] = col.mV[VX]; +    mMatrix[VY][VY] = col.mV[VY]; +    mMatrix[VZ][VY] = col.mV[VZ];  }  void LLMatrix4::setUpCol(const LLVector3 &col)  { -	mMatrix[VX][VZ] = col.mV[VX]; -	mMatrix[VY][VZ] = col.mV[VY]; -	mMatrix[VZ][VZ] = col.mV[VZ]; +    mMatrix[VX][VZ] = col.mV[VX]; +    mMatrix[VY][VZ] = col.mV[VY]; +    mMatrix[VZ][VZ] = col.mV[VZ];  } -const LLMatrix4&  	LLMatrix4::setTranslation(const F32 tx, const F32 ty, const F32 tz) +const LLMatrix4&    LLMatrix4::setTranslation(const F32 tx, const F32 ty, const F32 tz)  { -	mMatrix[VW][VX] = tx; -	mMatrix[VW][VY] = ty; -	mMatrix[VW][VZ] = tz; -	return (*this); +    mMatrix[VW][VX] = tx; +    mMatrix[VW][VY] = ty; +    mMatrix[VW][VZ] = tz; +    return (*this);  } -const LLMatrix4&  	LLMatrix4::setTranslation(const LLVector3 &translation) +const LLMatrix4&    LLMatrix4::setTranslation(const LLVector3 &translation)  { -	mMatrix[VW][VX] = translation.mV[VX]; -	mMatrix[VW][VY] = translation.mV[VY]; -	mMatrix[VW][VZ] = translation.mV[VZ]; -	return (*this); +    mMatrix[VW][VX] = translation.mV[VX]; +    mMatrix[VW][VY] = translation.mV[VY]; +    mMatrix[VW][VZ] = translation.mV[VZ]; +    return (*this);  } -const LLMatrix4&  	LLMatrix4::setTranslation(const LLVector4 &translation) +const LLMatrix4&    LLMatrix4::setTranslation(const LLVector4 &translation)  { -	mMatrix[VW][VX] = translation.mV[VX]; -	mMatrix[VW][VY] = translation.mV[VY]; -	mMatrix[VW][VZ] = translation.mV[VZ]; -	return (*this); +    mMatrix[VW][VX] = translation.mV[VX]; +    mMatrix[VW][VY] = translation.mV[VY]; +    mMatrix[VW][VZ] = translation.mV[VZ]; +    return (*this);  }  // LLMatrix3 Extraction and Setting -LLMatrix3  	LLMatrix4::getMat3() const +LLMatrix3   LLMatrix4::getMat3() const  { -	LLMatrix3 retmat; +    LLMatrix3 retmat; -	retmat.mMatrix[0][0] = mMatrix[0][0]; -	retmat.mMatrix[0][1] = mMatrix[0][1]; -	retmat.mMatrix[0][2] = mMatrix[0][2]; +    retmat.mMatrix[0][0] = mMatrix[0][0]; +    retmat.mMatrix[0][1] = mMatrix[0][1]; +    retmat.mMatrix[0][2] = mMatrix[0][2]; -	retmat.mMatrix[1][0] = mMatrix[1][0]; -	retmat.mMatrix[1][1] = mMatrix[1][1]; -	retmat.mMatrix[1][2] = mMatrix[1][2]; +    retmat.mMatrix[1][0] = mMatrix[1][0]; +    retmat.mMatrix[1][1] = mMatrix[1][1]; +    retmat.mMatrix[1][2] = mMatrix[1][2]; -	retmat.mMatrix[2][0] = mMatrix[2][0]; -	retmat.mMatrix[2][1] = mMatrix[2][1]; -	retmat.mMatrix[2][2] = mMatrix[2][2]; +    retmat.mMatrix[2][0] = mMatrix[2][0]; +    retmat.mMatrix[2][1] = mMatrix[2][1]; +    retmat.mMatrix[2][2] = mMatrix[2][2]; -	return retmat; +    return retmat;  } -const LLMatrix4&  	LLMatrix4::initMatrix(const LLMatrix3 &mat) +const LLMatrix4&    LLMatrix4::initMatrix(const LLMatrix3 &mat)  { -	mMatrix[0][0] = mat.mMatrix[0][0]; -	mMatrix[0][1] = mat.mMatrix[0][1]; -	mMatrix[0][2] = mat.mMatrix[0][2]; -	mMatrix[0][3] = 0.f; +    mMatrix[0][0] = mat.mMatrix[0][0]; +    mMatrix[0][1] = mat.mMatrix[0][1]; +    mMatrix[0][2] = mat.mMatrix[0][2]; +    mMatrix[0][3] = 0.f; -	mMatrix[1][0] = mat.mMatrix[1][0]; -	mMatrix[1][1] = mat.mMatrix[1][1]; -	mMatrix[1][2] = mat.mMatrix[1][2]; -	mMatrix[1][3] = 0.f; +    mMatrix[1][0] = mat.mMatrix[1][0]; +    mMatrix[1][1] = mat.mMatrix[1][1]; +    mMatrix[1][2] = mat.mMatrix[1][2]; +    mMatrix[1][3] = 0.f; -	mMatrix[2][0] = mat.mMatrix[2][0]; -	mMatrix[2][1] = mat.mMatrix[2][1]; -	mMatrix[2][2] = mat.mMatrix[2][2]; -	mMatrix[2][3] = 0.f; +    mMatrix[2][0] = mat.mMatrix[2][0]; +    mMatrix[2][1] = mat.mMatrix[2][1]; +    mMatrix[2][2] = mat.mMatrix[2][2]; +    mMatrix[2][3] = 0.f; -	mMatrix[3][0] = 0.f; -	mMatrix[3][1] = 0.f; -	mMatrix[3][2] = 0.f; -	mMatrix[3][3] = 1.f; -	return (*this); +    mMatrix[3][0] = 0.f; +    mMatrix[3][1] = 0.f; +    mMatrix[3][2] = 0.f; +    mMatrix[3][3] = 1.f; +    return (*this);  } -const LLMatrix4&  	LLMatrix4::initMatrix(const LLMatrix3 &mat, const LLVector4 &translation) +const LLMatrix4&    LLMatrix4::initMatrix(const LLMatrix3 &mat, const LLVector4 &translation)  { -	mMatrix[0][0] = mat.mMatrix[0][0]; -	mMatrix[0][1] = mat.mMatrix[0][1]; -	mMatrix[0][2] = mat.mMatrix[0][2]; -	mMatrix[0][3] = 0.f; +    mMatrix[0][0] = mat.mMatrix[0][0]; +    mMatrix[0][1] = mat.mMatrix[0][1]; +    mMatrix[0][2] = mat.mMatrix[0][2]; +    mMatrix[0][3] = 0.f; -	mMatrix[1][0] = mat.mMatrix[1][0]; -	mMatrix[1][1] = mat.mMatrix[1][1]; -	mMatrix[1][2] = mat.mMatrix[1][2]; -	mMatrix[1][3] = 0.f; +    mMatrix[1][0] = mat.mMatrix[1][0]; +    mMatrix[1][1] = mat.mMatrix[1][1]; +    mMatrix[1][2] = mat.mMatrix[1][2]; +    mMatrix[1][3] = 0.f; -	mMatrix[2][0] = mat.mMatrix[2][0]; -	mMatrix[2][1] = mat.mMatrix[2][1]; -	mMatrix[2][2] = mat.mMatrix[2][2]; -	mMatrix[2][3] = 0.f; +    mMatrix[2][0] = mat.mMatrix[2][0]; +    mMatrix[2][1] = mat.mMatrix[2][1]; +    mMatrix[2][2] = mat.mMatrix[2][2]; +    mMatrix[2][3] = 0.f; -	mMatrix[3][0] = translation.mV[0]; -	mMatrix[3][1] = translation.mV[1]; -	mMatrix[3][2] = translation.mV[2]; -	mMatrix[3][3] = 1.f; -	return (*this); +    mMatrix[3][0] = translation.mV[0]; +    mMatrix[3][1] = translation.mV[1]; +    mMatrix[3][2] = translation.mV[2]; +    mMatrix[3][3] = 1.f; +    return (*this);  }  // LLMatrix4 Operators  LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b)  { -	// Operate "to the left" on row-vector a -	return LLVector4(a.mV[VX] * b.mMatrix[VX][VX] +  -					 a.mV[VY] * b.mMatrix[VY][VX] +  -					 a.mV[VZ] * b.mMatrix[VZ][VX] + -					 a.mV[VW] * b.mMatrix[VW][VX], +    // Operate "to the left" on row-vector a +    return LLVector4(a.mV[VX] * b.mMatrix[VX][VX] + +                     a.mV[VY] * b.mMatrix[VY][VX] + +                     a.mV[VZ] * b.mMatrix[VZ][VX] + +                     a.mV[VW] * b.mMatrix[VW][VX], -					 a.mV[VX] * b.mMatrix[VX][VY] +  -					 a.mV[VY] * b.mMatrix[VY][VY] +  -					 a.mV[VZ] * b.mMatrix[VZ][VY] + -					 a.mV[VW] * b.mMatrix[VW][VY], +                     a.mV[VX] * b.mMatrix[VX][VY] + +                     a.mV[VY] * b.mMatrix[VY][VY] + +                     a.mV[VZ] * b.mMatrix[VZ][VY] + +                     a.mV[VW] * b.mMatrix[VW][VY], -					 a.mV[VX] * b.mMatrix[VX][VZ] +  -					 a.mV[VY] * b.mMatrix[VY][VZ] +  -					 a.mV[VZ] * b.mMatrix[VZ][VZ] + -					 a.mV[VW] * b.mMatrix[VW][VZ], +                     a.mV[VX] * b.mMatrix[VX][VZ] + +                     a.mV[VY] * b.mMatrix[VY][VZ] + +                     a.mV[VZ] * b.mMatrix[VZ][VZ] + +                     a.mV[VW] * b.mMatrix[VW][VZ], -					 a.mV[VX] * b.mMatrix[VX][VW] +  -					 a.mV[VY] * b.mMatrix[VY][VW] +  -					 a.mV[VZ] * b.mMatrix[VZ][VW] + -					 a.mV[VW] * b.mMatrix[VW][VW]); +                     a.mV[VX] * b.mMatrix[VX][VW] + +                     a.mV[VY] * b.mMatrix[VY][VW] + +                     a.mV[VZ] * b.mMatrix[VZ][VW] + +                     a.mV[VW] * b.mMatrix[VW][VW]);  }  LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b)  { -	// Rotates but does not translate -	// Operate "to the left" on row-vector a -	LLVector4	vec; -	vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] +  -				 a.mV[VY] * b.mMatrix[VY][VX] +  -				 a.mV[VZ] * b.mMatrix[VZ][VX]; +    // Rotates but does not translate +    // Operate "to the left" on row-vector a +    LLVector4   vec; +    vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] + +                 a.mV[VY] * b.mMatrix[VY][VX] + +                 a.mV[VZ] * b.mMatrix[VZ][VX]; -	vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] +  -				 a.mV[VY] * b.mMatrix[VY][VY] +  -				 a.mV[VZ] * b.mMatrix[VZ][VY]; +    vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] + +                 a.mV[VY] * b.mMatrix[VY][VY] + +                 a.mV[VZ] * b.mMatrix[VZ][VY]; -	vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] +  -				 a.mV[VY] * b.mMatrix[VY][VZ] +  -				 a.mV[VZ] * b.mMatrix[VZ][VZ]; +    vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] + +                 a.mV[VY] * b.mMatrix[VY][VZ] + +                 a.mV[VZ] * b.mMatrix[VZ][VZ]; -//	vec.mV[VW] = a.mV[VX] * b.mMatrix[VX][VW] +  -//				 a.mV[VY] * b.mMatrix[VY][VW] +  -//				 a.mV[VZ] * b.mMatrix[VZ][VW] + -	vec.mV[VW] = a.mV[VW]; -	return vec; +//  vec.mV[VW] = a.mV[VX] * b.mMatrix[VX][VW] + +//               a.mV[VY] * b.mMatrix[VY][VW] + +//               a.mV[VZ] * b.mMatrix[VZ][VW] + +    vec.mV[VW] = a.mV[VW]; +    return vec;  }  LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b)  { -	// Rotates but does not translate -	// Operate "to the left" on row-vector a -	LLVector3	vec; -	vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] +  -				 a.mV[VY] * b.mMatrix[VY][VX] +  -				 a.mV[VZ] * b.mMatrix[VZ][VX]; +    // Rotates but does not translate +    // Operate "to the left" on row-vector a +    LLVector3   vec; +    vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] + +                 a.mV[VY] * b.mMatrix[VY][VX] + +                 a.mV[VZ] * b.mMatrix[VZ][VX]; -	vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] +  -				 a.mV[VY] * b.mMatrix[VY][VY] +  -				 a.mV[VZ] * b.mMatrix[VZ][VY]; +    vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] + +                 a.mV[VY] * b.mMatrix[VY][VY] + +                 a.mV[VZ] * b.mMatrix[VZ][VY]; -	vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] +  -				 a.mV[VY] * b.mMatrix[VY][VZ] +  -				 a.mV[VZ] * b.mMatrix[VZ][VZ]; -	return vec; +    vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] + +                 a.mV[VY] * b.mMatrix[VY][VZ] + +                 a.mV[VZ] * b.mMatrix[VZ][VZ]; +    return vec;  }  bool operator==(const LLMatrix4 &a, const LLMatrix4 &b)  { -	U32		i, j; -	for (i = 0; i < NUM_VALUES_IN_MAT4; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT4; j++) -		{ -			if (a.mMatrix[j][i] != b.mMatrix[j][i]) -				return FALSE; -		} -	} -	return TRUE; +    U32     i, j; +    for (i = 0; i < NUM_VALUES_IN_MAT4; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT4; j++) +        { +            if (a.mMatrix[j][i] != b.mMatrix[j][i]) +                return FALSE; +        } +    } +    return TRUE;  }  bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b)  { -	U32		i, j; -	for (i = 0; i < NUM_VALUES_IN_MAT4; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT4; j++) -		{ -			if (a.mMatrix[j][i] != b.mMatrix[j][i]) -				return TRUE; -		} -	} -	return FALSE; +    U32     i, j; +    for (i = 0; i < NUM_VALUES_IN_MAT4; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT4; j++) +        { +            if (a.mMatrix[j][i] != b.mMatrix[j][i]) +                return TRUE; +        } +    } +    return FALSE;  }  bool operator<(const LLMatrix4& a, const LLMatrix4 &b)  { -	U32		i, j; -	for (i = 0; i < NUM_VALUES_IN_MAT4; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT4; j++) -		{ -			if (a.mMatrix[i][j] != b.mMatrix[i][j]) -			{ -				return a.mMatrix[i][j] < b.mMatrix[i][j]; -			} -		} -	} +    U32     i, j; +    for (i = 0; i < NUM_VALUES_IN_MAT4; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT4; j++) +        { +            if (a.mMatrix[i][j] != b.mMatrix[i][j]) +            { +                return a.mMatrix[i][j] < b.mMatrix[i][j]; +            } +        } +    } -	return false; +    return false;  }  const LLMatrix4& operator*=(LLMatrix4 &a, F32 k)  { -	U32		i, j; -	for (i = 0; i < NUM_VALUES_IN_MAT4; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT4; j++) -		{ -			a.mMatrix[j][i] *= k; -		} -	} -	return a; -} - -std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a)  -{ -	s << "{ "  -		<< a.mMatrix[VX][VX] << ", "  -		<< a.mMatrix[VX][VY] << ", "  -		<< a.mMatrix[VX][VZ] << ", "  -		<< a.mMatrix[VX][VW]  -		<< "; " -		<< a.mMatrix[VY][VX] << ", "  -		<< a.mMatrix[VY][VY] << ", "  -		<< a.mMatrix[VY][VZ] << ", "  -		<< a.mMatrix[VY][VW]  -		<< "; " -		<< a.mMatrix[VZ][VX] << ", "  -		<< a.mMatrix[VZ][VY] << ", "  -		<< a.mMatrix[VZ][VZ] << ", "  -		<< a.mMatrix[VZ][VW]  -		<< "; " -		<< a.mMatrix[VW][VX] << ", "  -		<< a.mMatrix[VW][VY] << ", "  -		<< a.mMatrix[VW][VZ] << ", "  -		<< a.mMatrix[VW][VW]  -	  << " }"; -	return s; +    U32     i, j; +    for (i = 0; i < NUM_VALUES_IN_MAT4; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT4; j++) +        { +            a.mMatrix[j][i] *= k; +        } +    } +    return a; +} + +std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a) +{ +    s << "{ " +        << a.mMatrix[VX][VX] << ", " +        << a.mMatrix[VX][VY] << ", " +        << a.mMatrix[VX][VZ] << ", " +        << a.mMatrix[VX][VW] +        << "; " +        << a.mMatrix[VY][VX] << ", " +        << a.mMatrix[VY][VY] << ", " +        << a.mMatrix[VY][VZ] << ", " +        << a.mMatrix[VY][VW] +        << "; " +        << a.mMatrix[VZ][VX] << ", " +        << a.mMatrix[VZ][VY] << ", " +        << a.mMatrix[VZ][VZ] << ", " +        << a.mMatrix[VZ][VW] +        << "; " +        << a.mMatrix[VW][VX] << ", " +        << a.mMatrix[VW][VY] << ", " +        << a.mMatrix[VW][VZ] << ", " +        << a.mMatrix[VW][VW] +      << " }"; +    return s;  }  LLSD LLMatrix4::getValue() const  { -	LLSD ret; -	 -	ret[0] = mMatrix[0][0]; -	ret[1] = mMatrix[0][1]; -	ret[2] = mMatrix[0][2]; -	ret[3] = mMatrix[0][3]; +    LLSD ret; + +    ret[0] = mMatrix[0][0]; +    ret[1] = mMatrix[0][1]; +    ret[2] = mMatrix[0][2]; +    ret[3] = mMatrix[0][3]; -	ret[4] = mMatrix[1][0]; -	ret[5] = mMatrix[1][1]; -	ret[6] = mMatrix[1][2]; -	ret[7] = mMatrix[1][3]; +    ret[4] = mMatrix[1][0]; +    ret[5] = mMatrix[1][1]; +    ret[6] = mMatrix[1][2]; +    ret[7] = mMatrix[1][3]; -	ret[8] = mMatrix[2][0]; -	ret[9] = mMatrix[2][1]; -	ret[10] = mMatrix[2][2]; -	ret[11] = mMatrix[2][3]; +    ret[8] = mMatrix[2][0]; +    ret[9] = mMatrix[2][1]; +    ret[10] = mMatrix[2][2]; +    ret[11] = mMatrix[2][3]; -	ret[12] = mMatrix[3][0]; -	ret[13] = mMatrix[3][1]; -	ret[14] = mMatrix[3][2]; -	ret[15] = mMatrix[3][3]; +    ret[12] = mMatrix[3][0]; +    ret[13] = mMatrix[3][1]; +    ret[14] = mMatrix[3][2]; +    ret[15] = mMatrix[3][3]; -	return ret; +    return ret;  } -void LLMatrix4::setValue(const LLSD& data)  +void LLMatrix4::setValue(const LLSD& data)  { -	mMatrix[0][0] = (F32)data[0].asReal(); -	mMatrix[0][1] = (F32)data[1].asReal(); -	mMatrix[0][2] = (F32)data[2].asReal(); -	mMatrix[0][3] = (F32)data[3].asReal(); +    mMatrix[0][0] = (F32)data[0].asReal(); +    mMatrix[0][1] = (F32)data[1].asReal(); +    mMatrix[0][2] = (F32)data[2].asReal(); +    mMatrix[0][3] = (F32)data[3].asReal(); -	mMatrix[1][0] = (F32)data[4].asReal(); -	mMatrix[1][1] = (F32)data[5].asReal(); -	mMatrix[1][2] = (F32)data[6].asReal(); -	mMatrix[1][3] = (F32)data[7].asReal(); +    mMatrix[1][0] = (F32)data[4].asReal(); +    mMatrix[1][1] = (F32)data[5].asReal(); +    mMatrix[1][2] = (F32)data[6].asReal(); +    mMatrix[1][3] = (F32)data[7].asReal(); -	mMatrix[2][0] = (F32)data[8].asReal(); -	mMatrix[2][1] = (F32)data[9].asReal(); -	mMatrix[2][2] = (F32)data[10].asReal(); -	mMatrix[2][3] = (F32)data[11].asReal(); +    mMatrix[2][0] = (F32)data[8].asReal(); +    mMatrix[2][1] = (F32)data[9].asReal(); +    mMatrix[2][2] = (F32)data[10].asReal(); +    mMatrix[2][3] = (F32)data[11].asReal(); -	mMatrix[3][0] = (F32)data[12].asReal(); -	mMatrix[3][1] = (F32)data[13].asReal(); -	mMatrix[3][2] = (F32)data[14].asReal(); -	mMatrix[3][3] = (F32)data[15].asReal(); +    mMatrix[3][0] = (F32)data[12].asReal(); +    mMatrix[3][1] = (F32)data[13].asReal(); +    mMatrix[3][2] = (F32)data[14].asReal(); +    mMatrix[3][3] = (F32)data[15].asReal();  } diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index b9da970cde..b0f8c90cdf 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -1,25 +1,25 @@ -/**  +/**   * @file m4math.h   * @brief LLMatrix4 class header file.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -58,16 +58,16 @@ class LLMatrix4a;  // One way to think about it is a matrix that takes the origin frame A  // and rotates it into B': i.e. A*M = B  // -//		Vectors: -//		f - forward axis of B expressed in A -//		l - left axis of B expressed in A -//		u - up axis of B expressed in A +//      Vectors: +//      f - forward axis of B expressed in A +//      l - left axis of B expressed in A +//      u - up axis of B expressed in A  // -//		|  0: fx  1: fy  2: fz  3:0 | +//      |  0: fx  1: fy  2: fz  3:0 |  //  M = |  4: lx  5: ly  6: lz  7:0 |  //      |  8: ux  9: uy 10: uz 11:0 |  //      | 12: 0  13: 0  14:  0 15:1 | -//		 +//  //  //  // @@ -76,18 +76,18 @@ class LLMatrix4a;  //  // so p*M = p'  // -//		Vectors: +//      Vectors:  //      f - forward of frame B in frame A  //      l - left of frame B in frame A  //      u - up of frame B in frame A  //      o - origin of frame frame B in frame A  // -//		|  0: fx  1: lx  2: ux  3:0 | +//      |  0: fx  1: lx  2: ux  3:0 |  //  M = |  4: fy  5: ly  6: uy  7:0 |  //      |  8: fz  9: lz 10: uz 11:0 |  //      | 12:-of 13:-ol 14:-ou 15:1 |  // -//		of, ol, and ou mean the component of the "global" origin o in the f axis, l axis, and u axis. +//      of, ol, and ou mean the component of the "global" origin o in the f axis, l axis, and u axis.  //  static const U32 NUM_VALUES_IN_MAT4 = 4; @@ -95,283 +95,283 @@ static const U32 NUM_VALUES_IN_MAT4 = 4;  class LLMatrix4  {  public: -	F32	mMatrix[NUM_VALUES_IN_MAT4][NUM_VALUES_IN_MAT4]; - -	// Initializes Matrix to identity matrix -	LLMatrix4() -	{ -		setIdentity(); -	} -	explicit LLMatrix4(const F32 *mat);								// Initializes Matrix to values in mat -	explicit LLMatrix4(const LLMatrix3 &mat);						// Initializes Matrix to values in mat and sets position to (0,0,0) -	explicit LLMatrix4(const LLQuaternion &q);						// Initializes Matrix with rotation q and sets position to (0,0,0) +    F32 mMatrix[NUM_VALUES_IN_MAT4][NUM_VALUES_IN_MAT4]; + +    // Initializes Matrix to identity matrix +    LLMatrix4() +    { +        setIdentity(); +    } +    explicit LLMatrix4(const F32 *mat);                             // Initializes Matrix to values in mat +    explicit LLMatrix4(const LLMatrix3 &mat);                       // Initializes Matrix to values in mat and sets position to (0,0,0) +    explicit LLMatrix4(const LLQuaternion &q);                      // Initializes Matrix with rotation q and sets position to (0,0,0)      explicit LLMatrix4(const LLMatrix4a& mat); -	LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos);	// Initializes Matrix to values in mat and pos +    LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos);  // Initializes Matrix to values in mat and pos + +    // These are really, really, inefficient as implemented! - djs +    LLMatrix4(const LLQuaternion &q, const LLVector4 &pos); // Initializes Matrix with rotation q and position pos +    LLMatrix4(F32 angle, +              const LLVector4 &vec, +              const LLVector4 &pos);                        // Initializes Matrix with axis-angle and position +    LLMatrix4(F32 angle, const LLVector4 &vec);             // Initializes Matrix with axis-angle and sets position to (0,0,0) +    LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw, +              const LLVector4 &pos);                        // Initializes Matrix with Euler angles +    LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw);              // Initializes Matrix with Euler angles + +    ~LLMatrix4(void);                                       // Destructor + +    LLSD getValue() const; +    void setValue(const LLSD&); -	// These are really, really, inefficient as implemented! - djs -	LLMatrix4(const LLQuaternion &q, const LLVector4 &pos);	// Initializes Matrix with rotation q and position pos -	LLMatrix4(F32 angle, -			  const LLVector4 &vec,  -			  const LLVector4 &pos);						// Initializes Matrix with axis-angle and position -	LLMatrix4(F32 angle, const LLVector4 &vec);				// Initializes Matrix with axis-angle and sets position to (0,0,0) -	LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw,  -			  const LLVector4 &pos);						// Initializes Matrix with Euler angles -	LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw);				// Initializes Matrix with Euler angles +    ////////////////////////////// +    // +    // Matrix initializers - these replace any existing values in the matrix +    // -	~LLMatrix4(void);										// Destructor +    void initRows(const LLVector4 &row0, +                  const LLVector4 &row1, +                  const LLVector4 &row2, +                  const LLVector4 &row3); -	LLSD getValue() const; -	void setValue(const LLSD&); +    // various useful matrix functions +    const LLMatrix4& setIdentity();                 // Load identity matrix +    bool isIdentity() const; +    const LLMatrix4& setZero();                     // Clears matrix to all zeros. -	////////////////////////////// -	// -	// Matrix initializers - these replace any existing values in the matrix -	// +    const LLMatrix4& initRotation(const F32 angle, const LLVector4 &axis);  // Calculate rotation matrix for rotating angle radians about vec +    const LLMatrix4& initRotation(const F32 roll, const F32 pitch, const F32 yaw);      // Calculate rotation matrix from Euler angles +    const LLMatrix4& initRotation(const LLQuaternion &q);           // Set with Quaternion and position -	void initRows(const LLVector4 &row0, -				  const LLVector4 &row1, -				  const LLVector4 &row2, -				  const LLVector4 &row3); +    // Position Only +    const LLMatrix4& initMatrix(const LLMatrix3 &mat); // +    const LLMatrix4& initMatrix(const LLMatrix3 &mat, const LLVector4 &translation); -	// various useful matrix functions -	const LLMatrix4& setIdentity();					// Load identity matrix -	bool isIdentity() const; -	const LLMatrix4& setZero();						// Clears matrix to all zeros. +    // These operation create a matrix that will rotate and translate by the +    // specified amounts. +    const LLMatrix4& initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3 &translation);     // Rotation from axis angle + translation +    const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation +    const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos); // Set with Quaternion and position -	const LLMatrix4& initRotation(const F32 angle, const LLVector4 &axis);	// Calculate rotation matrix for rotating angle radians about vec -	const LLMatrix4& initRotation(const F32 roll, const F32 pitch, const F32 yaw);		// Calculate rotation matrix from Euler angles -	const LLMatrix4& initRotation(const LLQuaternion &q);			// Set with Quaternion and position -	 -	// Position Only -	const LLMatrix4& initMatrix(const LLMatrix3 &mat); // -	const LLMatrix4& initMatrix(const LLMatrix3 &mat, const LLVector4 &translation); +    const LLMatrix4& initScale(const LLVector3 &scale); -	// These operation create a matrix that will rotate and translate by the -	// specified amounts. -	const LLMatrix4& initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3 &translation);	 // Rotation from axis angle + translation -	const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation -	const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos);	// Set with Quaternion and position +    // Set all +    const LLMatrix4& initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos); -	const LLMatrix4& initScale(const LLVector3 &scale); -	// Set all -	const LLMatrix4& initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos);	 +    /////////////////////////// +    // +    // Matrix setters - set some properties without modifying others +    // +    const LLMatrix4& setTranslation(const F32 x, const F32 y, const F32 z); // Sets matrix to translate by (x,y,z) -	/////////////////////////// -	// -	// Matrix setters - set some properties without modifying others -	// +    void setFwdRow(const LLVector3 &row); +    void setLeftRow(const LLVector3 &row); +    void setUpRow(const LLVector3 &row); -	const LLMatrix4& setTranslation(const F32 x, const F32 y, const F32 z);	// Sets matrix to translate by (x,y,z) +    void setFwdCol(const LLVector3 &col); +    void setLeftCol(const LLVector3 &col); +    void setUpCol(const LLVector3 &col); -	void setFwdRow(const LLVector3 &row); -	void setLeftRow(const LLVector3 &row); -	void setUpRow(const LLVector3 &row); +    const LLMatrix4& setTranslation(const LLVector4 &translation); +    const LLMatrix4& setTranslation(const LLVector3 &translation); -	void setFwdCol(const LLVector3 &col); -	void setLeftCol(const LLVector3 &col); -	void setUpCol(const LLVector3 &col); +    // Convenience func for simplifying comparison-heavy code by +    // intentionally stomping values [-FLT_EPS,FLT_EPS] to 0.0 +    // +    void condition(void); -	const LLMatrix4& setTranslation(const LLVector4 &translation); -	const LLMatrix4& setTranslation(const LLVector3 &translation); +    /////////////////////////// +    // +    // Get properties of a matrix +    // -	// Convenience func for simplifying comparison-heavy code by -	// intentionally stomping values [-FLT_EPS,FLT_EPS] to 0.0 -	// -	void condition(void); +    F32          determinant(void) const;                       // Return determinant +    LLQuaternion quaternion(void) const;            // Returns quaternion -	/////////////////////////// -	// -	// Get properties of a matrix -	// +    LLVector4 getFwdRow4() const; +    LLVector4 getLeftRow4() const; +    LLVector4 getUpRow4() const; -	F32			 determinant(void) const;						// Return determinant -	LLQuaternion quaternion(void) const;			// Returns quaternion +    LLMatrix3 getMat3() const; -	LLVector4 getFwdRow4() const; -	LLVector4 getLeftRow4() const; -	LLVector4 getUpRow4() const; +    const LLVector3& getTranslation() const { return *(LLVector3*)&mMatrix[3][0]; } -	LLMatrix3 getMat3() const; +    /////////////////////////// +    // +    // Operations on an existing matrix +    // -	const LLVector3& getTranslation() const { return *(LLVector3*)&mMatrix[3][0]; } +    const LLMatrix4& transpose();                       // Transpose LLMatrix4 +    const LLMatrix4& invert();                      // Invert LLMatrix4 -	/////////////////////////// -	// -	// Operations on an existing matrix -	// +    // Rotate existing matrix +    // These are really, really, inefficient as implemented! - djs +    const LLMatrix4& rotate(const F32 angle, const LLVector4 &vec);     // Rotate matrix by rotating angle radians about vec +    const LLMatrix4& rotate(const F32 roll, const F32 pitch, const F32 yaw);        // Rotate matrix by Euler angles +    const LLMatrix4& rotate(const LLQuaternion &q);             // Rotate matrix by Quaternion -	const LLMatrix4& transpose();						// Transpose LLMatrix4 -	const LLMatrix4& invert();						// Invert LLMatrix4 -	// Rotate existing matrix -	// These are really, really, inefficient as implemented! - djs -	const LLMatrix4& rotate(const F32 angle, const LLVector4 &vec);		// Rotate matrix by rotating angle radians about vec -	const LLMatrix4& rotate(const F32 roll, const F32 pitch, const F32 yaw);		// Rotate matrix by Euler angles -	const LLMatrix4& rotate(const LLQuaternion &q);				// Rotate matrix by Quaternion +    // Translate existing matrix +    const LLMatrix4& translate(const LLVector3 &vec);               // Translate matrix by (vec[VX], vec[VY], vec[VZ]) -	 -	// Translate existing matrix -	const LLMatrix4& translate(const LLVector3 &vec);				// Translate matrix by (vec[VX], vec[VY], vec[VZ]) -	 -	/////////////////////// -	// -	// Operators -	// +    /////////////////////// +    // +    // Operators +    // -	//	friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b);		// Return a * b -	friend LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b);		// Return transform of vector a by matrix b -	friend const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b);		// Return full transform of a by matrix b -	friend LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b);	// Rotates a but does not translate -	friend LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b);	// Rotates a but does not translate +    //  friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b);      // Return a * b +    friend LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b);     // Return transform of vector a by matrix b +    friend const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b);       // Return full transform of a by matrix b +    friend LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b); // Rotates a but does not translate +    friend LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b); // Rotates a but does not translate -	friend bool operator==(const LLMatrix4 &a, const LLMatrix4 &b);			// Return a == b -	friend bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b);			// Return a != b -	friend bool operator<(const LLMatrix4 &a, const LLMatrix4& b);			// Return a < b +    friend bool operator==(const LLMatrix4 &a, const LLMatrix4 &b);         // Return a == b +    friend bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b);         // Return a != b +    friend bool operator<(const LLMatrix4 &a, const LLMatrix4& b);          // Return a < b -	friend const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b);	// Return a + b -	friend const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b);	// Return a - b -	friend const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b);	// Return a * b -	friend const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b);			// Return a * b +    friend const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b);   // Return a + b +    friend const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b);   // Return a - b +    friend const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b);   // Return a * b +    friend const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b);         // Return a * b -	friend std::ostream&	 operator<<(std::ostream& s, const LLMatrix4 &a);	// Stream a +    friend std::ostream&     operator<<(std::ostream& s, const LLMatrix4 &a);   // Stream a  }; -inline const LLMatrix4&	LLMatrix4::setIdentity() +inline const LLMatrix4& LLMatrix4::setIdentity()  { -	mMatrix[0][0] = 1.f; -	mMatrix[0][1] = 0.f; -	mMatrix[0][2] = 0.f; -	mMatrix[0][3] = 0.f; - -	mMatrix[1][0] = 0.f; -	mMatrix[1][1] = 1.f; -	mMatrix[1][2] = 0.f; -	mMatrix[1][3] = 0.f; - -	mMatrix[2][0] = 0.f; -	mMatrix[2][1] = 0.f; -	mMatrix[2][2] = 1.f; -	mMatrix[2][3] = 0.f; - -	mMatrix[3][0] = 0.f; -	mMatrix[3][1] = 0.f; -	mMatrix[3][2] = 0.f; -	mMatrix[3][3] = 1.f; -	return (*this); +    mMatrix[0][0] = 1.f; +    mMatrix[0][1] = 0.f; +    mMatrix[0][2] = 0.f; +    mMatrix[0][3] = 0.f; + +    mMatrix[1][0] = 0.f; +    mMatrix[1][1] = 1.f; +    mMatrix[1][2] = 0.f; +    mMatrix[1][3] = 0.f; + +    mMatrix[2][0] = 0.f; +    mMatrix[2][1] = 0.f; +    mMatrix[2][2] = 1.f; +    mMatrix[2][3] = 0.f; + +    mMatrix[3][0] = 0.f; +    mMatrix[3][1] = 0.f; +    mMatrix[3][2] = 0.f; +    mMatrix[3][3] = 1.f; +    return (*this);  }  inline bool LLMatrix4::isIdentity() const  { -	return -		mMatrix[0][0] == 1.f && -		mMatrix[0][1] == 0.f && -		mMatrix[0][2] == 0.f && -		mMatrix[0][3] == 0.f && - -		mMatrix[1][0] == 0.f && -		mMatrix[1][1] == 1.f && -		mMatrix[1][2] == 0.f && -		mMatrix[1][3] == 0.f && - -		mMatrix[2][0] == 0.f && -		mMatrix[2][1] == 0.f && -		mMatrix[2][2] == 1.f && -		mMatrix[2][3] == 0.f && - -		mMatrix[3][0] == 0.f && -		mMatrix[3][1] == 0.f && -		mMatrix[3][2] == 0.f && -		mMatrix[3][3] == 1.f; +    return +        mMatrix[0][0] == 1.f && +        mMatrix[0][1] == 0.f && +        mMatrix[0][2] == 0.f && +        mMatrix[0][3] == 0.f && + +        mMatrix[1][0] == 0.f && +        mMatrix[1][1] == 1.f && +        mMatrix[1][2] == 0.f && +        mMatrix[1][3] == 0.f && + +        mMatrix[2][0] == 0.f && +        mMatrix[2][1] == 0.f && +        mMatrix[2][2] == 1.f && +        mMatrix[2][3] == 0.f && + +        mMatrix[3][0] == 0.f && +        mMatrix[3][1] == 0.f && +        mMatrix[3][2] == 0.f && +        mMatrix[3][3] == 1.f;  }  /*  inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b)  { -	U32		i, j; -	LLMatrix4	mat; -	for (i = 0; i < NUM_VALUES_IN_MAT4; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT4; j++) -		{ -			mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] +  -							    a.mMatrix[j][1] * b.mMatrix[1][i] +  -							    a.mMatrix[j][2] * b.mMatrix[2][i] + -								a.mMatrix[j][3] * b.mMatrix[3][i]; -		} -	} -	return mat; +    U32     i, j; +    LLMatrix4   mat; +    for (i = 0; i < NUM_VALUES_IN_MAT4; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT4; j++) +        { +            mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + +                                a.mMatrix[j][1] * b.mMatrix[1][i] + +                                a.mMatrix[j][2] * b.mMatrix[2][i] + +                                a.mMatrix[j][3] * b.mMatrix[3][i]; +        } +    } +    return mat;  }  */  inline const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b)  { -	U32		i, j; -	LLMatrix4	mat; -	for (i = 0; i < NUM_VALUES_IN_MAT4; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT4; j++) -		{ -			mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] +  -							    a.mMatrix[j][1] * b.mMatrix[1][i] +  -							    a.mMatrix[j][2] * b.mMatrix[2][i] + -								a.mMatrix[j][3] * b.mMatrix[3][i]; -		} -	} -	a = mat; -	return a; +    U32     i, j; +    LLMatrix4   mat; +    for (i = 0; i < NUM_VALUES_IN_MAT4; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT4; j++) +        { +            mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + +                                a.mMatrix[j][1] * b.mMatrix[1][i] + +                                a.mMatrix[j][2] * b.mMatrix[2][i] + +                                a.mMatrix[j][3] * b.mMatrix[3][i]; +        } +    } +    a = mat; +    return a;  }  inline const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b)  { -	U32		i, j; -	LLMatrix4	mat; -	for (i = 0; i < NUM_VALUES_IN_MAT4; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT4; j++) -		{ -			mat.mMatrix[j][i] = a.mMatrix[j][i] * b; -		} -	} -	a = mat; -	return a; +    U32     i, j; +    LLMatrix4   mat; +    for (i = 0; i < NUM_VALUES_IN_MAT4; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT4; j++) +        { +            mat.mMatrix[j][i] = a.mMatrix[j][i] * b; +        } +    } +    a = mat; +    return a;  }  inline const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b)  { -	LLMatrix4 mat; -	U32		i, j; -	for (i = 0; i < NUM_VALUES_IN_MAT4; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT4; j++) -		{ -			mat.mMatrix[j][i] = a.mMatrix[j][i] + b.mMatrix[j][i]; -		} -	} -	a = mat; -	return a; +    LLMatrix4 mat; +    U32     i, j; +    for (i = 0; i < NUM_VALUES_IN_MAT4; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT4; j++) +        { +            mat.mMatrix[j][i] = a.mMatrix[j][i] + b.mMatrix[j][i]; +        } +    } +    a = mat; +    return a;  }  inline const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b)  { -	LLMatrix4 mat; -	U32		i, j; -	for (i = 0; i < NUM_VALUES_IN_MAT4; i++) -	{ -		for (j = 0; j < NUM_VALUES_IN_MAT4; j++) -		{ -			mat.mMatrix[j][i] = a.mMatrix[j][i] - b.mMatrix[j][i]; -		} -	} -	a = mat; -	return a; +    LLMatrix4 mat; +    U32     i, j; +    for (i = 0; i < NUM_VALUES_IN_MAT4; i++) +    { +        for (j = 0; j < NUM_VALUES_IN_MAT4; j++) +        { +            mat.mMatrix[j][i] = a.mMatrix[j][i] - b.mMatrix[j][i]; +        } +    } +    a = mat; +    return a;  }  // Operates "to the left" on row-vector a @@ -380,24 +380,24 @@ inline const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b)  // due to software skinning in LLViewerJointMesh::updateGeometry().  JC  inline const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b)  { -	// This is better than making a temporary LLVector3.  This eliminates an -	// unnecessary LLVector3() constructor and also helps the compiler to -	// realize that the output floats do not alias the input floats, hence -	// eliminating redundant loads of a.mV[0], etc.  JC -	return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] +  -					 a.mV[VY] * b.mMatrix[VY][VX] +  -					 a.mV[VZ] * b.mMatrix[VZ][VX] + -					 b.mMatrix[VW][VX], -					  -					 a.mV[VX] * b.mMatrix[VX][VY] +  -					 a.mV[VY] * b.mMatrix[VY][VY] +  -					 a.mV[VZ] * b.mMatrix[VZ][VY] + -					 b.mMatrix[VW][VY], -					  -					 a.mV[VX] * b.mMatrix[VX][VZ] +  -					 a.mV[VY] * b.mMatrix[VY][VZ] +  -					 a.mV[VZ] * b.mMatrix[VZ][VZ] + -					 b.mMatrix[VW][VZ]); +    // This is better than making a temporary LLVector3.  This eliminates an +    // unnecessary LLVector3() constructor and also helps the compiler to +    // realize that the output floats do not alias the input floats, hence +    // eliminating redundant loads of a.mV[0], etc.  JC +    return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] + +                     a.mV[VY] * b.mMatrix[VY][VX] + +                     a.mV[VZ] * b.mMatrix[VZ][VX] + +                     b.mMatrix[VW][VX], + +                     a.mV[VX] * b.mMatrix[VX][VY] + +                     a.mV[VY] * b.mMatrix[VY][VY] + +                     a.mV[VZ] * b.mMatrix[VZ][VY] + +                     b.mMatrix[VW][VY], + +                     a.mV[VX] * b.mMatrix[VX][VZ] + +                     a.mV[VY] * b.mMatrix[VY][VZ] + +                     a.mV[VZ] * b.mMatrix[VZ][VZ] + +                     b.mMatrix[VW][VZ]);  }  #endif diff --git a/indra/llmath/raytrace.cpp b/indra/llmath/raytrace.cpp index f38fe49bcb..de51313fa2 100644 --- a/indra/llmath/raytrace.cpp +++ b/indra/llmath/raytrace.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file raytrace.cpp   * @brief Functions called by box object scripts.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -35,1237 +35,1237 @@  BOOL line_plane(const LLVector3 &line_point, const LLVector3 &line_direction, -				const LLVector3 &plane_point, const LLVector3 plane_normal,  -				LLVector3 &intersection) +                const LLVector3 &plane_point, const LLVector3 plane_normal, +                LLVector3 &intersection)  { -	F32 N = line_direction * plane_normal; -	if (0.0f == N) -	{ -		// line is perpendicular to plane normal -		// so it is either entirely on plane, or not on plane at all -		return FALSE; -	} -	// Ax + By, + Cz + D = 0 -	// D = - (plane_point * plane_normal) -	// N = line_direction * plane_normal -	// intersection = line_point - ((D + plane_normal * line_point) / N) * line_direction -	intersection = line_point - ((plane_normal * line_point - plane_point * plane_normal) / N) * line_direction; -	return TRUE; +    F32 N = line_direction * plane_normal; +    if (0.0f == N) +    { +        // line is perpendicular to plane normal +        // so it is either entirely on plane, or not on plane at all +        return FALSE; +    } +    // Ax + By, + Cz + D = 0 +    // D = - (plane_point * plane_normal) +    // N = line_direction * plane_normal +    // intersection = line_point - ((D + plane_normal * line_point) / N) * line_direction +    intersection = line_point - ((plane_normal * line_point - plane_point * plane_normal) / N) * line_direction; +    return TRUE;  }  BOOL ray_plane(const LLVector3 &ray_point, const LLVector3 &ray_direction, -			   const LLVector3 &plane_point, const LLVector3 plane_normal,  -			   LLVector3 &intersection) +               const LLVector3 &plane_point, const LLVector3 plane_normal, +               LLVector3 &intersection)  { -	F32 N = ray_direction * plane_normal; -	if (0.0f == N) -	{ -		// ray is perpendicular to plane normal -		// so it is either entirely on plane, or not on plane at all -		return FALSE; -	} -	// Ax + By, + Cz + D = 0 -	// D = - (plane_point * plane_normal) -	// N = ray_direction * plane_normal -	// intersection = ray_point - ((D + plane_normal * ray_point) / N) * ray_direction -	F32 alpha = -(plane_normal * ray_point - plane_point * plane_normal) / N; -	if (alpha < 0.0f) -	{ -		// ray points away from plane -		return FALSE; -	} -	intersection = ray_point + alpha * ray_direction; -	return TRUE; +    F32 N = ray_direction * plane_normal; +    if (0.0f == N) +    { +        // ray is perpendicular to plane normal +        // so it is either entirely on plane, or not on plane at all +        return FALSE; +    } +    // Ax + By, + Cz + D = 0 +    // D = - (plane_point * plane_normal) +    // N = ray_direction * plane_normal +    // intersection = ray_point - ((D + plane_normal * ray_point) / N) * ray_direction +    F32 alpha = -(plane_normal * ray_point - plane_point * plane_normal) / N; +    if (alpha < 0.0f) +    { +        // ray points away from plane +        return FALSE; +    } +    intersection = ray_point + alpha * ray_direction; +    return TRUE;  }  BOOL ray_circle(const LLVector3 &ray_point, const LLVector3 &ray_direction, -				const LLVector3 &circle_center, const LLVector3 plane_normal, F32 circle_radius, -				LLVector3 &intersection) +                const LLVector3 &circle_center, const LLVector3 plane_normal, F32 circle_radius, +                LLVector3 &intersection)  { -	if (ray_plane(ray_point, ray_direction, circle_center, plane_normal, intersection)) -	{ -		if (circle_radius >= (intersection - circle_center).magVec()) -		{ -			return TRUE; -		} -	} -	return FALSE; +    if (ray_plane(ray_point, ray_direction, circle_center, plane_normal, intersection)) +    { +        if (circle_radius >= (intersection - circle_center).magVec()) +        { +            return TRUE; +        } +    } +    return FALSE;  }  BOOL ray_triangle(const LLVector3 &ray_point, const LLVector3 &ray_direction, -				  const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2,  -				  LLVector3 &intersection, LLVector3 &intersection_normal) +                  const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, +                  LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 side_01 = point_1 - point_0; -	LLVector3 side_12 = point_2 - point_1; - -	intersection_normal = side_01 % side_12; -	intersection_normal.normVec(); - -	if (ray_plane(ray_point, ray_direction, point_0, intersection_normal, intersection)) -	{ -		LLVector3 side_20 = point_0 - point_2; -		if (intersection_normal * (side_01 % (intersection - point_0)) >= 0.0f  && -			intersection_normal * (side_12 % (intersection - point_1)) >= 0.0f  && -			intersection_normal * (side_20 % (intersection - point_2)) >= 0.0f) -		{ -			return TRUE; -		} -	} -	return FALSE; +    LLVector3 side_01 = point_1 - point_0; +    LLVector3 side_12 = point_2 - point_1; + +    intersection_normal = side_01 % side_12; +    intersection_normal.normVec(); + +    if (ray_plane(ray_point, ray_direction, point_0, intersection_normal, intersection)) +    { +        LLVector3 side_20 = point_0 - point_2; +        if (intersection_normal * (side_01 % (intersection - point_0)) >= 0.0f  && +            intersection_normal * (side_12 % (intersection - point_1)) >= 0.0f  && +            intersection_normal * (side_20 % (intersection - point_2)) >= 0.0f) +        { +            return TRUE; +        } +    } +    return FALSE;  }  // assumes a parallelogram  BOOL ray_quadrangle(const LLVector3 &ray_point, const LLVector3 &ray_direction, -					const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, -					LLVector3 &intersection, LLVector3 &intersection_normal) +                    const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, +                    LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 side_01 = point_1 - point_0; -	LLVector3 side_12 = point_2 - point_1; - -	intersection_normal = side_01 % side_12; -	intersection_normal.normVec(); - -	if (ray_plane(ray_point, ray_direction, point_0, intersection_normal, intersection)) -	{ -		LLVector3 point_3 = point_0 + (side_12); -		LLVector3 side_23 = point_3 - point_2; -		LLVector3 side_30 = point_0 - point_3; -		if (intersection_normal * (side_01 % (intersection - point_0)) >= 0.0f  && -			intersection_normal * (side_12 % (intersection - point_1)) >= 0.0f  && -			intersection_normal * (side_23 % (intersection - point_2)) >= 0.0f  && -			intersection_normal * (side_30 % (intersection - point_3)) >= 0.0f) -		{ -			return TRUE; -		} -	} -	return FALSE; +    LLVector3 side_01 = point_1 - point_0; +    LLVector3 side_12 = point_2 - point_1; + +    intersection_normal = side_01 % side_12; +    intersection_normal.normVec(); + +    if (ray_plane(ray_point, ray_direction, point_0, intersection_normal, intersection)) +    { +        LLVector3 point_3 = point_0 + (side_12); +        LLVector3 side_23 = point_3 - point_2; +        LLVector3 side_30 = point_0 - point_3; +        if (intersection_normal * (side_01 % (intersection - point_0)) >= 0.0f  && +            intersection_normal * (side_12 % (intersection - point_1)) >= 0.0f  && +            intersection_normal * (side_23 % (intersection - point_2)) >= 0.0f  && +            intersection_normal * (side_30 % (intersection - point_3)) >= 0.0f) +        { +            return TRUE; +        } +    } +    return FALSE;  }  BOOL ray_sphere(const LLVector3 &ray_point, const LLVector3 &ray_direction, -				const LLVector3 &sphere_center, F32 sphere_radius, -				LLVector3 &intersection, LLVector3 &intersection_normal) +                const LLVector3 &sphere_center, F32 sphere_radius, +                LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 ray_to_sphere = sphere_center - ray_point; -	F32 dot = ray_to_sphere * ray_direction; - -	LLVector3 closest_approach = dot * ray_direction - ray_to_sphere; - -	F32 shortest_distance = closest_approach.magVecSquared(); -	F32 radius_squared = sphere_radius * sphere_radius; -	if (shortest_distance > radius_squared) -	{ -		return FALSE; -	} - -	F32 half_chord = (F32) sqrt(radius_squared - shortest_distance); -	closest_approach = sphere_center + closest_approach;			// closest_approach now in absolute coordinates -	intersection = closest_approach + half_chord * ray_direction; -	dot = ray_direction * (intersection - ray_point); -	if (dot < 0.0f) -	{ -		// ray shoots away from sphere and is not inside it -		return FALSE; -	} - -	shortest_distance = ray_direction * ((closest_approach - half_chord * ray_direction) - ray_point); -	if (shortest_distance > 0.0f) -	{ -		// ray enters sphere  -		intersection = intersection - (2.0f * half_chord) * ray_direction; -	} -	else -	{ -		// do nothing -		// ray starts inside sphere and intersects as it leaves the sphere -	} - -	intersection_normal = intersection - sphere_center; -	if (sphere_radius > 0.0f) -	{ -		intersection_normal *= 1.0f / sphere_radius; -	} -	else -	{ -		intersection_normal.setVec(0.0f, 0.0f, 0.0f); -	} -	 -	return TRUE; +    LLVector3 ray_to_sphere = sphere_center - ray_point; +    F32 dot = ray_to_sphere * ray_direction; + +    LLVector3 closest_approach = dot * ray_direction - ray_to_sphere; + +    F32 shortest_distance = closest_approach.magVecSquared(); +    F32 radius_squared = sphere_radius * sphere_radius; +    if (shortest_distance > radius_squared) +    { +        return FALSE; +    } + +    F32 half_chord = (F32) sqrt(radius_squared - shortest_distance); +    closest_approach = sphere_center + closest_approach;            // closest_approach now in absolute coordinates +    intersection = closest_approach + half_chord * ray_direction; +    dot = ray_direction * (intersection - ray_point); +    if (dot < 0.0f) +    { +        // ray shoots away from sphere and is not inside it +        return FALSE; +    } + +    shortest_distance = ray_direction * ((closest_approach - half_chord * ray_direction) - ray_point); +    if (shortest_distance > 0.0f) +    { +        // ray enters sphere +        intersection = intersection - (2.0f * half_chord) * ray_direction; +    } +    else +    { +        // do nothing +        // ray starts inside sphere and intersects as it leaves the sphere +    } + +    intersection_normal = intersection - sphere_center; +    if (sphere_radius > 0.0f) +    { +        intersection_normal *= 1.0f / sphere_radius; +    } +    else +    { +        intersection_normal.setVec(0.0f, 0.0f, 0.0f); +    } + +    return TRUE;  }  BOOL ray_cylinder(const LLVector3 &ray_point, const LLVector3 &ray_direction, -				  const LLVector3 &cyl_center, const LLVector3 &cyl_scale, const LLQuaternion &cyl_rotation, -				  LLVector3 &intersection, LLVector3 &intersection_normal) +                  const LLVector3 &cyl_center, const LLVector3 &cyl_scale, const LLQuaternion &cyl_rotation, +                  LLVector3 &intersection, LLVector3 &intersection_normal)  { -	// calculate the centers of the cylinder caps in the absolute frame -	LLVector3 cyl_top(0.0f, 0.0f, 0.5f * cyl_scale.mV[VZ]); -	LLVector3 cyl_bottom(0.0f, 0.0f, -cyl_top.mV[VZ]); -	cyl_top = (cyl_top * cyl_rotation) + cyl_center; -	cyl_bottom = (cyl_bottom * cyl_rotation) + cyl_center; - -	// we only handle cylinders with circular cross-sections at the moment -	F32 cyl_radius = 0.5f * llmax(cyl_scale.mV[VX], cyl_scale.mV[VY]);	// HACK until scaled cylinders are supported - -	// This implementation is based on the intcyl() function from Graphics_Gems_IV, page 361 -	LLVector3   cyl_axis;								// axis direction (bottom toward top) -	LLVector3 	ray_to_cyl;								// ray_point to cyl_top -	F32 		shortest_distance;						// shortest distance from ray to axis -	F32 		cyl_length; -	LLVector3	shortest_direction; -	LLVector3	temp_vector; - -	cyl_axis = cyl_bottom - cyl_top; -	cyl_length = cyl_axis.normVec(); -	ray_to_cyl = ray_point - cyl_bottom; -	shortest_direction = ray_direction % cyl_axis; -	shortest_distance = shortest_direction.normVec();	// recycle shortest_distance - -	// check for ray parallel to cylinder axis -	if (0.0f == shortest_distance) -	{ -		// ray is parallel to cylinder axis -		temp_vector = ray_to_cyl - (ray_to_cyl * cyl_axis) * cyl_axis; -		shortest_distance = temp_vector.magVec(); -		if (shortest_distance <= cyl_radius) -		{ -			shortest_distance = ray_to_cyl * cyl_axis; -			F32 dot = ray_direction * cyl_axis; - -			if (shortest_distance > 0.0) -			{ -			   	if (dot > 0.0f) -				{ -					// ray points away from cylinder bottom -					return FALSE; -				} -				// ray hit bottom of cylinder from outside  -				intersection = ray_point - shortest_distance * cyl_axis; -				intersection_normal = cyl_axis; - -			} -			else if (shortest_distance > -cyl_length) -			{ -				// ray starts inside cylinder -				if (dot < 0.0f) -				{ -					// ray hit top from inside -					intersection = ray_point - (cyl_length + shortest_distance) * cyl_axis; -					intersection_normal = -cyl_axis; -				} -				else -				{ -					// ray hit bottom from inside -					intersection = ray_point - shortest_distance * cyl_axis; -					intersection_normal = cyl_axis; -				} -			} -			else -			{ -				if (dot < 0.0f) -				{ -					// ray points away from cylinder bottom -					return FALSE; -				} -				// ray hit top from outside -				intersection = ray_point - (shortest_distance + cyl_length) * cyl_axis; -				intersection_normal = -cyl_axis; -			} -			return TRUE; -		} -		return FALSE; -	} - -	// check for intersection with infinite cylinder -	shortest_distance = (F32) fabs(ray_to_cyl * shortest_direction); -	if (shortest_distance <= cyl_radius) -	{ -		F32 		dist_to_closest_point;				// dist from ray_point to closest_point -		F32 		half_chord_length;					// half length of intersection chord -		F32 		in, out;							// distances to entering/exiting points -		temp_vector = ray_to_cyl % cyl_axis; -		dist_to_closest_point = - (temp_vector * shortest_direction); -		temp_vector = shortest_direction % cyl_axis; -		temp_vector.normVec(); -		half_chord_length = (F32) fabs( sqrt(cyl_radius*cyl_radius - shortest_distance * shortest_distance) / -							(ray_direction * temp_vector) ); - -		out = dist_to_closest_point + half_chord_length;	// dist to exiting point -		if (out < 0.0f) -		{ -			// cylinder is behind the ray, so we return FALSE -			return FALSE; -		} - -		in = dist_to_closest_point - half_chord_length;		// dist to entering point -		if (in < 0.0f) -		{ -			// ray_point is inside the cylinder -			// so we store the exiting intersection -			intersection = ray_point + out * ray_direction; -			shortest_distance = out; -		} -		else -		{ -			// ray hit cylinder from outside -			// so we store the entering intersection -			intersection = ray_point + in * ray_direction; -			shortest_distance = in; -		} - -		// calculate the normal at intersection -		if (0.0f == cyl_radius) -		{ -			intersection_normal.setVec(0.0f, 0.0f, 0.0f); -		} -		else -		{ -			temp_vector = intersection - cyl_bottom;	 -			intersection_normal = temp_vector - (temp_vector * cyl_axis) * cyl_axis; -			intersection_normal.normVec(); -		} - -		// check for intersection with end caps -		// calculate intersection of ray and top plane -		if (line_plane(ray_point, ray_direction, cyl_top, -cyl_axis, temp_vector))	// NOTE side-effect: changing temp_vector -		{ -			shortest_distance = (temp_vector - ray_point).magVec(); -			if ( (ray_direction * cyl_axis) > 0.0f) -			{ -				// ray potentially enters the cylinder at top -				if (shortest_distance > out) -				{ -					// ray missed the finite cylinder -					return FALSE; -				} -				if (shortest_distance > in) -				{ -					// ray intersects cylinder at top plane -					intersection = temp_vector; -					intersection_normal = -cyl_axis; -					return TRUE; -				} -			} -			else -			{ -				// ray potentially exits the cylinder at top -				if (shortest_distance < in) -				{ -					// missed the finite cylinder -					return FALSE; -				} -			} - -			// calculate intersection of ray and bottom plane -			line_plane(ray_point, ray_direction, cyl_bottom, cyl_axis, temp_vector); // NOTE side-effect: changing temp_vector -			shortest_distance = (temp_vector - ray_point).magVec(); -			if ( (ray_direction * cyl_axis) < 0.0) -			{ -				// ray potentially enters the cylinder at bottom -				if (shortest_distance > out) -				{ -					// ray missed the finite cylinder -					return FALSE; -				} -				if (shortest_distance > in) -				{ -					// ray intersects cylinder at bottom plane -					intersection = temp_vector; -					intersection_normal = cyl_axis; -					return TRUE; -				} -			} -			else -			{ -				// ray potentially exits the cylinder at bottom -				if (shortest_distance < in) -				{ -					// ray missed the finite cylinder -					return FALSE; -				} -			} - -		} -		else -		{ -			// ray is parallel to end cap planes -			temp_vector = cyl_bottom - ray_point; -			shortest_distance = temp_vector * cyl_axis; -			if (shortest_distance < 0.0f  ||  shortest_distance > cyl_length) -			{ -				// ray missed finite cylinder -				return FALSE; -			} -		} - -		return TRUE; -	} - -	return FALSE; +    // calculate the centers of the cylinder caps in the absolute frame +    LLVector3 cyl_top(0.0f, 0.0f, 0.5f * cyl_scale.mV[VZ]); +    LLVector3 cyl_bottom(0.0f, 0.0f, -cyl_top.mV[VZ]); +    cyl_top = (cyl_top * cyl_rotation) + cyl_center; +    cyl_bottom = (cyl_bottom * cyl_rotation) + cyl_center; + +    // we only handle cylinders with circular cross-sections at the moment +    F32 cyl_radius = 0.5f * llmax(cyl_scale.mV[VX], cyl_scale.mV[VY]);  // HACK until scaled cylinders are supported + +    // This implementation is based on the intcyl() function from Graphics_Gems_IV, page 361 +    LLVector3   cyl_axis;                               // axis direction (bottom toward top) +    LLVector3   ray_to_cyl;                             // ray_point to cyl_top +    F32         shortest_distance;                      // shortest distance from ray to axis +    F32         cyl_length; +    LLVector3   shortest_direction; +    LLVector3   temp_vector; + +    cyl_axis = cyl_bottom - cyl_top; +    cyl_length = cyl_axis.normVec(); +    ray_to_cyl = ray_point - cyl_bottom; +    shortest_direction = ray_direction % cyl_axis; +    shortest_distance = shortest_direction.normVec();   // recycle shortest_distance + +    // check for ray parallel to cylinder axis +    if (0.0f == shortest_distance) +    { +        // ray is parallel to cylinder axis +        temp_vector = ray_to_cyl - (ray_to_cyl * cyl_axis) * cyl_axis; +        shortest_distance = temp_vector.magVec(); +        if (shortest_distance <= cyl_radius) +        { +            shortest_distance = ray_to_cyl * cyl_axis; +            F32 dot = ray_direction * cyl_axis; + +            if (shortest_distance > 0.0) +            { +                if (dot > 0.0f) +                { +                    // ray points away from cylinder bottom +                    return FALSE; +                } +                // ray hit bottom of cylinder from outside +                intersection = ray_point - shortest_distance * cyl_axis; +                intersection_normal = cyl_axis; + +            } +            else if (shortest_distance > -cyl_length) +            { +                // ray starts inside cylinder +                if (dot < 0.0f) +                { +                    // ray hit top from inside +                    intersection = ray_point - (cyl_length + shortest_distance) * cyl_axis; +                    intersection_normal = -cyl_axis; +                } +                else +                { +                    // ray hit bottom from inside +                    intersection = ray_point - shortest_distance * cyl_axis; +                    intersection_normal = cyl_axis; +                } +            } +            else +            { +                if (dot < 0.0f) +                { +                    // ray points away from cylinder bottom +                    return FALSE; +                } +                // ray hit top from outside +                intersection = ray_point - (shortest_distance + cyl_length) * cyl_axis; +                intersection_normal = -cyl_axis; +            } +            return TRUE; +        } +        return FALSE; +    } + +    // check for intersection with infinite cylinder +    shortest_distance = (F32) fabs(ray_to_cyl * shortest_direction); +    if (shortest_distance <= cyl_radius) +    { +        F32         dist_to_closest_point;              // dist from ray_point to closest_point +        F32         half_chord_length;                  // half length of intersection chord +        F32         in, out;                            // distances to entering/exiting points +        temp_vector = ray_to_cyl % cyl_axis; +        dist_to_closest_point = - (temp_vector * shortest_direction); +        temp_vector = shortest_direction % cyl_axis; +        temp_vector.normVec(); +        half_chord_length = (F32) fabs( sqrt(cyl_radius*cyl_radius - shortest_distance * shortest_distance) / +                            (ray_direction * temp_vector) ); + +        out = dist_to_closest_point + half_chord_length;    // dist to exiting point +        if (out < 0.0f) +        { +            // cylinder is behind the ray, so we return FALSE +            return FALSE; +        } + +        in = dist_to_closest_point - half_chord_length;     // dist to entering point +        if (in < 0.0f) +        { +            // ray_point is inside the cylinder +            // so we store the exiting intersection +            intersection = ray_point + out * ray_direction; +            shortest_distance = out; +        } +        else +        { +            // ray hit cylinder from outside +            // so we store the entering intersection +            intersection = ray_point + in * ray_direction; +            shortest_distance = in; +        } + +        // calculate the normal at intersection +        if (0.0f == cyl_radius) +        { +            intersection_normal.setVec(0.0f, 0.0f, 0.0f); +        } +        else +        { +            temp_vector = intersection - cyl_bottom; +            intersection_normal = temp_vector - (temp_vector * cyl_axis) * cyl_axis; +            intersection_normal.normVec(); +        } + +        // check for intersection with end caps +        // calculate intersection of ray and top plane +        if (line_plane(ray_point, ray_direction, cyl_top, -cyl_axis, temp_vector))  // NOTE side-effect: changing temp_vector +        { +            shortest_distance = (temp_vector - ray_point).magVec(); +            if ( (ray_direction * cyl_axis) > 0.0f) +            { +                // ray potentially enters the cylinder at top +                if (shortest_distance > out) +                { +                    // ray missed the finite cylinder +                    return FALSE; +                } +                if (shortest_distance > in) +                { +                    // ray intersects cylinder at top plane +                    intersection = temp_vector; +                    intersection_normal = -cyl_axis; +                    return TRUE; +                } +            } +            else +            { +                // ray potentially exits the cylinder at top +                if (shortest_distance < in) +                { +                    // missed the finite cylinder +                    return FALSE; +                } +            } + +            // calculate intersection of ray and bottom plane +            line_plane(ray_point, ray_direction, cyl_bottom, cyl_axis, temp_vector); // NOTE side-effect: changing temp_vector +            shortest_distance = (temp_vector - ray_point).magVec(); +            if ( (ray_direction * cyl_axis) < 0.0) +            { +                // ray potentially enters the cylinder at bottom +                if (shortest_distance > out) +                { +                    // ray missed the finite cylinder +                    return FALSE; +                } +                if (shortest_distance > in) +                { +                    // ray intersects cylinder at bottom plane +                    intersection = temp_vector; +                    intersection_normal = cyl_axis; +                    return TRUE; +                } +            } +            else +            { +                // ray potentially exits the cylinder at bottom +                if (shortest_distance < in) +                { +                    // ray missed the finite cylinder +                    return FALSE; +                } +            } + +        } +        else +        { +            // ray is parallel to end cap planes +            temp_vector = cyl_bottom - ray_point; +            shortest_distance = temp_vector * cyl_axis; +            if (shortest_distance < 0.0f  ||  shortest_distance > cyl_length) +            { +                // ray missed finite cylinder +                return FALSE; +            } +        } + +        return TRUE; +    } + +    return FALSE;  } -U32 ray_box(const LLVector3 &ray_point, const LLVector3 &ray_direction,  -			const LLVector3 &box_center, const LLVector3 &box_scale, const LLQuaternion &box_rotation, -			LLVector3 &intersection, LLVector3 &intersection_normal) +U32 ray_box(const LLVector3 &ray_point, const LLVector3 &ray_direction, +            const LLVector3 &box_center, const LLVector3 &box_scale, const LLQuaternion &box_rotation, +            LLVector3 &intersection, LLVector3 &intersection_normal)  { -	// Need to rotate into box frame -	LLQuaternion into_box_frame(box_rotation);		// rotates things from box frame to absolute -	into_box_frame.conjQuat();						// now rotates things into box frame -	LLVector3 line_point = (ray_point - box_center) * into_box_frame; -	LLVector3 line_direction = ray_direction * into_box_frame; - -	// Suppose we have a plane:  Ax + By + Cz + D = 0 -	// then, assuming [A, B, C] is a unit vector: -	// -	//    plane_normal = [A, B, C]  -	//    D = - (plane_normal * plane_point) -	//  -	// Suppose we have a line:  X = line_point + alpha * line_direction -	// -	// the intersection of the plane and line determines alpha -	// -	//    alpha = - (D + plane_normal * line_point) / (plane_normal * line_direction) - -	LLVector3 line_plane_intersection; - -	F32 pointX = line_point.mV[VX]; -	F32 pointY = line_point.mV[VY]; -	F32 pointZ = line_point.mV[VZ]; - -	F32 dirX = line_direction.mV[VX]; -	F32 dirY = line_direction.mV[VY]; -	F32 dirZ = line_direction.mV[VZ]; - -	// we'll be using the half-scales of the box -	F32 boxX = 0.5f * box_scale.mV[VX]; -	F32 boxY = 0.5f * box_scale.mV[VY]; -	F32 boxZ = 0.5f * box_scale.mV[VZ]; - -	// check to see if line_point is OUTSIDE the box -	if (pointX < -boxX || -		pointX >  boxX || -		pointY < -boxY || -		pointY >  boxY || -		pointZ < -boxZ || -		pointZ >  boxZ)  -	{ -		// -------------- point is OUTSIDE the box ---------------- - -		// front -		if (pointX > 0.0f  &&  dirX < 0.0f) -		{ -			// plane_normal                = [ 1, 0, 0] -			// plane_normal*line_point     = pointX -			// plane_normal*line_direction = dirX -			// D                           = -boxX -			// alpha                       = - (-boxX + pointX) / dirX -			line_plane_intersection = line_point - ((pointX - boxX) / dirX) * line_direction; -			if (line_plane_intersection.mV[VY] <  boxY && -				line_plane_intersection.mV[VY] > -boxY && -				line_plane_intersection.mV[VZ] <  boxZ && -				line_plane_intersection.mV[VZ] > -boxZ ) -			{ -				intersection = (line_plane_intersection * box_rotation) + box_center; -				intersection_normal = LLVector3(1.0f, 0.0f, 0.0f) * box_rotation; -				return FRONT_SIDE; -			} -		} -	 -		// back -		if (pointX < 0.0f  &&  dirX > 0.0f) -		{ -			// plane_normal                = [ -1, 0, 0] -			// plane_normal*line_point     = -pX  -			// plane_normal*line_direction = -direction.mV[VX] -			// D                           = -bX -			// alpha                       = - (-bX - pX) / (-dirX) -			line_plane_intersection = line_point - ((boxX + pointX)/ dirX) * line_direction; -			if (line_plane_intersection.mV[VY] <  boxY && -				line_plane_intersection.mV[VY] > -boxY && -				line_plane_intersection.mV[VZ] <  boxZ && -				line_plane_intersection.mV[VZ] > -boxZ ) -			{ -				intersection = (line_plane_intersection * box_rotation) + box_center; -				intersection_normal = LLVector3(-1.0f, 0.0f, 0.0f) * box_rotation; -				return BACK_SIDE; -			} -		} -	 -		// left -		if (pointY > 0.0f  &&  dirY < 0.0f) -		{ -			// plane_normal                = [0, 1, 0] -			// plane_normal*line_point     = pointY  -			// plane_normal*line_direction = dirY -			// D                           = -boxY -			// alpha                       = - (-boxY + pointY) / dirY -			line_plane_intersection = line_point + ((boxY - pointY)/dirY) * line_direction; - -			if (line_plane_intersection.mV[VX] <  boxX && -				line_plane_intersection.mV[VX] > -boxX && -				line_plane_intersection.mV[VZ] <  boxZ && -				line_plane_intersection.mV[VZ] > -boxZ ) -			{ -				intersection = (line_plane_intersection * box_rotation) + box_center; -				intersection_normal = LLVector3(0.0f, 1.0f, 0.0f) * box_rotation; -				return LEFT_SIDE; -			} -		} -	 -		// right -		if (pointY < 0.0f  &&  dirY > 0.0f) -		{ -			// plane_normal                = [0, -1, 0] -			// plane_normal*line_point     = -pointY  -			// plane_normal*line_direction = -dirY -			// D                           = -boxY -			// alpha                       = - (-boxY - pointY) / (-dirY) -			line_plane_intersection = line_point - ((boxY + pointY)/dirY) * line_direction; -			if (line_plane_intersection.mV[VX] <  boxX && -				line_plane_intersection.mV[VX] > -boxX && -				line_plane_intersection.mV[VZ] <  boxZ && -				line_plane_intersection.mV[VZ] > -boxZ ) -			{ -				intersection = (line_plane_intersection * box_rotation) + box_center; -				intersection_normal = LLVector3(0.0f, -1.0f, 0.0f) * box_rotation; -				return RIGHT_SIDE; -			} -		} -	 -		// top -		if (pointZ > 0.0f  &&  dirZ < 0.0f) -		{ -			// plane_normal                = [0, 0, 1] -			// plane_normal*line_point     = pointZ  -			// plane_normal*line_direction = dirZ -			// D                           = -boxZ -			// alpha                       = - (-boxZ + pointZ) / dirZ -			line_plane_intersection = line_point - ((pointZ - boxZ)/dirZ) * line_direction; -			if (line_plane_intersection.mV[VX] <  boxX && -				line_plane_intersection.mV[VX] > -boxX && -				line_plane_intersection.mV[VY] <  boxY && -				line_plane_intersection.mV[VY] > -boxY ) -			{ -				intersection = (line_plane_intersection * box_rotation) + box_center; -				intersection_normal = LLVector3(0.0f, 0.0f, 1.0f) * box_rotation; -				return TOP_SIDE; -			} -		} -	 -		// bottom -		if (pointZ < 0.0f  &&  dirZ > 0.0f) -		{ -			// plane_normal                = [0, 0, -1] -			// plane_normal*line_point     = -pointZ  -			// plane_normal*line_direction = -dirZ -			// D                           = -boxZ -			// alpha                       = - (-boxZ - pointZ) / (-dirZ) -			line_plane_intersection = line_point - ((boxZ + pointZ)/dirZ) * line_direction; -			if (line_plane_intersection.mV[VX] <  boxX && -				line_plane_intersection.mV[VX] > -boxX && -				line_plane_intersection.mV[VY] <  boxY && -				line_plane_intersection.mV[VY] > -boxY ) -			{ -				intersection = (line_plane_intersection * box_rotation) + box_center; -				intersection_normal = LLVector3(0.0f, 0.0f, -1.0f) * box_rotation; -				return BOTTOM_SIDE; -			} -		} -		return NO_SIDE; -	} - -	// -------------- point is INSIDE the box ---------------- - -	// front -	if (dirX > 0.0f) -	{ -		// plane_normal                = [ 1, 0, 0] -		// plane_normal*line_point     = pointX -		// plane_normal*line_direction = dirX -		// D                           = -boxX -		// alpha                       = - (-boxX + pointX) / dirX -		line_plane_intersection = line_point - ((pointX - boxX) / dirX) * line_direction; -		if (line_plane_intersection.mV[VY] <  boxY && -			line_plane_intersection.mV[VY] > -boxY && -			line_plane_intersection.mV[VZ] <  boxZ && -			line_plane_intersection.mV[VZ] > -boxZ ) -		{ -			intersection = (line_plane_intersection * box_rotation) + box_center; -			intersection_normal = LLVector3(1.0f, 0.0f, 0.0f) * box_rotation; -			return FRONT_SIDE; -		} -	} - -	// back -	if (dirX < 0.0f) -	{ -		// plane_normal                = [ -1, 0, 0] -		// plane_normal*line_point     = -pX  -		// plane_normal*line_direction = -direction.mV[VX] -		// D                           = -bX -		// alpha                       = - (-bX - pX) / (-dirX) -		line_plane_intersection = line_point - ((boxX + pointX)/ dirX) * line_direction; -		if (line_plane_intersection.mV[VY] <  boxY && -			line_plane_intersection.mV[VY] > -boxY && -			line_plane_intersection.mV[VZ] <  boxZ && -			line_plane_intersection.mV[VZ] > -boxZ ) -		{ -			intersection = (line_plane_intersection * box_rotation) + box_center; -			intersection_normal = LLVector3(-1.0f, 0.0f, 0.0f) * box_rotation; -			return BACK_SIDE; -		} -	} - -	// left -	if (dirY > 0.0f) -	{ -		// plane_normal                = [0, 1, 0] -		// plane_normal*line_point     = pointY  -		// plane_normal*line_direction = dirY -		// D                           = -boxY -		// alpha                       = - (-boxY + pointY) / dirY -		line_plane_intersection = line_point + ((boxY - pointY)/dirY) * line_direction; - -		if (line_plane_intersection.mV[VX] <  boxX && -			line_plane_intersection.mV[VX] > -boxX && -			line_plane_intersection.mV[VZ] <  boxZ && -			line_plane_intersection.mV[VZ] > -boxZ ) -		{ -			intersection = (line_plane_intersection * box_rotation) + box_center; -			intersection_normal = LLVector3(0.0f, 1.0f, 0.0f) * box_rotation; -			return LEFT_SIDE; -		} -	} - -	// right -	if (dirY < 0.0f) -	{ -		// plane_normal                = [0, -1, 0] -		// plane_normal*line_point     = -pointY  -		// plane_normal*line_direction = -dirY -		// D                           = -boxY -		// alpha                       = - (-boxY - pointY) / (-dirY) -		line_plane_intersection = line_point - ((boxY + pointY)/dirY) * line_direction; -		if (line_plane_intersection.mV[VX] <  boxX && -			line_plane_intersection.mV[VX] > -boxX && -			line_plane_intersection.mV[VZ] <  boxZ && -			line_plane_intersection.mV[VZ] > -boxZ ) -		{ -			intersection = (line_plane_intersection * box_rotation) + box_center; -			intersection_normal = LLVector3(0.0f, -1.0f, 0.0f) * box_rotation; -			return RIGHT_SIDE; -		} -	} - -	// top -	if (dirZ > 0.0f) -	{ -		// plane_normal                = [0, 0, 1] -		// plane_normal*line_point     = pointZ  -		// plane_normal*line_direction = dirZ -		// D                           = -boxZ -		// alpha                       = - (-boxZ + pointZ) / dirZ -		line_plane_intersection = line_point - ((pointZ - boxZ)/dirZ) * line_direction; -		if (line_plane_intersection.mV[VX] <  boxX && -			line_plane_intersection.mV[VX] > -boxX && -			line_plane_intersection.mV[VY] <  boxY && -			line_plane_intersection.mV[VY] > -boxY ) -		{ -			intersection = (line_plane_intersection * box_rotation) + box_center; -			intersection_normal = LLVector3(0.0f, 0.0f, 1.0f) * box_rotation; -			return TOP_SIDE; -		} -	} - -	// bottom -	if (dirZ < 0.0f) -	{ -		// plane_normal                = [0, 0, -1] -		// plane_normal*line_point     = -pointZ  -		// plane_normal*line_direction = -dirZ -		// D                           = -boxZ -		// alpha                       = - (-boxZ - pointZ) / (-dirZ) -		line_plane_intersection = line_point - ((boxZ + pointZ)/dirZ) * line_direction; -		if (line_plane_intersection.mV[VX] <  boxX && -			line_plane_intersection.mV[VX] > -boxX && -			line_plane_intersection.mV[VY] <  boxY && -			line_plane_intersection.mV[VY] > -boxY ) -		{ -			intersection = (line_plane_intersection * box_rotation) + box_center; -			intersection_normal = LLVector3(0.0f, 0.0f, -1.0f) * box_rotation; -			return BOTTOM_SIDE; -		} -	} - -	// should never get here unless line instersects at tangent point on edge or corner -	// however such cases will be EXTREMELY rare -	return NO_SIDE; +    // Need to rotate into box frame +    LLQuaternion into_box_frame(box_rotation);      // rotates things from box frame to absolute +    into_box_frame.conjQuat();                      // now rotates things into box frame +    LLVector3 line_point = (ray_point - box_center) * into_box_frame; +    LLVector3 line_direction = ray_direction * into_box_frame; + +    // Suppose we have a plane:  Ax + By + Cz + D = 0 +    // then, assuming [A, B, C] is a unit vector: +    // +    //    plane_normal = [A, B, C] +    //    D = - (plane_normal * plane_point) +    // +    // Suppose we have a line:  X = line_point + alpha * line_direction +    // +    // the intersection of the plane and line determines alpha +    // +    //    alpha = - (D + plane_normal * line_point) / (plane_normal * line_direction) + +    LLVector3 line_plane_intersection; + +    F32 pointX = line_point.mV[VX]; +    F32 pointY = line_point.mV[VY]; +    F32 pointZ = line_point.mV[VZ]; + +    F32 dirX = line_direction.mV[VX]; +    F32 dirY = line_direction.mV[VY]; +    F32 dirZ = line_direction.mV[VZ]; + +    // we'll be using the half-scales of the box +    F32 boxX = 0.5f * box_scale.mV[VX]; +    F32 boxY = 0.5f * box_scale.mV[VY]; +    F32 boxZ = 0.5f * box_scale.mV[VZ]; + +    // check to see if line_point is OUTSIDE the box +    if (pointX < -boxX || +        pointX >  boxX || +        pointY < -boxY || +        pointY >  boxY || +        pointZ < -boxZ || +        pointZ >  boxZ) +    { +        // -------------- point is OUTSIDE the box ---------------- + +        // front +        if (pointX > 0.0f  &&  dirX < 0.0f) +        { +            // plane_normal                = [ 1, 0, 0] +            // plane_normal*line_point     = pointX +            // plane_normal*line_direction = dirX +            // D                           = -boxX +            // alpha                       = - (-boxX + pointX) / dirX +            line_plane_intersection = line_point - ((pointX - boxX) / dirX) * line_direction; +            if (line_plane_intersection.mV[VY] <  boxY && +                line_plane_intersection.mV[VY] > -boxY && +                line_plane_intersection.mV[VZ] <  boxZ && +                line_plane_intersection.mV[VZ] > -boxZ ) +            { +                intersection = (line_plane_intersection * box_rotation) + box_center; +                intersection_normal = LLVector3(1.0f, 0.0f, 0.0f) * box_rotation; +                return FRONT_SIDE; +            } +        } + +        // back +        if (pointX < 0.0f  &&  dirX > 0.0f) +        { +            // plane_normal                = [ -1, 0, 0] +            // plane_normal*line_point     = -pX +            // plane_normal*line_direction = -direction.mV[VX] +            // D                           = -bX +            // alpha                       = - (-bX - pX) / (-dirX) +            line_plane_intersection = line_point - ((boxX + pointX)/ dirX) * line_direction; +            if (line_plane_intersection.mV[VY] <  boxY && +                line_plane_intersection.mV[VY] > -boxY && +                line_plane_intersection.mV[VZ] <  boxZ && +                line_plane_intersection.mV[VZ] > -boxZ ) +            { +                intersection = (line_plane_intersection * box_rotation) + box_center; +                intersection_normal = LLVector3(-1.0f, 0.0f, 0.0f) * box_rotation; +                return BACK_SIDE; +            } +        } + +        // left +        if (pointY > 0.0f  &&  dirY < 0.0f) +        { +            // plane_normal                = [0, 1, 0] +            // plane_normal*line_point     = pointY +            // plane_normal*line_direction = dirY +            // D                           = -boxY +            // alpha                       = - (-boxY + pointY) / dirY +            line_plane_intersection = line_point + ((boxY - pointY)/dirY) * line_direction; + +            if (line_plane_intersection.mV[VX] <  boxX && +                line_plane_intersection.mV[VX] > -boxX && +                line_plane_intersection.mV[VZ] <  boxZ && +                line_plane_intersection.mV[VZ] > -boxZ ) +            { +                intersection = (line_plane_intersection * box_rotation) + box_center; +                intersection_normal = LLVector3(0.0f, 1.0f, 0.0f) * box_rotation; +                return LEFT_SIDE; +            } +        } + +        // right +        if (pointY < 0.0f  &&  dirY > 0.0f) +        { +            // plane_normal                = [0, -1, 0] +            // plane_normal*line_point     = -pointY +            // plane_normal*line_direction = -dirY +            // D                           = -boxY +            // alpha                       = - (-boxY - pointY) / (-dirY) +            line_plane_intersection = line_point - ((boxY + pointY)/dirY) * line_direction; +            if (line_plane_intersection.mV[VX] <  boxX && +                line_plane_intersection.mV[VX] > -boxX && +                line_plane_intersection.mV[VZ] <  boxZ && +                line_plane_intersection.mV[VZ] > -boxZ ) +            { +                intersection = (line_plane_intersection * box_rotation) + box_center; +                intersection_normal = LLVector3(0.0f, -1.0f, 0.0f) * box_rotation; +                return RIGHT_SIDE; +            } +        } + +        // top +        if (pointZ > 0.0f  &&  dirZ < 0.0f) +        { +            // plane_normal                = [0, 0, 1] +            // plane_normal*line_point     = pointZ +            // plane_normal*line_direction = dirZ +            // D                           = -boxZ +            // alpha                       = - (-boxZ + pointZ) / dirZ +            line_plane_intersection = line_point - ((pointZ - boxZ)/dirZ) * line_direction; +            if (line_plane_intersection.mV[VX] <  boxX && +                line_plane_intersection.mV[VX] > -boxX && +                line_plane_intersection.mV[VY] <  boxY && +                line_plane_intersection.mV[VY] > -boxY ) +            { +                intersection = (line_plane_intersection * box_rotation) + box_center; +                intersection_normal = LLVector3(0.0f, 0.0f, 1.0f) * box_rotation; +                return TOP_SIDE; +            } +        } + +        // bottom +        if (pointZ < 0.0f  &&  dirZ > 0.0f) +        { +            // plane_normal                = [0, 0, -1] +            // plane_normal*line_point     = -pointZ +            // plane_normal*line_direction = -dirZ +            // D                           = -boxZ +            // alpha                       = - (-boxZ - pointZ) / (-dirZ) +            line_plane_intersection = line_point - ((boxZ + pointZ)/dirZ) * line_direction; +            if (line_plane_intersection.mV[VX] <  boxX && +                line_plane_intersection.mV[VX] > -boxX && +                line_plane_intersection.mV[VY] <  boxY && +                line_plane_intersection.mV[VY] > -boxY ) +            { +                intersection = (line_plane_intersection * box_rotation) + box_center; +                intersection_normal = LLVector3(0.0f, 0.0f, -1.0f) * box_rotation; +                return BOTTOM_SIDE; +            } +        } +        return NO_SIDE; +    } + +    // -------------- point is INSIDE the box ---------------- + +    // front +    if (dirX > 0.0f) +    { +        // plane_normal                = [ 1, 0, 0] +        // plane_normal*line_point     = pointX +        // plane_normal*line_direction = dirX +        // D                           = -boxX +        // alpha                       = - (-boxX + pointX) / dirX +        line_plane_intersection = line_point - ((pointX - boxX) / dirX) * line_direction; +        if (line_plane_intersection.mV[VY] <  boxY && +            line_plane_intersection.mV[VY] > -boxY && +            line_plane_intersection.mV[VZ] <  boxZ && +            line_plane_intersection.mV[VZ] > -boxZ ) +        { +            intersection = (line_plane_intersection * box_rotation) + box_center; +            intersection_normal = LLVector3(1.0f, 0.0f, 0.0f) * box_rotation; +            return FRONT_SIDE; +        } +    } + +    // back +    if (dirX < 0.0f) +    { +        // plane_normal                = [ -1, 0, 0] +        // plane_normal*line_point     = -pX +        // plane_normal*line_direction = -direction.mV[VX] +        // D                           = -bX +        // alpha                       = - (-bX - pX) / (-dirX) +        line_plane_intersection = line_point - ((boxX + pointX)/ dirX) * line_direction; +        if (line_plane_intersection.mV[VY] <  boxY && +            line_plane_intersection.mV[VY] > -boxY && +            line_plane_intersection.mV[VZ] <  boxZ && +            line_plane_intersection.mV[VZ] > -boxZ ) +        { +            intersection = (line_plane_intersection * box_rotation) + box_center; +            intersection_normal = LLVector3(-1.0f, 0.0f, 0.0f) * box_rotation; +            return BACK_SIDE; +        } +    } + +    // left +    if (dirY > 0.0f) +    { +        // plane_normal                = [0, 1, 0] +        // plane_normal*line_point     = pointY +        // plane_normal*line_direction = dirY +        // D                           = -boxY +        // alpha                       = - (-boxY + pointY) / dirY +        line_plane_intersection = line_point + ((boxY - pointY)/dirY) * line_direction; + +        if (line_plane_intersection.mV[VX] <  boxX && +            line_plane_intersection.mV[VX] > -boxX && +            line_plane_intersection.mV[VZ] <  boxZ && +            line_plane_intersection.mV[VZ] > -boxZ ) +        { +            intersection = (line_plane_intersection * box_rotation) + box_center; +            intersection_normal = LLVector3(0.0f, 1.0f, 0.0f) * box_rotation; +            return LEFT_SIDE; +        } +    } + +    // right +    if (dirY < 0.0f) +    { +        // plane_normal                = [0, -1, 0] +        // plane_normal*line_point     = -pointY +        // plane_normal*line_direction = -dirY +        // D                           = -boxY +        // alpha                       = - (-boxY - pointY) / (-dirY) +        line_plane_intersection = line_point - ((boxY + pointY)/dirY) * line_direction; +        if (line_plane_intersection.mV[VX] <  boxX && +            line_plane_intersection.mV[VX] > -boxX && +            line_plane_intersection.mV[VZ] <  boxZ && +            line_plane_intersection.mV[VZ] > -boxZ ) +        { +            intersection = (line_plane_intersection * box_rotation) + box_center; +            intersection_normal = LLVector3(0.0f, -1.0f, 0.0f) * box_rotation; +            return RIGHT_SIDE; +        } +    } + +    // top +    if (dirZ > 0.0f) +    { +        // plane_normal                = [0, 0, 1] +        // plane_normal*line_point     = pointZ +        // plane_normal*line_direction = dirZ +        // D                           = -boxZ +        // alpha                       = - (-boxZ + pointZ) / dirZ +        line_plane_intersection = line_point - ((pointZ - boxZ)/dirZ) * line_direction; +        if (line_plane_intersection.mV[VX] <  boxX && +            line_plane_intersection.mV[VX] > -boxX && +            line_plane_intersection.mV[VY] <  boxY && +            line_plane_intersection.mV[VY] > -boxY ) +        { +            intersection = (line_plane_intersection * box_rotation) + box_center; +            intersection_normal = LLVector3(0.0f, 0.0f, 1.0f) * box_rotation; +            return TOP_SIDE; +        } +    } + +    // bottom +    if (dirZ < 0.0f) +    { +        // plane_normal                = [0, 0, -1] +        // plane_normal*line_point     = -pointZ +        // plane_normal*line_direction = -dirZ +        // D                           = -boxZ +        // alpha                       = - (-boxZ - pointZ) / (-dirZ) +        line_plane_intersection = line_point - ((boxZ + pointZ)/dirZ) * line_direction; +        if (line_plane_intersection.mV[VX] <  boxX && +            line_plane_intersection.mV[VX] > -boxX && +            line_plane_intersection.mV[VY] <  boxY && +            line_plane_intersection.mV[VY] > -boxY ) +        { +            intersection = (line_plane_intersection * box_rotation) + box_center; +            intersection_normal = LLVector3(0.0f, 0.0f, -1.0f) * box_rotation; +            return BOTTOM_SIDE; +        } +    } + +    // should never get here unless line instersects at tangent point on edge or corner +    // however such cases will be EXTREMELY rare +    return NO_SIDE;  }  BOOL ray_prism(const LLVector3 &ray_point, const LLVector3 &ray_direction, -			   const LLVector3 &prism_center, const LLVector3 &prism_scale, const LLQuaternion &prism_rotation, -			   LLVector3 &intersection, LLVector3 &intersection_normal) +               const LLVector3 &prism_center, const LLVector3 &prism_scale, const LLQuaternion &prism_rotation, +               LLVector3 &intersection, LLVector3 &intersection_normal)  { -	//      (0)              Z   -	//      /| \             .   -	//    (1)|  \           /|\  _.Y -	//     | \   \           |   /| -	//     | |\   \          |  / -	//     | | \(0)\         | /  -	//     | |  \   \        |/ -	//     | |   \   \      (*)----> X   -	//     |(3)---\---(2)       -	//     |/      \  /         -	//    (4)-------(5)         - -	// need to calculate the points of the prism so we can run ray tests with each face -	F32 x = prism_scale.mV[VX]; -	F32 y = prism_scale.mV[VY]; -	F32 z = prism_scale.mV[VZ]; - -	F32 tx = x * 2.0f / 3.0f; -	F32 ty = y * 0.5f; -	F32 tz = z * 2.0f / 3.0f; - -	LLVector3 point0(tx-x,  ty, tz); -	LLVector3 point1(tx-x, -ty, tz); -	LLVector3 point2(tx,    ty, tz-z); -	LLVector3 point3(tx-x,  ty, tz-z); -	LLVector3 point4(tx-x, -ty, tz-z); -	LLVector3 point5(tx,   -ty, tz-z); - -	// transform these points into absolute frame -	point0 = (point0 * prism_rotation) + prism_center; -	point1 = (point1 * prism_rotation) + prism_center; -	point2 = (point2 * prism_rotation) + prism_center; -	point3 = (point3 * prism_rotation) + prism_center; -	point4 = (point4 * prism_rotation) + prism_center; -	point5 = (point5 * prism_rotation) + prism_center; - -	// test ray intersection for each face -	BOOL b_hit = FALSE; -	LLVector3 face_intersection, face_normal; -	F32 distance_squared = 0.0f; -	F32 temp; - -	// face 0 -	if (ray_direction * ( (point0 - point2) % (point5 - point2)) < 0.0f  &&  -		ray_quadrangle(ray_point, ray_direction, point5, point2, point0, intersection, intersection_normal)) -	{ -		distance_squared = (ray_point - intersection).magVecSquared(); -		b_hit = TRUE; -	} - -	// face 1 -	if (ray_direction * ( (point0 - point3) % (point2 - point3)) < 0.0f  && -		ray_triangle(ray_point, ray_direction, point2, point3, point0, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				distance_squared = temp; -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			distance_squared = (ray_point - face_intersection).magVecSquared(); -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} -	 -	// face 2 -	if (ray_direction * ( (point1 - point4) % (point3 - point4)) < 0.0f  && -		ray_quadrangle(ray_point, ray_direction, point3, point4, point1, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				distance_squared = temp; -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			distance_squared = (ray_point - face_intersection).magVecSquared(); -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} -	 -	// face 3 -	if (ray_direction * ( (point5 - point4) % (point1 - point4)) < 0.0f  && -		ray_triangle(ray_point, ray_direction, point1, point4, point5, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				distance_squared = temp; -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			distance_squared = (ray_point - face_intersection).magVecSquared(); -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} - -	// face 4 -	if (ray_direction * ( (point4 - point5) % (point2 - point5)) < 0.0f  && -		ray_quadrangle(ray_point, ray_direction, point2, point5, point4, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				distance_squared = temp; -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			distance_squared = (ray_point - face_intersection).magVecSquared(); -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} - -	return b_hit; +    //      (0)              Z +    //      /| \             . +    //    (1)|  \           /|\  _.Y +    //     | \   \           |   /| +    //     | |\   \          |  / +    //     | | \(0)\         | / +    //     | |  \   \        |/ +    //     | |   \   \      (*)----> X +    //     |(3)---\---(2) +    //     |/      \  / +    //    (4)-------(5) + +    // need to calculate the points of the prism so we can run ray tests with each face +    F32 x = prism_scale.mV[VX]; +    F32 y = prism_scale.mV[VY]; +    F32 z = prism_scale.mV[VZ]; + +    F32 tx = x * 2.0f / 3.0f; +    F32 ty = y * 0.5f; +    F32 tz = z * 2.0f / 3.0f; + +    LLVector3 point0(tx-x,  ty, tz); +    LLVector3 point1(tx-x, -ty, tz); +    LLVector3 point2(tx,    ty, tz-z); +    LLVector3 point3(tx-x,  ty, tz-z); +    LLVector3 point4(tx-x, -ty, tz-z); +    LLVector3 point5(tx,   -ty, tz-z); + +    // transform these points into absolute frame +    point0 = (point0 * prism_rotation) + prism_center; +    point1 = (point1 * prism_rotation) + prism_center; +    point2 = (point2 * prism_rotation) + prism_center; +    point3 = (point3 * prism_rotation) + prism_center; +    point4 = (point4 * prism_rotation) + prism_center; +    point5 = (point5 * prism_rotation) + prism_center; + +    // test ray intersection for each face +    BOOL b_hit = FALSE; +    LLVector3 face_intersection, face_normal; +    F32 distance_squared = 0.0f; +    F32 temp; + +    // face 0 +    if (ray_direction * ( (point0 - point2) % (point5 - point2)) < 0.0f  && +        ray_quadrangle(ray_point, ray_direction, point5, point2, point0, intersection, intersection_normal)) +    { +        distance_squared = (ray_point - intersection).magVecSquared(); +        b_hit = TRUE; +    } + +    // face 1 +    if (ray_direction * ( (point0 - point3) % (point2 - point3)) < 0.0f  && +        ray_triangle(ray_point, ray_direction, point2, point3, point0, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                distance_squared = temp; +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            distance_squared = (ray_point - face_intersection).magVecSquared(); +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    // face 2 +    if (ray_direction * ( (point1 - point4) % (point3 - point4)) < 0.0f  && +        ray_quadrangle(ray_point, ray_direction, point3, point4, point1, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                distance_squared = temp; +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            distance_squared = (ray_point - face_intersection).magVecSquared(); +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    // face 3 +    if (ray_direction * ( (point5 - point4) % (point1 - point4)) < 0.0f  && +        ray_triangle(ray_point, ray_direction, point1, point4, point5, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                distance_squared = temp; +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            distance_squared = (ray_point - face_intersection).magVecSquared(); +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    // face 4 +    if (ray_direction * ( (point4 - point5) % (point2 - point5)) < 0.0f  && +        ray_quadrangle(ray_point, ray_direction, point2, point5, point4, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                distance_squared = temp; +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            distance_squared = (ray_point - face_intersection).magVecSquared(); +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    return b_hit;  }  BOOL ray_tetrahedron(const LLVector3 &ray_point, const LLVector3 &ray_direction, -					 const LLVector3 &t_center, const LLVector3 &t_scale, const LLQuaternion &t_rotation, -					 LLVector3 &intersection, LLVector3 &intersection_normal) +                     const LLVector3 &t_center, const LLVector3 &t_scale, const LLQuaternion &t_rotation, +                     LLVector3 &intersection, LLVector3 &intersection_normal)  { -	F32 a = 0.5f * F_SQRT3;				// height of unit triangle -	F32 b = 1.0f / F_SQRT3;				// distance of center of unit triangle to each point -	F32 c = F_SQRT2 / F_SQRT3;			// height of unit tetrahedron -	F32 d = 0.5f * F_SQRT3 / F_SQRT2;	// distance of center of tetrahedron to each point - -	// if we want the tetrahedron to have unit height (c = 1.0) then we need to divide -	// each constant by hieght of a unit tetrahedron -	F32 oo_c = 1.0f / c; -	a = a * oo_c; -	b = b * oo_c; -	c = 1.0f; -	d = d * oo_c; -	F32 e = 0.5f * oo_c; - -	LLVector3 point0(			   0.0f,					0.0f,  t_scale.mV[VZ] * d); -	LLVector3 point1(t_scale.mV[VX] * b,					0.0f,  t_scale.mV[VZ] * (d-c)); -	LLVector3 point2(t_scale.mV[VX] * (b-a),  e * t_scale.mV[VY],  t_scale.mV[VZ] * (d-c)); -	LLVector3 point3(t_scale.mV[VX] * (b-a), -e * t_scale.mV[VY],  t_scale.mV[VZ] * (d-c)); - -	// transform these points into absolute frame -	point0 = (point0 * t_rotation) + t_center; -	point1 = (point1 * t_rotation) + t_center; -	point2 = (point2 * t_rotation) + t_center; -	point3 = (point3 * t_rotation) + t_center; - -	// test ray intersection for each face -	BOOL b_hit = FALSE; -	LLVector3 face_intersection, face_normal; -	F32 distance_squared = 1.0e12f; -	F32 temp; - -	// face 0 -	if (ray_direction * ( (point2 - point1) % (point0 - point1)) < 0.0f  &&  -		ray_triangle(ray_point, ray_direction, point1, point2, point0, intersection, intersection_normal)) -	{ -		distance_squared = (ray_point - intersection).magVecSquared(); -		b_hit = TRUE; -	} - -	// face 1 -	if (ray_direction * ( (point3 - point2) % (point0 - point2)) < 0.0f  && -		ray_triangle(ray_point, ray_direction, point2, point3, point0, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				distance_squared = temp; -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			distance_squared = (ray_point - face_intersection).magVecSquared(); -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} -	 -	// face 2 -	if (ray_direction * ( (point1 - point3) % (point0 - point3)) < 0.0f  && -		ray_triangle(ray_point, ray_direction, point3, point1, point0, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				distance_squared = temp; -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			distance_squared = (ray_point - face_intersection).magVecSquared(); -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} -	 -	// face 3 -	if (ray_direction * ( (point2 - point3) % (point1 - point3)) < 0.0f  && -		ray_triangle(ray_point, ray_direction, point3, point2, point1, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} - -	return b_hit; +    F32 a = 0.5f * F_SQRT3;             // height of unit triangle +    F32 b = 1.0f / F_SQRT3;             // distance of center of unit triangle to each point +    F32 c = F_SQRT2 / F_SQRT3;          // height of unit tetrahedron +    F32 d = 0.5f * F_SQRT3 / F_SQRT2;   // distance of center of tetrahedron to each point + +    // if we want the tetrahedron to have unit height (c = 1.0) then we need to divide +    // each constant by hieght of a unit tetrahedron +    F32 oo_c = 1.0f / c; +    a = a * oo_c; +    b = b * oo_c; +    c = 1.0f; +    d = d * oo_c; +    F32 e = 0.5f * oo_c; + +    LLVector3 point0(              0.0f,                    0.0f,  t_scale.mV[VZ] * d); +    LLVector3 point1(t_scale.mV[VX] * b,                    0.0f,  t_scale.mV[VZ] * (d-c)); +    LLVector3 point2(t_scale.mV[VX] * (b-a),  e * t_scale.mV[VY],  t_scale.mV[VZ] * (d-c)); +    LLVector3 point3(t_scale.mV[VX] * (b-a), -e * t_scale.mV[VY],  t_scale.mV[VZ] * (d-c)); + +    // transform these points into absolute frame +    point0 = (point0 * t_rotation) + t_center; +    point1 = (point1 * t_rotation) + t_center; +    point2 = (point2 * t_rotation) + t_center; +    point3 = (point3 * t_rotation) + t_center; + +    // test ray intersection for each face +    BOOL b_hit = FALSE; +    LLVector3 face_intersection, face_normal; +    F32 distance_squared = 1.0e12f; +    F32 temp; + +    // face 0 +    if (ray_direction * ( (point2 - point1) % (point0 - point1)) < 0.0f  && +        ray_triangle(ray_point, ray_direction, point1, point2, point0, intersection, intersection_normal)) +    { +        distance_squared = (ray_point - intersection).magVecSquared(); +        b_hit = TRUE; +    } + +    // face 1 +    if (ray_direction * ( (point3 - point2) % (point0 - point2)) < 0.0f  && +        ray_triangle(ray_point, ray_direction, point2, point3, point0, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                distance_squared = temp; +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            distance_squared = (ray_point - face_intersection).magVecSquared(); +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    // face 2 +    if (ray_direction * ( (point1 - point3) % (point0 - point3)) < 0.0f  && +        ray_triangle(ray_point, ray_direction, point3, point1, point0, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                distance_squared = temp; +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            distance_squared = (ray_point - face_intersection).magVecSquared(); +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    // face 3 +    if (ray_direction * ( (point2 - point3) % (point1 - point3)) < 0.0f  && +        ray_triangle(ray_point, ray_direction, point3, point2, point1, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    return b_hit;  }  BOOL ray_pyramid(const LLVector3 &ray_point, const LLVector3 &ray_direction, -				 const LLVector3 &p_center, const LLVector3 &p_scale, const LLQuaternion &p_rotation, -				 LLVector3 &intersection, LLVector3 &intersection_normal) +                 const LLVector3 &p_center, const LLVector3 &p_scale, const LLQuaternion &p_rotation, +                 LLVector3 &intersection, LLVector3 &intersection_normal)  { -	// center of mass of pyramid is located 1/4 its height from the base -	F32 x = 0.5f * p_scale.mV[VX]; -	F32 y = 0.5f * p_scale.mV[VY]; -	F32 z = 0.25f * p_scale.mV[VZ]; - -	LLVector3 point0(0.0f, 0.0f,  p_scale.mV[VZ] - z); -	LLVector3 point1( x,  y, -z); -	LLVector3 point2(-x,  y, -z); -	LLVector3 point3(-x, -y, -z); -	LLVector3 point4( x, -y, -z); - -	// transform these points into absolute frame -	point0 = (point0 * p_rotation) + p_center; -	point1 = (point1 * p_rotation) + p_center; -	point2 = (point2 * p_rotation) + p_center; -	point3 = (point3 * p_rotation) + p_center; -	point4 = (point4 * p_rotation) + p_center; - -	// test ray intersection for each face -	BOOL b_hit = FALSE; -	LLVector3 face_intersection, face_normal; -	F32 distance_squared = 1.0e12f; -	F32 temp; - -	// face 0 -	if (ray_direction * ( (point1 - point4) % (point0 - point4)) < 0.0f  &&  -		ray_triangle(ray_point, ray_direction, point4, point1, point0, intersection, intersection_normal)) -	{ -		distance_squared = (ray_point - intersection).magVecSquared(); -		b_hit = TRUE; -	} - -	// face 1 -	if (ray_direction * ( (point2 - point1) % (point0 - point1)) < 0.0f  && -		ray_triangle(ray_point, ray_direction, point1, point2, point0, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				distance_squared = temp; -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			distance_squared = (ray_point - face_intersection).magVecSquared(); -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} -	 -	// face 2 -	if (ray_direction * ( (point3 - point2) % (point0 - point2)) < 0.0f  && -		ray_triangle(ray_point, ray_direction, point2, point3, point0, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				distance_squared = temp; -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			distance_squared = (ray_point - face_intersection).magVecSquared(); -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} - -	// face 3 -	if (ray_direction * ( (point4 - point3) % (point0 - point3)) < 0.0f  && -		ray_triangle(ray_point, ray_direction, point3, point4, point0, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				distance_squared = temp; -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			distance_squared = (ray_point - face_intersection).magVecSquared(); -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} -	 -	// face 4 -	if (ray_direction * ( (point3 - point4) % (point2 - point4)) < 0.0f  && -		ray_quadrangle(ray_point, ray_direction, point4, point3, point2, face_intersection, face_normal)) -	{ -		if (TRUE == b_hit) -		{ -			temp = (ray_point - face_intersection).magVecSquared(); -			if (temp < distance_squared) -			{ -				intersection = face_intersection; -				intersection_normal = face_normal; -			} -		} -		else  -		{ -			intersection = face_intersection; -			intersection_normal = face_normal; -			b_hit = TRUE; -		} -	} - -	return b_hit; +    // center of mass of pyramid is located 1/4 its height from the base +    F32 x = 0.5f * p_scale.mV[VX]; +    F32 y = 0.5f * p_scale.mV[VY]; +    F32 z = 0.25f * p_scale.mV[VZ]; + +    LLVector3 point0(0.0f, 0.0f,  p_scale.mV[VZ] - z); +    LLVector3 point1( x,  y, -z); +    LLVector3 point2(-x,  y, -z); +    LLVector3 point3(-x, -y, -z); +    LLVector3 point4( x, -y, -z); + +    // transform these points into absolute frame +    point0 = (point0 * p_rotation) + p_center; +    point1 = (point1 * p_rotation) + p_center; +    point2 = (point2 * p_rotation) + p_center; +    point3 = (point3 * p_rotation) + p_center; +    point4 = (point4 * p_rotation) + p_center; + +    // test ray intersection for each face +    BOOL b_hit = FALSE; +    LLVector3 face_intersection, face_normal; +    F32 distance_squared = 1.0e12f; +    F32 temp; + +    // face 0 +    if (ray_direction * ( (point1 - point4) % (point0 - point4)) < 0.0f  && +        ray_triangle(ray_point, ray_direction, point4, point1, point0, intersection, intersection_normal)) +    { +        distance_squared = (ray_point - intersection).magVecSquared(); +        b_hit = TRUE; +    } + +    // face 1 +    if (ray_direction * ( (point2 - point1) % (point0 - point1)) < 0.0f  && +        ray_triangle(ray_point, ray_direction, point1, point2, point0, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                distance_squared = temp; +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            distance_squared = (ray_point - face_intersection).magVecSquared(); +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    // face 2 +    if (ray_direction * ( (point3 - point2) % (point0 - point2)) < 0.0f  && +        ray_triangle(ray_point, ray_direction, point2, point3, point0, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                distance_squared = temp; +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            distance_squared = (ray_point - face_intersection).magVecSquared(); +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    // face 3 +    if (ray_direction * ( (point4 - point3) % (point0 - point3)) < 0.0f  && +        ray_triangle(ray_point, ray_direction, point3, point4, point0, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                distance_squared = temp; +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            distance_squared = (ray_point - face_intersection).magVecSquared(); +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    // face 4 +    if (ray_direction * ( (point3 - point4) % (point2 - point4)) < 0.0f  && +        ray_quadrangle(ray_point, ray_direction, point4, point3, point2, face_intersection, face_normal)) +    { +        if (TRUE == b_hit) +        { +            temp = (ray_point - face_intersection).magVecSquared(); +            if (temp < distance_squared) +            { +                intersection = face_intersection; +                intersection_normal = face_normal; +            } +        } +        else +        { +            intersection = face_intersection; +            intersection_normal = face_normal; +            b_hit = TRUE; +        } +    } + +    return b_hit;  }  BOOL linesegment_circle(const LLVector3 &point_a, const LLVector3 &point_b, -						const LLVector3 &circle_center, const LLVector3 plane_normal, F32 circle_radius, -						LLVector3 &intersection) +                        const LLVector3 &circle_center, const LLVector3 plane_normal, F32 circle_radius, +                        LLVector3 &intersection)  { -	LLVector3 ray_direction = point_b - point_a; -	F32 segment_length = ray_direction.normVec(); - -	if (ray_circle(point_a, ray_direction, circle_center, plane_normal, circle_radius, intersection)) -	{ -		if (segment_length >= (point_a - intersection).magVec()) -		{ -			return TRUE; -		} -	} -	return FALSE; +    LLVector3 ray_direction = point_b - point_a; +    F32 segment_length = ray_direction.normVec(); + +    if (ray_circle(point_a, ray_direction, circle_center, plane_normal, circle_radius, intersection)) +    { +        if (segment_length >= (point_a - intersection).magVec()) +        { +            return TRUE; +        } +    } +    return FALSE;  }  BOOL linesegment_triangle(const LLVector3 &point_a, const LLVector3 &point_b, -						  const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, -						  LLVector3 &intersection, LLVector3 &intersection_normal) +                          const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, +                          LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 ray_direction = point_b - point_a; -	F32 segment_length = ray_direction.normVec(); - -	if (ray_triangle(point_a, ray_direction, point_0, point_1, point_2, intersection, intersection_normal)) -	{ -		if (segment_length >= (point_a - intersection).magVec()) -		{ -			return TRUE; -		} -	} -	return FALSE; +    LLVector3 ray_direction = point_b - point_a; +    F32 segment_length = ray_direction.normVec(); + +    if (ray_triangle(point_a, ray_direction, point_0, point_1, point_2, intersection, intersection_normal)) +    { +        if (segment_length >= (point_a - intersection).magVec()) +        { +            return TRUE; +        } +    } +    return FALSE;  }  BOOL linesegment_quadrangle(const LLVector3 &point_a, const LLVector3 &point_b, -							const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, -							LLVector3 &intersection, LLVector3 &intersection_normal) +                            const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, +                            LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 ray_direction = point_b - point_a; -	F32 segment_length = ray_direction.normVec(); - -	if (ray_quadrangle(point_a, ray_direction, point_0, point_1, point_2, intersection, intersection_normal)) -	{ -		if (segment_length >= (point_a - intersection).magVec()) -		{ -			return TRUE; -		} -	} -	return FALSE; +    LLVector3 ray_direction = point_b - point_a; +    F32 segment_length = ray_direction.normVec(); + +    if (ray_quadrangle(point_a, ray_direction, point_0, point_1, point_2, intersection, intersection_normal)) +    { +        if (segment_length >= (point_a - intersection).magVec()) +        { +            return TRUE; +        } +    } +    return FALSE;  }  BOOL linesegment_sphere(const LLVector3 &point_a, const LLVector3 &point_b, -				const LLVector3 &sphere_center, F32 sphere_radius, -				LLVector3 &intersection, LLVector3 &intersection_normal) +                const LLVector3 &sphere_center, F32 sphere_radius, +                LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 ray_direction = point_b - point_a; -	F32 segment_length = ray_direction.normVec(); - -	if (ray_sphere(point_a, ray_direction, sphere_center, sphere_radius, intersection, intersection_normal)) -	{ -		if (segment_length >= (point_a - intersection).magVec()) -		{ -			return TRUE; -		} -	} -	return FALSE; +    LLVector3 ray_direction = point_b - point_a; +    F32 segment_length = ray_direction.normVec(); + +    if (ray_sphere(point_a, ray_direction, sphere_center, sphere_radius, intersection, intersection_normal)) +    { +        if (segment_length >= (point_a - intersection).magVec()) +        { +            return TRUE; +        } +    } +    return FALSE;  }  BOOL linesegment_cylinder(const LLVector3 &point_a, const LLVector3 &point_b, -				  const LLVector3 &cyl_center, const LLVector3 &cyl_scale, const LLQuaternion &cyl_rotation, -				  LLVector3 &intersection, LLVector3 &intersection_normal) +                  const LLVector3 &cyl_center, const LLVector3 &cyl_scale, const LLQuaternion &cyl_rotation, +                  LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 ray_direction = point_b - point_a; -	F32 segment_length = ray_direction.normVec(); - -	if (ray_cylinder(point_a, ray_direction, cyl_center, cyl_scale, cyl_rotation, intersection, intersection_normal)) -	{ -		if (segment_length >= (point_a - intersection).magVec()) -		{ -			return TRUE; -		} -	} -	return FALSE; +    LLVector3 ray_direction = point_b - point_a; +    F32 segment_length = ray_direction.normVec(); + +    if (ray_cylinder(point_a, ray_direction, cyl_center, cyl_scale, cyl_rotation, intersection, intersection_normal)) +    { +        if (segment_length >= (point_a - intersection).magVec()) +        { +            return TRUE; +        } +    } +    return FALSE;  } -U32 linesegment_box(const LLVector3 &point_a, const LLVector3 &point_b,  -					const LLVector3 &box_center, const LLVector3 &box_scale, const LLQuaternion &box_rotation, -					LLVector3 &intersection, LLVector3 &intersection_normal) +U32 linesegment_box(const LLVector3 &point_a, const LLVector3 &point_b, +                    const LLVector3 &box_center, const LLVector3 &box_scale, const LLQuaternion &box_rotation, +                    LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 direction = point_b - point_a; -	if (direction.isNull()) -	{ -		return NO_SIDE; -	} - -	F32 segment_length = direction.normVec(); -	U32 box_side = ray_box(point_a, direction, box_center, box_scale, box_rotation, intersection, intersection_normal); -	if (NO_SIDE == box_side  ||  segment_length < (intersection - point_a).magVec()) -	{ -		return NO_SIDE; -	} - -	return box_side; +    LLVector3 direction = point_b - point_a; +    if (direction.isNull()) +    { +        return NO_SIDE; +    } + +    F32 segment_length = direction.normVec(); +    U32 box_side = ray_box(point_a, direction, box_center, box_scale, box_rotation, intersection, intersection_normal); +    if (NO_SIDE == box_side  ||  segment_length < (intersection - point_a).magVec()) +    { +        return NO_SIDE; +    } + +    return box_side;  }  BOOL linesegment_prism(const LLVector3 &point_a, const LLVector3 &point_b, -					   const LLVector3 &prism_center, const LLVector3 &prism_scale, const LLQuaternion &prism_rotation, -					   LLVector3 &intersection, LLVector3 &intersection_normal) +                       const LLVector3 &prism_center, const LLVector3 &prism_scale, const LLQuaternion &prism_rotation, +                       LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 ray_direction = point_b - point_a; -	F32 segment_length = ray_direction.normVec(); - -	if (ray_prism(point_a, ray_direction, prism_center, prism_scale, prism_rotation, intersection, intersection_normal)) -	{ -		if (segment_length >= (point_a - intersection).magVec()) -		{ -			return TRUE; -		} -	} -	return FALSE; +    LLVector3 ray_direction = point_b - point_a; +    F32 segment_length = ray_direction.normVec(); + +    if (ray_prism(point_a, ray_direction, prism_center, prism_scale, prism_rotation, intersection, intersection_normal)) +    { +        if (segment_length >= (point_a - intersection).magVec()) +        { +            return TRUE; +        } +    } +    return FALSE;  }  BOOL linesegment_tetrahedron(const LLVector3 &point_a, const LLVector3 &point_b, -							 const LLVector3 &t_center, const LLVector3 &t_scale, const LLQuaternion &t_rotation, -							 LLVector3 &intersection, LLVector3 &intersection_normal) +                             const LLVector3 &t_center, const LLVector3 &t_scale, const LLQuaternion &t_rotation, +                             LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 ray_direction = point_b - point_a; -	F32 segment_length = ray_direction.normVec(); - -	if (ray_tetrahedron(point_a, ray_direction, t_center, t_scale, t_rotation, intersection, intersection_normal)) -	{ -		if (segment_length >= (point_a - intersection).magVec()) -		{ -			return TRUE; -		} -	} -	return FALSE; +    LLVector3 ray_direction = point_b - point_a; +    F32 segment_length = ray_direction.normVec(); + +    if (ray_tetrahedron(point_a, ray_direction, t_center, t_scale, t_rotation, intersection, intersection_normal)) +    { +        if (segment_length >= (point_a - intersection).magVec()) +        { +            return TRUE; +        } +    } +    return FALSE;  }  BOOL linesegment_pyramid(const LLVector3 &point_a, const LLVector3 &point_b, -						 const LLVector3 &p_center, const LLVector3 &p_scale, const LLQuaternion &p_rotation, -						 LLVector3 &intersection, LLVector3 &intersection_normal) +                         const LLVector3 &p_center, const LLVector3 &p_scale, const LLQuaternion &p_rotation, +                         LLVector3 &intersection, LLVector3 &intersection_normal)  { -	LLVector3 ray_direction = point_b - point_a; -	F32 segment_length = ray_direction.normVec(); - -	if (ray_pyramid(point_a, ray_direction, p_center, p_scale, p_rotation, intersection, intersection_normal)) -	{ -		if (segment_length >= (point_a - intersection).magVec()) -		{ -			return TRUE; -		} -	} -	return FALSE; +    LLVector3 ray_direction = point_b - point_a; +    F32 segment_length = ray_direction.normVec(); + +    if (ray_pyramid(point_a, ray_direction, p_center, p_scale, p_rotation, intersection, intersection_normal)) +    { +        if (segment_length >= (point_a - intersection).magVec()) +        { +            return TRUE; +        } +    } +    return FALSE;  } diff --git a/indra/llmath/raytrace.h b/indra/llmath/raytrace.h index 2d32af0c86..01b8ee64f4 100644 --- a/indra/llmath/raytrace.h +++ b/indra/llmath/raytrace.h @@ -1,25 +1,25 @@ -/**  +/**   * @file raytrace.h   * @brief Ray intersection tests for primitives.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -39,7 +39,7 @@ class LLQuaternion;  // object along the three axes.  //  // All functions return the expected TRUE or FALSE, unless otherwise noted. -// When FALSE is returned, any resulting values that might have been stored  +// When FALSE is returned, any resulting values that might have been stored  // are undefined.  //  // Rays are defined by a "ray_point" and a "ray_direction" (unit). @@ -55,177 +55,177 @@ class LLQuaternion;  // Intersection normals always point outside the object, normal to the object's  // surface at the point of intersection.  // -// Object rotations passed as quaternions are expected to rotate from the  +// Object rotations passed as quaternions are expected to rotate from the  // object's local frame to the absolute frame.  So, if "foo" is a vector in  // the object's local frame, then "foo * object_rotation" is in the absolute  // frame.  // returns TRUE iff line is not parallel to plane. -BOOL line_plane(const LLVector3 &line_point, const LLVector3 &line_direction,  -				const LLVector3 &plane_point, const LLVector3 plane_normal,  -				LLVector3 &intersection); +BOOL line_plane(const LLVector3 &line_point, const LLVector3 &line_direction, +                const LLVector3 &plane_point, const LLVector3 plane_normal, +                LLVector3 &intersection);  // returns TRUE iff line is not parallel to plane. -BOOL ray_plane(const LLVector3 &ray_point, const LLVector3 &ray_direction,  -			   const LLVector3 &plane_point, const LLVector3 plane_normal,  -			   LLVector3 &intersection); +BOOL ray_plane(const LLVector3 &ray_point, const LLVector3 &ray_direction, +               const LLVector3 &plane_point, const LLVector3 plane_normal, +               LLVector3 &intersection); -BOOL ray_circle(const LLVector3 &ray_point, const LLVector3 &ray_direction,  -				const LLVector3 &circle_center, const LLVector3 plane_normal, F32 circle_radius, -				LLVector3 &intersection); +BOOL ray_circle(const LLVector3 &ray_point, const LLVector3 &ray_direction, +                const LLVector3 &circle_center, const LLVector3 plane_normal, F32 circle_radius, +                LLVector3 &intersection);  // point_0 through point_2 define the plane_normal via the right-hand rule:  // circle from point_0 to point_2 with fingers ==> thumb points in direction of normal -BOOL ray_triangle(const LLVector3 &ray_point, const LLVector3 &ray_direction,  -				  const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2,  -				  LLVector3 &intersection, LLVector3 &intersection_normal); +BOOL ray_triangle(const LLVector3 &ray_point, const LLVector3 &ray_direction, +                  const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, +                  LLVector3 &intersection, LLVector3 &intersection_normal);  // point_0 is the lower-left corner, point_1 is the lower-right, point_2 is the upper-right  // right-hand-rule... curl fingers from lower-left toward lower-right then toward upper-right  // ==> thumb points in direction of normal  // assumes a parallelogram, so point_3 is determined by the other points -BOOL ray_quadrangle(const LLVector3 &ray_point, const LLVector3 &ray_direction,  -					const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2,  -					LLVector3 &intersection, LLVector3 &intersection_normal); +BOOL ray_quadrangle(const LLVector3 &ray_point, const LLVector3 &ray_direction, +                    const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, +                    LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL ray_sphere(const LLVector3 &ray_point, const LLVector3 &ray_direction, -				const LLVector3 &sphere_center, F32 sphere_radius, -				LLVector3 &intersection, LLVector3 &intersection_normal); +                const LLVector3 &sphere_center, F32 sphere_radius, +                LLVector3 &intersection, LLVector3 &intersection_normal); -// finite right cylinder is defined by end centers: "cyl_top", "cyl_bottom",  +// finite right cylinder is defined by end centers: "cyl_top", "cyl_bottom",  // and by the cylinder radius "cyl_radius"  BOOL ray_cylinder(const LLVector3 &ray_point, const LLVector3 &ray_direction, -		          const LLVector3 &cyl_center, const LLVector3 &cyl_scale, const LLQuaternion &cyl_rotation, -				  LLVector3 &intersection, LLVector3 &intersection_normal); +                  const LLVector3 &cyl_center, const LLVector3 &cyl_scale, const LLQuaternion &cyl_rotation, +                  LLVector3 &intersection, LLVector3 &intersection_normal);  // this function doesn't just return a BOOL because the return is currently -// used to decide how to break up boxes that have been hit by shots...  +// used to decide how to break up boxes that have been hit by shots...  // a hack that will probably be changed later  //  // returns a number representing the side of the box that was hit by the ray,  // or NO_SIDE if intersection test failed.  U32 ray_box(const LLVector3 &ray_point, const LLVector3 &ray_direction, -		    const LLVector3 &box_center, const LLVector3 &box_scale, const LLQuaternion &box_rotation, -			LLVector3 &intersection, LLVector3 &intersection_normal); +            const LLVector3 &box_center, const LLVector3 &box_scale, const LLQuaternion &box_rotation, +            LLVector3 &intersection, LLVector3 &intersection_normal);  /* TODO  BOOL ray_ellipsoid(const LLVector3 &ray_point, const LLVector3 &ray_direction, -				   const LLVector3 &e_center, const LLVector3 &e_scale, const LLQuaternion &e_rotation, -				   LLVector3 &intersection, LLVector3 &intersection_normal); +                   const LLVector3 &e_center, const LLVector3 &e_scale, const LLQuaternion &e_rotation, +                   LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL ray_cone(const LLVector3 &ray_point, const LLVector3 &ray_direction, -			  const LLVector3 &cone_tip, const LLVector3 &cone_bottom,  -			  const LLVector3 &cone_scale, const LLQuaternion &cone_rotation, -			  LLVector3 &intersection, LLVector3 &intersection_normal); +              const LLVector3 &cone_tip, const LLVector3 &cone_bottom, +              const LLVector3 &cone_scale, const LLQuaternion &cone_rotation, +              LLVector3 &intersection, LLVector3 &intersection_normal);  */  BOOL ray_prism(const LLVector3 &ray_point, const LLVector3 &ray_direction, -			   const LLVector3 &prism_center, const LLVector3 &prism_scale, const LLQuaternion &prism_rotation, -			   LLVector3 &intersection, LLVector3 &intersection_normal); +               const LLVector3 &prism_center, const LLVector3 &prism_scale, const LLQuaternion &prism_rotation, +               LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL ray_tetrahedron(const LLVector3 &ray_point, const LLVector3 &ray_direction, -					 const LLVector3 &t_center, const LLVector3 &t_scale, const LLQuaternion &t_rotation, -					 LLVector3 &intersection, LLVector3 &intersection_normal); +                     const LLVector3 &t_center, const LLVector3 &t_scale, const LLQuaternion &t_rotation, +                     LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL ray_pyramid(const LLVector3 &ray_point, const LLVector3 &ray_direction, -				 const LLVector3 &p_center, const LLVector3 &p_scale, const LLQuaternion &p_rotation, -				 LLVector3 &intersection, LLVector3 &intersection_normal); +                 const LLVector3 &p_center, const LLVector3 &p_scale, const LLQuaternion &p_rotation, +                 LLVector3 &intersection, LLVector3 &intersection_normal);  /* TODO  BOOL ray_hemiellipsoid(const LLVector3 &ray_point, const LLVector3 &ray_direction, -					   const LLVector3 &e_center, const LLVector3 &e_scale, const LLQuaternion &e_rotation, -					   const LLVector3 &e_cut_normal, -					   LLVector3 &intersection, LLVector3 &intersection_normal); +                       const LLVector3 &e_center, const LLVector3 &e_scale, const LLQuaternion &e_rotation, +                       const LLVector3 &e_cut_normal, +                       LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL ray_hemisphere(const LLVector3 &ray_point, const LLVector3 &ray_direction, -					const LLVector3 &sphere_center, F32 sphere_radius, const LLVector3 &sphere_cut_normal,  -					LLVector3 &intersection, LLVector3 &intersection_normal); +                    const LLVector3 &sphere_center, F32 sphere_radius, const LLVector3 &sphere_cut_normal, +                    LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL ray_hemicylinder(const LLVector3 &ray_point, const LLVector3 &ray_direction, -					  const LLVector3 &cyl_top, const LLVector3 &cyl_bottom, F32 cyl_radius,  -					  const LLVector3 &cyl_cut_normal, -					  LLVector3 &intersection, LLVector3 &intersection_normal); +                      const LLVector3 &cyl_top, const LLVector3 &cyl_bottom, F32 cyl_radius, +                      const LLVector3 &cyl_cut_normal, +                      LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL ray_hemicone(const LLVector3 &ray_point, const LLVector3 &ray_direction, -				  const LLVector3 &cone_tip, const LLVector3 &cone_bottom,  -				  const LLVector3 &cone_scale, const LLVector3 &cyl_cut_normal, -				  LLVector3 &intersection, LLVector3 &intersection_normal); +                  const LLVector3 &cone_tip, const LLVector3 &cone_bottom, +                  const LLVector3 &cone_scale, const LLVector3 &cyl_cut_normal, +                  LLVector3 &intersection, LLVector3 &intersection_normal);  */ -BOOL linesegment_circle(const LLVector3 &point_a, const LLVector3 &point_b,  -						const LLVector3 &circle_center, const LLVector3 plane_normal, F32 circle_radius, -						LLVector3 &intersection); +BOOL linesegment_circle(const LLVector3 &point_a, const LLVector3 &point_b, +                        const LLVector3 &circle_center, const LLVector3 plane_normal, F32 circle_radius, +                        LLVector3 &intersection);  // point_0 through point_2 define the plane_normal via the right-hand rule:  // circle from point_0 to point_2 with fingers ==> thumb points in direction of normal -BOOL linesegment_triangle(const LLVector3 &point_a, const LLVector3 &point_b,  -						  const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2,  -						  LLVector3 &intersection, LLVector3 &intersection_normal); +BOOL linesegment_triangle(const LLVector3 &point_a, const LLVector3 &point_b, +                          const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, +                          LLVector3 &intersection, LLVector3 &intersection_normal);  // point_0 is the lower-left corner, point_1 is the lower-right, point_2 is the upper-right  // right-hand-rule... curl fingers from lower-left toward lower-right then toward upper-right  // ==> thumb points in direction of normal  // assumes a parallelogram, so point_3 is determined by the other points -BOOL linesegment_quadrangle(const LLVector3 &point_a, const LLVector3 &point_b,  -							const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2,  -							LLVector3 &intersection, LLVector3 &intersection_normal); +BOOL linesegment_quadrangle(const LLVector3 &point_a, const LLVector3 &point_b, +                            const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2, +                            LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL linesegment_sphere(const LLVector3 &point_a, const LLVector3 &point_b, -				const LLVector3 &sphere_center, F32 sphere_radius, -				LLVector3 &intersection, LLVector3 &intersection_normal); +                const LLVector3 &sphere_center, F32 sphere_radius, +                LLVector3 &intersection, LLVector3 &intersection_normal); -// finite right cylinder is defined by end centers: "cyl_top", "cyl_bottom",  +// finite right cylinder is defined by end centers: "cyl_top", "cyl_bottom",  // and by the cylinder radius "cyl_radius"  BOOL linesegment_cylinder(const LLVector3 &point_a, const LLVector3 &point_b, -						  const LLVector3 &cyl_center, const LLVector3 &cyl_scale, const LLQuaternion &cyl_rotation, -						  LLVector3 &intersection, LLVector3 &intersection_normal); +                          const LLVector3 &cyl_center, const LLVector3 &cyl_scale, const LLQuaternion &cyl_rotation, +                          LLVector3 &intersection, LLVector3 &intersection_normal);  // this function doesn't just return a BOOL because the return is currently -// used to decide how to break up boxes that have been hit by shots...  +// used to decide how to break up boxes that have been hit by shots...  // a hack that will probably be changed later  //  // returns a number representing the side of the box that was hit by the ray,  // or NO_SIDE if intersection test failed. -U32 linesegment_box(const LLVector3 &point_a, const LLVector3 &point_b,  -					const LLVector3 &box_center, const LLVector3 &box_scale, const LLQuaternion &box_rotation, -					LLVector3 &intersection, LLVector3 &intersection_normal); +U32 linesegment_box(const LLVector3 &point_a, const LLVector3 &point_b, +                    const LLVector3 &box_center, const LLVector3 &box_scale, const LLQuaternion &box_rotation, +                    LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL linesegment_prism(const LLVector3 &point_a, const LLVector3 &point_b, -					   const LLVector3 &prism_center, const LLVector3 &prism_scale, const LLQuaternion &prism_rotation, -					   LLVector3 &intersection, LLVector3 &intersection_normal); +                       const LLVector3 &prism_center, const LLVector3 &prism_scale, const LLQuaternion &prism_rotation, +                       LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL linesegment_tetrahedron(const LLVector3 &point_a, const LLVector3 &point_b, -							 const LLVector3 &t_center, const LLVector3 &t_scale, const LLQuaternion &t_rotation, -							 LLVector3 &intersection, LLVector3 &intersection_normal); +                             const LLVector3 &t_center, const LLVector3 &t_scale, const LLQuaternion &t_rotation, +                             LLVector3 &intersection, LLVector3 &intersection_normal);  BOOL linesegment_pyramid(const LLVector3 &point_a, const LLVector3 &point_b, -						 const LLVector3 &p_center, const LLVector3 &p_scale, const LLQuaternion &p_rotation, -						 LLVector3 &intersection, LLVector3 &intersection_normal); +                         const LLVector3 &p_center, const LLVector3 &p_scale, const LLQuaternion &p_rotation, +                         LLVector3 &intersection, LLVector3 &intersection_normal);  #endif diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp index 5ee3c45502..eb6fa4a3b8 100644 --- a/indra/llmath/tests/alignment_test.cpp +++ b/indra/llmath/tests/alignment_test.cpp @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2011&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2011, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -50,27 +50,27 @@ LL_ALIGN_PREFIX(16)  class MyVector4a  {  public: -	void* operator new(size_t size) -	{ -		return ll_aligned_malloc_16(size); -	} - -	void operator delete(void *p) -	{ -		ll_aligned_free_16(p); -	} - -	void* operator new[](size_t count) -	{	// try to allocate count bytes for an array -		return ll_aligned_malloc_16(count); -	} - -	void operator delete[](void *p) -	{ -		ll_aligned_free_16(p); -	} - -	LLQuad mQ; +    void* operator new(size_t size) +    { +        return ll_aligned_malloc_16(size); +    } + +    void operator delete(void *p) +    { +        ll_aligned_free_16(p); +    } + +    void* operator new[](size_t count) +    {   // try to allocate count bytes for an array +        return ll_aligned_malloc_16(count); +    } + +    void operator delete[](void *p) +    { +        ll_aligned_free_16(p); +    } + +    LLQuad mQ;  } LL_ALIGN_POSTFIX(16); @@ -79,36 +79,36 @@ template<> template<>  void alignment_test_object_t::test<1>()  {  #   ifdef LL_DEBUG -//	skip("This test fails on Windows when compiled in debug mode."); +//  skip("This test fails on Windows when compiled in debug mode.");  #   endif -	 -	const int num_tests = 7; -	void *align_ptr; -	for (int i=0; i<num_tests; i++) -	{ -		align_ptr = ll_aligned_malloc_16(sizeof(MyVector4a)); -		ensure("ll_aligned_malloc_16 failed", is_aligned(align_ptr,16)); - -		align_ptr = ll_aligned_realloc_16(align_ptr,2*sizeof(MyVector4a), sizeof(MyVector4a)); -		ensure("ll_aligned_realloc_16 failed", is_aligned(align_ptr,16)); - -		ll_aligned_free_16(align_ptr); - -		align_ptr = ll_aligned_malloc_32(sizeof(MyVector4a)); -		ensure("ll_aligned_malloc_32 failed", is_aligned(align_ptr,32)); -		ll_aligned_free_32(align_ptr); -	} + +    const int num_tests = 7; +    void *align_ptr; +    for (int i=0; i<num_tests; i++) +    { +        align_ptr = ll_aligned_malloc_16(sizeof(MyVector4a)); +        ensure("ll_aligned_malloc_16 failed", is_aligned(align_ptr,16)); + +        align_ptr = ll_aligned_realloc_16(align_ptr,2*sizeof(MyVector4a), sizeof(MyVector4a)); +        ensure("ll_aligned_realloc_16 failed", is_aligned(align_ptr,16)); + +        ll_aligned_free_16(align_ptr); + +        align_ptr = ll_aligned_malloc_32(sizeof(MyVector4a)); +        ensure("ll_aligned_malloc_32 failed", is_aligned(align_ptr,32)); +        ll_aligned_free_32(align_ptr); +    }  }  // In-place allocation of objects and arrays.  template<> template<>  void alignment_test_object_t::test<2>()  { -	MyVector4a vec1; -	ensure("LLAlignment vec1 unaligned", is_aligned(&vec1,16)); -	 -	MyVector4a veca[12]; -	ensure("LLAlignment veca unaligned", is_aligned(veca,16)); +    MyVector4a vec1; +    ensure("LLAlignment vec1 unaligned", is_aligned(&vec1,16)); + +    MyVector4a veca[12]; +    ensure("LLAlignment veca unaligned", is_aligned(veca,16));  }  // Heap allocation of objects and arrays. @@ -116,26 +116,26 @@ template<> template<>  void alignment_test_object_t::test<3>()  {  #   ifdef LL_DEBUG -//	skip("This test fails on Windows when compiled in debug mode."); +//  skip("This test fails on Windows when compiled in debug mode.");  #   endif -	 -	const int ARR_SIZE = 7; -	for(int i=0; i<ARR_SIZE; i++) -	{ -		MyVector4a *vecp = new MyVector4a; -		ensure("LLAlignment vecp unaligned", is_aligned(vecp,16)); -		delete vecp; -	} - -	MyVector4a *veca = new MyVector4a[ARR_SIZE]; -	//std::cout << "veca base is " << (S32) veca << std::endl; -	ensure("LLAligment veca base", is_aligned(veca,16)); -	for(int i=0; i<ARR_SIZE; i++) -	{ -		std::cout << "veca[" << i << "]" << std::endl; -		ensure("LLAlignment veca member unaligned", is_aligned(&veca[i],16)); -	} -	delete [] veca;  + +    const int ARR_SIZE = 7; +    for(int i=0; i<ARR_SIZE; i++) +    { +        MyVector4a *vecp = new MyVector4a; +        ensure("LLAlignment vecp unaligned", is_aligned(vecp,16)); +        delete vecp; +    } + +    MyVector4a *veca = new MyVector4a[ARR_SIZE]; +    //std::cout << "veca base is " << (S32) veca << std::endl; +    ensure("LLAligment veca base", is_aligned(veca,16)); +    for(int i=0; i<ARR_SIZE; i++) +    { +        std::cout << "veca[" << i << "]" << std::endl; +        ensure("LLAlignment veca member unaligned", is_aligned(&veca[i],16)); +    } +    delete [] veca;  }  } diff --git a/indra/llmath/tests/llbbox_test.cpp b/indra/llmath/tests/llbbox_test.cpp index fd0dbb58fc..1f2cd96ab2 100644 --- a/indra/llmath/tests/llbbox_test.cpp +++ b/indra/llmath/tests/llbbox_test.cpp @@ -3,25 +3,25 @@   * @author Martin Reddy   * @date   2009-06-25   * @brief  Test for llbbox.cpp. - *  + *   * $LicenseInfo:firstyear=2009&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -38,330 +38,330 @@  namespace tut  { -	struct LLBBoxData -	{ -	}; +    struct LLBBoxData +    { +    }; -	typedef test_group<LLBBoxData> factory; -	typedef factory::object object; +    typedef test_group<LLBBoxData> factory; +    typedef factory::object object;  }  namespace  { -	tut::factory llbbox_test_factory("LLBBox"); +    tut::factory llbbox_test_factory("LLBBox");  }  namespace tut  { -	template<> template<> -	void object::test<1>() -	{	 -		// -		// test the default constructor -		// -		 -		LLBBox bbox1; -		 -		ensure_equals("Default bbox min", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); -		ensure_equals("Default bbox max", bbox1.getMaxLocal(), LLVector3(0.0f, 0.0f, 0.0f)); -		ensure_equals("Default bbox pos agent", bbox1.getPositionAgent(), LLVector3(0.0f, 0.0f, 0.0f)); -		ensure_equals("Default bbox rotation", bbox1.getRotation(), LLQuaternion(0.0f, 0.0f, 0.0f, 1.0f)); -	} -	 -	template<> template<> -	void object::test<2>() -	{	 -		// -		// test the non-default constructor -		// -		 -		LLBBox bbox2(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), -					 LLVector3(2.0f, 3.0f, 4.0f), LLVector3(4.0f, 5.0f, 6.0f)); -		 -		ensure_equals("Custom bbox min", bbox2.getMinLocal(), LLVector3(2.0f, 3.0f, 4.0f)); -		ensure_equals("Custom bbox max", bbox2.getMaxLocal(), LLVector3(4.0f, 5.0f, 6.0f)); -		ensure_equals("Custom bbox pos agent", bbox2.getPositionAgent(), LLVector3(1.0f, 2.0f, 3.0f)); -		ensure_equals("Custom bbox rotation", bbox2.getRotation(), LLQuaternion(0.0f, 0.0f, 0.0f, 1.0f));		 -	} -		 -	template<> template<> -	void object::test<3>() -	{	 -		// -		// test the setMinLocal() method -		// -		LLBBox bbox2; -		bbox2.setMinLocal(LLVector3(3.0f, 3.0f, 3.0f)); -		ensure_equals("Custom bbox min (2)", bbox2.getMinLocal(), LLVector3(3.0f, 3.0f, 3.0f)); -	} - -	template<> template<> -	void object::test<4>() -	{	 -		// -		// test the setMaxLocal() method -		// -		LLBBox bbox2; -		bbox2.setMaxLocal(LLVector3(5.0f, 5.0f, 5.0f)); -		ensure_equals("Custom bbox max (2)", bbox2.getMaxLocal(), LLVector3(5.0f, 5.0f, 5.0f)); -	} - -	template<> template<> -	void object::test<5>() -	{	 -		// -		// test the getCenterLocal() method -		// -		 -		ensure_equals("Default bbox local center", LLBBox().getCenterLocal(), LLVector3(0.0f, 0.0f, 0.0f)); -		 -		LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), -					 LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); - -		ensure_equals("Custom bbox center local", bbox1.getCenterLocal(), LLVector3(3.0f, 5.0f, 7.0f)); - -		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), -					 LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); - -		ensure_equals("Custom bbox center local with rot", bbox2.getCenterLocal(), LLVector3(3.0f, 3.0f, 3.0f)); -	} - -	template<> template<> -	void object::test<6>() -	{	 -		// -		// test the getCenterAgent() -		// -		 -		ensure_equals("Default bbox agent center", LLBBox().getCenterAgent(), LLVector3(0.0f, 0.0f, 0.0f)); -		 -		LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), -					 LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); -		 -		ensure_equals("Custom bbox center agent", bbox1.getCenterAgent(), LLVector3(4.0f, 7.0f, 10.0f)); -		 -		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), -					 LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); -		 -		ensure("Custom bbox center agent with rot", APPROX_EQUAL(bbox2.getCenterAgent(), LLVector3(-2.0f, 4.0f, 4.0f))); -	} -	 -	template<> template<> -	void object::test<7>() -	{	 -		// -		// test the getExtentLocal() method -		// -		 -		ensure_equals("Default bbox local extent", LLBBox().getExtentLocal(), LLVector3(0.0f, 0.0f, 0.0f)); -		 -		LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), -					 LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); -		 -		ensure_equals("Custom bbox extent local", bbox1.getExtentLocal(), LLVector3(2.0f, 2.0f, 2.0f)); -		 -		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), -					 LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); -		 -		ensure_equals("Custom bbox extent local with rot", bbox1.getExtentLocal(), LLVector3(2.0f, 2.0f, 2.0f));		 -	} -	 -	template<> template<> -	void object::test<8>() -	{ -		// -		// test the addPointLocal() method -		// -		 -		LLBBox bbox1; -		bbox1.addPointLocal(LLVector3(1.0f, 1.0f, 1.0f)); -		bbox1.addPointLocal(LLVector3(3.0f, 3.0f, 3.0f)); -		 -		ensure_equals("addPointLocal center local (1)", bbox1.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); -		ensure_equals("addPointLocal center agent (1)", bbox1.getCenterAgent(), LLVector3(2.0f, 2.0f, 2.0f)); -		ensure_equals("addPointLocal min (1)", bbox1.getMinLocal(), LLVector3(1.0f, 1.0f, 1.0f)); -		ensure_equals("addPointLocal max (1)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); -		 -		bbox1.addPointLocal(LLVector3(0.0f, 0.0f, 0.0f)); -		bbox1.addPointLocal(LLVector3(1.0f, 1.0f, 1.0f)); -		bbox1.addPointLocal(LLVector3(2.0f, 2.0f, 2.0f)); -		 -		ensure_equals("addPointLocal center local (2)", bbox1.getCenterLocal(), LLVector3(1.5f, 1.5f, 1.5f)); -		ensure_equals("addPointLocal min (2)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); -		ensure_equals("addPointLocal max (2)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f));		 -	} - -	template<> template<> -	void object::test<9>() -	{ -		// -		// test the addBBoxLocal() method -		// -		 -		LLBBox bbox1; -		bbox1.addBBoxLocal(LLBBox(LLVector3(), LLQuaternion(), -								  LLVector3(0.0f, 0.0f, 0.0f), LLVector3(3.0f, 3.0f, 3.0f))); -		 -		ensure_equals("addPointLocal center local (3)", bbox1.getCenterLocal(), LLVector3(1.5f, 1.5f, 1.5f)); -		ensure_equals("addPointLocal min (3)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); -		ensure_equals("addPointLocal max (3)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); -		 -		bbox1.addBBoxLocal(LLBBox(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), -								  LLVector3(5.0f, 5.0f, 5.0f), LLVector3(10.0f, 10.0f, 10.0f))); -		 -		ensure_equals("addPointLocal center local (4)", bbox1.getCenterLocal(), LLVector3(5.0f, 5.0f, 5.0f)); -		ensure_equals("addPointLocal center agent (4)", bbox1.getCenterAgent(), LLVector3(5.0f, 5.0f, 5.0f)); -		ensure_equals("addPointLocal min (4)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); -		ensure_equals("addPointLocal max (4)", bbox1.getMaxLocal(), LLVector3(10.0f, 10.0f, 10.0f));		 -	} -	 -	template<> template<> -	void object::test<10>() -	{ -		// -		// test the addPointAgent() method -		// -		 -		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(1.0, 0.0, 0.0, 1.0), -					 LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); - -		bbox1.addPointAgent(LLVector3(1.0f, 1.0f, 1.0f)); -		bbox1.addPointAgent(LLVector3(3.0f, 3.0f, 3.0f)); -		 -		ensure_equals("addPointAgent center local (1)", bbox1.getCenterLocal(), LLVector3(2.0f, 2.0f, -2.0f)); -		ensure_equals("addPointAgent center agent (1)", bbox1.getCenterAgent(), LLVector3(3.0f, 3.0f, 7.0f)); -		ensure_equals("addPointAgent min (1)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, -4.0f)); -		ensure_equals("addPointAgent max (1)", bbox1.getMaxLocal(), LLVector3(4.0f, 4.0f, 0.0f)); -	} - -	template<> template<> -	void object::test<11>() -	{ -		// -		// test the addBBoxAgent() method -		// -		 -		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(1.0, 0.0, 0.0, 1.0), -					 LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); -		 -		bbox1.addPointAgent(LLVector3(1.0f, 1.0f, 1.0f)); -		bbox1.addPointAgent(LLVector3(3.0f, 3.0f, 3.0f)); -		 -		bbox1.addBBoxLocal(LLBBox(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), -								  LLVector3(5.0f, 5.0f, 5.0f), LLVector3(10.0f, 10.0f, 10.0f))); -		 -		ensure_equals("addPointAgent center local (2)", bbox1.getCenterLocal(), LLVector3(5.0f, 5.0f, 3.0f)); -		ensure_equals("addPointAgent center agent (2)", bbox1.getCenterAgent(), LLVector3(6.0f, -10.0f, 8.0f)); -		ensure_equals("addPointAgent min (2)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, -4.0f)); -		ensure_equals("addPointAgent max (2)", bbox1.getMaxLocal(), LLVector3(10.0f, 10.0f, 10.0f));		 -	} -	 -	template<> template<> -	void object::test<12>() -	{ -		// -		// test the expand() method -		// -		 -		LLBBox bbox1; -		bbox1.expand(0.0); - -		ensure_equals("Zero-expanded Default BBox center", bbox1.getCenterLocal(), LLVector3(0.0f, 0.0f, 0.0f)); - -		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), -					 LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); -		bbox2.expand(0.0); -		 -		ensure_equals("Zero-expanded center local", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); -		ensure_equals("Zero-expanded center agent", bbox2.getCenterAgent(), LLVector3(3.0f, 3.0f, 3.0f)); -		ensure_equals("Zero-expanded min", bbox2.getMinLocal(), LLVector3(1.0f, 1.0f, 1.0f)); -		ensure_equals("Zero-expanded max", bbox2.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); - -		bbox2.expand(0.5); - -		ensure_equals("Positive-expanded center", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); -		ensure_equals("Positive-expanded min", bbox2.getMinLocal(), LLVector3(0.5f, 0.5f, 0.5f)); -		ensure_equals("Positive-expanded max", bbox2.getMaxLocal(), LLVector3(3.5f, 3.5f, 3.5f)); - -		bbox2.expand(-1.0); -		 -		ensure_equals("Negative-expanded center", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); -		ensure_equals("Negative-expanded min", bbox2.getMinLocal(), LLVector3(1.5f, 1.5f, 1.5f)); -		ensure_equals("Negative-expanded max", bbox2.getMaxLocal(), LLVector3(2.5f, 2.5f, 2.5f));		 -	} -	 -	template<> template<> -	void object::test<13>() -	{ -		// -		// test the localToAgent() method -		// -		 -		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), -					 LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); -		 -		ensure_equals("localToAgent(1,2,3)", bbox1.localToAgent(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(2.0f, 3.0f, 4.0f)); -		 -		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(1.0f, 0.0f, 0.0f)), -					 LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); -		 -		ensure("localToAgent(1,2,3) rot", APPROX_EQUAL(bbox2.localToAgent(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(2.0f, -2.0f, 3.0f))); -	} -	 -	template<> template<> -	void object::test<14>() -	{ -		// -		// test the agentToLocal() method -		// -		 -		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), -					 LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); -		 -		ensure_equals("agentToLocal(1,2,3)", bbox1.agentToLocal(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(0.0f, 1.0f, 2.0f)); -		ensure_equals("agentToLocal(localToAgent)", bbox1.agentToLocal(bbox1.localToAgent(LLVector3(1.0f, 2.0f, 3.0f))), -					  LLVector3(1.0f, 2.0f, 3.0f)); -		 -		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(1.0f, 0.0f, 0.0f)), -					 LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); -		 -		ensure("agentToLocal(1,2,3) rot", APPROX_EQUAL(bbox2.agentToLocal(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(0.0f, 2.0f, -1.0f))); -		ensure("agentToLocal(localToAgent) rot", APPROX_EQUAL(bbox2.agentToLocal(bbox2.localToAgent(LLVector3(1.0f, 2.0f, 3.0f))), -															  LLVector3(1.0f, 2.0f, 3.0f))); -	} -	 -	template<> template<> -	void object::test<15>() -	{ -		// -		// test the containsPointLocal() method -		// -		 -		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), -					 LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); - -		ensure("containsPointLocal(0,0,0)", bbox1.containsPointLocal(LLVector3(0.0f, 0.0f, 0.0f)) == FALSE); -		ensure("containsPointLocal(1,2,3)", bbox1.containsPointLocal(LLVector3(1.0f, 2.0f, 3.0f)) == TRUE); -		ensure("containsPointLocal(0.999,2,3)", bbox1.containsPointLocal(LLVector3(0.999f, 2.0f, 3.0f)) == FALSE); -		ensure("containsPointLocal(3,4,5)", bbox1.containsPointLocal(LLVector3(3.0f, 4.0f, 5.0f)) == TRUE); -		ensure("containsPointLocal(3,4,5.001)", bbox1.containsPointLocal(LLVector3(3.0f, 4.0f, 5.001f)) == FALSE); -	} - -	template<> template<> -	void object::test<16>() -	{ -		// -		// test the containsPointAgent() method -		// -		 -		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), -					 LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); -		 -		ensure("containsPointAgent(0,0,0)", bbox1.containsPointAgent(LLVector3(0.0f, 0.0f, 0.0f)) == FALSE); -		ensure("containsPointAgent(2,3,4)", bbox1.containsPointAgent(LLVector3(2.0f, 3.0f, 4.0f)) == TRUE); -		ensure("containsPointAgent(2,2.999,4)", bbox1.containsPointAgent(LLVector3(2.0f, 2.999f, 4.0f)) == FALSE); -		ensure("containsPointAgent(4,5,6)", bbox1.containsPointAgent(LLVector3(4.0f, 5.0f, 6.0f)) == TRUE); -		ensure("containsPointAgent(4,5.001,6)", bbox1.containsPointAgent(LLVector3(4.0f, 5.001f, 6.0f)) == FALSE); -	}				 +    template<> template<> +    void object::test<1>() +    { +        // +        // test the default constructor +        // + +        LLBBox bbox1; + +        ensure_equals("Default bbox min", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +        ensure_equals("Default bbox max", bbox1.getMaxLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +        ensure_equals("Default bbox pos agent", bbox1.getPositionAgent(), LLVector3(0.0f, 0.0f, 0.0f)); +        ensure_equals("Default bbox rotation", bbox1.getRotation(), LLQuaternion(0.0f, 0.0f, 0.0f, 1.0f)); +    } + +    template<> template<> +    void object::test<2>() +    { +        // +        // test the non-default constructor +        // + +        LLBBox bbox2(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), +                     LLVector3(2.0f, 3.0f, 4.0f), LLVector3(4.0f, 5.0f, 6.0f)); + +        ensure_equals("Custom bbox min", bbox2.getMinLocal(), LLVector3(2.0f, 3.0f, 4.0f)); +        ensure_equals("Custom bbox max", bbox2.getMaxLocal(), LLVector3(4.0f, 5.0f, 6.0f)); +        ensure_equals("Custom bbox pos agent", bbox2.getPositionAgent(), LLVector3(1.0f, 2.0f, 3.0f)); +        ensure_equals("Custom bbox rotation", bbox2.getRotation(), LLQuaternion(0.0f, 0.0f, 0.0f, 1.0f)); +    } + +    template<> template<> +    void object::test<3>() +    { +        // +        // test the setMinLocal() method +        // +        LLBBox bbox2; +        bbox2.setMinLocal(LLVector3(3.0f, 3.0f, 3.0f)); +        ensure_equals("Custom bbox min (2)", bbox2.getMinLocal(), LLVector3(3.0f, 3.0f, 3.0f)); +    } + +    template<> template<> +    void object::test<4>() +    { +        // +        // test the setMaxLocal() method +        // +        LLBBox bbox2; +        bbox2.setMaxLocal(LLVector3(5.0f, 5.0f, 5.0f)); +        ensure_equals("Custom bbox max (2)", bbox2.getMaxLocal(), LLVector3(5.0f, 5.0f, 5.0f)); +    } + +    template<> template<> +    void object::test<5>() +    { +        // +        // test the getCenterLocal() method +        // + +        ensure_equals("Default bbox local center", LLBBox().getCenterLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + +        LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), +                     LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); + +        ensure_equals("Custom bbox center local", bbox1.getCenterLocal(), LLVector3(3.0f, 5.0f, 7.0f)); + +        LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), +                     LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + +        ensure_equals("Custom bbox center local with rot", bbox2.getCenterLocal(), LLVector3(3.0f, 3.0f, 3.0f)); +    } + +    template<> template<> +    void object::test<6>() +    { +        // +        // test the getCenterAgent() +        // + +        ensure_equals("Default bbox agent center", LLBBox().getCenterAgent(), LLVector3(0.0f, 0.0f, 0.0f)); + +        LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), +                     LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); + +        ensure_equals("Custom bbox center agent", bbox1.getCenterAgent(), LLVector3(4.0f, 7.0f, 10.0f)); + +        LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), +                     LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + +        ensure("Custom bbox center agent with rot", APPROX_EQUAL(bbox2.getCenterAgent(), LLVector3(-2.0f, 4.0f, 4.0f))); +    } + +    template<> template<> +    void object::test<7>() +    { +        // +        // test the getExtentLocal() method +        // + +        ensure_equals("Default bbox local extent", LLBBox().getExtentLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + +        LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), +                     LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); + +        ensure_equals("Custom bbox extent local", bbox1.getExtentLocal(), LLVector3(2.0f, 2.0f, 2.0f)); + +        LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), +                     LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + +        ensure_equals("Custom bbox extent local with rot", bbox1.getExtentLocal(), LLVector3(2.0f, 2.0f, 2.0f)); +    } + +    template<> template<> +    void object::test<8>() +    { +        // +        // test the addPointLocal() method +        // + +        LLBBox bbox1; +        bbox1.addPointLocal(LLVector3(1.0f, 1.0f, 1.0f)); +        bbox1.addPointLocal(LLVector3(3.0f, 3.0f, 3.0f)); + +        ensure_equals("addPointLocal center local (1)", bbox1.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); +        ensure_equals("addPointLocal center agent (1)", bbox1.getCenterAgent(), LLVector3(2.0f, 2.0f, 2.0f)); +        ensure_equals("addPointLocal min (1)", bbox1.getMinLocal(), LLVector3(1.0f, 1.0f, 1.0f)); +        ensure_equals("addPointLocal max (1)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); + +        bbox1.addPointLocal(LLVector3(0.0f, 0.0f, 0.0f)); +        bbox1.addPointLocal(LLVector3(1.0f, 1.0f, 1.0f)); +        bbox1.addPointLocal(LLVector3(2.0f, 2.0f, 2.0f)); + +        ensure_equals("addPointLocal center local (2)", bbox1.getCenterLocal(), LLVector3(1.5f, 1.5f, 1.5f)); +        ensure_equals("addPointLocal min (2)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +        ensure_equals("addPointLocal max (2)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); +    } + +    template<> template<> +    void object::test<9>() +    { +        // +        // test the addBBoxLocal() method +        // + +        LLBBox bbox1; +        bbox1.addBBoxLocal(LLBBox(LLVector3(), LLQuaternion(), +                                  LLVector3(0.0f, 0.0f, 0.0f), LLVector3(3.0f, 3.0f, 3.0f))); + +        ensure_equals("addPointLocal center local (3)", bbox1.getCenterLocal(), LLVector3(1.5f, 1.5f, 1.5f)); +        ensure_equals("addPointLocal min (3)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +        ensure_equals("addPointLocal max (3)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); + +        bbox1.addBBoxLocal(LLBBox(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +                                  LLVector3(5.0f, 5.0f, 5.0f), LLVector3(10.0f, 10.0f, 10.0f))); + +        ensure_equals("addPointLocal center local (4)", bbox1.getCenterLocal(), LLVector3(5.0f, 5.0f, 5.0f)); +        ensure_equals("addPointLocal center agent (4)", bbox1.getCenterAgent(), LLVector3(5.0f, 5.0f, 5.0f)); +        ensure_equals("addPointLocal min (4)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +        ensure_equals("addPointLocal max (4)", bbox1.getMaxLocal(), LLVector3(10.0f, 10.0f, 10.0f)); +    } + +    template<> template<> +    void object::test<10>() +    { +        // +        // test the addPointAgent() method +        // + +        LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(1.0, 0.0, 0.0, 1.0), +                     LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + +        bbox1.addPointAgent(LLVector3(1.0f, 1.0f, 1.0f)); +        bbox1.addPointAgent(LLVector3(3.0f, 3.0f, 3.0f)); + +        ensure_equals("addPointAgent center local (1)", bbox1.getCenterLocal(), LLVector3(2.0f, 2.0f, -2.0f)); +        ensure_equals("addPointAgent center agent (1)", bbox1.getCenterAgent(), LLVector3(3.0f, 3.0f, 7.0f)); +        ensure_equals("addPointAgent min (1)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, -4.0f)); +        ensure_equals("addPointAgent max (1)", bbox1.getMaxLocal(), LLVector3(4.0f, 4.0f, 0.0f)); +    } + +    template<> template<> +    void object::test<11>() +    { +        // +        // test the addBBoxAgent() method +        // + +        LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(1.0, 0.0, 0.0, 1.0), +                     LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + +        bbox1.addPointAgent(LLVector3(1.0f, 1.0f, 1.0f)); +        bbox1.addPointAgent(LLVector3(3.0f, 3.0f, 3.0f)); + +        bbox1.addBBoxLocal(LLBBox(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +                                  LLVector3(5.0f, 5.0f, 5.0f), LLVector3(10.0f, 10.0f, 10.0f))); + +        ensure_equals("addPointAgent center local (2)", bbox1.getCenterLocal(), LLVector3(5.0f, 5.0f, 3.0f)); +        ensure_equals("addPointAgent center agent (2)", bbox1.getCenterAgent(), LLVector3(6.0f, -10.0f, 8.0f)); +        ensure_equals("addPointAgent min (2)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, -4.0f)); +        ensure_equals("addPointAgent max (2)", bbox1.getMaxLocal(), LLVector3(10.0f, 10.0f, 10.0f)); +    } + +    template<> template<> +    void object::test<12>() +    { +        // +        // test the expand() method +        // + +        LLBBox bbox1; +        bbox1.expand(0.0); + +        ensure_equals("Zero-expanded Default BBox center", bbox1.getCenterLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + +        LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +                     LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); +        bbox2.expand(0.0); + +        ensure_equals("Zero-expanded center local", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); +        ensure_equals("Zero-expanded center agent", bbox2.getCenterAgent(), LLVector3(3.0f, 3.0f, 3.0f)); +        ensure_equals("Zero-expanded min", bbox2.getMinLocal(), LLVector3(1.0f, 1.0f, 1.0f)); +        ensure_equals("Zero-expanded max", bbox2.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); + +        bbox2.expand(0.5); + +        ensure_equals("Positive-expanded center", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); +        ensure_equals("Positive-expanded min", bbox2.getMinLocal(), LLVector3(0.5f, 0.5f, 0.5f)); +        ensure_equals("Positive-expanded max", bbox2.getMaxLocal(), LLVector3(3.5f, 3.5f, 3.5f)); + +        bbox2.expand(-1.0); + +        ensure_equals("Negative-expanded center", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); +        ensure_equals("Negative-expanded min", bbox2.getMinLocal(), LLVector3(1.5f, 1.5f, 1.5f)); +        ensure_equals("Negative-expanded max", bbox2.getMaxLocal(), LLVector3(2.5f, 2.5f, 2.5f)); +    } + +    template<> template<> +    void object::test<13>() +    { +        // +        // test the localToAgent() method +        // + +        LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +                     LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); + +        ensure_equals("localToAgent(1,2,3)", bbox1.localToAgent(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(2.0f, 3.0f, 4.0f)); + +        LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(1.0f, 0.0f, 0.0f)), +                     LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); + +        ensure("localToAgent(1,2,3) rot", APPROX_EQUAL(bbox2.localToAgent(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(2.0f, -2.0f, 3.0f))); +    } + +    template<> template<> +    void object::test<14>() +    { +        // +        // test the agentToLocal() method +        // + +        LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +                     LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); + +        ensure_equals("agentToLocal(1,2,3)", bbox1.agentToLocal(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(0.0f, 1.0f, 2.0f)); +        ensure_equals("agentToLocal(localToAgent)", bbox1.agentToLocal(bbox1.localToAgent(LLVector3(1.0f, 2.0f, 3.0f))), +                      LLVector3(1.0f, 2.0f, 3.0f)); + +        LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(1.0f, 0.0f, 0.0f)), +                     LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); + +        ensure("agentToLocal(1,2,3) rot", APPROX_EQUAL(bbox2.agentToLocal(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(0.0f, 2.0f, -1.0f))); +        ensure("agentToLocal(localToAgent) rot", APPROX_EQUAL(bbox2.agentToLocal(bbox2.localToAgent(LLVector3(1.0f, 2.0f, 3.0f))), +                                                              LLVector3(1.0f, 2.0f, 3.0f))); +    } + +    template<> template<> +    void object::test<15>() +    { +        // +        // test the containsPointLocal() method +        // + +        LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +                     LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); + +        ensure("containsPointLocal(0,0,0)", bbox1.containsPointLocal(LLVector3(0.0f, 0.0f, 0.0f)) == FALSE); +        ensure("containsPointLocal(1,2,3)", bbox1.containsPointLocal(LLVector3(1.0f, 2.0f, 3.0f)) == TRUE); +        ensure("containsPointLocal(0.999,2,3)", bbox1.containsPointLocal(LLVector3(0.999f, 2.0f, 3.0f)) == FALSE); +        ensure("containsPointLocal(3,4,5)", bbox1.containsPointLocal(LLVector3(3.0f, 4.0f, 5.0f)) == TRUE); +        ensure("containsPointLocal(3,4,5.001)", bbox1.containsPointLocal(LLVector3(3.0f, 4.0f, 5.001f)) == FALSE); +    } + +    template<> template<> +    void object::test<16>() +    { +        // +        // test the containsPointAgent() method +        // + +        LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +                     LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); + +        ensure("containsPointAgent(0,0,0)", bbox1.containsPointAgent(LLVector3(0.0f, 0.0f, 0.0f)) == FALSE); +        ensure("containsPointAgent(2,3,4)", bbox1.containsPointAgent(LLVector3(2.0f, 3.0f, 4.0f)) == TRUE); +        ensure("containsPointAgent(2,2.999,4)", bbox1.containsPointAgent(LLVector3(2.0f, 2.999f, 4.0f)) == FALSE); +        ensure("containsPointAgent(4,5,6)", bbox1.containsPointAgent(LLVector3(4.0f, 5.0f, 6.0f)) == TRUE); +        ensure("containsPointAgent(4,5.001,6)", bbox1.containsPointAgent(LLVector3(4.0f, 5.001f, 6.0f)) == FALSE); +    }  } diff --git a/indra/llmath/tests/llbboxlocal_test.cpp b/indra/llmath/tests/llbboxlocal_test.cpp index f31e4126c4..120e18cadf 100644 --- a/indra/llmath/tests/llbboxlocal_test.cpp +++ b/indra/llmath/tests/llbboxlocal_test.cpp @@ -3,25 +3,25 @@   * @author Martin Reddy   * @date   2009-06-25   * @brief  Test for llbboxlocal.cpp. - *  + *   * $LicenseInfo:firstyear=2009&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -32,201 +32,201 @@  namespace tut  { -	struct LLBBoxLocalData -	{ -	}; +    struct LLBBoxLocalData +    { +    }; -	typedef test_group<LLBBoxLocalData> factory; -	typedef factory::object object; +    typedef test_group<LLBBoxLocalData> factory; +    typedef factory::object object;  }  namespace  { -	tut::factory llbboxlocal_test_factory("LLBBoxLocal"); +    tut::factory llbboxlocal_test_factory("LLBBoxLocal");  }  namespace tut  { -	template<> template<> -	void object::test<1>() -	{	 -		// -		// test the default constructor -		// -		 -		LLBBoxLocal bbox1; -		 -		ensure_equals("Default bbox min", bbox1.getMin(), LLVector3(0.0f, 0.0f, 0.0f)); -		ensure_equals("Default bbox max", bbox1.getMax(), LLVector3(0.0f, 0.0f, 0.0f)); -	} - -	template<> template<> -	void object::test<2>() -	{	 -		// -		// test the non-default constructor -		// -		 -		LLBBoxLocal bbox2(LLVector3(-1.0f, -2.0f, 0.0f), LLVector3(1.0f, 2.0f, 3.0f)); -		 -		ensure_equals("Custom bbox min", bbox2.getMin(), LLVector3(-1.0f, -2.0f, 0.0f)); -		ensure_equals("Custom bbox max", bbox2.getMax(), LLVector3(1.0f, 2.0f, 3.0f));		 -	} -	 -	template<> template<> -	void object::test<3>() -	{	 -		// -		// test the setMin() -		// -		// N.B. no validation is currently performed to ensure that the min -		// and max vectors are actually the min/max values. -		// -		 -		LLBBoxLocal bbox2; -		bbox2.setMin(LLVector3(1.0f, 2.0f, 3.0f)); -		 -		ensure_equals("Custom bbox min (2)", bbox2.getMin(), LLVector3(1.0f, 2.0f, 3.0f)); -	} -	 -	template<> template<> -	void object::test<4>() -	{	 -		// -		// test the setMax() -		// -		// N.B. no validation is currently performed to ensure that the min -		// and max vectors are actually the min/max values. -		// -		 -		LLBBoxLocal bbox2; -		bbox2.setMax(LLVector3(10.0f, 20.0f, 30.0f)); -		 -		ensure_equals("Custom bbox max (2)", bbox2.getMax(), LLVector3(10.0f, 20.0f, 30.0f)); -	} -	 -	template<> template<> -	void object::test<5>() -	{	 -		// -		// test the getCenter() method -		// -		 -		ensure_equals("Default bbox center", LLBBoxLocal().getCenter(), LLVector3(0.0f, 0.0f, 0.0f)); -		 -		LLBBoxLocal bbox1(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(0.0f, 0.0f, 0.0f)); -		 -		ensure_equals("Custom bbox center", bbox1.getCenter(), LLVector3(-0.5f, -0.5f, -0.5f)); -		 -		LLBBoxLocal bbox2(LLVector3(0.0f, 0.0f, 0.0f), LLVector3(-1.0f, -1.0f, -1.0f)); -		 -		ensure_equals("Invalid bbox center", bbox2.getCenter(), LLVector3(-0.5f, -0.5f, -0.5f)); -	} - -	template<> template<> -	void object::test<6>() -	{	 -		// -		// test the getExtent() method -		// -		 -		LLBBoxLocal bbox2(LLVector3(0.0f, 0.0f, 0.0f), LLVector3(-1.0f, -1.0f, -1.0f)); -		 -		ensure_equals("Default bbox extent", LLBBoxLocal().getExtent(), LLVector3(0.0f, 0.0f, 0.0f)); -		 -		LLBBoxLocal bbox3(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(1.0f, 2.0f, 0.0f)); -		 -		ensure_equals("Custom bbox extent", bbox3.getExtent(), LLVector3(2.0f, 3.0f, 1.0f)); -	} -	 -	template<> template<> -	void object::test<7>() -	{ -		// -		// test the addPoint() method -		// -		// N.B. if you create an empty bbox and then add points, -		// the vector (0, 0, 0) will always be part of the bbox. -		// (Fixing this would require adding a bool to the class size). -		// -		 -		LLBBoxLocal bbox1; -		bbox1.addPoint(LLVector3(-1.0f, -2.0f, -3.0f)); -		bbox1.addPoint(LLVector3(3.0f, 4.0f, 5.0f)); -		 -		ensure_equals("Custom BBox center (1)", bbox1.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); -		ensure_equals("Custom BBox min (1)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); -		ensure_equals("Custom BBox max (1)", bbox1.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); -		 -		bbox1.addPoint(LLVector3(0.0f, 0.0f, 0.0f)); -		bbox1.addPoint(LLVector3(1.0f, 2.0f, 3.0f)); -		bbox1.addPoint(LLVector3(2.0f, 2.0f, 2.0f)); -		 -		ensure_equals("Custom BBox center (2)", bbox1.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); -		ensure_equals("Custom BBox min (2)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); -		ensure_equals("Custom BBox max (2)", bbox1.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); -		 -		bbox1.addPoint(LLVector3(5.0f, 5.0f, 5.0f)); -		 -		ensure_equals("Custom BBox center (3)", bbox1.getCenter(), LLVector3(2.0f, 1.5f, 1.0f)); -		ensure_equals("Custom BBox min (3)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); -		ensure_equals("Custom BBox max (3)", bbox1.getMax(), LLVector3(5.0f, 5.0f, 5.0f)); -	} -		 -	template<> template<> -	void object::test<8>() -	{ -		// -		// test the addBBox() methods -		// -		// N.B. if you create an empty bbox and then add points, -		// the vector (0, 0, 0) will always be part of the bbox. -		// (Fixing this would require adding a bool to the class size). -		// -		 -		LLBBoxLocal bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLVector3(2.0f, 2.0f, 2.0f)); -		bbox2.addBBox(LLBBoxLocal(LLVector3(1.5f, 1.5f, 1.5f), LLVector3(3.0f, 3.0f, 3.0f))); -		 -		ensure_equals("Custom BBox center (4)", bbox2.getCenter(), LLVector3(2.0f, 2.0f, 2.0f)); -		ensure_equals("Custom BBox min (4)", bbox2.getMin(), LLVector3(1.0f, 1.0f, 1.0f)); -		ensure_equals("Custom BBox max (4)", bbox2.getMax(), LLVector3(3.0f, 3.0f, 3.0f)); -		 -		bbox2.addBBox(LLBBoxLocal(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(0.0f, 0.0f, 0.0f))); -		 -		ensure_equals("Custom BBox center (5)", bbox2.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); -		ensure_equals("Custom BBox min (5)", bbox2.getMin(), LLVector3(-1.0f, -1.0f, -1.0f)); -		ensure_equals("Custom BBox max (5)", bbox2.getMax(), LLVector3(3.0f, 3.0f, 3.0f)); -	} -	 -	template<> template<> -	void object::test<9>() -	{ -		// -		// test the expand() method -		// -		 -		LLBBoxLocal bbox1; -		bbox1.expand(0.0f); - -		ensure_equals("Zero-expanded Default BBox center", bbox1.getCenter(), LLVector3(0.0f, 0.0f, 0.0f)); - -		LLBBoxLocal bbox2(LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); -		bbox2.expand(0.0f); -		 -		ensure_equals("Zero-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); -		ensure_equals("Zero-expanded BBox min", bbox2.getMin(), LLVector3(1.0f, 2.0f, 3.0f)); -		ensure_equals("Zero-expanded BBox max", bbox2.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); - -		bbox2.expand(0.5f); - -		ensure_equals("Positive-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); -		ensure_equals("Positive-expanded BBox min", bbox2.getMin(), LLVector3(0.5f, 1.5f, 2.5f)); -		ensure_equals("Positive-expanded BBox max", bbox2.getMax(), LLVector3(3.5f, 4.5f, 5.5f)); - -		bbox2.expand(-1.0f); -		 -		ensure_equals("Negative-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); -		ensure_equals("Negative-expanded BBox min", bbox2.getMin(), LLVector3(1.5f, 2.5f, 3.5f)); -		ensure_equals("Negative-expanded BBox max", bbox2.getMax(), LLVector3(2.5f, 3.5f, 4.5f));		 -	} +    template<> template<> +    void object::test<1>() +    { +        // +        // test the default constructor +        // + +        LLBBoxLocal bbox1; + +        ensure_equals("Default bbox min", bbox1.getMin(), LLVector3(0.0f, 0.0f, 0.0f)); +        ensure_equals("Default bbox max", bbox1.getMax(), LLVector3(0.0f, 0.0f, 0.0f)); +    } + +    template<> template<> +    void object::test<2>() +    { +        // +        // test the non-default constructor +        // + +        LLBBoxLocal bbox2(LLVector3(-1.0f, -2.0f, 0.0f), LLVector3(1.0f, 2.0f, 3.0f)); + +        ensure_equals("Custom bbox min", bbox2.getMin(), LLVector3(-1.0f, -2.0f, 0.0f)); +        ensure_equals("Custom bbox max", bbox2.getMax(), LLVector3(1.0f, 2.0f, 3.0f)); +    } + +    template<> template<> +    void object::test<3>() +    { +        // +        // test the setMin() +        // +        // N.B. no validation is currently performed to ensure that the min +        // and max vectors are actually the min/max values. +        // + +        LLBBoxLocal bbox2; +        bbox2.setMin(LLVector3(1.0f, 2.0f, 3.0f)); + +        ensure_equals("Custom bbox min (2)", bbox2.getMin(), LLVector3(1.0f, 2.0f, 3.0f)); +    } + +    template<> template<> +    void object::test<4>() +    { +        // +        // test the setMax() +        // +        // N.B. no validation is currently performed to ensure that the min +        // and max vectors are actually the min/max values. +        // + +        LLBBoxLocal bbox2; +        bbox2.setMax(LLVector3(10.0f, 20.0f, 30.0f)); + +        ensure_equals("Custom bbox max (2)", bbox2.getMax(), LLVector3(10.0f, 20.0f, 30.0f)); +    } + +    template<> template<> +    void object::test<5>() +    { +        // +        // test the getCenter() method +        // + +        ensure_equals("Default bbox center", LLBBoxLocal().getCenter(), LLVector3(0.0f, 0.0f, 0.0f)); + +        LLBBoxLocal bbox1(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(0.0f, 0.0f, 0.0f)); + +        ensure_equals("Custom bbox center", bbox1.getCenter(), LLVector3(-0.5f, -0.5f, -0.5f)); + +        LLBBoxLocal bbox2(LLVector3(0.0f, 0.0f, 0.0f), LLVector3(-1.0f, -1.0f, -1.0f)); + +        ensure_equals("Invalid bbox center", bbox2.getCenter(), LLVector3(-0.5f, -0.5f, -0.5f)); +    } + +    template<> template<> +    void object::test<6>() +    { +        // +        // test the getExtent() method +        // + +        LLBBoxLocal bbox2(LLVector3(0.0f, 0.0f, 0.0f), LLVector3(-1.0f, -1.0f, -1.0f)); + +        ensure_equals("Default bbox extent", LLBBoxLocal().getExtent(), LLVector3(0.0f, 0.0f, 0.0f)); + +        LLBBoxLocal bbox3(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(1.0f, 2.0f, 0.0f)); + +        ensure_equals("Custom bbox extent", bbox3.getExtent(), LLVector3(2.0f, 3.0f, 1.0f)); +    } + +    template<> template<> +    void object::test<7>() +    { +        // +        // test the addPoint() method +        // +        // N.B. if you create an empty bbox and then add points, +        // the vector (0, 0, 0) will always be part of the bbox. +        // (Fixing this would require adding a bool to the class size). +        // + +        LLBBoxLocal bbox1; +        bbox1.addPoint(LLVector3(-1.0f, -2.0f, -3.0f)); +        bbox1.addPoint(LLVector3(3.0f, 4.0f, 5.0f)); + +        ensure_equals("Custom BBox center (1)", bbox1.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); +        ensure_equals("Custom BBox min (1)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); +        ensure_equals("Custom BBox max (1)", bbox1.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); + +        bbox1.addPoint(LLVector3(0.0f, 0.0f, 0.0f)); +        bbox1.addPoint(LLVector3(1.0f, 2.0f, 3.0f)); +        bbox1.addPoint(LLVector3(2.0f, 2.0f, 2.0f)); + +        ensure_equals("Custom BBox center (2)", bbox1.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); +        ensure_equals("Custom BBox min (2)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); +        ensure_equals("Custom BBox max (2)", bbox1.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); + +        bbox1.addPoint(LLVector3(5.0f, 5.0f, 5.0f)); + +        ensure_equals("Custom BBox center (3)", bbox1.getCenter(), LLVector3(2.0f, 1.5f, 1.0f)); +        ensure_equals("Custom BBox min (3)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); +        ensure_equals("Custom BBox max (3)", bbox1.getMax(), LLVector3(5.0f, 5.0f, 5.0f)); +    } + +    template<> template<> +    void object::test<8>() +    { +        // +        // test the addBBox() methods +        // +        // N.B. if you create an empty bbox and then add points, +        // the vector (0, 0, 0) will always be part of the bbox. +        // (Fixing this would require adding a bool to the class size). +        // + +        LLBBoxLocal bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLVector3(2.0f, 2.0f, 2.0f)); +        bbox2.addBBox(LLBBoxLocal(LLVector3(1.5f, 1.5f, 1.5f), LLVector3(3.0f, 3.0f, 3.0f))); + +        ensure_equals("Custom BBox center (4)", bbox2.getCenter(), LLVector3(2.0f, 2.0f, 2.0f)); +        ensure_equals("Custom BBox min (4)", bbox2.getMin(), LLVector3(1.0f, 1.0f, 1.0f)); +        ensure_equals("Custom BBox max (4)", bbox2.getMax(), LLVector3(3.0f, 3.0f, 3.0f)); + +        bbox2.addBBox(LLBBoxLocal(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(0.0f, 0.0f, 0.0f))); + +        ensure_equals("Custom BBox center (5)", bbox2.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); +        ensure_equals("Custom BBox min (5)", bbox2.getMin(), LLVector3(-1.0f, -1.0f, -1.0f)); +        ensure_equals("Custom BBox max (5)", bbox2.getMax(), LLVector3(3.0f, 3.0f, 3.0f)); +    } + +    template<> template<> +    void object::test<9>() +    { +        // +        // test the expand() method +        // + +        LLBBoxLocal bbox1; +        bbox1.expand(0.0f); + +        ensure_equals("Zero-expanded Default BBox center", bbox1.getCenter(), LLVector3(0.0f, 0.0f, 0.0f)); + +        LLBBoxLocal bbox2(LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); +        bbox2.expand(0.0f); + +        ensure_equals("Zero-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); +        ensure_equals("Zero-expanded BBox min", bbox2.getMin(), LLVector3(1.0f, 2.0f, 3.0f)); +        ensure_equals("Zero-expanded BBox max", bbox2.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); + +        bbox2.expand(0.5f); + +        ensure_equals("Positive-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); +        ensure_equals("Positive-expanded BBox min", bbox2.getMin(), LLVector3(0.5f, 1.5f, 2.5f)); +        ensure_equals("Positive-expanded BBox max", bbox2.getMax(), LLVector3(3.5f, 4.5f, 5.5f)); + +        bbox2.expand(-1.0f); + +        ensure_equals("Negative-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); +        ensure_equals("Negative-expanded BBox min", bbox2.getMin(), LLVector3(1.5f, 2.5f, 3.5f)); +        ensure_equals("Negative-expanded BBox max", bbox2.getMax(), LLVector3(2.5f, 3.5f, 4.5f)); +    }  } diff --git a/indra/llmath/tests/llmodularmath_test.cpp b/indra/llmath/tests/llmodularmath_test.cpp index 063d3ef79f..399b3af05d 100644 --- a/indra/llmath/tests/llmodularmath_test.cpp +++ b/indra/llmath/tests/llmodularmath_test.cpp @@ -7,25 +7,25 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -  +  #include "linden_common.h"  #include "../llmodularmath.h" @@ -34,43 +34,43 @@  namespace tut  { -	struct modularmath_data -	{ -	}; -	typedef test_group<modularmath_data> modularmath_test; -	typedef modularmath_test::object modularmath_object; -	tut::modularmath_test modularmath_testcase("LLModularMath"); +    struct modularmath_data +    { +    }; +    typedef test_group<modularmath_data> modularmath_test; +    typedef modularmath_test::object modularmath_object; +    tut::modularmath_test modularmath_testcase("LLModularMath"); -	template<> template<> -	void modularmath_object::test<1>() -	{ -		// lhs < rhs -		const U32 lhs = 0x000001; -		const U32 rhs = 0xFFFFFF; -		const U32 width = 24; -		U32 result = LLModularMath::subtract<width>(lhs, rhs);  -		ensure_equals("diff(0x000001, 0xFFFFFF, 24)", result, 2); -	} +    template<> template<> +    void modularmath_object::test<1>() +    { +        // lhs < rhs +        const U32 lhs = 0x000001; +        const U32 rhs = 0xFFFFFF; +        const U32 width = 24; +        U32 result = LLModularMath::subtract<width>(lhs, rhs); +        ensure_equals("diff(0x000001, 0xFFFFFF, 24)", result, 2); +    } -	template<> template<> -	void modularmath_object::test<2>() -	{ -		// lhs > rhs -		const U32 lhs = 0x000002; -		const U32 rhs = 0x000001; -		const U32 width = 24; -		U32 result = LLModularMath::subtract<width>(lhs, rhs);  -		ensure_equals("diff(0x000002, 0x000001, 24)", result, 1); -	} +    template<> template<> +    void modularmath_object::test<2>() +    { +        // lhs > rhs +        const U32 lhs = 0x000002; +        const U32 rhs = 0x000001; +        const U32 width = 24; +        U32 result = LLModularMath::subtract<width>(lhs, rhs); +        ensure_equals("diff(0x000002, 0x000001, 24)", result, 1); +    } -	template<> template<> -	void modularmath_object::test<3>() -	{ -		// lhs == rhs -		const U32 lhs = 0xABCDEF; -		const U32 rhs = 0xABCDEF; -		const U32 width = 24; -		U32 result = LLModularMath::subtract<width>(lhs, rhs);  -		ensure_equals("diff(0xABCDEF, 0xABCDEF, 24)", result, 0); -	}	 +    template<> template<> +    void modularmath_object::test<3>() +    { +        // lhs == rhs +        const U32 lhs = 0xABCDEF; +        const U32 rhs = 0xABCDEF; +        const U32 width = 24; +        U32 result = LLModularMath::subtract<width>(lhs, rhs); +        ensure_equals("diff(0xABCDEF, 0xABCDEF, 24)", result, 0); +    }  } diff --git a/indra/llmath/tests/llquaternion_test.cpp b/indra/llmath/tests/llquaternion_test.cpp index 3490829743..aa3c0ad843 100644 --- a/indra/llmath/tests/llquaternion_test.cpp +++ b/indra/llmath/tests/llquaternion_test.cpp @@ -1,4 +1,4 @@ -/**  +/**   * @file llquaternion_test.cpp   * @author Adroit   * @date 2007-03 @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -38,623 +38,623 @@  namespace tut  { -	struct llquat_test -	{ -	}; -	typedef test_group<llquat_test> llquat_test_t; -	typedef llquat_test_t::object llquat_test_object_t; -	tut::llquat_test_t tut_llquat_test("LLQuaternion"); - -	//test case for LLQuaternion::LLQuaternion(void) fn. -	template<> template<> -	void llquat_test_object_t::test<1>() -	{ -		LLQuaternion llquat; -		ensure("LLQuaternion::LLQuaternion() failed", 0.f == llquat.mQ[0] && -		 									0.f == llquat.mQ[1] && -		 									0.f == llquat.mQ[2] && -											1.f == llquat.mQ[3]); -	} - -	//test case for explicit LLQuaternion(const LLMatrix4 &mat) fn. -	template<> template<> -	void llquat_test_object_t::test<2>() -	{ -		LLMatrix4 llmat; -		LLVector4 vector1(2.0f, 1.0f, 3.0f, 6.0f); -		LLVector4 vector2(5.0f, 6.0f, 0.0f, 1.0f); -		LLVector4 vector3(2.0f, 1.0f, 2.0f, 9.0f); -		LLVector4 vector4(3.0f, 8.0f, 1.0f, 5.0f); - -		llmat.initRows(vector1, vector2, vector3, vector4); -		ensure("explicit LLQuaternion(const LLMatrix4 &mat) failed", 2.0f == llmat.mMatrix[0][0] && -										 	1.0f == llmat.mMatrix[0][1] && -											3.0f == llmat.mMatrix[0][2] && -											6.0f == llmat.mMatrix[0][3] && -											5.0f == llmat.mMatrix[1][0] && -											6.0f == llmat.mMatrix[1][1] && -											0.0f == llmat.mMatrix[1][2] && -											1.0f == llmat.mMatrix[1][3] && -											2.0f == llmat.mMatrix[2][0] && -											1.0f == llmat.mMatrix[2][1] && -											2.0f == llmat.mMatrix[2][2] && -											9.0f == llmat.mMatrix[2][3] && -											3.0f == llmat.mMatrix[3][0] && -											8.0f == llmat.mMatrix[3][1] && -											1.0f == llmat.mMatrix[3][2] && -											5.0f == llmat.mMatrix[3][3]); -	} -	 -	template<> template<> -	void llquat_test_object_t::test<3>() -	{ -		LLMatrix3 llmat; - -		LLVector3 vect1(3.4028234660000000f , 234.56f, 4234.442234f); -		LLVector3 vect2(741.434f, 23.00034f, 6567.223423f); -		LLVector3 vect3(566.003034f, 12.98705f, 234.764423f); -		llmat.setRows(vect1, vect2, vect3); - -		ensure("LLMatrix3::setRows fn failed.", 3.4028234660000000f == llmat.mMatrix[0][0] && -										234.56f == llmat.mMatrix[0][1] && -										4234.442234f == llmat.mMatrix[0][2] && -										741.434f == llmat.mMatrix[1][0] && -										23.00034f == llmat.mMatrix[1][1] && -										6567.223423f == llmat.mMatrix[1][2] && -										566.003034f == llmat.mMatrix[2][0] && -										12.98705f == llmat.mMatrix[2][1] && -										234.764423f == llmat.mMatrix[2][2]);		 -	} - -	//test case for LLQuaternion(F32 x, F32 y, F32 z, F32 w), setQuatInit() and normQuat() fns. -	template<> template<> -	void llquat_test_object_t::test<4>() -	{ -		F32 x_val = 3.0f; -		F32 y_val = 2.0f; -		F32 z_val = 6.0f; -		F32 w_val = 1.0f; -		 -		LLQuaternion res_quat; -		res_quat.setQuatInit(x_val, y_val, z_val, w_val); -		res_quat.normQuat(); -				 -		ensure("LLQuaternion::normQuat() fn failed",  -							is_approx_equal(0.42426407f, res_quat.mQ[0]) && -							is_approx_equal(0.28284273f, res_quat.mQ[1]) && -							is_approx_equal(0.84852815f, res_quat.mQ[2]) && -							is_approx_equal(0.14142136f, res_quat.mQ[3])); -		 -		x_val = 0.0f; -		y_val = 0.0f; -		z_val = 0.0f; -		w_val = 0.0f; - -		res_quat.setQuatInit(x_val, y_val, z_val, w_val); -		res_quat.normQuat(); - -		ensure("LLQuaternion::normQuat() fn. failed.",  -							is_approx_equal(0.0f, res_quat.mQ[0]) && -							is_approx_equal(0.0f, res_quat.mQ[1]) && -							is_approx_equal(0.0f, res_quat.mQ[2]) && -							is_approx_equal(1.0f, res_quat.mQ[3])); - - -		ensure("LLQuaternion::normQuat() fn. failed.",  -							is_approx_equal(0.0f, res_quat.mQ[0]) && -							is_approx_equal(0.0f, res_quat.mQ[1]) && -							is_approx_equal(0.0f, res_quat.mQ[2]) && -							is_approx_equal(1.0f, res_quat.mQ[3])); -	} - -	//test case for conjQuat() and transQuat() fns. -	template<> template<> -	void llquat_test_object_t::test<5>() -	{ -		F32 x_val = 3.0f; -		F32 y_val = 2.0f; -		F32 z_val = 6.0f; -		F32 w_val = 1.0f; -		 -		LLQuaternion res_quat; -		LLQuaternion result, result1; -		result1 = result = res_quat.setQuatInit(x_val, y_val, z_val, w_val); -				 -		result.conjQuat(); -		result1.transQuat(); - -		ensure("LLQuaternion::conjQuat and LLQuaternion::transQuat failed ",  -								is_approx_equal(result1.mQ[0], result.mQ[0]) && -								is_approx_equal(result1.mQ[1], result.mQ[1]) && -								is_approx_equal(result1.mQ[2], result.mQ[2]));		 - -	} - -	//test case for dot(const LLQuaternion &a, const LLQuaternion &b) fn. -	template<> template<> -	void llquat_test_object_t::test<6>() -	{ -		LLQuaternion quat1(3.0f, 2.0f, 6.0f, 0.0f), quat2(1.0f, 1.0f, 1.0f, 1.0f); -		ensure("1. The two values are different", ll_round(12.000000f, 2) == ll_round(dot(quat1, quat2), 2)); - -		LLQuaternion quat0(3.0f, 9.334f, 34.5f, 23.0f), quat(34.5f, 23.23f, 2.0f, 45.5f); -		ensure("2. The two values are different", ll_round(1435.828807f, 2) == ll_round(dot(quat0, quat), 2)); -	} - -	//test case for LLQuaternion &LLQuaternion::constrain(F32 radians) fn. -	template<> template<> -	void llquat_test_object_t::test<7>() -	{ -		F32 radian = 60.0f; -		LLQuaternion quat(3.0f, 2.0f, 6.0f, 0.0f); -		LLQuaternion quat1; -		quat1 = quat.constrain(radian); -		ensure("1. LLQuaternion::constrain(F32 radians) failed",  -									is_approx_equal_fraction(-0.423442f, quat1.mQ[0], 8) && -									is_approx_equal_fraction(-0.282295f, quat1.mQ[1], 8) && -									is_approx_equal_fraction(-0.846884f, quat1.mQ[2], 8) &&				 -									is_approx_equal_fraction(0.154251f, quat1.mQ[3], 8));				 -											 - -		radian = 30.0f; -		LLQuaternion quat0(37.50f, 12.0f, 86.023f, 40.32f); -		quat1 = quat0.constrain(radian); -	 -		ensure("2. LLQuaternion::constrain(F32 radians) failed",  -									is_approx_equal_fraction(37.500000f, quat1.mQ[0], 8) && -									is_approx_equal_fraction(12.0000f, quat1.mQ[1], 8) && -									is_approx_equal_fraction(86.0230f, quat1.mQ[2], 8) &&				 -									is_approx_equal_fraction(40.320000f, quat1.mQ[3], 8));				 -	} - -	template<> template<> -	void llquat_test_object_t::test<8>() -	{ -		F32 value1 = 15.0f; -		LLQuaternion quat1(1.0f, 2.0f, 4.0f, 1.0f); -		LLQuaternion quat2(4.0f, 3.0f, 6.5f, 9.7f); -		LLQuaternion res_lerp, res_slerp, res_nlerp; -		 -		//test case for lerp(F32 t, const LLQuaternion &q) fn.  -		res_lerp = lerp(value1, quat1); -		ensure("1. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed",  -										is_approx_equal_fraction(0.181355f, res_lerp.mQ[0], 16) && -										is_approx_equal_fraction(0.362711f, res_lerp.mQ[1], 16) && -										is_approx_equal_fraction(0.725423f, res_lerp.mQ[2], 16) &&				 -										is_approx_equal_fraction(0.556158f, res_lerp.mQ[3], 16));				 - -		//test case for lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) fn. -		res_lerp = lerp(value1, quat1, quat2); -		ensure("2. LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) failed", -										is_approx_equal_fraction(0.314306f, res_lerp.mQ[0], 16) && -										is_approx_equal_fraction(0.116156f, res_lerp.mQ[1], 16) && -										is_approx_equal_fraction(0.283559f, res_lerp.mQ[2], 16) &&				 -										is_approx_equal_fraction(0.898506f, res_lerp.mQ[3], 16));				 - -		//test case for slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b ) fn. -		res_slerp = slerp(value1, quat1, quat2); -		ensure("3. LLQuaternion slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b) failed",  -										is_approx_equal_fraction(46.000f, res_slerp.mQ[0], 16) && -										is_approx_equal_fraction(17.00f, res_slerp.mQ[1], 16) && -										is_approx_equal_fraction(41.5f, res_slerp.mQ[2], 16) &&				 -										is_approx_equal_fraction(131.5f, res_slerp.mQ[3], 16));				 - -		//test case for nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) fn. -		res_nlerp = nlerp(value1, quat1, quat2); -		ensure("4. LLQuaternion nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) failed",   -										is_approx_equal_fraction(0.314306f, res_nlerp.mQ[0], 16) && -										is_approx_equal_fraction(0.116157f, res_nlerp.mQ[1], 16) && -										is_approx_equal_fraction(0.283559f, res_nlerp.mQ[2], 16) &&				 -										is_approx_equal_fraction(0.898506f, res_nlerp.mQ[3], 16));				 - -		//test case for nlerp(F32 t, const LLQuaternion &q) fn. -		res_slerp = slerp(value1, quat1); -		ensure("5. LLQuaternion slerp(F32 t, const LLQuaternion &q) failed",  -										is_approx_equal_fraction(1.0f, res_slerp.mQ[0], 16) && -										is_approx_equal_fraction(2.0f, res_slerp.mQ[1], 16) && -										is_approx_equal_fraction(4.0000f, res_slerp.mQ[2], 16) &&				 -										is_approx_equal_fraction(1.000f, res_slerp.mQ[3], 16));				 -										 -		LLQuaternion quat3(2.0f, 1.0f, 5.5f, 10.5f); -		LLQuaternion res_nlerp1; -		value1 = 100.0f; -		res_nlerp1 = nlerp(value1, quat3); -		ensure("6. LLQuaternion nlerp(F32 t, const LLQuaternion &q)  failed",  -										is_approx_equal_fraction(0.268245f, res_nlerp1.mQ[0], 16) &&										is_approx_equal_fraction(0.134122f, res_nlerp1.mQ[1], 2) && -										is_approx_equal_fraction(0.737673f, res_nlerp1.mQ[2], 16) &&				 -										is_approx_equal_fraction(0.604892f, res_nlerp1.mQ[3], 16));				 - -		//test case for lerp(F32 t, const LLQuaternion &q) fn.  -		res_lerp = lerp(value1, quat2); -		ensure("7. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed",  -										is_approx_equal_fraction(0.404867f, res_lerp.mQ[0], 16) && -										is_approx_equal_fraction(0.303650f, res_lerp.mQ[1], 16) && -										is_approx_equal_fraction(0.657909f, res_lerp.mQ[2], 16) &&				 -										is_approx_equal_fraction(0.557704f, res_lerp.mQ[3], 16));				 -		 -	} - -	template<> template<> -	void llquat_test_object_t::test<9>() -	{ -		//test case for LLQuaternion operator*(const LLQuaternion &a, const LLQuaternion &b) fn -		LLQuaternion quat1(1.0f, 2.5f, 3.5f, 5.5f); -		LLQuaternion quat2(4.0f, 3.0f, 5.0f, 1.0f); -		LLQuaternion result = quat1 *  quat2; -		ensure("1. LLQuaternion Operator* failed", (21.0f == result.mQ[0]) && -											(10.0f == result.mQ[1]) && -											(38.0f == result.mQ[2]) &&  -											(-23.5f == result.mQ[3])); - -		LLQuaternion quat3(2341.340f, 2352.345f, 233.25f, 7645.5f); -		LLQuaternion quat4(674.067f, 893.0897f, 578.0f, 231.0f); -		result = quat3 * quat4; -		ensure("2. LLQuaternion Operator* failed", (4543086.5f == result.mQ[0]) && -											(8567578.0f == result.mQ[1]) && -											(3967591.25f == result.mQ[2]) && -											is_approx_equal(-2047783.25f, result.mQ[3])); - -		//inline LLQuaternion operator+(const LLQuaternion &a, const LLQuaternion &b)fn.		 -		result = quat1 + quat2; -		ensure("3. LLQuaternion operator+ failed", (5.0f == result.mQ[0]) && -											(5.5f == result.mQ[1]) && -											(8.5f == result.mQ[2]) && -											(6.5f == result.mQ[3])); - -		result = quat3 + quat4; -		ensure( -			"4. LLQuaternion operator+ failed", -			is_approx_equal(3015.407227f, result.mQ[0]) && -			is_approx_equal(3245.434570f, result.mQ[1]) && -			(811.25f == result.mQ[2]) && -			(7876.5f == result.mQ[3])); - -		//inline LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) fn -		result = quat1 - quat2; -		ensure( -			"5. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed",  -			(-3.0f == result.mQ[0]) && -			(-0.5f == result.mQ[1]) && -			(-1.5f == result.mQ[2]) && -			(4.5f == result.mQ[3])); - -		result = quat3 - quat4; -		ensure( -			"6. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed",  -			is_approx_equal(1667.273071f, result.mQ[0]) && -			is_approx_equal(1459.255249f, result.mQ[1]) && -			(-344.75f == result.mQ[2]) && -			(7414.50f == result.mQ[3])); -	} - -	//test case for LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) fn. -	template<> template<> -	void llquat_test_object_t::test<10>() -	{ -		LLVector4 vect(12.0f, 5.0f, 60.0f, 75.1f); -		LLQuaternion quat(2323.034f, 23.5f, 673.23f, 57667.5f); -		LLVector4 result = vect * quat; -		ensure( -			"1. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed",  -			is_approx_equal(39928406016.0f, result.mV[0]) && -			// gcc on x86 actually gives us more precision than we were expecting, verified with -ffloat-store - we forgive this -			(1457802240.0f >= result.mV[1]) && // gcc+x86+linux -			(1457800960.0f <= result.mV[1]) && // elsewhere -			is_approx_equal(200580612096.0f, result.mV[2]) && -			(75.099998f == result.mV[3])); - -		LLVector4 vect1(22.0f, 45.0f, 40.0f, 78.1f); -		LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f); -		result = vect1 * quat1; -		ensure( -			"2. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed",  -			is_approx_equal(-58153.5390f, result.mV[0]) && -			(183787.8125f == result.mV[1]) && -			(116864.164063f == result.mV[2]) && -			(78.099998f == result.mV[3])); -	} - -	//test case for LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) fn. -	template<> template<> -	void llquat_test_object_t::test<11>() -	{ -		LLVector3 vect(12.0f, 5.0f, 60.0f); -		LLQuaternion quat(23.5f, 6.5f, 3.23f, 56.5f); -		LLVector3 result = vect * quat; -		ensure( -			"1. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed",  -			is_approx_equal(97182.953125f,result.mV[0]) && -			is_approx_equal(-135405.640625f, result.mV[1]) && -			is_approx_equal(162986.140f, result.mV[2])); - -		LLVector3 vect1(5.0f, 40.0f, 78.1f); -		LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f); -		result = vect1 * quat1; -		ensure( -			"2. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed",  -			is_approx_equal(33217.703f, result.mV[0]) && -			is_approx_equal(295383.8125f, result.mV[1]) && -			is_approx_equal(84718.140f, result.mV[2])); -	} - -	//test case for LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) fn. -	template<> template<> -	void llquat_test_object_t::test<12>() -	{ -		LLVector3d vect(-2.0f, 5.0f, -6.0f); -		LLQuaternion quat(-3.5f, 4.5f, 3.5f, 6.5f); -		LLVector3d result = vect * quat; -		ensure( -			"1. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed ",  -			(-633.0f == result.mdV[0]) && -			(-300.0f == result.mdV[1]) && -			(-36.0f == result.mdV[2])); - -		LLVector3d vect1(5.0f, -4.5f, 8.21f); -		LLQuaternion quat1(2.0f, 4.5f, -7.2f, 9.5f); -		result = vect1 * quat1; -		ensure( -			"2. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed",  -			is_approx_equal_fraction(-120.29f, (F32) result.mdV[0], 8) && -			is_approx_equal_fraction(-1683.958f, (F32) result.mdV[1], 8) && -			is_approx_equal_fraction(516.56f, (F32) result.mdV[2], 8)); - -		LLVector3d vect2(2.0f, 3.5f, 1.1f); -		LLQuaternion quat2(1.0f, 4.0f, 2.0f, 5.0f); -		result = vect2 * quat2; -		ensure( -			"3. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed",  -			is_approx_equal_fraction(18.400001f, (F32) result.mdV[0], 8) && -			is_approx_equal_fraction(188.6f, (F32) result.mdV[1], 8) && -			is_approx_equal_fraction(32.20f, (F32) result.mdV[2], 8)); -	} - -	//test case for inline LLQuaternion operator-(const LLQuaternion &a) fn. -	template<> template<> -	void llquat_test_object_t::test<13>() -	{ -		LLQuaternion quat(23.5f, 34.5f, 16723.4f, 324.7f); -		LLQuaternion result = -quat; -		ensure( -			"1. LLQuaternion operator-(const LLQuaternion &a) failed",  -			(-23.5f == result.mQ[0]) && -			(-34.5f == result.mQ[1]) && -			(-16723.4f == result.mQ[2]) && -			(-324.7f == result.mQ[3])); - -		LLQuaternion quat1(-3.5f, -34.5f, -16.4f, -154.7f); -		result = -quat1; -		ensure( -			"2. LLQuaternion operator-(const LLQuaternion &a) failed.",  -			(3.5f == result.mQ[0]) && -			(34.5f == result.mQ[1]) && -			(16.4f == result.mQ[2]) && -			(154.7f == result.mQ[3])); -	} - -	//test case for inline LLQuaternion operator*(F32 a, const LLQuaternion &q) and -	//inline LLQuaternion operator*(F32 a, const LLQuaternion &q) fns. -	template<> template<> -	void llquat_test_object_t::test<14>() -	{ -		LLQuaternion quat_value(9.0f, 8.0f, 7.0f, 6.0f); -		F32 a =3.5f; -		LLQuaternion result = a * quat_value; -		LLQuaternion result1 = quat_value * a; - -		ensure( -			"1. LLQuaternion operator* failed", -			(result.mQ[0] == result1.mQ[0]) && -			(result.mQ[1] == result1.mQ[1]) && -			(result.mQ[2] == result1.mQ[2]) && -			(result.mQ[3] == result1.mQ[3])); - - -		LLQuaternion quat_val(9454.0f, 43568.3450f, 456343247.0343f, 2346.03434f); -		a =-3324.3445f; -		result = a * quat_val; -		result1 = quat_val * a; - -		ensure( -			"2. LLQuaternion operator* failed", -			(result.mQ[0] == result1.mQ[0]) && -			(result.mQ[1] == result1.mQ[1]) && -			(result.mQ[2] == result1.mQ[2]) && -			(result.mQ[3] == result1.mQ[3])); -	} -	 -	template<> template<> -	void llquat_test_object_t::test<15>() -	{ -		// test cases for inline LLQuaternion operator~(const LLQuaternion &a) -		LLQuaternion quat_val(2323.634f, -43535.4f, 3455.88f, -32232.45f); -		LLQuaternion result = ~quat_val; -		ensure( -			"1. LLQuaternion operator~(const LLQuaternion &a) failed ",  -			(-2323.634f == result.mQ[0]) && -			(43535.4f == result.mQ[1]) && -			(-3455.88f == result.mQ[2]) && -			(-32232.45f == result.mQ[3])); - -		//test case for inline bool LLQuaternion::operator==(const LLQuaternion &b) const -		LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f); -		LLQuaternion quat_val2(2323.634f, -43535.4f, 3455.88f, -32232.45f); -		ensure( -			"2. LLQuaternion::operator==(const LLQuaternion &b) failed", -			quat_val1 == quat_val2); -	} -	 -	template<> template<> -	void llquat_test_object_t::test<16>() -	{ -		//test case for inline bool LLQuaternion::operator!=(const LLQuaternion &b) const -		LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f); -		LLQuaternion quat_val2(0, -43535.4f, 3455.88f, -32232.45f); -		ensure("LLQuaternion::operator!=(const LLQuaternion &b) failed", quat_val1 != quat_val2); -	} - -	template<> template<> -	void llquat_test_object_t::test<17>() -	{ -		//test case for LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) -		F32 x = 2.0f; -		F32 y = 1.0f; -		F32 z = 3.0f; -		 -		LLQuaternion result = mayaQ(x, y, z, LLQuaternion::XYZ); -		ensure( -			"1. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ", -			is_approx_equal_fraction(0.0172174f, result.mQ[0], 16) && -			is_approx_equal_fraction(0.009179f, result.mQ[1], 16) && -			is_approx_equal_fraction(0.026020f, result.mQ[2], 16) && -			is_approx_equal_fraction(0.999471f, result.mQ[3], 16)); - -		LLQuaternion result1 = mayaQ(x, y, z, LLQuaternion::YZX); -		ensure( -			"2. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ", -			is_approx_equal_fraction(0.017217f, result1.mQ[0], 16) && -			is_approx_equal_fraction(0.008265f, result1.mQ[1], 16) && -			is_approx_equal_fraction(0.026324f, result1.mQ[2], 16) && -			is_approx_equal_fraction(0.999471f, result1.mQ[3], 16)); -		 -		LLQuaternion result2 = mayaQ(x, y, z, LLQuaternion::ZXY); -		ensure( -			"3. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZXY",  -			is_approx_equal_fraction(0.017674f, result2.mQ[0], 16) && -			is_approx_equal_fraction(0.008265f, result2.mQ[1], 16) && -			is_approx_equal_fraction(0.026020f, result2.mQ[2], 16) && -			is_approx_equal_fraction(0.999471f, result2.mQ[3], 16)); -											 -		LLQuaternion result3 = mayaQ(x, y, z, LLQuaternion::XZY); -		ensure( -			"4. TLLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XZY",  -			is_approx_equal_fraction(0.017674f, result3.mQ[0], 16) && -			is_approx_equal_fraction(0.009179f, result3.mQ[1], 16) && -			is_approx_equal_fraction(0.026020f, result3.mQ[2], 16) && -			is_approx_equal_fraction(0.999463f, result3.mQ[3], 16)); -											 -		LLQuaternion result4 = mayaQ(x, y, z, LLQuaternion::YXZ); -		ensure( -			"5. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for YXZ",  -			is_approx_equal_fraction(0.017217f, result4.mQ[0], 16) && -			is_approx_equal_fraction(0.009179f, result4.mQ[1], 16) && -			is_approx_equal_fraction(0.026324f, result4.mQ[2], 16) && -			is_approx_equal_fraction(0.999463f, result4.mQ[3], 16)); -											 -		LLQuaternion result5 = mayaQ(x, y, z, LLQuaternion::ZYX); -		ensure( -			"6. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZYX",  -			is_approx_equal_fraction(0.017674f, result5.mQ[0], 16) && -			is_approx_equal_fraction(0.008265f, result5.mQ[1], 16) && -			is_approx_equal_fraction(0.026324f, result5.mQ[2], 16) && -			is_approx_equal_fraction(0.999463f, result5.mQ[3], 16)); -	} - -	template<> template<> -	void llquat_test_object_t::test<18>() -	{ -		// test case for friend std::ostream& operator<<(std::ostream &s, const LLQuaternion &a) fn -		LLQuaternion a(1.0f, 1.0f, 1.0f, 1.0f);  -		std::ostringstream result_value; -		result_value << a; -		ensure_equals("1. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }"); - -		LLQuaternion b(-31.034f, 231.2340f, 3451.344320f, -341.0f);  -		std::ostringstream result_value1; -		result_value1 << b; -		ensure_equals("2. Operator << failed", result_value1.str(), "{ -31.034, 231.234, 3451.34, -341 }"); - -		LLQuaternion c(1.0f, 2.2f, 3.3f, 4.4f);  -		result_value << c; -		ensure_equals("3. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }{ 1, 2.2, 3.3, 4.4 }"); - -	} -	 -	template<> template<> -	void llquat_test_object_t::test<19>() -	{ -		//test case for const char *OrderToString( const LLQuaternion::Order order ) fn -		const char* result = OrderToString(LLQuaternion::XYZ); -		ensure("1. OrderToString failed for XYZ",  (0 == strcmp("XYZ", result))); -		 -		result = OrderToString(LLQuaternion::YZX); -		ensure("2. OrderToString failed for YZX",  (0 == strcmp("YZX", result))); -		 -		result = OrderToString(LLQuaternion::ZXY); -		ensure( -			"3. OrderToString failed for ZXY", -			(0 == strcmp("ZXY", result)) && -			(0 != strcmp("XYZ", result)) && -			(0 != strcmp("YXZ", result)) && -			(0 != strcmp("ZYX", result)) && -			(0 != strcmp("XYZ", result))); - -		result = OrderToString(LLQuaternion::XZY); -		ensure("4. OrderToString failed for XZY",  (0 == strcmp("XZY", result))); - -		result = OrderToString(LLQuaternion::ZYX); -		ensure("5. OrderToString failed for ZYX",  (0 == strcmp("ZYX", result))); - -		result = OrderToString(LLQuaternion::YXZ); -		ensure("6.OrderToString failed for YXZ",  (0 == strcmp("YXZ", result))); -	} - -	template<> template<> -	void llquat_test_object_t::test<20>() -	{ -		//test case for LLQuaternion::Order StringToOrder( const char *str ) fn -		int result = StringToOrder("XYZ"); -		ensure("1. LLQuaternion::Order StringToOrder(const char *str ) failed for XYZ", 0 == result); - -		result = StringToOrder("YZX"); -		ensure("2. LLQuaternion::Order StringToOrder(const char *str) failed for YZX", 1 == result); - -		result = StringToOrder("ZXY"); -		ensure("3. LLQuaternion::Order StringToOrder(const char *str) failed for ZXY", 2 == result); -		 -		result = StringToOrder("XZY"); -		ensure("4. LLQuaternion::Order StringToOrder(const char *str) failed for XZY", 3 == result); - -		result = StringToOrder("YXZ"); -		ensure("5. LLQuaternion::Order StringToOrder(const char *str) failed for YXZ", 4 == result); -	 -		result = StringToOrder("ZYX"); -		ensure("6. LLQuaternion::Order StringToOrder(const char *str) failed for  ZYX", 5 == result);	 - -	} - -	template<> template<> -	void llquat_test_object_t::test<21>() -	{ -		//void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const fn -		F32 angle_value = 90.0f; -		LLVector3 vect(12.0f, 4.0f, 1.0f); -		LLQuaternion llquat(angle_value, vect); -		llquat.getAngleAxis(&angle_value, vect);  -		ensure( -			"LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) failed",  -			is_approx_equal_fraction(2.035406f, angle_value, 16) && -			is_approx_equal_fraction(0.315244f, vect.mV[1], 16) && -			is_approx_equal_fraction(0.078811f, vect.mV[2], 16) && -			is_approx_equal_fraction(0.945733f, vect.mV[0], 16)); -	} - -	template<> template<> -	void llquat_test_object_t::test<22>() -	{ -		//test case for void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const fn -		F32 roll = -12.0f; -		F32 pitch = -22.43f; -		F32 yaw = 11.0f; - -		LLQuaternion llquat; -		llquat.getEulerAngles(&roll, &pitch, &yaw); -		ensure( -			"LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) failed", -			is_approx_equal(0.000f, llquat.mQ[0]) && -			is_approx_equal(0.000f, llquat.mQ[1]) && -			is_approx_equal(0.000f, llquat.mQ[2]) && -			is_approx_equal(1.000f, llquat.mQ[3])); -	} +    struct llquat_test +    { +    }; +    typedef test_group<llquat_test> llquat_test_t; +    typedef llquat_test_t::object llquat_test_object_t; +    tut::llquat_test_t tut_llquat_test("LLQuaternion"); + +    //test case for LLQuaternion::LLQuaternion(void) fn. +    template<> template<> +    void llquat_test_object_t::test<1>() +    { +        LLQuaternion llquat; +        ensure("LLQuaternion::LLQuaternion() failed", 0.f == llquat.mQ[0] && +                                            0.f == llquat.mQ[1] && +                                            0.f == llquat.mQ[2] && +                                            1.f == llquat.mQ[3]); +    } + +    //test case for explicit LLQuaternion(const LLMatrix4 &mat) fn. +    template<> template<> +    void llquat_test_object_t::test<2>() +    { +        LLMatrix4 llmat; +        LLVector4 vector1(2.0f, 1.0f, 3.0f, 6.0f); +        LLVector4 vector2(5.0f, 6.0f, 0.0f, 1.0f); +        LLVector4 vector3(2.0f, 1.0f, 2.0f, 9.0f); +        LLVector4 vector4(3.0f, 8.0f, 1.0f, 5.0f); + +        llmat.initRows(vector1, vector2, vector3, vector4); +        ensure("explicit LLQuaternion(const LLMatrix4 &mat) failed", 2.0f == llmat.mMatrix[0][0] && +                                            1.0f == llmat.mMatrix[0][1] && +                                            3.0f == llmat.mMatrix[0][2] && +                                            6.0f == llmat.mMatrix[0][3] && +                                            5.0f == llmat.mMatrix[1][0] && +                                            6.0f == llmat.mMatrix[1][1] && +                                            0.0f == llmat.mMatrix[1][2] && +                                            1.0f == llmat.mMatrix[1][3] && +                                            2.0f == llmat.mMatrix[2][0] && +                                            1.0f == llmat.mMatrix[2][1] && +                                            2.0f == llmat.mMatrix[2][2] && +                                            9.0f == llmat.mMatrix[2][3] && +                                            3.0f == llmat.mMatrix[3][0] && +                                            8.0f == llmat.mMatrix[3][1] && +                                            1.0f == llmat.mMatrix[3][2] && +                                            5.0f == llmat.mMatrix[3][3]); +    } + +    template<> template<> +    void llquat_test_object_t::test<3>() +    { +        LLMatrix3 llmat; + +        LLVector3 vect1(3.4028234660000000f , 234.56f, 4234.442234f); +        LLVector3 vect2(741.434f, 23.00034f, 6567.223423f); +        LLVector3 vect3(566.003034f, 12.98705f, 234.764423f); +        llmat.setRows(vect1, vect2, vect3); + +        ensure("LLMatrix3::setRows fn failed.", 3.4028234660000000f == llmat.mMatrix[0][0] && +                                        234.56f == llmat.mMatrix[0][1] && +                                        4234.442234f == llmat.mMatrix[0][2] && +                                        741.434f == llmat.mMatrix[1][0] && +                                        23.00034f == llmat.mMatrix[1][1] && +                                        6567.223423f == llmat.mMatrix[1][2] && +                                        566.003034f == llmat.mMatrix[2][0] && +                                        12.98705f == llmat.mMatrix[2][1] && +                                        234.764423f == llmat.mMatrix[2][2]); +    } + +    //test case for LLQuaternion(F32 x, F32 y, F32 z, F32 w), setQuatInit() and normQuat() fns. +    template<> template<> +    void llquat_test_object_t::test<4>() +    { +        F32 x_val = 3.0f; +        F32 y_val = 2.0f; +        F32 z_val = 6.0f; +        F32 w_val = 1.0f; + +        LLQuaternion res_quat; +        res_quat.setQuatInit(x_val, y_val, z_val, w_val); +        res_quat.normQuat(); + +        ensure("LLQuaternion::normQuat() fn failed", +                            is_approx_equal(0.42426407f, res_quat.mQ[0]) && +                            is_approx_equal(0.28284273f, res_quat.mQ[1]) && +                            is_approx_equal(0.84852815f, res_quat.mQ[2]) && +                            is_approx_equal(0.14142136f, res_quat.mQ[3])); + +        x_val = 0.0f; +        y_val = 0.0f; +        z_val = 0.0f; +        w_val = 0.0f; + +        res_quat.setQuatInit(x_val, y_val, z_val, w_val); +        res_quat.normQuat(); + +        ensure("LLQuaternion::normQuat() fn. failed.", +                            is_approx_equal(0.0f, res_quat.mQ[0]) && +                            is_approx_equal(0.0f, res_quat.mQ[1]) && +                            is_approx_equal(0.0f, res_quat.mQ[2]) && +                            is_approx_equal(1.0f, res_quat.mQ[3])); + + +        ensure("LLQuaternion::normQuat() fn. failed.", +                            is_approx_equal(0.0f, res_quat.mQ[0]) && +                            is_approx_equal(0.0f, res_quat.mQ[1]) && +                            is_approx_equal(0.0f, res_quat.mQ[2]) && +                            is_approx_equal(1.0f, res_quat.mQ[3])); +    } + +    //test case for conjQuat() and transQuat() fns. +    template<> template<> +    void llquat_test_object_t::test<5>() +    { +        F32 x_val = 3.0f; +        F32 y_val = 2.0f; +        F32 z_val = 6.0f; +        F32 w_val = 1.0f; + +        LLQuaternion res_quat; +        LLQuaternion result, result1; +        result1 = result = res_quat.setQuatInit(x_val, y_val, z_val, w_val); + +        result.conjQuat(); +        result1.transQuat(); + +        ensure("LLQuaternion::conjQuat and LLQuaternion::transQuat failed ", +                                is_approx_equal(result1.mQ[0], result.mQ[0]) && +                                is_approx_equal(result1.mQ[1], result.mQ[1]) && +                                is_approx_equal(result1.mQ[2], result.mQ[2])); + +    } + +    //test case for dot(const LLQuaternion &a, const LLQuaternion &b) fn. +    template<> template<> +    void llquat_test_object_t::test<6>() +    { +        LLQuaternion quat1(3.0f, 2.0f, 6.0f, 0.0f), quat2(1.0f, 1.0f, 1.0f, 1.0f); +        ensure("1. The two values are different", ll_round(12.000000f, 2) == ll_round(dot(quat1, quat2), 2)); + +        LLQuaternion quat0(3.0f, 9.334f, 34.5f, 23.0f), quat(34.5f, 23.23f, 2.0f, 45.5f); +        ensure("2. The two values are different", ll_round(1435.828807f, 2) == ll_round(dot(quat0, quat), 2)); +    } + +    //test case for LLQuaternion &LLQuaternion::constrain(F32 radians) fn. +    template<> template<> +    void llquat_test_object_t::test<7>() +    { +        F32 radian = 60.0f; +        LLQuaternion quat(3.0f, 2.0f, 6.0f, 0.0f); +        LLQuaternion quat1; +        quat1 = quat.constrain(radian); +        ensure("1. LLQuaternion::constrain(F32 radians) failed", +                                    is_approx_equal_fraction(-0.423442f, quat1.mQ[0], 8) && +                                    is_approx_equal_fraction(-0.282295f, quat1.mQ[1], 8) && +                                    is_approx_equal_fraction(-0.846884f, quat1.mQ[2], 8) && +                                    is_approx_equal_fraction(0.154251f, quat1.mQ[3], 8)); + + +        radian = 30.0f; +        LLQuaternion quat0(37.50f, 12.0f, 86.023f, 40.32f); +        quat1 = quat0.constrain(radian); + +        ensure("2. LLQuaternion::constrain(F32 radians) failed", +                                    is_approx_equal_fraction(37.500000f, quat1.mQ[0], 8) && +                                    is_approx_equal_fraction(12.0000f, quat1.mQ[1], 8) && +                                    is_approx_equal_fraction(86.0230f, quat1.mQ[2], 8) && +                                    is_approx_equal_fraction(40.320000f, quat1.mQ[3], 8)); +    } + +    template<> template<> +    void llquat_test_object_t::test<8>() +    { +        F32 value1 = 15.0f; +        LLQuaternion quat1(1.0f, 2.0f, 4.0f, 1.0f); +        LLQuaternion quat2(4.0f, 3.0f, 6.5f, 9.7f); +        LLQuaternion res_lerp, res_slerp, res_nlerp; + +        //test case for lerp(F32 t, const LLQuaternion &q) fn. +        res_lerp = lerp(value1, quat1); +        ensure("1. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed", +                                        is_approx_equal_fraction(0.181355f, res_lerp.mQ[0], 16) && +                                        is_approx_equal_fraction(0.362711f, res_lerp.mQ[1], 16) && +                                        is_approx_equal_fraction(0.725423f, res_lerp.mQ[2], 16) && +                                        is_approx_equal_fraction(0.556158f, res_lerp.mQ[3], 16)); + +        //test case for lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) fn. +        res_lerp = lerp(value1, quat1, quat2); +        ensure("2. LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) failed", +                                        is_approx_equal_fraction(0.314306f, res_lerp.mQ[0], 16) && +                                        is_approx_equal_fraction(0.116156f, res_lerp.mQ[1], 16) && +                                        is_approx_equal_fraction(0.283559f, res_lerp.mQ[2], 16) && +                                        is_approx_equal_fraction(0.898506f, res_lerp.mQ[3], 16)); + +        //test case for slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b ) fn. +        res_slerp = slerp(value1, quat1, quat2); +        ensure("3. LLQuaternion slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b) failed", +                                        is_approx_equal_fraction(46.000f, res_slerp.mQ[0], 16) && +                                        is_approx_equal_fraction(17.00f, res_slerp.mQ[1], 16) && +                                        is_approx_equal_fraction(41.5f, res_slerp.mQ[2], 16) && +                                        is_approx_equal_fraction(131.5f, res_slerp.mQ[3], 16)); + +        //test case for nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) fn. +        res_nlerp = nlerp(value1, quat1, quat2); +        ensure("4. LLQuaternion nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) failed", +                                        is_approx_equal_fraction(0.314306f, res_nlerp.mQ[0], 16) && +                                        is_approx_equal_fraction(0.116157f, res_nlerp.mQ[1], 16) && +                                        is_approx_equal_fraction(0.283559f, res_nlerp.mQ[2], 16) && +                                        is_approx_equal_fraction(0.898506f, res_nlerp.mQ[3], 16)); + +        //test case for nlerp(F32 t, const LLQuaternion &q) fn. +        res_slerp = slerp(value1, quat1); +        ensure("5. LLQuaternion slerp(F32 t, const LLQuaternion &q) failed", +                                        is_approx_equal_fraction(1.0f, res_slerp.mQ[0], 16) && +                                        is_approx_equal_fraction(2.0f, res_slerp.mQ[1], 16) && +                                        is_approx_equal_fraction(4.0000f, res_slerp.mQ[2], 16) && +                                        is_approx_equal_fraction(1.000f, res_slerp.mQ[3], 16)); + +        LLQuaternion quat3(2.0f, 1.0f, 5.5f, 10.5f); +        LLQuaternion res_nlerp1; +        value1 = 100.0f; +        res_nlerp1 = nlerp(value1, quat3); +        ensure("6. LLQuaternion nlerp(F32 t, const LLQuaternion &q)  failed", +                                        is_approx_equal_fraction(0.268245f, res_nlerp1.mQ[0], 16) &&                                        is_approx_equal_fraction(0.134122f, res_nlerp1.mQ[1], 2) && +                                        is_approx_equal_fraction(0.737673f, res_nlerp1.mQ[2], 16) && +                                        is_approx_equal_fraction(0.604892f, res_nlerp1.mQ[3], 16)); + +        //test case for lerp(F32 t, const LLQuaternion &q) fn. +        res_lerp = lerp(value1, quat2); +        ensure("7. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed", +                                        is_approx_equal_fraction(0.404867f, res_lerp.mQ[0], 16) && +                                        is_approx_equal_fraction(0.303650f, res_lerp.mQ[1], 16) && +                                        is_approx_equal_fraction(0.657909f, res_lerp.mQ[2], 16) && +                                        is_approx_equal_fraction(0.557704f, res_lerp.mQ[3], 16)); + +    } + +    template<> template<> +    void llquat_test_object_t::test<9>() +    { +        //test case for LLQuaternion operator*(const LLQuaternion &a, const LLQuaternion &b) fn +        LLQuaternion quat1(1.0f, 2.5f, 3.5f, 5.5f); +        LLQuaternion quat2(4.0f, 3.0f, 5.0f, 1.0f); +        LLQuaternion result = quat1 *  quat2; +        ensure("1. LLQuaternion Operator* failed", (21.0f == result.mQ[0]) && +                                            (10.0f == result.mQ[1]) && +                                            (38.0f == result.mQ[2]) && +                                            (-23.5f == result.mQ[3])); + +        LLQuaternion quat3(2341.340f, 2352.345f, 233.25f, 7645.5f); +        LLQuaternion quat4(674.067f, 893.0897f, 578.0f, 231.0f); +        result = quat3 * quat4; +        ensure("2. LLQuaternion Operator* failed", (4543086.5f == result.mQ[0]) && +                                            (8567578.0f == result.mQ[1]) && +                                            (3967591.25f == result.mQ[2]) && +                                            is_approx_equal(-2047783.25f, result.mQ[3])); + +        //inline LLQuaternion operator+(const LLQuaternion &a, const LLQuaternion &b)fn. +        result = quat1 + quat2; +        ensure("3. LLQuaternion operator+ failed", (5.0f == result.mQ[0]) && +                                            (5.5f == result.mQ[1]) && +                                            (8.5f == result.mQ[2]) && +                                            (6.5f == result.mQ[3])); + +        result = quat3 + quat4; +        ensure( +            "4. LLQuaternion operator+ failed", +            is_approx_equal(3015.407227f, result.mQ[0]) && +            is_approx_equal(3245.434570f, result.mQ[1]) && +            (811.25f == result.mQ[2]) && +            (7876.5f == result.mQ[3])); + +        //inline LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) fn +        result = quat1 - quat2; +        ensure( +            "5. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed", +            (-3.0f == result.mQ[0]) && +            (-0.5f == result.mQ[1]) && +            (-1.5f == result.mQ[2]) && +            (4.5f == result.mQ[3])); + +        result = quat3 - quat4; +        ensure( +            "6. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed", +            is_approx_equal(1667.273071f, result.mQ[0]) && +            is_approx_equal(1459.255249f, result.mQ[1]) && +            (-344.75f == result.mQ[2]) && +            (7414.50f == result.mQ[3])); +    } + +    //test case for LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) fn. +    template<> template<> +    void llquat_test_object_t::test<10>() +    { +        LLVector4 vect(12.0f, 5.0f, 60.0f, 75.1f); +        LLQuaternion quat(2323.034f, 23.5f, 673.23f, 57667.5f); +        LLVector4 result = vect * quat; +        ensure( +            "1. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed", +            is_approx_equal(39928406016.0f, result.mV[0]) && +            // gcc on x86 actually gives us more precision than we were expecting, verified with -ffloat-store - we forgive this +            (1457802240.0f >= result.mV[1]) && // gcc+x86+linux +            (1457800960.0f <= result.mV[1]) && // elsewhere +            is_approx_equal(200580612096.0f, result.mV[2]) && +            (75.099998f == result.mV[3])); + +        LLVector4 vect1(22.0f, 45.0f, 40.0f, 78.1f); +        LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f); +        result = vect1 * quat1; +        ensure( +            "2. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed", +            is_approx_equal(-58153.5390f, result.mV[0]) && +            (183787.8125f == result.mV[1]) && +            (116864.164063f == result.mV[2]) && +            (78.099998f == result.mV[3])); +    } + +    //test case for LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) fn. +    template<> template<> +    void llquat_test_object_t::test<11>() +    { +        LLVector3 vect(12.0f, 5.0f, 60.0f); +        LLQuaternion quat(23.5f, 6.5f, 3.23f, 56.5f); +        LLVector3 result = vect * quat; +        ensure( +            "1. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed", +            is_approx_equal(97182.953125f,result.mV[0]) && +            is_approx_equal(-135405.640625f, result.mV[1]) && +            is_approx_equal(162986.140f, result.mV[2])); + +        LLVector3 vect1(5.0f, 40.0f, 78.1f); +        LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f); +        result = vect1 * quat1; +        ensure( +            "2. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed", +            is_approx_equal(33217.703f, result.mV[0]) && +            is_approx_equal(295383.8125f, result.mV[1]) && +            is_approx_equal(84718.140f, result.mV[2])); +    } + +    //test case for LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) fn. +    template<> template<> +    void llquat_test_object_t::test<12>() +    { +        LLVector3d vect(-2.0f, 5.0f, -6.0f); +        LLQuaternion quat(-3.5f, 4.5f, 3.5f, 6.5f); +        LLVector3d result = vect * quat; +        ensure( +            "1. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed ", +            (-633.0f == result.mdV[0]) && +            (-300.0f == result.mdV[1]) && +            (-36.0f == result.mdV[2])); + +        LLVector3d vect1(5.0f, -4.5f, 8.21f); +        LLQuaternion quat1(2.0f, 4.5f, -7.2f, 9.5f); +        result = vect1 * quat1; +        ensure( +            "2. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed", +            is_approx_equal_fraction(-120.29f, (F32) result.mdV[0], 8) && +            is_approx_equal_fraction(-1683.958f, (F32) result.mdV[1], 8) && +            is_approx_equal_fraction(516.56f, (F32) result.mdV[2], 8)); + +        LLVector3d vect2(2.0f, 3.5f, 1.1f); +        LLQuaternion quat2(1.0f, 4.0f, 2.0f, 5.0f); +        result = vect2 * quat2; +        ensure( +            "3. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed", +            is_approx_equal_fraction(18.400001f, (F32) result.mdV[0], 8) && +            is_approx_equal_fraction(188.6f, (F32) result.mdV[1], 8) && +            is_approx_equal_fraction(32.20f, (F32) result.mdV[2], 8)); +    } + +    //test case for inline LLQuaternion operator-(const LLQuaternion &a) fn. +    template<> template<> +    void llquat_test_object_t::test<13>() +    { +        LLQuaternion quat(23.5f, 34.5f, 16723.4f, 324.7f); +        LLQuaternion result = -quat; +        ensure( +            "1. LLQuaternion operator-(const LLQuaternion &a) failed", +            (-23.5f == result.mQ[0]) && +            (-34.5f == result.mQ[1]) && +            (-16723.4f == result.mQ[2]) && +            (-324.7f == result.mQ[3])); + +        LLQuaternion quat1(-3.5f, -34.5f, -16.4f, -154.7f); +        result = -quat1; +        ensure( +            "2. LLQuaternion operator-(const LLQuaternion &a) failed.", +            (3.5f == result.mQ[0]) && +            (34.5f == result.mQ[1]) && +            (16.4f == result.mQ[2]) && +            (154.7f == result.mQ[3])); +    } + +    //test case for inline LLQuaternion operator*(F32 a, const LLQuaternion &q) and +    //inline LLQuaternion operator*(F32 a, const LLQuaternion &q) fns. +    template<> template<> +    void llquat_test_object_t::test<14>() +    { +        LLQuaternion quat_value(9.0f, 8.0f, 7.0f, 6.0f); +        F32 a =3.5f; +        LLQuaternion result = a * quat_value; +        LLQuaternion result1 = quat_value * a; + +        ensure( +            "1. LLQuaternion operator* failed", +            (result.mQ[0] == result1.mQ[0]) && +            (result.mQ[1] == result1.mQ[1]) && +            (result.mQ[2] == result1.mQ[2]) && +            (result.mQ[3] == result1.mQ[3])); + + +        LLQuaternion quat_val(9454.0f, 43568.3450f, 456343247.0343f, 2346.03434f); +        a =-3324.3445f; +        result = a * quat_val; +        result1 = quat_val * a; + +        ensure( +            "2. LLQuaternion operator* failed", +            (result.mQ[0] == result1.mQ[0]) && +            (result.mQ[1] == result1.mQ[1]) && +            (result.mQ[2] == result1.mQ[2]) && +            (result.mQ[3] == result1.mQ[3])); +    } + +    template<> template<> +    void llquat_test_object_t::test<15>() +    { +        // test cases for inline LLQuaternion operator~(const LLQuaternion &a) +        LLQuaternion quat_val(2323.634f, -43535.4f, 3455.88f, -32232.45f); +        LLQuaternion result = ~quat_val; +        ensure( +            "1. LLQuaternion operator~(const LLQuaternion &a) failed ", +            (-2323.634f == result.mQ[0]) && +            (43535.4f == result.mQ[1]) && +            (-3455.88f == result.mQ[2]) && +            (-32232.45f == result.mQ[3])); + +        //test case for inline bool LLQuaternion::operator==(const LLQuaternion &b) const +        LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f); +        LLQuaternion quat_val2(2323.634f, -43535.4f, 3455.88f, -32232.45f); +        ensure( +            "2. LLQuaternion::operator==(const LLQuaternion &b) failed", +            quat_val1 == quat_val2); +    } + +    template<> template<> +    void llquat_test_object_t::test<16>() +    { +        //test case for inline bool LLQuaternion::operator!=(const LLQuaternion &b) const +        LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f); +        LLQuaternion quat_val2(0, -43535.4f, 3455.88f, -32232.45f); +        ensure("LLQuaternion::operator!=(const LLQuaternion &b) failed", quat_val1 != quat_val2); +    } + +    template<> template<> +    void llquat_test_object_t::test<17>() +    { +        //test case for LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) +        F32 x = 2.0f; +        F32 y = 1.0f; +        F32 z = 3.0f; + +        LLQuaternion result = mayaQ(x, y, z, LLQuaternion::XYZ); +        ensure( +            "1. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ", +            is_approx_equal_fraction(0.0172174f, result.mQ[0], 16) && +            is_approx_equal_fraction(0.009179f, result.mQ[1], 16) && +            is_approx_equal_fraction(0.026020f, result.mQ[2], 16) && +            is_approx_equal_fraction(0.999471f, result.mQ[3], 16)); + +        LLQuaternion result1 = mayaQ(x, y, z, LLQuaternion::YZX); +        ensure( +            "2. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ", +            is_approx_equal_fraction(0.017217f, result1.mQ[0], 16) && +            is_approx_equal_fraction(0.008265f, result1.mQ[1], 16) && +            is_approx_equal_fraction(0.026324f, result1.mQ[2], 16) && +            is_approx_equal_fraction(0.999471f, result1.mQ[3], 16)); + +        LLQuaternion result2 = mayaQ(x, y, z, LLQuaternion::ZXY); +        ensure( +            "3. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZXY", +            is_approx_equal_fraction(0.017674f, result2.mQ[0], 16) && +            is_approx_equal_fraction(0.008265f, result2.mQ[1], 16) && +            is_approx_equal_fraction(0.026020f, result2.mQ[2], 16) && +            is_approx_equal_fraction(0.999471f, result2.mQ[3], 16)); + +        LLQuaternion result3 = mayaQ(x, y, z, LLQuaternion::XZY); +        ensure( +            "4. TLLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XZY", +            is_approx_equal_fraction(0.017674f, result3.mQ[0], 16) && +            is_approx_equal_fraction(0.009179f, result3.mQ[1], 16) && +            is_approx_equal_fraction(0.026020f, result3.mQ[2], 16) && +            is_approx_equal_fraction(0.999463f, result3.mQ[3], 16)); + +        LLQuaternion result4 = mayaQ(x, y, z, LLQuaternion::YXZ); +        ensure( +            "5. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for YXZ", +            is_approx_equal_fraction(0.017217f, result4.mQ[0], 16) && +            is_approx_equal_fraction(0.009179f, result4.mQ[1], 16) && +            is_approx_equal_fraction(0.026324f, result4.mQ[2], 16) && +            is_approx_equal_fraction(0.999463f, result4.mQ[3], 16)); + +        LLQuaternion result5 = mayaQ(x, y, z, LLQuaternion::ZYX); +        ensure( +            "6. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZYX", +            is_approx_equal_fraction(0.017674f, result5.mQ[0], 16) && +            is_approx_equal_fraction(0.008265f, result5.mQ[1], 16) && +            is_approx_equal_fraction(0.026324f, result5.mQ[2], 16) && +            is_approx_equal_fraction(0.999463f, result5.mQ[3], 16)); +    } + +    template<> template<> +    void llquat_test_object_t::test<18>() +    { +        // test case for friend std::ostream& operator<<(std::ostream &s, const LLQuaternion &a) fn +        LLQuaternion a(1.0f, 1.0f, 1.0f, 1.0f); +        std::ostringstream result_value; +        result_value << a; +        ensure_equals("1. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }"); + +        LLQuaternion b(-31.034f, 231.2340f, 3451.344320f, -341.0f); +        std::ostringstream result_value1; +        result_value1 << b; +        ensure_equals("2. Operator << failed", result_value1.str(), "{ -31.034, 231.234, 3451.34, -341 }"); + +        LLQuaternion c(1.0f, 2.2f, 3.3f, 4.4f); +        result_value << c; +        ensure_equals("3. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }{ 1, 2.2, 3.3, 4.4 }"); + +    } + +    template<> template<> +    void llquat_test_object_t::test<19>() +    { +        //test case for const char *OrderToString( const LLQuaternion::Order order ) fn +        const char* result = OrderToString(LLQuaternion::XYZ); +        ensure("1. OrderToString failed for XYZ",  (0 == strcmp("XYZ", result))); + +        result = OrderToString(LLQuaternion::YZX); +        ensure("2. OrderToString failed for YZX",  (0 == strcmp("YZX", result))); + +        result = OrderToString(LLQuaternion::ZXY); +        ensure( +            "3. OrderToString failed for ZXY", +            (0 == strcmp("ZXY", result)) && +            (0 != strcmp("XYZ", result)) && +            (0 != strcmp("YXZ", result)) && +            (0 != strcmp("ZYX", result)) && +            (0 != strcmp("XYZ", result))); + +        result = OrderToString(LLQuaternion::XZY); +        ensure("4. OrderToString failed for XZY",  (0 == strcmp("XZY", result))); + +        result = OrderToString(LLQuaternion::ZYX); +        ensure("5. OrderToString failed for ZYX",  (0 == strcmp("ZYX", result))); + +        result = OrderToString(LLQuaternion::YXZ); +        ensure("6.OrderToString failed for YXZ",  (0 == strcmp("YXZ", result))); +    } + +    template<> template<> +    void llquat_test_object_t::test<20>() +    { +        //test case for LLQuaternion::Order StringToOrder( const char *str ) fn +        int result = StringToOrder("XYZ"); +        ensure("1. LLQuaternion::Order StringToOrder(const char *str ) failed for XYZ", 0 == result); + +        result = StringToOrder("YZX"); +        ensure("2. LLQuaternion::Order StringToOrder(const char *str) failed for YZX", 1 == result); + +        result = StringToOrder("ZXY"); +        ensure("3. LLQuaternion::Order StringToOrder(const char *str) failed for ZXY", 2 == result); + +        result = StringToOrder("XZY"); +        ensure("4. LLQuaternion::Order StringToOrder(const char *str) failed for XZY", 3 == result); + +        result = StringToOrder("YXZ"); +        ensure("5. LLQuaternion::Order StringToOrder(const char *str) failed for YXZ", 4 == result); + +        result = StringToOrder("ZYX"); +        ensure("6. LLQuaternion::Order StringToOrder(const char *str) failed for  ZYX", 5 == result); + +    } + +    template<> template<> +    void llquat_test_object_t::test<21>() +    { +        //void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const fn +        F32 angle_value = 90.0f; +        LLVector3 vect(12.0f, 4.0f, 1.0f); +        LLQuaternion llquat(angle_value, vect); +        llquat.getAngleAxis(&angle_value, vect); +        ensure( +            "LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) failed", +            is_approx_equal_fraction(2.035406f, angle_value, 16) && +            is_approx_equal_fraction(0.315244f, vect.mV[1], 16) && +            is_approx_equal_fraction(0.078811f, vect.mV[2], 16) && +            is_approx_equal_fraction(0.945733f, vect.mV[0], 16)); +    } + +    template<> template<> +    void llquat_test_object_t::test<22>() +    { +        //test case for void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const fn +        F32 roll = -12.0f; +        F32 pitch = -22.43f; +        F32 yaw = 11.0f; + +        LLQuaternion llquat; +        llquat.getEulerAngles(&roll, &pitch, &yaw); +        ensure( +            "LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) failed", +            is_approx_equal(0.000f, llquat.mQ[0]) && +            is_approx_equal(0.000f, llquat.mQ[1]) && +            is_approx_equal(0.000f, llquat.mQ[2]) && +            is_approx_equal(1.000f, llquat.mQ[3])); +    }  } diff --git a/indra/llmath/tests/llrect_test.cpp b/indra/llmath/tests/llrect_test.cpp index d740173e69..ca042a60d7 100644 --- a/indra/llmath/tests/llrect_test.cpp +++ b/indra/llmath/tests/llrect_test.cpp @@ -3,25 +3,25 @@   * @author Martin Reddy   * @date   2009-06-25   * @brief  Test for llrect.cpp. - *  + *   * $LicenseInfo:firstyear=2009&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -32,495 +32,495 @@  namespace tut  { -	struct LLRectData -	{ -	}; +    struct LLRectData +    { +    }; -	typedef test_group<LLRectData> factory; -	typedef factory::object object; +    typedef test_group<LLRectData> factory; +    typedef factory::object object;  }  namespace  { -	tut::factory llrect_test_factory("LLRect"); +    tut::factory llrect_test_factory("LLRect");  }  namespace tut  { -	template<> template<> -	void object::test<1>() -	{	 -		// -		// test the LLRect default constructor -		// -		 -		LLSD zero; -		zero.append(0);	zero.append(0); zero.append(0); zero.append(0); -		 -		// default constructor -		LLRect rect1; -		ensure_equals("Empty rect", rect1.getValue(), zero); -		ensure_equals("Empty rect left", rect1.mLeft, 0); -		ensure_equals("Empty rect top", rect1.mTop, 0); -		ensure_equals("Empty rect right", rect1.mRight, 0); -		ensure_equals("Empty rect bottom", rect1.mBottom, 0); -		ensure_equals("Empty rect width", rect1.getWidth(), 0); -		ensure_equals("Empty rect height", rect1.getHeight(), 0); -		ensure_equals("Empty rect centerx", rect1.getCenterX(), 0); -		ensure_equals("Empty rect centery", rect1.getCenterY(), 0); -	} -	 -	template<> template<> -	void object::test<2>() -	{	 -		// -		// test the LLRectf default constructor -		// -		 -		LLSD zerof; -		zerof.append(0.0f); zerof.append(0.0f); zerof.append(0.0f); zerof.append(0.0f); - -		LLRectf rect2; -		ensure_equals("Empty rectf", rect2.getValue(), zerof); -		ensure_equals("Empty rectf left", rect2.mLeft, 0.0f); -		ensure_equals("Empty rectf top", rect2.mTop, 0.0f); -		ensure_equals("Empty rectf right", rect2.mRight, 0.0f); -		ensure_equals("Empty rectf bottom", rect2.mBottom, 0.0f); -		ensure_equals("Empty rectf width", rect2.getWidth(), 0.0f); -		ensure_equals("Empty rectf height", rect2.getHeight(), 0.0f); -		ensure_equals("Empty rectf centerx", rect2.getCenterX(), 0.0f); -		ensure_equals("Empty rectf centery", rect2.getCenterY(), 0.0f); -	} - -	template<> template<> -	void object::test<3>() -	{	 -		// -		// test the LLRect constructor from another LLRect -		//	 -		 -		LLRect rect3(LLRect(1, 6, 7, 2)); -		ensure_equals("Default rect left", rect3.mLeft, 1); -		ensure_equals("Default rect top", rect3.mTop, 6); -		ensure_equals("Default rect right", rect3.mRight, 7); -		ensure_equals("Default rect bottom", rect3.mBottom, 2); -		ensure_equals("Default rect width", rect3.getWidth(), 6); -		ensure_equals("Default rect height", rect3.getHeight(), 4); -		ensure_equals("Default rect centerx", rect3.getCenterX(), 4); -		ensure_equals("Default rect centery", rect3.getCenterY(), 4); -	} - -	template<> template<> -	void object::test<4>() -	{	 -		// -		// test the LLRectf four-float constructor -		//	 -		 -		LLRectf rect4(1.0f, 5.0f, 6.0f, 2.0f); -		ensure_equals("Default rectf left", rect4.mLeft, 1.0f); -		ensure_equals("Default rectf top", rect4.mTop, 5.0f); -		ensure_equals("Default rectf right", rect4.mRight, 6.0f); -		ensure_equals("Default rectf bottom", rect4.mBottom, 2.0f); -		ensure_equals("Default rectf width", rect4.getWidth(), 5.0f); -		ensure_equals("Default rectf height", rect4.getHeight(), 3.0f); -		ensure_equals("Default rectf centerx", rect4.getCenterX(), 3.5f); -		ensure_equals("Default rectf centery", rect4.getCenterY(), 3.5f); -	} - -	template<> template<> -	void object::test<5>() -	{	 -		// -		// test the LLRectf LLSD constructor -		// - -		LLSD array; -		array.append(-1.0f); array.append(0.0f); array.append(0.0f); array.append(-1.0f); -		LLRectf rect5(array); -		ensure_equals("LLSD rectf left", rect5.mLeft, -1.0f); -		ensure_equals("LLSD rectf top", rect5.mTop, 0.0f); -		ensure_equals("LLSD rectf right", rect5.mRight, 0.0f); -		ensure_equals("LLSD rectf bottom", rect5.mBottom, -1.0f); -		ensure_equals("LLSD rectf width", rect5.getWidth(), 1.0f); -		ensure_equals("LLSD rectf height", rect5.getHeight(), 1.0f); -		ensure_equals("LLSD rectf centerx", rect5.getCenterX(), -0.5f); -		ensure_equals("LLSD rectf centery", rect5.getCenterY(), -0.5f);		 -	} -	 -	template<> template<> -	void object::test<6>() -	{	 -		// -		// test directly setting the member variables for dimensions -		// -		 -		LLRectf rectf; - -		rectf.mLeft = -1.0f; -		rectf.mTop = 1.0f; -		rectf.mRight = 1.0f; -		rectf.mBottom = -1.0f; -		ensure_equals("Member-set rectf left", rectf.mLeft, -1.0f); -		ensure_equals("Member-set rectf top", rectf.mTop, 1.0f); -		ensure_equals("Member-set rectf right", rectf.mRight, 1.0f); -		ensure_equals("Member-set rectf bottom", rectf.mBottom, -1.0f); -		ensure_equals("Member-set rectf width", rectf.getWidth(), 2.0f); -		ensure_equals("Member-set rectf height", rectf.getHeight(), 2.0f); -		ensure_equals("Member-set rectf centerx", rectf.getCenterX(), 0.0f); -		ensure_equals("Member-set rectf centery", rectf.getCenterY(), 0.0f); -	} -		 -	template<> template<> -	void object::test<7>() -	{	 -		// -		// test the setValue() method -		// -			 -		LLRectf rectf; -		 -		LLSD array; -		array.append(-1.0f); array.append(0.0f); array.append(0.0f); array.append(-1.0f); -		rectf.setValue(array); -		ensure_equals("setValue() rectf left", rectf.mLeft, -1.0f); -		ensure_equals("setValue() rectf top", rectf.mTop, 0.0f); -		ensure_equals("setValue() rectf right", rectf.mRight, 0.0f); -		ensure_equals("setValue() rectf bottom", rectf.mBottom, -1.0f); -		ensure_equals("setValue() rectf width", rectf.getWidth(), 1.0f); -		ensure_equals("setValue() rectf height", rectf.getHeight(), 1.0f); -		ensure_equals("setValue() rectf centerx", rectf.getCenterX(), -0.5f); -		ensure_equals("setValue() rectf centery", rectf.getCenterY(), -0.5f); -	} -		 -	template<> template<> -	void object::test<8>() -	{	 -		// -		// test the set() method -		// -		 -		LLRect rect; -		 -		rect.set(10, 90, 70, 10); -		ensure_equals("set() rectf left", rect.mLeft, 10); -		ensure_equals("set() rectf top", rect.mTop, 90); -		ensure_equals("set() rectf right", rect.mRight, 70); -		ensure_equals("set() rectf bottom", rect.mBottom, 10); -		ensure_equals("set() rectf width", rect.getWidth(), 60); -		ensure_equals("set() rectf height", rect.getHeight(), 80); -		ensure_equals("set() rectf centerx", rect.getCenterX(), 40); -		ensure_equals("set() rectf centery", rect.getCenterY(), 50); -	} - -	template<> template<> -	void object::test<9>() -	{	 -		// -		// test the setOriginAndSize() method -		// -		 -		LLRectf rectf; -		 -		rectf.setOriginAndSize(0.0f, 0.0f, 2.0f, 1.0f); -		ensure_equals("setOriginAndSize() rectf left", rectf.mLeft, 0.0f); -		ensure_equals("setOriginAndSize() rectf top", rectf.mTop, 1.0f); -		ensure_equals("setOriginAndSize() rectf right", rectf.mRight, 2.0f); -		ensure_equals("setOriginAndSize() rectf bottom", rectf.mBottom, 0.0f); -		ensure_equals("setOriginAndSize() rectf width", rectf.getWidth(), 2.0f); -		ensure_equals("setOriginAndSize() rectf height", rectf.getHeight(), 1.0f); -		ensure_equals("setOriginAndSize() rectf centerx", rectf.getCenterX(), 1.0f); -		ensure_equals("setOriginAndSize() rectf centery", rectf.getCenterY(), 0.5f);	 -	} -	 -	template<> template<> -	void object::test<10>() -	{	 -		// -		// test the setLeftTopAndSize() method -		// -		 -		LLRectf rectf; - -		rectf.setLeftTopAndSize(0.0f, 0.0f, 2.0f, 1.0f); -		ensure_equals("setLeftTopAndSize() rectf left", rectf.mLeft, 0.0f); -		ensure_equals("setLeftTopAndSize() rectf top", rectf.mTop, 0.0f); -		ensure_equals("setLeftTopAndSize() rectf right", rectf.mRight, 2.0f); -		ensure_equals("setLeftTopAndSize() rectf bottom", rectf.mBottom, -1.0f); -		ensure_equals("setLeftTopAndSize() rectf width", rectf.getWidth(), 2.0f); -		ensure_equals("setLeftTopAndSize() rectf height", rectf.getHeight(), 1.0f); -		ensure_equals("setLeftTopAndSize() rectf centerx", rectf.getCenterX(), 1.0f); -		ensure_equals("setLeftTopAndSize() rectf centery", rectf.getCenterY(), -0.5f); -	} - -	template<> template<> -	void object::test<11>() -	{	 -		// -		// test the setCenterAndSize() method -		// -		 -		LLRectf rectf; -		 -		rectf.setCenterAndSize(0.0f, 0.0f, 2.0f, 1.0f); -		ensure_equals("setCenterAndSize() rectf left", rectf.mLeft, -1.0f); -		ensure_equals("setCenterAndSize() rectf top", rectf.mTop, 0.5f); -		ensure_equals("setCenterAndSize() rectf right", rectf.mRight, 1.0f); -		ensure_equals("setCenterAndSize() rectf bottom", rectf.mBottom, -0.5f); -		ensure_equals("setCenterAndSize() rectf width", rectf.getWidth(), 2.0f); -		ensure_equals("setCenterAndSize() rectf height", rectf.getHeight(), 1.0f); -		ensure_equals("setCenterAndSize() rectf centerx", rectf.getCenterX(), 0.0f); -		ensure_equals("setCenterAndSize() rectf centery", rectf.getCenterY(), 0.0f); -	} - -	template<> template<> -	void object::test<12>() -	{	 -		// -		// test the validity checking method -		// -		 -		LLRectf rectf; - -		rectf.set(-1.0f, 1.0f, 1.0f, -1.0f); -		ensure("BBox is valid", rectf.isValid()); - -		rectf.mLeft = 2.0f; -		ensure("BBox is not valid", ! rectf.isValid()); - -		rectf.makeValid(); -		ensure("BBox forced valid", rectf.isValid()); - -		rectf.set(-1.0f, -1.0f, -1.0f, -1.0f); -		ensure("BBox(0,0,0,0) is valid", rectf.isValid()); -	} - -	template<> template<> -	void object::test<13>() -	{	 -		// -		// test the null checking methods -		// -		 -		LLRectf rectf; -		 -		rectf.set(-1.0f, 1.0f, 1.0f, -1.0f); -		ensure("BBox is not Null", ! rectf.isEmpty()); -		ensure("BBox notNull", rectf.notEmpty()); -		 -		rectf.mLeft = 2.0f; -		rectf.makeValid(); -		ensure("BBox is now Null", rectf.isEmpty()); -		 -		rectf.set(-1.0f, -1.0f, -1.0f, -1.0f); -		ensure("BBox(0,0,0,0) is Null", rectf.isEmpty()); -	} -		 -	template<> template<> -	void object::test<14>() -	{	 -		// -		// test the (in)equality operators -		// -		 -		LLRectf rect1, rect2; - -		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); -		rect2.set(-1.0f, 0.9f, 1.0f, -1.0f); - -		ensure("rect1 == rect2 (false)", ! (rect1 == rect2)); -		ensure("rect1 != rect2 (true)", rect1 != rect2); - -		ensure("rect1 == rect1 (true)", rect1 == rect1); -		ensure("rect1 != rect1 (false)", ! (rect1 != rect1)); -	} -	 -	template<> template<> -	void object::test<15>() -	{	 -		// -		// test the copy constructor -		// -		 -		LLRectf rect1, rect2(rect1); - -		ensure("rect1 == rect2 (true)", rect1 == rect2); -		ensure("rect1 != rect2 (false)", ! (rect1 != rect2)); -	} - -	template<> template<> -	void object::test<16>() -	{	 -		// -		// test the translate() method -		// -		 -		LLRectf rect1(-1.0f, 1.0f, 1.0f, -1.0f); -		LLRectf rect2(rect1); - -		rect1.translate(0.0f, 0.0f); - -		ensure("translate(0, 0)", rect1 == rect2); - -		rect1.translate(100.0f, 100.0f); -		rect1.translate(-100.0f, -100.0f); - -		ensure("translate(100, 100) + translate(-100, -100)", rect1 == rect2); - -		rect1.translate(10.0f, 0.0f); -		rect2.set(9.0f, 1.0f, 11.0f, -1.0f); -		ensure("translate(10, 0)", rect1 == rect2); - -		rect1.translate(0.0f, 10.0f); -		rect2.set(9.0f, 11.0f, 11.0f, 9.0f); -		ensure("translate(0, 10)", rect1 == rect2); - -		rect1.translate(-10.0f, -10.0f); -		rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); -		ensure("translate(-10, -10)", rect1 == rect2); -	} - -	template<> template<> -	void object::test<17>() -	{	 -		// -		// test the stretch() method -		// -		 -		LLRectf rect1(-1.0f, 1.0f, 1.0f, -1.0f); -		LLRectf rect2(rect1); -		 -		rect1.stretch(0.0f); -		ensure("stretch(0)", rect1 == rect2); -		 -		rect1.stretch(0.0f, 0.0f); -		ensure("stretch(0, 0)", rect1 == rect2); -		 -		rect1.stretch(10.0f); -		rect1.stretch(-10.0f); -		ensure("stretch(10) + stretch(-10)", rect1 == rect2); -		 -		rect1.stretch(2.0f, 1.0f); -		rect2.set(-3.0f, 2.0f, 3.0f, -2.0f); -		ensure("stretch(2, 1)", rect1 == rect2); -	} -	 -	 -	template<> template<> -	void object::test<18>() -	{	 -		// -		// test the unionWith() method -		// -		 -		LLRectf rect1, rect2, rect3; - -		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); -		rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); -		rect3 = rect1; -		rect3.unionWith(rect2); -		ensure_equals("union with self", rect3, rect1); - -		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); -		rect2.set(-2.0f, 2.0f, 0.0f, 0.0f); -		rect3 = rect1; -		rect3.unionWith(rect2); -		ensure_equals("union - overlap", rect3, LLRectf(-2.0f, 2.0f, 1.0f, -1.0f)); -		 -		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); -		rect2.set(5.0f, 10.0f, 10.0f, 5.0f); -		rect3 = rect1; -		rect3.unionWith(rect2); -		ensure_equals("union - no overlap", rect3, LLRectf(-1.0f, 10.0f, 10.0f, -1.0f)); -	} - -	template<> template<> -	void object::test<19>() -	{	 -		// -		// test the intersectWith() methods -		// -		 -		LLRectf rect1, rect2, rect3; -		 -		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); -		rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); -		rect3 = rect1; -		rect3.intersectWith(rect2); -		ensure_equals("intersect with self", rect3, rect1); -		 -		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); -		rect2.set(-2.0f, 2.0f, 0.0f, 0.0f); -		rect3 = rect1; -		rect3.intersectWith(rect2); -		ensure_equals("intersect - overlap", rect3, LLRectf(-1.0f, 1.0f, 0.0f, 0.0f)); -		 -		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); -		rect2.set(5.0f, 10.0f, 10.0f, 5.0f); -		rect3 = rect1; -		rect3.intersectWith(rect2); -		ensure("intersect - no overlap", rect3.isEmpty()); -	} -		 -	template<> template<> -	void object::test<20>() -	{ -		// -		// test the pointInRect() method -		// -		 -		LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); - -		ensure("(0,0) not in rect", rect.pointInRect(0.0f, 0.0f) == FALSE); -		ensure("(2,2) in rect", rect.pointInRect(2.0f, 2.0f) == TRUE); -		ensure("(1,1) in rect", rect.pointInRect(1.0f, 1.0f) == TRUE); -		ensure("(3,3) not in rect", rect.pointInRect(3.0f, 3.0f) == FALSE); -		ensure("(2.999,2.999) in rect", rect.pointInRect(2.999f, 2.999f) == TRUE); -		ensure("(2.999,3.0) not in rect", rect.pointInRect(2.999f, 3.0f) == FALSE); -		ensure("(3.0,2.999) not in rect", rect.pointInRect(3.0f, 2.999f) == FALSE); -	} - -	template<> template<> -	void object::test<21>() -	{ -		// -		// test the localPointInRect() method -		// -		 -		LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); -		 -		ensure("(0,0) in local rect", rect.localPointInRect(0.0f, 0.0f) == TRUE); -		ensure("(-0.0001,-0.0001) not in local rect", rect.localPointInRect(-0.0001f, -0.001f) == FALSE); -		ensure("(1,1) in local rect", rect.localPointInRect(1.0f, 1.0f) == TRUE); -		ensure("(2,2) not in local rect", rect.localPointInRect(2.0f, 2.0f) == FALSE); -		ensure("(1.999,1.999) in local rect", rect.localPointInRect(1.999f, 1.999f) == TRUE); -		ensure("(1.999,2.0) not in local rect", rect.localPointInRect(1.999f, 2.0f) == FALSE); -		ensure("(2.0,1.999) not in local rect", rect.localPointInRect(2.0f, 1.999f) == FALSE); -	} -	 -	template<> template<> -	void object::test<22>() -	{ -		// -		// test the clampPointToRect() method -		// - -		LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); -		F32 x, y; - -		x = 2.0f; y = 2.0f; -		rect.clampPointToRect(x, y); -		ensure_equals("clamp x-coord within rect", x, 2.0f); -		ensure_equals("clamp y-coord within rect", y, 2.0f); - -		x = -100.0f; y = 100.0f; -		rect.clampPointToRect(x, y); -		ensure_equals("clamp x-coord outside rect", x, 1.0f); -		ensure_equals("clamp y-coord outside rect", y, 3.0f); - -		x = 3.0f; y = 1.0f; -		rect.clampPointToRect(x, y); -		ensure_equals("clamp x-coord edge rect", x, 3.0f); -		ensure_equals("clamp y-coord edge rect", y, 1.0f); -	} +    template<> template<> +    void object::test<1>() +    { +        // +        // test the LLRect default constructor +        // + +        LLSD zero; +        zero.append(0); zero.append(0); zero.append(0); zero.append(0); + +        // default constructor +        LLRect rect1; +        ensure_equals("Empty rect", rect1.getValue(), zero); +        ensure_equals("Empty rect left", rect1.mLeft, 0); +        ensure_equals("Empty rect top", rect1.mTop, 0); +        ensure_equals("Empty rect right", rect1.mRight, 0); +        ensure_equals("Empty rect bottom", rect1.mBottom, 0); +        ensure_equals("Empty rect width", rect1.getWidth(), 0); +        ensure_equals("Empty rect height", rect1.getHeight(), 0); +        ensure_equals("Empty rect centerx", rect1.getCenterX(), 0); +        ensure_equals("Empty rect centery", rect1.getCenterY(), 0); +    } + +    template<> template<> +    void object::test<2>() +    { +        // +        // test the LLRectf default constructor +        // + +        LLSD zerof; +        zerof.append(0.0f); zerof.append(0.0f); zerof.append(0.0f); zerof.append(0.0f); + +        LLRectf rect2; +        ensure_equals("Empty rectf", rect2.getValue(), zerof); +        ensure_equals("Empty rectf left", rect2.mLeft, 0.0f); +        ensure_equals("Empty rectf top", rect2.mTop, 0.0f); +        ensure_equals("Empty rectf right", rect2.mRight, 0.0f); +        ensure_equals("Empty rectf bottom", rect2.mBottom, 0.0f); +        ensure_equals("Empty rectf width", rect2.getWidth(), 0.0f); +        ensure_equals("Empty rectf height", rect2.getHeight(), 0.0f); +        ensure_equals("Empty rectf centerx", rect2.getCenterX(), 0.0f); +        ensure_equals("Empty rectf centery", rect2.getCenterY(), 0.0f); +    } + +    template<> template<> +    void object::test<3>() +    { +        // +        // test the LLRect constructor from another LLRect +        // + +        LLRect rect3(LLRect(1, 6, 7, 2)); +        ensure_equals("Default rect left", rect3.mLeft, 1); +        ensure_equals("Default rect top", rect3.mTop, 6); +        ensure_equals("Default rect right", rect3.mRight, 7); +        ensure_equals("Default rect bottom", rect3.mBottom, 2); +        ensure_equals("Default rect width", rect3.getWidth(), 6); +        ensure_equals("Default rect height", rect3.getHeight(), 4); +        ensure_equals("Default rect centerx", rect3.getCenterX(), 4); +        ensure_equals("Default rect centery", rect3.getCenterY(), 4); +    } + +    template<> template<> +    void object::test<4>() +    { +        // +        // test the LLRectf four-float constructor +        // + +        LLRectf rect4(1.0f, 5.0f, 6.0f, 2.0f); +        ensure_equals("Default rectf left", rect4.mLeft, 1.0f); +        ensure_equals("Default rectf top", rect4.mTop, 5.0f); +        ensure_equals("Default rectf right", rect4.mRight, 6.0f); +        ensure_equals("Default rectf bottom", rect4.mBottom, 2.0f); +        ensure_equals("Default rectf width", rect4.getWidth(), 5.0f); +        ensure_equals("Default rectf height", rect4.getHeight(), 3.0f); +        ensure_equals("Default rectf centerx", rect4.getCenterX(), 3.5f); +        ensure_equals("Default rectf centery", rect4.getCenterY(), 3.5f); +    } + +    template<> template<> +    void object::test<5>() +    { +        // +        // test the LLRectf LLSD constructor +        // + +        LLSD array; +        array.append(-1.0f); array.append(0.0f); array.append(0.0f); array.append(-1.0f); +        LLRectf rect5(array); +        ensure_equals("LLSD rectf left", rect5.mLeft, -1.0f); +        ensure_equals("LLSD rectf top", rect5.mTop, 0.0f); +        ensure_equals("LLSD rectf right", rect5.mRight, 0.0f); +        ensure_equals("LLSD rectf bottom", rect5.mBottom, -1.0f); +        ensure_equals("LLSD rectf width", rect5.getWidth(), 1.0f); +        ensure_equals("LLSD rectf height", rect5.getHeight(), 1.0f); +        ensure_equals("LLSD rectf centerx", rect5.getCenterX(), -0.5f); +        ensure_equals("LLSD rectf centery", rect5.getCenterY(), -0.5f); +    } + +    template<> template<> +    void object::test<6>() +    { +        // +        // test directly setting the member variables for dimensions +        // + +        LLRectf rectf; + +        rectf.mLeft = -1.0f; +        rectf.mTop = 1.0f; +        rectf.mRight = 1.0f; +        rectf.mBottom = -1.0f; +        ensure_equals("Member-set rectf left", rectf.mLeft, -1.0f); +        ensure_equals("Member-set rectf top", rectf.mTop, 1.0f); +        ensure_equals("Member-set rectf right", rectf.mRight, 1.0f); +        ensure_equals("Member-set rectf bottom", rectf.mBottom, -1.0f); +        ensure_equals("Member-set rectf width", rectf.getWidth(), 2.0f); +        ensure_equals("Member-set rectf height", rectf.getHeight(), 2.0f); +        ensure_equals("Member-set rectf centerx", rectf.getCenterX(), 0.0f); +        ensure_equals("Member-set rectf centery", rectf.getCenterY(), 0.0f); +    } + +    template<> template<> +    void object::test<7>() +    { +        // +        // test the setValue() method +        // + +        LLRectf rectf; + +        LLSD array; +        array.append(-1.0f); array.append(0.0f); array.append(0.0f); array.append(-1.0f); +        rectf.setValue(array); +        ensure_equals("setValue() rectf left", rectf.mLeft, -1.0f); +        ensure_equals("setValue() rectf top", rectf.mTop, 0.0f); +        ensure_equals("setValue() rectf right", rectf.mRight, 0.0f); +        ensure_equals("setValue() rectf bottom", rectf.mBottom, -1.0f); +        ensure_equals("setValue() rectf width", rectf.getWidth(), 1.0f); +        ensure_equals("setValue() rectf height", rectf.getHeight(), 1.0f); +        ensure_equals("setValue() rectf centerx", rectf.getCenterX(), -0.5f); +        ensure_equals("setValue() rectf centery", rectf.getCenterY(), -0.5f); +    } + +    template<> template<> +    void object::test<8>() +    { +        // +        // test the set() method +        // + +        LLRect rect; + +        rect.set(10, 90, 70, 10); +        ensure_equals("set() rectf left", rect.mLeft, 10); +        ensure_equals("set() rectf top", rect.mTop, 90); +        ensure_equals("set() rectf right", rect.mRight, 70); +        ensure_equals("set() rectf bottom", rect.mBottom, 10); +        ensure_equals("set() rectf width", rect.getWidth(), 60); +        ensure_equals("set() rectf height", rect.getHeight(), 80); +        ensure_equals("set() rectf centerx", rect.getCenterX(), 40); +        ensure_equals("set() rectf centery", rect.getCenterY(), 50); +    } + +    template<> template<> +    void object::test<9>() +    { +        // +        // test the setOriginAndSize() method +        // + +        LLRectf rectf; + +        rectf.setOriginAndSize(0.0f, 0.0f, 2.0f, 1.0f); +        ensure_equals("setOriginAndSize() rectf left", rectf.mLeft, 0.0f); +        ensure_equals("setOriginAndSize() rectf top", rectf.mTop, 1.0f); +        ensure_equals("setOriginAndSize() rectf right", rectf.mRight, 2.0f); +        ensure_equals("setOriginAndSize() rectf bottom", rectf.mBottom, 0.0f); +        ensure_equals("setOriginAndSize() rectf width", rectf.getWidth(), 2.0f); +        ensure_equals("setOriginAndSize() rectf height", rectf.getHeight(), 1.0f); +        ensure_equals("setOriginAndSize() rectf centerx", rectf.getCenterX(), 1.0f); +        ensure_equals("setOriginAndSize() rectf centery", rectf.getCenterY(), 0.5f); +    } + +    template<> template<> +    void object::test<10>() +    { +        // +        // test the setLeftTopAndSize() method +        // + +        LLRectf rectf; + +        rectf.setLeftTopAndSize(0.0f, 0.0f, 2.0f, 1.0f); +        ensure_equals("setLeftTopAndSize() rectf left", rectf.mLeft, 0.0f); +        ensure_equals("setLeftTopAndSize() rectf top", rectf.mTop, 0.0f); +        ensure_equals("setLeftTopAndSize() rectf right", rectf.mRight, 2.0f); +        ensure_equals("setLeftTopAndSize() rectf bottom", rectf.mBottom, -1.0f); +        ensure_equals("setLeftTopAndSize() rectf width", rectf.getWidth(), 2.0f); +        ensure_equals("setLeftTopAndSize() rectf height", rectf.getHeight(), 1.0f); +        ensure_equals("setLeftTopAndSize() rectf centerx", rectf.getCenterX(), 1.0f); +        ensure_equals("setLeftTopAndSize() rectf centery", rectf.getCenterY(), -0.5f); +    } + +    template<> template<> +    void object::test<11>() +    { +        // +        // test the setCenterAndSize() method +        // + +        LLRectf rectf; + +        rectf.setCenterAndSize(0.0f, 0.0f, 2.0f, 1.0f); +        ensure_equals("setCenterAndSize() rectf left", rectf.mLeft, -1.0f); +        ensure_equals("setCenterAndSize() rectf top", rectf.mTop, 0.5f); +        ensure_equals("setCenterAndSize() rectf right", rectf.mRight, 1.0f); +        ensure_equals("setCenterAndSize() rectf bottom", rectf.mBottom, -0.5f); +        ensure_equals("setCenterAndSize() rectf width", rectf.getWidth(), 2.0f); +        ensure_equals("setCenterAndSize() rectf height", rectf.getHeight(), 1.0f); +        ensure_equals("setCenterAndSize() rectf centerx", rectf.getCenterX(), 0.0f); +        ensure_equals("setCenterAndSize() rectf centery", rectf.getCenterY(), 0.0f); +    } + +    template<> template<> +    void object::test<12>() +    { +        // +        // test the validity checking method +        // + +        LLRectf rectf; + +        rectf.set(-1.0f, 1.0f, 1.0f, -1.0f); +        ensure("BBox is valid", rectf.isValid()); + +        rectf.mLeft = 2.0f; +        ensure("BBox is not valid", ! rectf.isValid()); + +        rectf.makeValid(); +        ensure("BBox forced valid", rectf.isValid()); + +        rectf.set(-1.0f, -1.0f, -1.0f, -1.0f); +        ensure("BBox(0,0,0,0) is valid", rectf.isValid()); +    } + +    template<> template<> +    void object::test<13>() +    { +        // +        // test the null checking methods +        // + +        LLRectf rectf; + +        rectf.set(-1.0f, 1.0f, 1.0f, -1.0f); +        ensure("BBox is not Null", ! rectf.isEmpty()); +        ensure("BBox notNull", rectf.notEmpty()); + +        rectf.mLeft = 2.0f; +        rectf.makeValid(); +        ensure("BBox is now Null", rectf.isEmpty()); + +        rectf.set(-1.0f, -1.0f, -1.0f, -1.0f); +        ensure("BBox(0,0,0,0) is Null", rectf.isEmpty()); +    } + +    template<> template<> +    void object::test<14>() +    { +        // +        // test the (in)equality operators +        // + +        LLRectf rect1, rect2; + +        rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +        rect2.set(-1.0f, 0.9f, 1.0f, -1.0f); + +        ensure("rect1 == rect2 (false)", ! (rect1 == rect2)); +        ensure("rect1 != rect2 (true)", rect1 != rect2); + +        ensure("rect1 == rect1 (true)", rect1 == rect1); +        ensure("rect1 != rect1 (false)", ! (rect1 != rect1)); +    } + +    template<> template<> +    void object::test<15>() +    { +        // +        // test the copy constructor +        // + +        LLRectf rect1, rect2(rect1); + +        ensure("rect1 == rect2 (true)", rect1 == rect2); +        ensure("rect1 != rect2 (false)", ! (rect1 != rect2)); +    } + +    template<> template<> +    void object::test<16>() +    { +        // +        // test the translate() method +        // + +        LLRectf rect1(-1.0f, 1.0f, 1.0f, -1.0f); +        LLRectf rect2(rect1); + +        rect1.translate(0.0f, 0.0f); + +        ensure("translate(0, 0)", rect1 == rect2); + +        rect1.translate(100.0f, 100.0f); +        rect1.translate(-100.0f, -100.0f); + +        ensure("translate(100, 100) + translate(-100, -100)", rect1 == rect2); + +        rect1.translate(10.0f, 0.0f); +        rect2.set(9.0f, 1.0f, 11.0f, -1.0f); +        ensure("translate(10, 0)", rect1 == rect2); + +        rect1.translate(0.0f, 10.0f); +        rect2.set(9.0f, 11.0f, 11.0f, 9.0f); +        ensure("translate(0, 10)", rect1 == rect2); + +        rect1.translate(-10.0f, -10.0f); +        rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); +        ensure("translate(-10, -10)", rect1 == rect2); +    } + +    template<> template<> +    void object::test<17>() +    { +        // +        // test the stretch() method +        // + +        LLRectf rect1(-1.0f, 1.0f, 1.0f, -1.0f); +        LLRectf rect2(rect1); + +        rect1.stretch(0.0f); +        ensure("stretch(0)", rect1 == rect2); + +        rect1.stretch(0.0f, 0.0f); +        ensure("stretch(0, 0)", rect1 == rect2); + +        rect1.stretch(10.0f); +        rect1.stretch(-10.0f); +        ensure("stretch(10) + stretch(-10)", rect1 == rect2); + +        rect1.stretch(2.0f, 1.0f); +        rect2.set(-3.0f, 2.0f, 3.0f, -2.0f); +        ensure("stretch(2, 1)", rect1 == rect2); +    } + + +    template<> template<> +    void object::test<18>() +    { +        // +        // test the unionWith() method +        // + +        LLRectf rect1, rect2, rect3; + +        rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +        rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); +        rect3 = rect1; +        rect3.unionWith(rect2); +        ensure_equals("union with self", rect3, rect1); + +        rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +        rect2.set(-2.0f, 2.0f, 0.0f, 0.0f); +        rect3 = rect1; +        rect3.unionWith(rect2); +        ensure_equals("union - overlap", rect3, LLRectf(-2.0f, 2.0f, 1.0f, -1.0f)); + +        rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +        rect2.set(5.0f, 10.0f, 10.0f, 5.0f); +        rect3 = rect1; +        rect3.unionWith(rect2); +        ensure_equals("union - no overlap", rect3, LLRectf(-1.0f, 10.0f, 10.0f, -1.0f)); +    } + +    template<> template<> +    void object::test<19>() +    { +        // +        // test the intersectWith() methods +        // + +        LLRectf rect1, rect2, rect3; + +        rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +        rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); +        rect3 = rect1; +        rect3.intersectWith(rect2); +        ensure_equals("intersect with self", rect3, rect1); + +        rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +        rect2.set(-2.0f, 2.0f, 0.0f, 0.0f); +        rect3 = rect1; +        rect3.intersectWith(rect2); +        ensure_equals("intersect - overlap", rect3, LLRectf(-1.0f, 1.0f, 0.0f, 0.0f)); + +        rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +        rect2.set(5.0f, 10.0f, 10.0f, 5.0f); +        rect3 = rect1; +        rect3.intersectWith(rect2); +        ensure("intersect - no overlap", rect3.isEmpty()); +    } + +    template<> template<> +    void object::test<20>() +    { +        // +        // test the pointInRect() method +        // + +        LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); + +        ensure("(0,0) not in rect", rect.pointInRect(0.0f, 0.0f) == FALSE); +        ensure("(2,2) in rect", rect.pointInRect(2.0f, 2.0f) == TRUE); +        ensure("(1,1) in rect", rect.pointInRect(1.0f, 1.0f) == TRUE); +        ensure("(3,3) not in rect", rect.pointInRect(3.0f, 3.0f) == FALSE); +        ensure("(2.999,2.999) in rect", rect.pointInRect(2.999f, 2.999f) == TRUE); +        ensure("(2.999,3.0) not in rect", rect.pointInRect(2.999f, 3.0f) == FALSE); +        ensure("(3.0,2.999) not in rect", rect.pointInRect(3.0f, 2.999f) == FALSE); +    } + +    template<> template<> +    void object::test<21>() +    { +        // +        // test the localPointInRect() method +        // + +        LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); + +        ensure("(0,0) in local rect", rect.localPointInRect(0.0f, 0.0f) == TRUE); +        ensure("(-0.0001,-0.0001) not in local rect", rect.localPointInRect(-0.0001f, -0.001f) == FALSE); +        ensure("(1,1) in local rect", rect.localPointInRect(1.0f, 1.0f) == TRUE); +        ensure("(2,2) not in local rect", rect.localPointInRect(2.0f, 2.0f) == FALSE); +        ensure("(1.999,1.999) in local rect", rect.localPointInRect(1.999f, 1.999f) == TRUE); +        ensure("(1.999,2.0) not in local rect", rect.localPointInRect(1.999f, 2.0f) == FALSE); +        ensure("(2.0,1.999) not in local rect", rect.localPointInRect(2.0f, 1.999f) == FALSE); +    } + +    template<> template<> +    void object::test<22>() +    { +        // +        // test the clampPointToRect() method +        // + +        LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); +        F32 x, y; + +        x = 2.0f; y = 2.0f; +        rect.clampPointToRect(x, y); +        ensure_equals("clamp x-coord within rect", x, 2.0f); +        ensure_equals("clamp y-coord within rect", y, 2.0f); + +        x = -100.0f; y = 100.0f; +        rect.clampPointToRect(x, y); +        ensure_equals("clamp x-coord outside rect", x, 1.0f); +        ensure_equals("clamp y-coord outside rect", y, 3.0f); + +        x = 3.0f; y = 1.0f; +        rect.clampPointToRect(x, y); +        ensure_equals("clamp x-coord edge rect", x, 3.0f); +        ensure_equals("clamp y-coord edge rect", y, 1.0f); +    }  } diff --git a/indra/llmath/tests/m3math_test.cpp b/indra/llmath/tests/m3math_test.cpp index 2a0fe76aa7..b023c85ffd 100644 --- a/indra/llmath/tests/m3math_test.cpp +++ b/indra/llmath/tests/m3math_test.cpp @@ -1,4 +1,4 @@ -/**  +/**   * @file m3math_test.cpp   * @author Adroit   * @date 2007-03 @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -49,284 +49,284 @@  namespace tut  { -	struct m3math_test -	{ -	}; -	typedef test_group<m3math_test> m3math_test_t; -	typedef m3math_test_t::object m3math_test_object_t; -	tut::m3math_test_t tut_m3math_test("m3math_h"); - -	//test case for setIdentity() fn. -	template<> template<> -	void m3math_test_object_t::test<1>() -	{ -		LLMatrix3 llmat3_obj; -		llmat3_obj.setIdentity(); -		ensure("LLMatrix3::setIdentity failed", 1.f == llmat3_obj.mMatrix[0][0] && -					0.f == llmat3_obj.mMatrix[0][1] && -					0.f == llmat3_obj.mMatrix[0][2] && -					0.f == llmat3_obj.mMatrix[1][0] && -					1.f == llmat3_obj.mMatrix[1][1] && -					0.f == llmat3_obj.mMatrix[1][2] && -					0.f == llmat3_obj.mMatrix[2][0] && -					0.f == llmat3_obj.mMatrix[2][1] && -					1.f == llmat3_obj.mMatrix[2][2]); -	} - -	//test case for LLMatrix3& setZero() fn. -	template<> template<> -	void m3math_test_object_t::test<2>() -	{ -		LLMatrix3 llmat3_obj; -		llmat3_obj.setZero(); - -		ensure("LLMatrix3::setZero failed", 0.f == llmat3_obj.setZero().mMatrix[0][0] && -					0.f == llmat3_obj.setZero().mMatrix[0][1] && -					0.f == llmat3_obj.setZero().mMatrix[0][2] && -					0.f == llmat3_obj.setZero().mMatrix[1][0] && -					0.f == llmat3_obj.setZero().mMatrix[1][1] && -					0.f == llmat3_obj.setZero().mMatrix[1][2] && -					0.f == llmat3_obj.setZero().mMatrix[2][0] && -					0.f == llmat3_obj.setZero().mMatrix[2][1] && -					0.f == llmat3_obj.setZero().mMatrix[2][2]); -	} - -	//test case for setRows(const LLVector3 &x_axis, const LLVector3 &y_axis, const LLVector3 &z_axis) fns. -	template<> template<> -	void m3math_test_object_t::test<3>() -	{ -		LLMatrix3 llmat3_obj; -		LLVector3 vect1(2, 1, 4); -		LLVector3 vect2(3, 5, 7); -		LLVector3 vect3(6, 9, 7); -		llmat3_obj.setRows(vect1, vect2, vect3); -		ensure("LLVector3::setRows failed ", 2 == llmat3_obj.mMatrix[0][0] && -						1 == llmat3_obj.mMatrix[0][1] && -						4 == llmat3_obj.mMatrix[0][2] && -						3 == llmat3_obj.mMatrix[1][0] && -						5 == llmat3_obj.mMatrix[1][1] && -						7 == llmat3_obj.mMatrix[1][2] && -						6 == llmat3_obj.mMatrix[2][0] && -						9 == llmat3_obj.mMatrix[2][1] && -						7 == llmat3_obj.mMatrix[2][2]); -	} - -	//test case for getFwdRow(), getLeftRow(), getUpRow() fns. -	template<> template<> -	void m3math_test_object_t::test<4>() -	{ -		LLMatrix3 llmat3_obj; -		LLVector3 vect1(2, 1, 4); -		LLVector3 vect2(3, 5, 7); -		LLVector3 vect3(6, 9, 7); -		llmat3_obj.setRows(vect1, vect2, vect3); -		 -		ensure("LLVector3::getFwdRow failed ", vect1 == llmat3_obj.getFwdRow()); -		ensure("LLVector3::getLeftRow failed ", vect2 == llmat3_obj.getLeftRow()); -		ensure("LLVector3::getUpRow failed ", vect3 == llmat3_obj.getUpRow()); -	} - -	//test case for operator*(const LLMatrix3 &a, const LLMatrix3 &b) -	template<> template<> -	void m3math_test_object_t::test<5>() -	{ -		LLMatrix3 llmat_obj1; -		LLMatrix3 llmat_obj2;		 -		LLMatrix3 llmat_obj3; -		 -		LLVector3 llvec1(1, 3, 5); -		LLVector3 llvec2(3, 6, 1); -		LLVector3 llvec3(4, 6, 9); - -		LLVector3 llvec4(1, 1, 5); -		LLVector3 llvec5(3, 6, 8); -		LLVector3 llvec6(8, 6, 2); - -		LLVector3 llvec7(0, 0, 0); -		LLVector3 llvec8(0, 0, 0); -		LLVector3 llvec9(0, 0, 0); -		 -		llmat_obj1.setRows(llvec1, llvec2, llvec3); -		llmat_obj2.setRows(llvec4, llvec5, llvec6); -		llmat_obj3.setRows(llvec7, llvec8, llvec9); -		llmat_obj3 = llmat_obj1 * llmat_obj2; -		ensure("LLMatrix3::operator*(const LLMatrix3 &a, const LLMatrix3 &b) failed",  -						50 == llmat_obj3.mMatrix[0][0] && -						49 == llmat_obj3.mMatrix[0][1] && -						39 == llmat_obj3.mMatrix[0][2] && -						29 == llmat_obj3.mMatrix[1][0] && -						45 == llmat_obj3.mMatrix[1][1] && -						65 == llmat_obj3.mMatrix[1][2] && -						94 == llmat_obj3.mMatrix[2][0] && -						94 == llmat_obj3.mMatrix[2][1] && -						86 == llmat_obj3.mMatrix[2][2]); -	} - - -	//test case for operator*(const LLVector3 &a, const LLMatrix3 &b) -	template<> template<> -	void m3math_test_object_t::test<6>() -	{ -				 -		LLMatrix3 llmat_obj1; -		 -		LLVector3 llvec(1, 3, 5); -		LLVector3 res_vec(0, 0, 0); -		LLVector3 llvec1(1, 3, 5); -		LLVector3 llvec2(3, 6, 1); -		LLVector3 llvec3(4, 6, 9); -		 -		llmat_obj1.setRows(llvec1, llvec2, llvec3); -		res_vec = llvec * llmat_obj1; - -		LLVector3 expected_result(30, 51, 53); - -		ensure("LLMatrix3::operator*(const LLVector3 &a, const LLMatrix3 &b) failed", res_vec == expected_result); -	} - -	//test case for operator*(const LLVector3d &a, const LLMatrix3 &b)  -	template<> template<> -	void m3math_test_object_t::test<7>() -	{ -		LLMatrix3 llmat_obj1; -		LLVector3d llvec3d1;		 -		LLVector3d llvec3d2(0, 3, 4); - -		LLVector3 llvec1(1, 3, 5); -		LLVector3 llvec2(3, 2, 1); -		LLVector3 llvec3(4, 6, 0); -		 -		llmat_obj1.setRows(llvec1, llvec2, llvec3); -		llvec3d1 = llvec3d2 * llmat_obj1; - -		LLVector3d expected_result(25, 30, 3); -		 -		ensure("LLMatrix3::operator*(const LLVector3 &a, const LLMatrix3 &b) failed", llvec3d1 == expected_result); -	} - -	// test case for operator==(const LLMatrix3 &a, const LLMatrix3 &b) -	template<> template<> -	void m3math_test_object_t::test<8>() -	{ -		LLMatrix3 llmat_obj1; -		LLMatrix3 llmat_obj2;		 -		 -		LLVector3 llvec1(1, 3, 5); -		LLVector3 llvec2(3, 6, 1); -		LLVector3 llvec3(4, 6, 9); - -		llmat_obj1.setRows(llvec1, llvec2, llvec3); -		llmat_obj2.setRows(llvec1, llvec2, llvec3); -		ensure("LLMatrix3::operator==(const LLMatrix3 &a, const LLMatrix3 &b) failed", llmat_obj1 == llmat_obj2); - -		llmat_obj2.setRows(llvec2, llvec2, llvec3); -		ensure("LLMatrix3::operator!=(const LLMatrix3 &a, const LLMatrix3 &b) failed", llmat_obj1 != llmat_obj2); -	} - -	//test case for quaternion() fn. -	template<> template<> -	void m3math_test_object_t::test<9>() -	{ -		LLMatrix3 llmat_obj1; -		LLQuaternion llmat_quat;		 -		 -		LLVector3 llmat1(2.0f, 1.0f, 6.0f); -		LLVector3 llmat2(1.0f, 1.0f, 3.0f); -		LLVector3 llmat3(1.0f, 7.0f, 5.0f); - -		llmat_obj1.setRows(llmat1, llmat2, llmat3); -		llmat_quat = llmat_obj1.quaternion(); -		ensure("LLMatrix3::quaternion failed ", is_approx_equal(-0.66666669f, llmat_quat.mQ[0]) && -						is_approx_equal(-0.83333337f, llmat_quat.mQ[1]) && -						is_approx_equal(0.0f, llmat_quat.mQ[2]) && -						is_approx_equal(1.5f, llmat_quat.mQ[3])); -	} - -	//test case for transpose() fn. -	template<> template<> -	void m3math_test_object_t::test<10>() -	{ -		LLMatrix3 llmat_obj; -	 -		LLVector3 llvec1(1, 2, 3); -		LLVector3 llvec2(3, 2, 1); -		LLVector3 llvec3(2, 2, 2); - -		llmat_obj.setRows(llvec1, llvec2, llvec3); -		llmat_obj.transpose(); - -		LLVector3 resllvec1(1, 3, 2); -		LLVector3 resllvec2(2, 2, 2); -		LLVector3 resllvec3(3, 1, 2); -		LLMatrix3 expectedllmat_obj; -		expectedllmat_obj.setRows(resllvec1, resllvec2, resllvec3); - -		ensure("LLMatrix3::transpose failed ", llmat_obj == expectedllmat_obj); -	} -	 -	//test case for determinant() fn. -	template<> template<> -	void m3math_test_object_t::test<11>() -	{ -		LLMatrix3 llmat_obj1; -		 -		LLVector3 llvec1(1, 2, 3); -		LLVector3 llvec2(3, 2, 1); -		LLVector3 llvec3(2, 2, 2); -		llmat_obj1.setRows(llvec1, llvec2, llvec3); -		ensure("LLMatrix3::determinant failed ",  0.0f == llmat_obj1.determinant()); -	} - -	//test case for orthogonalize() fn. -	template<> template<> -	void m3math_test_object_t::test<12>() -	{ -		LLMatrix3 llmat_obj; - -		LLVector3 llvec1(1, 4, 3); -		LLVector3 llvec2(1, 2, 0); -		LLVector3 llvec3(2, 4, 2); +    struct m3math_test +    { +    }; +    typedef test_group<m3math_test> m3math_test_t; +    typedef m3math_test_t::object m3math_test_object_t; +    tut::m3math_test_t tut_m3math_test("m3math_h"); + +    //test case for setIdentity() fn. +    template<> template<> +    void m3math_test_object_t::test<1>() +    { +        LLMatrix3 llmat3_obj; +        llmat3_obj.setIdentity(); +        ensure("LLMatrix3::setIdentity failed", 1.f == llmat3_obj.mMatrix[0][0] && +                    0.f == llmat3_obj.mMatrix[0][1] && +                    0.f == llmat3_obj.mMatrix[0][2] && +                    0.f == llmat3_obj.mMatrix[1][0] && +                    1.f == llmat3_obj.mMatrix[1][1] && +                    0.f == llmat3_obj.mMatrix[1][2] && +                    0.f == llmat3_obj.mMatrix[2][0] && +                    0.f == llmat3_obj.mMatrix[2][1] && +                    1.f == llmat3_obj.mMatrix[2][2]); +    } + +    //test case for LLMatrix3& setZero() fn. +    template<> template<> +    void m3math_test_object_t::test<2>() +    { +        LLMatrix3 llmat3_obj; +        llmat3_obj.setZero(); + +        ensure("LLMatrix3::setZero failed", 0.f == llmat3_obj.setZero().mMatrix[0][0] && +                    0.f == llmat3_obj.setZero().mMatrix[0][1] && +                    0.f == llmat3_obj.setZero().mMatrix[0][2] && +                    0.f == llmat3_obj.setZero().mMatrix[1][0] && +                    0.f == llmat3_obj.setZero().mMatrix[1][1] && +                    0.f == llmat3_obj.setZero().mMatrix[1][2] && +                    0.f == llmat3_obj.setZero().mMatrix[2][0] && +                    0.f == llmat3_obj.setZero().mMatrix[2][1] && +                    0.f == llmat3_obj.setZero().mMatrix[2][2]); +    } + +    //test case for setRows(const LLVector3 &x_axis, const LLVector3 &y_axis, const LLVector3 &z_axis) fns. +    template<> template<> +    void m3math_test_object_t::test<3>() +    { +        LLMatrix3 llmat3_obj; +        LLVector3 vect1(2, 1, 4); +        LLVector3 vect2(3, 5, 7); +        LLVector3 vect3(6, 9, 7); +        llmat3_obj.setRows(vect1, vect2, vect3); +        ensure("LLVector3::setRows failed ", 2 == llmat3_obj.mMatrix[0][0] && +                        1 == llmat3_obj.mMatrix[0][1] && +                        4 == llmat3_obj.mMatrix[0][2] && +                        3 == llmat3_obj.mMatrix[1][0] && +                        5 == llmat3_obj.mMatrix[1][1] && +                        7 == llmat3_obj.mMatrix[1][2] && +                        6 == llmat3_obj.mMatrix[2][0] && +                        9 == llmat3_obj.mMatrix[2][1] && +                        7 == llmat3_obj.mMatrix[2][2]); +    } + +    //test case for getFwdRow(), getLeftRow(), getUpRow() fns. +    template<> template<> +    void m3math_test_object_t::test<4>() +    { +        LLMatrix3 llmat3_obj; +        LLVector3 vect1(2, 1, 4); +        LLVector3 vect2(3, 5, 7); +        LLVector3 vect3(6, 9, 7); +        llmat3_obj.setRows(vect1, vect2, vect3); + +        ensure("LLVector3::getFwdRow failed ", vect1 == llmat3_obj.getFwdRow()); +        ensure("LLVector3::getLeftRow failed ", vect2 == llmat3_obj.getLeftRow()); +        ensure("LLVector3::getUpRow failed ", vect3 == llmat3_obj.getUpRow()); +    } + +    //test case for operator*(const LLMatrix3 &a, const LLMatrix3 &b) +    template<> template<> +    void m3math_test_object_t::test<5>() +    { +        LLMatrix3 llmat_obj1; +        LLMatrix3 llmat_obj2; +        LLMatrix3 llmat_obj3; + +        LLVector3 llvec1(1, 3, 5); +        LLVector3 llvec2(3, 6, 1); +        LLVector3 llvec3(4, 6, 9); + +        LLVector3 llvec4(1, 1, 5); +        LLVector3 llvec5(3, 6, 8); +        LLVector3 llvec6(8, 6, 2); + +        LLVector3 llvec7(0, 0, 0); +        LLVector3 llvec8(0, 0, 0); +        LLVector3 llvec9(0, 0, 0); + +        llmat_obj1.setRows(llvec1, llvec2, llvec3); +        llmat_obj2.setRows(llvec4, llvec5, llvec6); +        llmat_obj3.setRows(llvec7, llvec8, llvec9); +        llmat_obj3 = llmat_obj1 * llmat_obj2; +        ensure("LLMatrix3::operator*(const LLMatrix3 &a, const LLMatrix3 &b) failed", +                        50 == llmat_obj3.mMatrix[0][0] && +                        49 == llmat_obj3.mMatrix[0][1] && +                        39 == llmat_obj3.mMatrix[0][2] && +                        29 == llmat_obj3.mMatrix[1][0] && +                        45 == llmat_obj3.mMatrix[1][1] && +                        65 == llmat_obj3.mMatrix[1][2] && +                        94 == llmat_obj3.mMatrix[2][0] && +                        94 == llmat_obj3.mMatrix[2][1] && +                        86 == llmat_obj3.mMatrix[2][2]); +    } + + +    //test case for operator*(const LLVector3 &a, const LLMatrix3 &b) +    template<> template<> +    void m3math_test_object_t::test<6>() +    { + +        LLMatrix3 llmat_obj1; + +        LLVector3 llvec(1, 3, 5); +        LLVector3 res_vec(0, 0, 0); +        LLVector3 llvec1(1, 3, 5); +        LLVector3 llvec2(3, 6, 1); +        LLVector3 llvec3(4, 6, 9); + +        llmat_obj1.setRows(llvec1, llvec2, llvec3); +        res_vec = llvec * llmat_obj1; + +        LLVector3 expected_result(30, 51, 53); + +        ensure("LLMatrix3::operator*(const LLVector3 &a, const LLMatrix3 &b) failed", res_vec == expected_result); +    } + +    //test case for operator*(const LLVector3d &a, const LLMatrix3 &b) +    template<> template<> +    void m3math_test_object_t::test<7>() +    { +        LLMatrix3 llmat_obj1; +        LLVector3d llvec3d1; +        LLVector3d llvec3d2(0, 3, 4); + +        LLVector3 llvec1(1, 3, 5); +        LLVector3 llvec2(3, 2, 1); +        LLVector3 llvec3(4, 6, 0); + +        llmat_obj1.setRows(llvec1, llvec2, llvec3); +        llvec3d1 = llvec3d2 * llmat_obj1; + +        LLVector3d expected_result(25, 30, 3); + +        ensure("LLMatrix3::operator*(const LLVector3 &a, const LLMatrix3 &b) failed", llvec3d1 == expected_result); +    } + +    // test case for operator==(const LLMatrix3 &a, const LLMatrix3 &b) +    template<> template<> +    void m3math_test_object_t::test<8>() +    { +        LLMatrix3 llmat_obj1; +        LLMatrix3 llmat_obj2; + +        LLVector3 llvec1(1, 3, 5); +        LLVector3 llvec2(3, 6, 1); +        LLVector3 llvec3(4, 6, 9); + +        llmat_obj1.setRows(llvec1, llvec2, llvec3); +        llmat_obj2.setRows(llvec1, llvec2, llvec3); +        ensure("LLMatrix3::operator==(const LLMatrix3 &a, const LLMatrix3 &b) failed", llmat_obj1 == llmat_obj2); + +        llmat_obj2.setRows(llvec2, llvec2, llvec3); +        ensure("LLMatrix3::operator!=(const LLMatrix3 &a, const LLMatrix3 &b) failed", llmat_obj1 != llmat_obj2); +    } + +    //test case for quaternion() fn. +    template<> template<> +    void m3math_test_object_t::test<9>() +    { +        LLMatrix3 llmat_obj1; +        LLQuaternion llmat_quat; + +        LLVector3 llmat1(2.0f, 1.0f, 6.0f); +        LLVector3 llmat2(1.0f, 1.0f, 3.0f); +        LLVector3 llmat3(1.0f, 7.0f, 5.0f); + +        llmat_obj1.setRows(llmat1, llmat2, llmat3); +        llmat_quat = llmat_obj1.quaternion(); +        ensure("LLMatrix3::quaternion failed ", is_approx_equal(-0.66666669f, llmat_quat.mQ[0]) && +                        is_approx_equal(-0.83333337f, llmat_quat.mQ[1]) && +                        is_approx_equal(0.0f, llmat_quat.mQ[2]) && +                        is_approx_equal(1.5f, llmat_quat.mQ[3])); +    } + +    //test case for transpose() fn. +    template<> template<> +    void m3math_test_object_t::test<10>() +    { +        LLMatrix3 llmat_obj; + +        LLVector3 llvec1(1, 2, 3); +        LLVector3 llvec2(3, 2, 1); +        LLVector3 llvec3(2, 2, 2); + +        llmat_obj.setRows(llvec1, llvec2, llvec3); +        llmat_obj.transpose(); + +        LLVector3 resllvec1(1, 3, 2); +        LLVector3 resllvec2(2, 2, 2); +        LLVector3 resllvec3(3, 1, 2); +        LLMatrix3 expectedllmat_obj; +        expectedllmat_obj.setRows(resllvec1, resllvec2, resllvec3); + +        ensure("LLMatrix3::transpose failed ", llmat_obj == expectedllmat_obj); +    } + +    //test case for determinant() fn. +    template<> template<> +    void m3math_test_object_t::test<11>() +    { +        LLMatrix3 llmat_obj1; + +        LLVector3 llvec1(1, 2, 3); +        LLVector3 llvec2(3, 2, 1); +        LLVector3 llvec3(2, 2, 2); +        llmat_obj1.setRows(llvec1, llvec2, llvec3); +        ensure("LLMatrix3::determinant failed ",  0.0f == llmat_obj1.determinant()); +    } + +    //test case for orthogonalize() fn. +    template<> template<> +    void m3math_test_object_t::test<12>() +    { +        LLMatrix3 llmat_obj; + +        LLVector3 llvec1(1, 4, 3); +        LLVector3 llvec2(1, 2, 0); +        LLVector3 llvec3(2, 4, 2);          skip("This test fails depending on architecture. Need to fix comparison operation, is_approx_equal, to work on more than one platform."); -		llmat_obj.setRows(llvec1, llvec2, llvec3); -		llmat_obj.orthogonalize(); - -		ensure("LLMatrix3::orthogonalize failed ", -		       is_approx_equal(0.19611614f, llmat_obj.mMatrix[0][0]) && -		       is_approx_equal(0.78446454f, llmat_obj.mMatrix[0][1]) && -		       is_approx_equal(0.58834841f, llmat_obj.mMatrix[0][2]) && -		       is_approx_equal(0.47628204f, llmat_obj.mMatrix[1][0]) && -		       is_approx_equal(0.44826545f, llmat_obj.mMatrix[1][1]) && -		       is_approx_equal(-0.75644795f, llmat_obj.mMatrix[1][2]) && -		       is_approx_equal(-0.85714286f, llmat_obj.mMatrix[2][0]) && -		       is_approx_equal(0.42857143f, llmat_obj.mMatrix[2][1]) && -		       is_approx_equal(-0.28571429f, llmat_obj.mMatrix[2][2])); -	} - -	//test case for adjointTranspose() fn. -	template<> template<> -	void m3math_test_object_t::test<13>() -	{ -		LLMatrix3 llmat_obj; - -		LLVector3 llvec1(3, 2, 1); -		LLVector3 llvec2(6, 2, 1); -		LLVector3 llvec3(3, 6, 8); - -		llmat_obj.setRows(llvec1, llvec2, llvec3); -		llmat_obj.adjointTranspose(); -		 -		ensure("LLMatrix3::adjointTranspose failed ", 10 == llmat_obj.mMatrix[0][0] && -						-45 == llmat_obj.mMatrix[1][0] && -						30 == llmat_obj.mMatrix[2][0] && -						-10 == llmat_obj.mMatrix[0][1] && -						21 == llmat_obj.mMatrix[1][1] && -						-12 == llmat_obj.mMatrix[2][1] && -						0  == llmat_obj.mMatrix[0][2] && -						3 == llmat_obj.mMatrix[1][2] && -						-6 == llmat_obj.mMatrix[2][2]); -	} - -	/* TBD: Need to add test cases for getEulerAngles() and setRot() functions */ +        llmat_obj.setRows(llvec1, llvec2, llvec3); +        llmat_obj.orthogonalize(); + +        ensure("LLMatrix3::orthogonalize failed ", +               is_approx_equal(0.19611614f, llmat_obj.mMatrix[0][0]) && +               is_approx_equal(0.78446454f, llmat_obj.mMatrix[0][1]) && +               is_approx_equal(0.58834841f, llmat_obj.mMatrix[0][2]) && +               is_approx_equal(0.47628204f, llmat_obj.mMatrix[1][0]) && +               is_approx_equal(0.44826545f, llmat_obj.mMatrix[1][1]) && +               is_approx_equal(-0.75644795f, llmat_obj.mMatrix[1][2]) && +               is_approx_equal(-0.85714286f, llmat_obj.mMatrix[2][0]) && +               is_approx_equal(0.42857143f, llmat_obj.mMatrix[2][1]) && +               is_approx_equal(-0.28571429f, llmat_obj.mMatrix[2][2])); +    } + +    //test case for adjointTranspose() fn. +    template<> template<> +    void m3math_test_object_t::test<13>() +    { +        LLMatrix3 llmat_obj; + +        LLVector3 llvec1(3, 2, 1); +        LLVector3 llvec2(6, 2, 1); +        LLVector3 llvec3(3, 6, 8); + +        llmat_obj.setRows(llvec1, llvec2, llvec3); +        llmat_obj.adjointTranspose(); + +        ensure("LLMatrix3::adjointTranspose failed ", 10 == llmat_obj.mMatrix[0][0] && +                        -45 == llmat_obj.mMatrix[1][0] && +                        30 == llmat_obj.mMatrix[2][0] && +                        -10 == llmat_obj.mMatrix[0][1] && +                        21 == llmat_obj.mMatrix[1][1] && +                        -12 == llmat_obj.mMatrix[2][1] && +                        0  == llmat_obj.mMatrix[0][2] && +                        3 == llmat_obj.mMatrix[1][2] && +                        -6 == llmat_obj.mMatrix[2][2]); +    } + +    /* TBD: Need to add test cases for getEulerAngles() and setRot() functions */  } diff --git a/indra/llmath/tests/mathmisc_test.cpp b/indra/llmath/tests/mathmisc_test.cpp index f12140cf8f..163cf02350 100644 --- a/indra/llmath/tests/mathmisc_test.cpp +++ b/indra/llmath/tests/mathmisc_test.cpp @@ -1,4 +1,4 @@ -/**  +/**   * @file math.cpp   * @author Phoenix   * @date 2005-09-26 @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -40,684 +40,684 @@  namespace tut  { -	struct math_data -	{ -	}; -	typedef test_group<math_data> math_test; -	typedef math_test::object math_object; -	tut::math_test tm("BasicLindenMath"); - -	template<> template<> -	void math_object::test<1>() -	{ -		S32 val = 89543; -		val = llabs(val); -		ensure("integer absolute value 1", (89543 == val)); -		val = -500; -		val = llabs(val); -		ensure("integer absolute value 2", (500 == val)); -	} - -	template<> template<> -	void math_object::test<2>() -	{ -		F32 val = -2583.4f; -		val = llabs(val); -		ensure("float absolute value 1", (2583.4f == val)); -		val = 430903.f; -		val = llabs(val); -		ensure("float absolute value 2", (430903.f == val)); -	} - -	template<> template<> -	void math_object::test<3>() -	{ -		F64 val = 387439393.987329839; -		val = llabs(val); -		ensure("double absolute value 1", (387439393.987329839 == val)); -		val = -8937843.9394878; -		val = llabs(val); -		ensure("double absolute value 2", (8937843.9394878 == val)); -	} - -	template<> template<> -	void math_object::test<4>() -	{ -		F32 val = 430903.9f; -		S32 val1 = lltrunc(val); -		ensure("float truncate value 1", (430903 == val1)); -		val = -2303.9f; -		val1 = lltrunc(val); -		ensure("float truncate value 2", (-2303  == val1)); -	} - -	template<> template<> -	void math_object::test<5>() -	{ -		F64 val = 387439393.987329839 ; -		S32 val1 = lltrunc(val); -		ensure("float truncate value 1", (387439393 == val1)); -		val = -387439393.987329839; -		val1 = lltrunc(val); -		ensure("float truncate value 2", (-387439393  == val1)); -	} - -	template<> template<> -	void math_object::test<6>() -	{ -		F32 val = 430903.2f; -		S32 val1 = llfloor(val); -		ensure("float llfloor value 1", (430903 == val1)); -		val = -430903.9f; -		val1 = llfloor(val); -		ensure("float llfloor value 2", (-430904 == val1)); -	} - -	template<> template<> -	void math_object::test<7>() -	{ -		F32 val = 430903.2f; -		S32 val1 = llceil(val); -		ensure("float llceil value 1", (430904 == val1)); -		val = -430903.9f; -		val1 = llceil(val); -		ensure("float llceil value 2", (-430903 == val1)); -	} - -	template<> template<> -	void math_object::test<8>() -	{ -		F32 val = 430903.2f; -		S32 val1 = ll_round(val); -		ensure("float ll_round value 1", (430903 == val1)); -		val = -430903.9f; -		val1 = ll_round(val); -		ensure("float ll_round value 2", (-430904 == val1)); -	} - -	template<> template<> -	void math_object::test<9>() -	{ -		F32 val = 430905.2654f, nearest = 100.f; -		val = ll_round(val, nearest); -		ensure("float ll_round value 1", (430900 == val)); -		val = -430905.2654f, nearest = 10.f; -		val = ll_round(val, nearest); -		ensure("float ll_round value 1", (-430910 == val)); -	} - -	template<> template<> -	void math_object::test<10>() -	{ -		F64 val = 430905.2654, nearest = 100.0; -		val = ll_round(val, nearest); -		ensure("double ll_round value 1", (430900 == val)); -		val = -430905.2654, nearest = 10.0; -		val = ll_round(val, nearest); -		ensure("double ll_round value 1", (-430910.00000 == val)); -	} - -	template<> template<> -	void math_object::test<11>() -	{ -		const F32	F_PI		= 3.1415926535897932384626433832795f; -		F32 angle = 3506.f; -		angle =  llsimple_angle(angle); -		ensure("llsimple_angle  value 1", (angle <=F_PI && angle >= -F_PI)); -		angle = -431.f; -		angle =  llsimple_angle(angle); -		ensure("llsimple_angle  value 1", (angle <=F_PI && angle >= -F_PI)); -	} +    struct math_data +    { +    }; +    typedef test_group<math_data> math_test; +    typedef math_test::object math_object; +    tut::math_test tm("BasicLindenMath"); + +    template<> template<> +    void math_object::test<1>() +    { +        S32 val = 89543; +        val = llabs(val); +        ensure("integer absolute value 1", (89543 == val)); +        val = -500; +        val = llabs(val); +        ensure("integer absolute value 2", (500 == val)); +    } + +    template<> template<> +    void math_object::test<2>() +    { +        F32 val = -2583.4f; +        val = llabs(val); +        ensure("float absolute value 1", (2583.4f == val)); +        val = 430903.f; +        val = llabs(val); +        ensure("float absolute value 2", (430903.f == val)); +    } + +    template<> template<> +    void math_object::test<3>() +    { +        F64 val = 387439393.987329839; +        val = llabs(val); +        ensure("double absolute value 1", (387439393.987329839 == val)); +        val = -8937843.9394878; +        val = llabs(val); +        ensure("double absolute value 2", (8937843.9394878 == val)); +    } + +    template<> template<> +    void math_object::test<4>() +    { +        F32 val = 430903.9f; +        S32 val1 = lltrunc(val); +        ensure("float truncate value 1", (430903 == val1)); +        val = -2303.9f; +        val1 = lltrunc(val); +        ensure("float truncate value 2", (-2303  == val1)); +    } + +    template<> template<> +    void math_object::test<5>() +    { +        F64 val = 387439393.987329839 ; +        S32 val1 = lltrunc(val); +        ensure("float truncate value 1", (387439393 == val1)); +        val = -387439393.987329839; +        val1 = lltrunc(val); +        ensure("float truncate value 2", (-387439393  == val1)); +    } + +    template<> template<> +    void math_object::test<6>() +    { +        F32 val = 430903.2f; +        S32 val1 = llfloor(val); +        ensure("float llfloor value 1", (430903 == val1)); +        val = -430903.9f; +        val1 = llfloor(val); +        ensure("float llfloor value 2", (-430904 == val1)); +    } + +    template<> template<> +    void math_object::test<7>() +    { +        F32 val = 430903.2f; +        S32 val1 = llceil(val); +        ensure("float llceil value 1", (430904 == val1)); +        val = -430903.9f; +        val1 = llceil(val); +        ensure("float llceil value 2", (-430903 == val1)); +    } + +    template<> template<> +    void math_object::test<8>() +    { +        F32 val = 430903.2f; +        S32 val1 = ll_round(val); +        ensure("float ll_round value 1", (430903 == val1)); +        val = -430903.9f; +        val1 = ll_round(val); +        ensure("float ll_round value 2", (-430904 == val1)); +    } + +    template<> template<> +    void math_object::test<9>() +    { +        F32 val = 430905.2654f, nearest = 100.f; +        val = ll_round(val, nearest); +        ensure("float ll_round value 1", (430900 == val)); +        val = -430905.2654f, nearest = 10.f; +        val = ll_round(val, nearest); +        ensure("float ll_round value 1", (-430910 == val)); +    } + +    template<> template<> +    void math_object::test<10>() +    { +        F64 val = 430905.2654, nearest = 100.0; +        val = ll_round(val, nearest); +        ensure("double ll_round value 1", (430900 == val)); +        val = -430905.2654, nearest = 10.0; +        val = ll_round(val, nearest); +        ensure("double ll_round value 1", (-430910.00000 == val)); +    } + +    template<> template<> +    void math_object::test<11>() +    { +        const F32   F_PI        = 3.1415926535897932384626433832795f; +        F32 angle = 3506.f; +        angle =  llsimple_angle(angle); +        ensure("llsimple_angle  value 1", (angle <=F_PI && angle >= -F_PI)); +        angle = -431.f; +        angle =  llsimple_angle(angle); +        ensure("llsimple_angle  value 1", (angle <=F_PI && angle >= -F_PI)); +    }  }  namespace tut  { -	struct uuid_data -	{ -		LLUUID id; -	}; -	typedef test_group<uuid_data> uuid_test; -	typedef uuid_test::object uuid_object; -	tut::uuid_test tu("LLUUID"); - -	template<> template<> -	void uuid_object::test<1>() -	{ -		ensure("uuid null", id.isNull()); -		id.generate(); -		ensure("generate not null", id.notNull()); -		id.setNull(); -		ensure("set null", id.isNull()); -	} - -	template<> template<> -	void uuid_object::test<2>() -	{ -		id.generate(); -		LLUUID a(id); -		ensure_equals("copy equal", id, a); -		a.generate(); -		ensure_not_equals("generate not equal", id, a); -		a = id; -		ensure_equals("assignment equal", id, a); -	} - -	template<> template<> -	void uuid_object::test<3>() -	{ -		id.generate(); -		LLUUID copy(id); -		LLUUID mask; -		mask.generate(); -		copy ^= mask; -		ensure_not_equals("mask not equal", id, copy); -		copy ^= mask; -		ensure_equals("mask back", id, copy); -	} - -	template<> template<> -	void uuid_object::test<4>() -	{ -		id.generate(); -		std::string id_str = id.asString(); -		LLUUID copy(id_str.c_str()); -		ensure_equals("string serialization", id, copy); -	} -	 +    struct uuid_data +    { +        LLUUID id; +    }; +    typedef test_group<uuid_data> uuid_test; +    typedef uuid_test::object uuid_object; +    tut::uuid_test tu("LLUUID"); + +    template<> template<> +    void uuid_object::test<1>() +    { +        ensure("uuid null", id.isNull()); +        id.generate(); +        ensure("generate not null", id.notNull()); +        id.setNull(); +        ensure("set null", id.isNull()); +    } + +    template<> template<> +    void uuid_object::test<2>() +    { +        id.generate(); +        LLUUID a(id); +        ensure_equals("copy equal", id, a); +        a.generate(); +        ensure_not_equals("generate not equal", id, a); +        a = id; +        ensure_equals("assignment equal", id, a); +    } + +    template<> template<> +    void uuid_object::test<3>() +    { +        id.generate(); +        LLUUID copy(id); +        LLUUID mask; +        mask.generate(); +        copy ^= mask; +        ensure_not_equals("mask not equal", id, copy); +        copy ^= mask; +        ensure_equals("mask back", id, copy); +    } + +    template<> template<> +    void uuid_object::test<4>() +    { +        id.generate(); +        std::string id_str = id.asString(); +        LLUUID copy(id_str.c_str()); +        ensure_equals("string serialization", id, copy); +    } +  }  namespace tut  { -	struct crc_data -	{ -	}; -	typedef test_group<crc_data> crc_test; -	typedef crc_test::object crc_object; -	tut::crc_test tc("LLCrc"); - -	template<> template<> -	void crc_object::test<1>() -	{ -		/* Test buffer update and individual char update */ -		const char TEST_BUFFER[] = "hello &#$)$&Nd0"; -		LLCRC c1, c2; -		c1.update((U8*)TEST_BUFFER, sizeof(TEST_BUFFER) - 1); -		char* rh = (char*)TEST_BUFFER; -		while(*rh != '\0') -		{ -			c2.update(*rh); -			++rh; -		} -		ensure_equals("crc update 1", c1.getCRC(), c2.getCRC()); -	} - -	template<> template<> -	void crc_object::test<2>() -	{ -		/* Test mixing of buffer and individual char update */ -		const char TEST_BUFFER1[] = "Split Buffer one $^%$%#@$"; -		const char TEST_BUFFER2[] = "Split Buffer two )(8723#5dsds"; -		LLCRC c1, c2; -		c1.update((U8*)TEST_BUFFER1, sizeof(TEST_BUFFER1) - 1); -		char* rh = (char*)TEST_BUFFER2; -		while(*rh != '\0') -		{ -			c1.update(*rh); -			++rh; -		} - -		rh = (char*)TEST_BUFFER1; -		while(*rh != '\0') -		{ -			c2.update(*rh); -			++rh; -		} -		c2.update((U8*)TEST_BUFFER2, sizeof(TEST_BUFFER2) - 1); - -		ensure_equals("crc update 2", c1.getCRC(), c2.getCRC()); -	} +    struct crc_data +    { +    }; +    typedef test_group<crc_data> crc_test; +    typedef crc_test::object crc_object; +    tut::crc_test tc("LLCrc"); + +    template<> template<> +    void crc_object::test<1>() +    { +        /* Test buffer update and individual char update */ +        const char TEST_BUFFER[] = "hello &#$)$&Nd0"; +        LLCRC c1, c2; +        c1.update((U8*)TEST_BUFFER, sizeof(TEST_BUFFER) - 1); +        char* rh = (char*)TEST_BUFFER; +        while(*rh != '\0') +        { +            c2.update(*rh); +            ++rh; +        } +        ensure_equals("crc update 1", c1.getCRC(), c2.getCRC()); +    } + +    template<> template<> +    void crc_object::test<2>() +    { +        /* Test mixing of buffer and individual char update */ +        const char TEST_BUFFER1[] = "Split Buffer one $^%$%#@$"; +        const char TEST_BUFFER2[] = "Split Buffer two )(8723#5dsds"; +        LLCRC c1, c2; +        c1.update((U8*)TEST_BUFFER1, sizeof(TEST_BUFFER1) - 1); +        char* rh = (char*)TEST_BUFFER2; +        while(*rh != '\0') +        { +            c1.update(*rh); +            ++rh; +        } + +        rh = (char*)TEST_BUFFER1; +        while(*rh != '\0') +        { +            c2.update(*rh); +            ++rh; +        } +        c2.update((U8*)TEST_BUFFER2, sizeof(TEST_BUFFER2) - 1); + +        ensure_equals("crc update 2", c1.getCRC(), c2.getCRC()); +    }  }  namespace tut  { -	struct sphere_data -	{ -	}; -	typedef test_group<sphere_data> sphere_test; -	typedef sphere_test::object sphere_object; -	tut::sphere_test tsphere("LLSphere"); - -	template<> template<> -	void sphere_object::test<1>() -	{ -		// test LLSphere::contains() and ::overlaps() -		S32 number_of_tests = 10; -		for (S32 test = 0; test < number_of_tests; ++test) -		{ -			LLVector3 first_center(1.f, 1.f, 1.f); -			F32 first_radius = 3.f; -			LLSphere first_sphere( first_center, first_radius ); -	 -			F32 half_millimeter = 0.0005f; -			LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); -			direction.normalize(); -	 -			F32 distance = ll_frand(first_radius - 2.f * half_millimeter); -			LLVector3 second_center = first_center + distance * direction; -			F32 second_radius = first_radius - distance - half_millimeter; -			LLSphere second_sphere( second_center, second_radius ); -			ensure("first sphere should contain the second", first_sphere.contains(second_sphere)); -			ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere)); -	 -			distance = first_radius + ll_frand(first_radius); -			second_center = first_center + distance * direction; -			second_radius = distance - first_radius + half_millimeter; -			second_sphere.set( second_center, second_radius ); -			ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere)); -			ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere)); -	 -			distance = first_radius + ll_frand(first_radius) + half_millimeter; -			second_center = first_center + distance * direction; -			second_radius = distance - first_radius - half_millimeter; -			second_sphere.set( second_center, second_radius ); -			ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere)); -			ensure("first sphere should NOT overlap the second", !first_sphere.overlaps(second_sphere)); -		} -	} - -	template<> template<> -	void sphere_object::test<2>() -	{ -		skip("See SNOW-620.  Neither the test nor the code being tested seem good.  Also sim-only."); - -		// test LLSphere::getBoundingSphere() -		S32 number_of_tests = 100; -		S32 number_of_spheres = 10; -		F32 sphere_center_range = 32.f; -		F32 sphere_radius_range = 5.f; - -		for (S32 test = 0; test < number_of_tests; ++test) -		{ -			// gegnerate a bunch of random sphere -			std::vector< LLSphere > sphere_list; -			for (S32 sphere_count=0; sphere_count < number_of_spheres; ++sphere_count) -			{ -				LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); -				direction.normalize(); -				F32 distance = ll_frand(sphere_center_range); -				LLVector3 center = distance * direction; -				F32 radius = ll_frand(sphere_radius_range); -				LLSphere sphere( center, radius ); -				sphere_list.push_back(sphere); -			} - -			// compute the bounding sphere -			LLSphere bounding_sphere = LLSphere::getBoundingSphere(sphere_list); - -			// make sure all spheres are inside the bounding sphere -			{ -				std::vector< LLSphere >::const_iterator sphere_itr; -				for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) -				{ -					ensure("sphere should be contained by the bounding sphere", bounding_sphere.contains(*sphere_itr)); -				} -			} - -			// TODO -- improve LLSphere::getBoundingSphere() to the point where -			// we can reduce the 'expansion' in the two tests below to about  -			// 2 mm or less - -			F32 expansion = 0.005f; -			// move all spheres out a little bit  -			// and count how many are NOT contained -			{ -				std::vector< LLVector3 > uncontained_directions; -				std::vector< LLSphere >::iterator sphere_itr; -				for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) -				{ -					LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter(); -					direction.normalize(); -	 -					sphere_itr->setCenter( sphere_itr->getCenter() + expansion * direction ); -					if (! bounding_sphere.contains( *sphere_itr ) ) -					{ -						uncontained_directions.push_back(direction); -					} -				} -				ensure("when moving spheres out there should be at least two uncontained spheres",  -						uncontained_directions.size() > 1); - -				/* TODO -- when the bounding sphere algorithm is improved we can open up this test -				 * at the moment it occasionally fails when the sphere collection is tight and small -				 * (2 meters or less) -				if (2 == uncontained_directions.size() ) -				{ -					// if there were only two uncontained spheres then -					// the two directions should be nearly opposite -					F32 dir_dot = uncontained_directions[0] * uncontained_directions[1]; -					ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f); -				} -				*/ -			} - -			// compute the new bounding sphere -			bounding_sphere = LLSphere::getBoundingSphere(sphere_list); - -			// increase the size of all spheres a little bit -			// and count how many are NOT contained -			{ -				std::vector< LLVector3 > uncontained_directions; -				std::vector< LLSphere >::iterator sphere_itr; -				for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) -				{ -					LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter(); -					direction.normalize(); -	 -					sphere_itr->setRadius( sphere_itr->getRadius() + expansion ); -					if (! bounding_sphere.contains( *sphere_itr ) ) -					{ -						uncontained_directions.push_back(direction); -					} -				} -				ensure("when boosting sphere radii there should be at least two uncontained spheres",  -						uncontained_directions.size() > 1); - -				/* TODO -- when the bounding sphere algorithm is improved we can open up this test -				 * at the moment it occasionally fails when the sphere collection is tight and small -				 * (2 meters or less) -				if (2 == uncontained_directions.size() ) -				{ -					// if there were only two uncontained spheres then -					// the two directions should be nearly opposite -					F32 dir_dot = uncontained_directions[0] * uncontained_directions[1]; -					ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f); -				} -				*/ -			} -		} -	} +    struct sphere_data +    { +    }; +    typedef test_group<sphere_data> sphere_test; +    typedef sphere_test::object sphere_object; +    tut::sphere_test tsphere("LLSphere"); + +    template<> template<> +    void sphere_object::test<1>() +    { +        // test LLSphere::contains() and ::overlaps() +        S32 number_of_tests = 10; +        for (S32 test = 0; test < number_of_tests; ++test) +        { +            LLVector3 first_center(1.f, 1.f, 1.f); +            F32 first_radius = 3.f; +            LLSphere first_sphere( first_center, first_radius ); + +            F32 half_millimeter = 0.0005f; +            LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); +            direction.normalize(); + +            F32 distance = ll_frand(first_radius - 2.f * half_millimeter); +            LLVector3 second_center = first_center + distance * direction; +            F32 second_radius = first_radius - distance - half_millimeter; +            LLSphere second_sphere( second_center, second_radius ); +            ensure("first sphere should contain the second", first_sphere.contains(second_sphere)); +            ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere)); + +            distance = first_radius + ll_frand(first_radius); +            second_center = first_center + distance * direction; +            second_radius = distance - first_radius + half_millimeter; +            second_sphere.set( second_center, second_radius ); +            ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere)); +            ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere)); + +            distance = first_radius + ll_frand(first_radius) + half_millimeter; +            second_center = first_center + distance * direction; +            second_radius = distance - first_radius - half_millimeter; +            second_sphere.set( second_center, second_radius ); +            ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere)); +            ensure("first sphere should NOT overlap the second", !first_sphere.overlaps(second_sphere)); +        } +    } + +    template<> template<> +    void sphere_object::test<2>() +    { +        skip("See SNOW-620.  Neither the test nor the code being tested seem good.  Also sim-only."); + +        // test LLSphere::getBoundingSphere() +        S32 number_of_tests = 100; +        S32 number_of_spheres = 10; +        F32 sphere_center_range = 32.f; +        F32 sphere_radius_range = 5.f; + +        for (S32 test = 0; test < number_of_tests; ++test) +        { +            // gegnerate a bunch of random sphere +            std::vector< LLSphere > sphere_list; +            for (S32 sphere_count=0; sphere_count < number_of_spheres; ++sphere_count) +            { +                LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); +                direction.normalize(); +                F32 distance = ll_frand(sphere_center_range); +                LLVector3 center = distance * direction; +                F32 radius = ll_frand(sphere_radius_range); +                LLSphere sphere( center, radius ); +                sphere_list.push_back(sphere); +            } + +            // compute the bounding sphere +            LLSphere bounding_sphere = LLSphere::getBoundingSphere(sphere_list); + +            // make sure all spheres are inside the bounding sphere +            { +                std::vector< LLSphere >::const_iterator sphere_itr; +                for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) +                { +                    ensure("sphere should be contained by the bounding sphere", bounding_sphere.contains(*sphere_itr)); +                } +            } + +            // TODO -- improve LLSphere::getBoundingSphere() to the point where +            // we can reduce the 'expansion' in the two tests below to about +            // 2 mm or less + +            F32 expansion = 0.005f; +            // move all spheres out a little bit +            // and count how many are NOT contained +            { +                std::vector< LLVector3 > uncontained_directions; +                std::vector< LLSphere >::iterator sphere_itr; +                for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) +                { +                    LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter(); +                    direction.normalize(); + +                    sphere_itr->setCenter( sphere_itr->getCenter() + expansion * direction ); +                    if (! bounding_sphere.contains( *sphere_itr ) ) +                    { +                        uncontained_directions.push_back(direction); +                    } +                } +                ensure("when moving spheres out there should be at least two uncontained spheres", +                        uncontained_directions.size() > 1); + +                /* TODO -- when the bounding sphere algorithm is improved we can open up this test +                 * at the moment it occasionally fails when the sphere collection is tight and small +                 * (2 meters or less) +                if (2 == uncontained_directions.size() ) +                { +                    // if there were only two uncontained spheres then +                    // the two directions should be nearly opposite +                    F32 dir_dot = uncontained_directions[0] * uncontained_directions[1]; +                    ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f); +                } +                */ +            } + +            // compute the new bounding sphere +            bounding_sphere = LLSphere::getBoundingSphere(sphere_list); + +            // increase the size of all spheres a little bit +            // and count how many are NOT contained +            { +                std::vector< LLVector3 > uncontained_directions; +                std::vector< LLSphere >::iterator sphere_itr; +                for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) +                { +                    LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter(); +                    direction.normalize(); + +                    sphere_itr->setRadius( sphere_itr->getRadius() + expansion ); +                    if (! bounding_sphere.contains( *sphere_itr ) ) +                    { +                        uncontained_directions.push_back(direction); +                    } +                } +                ensure("when boosting sphere radii there should be at least two uncontained spheres", +                        uncontained_directions.size() > 1); + +                /* TODO -- when the bounding sphere algorithm is improved we can open up this test +                 * at the moment it occasionally fails when the sphere collection is tight and small +                 * (2 meters or less) +                if (2 == uncontained_directions.size() ) +                { +                    // if there were only two uncontained spheres then +                    // the two directions should be nearly opposite +                    F32 dir_dot = uncontained_directions[0] * uncontained_directions[1]; +                    ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f); +                } +                */ +            } +        } +    }  }  namespace tut  { -	F32 SMALL_RADIUS = 1.0f; -	F32 MEDIUM_RADIUS = 5.0f; -	F32 LARGE_RADIUS = 10.0f; - -	struct line_data -	{ -	}; -	typedef test_group<line_data> line_test; -	typedef line_test::object line_object; -	tut::line_test tline("LLLine"); - -	template<> template<> -	void line_object::test<1>() -	{ -		// this is a test for LLLine::intersects(point) which returns TRUE  -		// if the line passes within some tolerance of point - -		// these tests will have some floating point error,  -		// so we need to specify how much error is ok -		F32 allowable_relative_error = 0.00001f; -		S32 number_of_tests = 100; -		for (S32 test = 0; test < number_of_tests; ++test) -		{ -			// generate some random point to be on the line -			LLVector3 point_on_line( ll_frand(2.f) - 1.f,  -			   						 ll_frand(2.f) - 1.f,  -			   						 ll_frand(2.f) - 1.f); -			point_on_line.normalize(); -			point_on_line *= ll_frand(LARGE_RADIUS); - -			// generate some random point to "intersect" -			LLVector3 random_direction ( ll_frand(2.f) - 1.f,  -			   							 ll_frand(2.f) - 1.f,  -			   							 ll_frand(2.f) - 1.f); -			random_direction.normalize(); - -			LLVector3 random_offset( ll_frand(2.f) - 1.f,  -			   						 ll_frand(2.f) - 1.f,  -			   						 ll_frand(2.f) - 1.f); -			random_offset.normalize(); -			random_offset *= ll_frand(SMALL_RADIUS); - -			LLVector3 point = point_on_line + MEDIUM_RADIUS * random_direction -				+ random_offset; -	 -			// compute the axis of approach (a unit vector between the points) -			LLVector3 axis_of_approach = point - point_on_line; -			axis_of_approach.normalize(); -	 -			// compute the direction of the the first line (perp to axis_of_approach) -			LLVector3 first_dir( ll_frand(2.f) - 1.f,  -			   					 ll_frand(2.f) - 1.f,  -			   					 ll_frand(2.f) - 1.f); -			first_dir.normalize(); -			F32 dot = first_dir * axis_of_approach;		 -			first_dir -= dot * axis_of_approach;	// subtract component parallel to axis -			first_dir.normalize(); -	 -			// construct the line -			LLVector3 another_point_on_line = point_on_line + ll_frand(LARGE_RADIUS) * first_dir; -			LLLine line(another_point_on_line, point_on_line); -	 -			// test that the intersection point is within MEDIUM_RADIUS + SMALL_RADIUS -			F32 test_radius = MEDIUM_RADIUS + SMALL_RADIUS; -			test_radius += (LARGE_RADIUS * allowable_relative_error); -			ensure("line should pass near intersection point", line.intersects(point, test_radius)); - -			test_radius = allowable_relative_error * (point - point_on_line).length(); -			ensure("line should intersect point used to define it", line.intersects(point_on_line, test_radius)); -		} -	} - -	template<> template<> -	void line_object::test<2>() -	{ +    F32 SMALL_RADIUS = 1.0f; +    F32 MEDIUM_RADIUS = 5.0f; +    F32 LARGE_RADIUS = 10.0f; + +    struct line_data +    { +    }; +    typedef test_group<line_data> line_test; +    typedef line_test::object line_object; +    tut::line_test tline("LLLine"); + +    template<> template<> +    void line_object::test<1>() +    { +        // this is a test for LLLine::intersects(point) which returns TRUE +        // if the line passes within some tolerance of point + +        // these tests will have some floating point error, +        // so we need to specify how much error is ok +        F32 allowable_relative_error = 0.00001f; +        S32 number_of_tests = 100; +        for (S32 test = 0; test < number_of_tests; ++test) +        { +            // generate some random point to be on the line +            LLVector3 point_on_line( ll_frand(2.f) - 1.f, +                                     ll_frand(2.f) - 1.f, +                                     ll_frand(2.f) - 1.f); +            point_on_line.normalize(); +            point_on_line *= ll_frand(LARGE_RADIUS); + +            // generate some random point to "intersect" +            LLVector3 random_direction ( ll_frand(2.f) - 1.f, +                                         ll_frand(2.f) - 1.f, +                                         ll_frand(2.f) - 1.f); +            random_direction.normalize(); + +            LLVector3 random_offset( ll_frand(2.f) - 1.f, +                                     ll_frand(2.f) - 1.f, +                                     ll_frand(2.f) - 1.f); +            random_offset.normalize(); +            random_offset *= ll_frand(SMALL_RADIUS); + +            LLVector3 point = point_on_line + MEDIUM_RADIUS * random_direction +                + random_offset; + +            // compute the axis of approach (a unit vector between the points) +            LLVector3 axis_of_approach = point - point_on_line; +            axis_of_approach.normalize(); + +            // compute the direction of the the first line (perp to axis_of_approach) +            LLVector3 first_dir( ll_frand(2.f) - 1.f, +                                 ll_frand(2.f) - 1.f, +                                 ll_frand(2.f) - 1.f); +            first_dir.normalize(); +            F32 dot = first_dir * axis_of_approach; +            first_dir -= dot * axis_of_approach;    // subtract component parallel to axis +            first_dir.normalize(); + +            // construct the line +            LLVector3 another_point_on_line = point_on_line + ll_frand(LARGE_RADIUS) * first_dir; +            LLLine line(another_point_on_line, point_on_line); + +            // test that the intersection point is within MEDIUM_RADIUS + SMALL_RADIUS +            F32 test_radius = MEDIUM_RADIUS + SMALL_RADIUS; +            test_radius += (LARGE_RADIUS * allowable_relative_error); +            ensure("line should pass near intersection point", line.intersects(point, test_radius)); + +            test_radius = allowable_relative_error * (point - point_on_line).length(); +            ensure("line should intersect point used to define it", line.intersects(point_on_line, test_radius)); +        } +    } + +    template<> template<> +    void line_object::test<2>() +    {            /*              These tests fail intermittently on all platforms - see DEV-16600              Commenting this out until dev has time to investigate. -             -		// this is a test for LLLine::nearestApproach(LLLIne) method -		// which computes the point on a line nearest another line - -		// these tests will have some floating point error,  -		// so we need to specify how much error is ok -		// TODO -- make nearestApproach() algorithm more accurate so -		// we can tighten the allowable_error.  Most tests are tighter -		// than one milimeter, however when doing randomized testing -		// you can walk into inaccurate cases. -		F32 allowable_relative_error = 0.001f; -		S32 number_of_tests = 100; -		for (S32 test = 0; test < number_of_tests; ++test) -		{ -			// generate two points to be our known nearest approaches -			LLVector3 some_point( ll_frand(2.f) - 1.f,  -			   					  ll_frand(2.f) - 1.f,  -			   					  ll_frand(2.f) - 1.f); -			some_point.normalize(); -			some_point *= ll_frand(LARGE_RADIUS); - -			LLVector3 another_point( ll_frand(2.f) - 1.f,  -			   						 ll_frand(2.f) - 1.f,  -			   						 ll_frand(2.f) - 1.f); -			another_point.normalize(); -			another_point *= ll_frand(LARGE_RADIUS); - -			// compute the axis of approach (a unit vector between the points) -			LLVector3 axis_of_approach = another_point - some_point; -			axis_of_approach.normalize(); -	 -			// compute the direction of the the first line (perp to axis_of_approach) -			LLVector3 first_dir( ll_frand(2.f) - 1.f,  -			   					 ll_frand(2.f) - 1.f,  -			   					 ll_frand(2.f) - 1.f); -			F32 dot = first_dir * axis_of_approach;		 -			first_dir -= dot * axis_of_approach;		// subtract component parallel to axis -			first_dir.normalize();						// normalize -	 -			// compute the direction of the the second line -			LLVector3 second_dir( ll_frand(2.f) - 1.f,  -			   					  ll_frand(2.f) - 1.f,  -			   					  ll_frand(2.f) - 1.f); -			dot = second_dir * axis_of_approach;		 -			second_dir -= dot * axis_of_approach; -			second_dir.normalize(); - -			// make sure the lines aren't too parallel,  -			dot = fabsf(first_dir * second_dir); -			if (dot > 0.99f) -			{ -				// skip this test, we're not interested in testing  -				// the intractible cases -				continue; -			} -	 -			// construct the lines -			LLVector3 first_point = some_point + ll_frand(LARGE_RADIUS) * first_dir; -			LLLine first_line(first_point, some_point); -	 -			LLVector3 second_point = another_point + ll_frand(LARGE_RADIUS) * second_dir; -			LLLine second_line(second_point, another_point); -	 -			// compute the points of nearest approach -			LLVector3 some_computed_point = first_line.nearestApproach(second_line); -			LLVector3 another_computed_point = second_line.nearestApproach(first_line); -	 -			// compute the error -			F32 first_error = (some_point - some_computed_point).length(); -			F32 scale = llmax((some_point - another_point).length(), some_point.length()); -			scale = llmax(scale, another_point.length()); -			scale = llmax(scale, 1.f); -			F32 first_relative_error = first_error / scale; - -			F32 second_error = (another_point - another_computed_point).length(); -			F32 second_relative_error = second_error / scale; - -			//if (first_relative_error > allowable_relative_error) -			//{ -			//	std::cout << "first_error = " << first_error  -			//		<< "  first_relative_error = " << first_relative_error  -			//		<< "  scale = " << scale  -			//		<< "  dir_dot = " << (first_dir * second_dir) -			//		<< std::endl; -			//} -			//if (second_relative_error > allowable_relative_error) -			//{ -			//	std::cout << "second_error = " << second_error  -			//		<< "  second_relative_error = " << second_relative_error  -			//		<< "  scale = " << scale  -			//		<< "  dist = " << (some_point - another_point).length() -			//		<< "  dir_dot = " << (first_dir * second_dir) -			//		<< std::endl; -			//} - -			// test that the errors are small - -			ensure("first line should accurately compute its closest approach",  -					first_relative_error <= allowable_relative_error); -			ensure("second line should accurately compute its closest approach",  -					second_relative_error <= allowable_relative_error); -		} + +        // this is a test for LLLine::nearestApproach(LLLIne) method +        // which computes the point on a line nearest another line + +        // these tests will have some floating point error, +        // so we need to specify how much error is ok +        // TODO -- make nearestApproach() algorithm more accurate so +        // we can tighten the allowable_error.  Most tests are tighter +        // than one milimeter, however when doing randomized testing +        // you can walk into inaccurate cases. +        F32 allowable_relative_error = 0.001f; +        S32 number_of_tests = 100; +        for (S32 test = 0; test < number_of_tests; ++test) +        { +            // generate two points to be our known nearest approaches +            LLVector3 some_point( ll_frand(2.f) - 1.f, +                                  ll_frand(2.f) - 1.f, +                                  ll_frand(2.f) - 1.f); +            some_point.normalize(); +            some_point *= ll_frand(LARGE_RADIUS); + +            LLVector3 another_point( ll_frand(2.f) - 1.f, +                                     ll_frand(2.f) - 1.f, +                                     ll_frand(2.f) - 1.f); +            another_point.normalize(); +            another_point *= ll_frand(LARGE_RADIUS); + +            // compute the axis of approach (a unit vector between the points) +            LLVector3 axis_of_approach = another_point - some_point; +            axis_of_approach.normalize(); + +            // compute the direction of the the first line (perp to axis_of_approach) +            LLVector3 first_dir( ll_frand(2.f) - 1.f, +                                 ll_frand(2.f) - 1.f, +                                 ll_frand(2.f) - 1.f); +            F32 dot = first_dir * axis_of_approach; +            first_dir -= dot * axis_of_approach;        // subtract component parallel to axis +            first_dir.normalize();                      // normalize + +            // compute the direction of the the second line +            LLVector3 second_dir( ll_frand(2.f) - 1.f, +                                  ll_frand(2.f) - 1.f, +                                  ll_frand(2.f) - 1.f); +            dot = second_dir * axis_of_approach; +            second_dir -= dot * axis_of_approach; +            second_dir.normalize(); + +            // make sure the lines aren't too parallel, +            dot = fabsf(first_dir * second_dir); +            if (dot > 0.99f) +            { +                // skip this test, we're not interested in testing +                // the intractible cases +                continue; +            } + +            // construct the lines +            LLVector3 first_point = some_point + ll_frand(LARGE_RADIUS) * first_dir; +            LLLine first_line(first_point, some_point); + +            LLVector3 second_point = another_point + ll_frand(LARGE_RADIUS) * second_dir; +            LLLine second_line(second_point, another_point); + +            // compute the points of nearest approach +            LLVector3 some_computed_point = first_line.nearestApproach(second_line); +            LLVector3 another_computed_point = second_line.nearestApproach(first_line); + +            // compute the error +            F32 first_error = (some_point - some_computed_point).length(); +            F32 scale = llmax((some_point - another_point).length(), some_point.length()); +            scale = llmax(scale, another_point.length()); +            scale = llmax(scale, 1.f); +            F32 first_relative_error = first_error / scale; + +            F32 second_error = (another_point - another_computed_point).length(); +            F32 second_relative_error = second_error / scale; + +            //if (first_relative_error > allowable_relative_error) +            //{ +            //  std::cout << "first_error = " << first_error +            //      << "  first_relative_error = " << first_relative_error +            //      << "  scale = " << scale +            //      << "  dir_dot = " << (first_dir * second_dir) +            //      << std::endl; +            //} +            //if (second_relative_error > allowable_relative_error) +            //{ +            //  std::cout << "second_error = " << second_error +            //      << "  second_relative_error = " << second_relative_error +            //      << "  scale = " << scale +            //      << "  dist = " << (some_point - another_point).length() +            //      << "  dir_dot = " << (first_dir * second_dir) +            //      << std::endl; +            //} + +            // test that the errors are small + +            ensure("first line should accurately compute its closest approach", +                    first_relative_error <= allowable_relative_error); +            ensure("second line should accurately compute its closest approach", +                    second_relative_error <= allowable_relative_error); +        }            */ -	} - -	F32 ALMOST_PARALLEL = 0.99f; -	template<> template<> -	void line_object::test<3>() -	{ -		// this is a test for LLLine::getIntersectionBetweenTwoPlanes() method - -		// first some known tests -		LLLine xy_plane(LLVector3(0.f, 0.f, 2.f), LLVector3(0.f, 0.f, 3.f)); -		LLLine yz_plane(LLVector3(2.f, 0.f, 0.f), LLVector3(3.f, 0.f, 0.f)); -		LLLine zx_plane(LLVector3(0.f, 2.f, 0.f), LLVector3(0.f, 3.f, 0.f)); - -		LLLine x_line; -		LLLine y_line; -		LLLine z_line; - -		bool x_success = LLLine::getIntersectionBetweenTwoPlanes(x_line, xy_plane, zx_plane); -		bool y_success = LLLine::getIntersectionBetweenTwoPlanes(y_line, yz_plane, xy_plane); -		bool z_success = LLLine::getIntersectionBetweenTwoPlanes(z_line, zx_plane, yz_plane); - -		ensure("xy and zx planes should intersect", x_success); -		ensure("yz and xy planes should intersect", y_success); -		ensure("zx and yz planes should intersect", z_success); - -		LLVector3 direction = x_line.getDirection(); -		ensure("x_line should be parallel to x_axis", fabs(direction.mV[VX]) == 1.f -				                                      && 0.f == direction.mV[VY] -				                                      && 0.f == direction.mV[VZ] ); -		direction = y_line.getDirection(); -		ensure("y_line should be parallel to y_axis", 0.f == direction.mV[VX] -													  && fabs(direction.mV[VY]) == 1.f -				                                      && 0.f == direction.mV[VZ] ); -		direction = z_line.getDirection(); -		ensure("z_line should be parallel to z_axis", 0.f == direction.mV[VX] -				                                      && 0.f == direction.mV[VY] -													  && fabs(direction.mV[VZ]) == 1.f ); - -		// next some random tests -		F32 allowable_relative_error = 0.0001f; -		S32 number_of_tests = 20; -		for (S32 test = 0; test < number_of_tests; ++test) -		{ -			// generate the known line -			LLVector3 some_point( ll_frand(2.f) - 1.f,  -			   					  ll_frand(2.f) - 1.f,  -			   					  ll_frand(2.f) - 1.f); -			some_point.normalize(); -			some_point *= ll_frand(LARGE_RADIUS); -			LLVector3 another_point( ll_frand(2.f) - 1.f,  -			   						 ll_frand(2.f) - 1.f,  -			   						 ll_frand(2.f) - 1.f); -			another_point.normalize(); -			another_point *= ll_frand(LARGE_RADIUS); -			LLLine known_intersection(some_point, another_point); - -			// compute a plane that intersect the line -			LLVector3 point_on_plane( ll_frand(2.f) - 1.f,  -			   						  ll_frand(2.f) - 1.f,  -			   						  ll_frand(2.f) - 1.f); -			point_on_plane.normalize(); -			point_on_plane *= ll_frand(LARGE_RADIUS); -			LLVector3 plane_normal = (point_on_plane - some_point) % known_intersection.getDirection(); -			plane_normal.normalize(); -			LLLine first_plane(point_on_plane, point_on_plane + plane_normal); - -			// compute a different plane that intersect the line -			LLVector3 point_on_different_plane( ll_frand(2.f) - 1.f,  -			   									ll_frand(2.f) - 1.f,  -			   									ll_frand(2.f) - 1.f); -			point_on_different_plane.normalize(); -			point_on_different_plane *= ll_frand(LARGE_RADIUS); -			LLVector3 different_plane_normal = (point_on_different_plane - another_point) % known_intersection.getDirection(); -			different_plane_normal.normalize(); -			LLLine second_plane(point_on_different_plane, point_on_different_plane + different_plane_normal); - -			if (fabs(plane_normal * different_plane_normal) > ALMOST_PARALLEL) -			{ -				// the two planes are approximately parallel, so we won't test this case -				continue; -			} - -			LLLine measured_intersection; -			bool success = LLLine::getIntersectionBetweenTwoPlanes( -					measured_intersection, -					first_plane, -					second_plane); - -			ensure("plane intersection should succeed", success); - -			F32 dot = fabs(known_intersection.getDirection() * measured_intersection.getDirection()); -			ensure("measured intersection should be parallel to known intersection", -					dot > ALMOST_PARALLEL); - -			ensure("measured intersection should pass near known point", -					measured_intersection.intersects(some_point, LARGE_RADIUS * allowable_relative_error)); -		} -	} +    } + +    F32 ALMOST_PARALLEL = 0.99f; +    template<> template<> +    void line_object::test<3>() +    { +        // this is a test for LLLine::getIntersectionBetweenTwoPlanes() method + +        // first some known tests +        LLLine xy_plane(LLVector3(0.f, 0.f, 2.f), LLVector3(0.f, 0.f, 3.f)); +        LLLine yz_plane(LLVector3(2.f, 0.f, 0.f), LLVector3(3.f, 0.f, 0.f)); +        LLLine zx_plane(LLVector3(0.f, 2.f, 0.f), LLVector3(0.f, 3.f, 0.f)); + +        LLLine x_line; +        LLLine y_line; +        LLLine z_line; + +        bool x_success = LLLine::getIntersectionBetweenTwoPlanes(x_line, xy_plane, zx_plane); +        bool y_success = LLLine::getIntersectionBetweenTwoPlanes(y_line, yz_plane, xy_plane); +        bool z_success = LLLine::getIntersectionBetweenTwoPlanes(z_line, zx_plane, yz_plane); + +        ensure("xy and zx planes should intersect", x_success); +        ensure("yz and xy planes should intersect", y_success); +        ensure("zx and yz planes should intersect", z_success); + +        LLVector3 direction = x_line.getDirection(); +        ensure("x_line should be parallel to x_axis", fabs(direction.mV[VX]) == 1.f +                                                      && 0.f == direction.mV[VY] +                                                      && 0.f == direction.mV[VZ] ); +        direction = y_line.getDirection(); +        ensure("y_line should be parallel to y_axis", 0.f == direction.mV[VX] +                                                      && fabs(direction.mV[VY]) == 1.f +                                                      && 0.f == direction.mV[VZ] ); +        direction = z_line.getDirection(); +        ensure("z_line should be parallel to z_axis", 0.f == direction.mV[VX] +                                                      && 0.f == direction.mV[VY] +                                                      && fabs(direction.mV[VZ]) == 1.f ); + +        // next some random tests +        F32 allowable_relative_error = 0.0001f; +        S32 number_of_tests = 20; +        for (S32 test = 0; test < number_of_tests; ++test) +        { +            // generate the known line +            LLVector3 some_point( ll_frand(2.f) - 1.f, +                                  ll_frand(2.f) - 1.f, +                                  ll_frand(2.f) - 1.f); +            some_point.normalize(); +            some_point *= ll_frand(LARGE_RADIUS); +            LLVector3 another_point( ll_frand(2.f) - 1.f, +                                     ll_frand(2.f) - 1.f, +                                     ll_frand(2.f) - 1.f); +            another_point.normalize(); +            another_point *= ll_frand(LARGE_RADIUS); +            LLLine known_intersection(some_point, another_point); + +            // compute a plane that intersect the line +            LLVector3 point_on_plane( ll_frand(2.f) - 1.f, +                                      ll_frand(2.f) - 1.f, +                                      ll_frand(2.f) - 1.f); +            point_on_plane.normalize(); +            point_on_plane *= ll_frand(LARGE_RADIUS); +            LLVector3 plane_normal = (point_on_plane - some_point) % known_intersection.getDirection(); +            plane_normal.normalize(); +            LLLine first_plane(point_on_plane, point_on_plane + plane_normal); + +            // compute a different plane that intersect the line +            LLVector3 point_on_different_plane( ll_frand(2.f) - 1.f, +                                                ll_frand(2.f) - 1.f, +                                                ll_frand(2.f) - 1.f); +            point_on_different_plane.normalize(); +            point_on_different_plane *= ll_frand(LARGE_RADIUS); +            LLVector3 different_plane_normal = (point_on_different_plane - another_point) % known_intersection.getDirection(); +            different_plane_normal.normalize(); +            LLLine second_plane(point_on_different_plane, point_on_different_plane + different_plane_normal); + +            if (fabs(plane_normal * different_plane_normal) > ALMOST_PARALLEL) +            { +                // the two planes are approximately parallel, so we won't test this case +                continue; +            } + +            LLLine measured_intersection; +            bool success = LLLine::getIntersectionBetweenTwoPlanes( +                    measured_intersection, +                    first_plane, +                    second_plane); + +            ensure("plane intersection should succeed", success); + +            F32 dot = fabs(known_intersection.getDirection() * measured_intersection.getDirection()); +            ensure("measured intersection should be parallel to known intersection", +                    dot > ALMOST_PARALLEL); + +            ensure("measured intersection should pass near known point", +                    measured_intersection.intersects(some_point, LARGE_RADIUS * allowable_relative_error)); +        } +    }  } diff --git a/indra/llmath/tests/v2math_test.cpp b/indra/llmath/tests/v2math_test.cpp index 4d6a2eca93..f66142c6a7 100644 --- a/indra/llmath/tests/v2math_test.cpp +++ b/indra/llmath/tests/v2math_test.cpp @@ -7,442 +7,442 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */  #include "linden_common.h" -#include "../test/lltut.h"  +#include "../test/lltut.h"  #include "../v2math.h"  namespace tut  { -	struct v2math_data -	{ -	}; -	typedef test_group<v2math_data> v2math_test; -	typedef v2math_test::object v2math_object; -	tut::v2math_test v2math_testcase("v2math_h"); - -	template<> template<> -	void v2math_object::test<1>() -	{ -		LLVector2 vec2; -		ensure("LLVector2:Fail to initialize ", (0.f == vec2.mV[VX] && 0.f == vec2.mV[VY])); - -		F32 x =2.0f, y = 3.2f ; -		LLVector2 vec3(x,y); -		ensure("LLVector2(F32 x, F32 y):Fail to initialize ", (x == vec3.mV[VX]) && (y == vec3.mV[VY])); - -		const F32 vec[2] = {3.2f, 4.5f}; -		LLVector2 vec4(vec); -		ensure("LLVector2(const F32 *vec):Fail to initialize ", (vec[0] == vec4.mV[VX]) && (vec[1] == vec4.mV[VY])); - -		vec4.clearVec(); -		ensure("clearVec():Fail to clean the values ", (0.f == vec4.mV[VX] && 0.f == vec4.mV[VY])); - -		vec3.zeroVec(); -		ensure("zeroVec():Fail to fill the zero ", (0.f == vec3.mV[VX] && 0.f == vec3.mV[VY])); -	} - -	template<> template<> -	void v2math_object::test<2>() -	{ -		F32 x = 123.356f, y = 2387.453f; -		LLVector2 vec2,vec3; -		vec2.setVec(x, y); -		ensure("1:setVec: Fail  ", (x == vec2.mV[VX]) && (y == vec2.mV[VY])); - -		vec3.setVec(vec2); -		ensure("2:setVec: Fail   " ,(vec2 == vec3)); - -		vec3.zeroVec(); -		const F32 vec[2] = {3.24653f, 457653.4f}; -		vec3.setVec(vec); -		ensure("3:setVec: Fail  ", (vec[0] == vec3.mV[VX]) && (vec[1] == vec3.mV[VY])); -	} - -	template<> template<> -	void v2math_object::test<3>() -	{ -		F32 x = 2.2345f, y = 3.5678f ; -		LLVector2 vec2(x,y); -		ensure("magVecSquared:Fail ", is_approx_equal(vec2.magVecSquared(), (x*x + y*y))); -		ensure("magVec:Fail ", is_approx_equal(vec2.magVec(), (F32) sqrt(x*x + y*y))); -	} - -	template<> template<> -	void v2math_object::test<4>() -	{ -		F32 x =-2.0f, y = -3.0f ; -		LLVector2 vec2(x,y); -		ensure_equals("abs():Fail", vec2.abs(), TRUE); -		ensure("abs() x", is_approx_equal(vec2.mV[VX], 2.f)); -		ensure("abs() y", is_approx_equal(vec2.mV[VY], 3.f)); - -		ensure("isNull():Fail ", FALSE == vec2.isNull());	//Returns TRUE if vector has a _very_small_ length - -		x =.00000001f, y = .000001001f; -		vec2.setVec(x, y); -		ensure("isNull(): Fail ", TRUE == vec2.isNull());	 -	} - -	template<> template<> -	void v2math_object::test<5>() -	{ -		F32 x =1.f, y = 2.f; -		LLVector2 vec2(x, y), vec3; -		vec3 = vec3.scaleVec(vec2); -		ensure("scaleVec: Fail ", vec3.mV[VX] == 0. && vec3.mV[VY] == 0.); -		ensure("isExactlyZero(): Fail", TRUE == vec3.isExactlyZero()); - -		vec3.setVec(2.f, 1.f); -		vec3 = vec3.scaleVec(vec2); -		ensure("scaleVec: Fail ", (2.f == vec3.mV[VX]) && (2.f == vec3.mV[VY])); -		ensure("isExactlyZero():Fail", FALSE == vec3.isExactlyZero()); -	} - -	template<> template<> -	void v2math_object::test<6>() -	{ -		F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f; -		F32 val1, val2; -		LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; -		vec4 = vec2 + vec3 ; -		val1 = x1+x2; -		val2 = y1+y2; -		ensure("1:operator+ failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));  - -		vec2.clearVec(); -		vec3.clearVec(); -		x1 = -.235f, y1 = -24.32f,  x2 = -2.3f, y2 = 1.f; -		vec2.setVec(x1, y1); -		vec3.setVec(x2, y2); -		vec4 = vec2 + vec3; -		val1 = x1+x2; -		val2 = y1+y2; -		ensure("2:operator+ failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));  -	} - -	template<> template<> -	void v2math_object::test<7>() -	{ -		F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; -		F32 val1, val2; -		LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; -		vec4 = vec2 - vec3 ; -		val1 = x1-x2; -		val2 = y1-y2; -		ensure("1:operator- failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));  - -		vec2.clearVec(); -		vec3.clearVec(); -		vec4.clearVec(); -		x1 = -.235f, y1 = -24.32f,  x2 = -2.3f, y2 = 1.f; -		vec2.setVec(x1, y1); -		vec3.setVec(x2, y2); -		vec4 = vec2 - vec3; -		val1 = x1-x2; -		val2 = y1-y2; -		ensure("2:operator- failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));  -	} - -	template<> template<> -	void v2math_object::test<8>() -	{ -		F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; -		F32 val1, val2; -		LLVector2 vec2(x1, y1), vec3(x2, y2); -		val1 = vec2 * vec3; -		val2 = x1*x2 + y1*y2; -		ensure("1:operator* failed",(val1 == val2)); - -		vec3.clearVec(); -		F32 mulVal = 4.332f; -		vec3 = vec2 * mulVal; -		val1 = x1*mulVal; -		val2 = y1*mulVal; -		ensure("2:operator* failed",(val1 == vec3.mV[VX]) && (val2 == vec3.mV[VY])); - -		vec3.clearVec(); -		vec3 = mulVal * vec2; -		ensure("3:operator* failed",(val1 == vec3.mV[VX]) && (val2 == vec3.mV[VY]));		 -	} - -	template<> template<> -	void v2math_object::test<9>() -	{ -		F32 x1 =1.f, y1 = 2.f, div = 3.2f; -		F32 val1, val2; -		LLVector2 vec2(x1, y1), vec3; -		vec3 = vec2 / div; -		val1 = x1 / div; -		val2 = y1 / div; -		ensure("1:operator/ failed", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]));		 - -		vec3.clearVec(); -		x1 = -.235f, y1 = -24.32f, div = -2.2f; -		vec2.setVec(x1, y1); -		vec3 = vec2 / div; -		val1 = x1 / div; -		val2 = y1 / div; -		ensure("2:operator/ failed", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]));		 -	} - -	template<> template<> -	void v2math_object::test<10>() -	{ -		F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; -		F32 val1, val2; -		LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; -		vec4 = vec2 % vec3; -		val1 = x1*y2 - x2*y1; -		val2 = y1*x2 - y2*x1; -		ensure("1:operator% failed",(val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY]));	 - -		vec2.clearVec(); -		vec3.clearVec(); -		vec4.clearVec(); -		x1 = -.235f, y1 = -24.32f,  x2 = -2.3f, y2 = 1.f; -		vec2.setVec(x1, y1); -		vec3.setVec(x2, y2); -		vec4 = vec2 % vec3; -		val1 = x1*y2 - x2*y1; -		val2 = y1*x2 - y2*x1; -		ensure("2:operator% failed",(val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY]));	 -	} -	template<> template<> -	void v2math_object::test<11>() -	{ -		F32 x1 =1.f, y1 = 2.f; -		LLVector2 vec2(x1, y1), vec3(x1, y1); -		ensure("1:operator== failed",(vec2 == vec3)); -		 -		vec2.clearVec(); -		vec3.clearVec(); -		x1 = -.235f, y1 = -24.32f; -		vec2.setVec(x1, y1); -		vec3.setVec(vec2); -		ensure("2:operator== failed",(vec2 == vec3)); -	} - -	template<> template<> -	void v2math_object::test<12>() -	{ -		F32 x1 = 1.f, y1 = 2.f,x2 = 2.332f, y2 = -1.23f; -		LLVector2 vec2(x1, y1), vec3(x2, y2); -		ensure("1:operator!= failed",(vec2 != vec3)); -		 -		vec2.clearVec(); -		vec3.clearVec(); -		vec2.setVec(x1, y1); -		vec3.setVec(vec2); -		ensure("2:operator!= failed", (FALSE == (vec2 != vec3))); -	} -	template<> template<> -	void v2math_object::test<13>() -	{ -		F32 x1 = 1.f, y1 = 2.f,x2 = 2.332f, y2 = -1.23f; -		F32 val1, val2; -		LLVector2 vec2(x1, y1), vec3(x2, y2); -		vec2 +=vec3; -		val1 = x1+x2; -		val2 = y1+y2; -		ensure("1:operator+= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); -		 -		vec2.setVec(x1, y1); -		vec2 -=vec3; -		val1 = x1-x2; -		val2 = y1-y2; -		ensure("2:operator-= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); -		 -		vec2.clearVec(); -		vec3.clearVec(); -		x1 = -21.000466f, y1 = 2.98382f,x2 = 0.332f, y2 = -01.23f; -		vec2.setVec(x1, y1); -		vec3.setVec(x2, y2); -		vec2 +=vec3; -		val1 = x1+x2; -		val2 = y1+y2; -		ensure("3:operator+= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); - -		vec2.setVec(x1, y1); -		vec2 -=vec3; -		val1 = x1-x2; -		val2 = y1-y2; -		ensure("4:operator-= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); -	} - -	template<> template<> -	void v2math_object::test<14>() -	{ -		F32 x1 =1.f, y1 = 2.f; -		F32 val1, val2, mulVal = 4.332f; -		LLVector2 vec2(x1, y1); -		vec2 /=mulVal; -		val1 = x1 / mulVal; -		val2 = y1 / mulVal; -		ensure("1:operator/= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); -		 -		vec2.clearVec(); -		x1 = .213f, y1 = -2.34f, mulVal = -.23f; -		vec2.setVec(x1, y1); -		vec2 /=mulVal; -		val1 = x1 / mulVal; -		val2 = y1 / mulVal; -		ensure("2:operator/= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); -	} - -	template<> template<> -	void v2math_object::test<15>() -	{ -		F32 x1 =1.f, y1 = 2.f; -		F32 val1, val2, mulVal = 4.332f; -		LLVector2 vec2(x1, y1); -		vec2 *=mulVal; -		val1 = x1*mulVal; -		val2 = y1*mulVal; -		ensure("1:operator*= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); -		 -		vec2.clearVec(); -		x1 = .213f, y1 = -2.34f, mulVal = -.23f; -		vec2.setVec(x1, y1); -		vec2 *=mulVal; -		val1 = x1*mulVal; -		val2 = y1*mulVal; -		ensure("2:operator*= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); -	} -	 -	template<> template<> -	void v2math_object::test<16>() -	{ -		F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; -		F32 val1, val2; -		LLVector2 vec2(x1, y1), vec3(x2, y2); -		vec2 %= vec3; -		val1 = x1*y2 - x2*y1; -		val2 = y1*x2 - y2*x1; -		ensure("1:operator%= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY]));	 -	} - -	template<> template<> -	void v2math_object::test<17>() -	{ -		F32 x1 =1.f, y1 = 2.f; -		LLVector2 vec2(x1, y1),vec3; -		vec3 = -vec2; -		ensure("1:operator- failed",(-vec3 == vec2));	 -	} - -	template<> template<> -	void v2math_object::test<18>() -	{ -		F32 x1 =1.f, y1 = 2.f; -		std::ostringstream stream1, stream2; -		LLVector2 vec2(x1, y1),vec3; -		stream1 << vec2; -		vec3.setVec(x1, y1); -		stream2 << vec3; -		ensure("1:operator << failed",(stream1.str() == stream2.str()));	 -	} - -	template<> template<> -	void v2math_object::test<19>() -	{ -		F32 x1 =1.0f, y1 = 2.0f, x2 = -.32f, y2 = .2234f; -		LLVector2 vec2(x1, y1),vec3(x2, y2); -		ensure("1:operator < failed",(vec3 < vec2));	 - -		x1 = 1.0f, y1 = 2.0f, x2 = 1.0f, y2 = 3.2234f; -		vec2.setVec(x1, y1); -		vec3.setVec(x2, y2); -		ensure("2:operator < failed", (FALSE == (vec3 < vec2)));	 -	} - -	template<> template<> -	void v2math_object::test<20>() -	{ -		F32 x1 =1.0f, y1 = 2.0f; -		LLVector2 vec2(x1, y1); -		ensure("1:operator [] failed",( x1 ==  vec2[0]));	 -		ensure("2:operator [] failed",( y1 ==  vec2[1])); - -		vec2.clearVec(); -		x1 = 23.0f, y1 = -.2361f; -		vec2.setVec(x1, y1); -		F32 ref1 = vec2[0]; -		ensure("3:operator [] failed", ( ref1 ==  x1)); -		F32 ref2 = vec2[1]; -		ensure("4:operator [] failed", ( ref2 ==  y1)); -	} - -	template<> template<> -	void v2math_object::test<21>() -	{ -		F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f; -		F32 val1, val2; -		LLVector2 vec2(x1, y1),vec3(x2, y2);		 -		val1 = dist_vec_squared2D(vec2, vec3); -		val2 = (x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2); -		ensure_equals("dist_vec_squared2D values are not equal",val2, val1); - -		val1 = dist_vec_squared(vec2, vec3); -		ensure_equals("dist_vec_squared values are not equal",val2, val1); - -		val1 = 	dist_vec(vec2, vec3); -		val2 = (F32) sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2)); -		ensure_equals("dist_vec values are not equal",val2, val1); -	} - -	template<> template<> -	void v2math_object::test<22>() -	{ -		F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f,fVal = .0121f; -		F32 val1, val2; -		LLVector2 vec2(x1, y1),vec3(x2, y2); -		LLVector2 vec4 = lerp(vec2, vec3, fVal); -		val1 = x1 + (x2 - x1) * fVal; -		val2 = y1 + (y2 - y1) * fVal; -		ensure("lerp values are not equal", ((val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY]))); -	} - -	template<> template<> -	void v2math_object::test<23>() -	{ -		F32 x1 =1.f, y1 = 2.f; -		F32 val1, val2; -		LLVector2 vec2(x1, y1); - -		F32 vecMag = vec2.normVec(); -		F32 mag = (F32) sqrt(x1*x1 + y1*y1); - -		F32 oomag = 1.f / mag; -		val1 = x1 * oomag; -		val2 = y1 * oomag; - -		ensure("normVec failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY]) && is_approx_equal(vecMag, mag)); - -		x1 =.00000001f, y1 = 0.f; - -		vec2.setVec(x1, y1); -		vecMag = vec2.normVec(); -		ensure("normVec failed should be 0.", 0. == vec2.mV[VX] && 0. == vec2.mV[VY] && vecMag == 0.); -	} +    struct v2math_data +    { +    }; +    typedef test_group<v2math_data> v2math_test; +    typedef v2math_test::object v2math_object; +    tut::v2math_test v2math_testcase("v2math_h"); + +    template<> template<> +    void v2math_object::test<1>() +    { +        LLVector2 vec2; +        ensure("LLVector2:Fail to initialize ", (0.f == vec2.mV[VX] && 0.f == vec2.mV[VY])); + +        F32 x =2.0f, y = 3.2f ; +        LLVector2 vec3(x,y); +        ensure("LLVector2(F32 x, F32 y):Fail to initialize ", (x == vec3.mV[VX]) && (y == vec3.mV[VY])); + +        const F32 vec[2] = {3.2f, 4.5f}; +        LLVector2 vec4(vec); +        ensure("LLVector2(const F32 *vec):Fail to initialize ", (vec[0] == vec4.mV[VX]) && (vec[1] == vec4.mV[VY])); + +        vec4.clearVec(); +        ensure("clearVec():Fail to clean the values ", (0.f == vec4.mV[VX] && 0.f == vec4.mV[VY])); + +        vec3.zeroVec(); +        ensure("zeroVec():Fail to fill the zero ", (0.f == vec3.mV[VX] && 0.f == vec3.mV[VY])); +    } + +    template<> template<> +    void v2math_object::test<2>() +    { +        F32 x = 123.356f, y = 2387.453f; +        LLVector2 vec2,vec3; +        vec2.setVec(x, y); +        ensure("1:setVec: Fail  ", (x == vec2.mV[VX]) && (y == vec2.mV[VY])); + +        vec3.setVec(vec2); +        ensure("2:setVec: Fail   " ,(vec2 == vec3)); + +        vec3.zeroVec(); +        const F32 vec[2] = {3.24653f, 457653.4f}; +        vec3.setVec(vec); +        ensure("3:setVec: Fail  ", (vec[0] == vec3.mV[VX]) && (vec[1] == vec3.mV[VY])); +    } + +    template<> template<> +    void v2math_object::test<3>() +    { +        F32 x = 2.2345f, y = 3.5678f ; +        LLVector2 vec2(x,y); +        ensure("magVecSquared:Fail ", is_approx_equal(vec2.magVecSquared(), (x*x + y*y))); +        ensure("magVec:Fail ", is_approx_equal(vec2.magVec(), (F32) sqrt(x*x + y*y))); +    } + +    template<> template<> +    void v2math_object::test<4>() +    { +        F32 x =-2.0f, y = -3.0f ; +        LLVector2 vec2(x,y); +        ensure_equals("abs():Fail", vec2.abs(), TRUE); +        ensure("abs() x", is_approx_equal(vec2.mV[VX], 2.f)); +        ensure("abs() y", is_approx_equal(vec2.mV[VY], 3.f)); + +        ensure("isNull():Fail ", FALSE == vec2.isNull());   //Returns TRUE if vector has a _very_small_ length + +        x =.00000001f, y = .000001001f; +        vec2.setVec(x, y); +        ensure("isNull(): Fail ", TRUE == vec2.isNull()); +    } + +    template<> template<> +    void v2math_object::test<5>() +    { +        F32 x =1.f, y = 2.f; +        LLVector2 vec2(x, y), vec3; +        vec3 = vec3.scaleVec(vec2); +        ensure("scaleVec: Fail ", vec3.mV[VX] == 0. && vec3.mV[VY] == 0.); +        ensure("isExactlyZero(): Fail", TRUE == vec3.isExactlyZero()); + +        vec3.setVec(2.f, 1.f); +        vec3 = vec3.scaleVec(vec2); +        ensure("scaleVec: Fail ", (2.f == vec3.mV[VX]) && (2.f == vec3.mV[VY])); +        ensure("isExactlyZero():Fail", FALSE == vec3.isExactlyZero()); +    } + +    template<> template<> +    void v2math_object::test<6>() +    { +        F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f; +        F32 val1, val2; +        LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; +        vec4 = vec2 + vec3 ; +        val1 = x1+x2; +        val2 = y1+y2; +        ensure("1:operator+ failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY]))); + +        vec2.clearVec(); +        vec3.clearVec(); +        x1 = -.235f, y1 = -24.32f,  x2 = -2.3f, y2 = 1.f; +        vec2.setVec(x1, y1); +        vec3.setVec(x2, y2); +        vec4 = vec2 + vec3; +        val1 = x1+x2; +        val2 = y1+y2; +        ensure("2:operator+ failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY]))); +    } + +    template<> template<> +    void v2math_object::test<7>() +    { +        F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; +        F32 val1, val2; +        LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; +        vec4 = vec2 - vec3 ; +        val1 = x1-x2; +        val2 = y1-y2; +        ensure("1:operator- failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY]))); + +        vec2.clearVec(); +        vec3.clearVec(); +        vec4.clearVec(); +        x1 = -.235f, y1 = -24.32f,  x2 = -2.3f, y2 = 1.f; +        vec2.setVec(x1, y1); +        vec3.setVec(x2, y2); +        vec4 = vec2 - vec3; +        val1 = x1-x2; +        val2 = y1-y2; +        ensure("2:operator- failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY]))); +    } + +    template<> template<> +    void v2math_object::test<8>() +    { +        F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; +        F32 val1, val2; +        LLVector2 vec2(x1, y1), vec3(x2, y2); +        val1 = vec2 * vec3; +        val2 = x1*x2 + y1*y2; +        ensure("1:operator* failed",(val1 == val2)); + +        vec3.clearVec(); +        F32 mulVal = 4.332f; +        vec3 = vec2 * mulVal; +        val1 = x1*mulVal; +        val2 = y1*mulVal; +        ensure("2:operator* failed",(val1 == vec3.mV[VX]) && (val2 == vec3.mV[VY])); + +        vec3.clearVec(); +        vec3 = mulVal * vec2; +        ensure("3:operator* failed",(val1 == vec3.mV[VX]) && (val2 == vec3.mV[VY])); +    } + +    template<> template<> +    void v2math_object::test<9>() +    { +        F32 x1 =1.f, y1 = 2.f, div = 3.2f; +        F32 val1, val2; +        LLVector2 vec2(x1, y1), vec3; +        vec3 = vec2 / div; +        val1 = x1 / div; +        val2 = y1 / div; +        ensure("1:operator/ failed", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY])); + +        vec3.clearVec(); +        x1 = -.235f, y1 = -24.32f, div = -2.2f; +        vec2.setVec(x1, y1); +        vec3 = vec2 / div; +        val1 = x1 / div; +        val2 = y1 / div; +        ensure("2:operator/ failed", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY])); +    } + +    template<> template<> +    void v2math_object::test<10>() +    { +        F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; +        F32 val1, val2; +        LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; +        vec4 = vec2 % vec3; +        val1 = x1*y2 - x2*y1; +        val2 = y1*x2 - y2*x1; +        ensure("1:operator% failed",(val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY])); + +        vec2.clearVec(); +        vec3.clearVec(); +        vec4.clearVec(); +        x1 = -.235f, y1 = -24.32f,  x2 = -2.3f, y2 = 1.f; +        vec2.setVec(x1, y1); +        vec3.setVec(x2, y2); +        vec4 = vec2 % vec3; +        val1 = x1*y2 - x2*y1; +        val2 = y1*x2 - y2*x1; +        ensure("2:operator% failed",(val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY])); +    } +    template<> template<> +    void v2math_object::test<11>() +    { +        F32 x1 =1.f, y1 = 2.f; +        LLVector2 vec2(x1, y1), vec3(x1, y1); +        ensure("1:operator== failed",(vec2 == vec3)); + +        vec2.clearVec(); +        vec3.clearVec(); +        x1 = -.235f, y1 = -24.32f; +        vec2.setVec(x1, y1); +        vec3.setVec(vec2); +        ensure("2:operator== failed",(vec2 == vec3)); +    } + +    template<> template<> +    void v2math_object::test<12>() +    { +        F32 x1 = 1.f, y1 = 2.f,x2 = 2.332f, y2 = -1.23f; +        LLVector2 vec2(x1, y1), vec3(x2, y2); +        ensure("1:operator!= failed",(vec2 != vec3)); + +        vec2.clearVec(); +        vec3.clearVec(); +        vec2.setVec(x1, y1); +        vec3.setVec(vec2); +        ensure("2:operator!= failed", (FALSE == (vec2 != vec3))); +    } +    template<> template<> +    void v2math_object::test<13>() +    { +        F32 x1 = 1.f, y1 = 2.f,x2 = 2.332f, y2 = -1.23f; +        F32 val1, val2; +        LLVector2 vec2(x1, y1), vec3(x2, y2); +        vec2 +=vec3; +        val1 = x1+x2; +        val2 = y1+y2; +        ensure("1:operator+= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + +        vec2.setVec(x1, y1); +        vec2 -=vec3; +        val1 = x1-x2; +        val2 = y1-y2; +        ensure("2:operator-= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + +        vec2.clearVec(); +        vec3.clearVec(); +        x1 = -21.000466f, y1 = 2.98382f,x2 = 0.332f, y2 = -01.23f; +        vec2.setVec(x1, y1); +        vec3.setVec(x2, y2); +        vec2 +=vec3; +        val1 = x1+x2; +        val2 = y1+y2; +        ensure("3:operator+= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + +        vec2.setVec(x1, y1); +        vec2 -=vec3; +        val1 = x1-x2; +        val2 = y1-y2; +        ensure("4:operator-= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); +    } + +    template<> template<> +    void v2math_object::test<14>() +    { +        F32 x1 =1.f, y1 = 2.f; +        F32 val1, val2, mulVal = 4.332f; +        LLVector2 vec2(x1, y1); +        vec2 /=mulVal; +        val1 = x1 / mulVal; +        val2 = y1 / mulVal; +        ensure("1:operator/= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); + +        vec2.clearVec(); +        x1 = .213f, y1 = -2.34f, mulVal = -.23f; +        vec2.setVec(x1, y1); +        vec2 /=mulVal; +        val1 = x1 / mulVal; +        val2 = y1 / mulVal; +        ensure("2:operator/= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); +    } + +    template<> template<> +    void v2math_object::test<15>() +    { +        F32 x1 =1.f, y1 = 2.f; +        F32 val1, val2, mulVal = 4.332f; +        LLVector2 vec2(x1, y1); +        vec2 *=mulVal; +        val1 = x1*mulVal; +        val2 = y1*mulVal; +        ensure("1:operator*= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + +        vec2.clearVec(); +        x1 = .213f, y1 = -2.34f, mulVal = -.23f; +        vec2.setVec(x1, y1); +        vec2 *=mulVal; +        val1 = x1*mulVal; +        val2 = y1*mulVal; +        ensure("2:operator*= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); +    } + +    template<> template<> +    void v2math_object::test<16>() +    { +        F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; +        F32 val1, val2; +        LLVector2 vec2(x1, y1), vec3(x2, y2); +        vec2 %= vec3; +        val1 = x1*y2 - x2*y1; +        val2 = y1*x2 - y2*x1; +        ensure("1:operator%= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); +    } + +    template<> template<> +    void v2math_object::test<17>() +    { +        F32 x1 =1.f, y1 = 2.f; +        LLVector2 vec2(x1, y1),vec3; +        vec3 = -vec2; +        ensure("1:operator- failed",(-vec3 == vec2)); +    } + +    template<> template<> +    void v2math_object::test<18>() +    { +        F32 x1 =1.f, y1 = 2.f; +        std::ostringstream stream1, stream2; +        LLVector2 vec2(x1, y1),vec3; +        stream1 << vec2; +        vec3.setVec(x1, y1); +        stream2 << vec3; +        ensure("1:operator << failed",(stream1.str() == stream2.str())); +    } + +    template<> template<> +    void v2math_object::test<19>() +    { +        F32 x1 =1.0f, y1 = 2.0f, x2 = -.32f, y2 = .2234f; +        LLVector2 vec2(x1, y1),vec3(x2, y2); +        ensure("1:operator < failed",(vec3 < vec2)); + +        x1 = 1.0f, y1 = 2.0f, x2 = 1.0f, y2 = 3.2234f; +        vec2.setVec(x1, y1); +        vec3.setVec(x2, y2); +        ensure("2:operator < failed", (FALSE == (vec3 < vec2))); +    } + +    template<> template<> +    void v2math_object::test<20>() +    { +        F32 x1 =1.0f, y1 = 2.0f; +        LLVector2 vec2(x1, y1); +        ensure("1:operator [] failed",( x1 ==  vec2[0])); +        ensure("2:operator [] failed",( y1 ==  vec2[1])); + +        vec2.clearVec(); +        x1 = 23.0f, y1 = -.2361f; +        vec2.setVec(x1, y1); +        F32 ref1 = vec2[0]; +        ensure("3:operator [] failed", ( ref1 ==  x1)); +        F32 ref2 = vec2[1]; +        ensure("4:operator [] failed", ( ref2 ==  y1)); +    } + +    template<> template<> +    void v2math_object::test<21>() +    { +        F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f; +        F32 val1, val2; +        LLVector2 vec2(x1, y1),vec3(x2, y2); +        val1 = dist_vec_squared2D(vec2, vec3); +        val2 = (x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2); +        ensure_equals("dist_vec_squared2D values are not equal",val2, val1); + +        val1 = dist_vec_squared(vec2, vec3); +        ensure_equals("dist_vec_squared values are not equal",val2, val1); + +        val1 =  dist_vec(vec2, vec3); +        val2 = (F32) sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2)); +        ensure_equals("dist_vec values are not equal",val2, val1); +    } + +    template<> template<> +    void v2math_object::test<22>() +    { +        F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f,fVal = .0121f; +        F32 val1, val2; +        LLVector2 vec2(x1, y1),vec3(x2, y2); +        LLVector2 vec4 = lerp(vec2, vec3, fVal); +        val1 = x1 + (x2 - x1) * fVal; +        val2 = y1 + (y2 - y1) * fVal; +        ensure("lerp values are not equal", ((val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY]))); +    } + +    template<> template<> +    void v2math_object::test<23>() +    { +        F32 x1 =1.f, y1 = 2.f; +        F32 val1, val2; +        LLVector2 vec2(x1, y1); + +        F32 vecMag = vec2.normVec(); +        F32 mag = (F32) sqrt(x1*x1 + y1*y1); + +        F32 oomag = 1.f / mag; +        val1 = x1 * oomag; +        val2 = y1 * oomag; + +        ensure("normVec failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY]) && is_approx_equal(vecMag, mag)); + +        x1 =.00000001f, y1 = 0.f; + +        vec2.setVec(x1, y1); +        vecMag = vec2.normVec(); +        ensure("normVec failed should be 0.", 0. == vec2.mV[VX] && 0. == vec2.mV[VY] && vecMag == 0.); +    }  } diff --git a/indra/llmath/tests/v3color_test.cpp b/indra/llmath/tests/v3color_test.cpp index 29d1c483ab..d1baa53a9b 100644 --- a/indra/llmath/tests/v3color_test.cpp +++ b/indra/llmath/tests/v3color_test.cpp @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -34,276 +34,276 @@  namespace tut  { -	struct v3color_data -	{ -	}; -	typedef test_group<v3color_data> v3color_test; -	typedef v3color_test::object v3color_object; -	tut::v3color_test v3color_testcase("v3color_h"); +    struct v3color_data +    { +    }; +    typedef test_group<v3color_data> v3color_test; +    typedef v3color_test::object v3color_object; +    tut::v3color_test v3color_testcase("v3color_h"); + +    template<> template<> +    void v3color_object::test<1>() +    { +        LLColor3 llcolor3; +        ensure("1:LLColor3:Fail to default-initialize ", (0.0f == llcolor3.mV[0]) && (0.0f == llcolor3.mV[1]) && (0.0f == llcolor3.mV[2])); +        F32 r = 2.0f, g = 3.2f, b = 1.f; +        F32 v1,v2,v3; +        LLColor3 llcolor3a(r,g,b); +        ensure("2:LLColor3:Fail to initialize " ,(2.0f == llcolor3a.mV[0]) && (3.2f == llcolor3a.mV[1]) && (1.f == llcolor3a.mV[2])); + +        const F32 vec[3] = {2.0f, 3.2f,1.f}; +        LLColor3 llcolor3b(vec); +        ensure("3:LLColor3:Fail to initialize " ,(2.0f == llcolor3b.mV[0]) && (3.2f == llcolor3b.mV[1]) && (1.f == llcolor3b.mV[2])); +        const char* str = "561122"; +        LLColor3 llcolor3c(str); +        v1 = (F32)86.0f/255.0f; // 0x56 = 86 +        v2 = (F32)17.0f/255.0f; // 0x11 = 17 +        v3 = (F32)34.0f/255.f;  // 0x22 = 34 +        ensure("4:LLColor3:Fail to initialize " , is_approx_equal(v1, llcolor3c.mV[0]) && is_approx_equal(v2, llcolor3c.mV[1]) && is_approx_equal(v3, llcolor3c.mV[2])); +    } + +    template<> template<> +    void v3color_object::test<2>() +    { +        LLColor3 llcolor3; +        llcolor3.setToBlack(); +        ensure("setToBlack:Fail to set black ", ((llcolor3.mV[0] == 0.f) && (llcolor3.mV[1] == 0.f) && (llcolor3.mV[2] == 0.f))); +        llcolor3.setToWhite(); +        ensure("setToWhite:Fail to set white  ", ((llcolor3.mV[0] == 1.f) && (llcolor3.mV[1] == 1.f) && (llcolor3.mV[2] == 1.f))); +    } + +    template<> template<> +    void v3color_object::test<3>() +    { +        F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; +        LLColor3 llcolor3, llcolor3a; +        llcolor3.setVec(r,g,b); +        ensure("1:setVec(r,g,b) Fail ",((r == llcolor3.mV[0]) && (g == llcolor3.mV[1]) && (b == llcolor3.mV[2]))); +        llcolor3a.setVec(llcolor3); +        ensure_equals("2:setVec(LLColor3) Fail ", llcolor3,llcolor3a); +        F32 vec[3] = {1.2324f, 2.45634f, .234563f}; +        llcolor3.setToBlack(); +        llcolor3.setVec(vec); +        ensure("3:setVec(F32*) Fail ",((vec[0] == llcolor3.mV[0]) && (vec[1] == llcolor3.mV[1]) && (vec[2] == llcolor3.mV[2]))); +    } -	template<> template<> -	void v3color_object::test<1>() -	{ -		LLColor3 llcolor3; -		ensure("1:LLColor3:Fail to default-initialize ", (0.0f == llcolor3.mV[0]) && (0.0f == llcolor3.mV[1]) && (0.0f == llcolor3.mV[2])); -		F32 r = 2.0f, g = 3.2f, b = 1.f; -		F32 v1,v2,v3; -		LLColor3 llcolor3a(r,g,b); -		ensure("2:LLColor3:Fail to initialize " ,(2.0f == llcolor3a.mV[0]) && (3.2f == llcolor3a.mV[1]) && (1.f == llcolor3a.mV[2])); -		 -		const F32 vec[3] = {2.0f, 3.2f,1.f}; -		LLColor3 llcolor3b(vec); -		ensure("3:LLColor3:Fail to initialize " ,(2.0f == llcolor3b.mV[0]) && (3.2f == llcolor3b.mV[1]) && (1.f == llcolor3b.mV[2])); -		const char* str = "561122"; -		LLColor3 llcolor3c(str); -		v1 = (F32)86.0f/255.0f; // 0x56 = 86 -		v2 = (F32)17.0f/255.0f; // 0x11 = 17 -		v3 = (F32)34.0f/255.f;  // 0x22 = 34 -		ensure("4:LLColor3:Fail to initialize " , is_approx_equal(v1, llcolor3c.mV[0]) && is_approx_equal(v2, llcolor3c.mV[1]) && is_approx_equal(v3, llcolor3c.mV[2])); -	} +    template<> template<> +    void v3color_object::test<4>() +    { +        F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; +        LLColor3 llcolor3(r,g,b); +        ensure("magVecSquared:Fail ", is_approx_equal(llcolor3.magVecSquared(), (r*r + g*g + b*b))); +        ensure("magVec:Fail ", is_approx_equal(llcolor3.magVec(), (F32) sqrt(r*r + g*g + b*b))); +    } -	template<> template<> -	void v3color_object::test<2>() -	{ -		LLColor3 llcolor3; -		llcolor3.setToBlack(); -		ensure("setToBlack:Fail to set black ", ((llcolor3.mV[0] == 0.f) && (llcolor3.mV[1] == 0.f) && (llcolor3.mV[2] == 0.f))); -		llcolor3.setToWhite(); -		ensure("setToWhite:Fail to set white  ", ((llcolor3.mV[0] == 1.f) && (llcolor3.mV[1] == 1.f) && (llcolor3.mV[2] == 1.f))); -	} +    template<> template<> +    void v3color_object::test<5>() +    { +        F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; +        F32 val1, val2,val3; +        LLColor3 llcolor3(r,g,b); +        F32 vecMag = llcolor3.normVec(); +        F32 mag = (F32) sqrt(r*r + g*g + b*b); +        F32 oomag = 1.f / mag; +        val1 = r * oomag; +        val2 = g * oomag; +        val3 = b * oomag; +        ensure("1:normVec failed ", (is_approx_equal(val1, llcolor3.mV[0]) && is_approx_equal(val2, llcolor3.mV[1]) && is_approx_equal(val3, llcolor3.mV[2]) && is_approx_equal(vecMag, mag))); +        r = .000000000f, g = 0.f, b = 0.0f; +        llcolor3.setVec(r,g,b); +        vecMag = llcolor3.normVec(); +        ensure("2:normVec failed should be 0. ", (0. == llcolor3.mV[0] && 0. == llcolor3.mV[1] && 0. == llcolor3.mV[2] && vecMag == 0.)); +    } -	template<> template<> -	void v3color_object::test<3>() -	{ -		F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; -		LLColor3 llcolor3, llcolor3a; -		llcolor3.setVec(r,g,b); -		ensure("1:setVec(r,g,b) Fail ",((r == llcolor3.mV[0]) && (g == llcolor3.mV[1]) && (b == llcolor3.mV[2]))); -		llcolor3a.setVec(llcolor3); -		ensure_equals("2:setVec(LLColor3) Fail ", llcolor3,llcolor3a); -		F32 vec[3] = {1.2324f, 2.45634f, .234563f}; -		llcolor3.setToBlack(); -		llcolor3.setVec(vec); -		ensure("3:setVec(F32*) Fail ",((vec[0] == llcolor3.mV[0]) && (vec[1] == llcolor3.mV[1]) && (vec[2] == llcolor3.mV[2]))); -	} +    template<> template<> +    void v3color_object::test<6>() +    { +        F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; +        std::ostringstream stream1, stream2; +        LLColor3 llcolor3(r,g,b),llcolor3a; +        stream1 << llcolor3; +        llcolor3a.setVec(r,g,b); +        stream2 << llcolor3a; +        ensure("operator << failed ", (stream1.str() == stream2.str())); +    } -	template<> template<> -	void v3color_object::test<4>() -	{ -		F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; -		LLColor3 llcolor3(r,g,b); -		ensure("magVecSquared:Fail ", is_approx_equal(llcolor3.magVecSquared(), (r*r + g*g + b*b))); -		ensure("magVec:Fail ", is_approx_equal(llcolor3.magVec(), (F32) sqrt(r*r + g*g + b*b))); -	} +    template<> template<> +    void v3color_object::test<7>() +    { +        F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; +        LLColor3 llcolor3(r,g,b),llcolor3a; +        llcolor3a = llcolor3; +        ensure("operator == failed ", (llcolor3a == llcolor3)); +    } -	template<> template<> -	void v3color_object::test<5>() -	{ -		F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; -		F32 val1, val2,val3; -		LLColor3 llcolor3(r,g,b); -		F32 vecMag = llcolor3.normVec(); -		F32 mag = (F32) sqrt(r*r + g*g + b*b); -		F32 oomag = 1.f / mag; -		val1 = r * oomag; -		val2 = g * oomag; -		val3 = b * oomag; -		ensure("1:normVec failed ", (is_approx_equal(val1, llcolor3.mV[0]) && is_approx_equal(val2, llcolor3.mV[1]) && is_approx_equal(val3, llcolor3.mV[2]) && is_approx_equal(vecMag, mag))); -		r = .000000000f, g = 0.f, b = 0.0f; -		llcolor3.setVec(r,g,b); -		vecMag = llcolor3.normVec(); -		ensure("2:normVec failed should be 0. ", (0. == llcolor3.mV[0] && 0. == llcolor3.mV[1] && 0. == llcolor3.mV[2] && vecMag == 0.)); -	} +    template<> template<> +    void v3color_object::test<8>() +    { +        F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +        LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; +        llcolor3b = llcolor3 + llcolor3a ; +        ensure("1:operator+ failed",is_approx_equal(r1+r2 ,llcolor3b.mV[0]) && is_approx_equal(g1+g2,llcolor3b.mV[1])&& is_approx_equal(b1+b2,llcolor3b.mV[2])); +        r1 = -.235f, g1 = -24.32f, b1 = 2.13f,  r2 = -2.3f, g2 = 1.f, b2 = 34.21f; +        llcolor3.setVec(r1,g1,b1); +        llcolor3a.setVec(r2,g2,b2); +        llcolor3b = llcolor3 + llcolor3a; +        ensure("2:operator+ failed",is_approx_equal(r1+r2 ,llcolor3b.mV[0]) && is_approx_equal(g1+g2,llcolor3b.mV[1])&& is_approx_equal(b1+b2,llcolor3b.mV[2])); +    } -	template<> template<> -	void v3color_object::test<6>() -	{ -		F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; -		std::ostringstream stream1, stream2; -		LLColor3 llcolor3(r,g,b),llcolor3a; -		stream1 << llcolor3; -		llcolor3a.setVec(r,g,b); -		stream2 << llcolor3a; -		ensure("operator << failed ", (stream1.str() == stream2.str()));	 -	} -		 -	template<> template<> -	void v3color_object::test<7>() -	{ -		F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; -		LLColor3 llcolor3(r,g,b),llcolor3a; -		llcolor3a = llcolor3; -		ensure("operator == failed ", (llcolor3a == llcolor3));	 -	} +    template<> template<> +    void v3color_object::test<9>() +    { +        F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +        LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; +        llcolor3b = llcolor3 - llcolor3a ; +        ensure("1:operator- failed",is_approx_equal(r1-r2 ,llcolor3b.mV[0]) && is_approx_equal(g1-g2,llcolor3b.mV[1])&& is_approx_equal(b1-b2,llcolor3b.mV[2])); +        r1 = -.235f, g1 = -24.32f, b1 = 2.13f,  r2 = -2.3f, g2 = 1.f, b2 = 34.21f; +        llcolor3.setVec(r1,g1,b1); +        llcolor3a.setVec(r2,g2,b2); +        llcolor3b = llcolor3 - llcolor3a; +        ensure("2:operator- failed",is_approx_equal(r1-r2 ,llcolor3b.mV[0]) && is_approx_equal(g1-g2,llcolor3b.mV[1])&& is_approx_equal(b1-b2,llcolor3b.mV[2])); +    } -	template<> template<> -	void v3color_object::test<8>() -	{ -		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; -		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; -		llcolor3b = llcolor3 + llcolor3a ; -		ensure("1:operator+ failed",is_approx_equal(r1+r2 ,llcolor3b.mV[0]) && is_approx_equal(g1+g2,llcolor3b.mV[1])&& is_approx_equal(b1+b2,llcolor3b.mV[2])); -		r1 = -.235f, g1 = -24.32f, b1 = 2.13f,  r2 = -2.3f, g2 = 1.f, b2 = 34.21f; -		llcolor3.setVec(r1,g1,b1); -		llcolor3a.setVec(r2,g2,b2); -		llcolor3b = llcolor3 + llcolor3a; -		ensure("2:operator+ failed",is_approx_equal(r1+r2 ,llcolor3b.mV[0]) && is_approx_equal(g1+g2,llcolor3b.mV[1])&& is_approx_equal(b1+b2,llcolor3b.mV[2])); -	} +    template<> template<> +    void v3color_object::test<10>() +    { +        F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +        LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; +        llcolor3b = llcolor3 * llcolor3a; +        ensure("1:operator* failed",is_approx_equal(r1*r2 ,llcolor3b.mV[0]) && is_approx_equal(g1*g2,llcolor3b.mV[1])&& is_approx_equal(b1*b2,llcolor3b.mV[2])); +        llcolor3a.setToBlack(); +        F32 mulVal = 4.332f; +        llcolor3a = llcolor3 * mulVal; +        ensure("2:operator* failed",is_approx_equal(r1*mulVal ,llcolor3a.mV[0]) && is_approx_equal(g1*mulVal,llcolor3a.mV[1])&& is_approx_equal(b1*mulVal,llcolor3a.mV[2])); +        llcolor3a.setToBlack(); +        llcolor3a = mulVal * llcolor3; +        ensure("3:operator* failed",is_approx_equal(r1*mulVal ,llcolor3a.mV[0]) && is_approx_equal(g1*mulVal,llcolor3a.mV[1])&& is_approx_equal(b1*mulVal,llcolor3a.mV[2])); +    } -	template<> template<> -	void v3color_object::test<9>() -	{ -		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; -		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; -		llcolor3b = llcolor3 - llcolor3a ; -		ensure("1:operator- failed",is_approx_equal(r1-r2 ,llcolor3b.mV[0]) && is_approx_equal(g1-g2,llcolor3b.mV[1])&& is_approx_equal(b1-b2,llcolor3b.mV[2])); -		r1 = -.235f, g1 = -24.32f, b1 = 2.13f,  r2 = -2.3f, g2 = 1.f, b2 = 34.21f; -		llcolor3.setVec(r1,g1,b1); -		llcolor3a.setVec(r2,g2,b2); -		llcolor3b = llcolor3 - llcolor3a; -		ensure("2:operator- failed",is_approx_equal(r1-r2 ,llcolor3b.mV[0]) && is_approx_equal(g1-g2,llcolor3b.mV[1])&& is_approx_equal(b1-b2,llcolor3b.mV[2])); -	} +    template<> template<> +    void v3color_object::test<11>() +    { +        F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; +        LLColor3 llcolor3(r,g,b),llcolor3a; +        llcolor3a = -llcolor3; +        ensure("operator- failed ", (-llcolor3a == llcolor3)); +    } -	template<> template<> -	void v3color_object::test<10>() -	{ -		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; -		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; -		llcolor3b = llcolor3 * llcolor3a; -		ensure("1:operator* failed",is_approx_equal(r1*r2 ,llcolor3b.mV[0]) && is_approx_equal(g1*g2,llcolor3b.mV[1])&& is_approx_equal(b1*b2,llcolor3b.mV[2])); -		llcolor3a.setToBlack(); -		F32 mulVal = 4.332f; -		llcolor3a = llcolor3 * mulVal; -		ensure("2:operator* failed",is_approx_equal(r1*mulVal ,llcolor3a.mV[0]) && is_approx_equal(g1*mulVal,llcolor3a.mV[1])&& is_approx_equal(b1*mulVal,llcolor3a.mV[2])); -		llcolor3a.setToBlack(); -		llcolor3a = mulVal * llcolor3; -		ensure("3:operator* failed",is_approx_equal(r1*mulVal ,llcolor3a.mV[0]) && is_approx_equal(g1*mulVal,llcolor3a.mV[1])&& is_approx_equal(b1*mulVal,llcolor3a.mV[2])); -	} +    template<> template<> +    void v3color_object::test<12>() +    { +        F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; +        LLColor3 llcolor3(r,g,b),llcolor3a(r,g,b); +        ensure_equals("1:operator== failed",llcolor3a,llcolor3); +        r = 13.3436212f, g = -11.f, b = .7849321232f; +        llcolor3.setVec(r,g,b); +        llcolor3a.setVec(r,g,b); +        ensure_equals("2:operator== failed",llcolor3a,llcolor3); +    } -	template<> template<> -	void v3color_object::test<11>() -	{ -		F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; -		LLColor3 llcolor3(r,g,b),llcolor3a; -		llcolor3a = -llcolor3; -		ensure("operator- failed ", (-llcolor3a == llcolor3));	 -	} +    template<> template<> +    void v3color_object::test<13>() +    { +        F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +        LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +        ensure("1:operator!= failed",(llcolor3 != llcolor3a)); +        llcolor3.setToBlack(); +        llcolor3a.setVec(llcolor3); +        ensure("2:operator!= failed", ( FALSE == (llcolor3a != llcolor3))); +    } -	template<> template<> -	void v3color_object::test<12>() -	{ -		F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; -		LLColor3 llcolor3(r,g,b),llcolor3a(r,g,b); -		ensure_equals("1:operator== failed",llcolor3a,llcolor3); -		r = 13.3436212f, g = -11.f, b = .7849321232f; -		llcolor3.setVec(r,g,b); -		llcolor3a.setVec(r,g,b); -		ensure_equals("2:operator== failed",llcolor3a,llcolor3); -	} +    template<> template<> +    void v3color_object::test<14>() +    { +        F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +        LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +        llcolor3a += llcolor3; +        ensure("1:operator+= failed",is_approx_equal(r1+r2 ,llcolor3a.mV[0]) && is_approx_equal(g1+g2,llcolor3a.mV[1])&& is_approx_equal(b1+b2,llcolor3a.mV[2])); +        llcolor3.setVec(r1,g1,b1); +        llcolor3a.setVec(r2,g2,b2); +        llcolor3a += llcolor3; +        ensure("2:operator+= failed",is_approx_equal(r1+r2 ,llcolor3a.mV[0]) && is_approx_equal(g1+g2,llcolor3a.mV[1])&& is_approx_equal(b1+b2,llcolor3a.mV[2])); +    } -	template<> template<> -	void v3color_object::test<13>() -	{ -		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; -		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); -		ensure("1:operator!= failed",(llcolor3 != llcolor3a)); -		llcolor3.setToBlack(); -		llcolor3a.setVec(llcolor3); -		ensure("2:operator!= failed", ( FALSE == (llcolor3a != llcolor3))); -	} +    template<> template<> +    void v3color_object::test<15>() +    { +        F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +        LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +        llcolor3a -= llcolor3; +        ensure("1:operator-= failed", is_approx_equal(r2-r1, llcolor3a.mV[0])); +        ensure("2:operator-= failed", is_approx_equal(g2-g1, llcolor3a.mV[1])); +        ensure("3:operator-= failed", is_approx_equal(b2-b1, llcolor3a.mV[2])); +        llcolor3.setVec(r1,g1,b1); +        llcolor3a.setVec(r2,g2,b2); +        llcolor3a -= llcolor3; +        ensure("4:operator-= failed", is_approx_equal(r2-r1, llcolor3a.mV[0])); +        ensure("5:operator-= failed", is_approx_equal(g2-g1, llcolor3a.mV[1])); +        ensure("6:operator-= failed", is_approx_equal(b2-b1, llcolor3a.mV[2])); +    } -	template<> template<> -	void v3color_object::test<14>() -	{ -		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; -		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); -		llcolor3a += llcolor3; -		ensure("1:operator+= failed",is_approx_equal(r1+r2 ,llcolor3a.mV[0]) && is_approx_equal(g1+g2,llcolor3a.mV[1])&& is_approx_equal(b1+b2,llcolor3a.mV[2])); -		llcolor3.setVec(r1,g1,b1); -		llcolor3a.setVec(r2,g2,b2); -		llcolor3a += llcolor3; -		ensure("2:operator+= failed",is_approx_equal(r1+r2 ,llcolor3a.mV[0]) && is_approx_equal(g1+g2,llcolor3a.mV[1])&& is_approx_equal(b1+b2,llcolor3a.mV[2])); -	} +    template<> template<> +    void v3color_object::test<16>() +    { +        F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +        LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +        llcolor3a *= llcolor3; +        ensure("1:operator*= failed",is_approx_equal(r1*r2 ,llcolor3a.mV[0]) && is_approx_equal(g1*g2,llcolor3a.mV[1])&& is_approx_equal(b1*b2,llcolor3a.mV[2])); +        F32 mulVal = 4.332f; +        llcolor3 *=mulVal; +        ensure("2:operator*= failed",is_approx_equal(r1*mulVal ,llcolor3.mV[0]) && is_approx_equal(g1*mulVal,llcolor3.mV[1])&& is_approx_equal(b1*mulVal,llcolor3.mV[2])); +    } -	template<> template<> -	void v3color_object::test<15>() -	{ -		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; -		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); -		llcolor3a -= llcolor3; -		ensure("1:operator-= failed", is_approx_equal(r2-r1, llcolor3a.mV[0])); -		ensure("2:operator-= failed", is_approx_equal(g2-g1, llcolor3a.mV[1])); -		ensure("3:operator-= failed", is_approx_equal(b2-b1, llcolor3a.mV[2])); -		llcolor3.setVec(r1,g1,b1); -		llcolor3a.setVec(r2,g2,b2); -		llcolor3a -= llcolor3; -		ensure("4:operator-= failed", is_approx_equal(r2-r1, llcolor3a.mV[0])); -		ensure("5:operator-= failed", is_approx_equal(g2-g1, llcolor3a.mV[1])); -		ensure("6:operator-= failed", is_approx_equal(b2-b1, llcolor3a.mV[2])); -	} -	 -	template<> template<> -	void v3color_object::test<16>() -	{ -		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; -		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); -		llcolor3a *= llcolor3; -		ensure("1:operator*= failed",is_approx_equal(r1*r2 ,llcolor3a.mV[0]) && is_approx_equal(g1*g2,llcolor3a.mV[1])&& is_approx_equal(b1*b2,llcolor3a.mV[2])); -		F32 mulVal = 4.332f; -		llcolor3 *=mulVal; -		ensure("2:operator*= failed",is_approx_equal(r1*mulVal ,llcolor3.mV[0]) && is_approx_equal(g1*mulVal,llcolor3.mV[1])&& is_approx_equal(b1*mulVal,llcolor3.mV[2])); -	} +    template<> template<> +    void v3color_object::test<17>() +    { +        F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; +        LLColor3 llcolor3(r,g,b); +        llcolor3.clamp(); +        ensure("1:clamp:Fail to clamp " ,(1.0f == llcolor3.mV[0]) && (0.f == llcolor3.mV[1]) && (b == llcolor3.mV[2])); +        r = -2.3436212f, g = -1231.f, b = 67.7849321232f; +        llcolor3.setVec(r,g,b); +        llcolor3.clamp(); +        ensure("2:clamp:Fail to clamp " ,(0.f == llcolor3.mV[0]) && (0.f == llcolor3.mV[1]) && (1.f == llcolor3.mV[2])); +    } -	template<> template<> -	void v3color_object::test<17>() -	{ -		F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; -		LLColor3 llcolor3(r,g,b); -		llcolor3.clamp(); -		ensure("1:clamp:Fail to clamp " ,(1.0f == llcolor3.mV[0]) && (0.f == llcolor3.mV[1]) && (b == llcolor3.mV[2])); -		r = -2.3436212f, g = -1231.f, b = 67.7849321232f; -		llcolor3.setVec(r,g,b); -		llcolor3.clamp(); -		ensure("2:clamp:Fail to clamp " ,(0.f == llcolor3.mV[0]) && (0.f == llcolor3.mV[1]) && (1.f == llcolor3.mV[2])); -	} +    template<> template<> +    void v3color_object::test<18>() +    { +        F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +        F32 val = 2.3f,val1,val2,val3; +        LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +        val1 = r1 + (r2 - r1)* val; +        val2 = g1 + (g2 - g1)* val; +        val3 = b1 + (b2 - b1)* val; +        LLColor3 llcolor3b = lerp(llcolor3,llcolor3a,val); +        ensure("lerp failed ", ((val1 ==llcolor3b.mV[0])&& (val2 ==llcolor3b.mV[1]) && (val3 ==llcolor3b.mV[2]))); +    } -	template<> template<> -	void v3color_object::test<18>() -	{ -		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; -		F32 val = 2.3f,val1,val2,val3; -		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); -		val1 = r1 + (r2 - r1)* val; -		val2 = g1 + (g2 - g1)* val; -		val3 = b1 + (b2 - b1)* val; -		LLColor3 llcolor3b = lerp(llcolor3,llcolor3a,val); -		ensure("lerp failed ", ((val1 ==llcolor3b.mV[0])&& (val2 ==llcolor3b.mV[1]) && (val3 ==llcolor3b.mV[2])));		 -	} +    template<> template<> +    void v3color_object::test<19>() +    { +        F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +        LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +        F32 val = distVec(llcolor3,llcolor3a); +        ensure("distVec failed ", is_approx_equal((F32) sqrt((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) ,val)); -	template<> template<> -	void v3color_object::test<19>() -	{ -		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; -		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); -		F32 val = distVec(llcolor3,llcolor3a); -		ensure("distVec failed ", is_approx_equal((F32) sqrt((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) ,val)); -		 -		F32 val1 = distVec_squared(llcolor3,llcolor3a); -		ensure("distVec_squared failed ", is_approx_equal(((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) ,val1)); -	} +        F32 val1 = distVec_squared(llcolor3,llcolor3a); +        ensure("distVec_squared failed ", is_approx_equal(((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) ,val1)); +    } -	template<> template<> -	void v3color_object::test<20>() -	{ -		F32 r1 = 1.02223f, g1 = 22222.212f, b1 = 122222.00002f; -		LLColor3 llcolor31(r1,g1,b1); +    template<> template<> +    void v3color_object::test<20>() +    { +        F32 r1 = 1.02223f, g1 = 22222.212f, b1 = 122222.00002f; +        LLColor3 llcolor31(r1,g1,b1); -		LLSD sd = llcolor31.getValue(); -		LLColor3 llcolor32; -		llcolor32.setValue(sd); -		ensure_equals("LLColor3::setValue/getValue failed", llcolor31, llcolor32); +        LLSD sd = llcolor31.getValue(); +        LLColor3 llcolor32; +        llcolor32.setValue(sd); +        ensure_equals("LLColor3::setValue/getValue failed", llcolor31, llcolor32); -		LLColor3 llcolor33(sd); -		ensure_equals("LLColor3(LLSD) failed", llcolor31, llcolor33); -	} +        LLColor3 llcolor33(sd); +        ensure_equals("LLColor3(LLSD) failed", llcolor31, llcolor33); +    }  } diff --git a/indra/llmath/tests/v3dmath_test.cpp b/indra/llmath/tests/v3dmath_test.cpp index c4744e1b25..6b58cbd007 100644 --- a/indra/llmath/tests/v3dmath_test.cpp +++ b/indra/llmath/tests/v3dmath_test.cpp @@ -7,25 +7,25 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -  +  #include "linden_common.h"  #include "llsd.h"  #include "../test/lltut.h" @@ -38,494 +38,494 @@  namespace tut  { -	struct v3dmath_data -	{ -	}; -	typedef test_group<v3dmath_data> v3dmath_test; -	typedef v3dmath_test::object v3dmath_object; -	tut::v3dmath_test v3dmath_testcase("v3dmath_h"); +    struct v3dmath_data +    { +    }; +    typedef test_group<v3dmath_data> v3dmath_test; +    typedef v3dmath_test::object v3dmath_object; +    tut::v3dmath_test v3dmath_testcase("v3dmath_h"); -	template<> template<> -	void v3dmath_object::test<1>() -	{ -		LLVector3d vec3D; -		ensure("1:LLVector3d:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); -		F64 x = 2.32f, y = 1.212f, z = -.12f; -		LLVector3d vec3Da(x,y,z); -		ensure("2:LLVector3d:Fail to initialize ", ((2.32f == vec3Da.mdV[VX]) && (1.212f == vec3Da.mdV[VY]) && (-.12f == vec3Da.mdV[VZ]))); -		const F64 vec[3] = {1.2f ,3.2f, -4.2f}; -		LLVector3d vec3Db(vec); -		ensure("3:LLVector3d:Fail to initialize ", ((1.2f == vec3Db.mdV[VX]) && (3.2f == vec3Db.mdV[VY]) && (-4.2f == vec3Db.mdV[VZ]))); -		LLVector3 vec3((F32)x,(F32)y,(F32)z); -		LLVector3d vec3Dc(vec3); -		ensure_equals("4:LLVector3d Fail to initialize",vec3Da,vec3Dc); -	} +    template<> template<> +    void v3dmath_object::test<1>() +    { +        LLVector3d vec3D; +        ensure("1:LLVector3d:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); +        F64 x = 2.32f, y = 1.212f, z = -.12f; +        LLVector3d vec3Da(x,y,z); +        ensure("2:LLVector3d:Fail to initialize ", ((2.32f == vec3Da.mdV[VX]) && (1.212f == vec3Da.mdV[VY]) && (-.12f == vec3Da.mdV[VZ]))); +        const F64 vec[3] = {1.2f ,3.2f, -4.2f}; +        LLVector3d vec3Db(vec); +        ensure("3:LLVector3d:Fail to initialize ", ((1.2f == vec3Db.mdV[VX]) && (3.2f == vec3Db.mdV[VY]) && (-4.2f == vec3Db.mdV[VZ]))); +        LLVector3 vec3((F32)x,(F32)y,(F32)z); +        LLVector3d vec3Dc(vec3); +        ensure_equals("4:LLVector3d Fail to initialize",vec3Da,vec3Dc); +    } -	template<> template<> -	void v3dmath_object::test<2>() -	{ -		S32 a = -235; -		LLSD llsd(a); -		LLVector3d vec3d(llsd); -		LLSD sd = vec3d.getValue(); -		LLVector3d vec3da(sd); -		ensure("1:getValue:Fail ", (vec3d == vec3da)); -	} +    template<> template<> +    void v3dmath_object::test<2>() +    { +        S32 a = -235; +        LLSD llsd(a); +        LLVector3d vec3d(llsd); +        LLSD sd = vec3d.getValue(); +        LLVector3d vec3da(sd); +        ensure("1:getValue:Fail ", (vec3d == vec3da)); +    } -	template<> template<> -	void v3dmath_object::test<3>() -	{ -		F64 a = 232345521.411132; -		LLSD llsd(a); -		LLVector3d vec3d; -		vec3d.setValue(llsd); -		LLSD sd = vec3d.getValue(); -		LLVector3d vec3da(sd); -		ensure("1:setValue:Fail to initialize ", (vec3d == vec3da)); -	} +    template<> template<> +    void v3dmath_object::test<3>() +    { +        F64 a = 232345521.411132; +        LLSD llsd(a); +        LLVector3d vec3d; +        vec3d.setValue(llsd); +        LLSD sd = vec3d.getValue(); +        LLVector3d vec3da(sd); +        ensure("1:setValue:Fail to initialize ", (vec3d == vec3da)); +    } -	template<> template<> -	void v3dmath_object::test<4>() -	{ -		F64 a[3] = {222231.43222, 12345.2343, -434343.33222}; -		LLSD llsd; -		llsd[0] = a[0]; -		llsd[1] = a[1]; -		llsd[2] = a[2]; -		LLVector3d vec3D; -		vec3D = (LLVector3d)llsd; -		ensure("1:operator=:Fail to initialize ", ((llsd[0].asReal()== vec3D.mdV[VX]) && (llsd[1].asReal() == vec3D.mdV[VY]) && (llsd[2].asReal() == vec3D.mdV[VZ]))); -	} -	 -	template<> template<> -	void v3dmath_object::test<5>() -	{ -		F64 x = 2.32f, y = 1.212f, z = -.12f; -		LLVector3d vec3D(x,y,z); -		vec3D.clearVec(); -		ensure("1:clearVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); -		vec3D.setVec(x,y,z); -		ensure("2:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); -		vec3D.zeroVec(); -		ensure("3:zeroVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); -		vec3D.clearVec(); -		LLVector3 vec3((F32)x,(F32)y,(F32)z); -		vec3D.setVec(vec3); -		ensure("4:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); -		vec3D.clearVec(); -		const F64 vec[3] = {x,y,z}; -		vec3D.setVec(vec); -		ensure("5:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); -		LLVector3d vec3Da; -		vec3Da.setVec(vec3D); -		ensure_equals("6:setVec: Fail to initialize", vec3D, vec3Da); -	} -	 -	template<> template<> -	void v3dmath_object::test<6>() -	{ -		F64 x = -2.32, y = 1.212, z = -.12; -		LLVector3d vec3D(x,y,z); -		vec3D.abs(); -		ensure("1:abs:Fail  ", ((-x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (-z == vec3D.mdV[VZ]))); -		ensure("2:isNull():Fail ", (FALSE == vec3D.isNull()));	 -		vec3D.clearVec(); -		x =.00000001, y = .000001001, z = .000001001; -		vec3D.setVec(x,y,z); -		ensure("3:isNull():Fail ", (TRUE == vec3D.isNull()));	 -		ensure("4:isExactlyZero():Fail ", (FALSE == vec3D.isExactlyZero()));	 -		x =.0000000, y = .00000000, z = .00000000; -		vec3D.setVec(x,y,z); -		ensure("5:isExactlyZero():Fail ", (TRUE == vec3D.isExactlyZero()));	 -	} +    template<> template<> +    void v3dmath_object::test<4>() +    { +        F64 a[3] = {222231.43222, 12345.2343, -434343.33222}; +        LLSD llsd; +        llsd[0] = a[0]; +        llsd[1] = a[1]; +        llsd[2] = a[2]; +        LLVector3d vec3D; +        vec3D = (LLVector3d)llsd; +        ensure("1:operator=:Fail to initialize ", ((llsd[0].asReal()== vec3D.mdV[VX]) && (llsd[1].asReal() == vec3D.mdV[VY]) && (llsd[2].asReal() == vec3D.mdV[VZ]))); +    } -	template<> template<> -	void v3dmath_object::test<7>() -	{ -		F64 x = -2.32, y = 1.212, z = -.12; -		LLVector3d vec3D(x,y,z); -		 -		ensure("1:operator [] failed",( x ==  vec3D[0]));	 -		ensure("2:operator [] failed",( y ==  vec3D[1])); -		ensure("3:operator [] failed",( z ==  vec3D[2])); -		vec3D.clearVec(); -		x = 23.23, y = -.2361, z = 3.25; -		vec3D.setVec(x,y,z); -		F64 &ref1 = vec3D[0]; -		ensure("4:operator [] failed",( ref1 ==  vec3D[0])); -		F64 &ref2 = vec3D[1]; -		ensure("5:operator [] failed",( ref2 ==  vec3D[1])); -		F64 &ref3 = vec3D[2]; -		ensure("6:operator [] failed",( ref3 ==  vec3D[2])); -	} +    template<> template<> +    void v3dmath_object::test<5>() +    { +        F64 x = 2.32f, y = 1.212f, z = -.12f; +        LLVector3d vec3D(x,y,z); +        vec3D.clearVec(); +        ensure("1:clearVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); +        vec3D.setVec(x,y,z); +        ensure("2:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); +        vec3D.zeroVec(); +        ensure("3:zeroVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); +        vec3D.clearVec(); +        LLVector3 vec3((F32)x,(F32)y,(F32)z); +        vec3D.setVec(vec3); +        ensure("4:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); +        vec3D.clearVec(); +        const F64 vec[3] = {x,y,z}; +        vec3D.setVec(vec); +        ensure("5:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); +        LLVector3d vec3Da; +        vec3Da.setVec(vec3D); +        ensure_equals("6:setVec: Fail to initialize", vec3D, vec3Da); +    } -	template<> template<> -	void v3dmath_object::test<8>() -	{ -		F32 x = 1.f, y = 2.f, z = -1.f; -		LLVector4 vec4(x,y,z);		 -		LLVector3d vec3D; -		vec3D = vec4; -		ensure("1:operator=:Fail to initialize ", ((vec4.mV[VX] == vec3D.mdV[VX]) && (vec4.mV[VY] == vec3D.mdV[VY]) && (vec4.mV[VZ] == vec3D.mdV[VZ]))); -	} +    template<> template<> +    void v3dmath_object::test<6>() +    { +        F64 x = -2.32, y = 1.212, z = -.12; +        LLVector3d vec3D(x,y,z); +        vec3D.abs(); +        ensure("1:abs:Fail  ", ((-x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (-z == vec3D.mdV[VZ]))); +        ensure("2:isNull():Fail ", (FALSE == vec3D.isNull())); +        vec3D.clearVec(); +        x =.00000001, y = .000001001, z = .000001001; +        vec3D.setVec(x,y,z); +        ensure("3:isNull():Fail ", (TRUE == vec3D.isNull())); +        ensure("4:isExactlyZero():Fail ", (FALSE == vec3D.isExactlyZero())); +        x =.0000000, y = .00000000, z = .00000000; +        vec3D.setVec(x,y,z); +        ensure("5:isExactlyZero():Fail ", (TRUE == vec3D.isExactlyZero())); +    } -	template<> template<> -	void v3dmath_object::test<9>() -	{ -		F64 x1 = 1.78787878, y1 = 232322.2121, z1 = -12121.121212; -		F64 x2 = 1.2, y2 = 2.5, z2 = 1.; -		LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db; -		vec3Db = vec3Da+ vec3D; -		ensure("1:operator+:Fail to initialize ", ((x1+x2 == vec3Db.mdV[VX]) && (y1+y2 == vec3Db.mdV[VY]) && (z1+z2 == vec3Db.mdV[VZ]))); -		x1 = -2.45, y1 = 2.1, z1 = 3.0; -		vec3D.clearVec(); -		vec3Da.clearVec(); -		vec3D.setVec(x1,y1,z1); -		vec3Da += vec3D; -		ensure_equals("2:operator+=: Fail to initialize", vec3Da,vec3D); -		vec3Da += vec3D; -		ensure("3:operator+=:Fail to initialize ", ((2*x1 == vec3Da.mdV[VX]) && (2*y1 == vec3Da.mdV[VY]) && (2*z1 == vec3Da.mdV[VZ]))); -	} +    template<> template<> +    void v3dmath_object::test<7>() +    { +        F64 x = -2.32, y = 1.212, z = -.12; +        LLVector3d vec3D(x,y,z); -	template<> template<> -	void v3dmath_object::test<10>() -	{ -		F64 x1 = 1., y1 = 2., z1 = -1.1; -		F64 x2 = 1.2, y2 = 2.5, z2 = 1.; -		LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db; -		vec3Db = vec3Da - vec3D; -		ensure("1:operator-:Fail to initialize ", ((x2-x1 == vec3Db.mdV[VX]) && (y2-y1 == vec3Db.mdV[VY]) && (z2-z1 == vec3Db.mdV[VZ]))); -		x1 = -2.45, y1 = 2.1, z1 = 3.0; -		vec3D.clearVec(); -		vec3Da.clearVec(); -		vec3D.setVec(x1,y1,z1); -		vec3Da -=vec3D; -		ensure("2:operator-=:Fail to initialize ", ((2.45 == vec3Da.mdV[VX]) && (-2.1 == vec3Da.mdV[VY]) && (-3.0 == vec3Da.mdV[VZ]))); -		vec3Da -= vec3D; -		ensure("3:operator-=:Fail to initialize ", ((-2*x1 == vec3Da.mdV[VX]) && (-2*y1 == vec3Da.mdV[VY]) && (-2*z1 == vec3Da.mdV[VZ]))); -	} -	template<> template<> -	void v3dmath_object::test<11>() -	{ -		F64 x1 = 1., y1 = 2., z1 = -1.1; -		F64 x2 = 1.2, y2 = 2.5, z2 = 1.; -		LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2); -		F64 res = vec3D * vec3Da; -		ensure_approximately_equals( -			"1:operator* failed", -			res, -			(x1*x2 + y1*y2 + z1*z2), -			8); -		vec3Da.clearVec(); -		F64 mulVal = 4.2; -		vec3Da = vec3D * mulVal; -		ensure_approximately_equals( -			"2a:operator* failed", -			vec3Da.mdV[VX], -			x1*mulVal, -			8); -		ensure_approximately_equals( -			"2b:operator* failed", -			vec3Da.mdV[VY], -			y1*mulVal, -			8); -		ensure_approximately_equals( -			"2c:operator* failed", -			vec3Da.mdV[VZ], -			z1*mulVal, -			8); -		vec3Da.clearVec(); -		vec3Da = mulVal * vec3D; -		ensure_approximately_equals( -			"3a:operator* failed", -			vec3Da.mdV[VX], -			x1*mulVal, -			8); -		ensure_approximately_equals( -			"3b:operator* failed", -			vec3Da.mdV[VY], -			y1*mulVal, -			8); -		ensure_approximately_equals( -			"3c:operator* failed", -			vec3Da.mdV[VZ], -			z1*mulVal, -			8); -		vec3D *= mulVal; -		ensure_approximately_equals( -			"4a:operator*= failed", -			vec3D.mdV[VX], -			x1*mulVal, -			8); -		ensure_approximately_equals( -			"4b:operator*= failed", -			vec3D.mdV[VY], -			y1*mulVal, -			8); -		ensure_approximately_equals( -			"4c:operator*= failed", -			vec3D.mdV[VZ], -			z1*mulVal, -			8); -	} +        ensure("1:operator [] failed",( x ==  vec3D[0])); +        ensure("2:operator [] failed",( y ==  vec3D[1])); +        ensure("3:operator [] failed",( z ==  vec3D[2])); +        vec3D.clearVec(); +        x = 23.23, y = -.2361, z = 3.25; +        vec3D.setVec(x,y,z); +        F64 &ref1 = vec3D[0]; +        ensure("4:operator [] failed",( ref1 ==  vec3D[0])); +        F64 &ref2 = vec3D[1]; +        ensure("5:operator [] failed",( ref2 ==  vec3D[1])); +        F64 &ref3 = vec3D[2]; +        ensure("6:operator [] failed",( ref3 ==  vec3D[2])); +    } -	template<> template<> -	void v3dmath_object::test<12>() -	{ -		F64 x1 = 1., y1 = 2., z1 = -1.1; -		F64 x2 = 1.2, y2 = 2.5, z2 = 1.; -		F64 val1, val2, val3; -		LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2), vec3Db; -		vec3Db = vec3D % vec3Da; -		val1 = y1*z2 - y2*z1; -		val2 = z1*x2 -z2*x1; -		val3 = x1*y2-x2*y1; -		ensure("1:operator% failed",(val1 == vec3Db.mdV[VX]) && (val2 == vec3Db.mdV[VY]) && (val3 == vec3Db.mdV[VZ]));  -		vec3D %= vec3Da; -		ensure("2:operator%= failed", -		       is_approx_equal(vec3D.mdV[VX],vec3Db.mdV[VX]) && -		       is_approx_equal(vec3D.mdV[VY],vec3Db.mdV[VY]) && -		       is_approx_equal(vec3D.mdV[VZ],vec3Db.mdV[VZ]) );  -	} +    template<> template<> +    void v3dmath_object::test<8>() +    { +        F32 x = 1.f, y = 2.f, z = -1.f; +        LLVector4 vec4(x,y,z); +        LLVector3d vec3D; +        vec3D = vec4; +        ensure("1:operator=:Fail to initialize ", ((vec4.mV[VX] == vec3D.mdV[VX]) && (vec4.mV[VY] == vec3D.mdV[VY]) && (vec4.mV[VZ] == vec3D.mdV[VZ]))); +    } -	template<> template<> -	void v3dmath_object::test<13>() -	{ -		F64 x1 = 1., y1 = 2., z1 = -1.1,div = 4.2; -		F64 t = 1.f / div; -		LLVector3d vec3D(x1,y1,z1), vec3Da; -		vec3Da = vec3D/div; -		ensure_approximately_equals( -			"1a:operator/ failed", -			vec3Da.mdV[VX], -			x1*t, -			8); -		ensure_approximately_equals( -			"1b:operator/ failed", -			vec3Da.mdV[VY], -			y1*t, -			8); -		ensure_approximately_equals( -			"1c:operator/ failed", -			vec3Da.mdV[VZ], -			z1*t, -			8); -		x1 = 1.23, y1 = 4., z1 = -2.32; -		vec3D.clearVec(); -		vec3Da.clearVec(); -		vec3D.setVec(x1,y1,z1); -		vec3Da = vec3D/div; -		ensure_approximately_equals( -			"2a:operator/ failed", -			vec3Da.mdV[VX], -			x1*t, -			8); -		ensure_approximately_equals( -			"2b:operator/ failed", -			vec3Da.mdV[VY], -			y1*t, -			8); -		ensure_approximately_equals( -			"2c:operator/ failed", -			vec3Da.mdV[VZ], -			z1*t, -			8); -		vec3D /= div; -		ensure_approximately_equals( -			"3a:operator/= failed", -			vec3D.mdV[VX], -			x1*t, -			8); -		ensure_approximately_equals( -			"3b:operator/= failed", -			vec3D.mdV[VY], -			y1*t, -			8); -		ensure_approximately_equals( -			"3c:operator/= failed", -			vec3D.mdV[VZ], -			z1*t, -			8); -	} +    template<> template<> +    void v3dmath_object::test<9>() +    { +        F64 x1 = 1.78787878, y1 = 232322.2121, z1 = -12121.121212; +        F64 x2 = 1.2, y2 = 2.5, z2 = 1.; +        LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db; +        vec3Db = vec3Da+ vec3D; +        ensure("1:operator+:Fail to initialize ", ((x1+x2 == vec3Db.mdV[VX]) && (y1+y2 == vec3Db.mdV[VY]) && (z1+z2 == vec3Db.mdV[VZ]))); +        x1 = -2.45, y1 = 2.1, z1 = 3.0; +        vec3D.clearVec(); +        vec3Da.clearVec(); +        vec3D.setVec(x1,y1,z1); +        vec3Da += vec3D; +        ensure_equals("2:operator+=: Fail to initialize", vec3Da,vec3D); +        vec3Da += vec3D; +        ensure("3:operator+=:Fail to initialize ", ((2*x1 == vec3Da.mdV[VX]) && (2*y1 == vec3Da.mdV[VY]) && (2*z1 == vec3Da.mdV[VZ]))); +    } -	template<> template<> -	void v3dmath_object::test<14>() -	{ -		F64 x1 = 1., y1 = 2., z1 = -1.1; -		LLVector3d vec3D(x1,y1,z1), vec3Da; -		ensure("1:operator!= failed",(TRUE == (vec3D !=vec3Da))); -		vec3Da = vec3D; -		ensure("2:operator== failed",(vec3D ==vec3Da));  -		vec3D.clearVec(); -		vec3Da.clearVec(); -		x1 = .211, y1 = 21.111, z1 = 23.22; -		vec3D.setVec(x1,y1,z1); -		vec3Da.setVec(x1,y1,z1); -		ensure("3:operator== failed",(vec3D ==vec3Da));  -		ensure("4:operator!= failed",(FALSE == (vec3D !=vec3Da))); -	} -		 -	template<> template<> -	void v3dmath_object::test<15>() -	{ -		F64 x1 = 1., y1 = 2., z1 = -1.1; -		LLVector3d vec3D(x1,y1,z1), vec3Da; -		std::ostringstream stream1, stream2; -		stream1 << vec3D; -		vec3Da.setVec(x1,y1,z1); -		stream2 << vec3Da; -		ensure("1:operator << failed",(stream1.str() == stream2.str()));	 -	} +    template<> template<> +    void v3dmath_object::test<10>() +    { +        F64 x1 = 1., y1 = 2., z1 = -1.1; +        F64 x2 = 1.2, y2 = 2.5, z2 = 1.; +        LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db; +        vec3Db = vec3Da - vec3D; +        ensure("1:operator-:Fail to initialize ", ((x2-x1 == vec3Db.mdV[VX]) && (y2-y1 == vec3Db.mdV[VY]) && (z2-z1 == vec3Db.mdV[VZ]))); +        x1 = -2.45, y1 = 2.1, z1 = 3.0; +        vec3D.clearVec(); +        vec3Da.clearVec(); +        vec3D.setVec(x1,y1,z1); +        vec3Da -=vec3D; +        ensure("2:operator-=:Fail to initialize ", ((2.45 == vec3Da.mdV[VX]) && (-2.1 == vec3Da.mdV[VY]) && (-3.0 == vec3Da.mdV[VZ]))); +        vec3Da -= vec3D; +        ensure("3:operator-=:Fail to initialize ", ((-2*x1 == vec3Da.mdV[VX]) && (-2*y1 == vec3Da.mdV[VY]) && (-2*z1 == vec3Da.mdV[VZ]))); +    } +    template<> template<> +    void v3dmath_object::test<11>() +    { +        F64 x1 = 1., y1 = 2., z1 = -1.1; +        F64 x2 = 1.2, y2 = 2.5, z2 = 1.; +        LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2); +        F64 res = vec3D * vec3Da; +        ensure_approximately_equals( +            "1:operator* failed", +            res, +            (x1*x2 + y1*y2 + z1*z2), +            8); +        vec3Da.clearVec(); +        F64 mulVal = 4.2; +        vec3Da = vec3D * mulVal; +        ensure_approximately_equals( +            "2a:operator* failed", +            vec3Da.mdV[VX], +            x1*mulVal, +            8); +        ensure_approximately_equals( +            "2b:operator* failed", +            vec3Da.mdV[VY], +            y1*mulVal, +            8); +        ensure_approximately_equals( +            "2c:operator* failed", +            vec3Da.mdV[VZ], +            z1*mulVal, +            8); +        vec3Da.clearVec(); +        vec3Da = mulVal * vec3D; +        ensure_approximately_equals( +            "3a:operator* failed", +            vec3Da.mdV[VX], +            x1*mulVal, +            8); +        ensure_approximately_equals( +            "3b:operator* failed", +            vec3Da.mdV[VY], +            y1*mulVal, +            8); +        ensure_approximately_equals( +            "3c:operator* failed", +            vec3Da.mdV[VZ], +            z1*mulVal, +            8); +        vec3D *= mulVal; +        ensure_approximately_equals( +            "4a:operator*= failed", +            vec3D.mdV[VX], +            x1*mulVal, +            8); +        ensure_approximately_equals( +            "4b:operator*= failed", +            vec3D.mdV[VY], +            y1*mulVal, +            8); +        ensure_approximately_equals( +            "4c:operator*= failed", +            vec3D.mdV[VZ], +            z1*mulVal, +            8); +    } -	template<> template<> -	void v3dmath_object::test<16>() -	{ -		F64 x1 = 1.23, y1 = 2.0, z1 = 4.; -		std::string buf("1.23 2. 4"); -		LLVector3d vec3D, vec3Da(x1,y1,z1); -		LLVector3d::parseVector3d(buf, &vec3D); -		ensure_equals("1:parseVector3d: failed " , vec3D, vec3Da);	 -	} +    template<> template<> +    void v3dmath_object::test<12>() +    { +        F64 x1 = 1., y1 = 2., z1 = -1.1; +        F64 x2 = 1.2, y2 = 2.5, z2 = 1.; +        F64 val1, val2, val3; +        LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2), vec3Db; +        vec3Db = vec3D % vec3Da; +        val1 = y1*z2 - y2*z1; +        val2 = z1*x2 -z2*x1; +        val3 = x1*y2-x2*y1; +        ensure("1:operator% failed",(val1 == vec3Db.mdV[VX]) && (val2 == vec3Db.mdV[VY]) && (val3 == vec3Db.mdV[VZ])); +        vec3D %= vec3Da; +        ensure("2:operator%= failed", +               is_approx_equal(vec3D.mdV[VX],vec3Db.mdV[VX]) && +               is_approx_equal(vec3D.mdV[VY],vec3Db.mdV[VY]) && +               is_approx_equal(vec3D.mdV[VZ],vec3Db.mdV[VZ]) ); +    } -	template<> template<> -	void v3dmath_object::test<17>() -	{ -		F64 x1 = 1., y1 = 2., z1 = -1.1; -		LLVector3d vec3D(x1,y1,z1), vec3Da; -		vec3Da = -vec3D; -		ensure("1:operator- failed", (vec3D == - vec3Da));	 -	} +    template<> template<> +    void v3dmath_object::test<13>() +    { +        F64 x1 = 1., y1 = 2., z1 = -1.1,div = 4.2; +        F64 t = 1.f / div; +        LLVector3d vec3D(x1,y1,z1), vec3Da; +        vec3Da = vec3D/div; +        ensure_approximately_equals( +            "1a:operator/ failed", +            vec3Da.mdV[VX], +            x1*t, +            8); +        ensure_approximately_equals( +            "1b:operator/ failed", +            vec3Da.mdV[VY], +            y1*t, +            8); +        ensure_approximately_equals( +            "1c:operator/ failed", +            vec3Da.mdV[VZ], +            z1*t, +            8); +        x1 = 1.23, y1 = 4., z1 = -2.32; +        vec3D.clearVec(); +        vec3Da.clearVec(); +        vec3D.setVec(x1,y1,z1); +        vec3Da = vec3D/div; +        ensure_approximately_equals( +            "2a:operator/ failed", +            vec3Da.mdV[VX], +            x1*t, +            8); +        ensure_approximately_equals( +            "2b:operator/ failed", +            vec3Da.mdV[VY], +            y1*t, +            8); +        ensure_approximately_equals( +            "2c:operator/ failed", +            vec3Da.mdV[VZ], +            z1*t, +            8); +        vec3D /= div; +        ensure_approximately_equals( +            "3a:operator/= failed", +            vec3D.mdV[VX], +            x1*t, +            8); +        ensure_approximately_equals( +            "3b:operator/= failed", +            vec3D.mdV[VY], +            y1*t, +            8); +        ensure_approximately_equals( +            "3c:operator/= failed", +            vec3D.mdV[VZ], +            z1*t, +            8); +    } -	template<> template<> -	void v3dmath_object::test<18>() -	{ -		F64 x = 1., y = 2., z = -1.1; -		LLVector3d vec3D(x,y,z); -		F64 res = (x*x + y*y + z*z) - vec3D.magVecSquared(); -		ensure("1:magVecSquared:Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO))); -		res = (F32) sqrt(x*x + y*y + z*z) - vec3D.magVec(); -		ensure("2:magVec: Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO)));	 -	} +    template<> template<> +    void v3dmath_object::test<14>() +    { +        F64 x1 = 1., y1 = 2., z1 = -1.1; +        LLVector3d vec3D(x1,y1,z1), vec3Da; +        ensure("1:operator!= failed",(TRUE == (vec3D !=vec3Da))); +        vec3Da = vec3D; +        ensure("2:operator== failed",(vec3D ==vec3Da)); +        vec3D.clearVec(); +        vec3Da.clearVec(); +        x1 = .211, y1 = 21.111, z1 = 23.22; +        vec3D.setVec(x1,y1,z1); +        vec3Da.setVec(x1,y1,z1); +        ensure("3:operator== failed",(vec3D ==vec3Da)); +        ensure("4:operator!= failed",(FALSE == (vec3D !=vec3Da))); +    } -	template<> template<> -	void v3dmath_object::test<19>() -	{ -		F64 x = 1., y = 2., z = -1.1; -		LLVector3d vec3D(x,y,z); -		F64 mag = vec3D.normVec(); -		mag = 1.f/ mag; -		ensure_approximately_equals( -			"1a:normVec: Fail ", -			vec3D.mdV[VX], -			x * mag, -			8); -		ensure_approximately_equals( -			"1b:normVec: Fail ", -			vec3D.mdV[VY], -			y * mag, -			8); -		ensure_approximately_equals( -			"1c:normVec: Fail ", -			vec3D.mdV[VZ], -			z * mag, -			8); -		x = 0.000000001, y = 0.000000001, z = 0.000000001; -		vec3D.clearVec(); -		vec3D.setVec(x,y,z); -		mag = vec3D.normVec(); -		ensure_approximately_equals( -			"2a:normVec: Fail ", -			vec3D.mdV[VX], -			x * mag, -			8); -		ensure_approximately_equals( -			"2b:normVec: Fail ", -			vec3D.mdV[VY], -			y * mag, -			8); -		ensure_approximately_equals( -			"2c:normVec: Fail ", -			vec3D.mdV[VZ], -			z * mag, -			8); -	} +    template<> template<> +    void v3dmath_object::test<15>() +    { +        F64 x1 = 1., y1 = 2., z1 = -1.1; +        LLVector3d vec3D(x1,y1,z1), vec3Da; +        std::ostringstream stream1, stream2; +        stream1 << vec3D; +        vec3Da.setVec(x1,y1,z1); +        stream2 << vec3Da; +        ensure("1:operator << failed",(stream1.str() == stream2.str())); +    } -	template<> template<> -	void v3dmath_object::test<20>() -	{ -		F64 x1 = 1111.232222; -		F64 y1 = 2222222222.22; -		F64 z1 = 422222222222.0; -		std::string buf("1111.232222 2222222222.22 422222222222"); -		LLVector3d vec3Da, vec3Db(x1,y1,z1); -		LLVector3d::parseVector3d(buf, &vec3Da); -		ensure_equals("1:parseVector3 failed", vec3Da, vec3Db);	 -	} +    template<> template<> +    void v3dmath_object::test<16>() +    { +        F64 x1 = 1.23, y1 = 2.0, z1 = 4.; +        std::string buf("1.23 2. 4"); +        LLVector3d vec3D, vec3Da(x1,y1,z1); +        LLVector3d::parseVector3d(buf, &vec3D); +        ensure_equals("1:parseVector3d: failed " , vec3D, vec3Da); +    } -	template<> template<> -	void v3dmath_object::test<21>() -	{ -		F64 x1 = 1., y1 = 2., z1 = -1.1; -		F64 x2 = 1.2, y2 = 2.5, z2 = 1.; -		F64 val = 2.3f,val1,val2,val3; -		val1 = x1 + (x2 - x1)* val; -		val2 = y1 + (y2 - y1)* val; -		val3 = z1 + (z2 - z1)* val; -		LLVector3d vec3Da(x1,y1,z1),vec3Db(x2,y2,z2); -		LLVector3d vec3d = lerp(vec3Da,vec3Db,val); -		ensure("1:lerp failed", ((val1 ==vec3d.mdV[VX])&& (val2 ==vec3d.mdV[VY]) && (val3 ==vec3d.mdV[VZ])));		 -	} +    template<> template<> +    void v3dmath_object::test<17>() +    { +        F64 x1 = 1., y1 = 2., z1 = -1.1; +        LLVector3d vec3D(x1,y1,z1), vec3Da; +        vec3Da = -vec3D; +        ensure("1:operator- failed", (vec3D == - vec3Da)); +    } -	template<> template<> -	void v3dmath_object::test<22>() -	{ -		F64 x = 2.32, y = 1.212, z = -.12; -		F64 min = 0.0001, max = 3.0; -		LLVector3d vec3d(x,y,z);		 -		ensure("1:clamp:Fail ", (TRUE == (vec3d.clamp(min, max)))); -		x = 0.000001f, z = 5.3f; -		vec3d.setVec(x,y,z); -		ensure("2:clamp:Fail ", (TRUE == (vec3d.clamp(min, max)))); -	} +    template<> template<> +    void v3dmath_object::test<18>() +    { +        F64 x = 1., y = 2., z = -1.1; +        LLVector3d vec3D(x,y,z); +        F64 res = (x*x + y*y + z*z) - vec3D.magVecSquared(); +        ensure("1:magVecSquared:Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO))); +        res = (F32) sqrt(x*x + y*y + z*z) - vec3D.magVec(); +        ensure("2:magVec: Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO))); +    } -	template<> template<> -	void v3dmath_object::test<23>() -	{ -		F64 x = 10., y = 20., z = -15.; -		F64 epsilon = .23425; -		LLVector3d vec3Da(x,y,z), vec3Db(x,y,z); -		ensure("1:are_parallel: Fail ", (TRUE == are_parallel(vec3Da,vec3Db,epsilon))); -		F64 x1 = -12., y1 = -20., z1 = -100.; -		vec3Db.clearVec(); -		vec3Db.setVec(x1,y1,z1); -		ensure("2:are_parallel: Fail ", (FALSE == are_parallel(vec3Da,vec3Db,epsilon))); -	} +    template<> template<> +    void v3dmath_object::test<19>() +    { +        F64 x = 1., y = 2., z = -1.1; +        LLVector3d vec3D(x,y,z); +        F64 mag = vec3D.normVec(); +        mag = 1.f/ mag; +        ensure_approximately_equals( +            "1a:normVec: Fail ", +            vec3D.mdV[VX], +            x * mag, +            8); +        ensure_approximately_equals( +            "1b:normVec: Fail ", +            vec3D.mdV[VY], +            y * mag, +            8); +        ensure_approximately_equals( +            "1c:normVec: Fail ", +            vec3D.mdV[VZ], +            z * mag, +            8); +        x = 0.000000001, y = 0.000000001, z = 0.000000001; +        vec3D.clearVec(); +        vec3D.setVec(x,y,z); +        mag = vec3D.normVec(); +        ensure_approximately_equals( +            "2a:normVec: Fail ", +            vec3D.mdV[VX], +            x * mag, +            8); +        ensure_approximately_equals( +            "2b:normVec: Fail ", +            vec3D.mdV[VY], +            y * mag, +            8); +        ensure_approximately_equals( +            "2c:normVec: Fail ", +            vec3D.mdV[VZ], +            z * mag, +            8); +    } -	template<> template<> -	void v3dmath_object::test<24>() -	{ +    template<> template<> +    void v3dmath_object::test<20>() +    { +        F64 x1 = 1111.232222; +        F64 y1 = 2222222222.22; +        F64 z1 = 422222222222.0; +        std::string buf("1111.232222 2222222222.22 422222222222"); +        LLVector3d vec3Da, vec3Db(x1,y1,z1); +        LLVector3d::parseVector3d(buf, &vec3Da); +        ensure_equals("1:parseVector3 failed", vec3Da, vec3Db); +    } + +    template<> template<> +    void v3dmath_object::test<21>() +    { +        F64 x1 = 1., y1 = 2., z1 = -1.1; +        F64 x2 = 1.2, y2 = 2.5, z2 = 1.; +        F64 val = 2.3f,val1,val2,val3; +        val1 = x1 + (x2 - x1)* val; +        val2 = y1 + (y2 - y1)* val; +        val3 = z1 + (z2 - z1)* val; +        LLVector3d vec3Da(x1,y1,z1),vec3Db(x2,y2,z2); +        LLVector3d vec3d = lerp(vec3Da,vec3Db,val); +        ensure("1:lerp failed", ((val1 ==vec3d.mdV[VX])&& (val2 ==vec3d.mdV[VY]) && (val3 ==vec3d.mdV[VZ]))); +    } + +    template<> template<> +    void v3dmath_object::test<22>() +    { +        F64 x = 2.32, y = 1.212, z = -.12; +        F64 min = 0.0001, max = 3.0; +        LLVector3d vec3d(x,y,z); +        ensure("1:clamp:Fail ", (TRUE == (vec3d.clamp(min, max)))); +        x = 0.000001f, z = 5.3f; +        vec3d.setVec(x,y,z); +        ensure("2:clamp:Fail ", (TRUE == (vec3d.clamp(min, max)))); +    } + +    template<> template<> +    void v3dmath_object::test<23>() +    { +        F64 x = 10., y = 20., z = -15.; +        F64 epsilon = .23425; +        LLVector3d vec3Da(x,y,z), vec3Db(x,y,z); +        ensure("1:are_parallel: Fail ", (TRUE == are_parallel(vec3Da,vec3Db,epsilon))); +        F64 x1 = -12., y1 = -20., z1 = -100.; +        vec3Db.clearVec(); +        vec3Db.setVec(x1,y1,z1); +        ensure("2:are_parallel: Fail ", (FALSE == are_parallel(vec3Da,vec3Db,epsilon))); +    } + +    template<> template<> +    void v3dmath_object::test<24>() +    {  #if LL_WINDOWS && _MSC_VER < 1400 -		skip("This fails on VS2003!"); +        skip("This fails on VS2003!");  #else -		F64 x = 10., y = 20., z = -15.; -		F64 angle1, angle2; -		LLVector3d vec3Da(x,y,z), vec3Db(x,y,z); -		angle1 = angle_between(vec3Da, vec3Db); -		ensure("1:angle_between: Fail ", (0 == angle1)); -		F64 x1 = -1., y1 = -20., z1 = -1.; -		vec3Da.clearVec(); -		vec3Da.setVec(x1,y1,z1); -		angle2 = angle_between(vec3Da, vec3Db); -		vec3Db.normVec(); -		vec3Da.normVec(); -		F64 angle = vec3Db*vec3Da; -		angle = acos(angle); +        F64 x = 10., y = 20., z = -15.; +        F64 angle1, angle2; +        LLVector3d vec3Da(x,y,z), vec3Db(x,y,z); +        angle1 = angle_between(vec3Da, vec3Db); +        ensure("1:angle_between: Fail ", (0 == angle1)); +        F64 x1 = -1., y1 = -20., z1 = -1.; +        vec3Da.clearVec(); +        vec3Da.setVec(x1,y1,z1); +        angle2 = angle_between(vec3Da, vec3Db); +        vec3Db.normVec(); +        vec3Da.normVec(); +        F64 angle = vec3Db*vec3Da; +        angle = acos(angle);  #if LL_WINDOWS && _MSC_VER > 1900 -		skip("This fails on VS2017!"); +        skip("This fails on VS2017!");  #else -		ensure("2:angle_between: Fail ", (angle == angle2)); +        ensure("2:angle_between: Fail ", (angle == angle2));  #endif -		 +  #endif -	} +    }  } diff --git a/indra/llmath/tests/v3math_test.cpp b/indra/llmath/tests/v3math_test.cpp index e4ae1c10ef..7f93aba354 100644 --- a/indra/llmath/tests/v3math_test.cpp +++ b/indra/llmath/tests/v3math_test.cpp @@ -7,25 +7,25 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -  +  #include "linden_common.h"  #include "../test/lltut.h"  #include "llsd.h" @@ -40,546 +40,546 @@  namespace tut  { -	struct v3math_data -	{ -	}; -	typedef test_group<v3math_data> v3math_test; -	typedef v3math_test::object v3math_object; -	tut::v3math_test v3math_testcase("v3math_h"); - -	template<> template<> -	void v3math_object::test<1>() -	{ -		LLVector3 vec3; -		ensure("1:LLVector3:Fail to initialize ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); -		F32 x = 2.32f, y = 1.212f, z = -.12f; -		LLVector3 vec3a(x,y,z); -		ensure("2:LLVector3:Fail to initialize ", ((2.32f == vec3a.mV[VX]) && (1.212f == vec3a.mV[VY]) && (-.12f == vec3a.mV[VZ]))); -		const F32 vec[3] = {1.2f ,3.2f, -4.2f}; -		LLVector3 vec3b(vec); -		ensure("3:LLVector3:Fail to initialize ", ((1.2f == vec3b.mV[VX]) && (3.2f == vec3b.mV[VY]) && (-4.2f == vec3b.mV[VZ]))); -	} - -	template<> template<> -	void v3math_object::test<2>() -	{ -		F32 x = 2.32f, y = 1.212f, z = -.12f; -		LLVector3 vec3(x,y,z); -		LLVector3d vector3d(vec3); -		LLVector3 vec3a(vector3d); -		ensure("1:LLVector3:Fail to initialize ", vec3 == vec3a); -		LLVector4 vector4(vec3); -		LLVector3 vec3b(vector4); -		ensure("2:LLVector3:Fail to initialize ", vec3 == vec3b); -	} - -	template<> template<> -	void v3math_object::test<3>() -	{ -		S32 a = 231; -		LLSD llsd(a); -		LLVector3 vec3(llsd); -		LLSD sd = vec3.getValue(); -		LLVector3 vec3a(sd); -		ensure("1:LLVector3:Fail to initialize ", (vec3 == vec3a)); -	} - -	template<> template<> -	void v3math_object::test<4>() -	{ -		S32 a = 231; -		LLSD llsd(a); -		LLVector3 vec3(llsd),vec3a; -		vec3a = vec3; -		ensure("1:Operator= Fail to initialize " ,(vec3 == vec3a)); -	} -	 -	template<> template<> -	void v3math_object::test<5>() -	{ -		F32 x = 2.32f, y = 1.212f, z = -.12f; -		LLVector3 vec3(x,y,z); -		ensure("1:isFinite= Fail to initialize ", (TRUE == vec3.isFinite()));//need more test cases: -		vec3.clearVec(); -		ensure("2:clearVec:Fail to set values ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); -		vec3.setVec(x,y,z); -		ensure("3:setVec:Fail to set values ", ((2.32f == vec3.mV[VX]) && (1.212f == vec3.mV[VY]) && (-.12f == vec3.mV[VZ]))); -		vec3.zeroVec(); -		ensure("4:zeroVec:Fail to set values ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); -	} -	 -	template<> template<> -	void v3math_object::test<6>() -	{ -		F32 x = 2.32f, y = 1.212f, z = -.12f; -		LLVector3 vec3(x,y,z),vec3a; -		vec3.abs(); -		ensure("1:abs:Fail ", ((x == vec3.mV[VX]) && (y == vec3.mV[VY]) && (-z == vec3.mV[VZ]))); -		vec3a.setVec(vec3); -		ensure("2:setVec:Fail to initialize ", (vec3a == vec3));	 -		const F32 vec[3] = {1.2f ,3.2f, -4.2f}; -		vec3.clearVec(); -		vec3.setVec(vec); -		ensure("3:setVec:Fail to initialize ", ((1.2f == vec3.mV[VX]) && (3.2f == vec3.mV[VY]) && (-4.2f == vec3.mV[VZ]))); -		vec3a.clearVec(); -		LLVector3d vector3d(vec3); -		vec3a.setVec(vector3d); -		ensure("4:setVec:Fail to initialize ", (vec3 == vec3a)); -		LLVector4 vector4(vec3); -		vec3a.clearVec(); -		vec3a.setVec(vector4); -		ensure("5:setVec:Fail to initialize ", (vec3 == vec3a)); -	} - -	template<> template<> -	void v3math_object::test<7>() -	{ -		F32 x = 2.32f, y = 3.212f, z = -.12f; -		F32 min = 0.0001f, max = 3.0f; -		LLVector3 vec3(x,y,z);		 -		ensure("1:clamp:Fail  ", TRUE == vec3.clamp(min, max) && x == vec3.mV[VX] && max == vec3.mV[VY] && min == vec3.mV[VZ]); -		x = 1.f, y = 2.2f, z = 2.8f; -		vec3.setVec(x,y,z); -		ensure("2:clamp:Fail  ", FALSE == vec3.clamp(min, max)); -	} - -	template<> template<> -	void v3math_object::test<8>() -	{ -		F32 x = 2.32f, y = 1.212f, z = -.12f; -		LLVector3 vec3(x,y,z);		 -		ensure("1:magVecSquared:Fail ", is_approx_equal(vec3.magVecSquared(), (x*x + y*y + z*z))); -		ensure("2:magVec:Fail ", is_approx_equal(vec3.magVec(), (F32) sqrt(x*x + y*y + z*z))); -	} - -	template<> template<> -	void v3math_object::test<9>() -	{ -		F32 x =-2.0f, y = -3.0f, z = 1.23f ; -		LLVector3 vec3(x,y,z); -		ensure("1:abs():Fail ", (TRUE == vec3.abs()));	 -		ensure("2:isNull():Fail", (FALSE == vec3.isNull()));	//Returns TRUE if vector has a _very_small_ length -		x =.00000001f, y = .000001001f, z = .000001001f; -		vec3.setVec(x,y,z); -		ensure("3:isNull(): Fail ", (TRUE == vec3.isNull()));	 -	} - -	template<> template<> -	void v3math_object::test<10>() -	{ -		F32 x =-2.0f, y = -3.0f, z = 1.f ; -		LLVector3 vec3(x,y,z),vec3a; -		ensure("1:isExactlyZero():Fail ", (TRUE == vec3a.isExactlyZero())); -		vec3a = vec3a.scaleVec(vec3); -		ensure("2:scaleVec: Fail ", vec3a.mV[VX] == 0.f && vec3a.mV[VY] == 0.f && vec3a.mV[VZ] == 0.f); -		vec3a.setVec(x,y,z); -		vec3a = vec3a.scaleVec(vec3); -		ensure("3:scaleVec: Fail ", ((4 == vec3a.mV[VX]) && (9 == vec3a.mV[VY]) &&(1 == vec3a.mV[VZ]))); -		ensure("4:isExactlyZero():Fail ", (FALSE == vec3.isExactlyZero())); -	} - -	template<> template<> -	void v3math_object::test<11>() -	{ -		F32 x =20.0f, y = 30.0f, z = 15.f ; -		F32 angle = 100.f; -		LLVector3 vec3(x,y,z),vec3a(1.f,2.f,3.f); -		vec3a = vec3a.rotVec(angle, vec3); -		LLVector3 vec3b(1.f,2.f,3.f); -		vec3b = vec3b.rotVec(angle, vec3); -		ensure_equals("rotVec():Fail" ,vec3b,vec3a); -	} - -	template<> template<> -	void v3math_object::test<12>() -	{ -		F32 x =-2.0f, y = -3.0f, z = 1.f ; -		LLVector3 vec3(x,y,z); -		ensure("1:operator [] failed",( x ==  vec3[0]));	 -		ensure("2:operator [] failed",( y ==  vec3[1])); -		ensure("3:operator [] failed",( z ==  vec3[2])); - -		vec3.clearVec(); -		x = 23.f, y = -.2361f, z = 3.25; -		vec3.setVec(x,y,z); -		F32 &ref1 = vec3[0]; -		ensure("4:operator [] failed",( ref1 ==  vec3[0])); -		F32 &ref2 = vec3[1]; -		ensure("5:operator [] failed",( ref2 ==  vec3[1])); -		F32 &ref3 = vec3[2]; -		ensure("6:operator [] failed",( ref3 ==  vec3[2])); -	} - -	template<> template<> -	void v3math_object::test<13>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; -		F32 val1, val2, val3; -		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; -		vec3b = vec3 + vec3a ; -		val1 = x1+x2; -		val2 = y1+y2; -		val3 = z1+z2; -		ensure("1:operator+ failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  - -		vec3.clearVec(); -		vec3a.clearVec(); -		vec3b.clearVec(); -		x1 = -.235f, y1 = -24.32f,z1 = 2.13f,  x2 = -2.3f, y2 = 1.f, z2 = 34.21f; -		vec3.setVec(x1,y1,z1); -		vec3a.setVec(x2,y2,z2); -		vec3b = vec3 + vec3a; -		val1 = x1+x2; -		val2 = y1+y2; -		val3 = z1+z2; -		ensure("2:operator+ failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  -	} - -	template<> template<> -	void v3math_object::test<14>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; -		F32 val1, val2, val3; -		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; -		vec3b = vec3 - vec3a ; -		val1 = x1-x2; -		val2 = y1-y2; -		val3 = z1-z2; -		ensure("1:operator- failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  - -		vec3.clearVec(); -		vec3a.clearVec(); -		vec3b.clearVec(); -		x1 = -.235f, y1 = -24.32f,z1 = 2.13f,  x2 = -2.3f, y2 = 1.f, z2 = 34.21f; -		vec3.setVec(x1,y1,z1); -		vec3a.setVec(x2,y2,z2); -		vec3b = vec3 - vec3a; -		val1 = x1-x2; -		val2 = y1-y2; -		val3 = z1-z2; -		ensure("2:operator- failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  -	} - -	template<> template<> -	void v3math_object::test<15>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; -		F32 val1, val2, val3; -		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); -		val1 = vec3 * vec3a; -		val2 = x1*x2 + y1*y2 + z1*z2; -		ensure_equals("1:operator* failed",val1,val2); - -		vec3a.clearVec(); -		F32 mulVal = 4.332f; -		vec3a = vec3 * mulVal; -		val1 = x1*mulVal; -		val2 = y1*mulVal; -		val3 = z1*mulVal; -		ensure("2:operator* failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); -		vec3a.clearVec(); -		vec3a = mulVal * vec3; -		ensure("3:operator* failed ", (val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); -	} - -	template<> template<> -	void v3math_object::test<16>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; -		F32 val1, val2, val3; -		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; -		vec3b = vec3 % vec3a ; -		val1 = y1*z2 - y2*z1; -		val2 = z1*x2 -z2*x1; -		val3 = x1*y2-x2*y1; -		ensure("1:operator% failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  - -		vec3.clearVec(); -		vec3a.clearVec(); -		vec3b.clearVec(); -		x1 =112.f, y1 = 22.3f,z1 = 1.2f, x2 = -2.3f, y2 = 341.11f, z2 = 1234.234f; -		vec3.setVec(x1,y1,z1); -		vec3a.setVec(x2,y2,z2); -		vec3b = vec3 % vec3a ; -		val1 = y1*z2 - y2*z1; -		val2 = z1*x2 -z2*x1; -		val3 = x1*y2-x2*y1; -		ensure("2:operator% failed ", (val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  -	} - -	template<> template<> -	void v3math_object::test<17>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, div = 3.2f; -		F32 t = 1.f / div, val1, val2, val3; -		LLVector3 vec3(x1,y1,z1), vec3a; -		vec3a = vec3 / div; -		val1 = x1 * t; -		val2 = y1 * t; -		val3 = z1 *t; -		ensure("1:operator/ failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ]));		 - -		vec3a.clearVec(); -		x1 = -.235f, y1 = -24.32f, z1 = .342f, div = -2.2f; -		t = 1.f / div; -		vec3.setVec(x1,y1,z1); -		vec3a = vec3 / div; -		val1 = x1 * t; -		val2 = y1 * t; -		val3 = z1 *t; -		ensure("2:operator/ failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ]));		 -	} - -	template<> template<> -	void v3math_object::test<18>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; -		LLVector3 vec3(x1,y1,z1), vec3a(x1,y1,z1); -		ensure("1:operator== failed",(vec3 == vec3a));		 - -		vec3a.clearVec(); -		x1 = -.235f, y1 = -24.32f, z1 = .342f; -		vec3.clearVec(); -		vec3a.clearVec(); -		vec3.setVec(x1,y1,z1); -		vec3a.setVec(x1,y1,z1); -		ensure("2:operator== failed ", (vec3 == vec3a));		 -	} - -	template<> template<> -	void v3math_object::test<19>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.234f,z2 = 11.2f;; -		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); -		ensure("1:operator!= failed",(vec3a != vec3)); - -		vec3.clearVec(); -		vec3.clearVec(); -		vec3a.setVec(vec3); -		ensure("2:operator!= failed", ( FALSE == (vec3a != vec3))); -	} - -	template<> template<> -	void v3math_object::test<20>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.2f,z2 = 11.2f;; -		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); -		vec3a += vec3; -		F32 val1, val2, val3; -		val1 = x1+x2; -		val2 = y1+y2; -		val3 = z1+z2; -		ensure("1:operator+= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); -	} -	 -	template<> template<> -	void v3math_object::test<21>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.2f,z2 = 11.2f;; -		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); -		vec3a -= vec3; -		F32 val1, val2, val3; -		val1 = x2-x1; -		val2 = y2-y1; -		val3 = z2-z1; -		ensure("1:operator-= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); -	} - -	template<> template<> -	void v3math_object::test<22>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; -		F32 val1,val2,val3; -		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); -		vec3a *= vec3; -		val1 = x1*x2; -		val2 = y1*y2; -		val3 = z1*z2; -		ensure("1:operator*= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); - -		F32 mulVal = 4.332f; -		vec3 *=mulVal; -		val1 = x1*mulVal; -		val2 = y1*mulVal; -		val3 = z1*mulVal; -		ensure("2:operator*= failed ", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]) && is_approx_equal(val3, vec3.mV[VZ])); -	} - -	template<> template<> -	void v3math_object::test<23>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; -		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2),vec3b; -		vec3b = vec3a % vec3; -		vec3a %= vec3; -		ensure_equals("1:operator%= failed",vec3a,vec3b);  -	} - -	template<> template<> -	void v3math_object::test<24>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, div = 3.2f; -		F32 t = 1.f / div, val1, val2, val3; -		LLVector3 vec3a(x1,y1,z1); -		vec3a /= div; -		val1 = x1 * t; -		val2 = y1 * t; -		val3 = z1 *t; -		ensure("1:operator/= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ]));		 -	} - -	template<> template<> -	void v3math_object::test<25>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; -		LLVector3 vec3(x1,y1,z1), vec3a; -		vec3a = -vec3; -		ensure("1:operator- failed",(-vec3a == vec3));	 -	} - -	template<> template<> -	void v3math_object::test<26>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; -		std::ostringstream stream1, stream2; -		LLVector3 vec3(x1,y1,z1), vec3a; -		stream1 << vec3; -		vec3a.setVec(x1,y1,z1); -		stream2 << vec3a; -		ensure("1:operator << failed",(stream1.str() == stream2.str()));	 -	} - -	template<> template<> -	void v3math_object::test<27>() -	{ -		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.11f, z2 = 1234.234f; -		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); -		ensure("1:operator< failed", (TRUE == (vec3 < vec3a))); -		x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 2.f, z2 = 1234.234f; -		vec3.setVec(x1,y1,z1); -		vec3a.setVec(x2,y2,z2); -		ensure("2:operator< failed ", (TRUE == (vec3 < vec3a))); -		x1 =2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, -		vec3.setVec(x1,y1,z1); -		vec3a.setVec(x2,y2,z2); -		ensure("3:operator< failed ", (FALSE == (vec3 < vec3a))); -	} - -	template<> template<> -	void v3math_object::test<28>() -	{ -		F32 x1 =1.23f, y1 = 2.f,z1 = 4.f; -		std::string buf("1.23 2. 4"); -		LLVector3 vec3, vec3a(x1,y1,z1); -		LLVector3::parseVector3(buf, &vec3); -		ensure_equals("1:parseVector3 failed", vec3, vec3a);	 -	} - -	template<> template<> -	void v3math_object::test<29>() -	{ -		F32 x1 =1.f, y1 = 2.f,z1 = 4.f; -		LLVector3 vec3(x1,y1,z1),vec3a,vec3b; -		vec3a.setVec(1,1,1); -		vec3a.scaleVec(vec3); -		ensure_equals("1:scaleVec failed", vec3, vec3a);	 -		vec3a.clearVec(); -		vec3a.setVec(x1,y1,z1); -		vec3a.scaleVec(vec3); -		ensure("2:scaleVec failed", ((1.f ==vec3a.mV[VX])&& (4.f ==vec3a.mV[VY]) && (16.f ==vec3a.mV[VZ])));		 -	} -	 -	template<> template<> -	void v3math_object::test<30>() -	{ -		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.11f, z2 = 1234.234f; -		F32 val = 2.3f,val1,val2,val3; -		val1 = x1 + (x2 - x1)* val; -		val2 = y1 + (y2 - y1)* val; -		val3 = z1 + (z2 - z1)* val; -		LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2); -		LLVector3 vec3b = lerp(vec3,vec3a,val); -		ensure("1:lerp failed", ((val1 ==vec3b.mV[VX])&& (val2 ==vec3b.mV[VY]) && (val3 ==vec3b.mV[VZ])));		 -	} - -	template<> template<> -	void v3math_object::test<31>() -	{ -		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f; -		F32 val1,val2; -		LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2); -		val1 = dist_vec(vec3,vec3a); -		val2 = (F32) sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); -		ensure_equals("1:dist_vec: Fail ",val2, val1); -		val1 = dist_vec_squared(vec3,vec3a); -		val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); -		ensure_equals("2:dist_vec_squared: Fail ",val2, val1); -		val1 = dist_vec_squared2D(vec3, vec3a); -		val2 =(x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2); -		ensure_equals("3:dist_vec_squared2D: Fail ",val2, val1); -	} - -	template<> template<> -	void v3math_object::test<32>() -	{ -		F32 x =12.3524f, y = -342.f,z = 4.126341f; -		LLVector3 vec3(x,y,z); -		F32 mag = vec3.normVec(); -		mag = 1.f/ mag; -		F32 val1 = x* mag, val2 = y* mag, val3 = z* mag; -		ensure("1:normVec: Fail ", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]) && is_approx_equal(val3, vec3.mV[VZ])); -		x = 0.000000001f, y = 0.f, z = 0.f; -		vec3.clearVec(); -		vec3.setVec(x,y,z); -		mag = vec3.normVec(); -		val1 = x* mag, val2 = y* mag, val3 = z* mag; -		ensure("2:normVec: Fail ", (mag == 0.) && (0. == vec3.mV[VX]) && (0. == vec3.mV[VY])&& (0. == vec3.mV[VZ])); -	} - -	template<> template<> -	void v3math_object::test<33>() -	{ -		F32 x = -202.23412f, y = 123.2312f, z = -89.f; -		LLVector3 vec(x,y,z); -		vec.snap(2); -		ensure("1:snap: Fail ", is_approx_equal(-202.23f, vec.mV[VX]) && is_approx_equal(123.23f, vec.mV[VY]) && is_approx_equal(-89.f, vec.mV[VZ])); -	} -		 -	template<> template<> -	void v3math_object::test<34>() -	{ -		F32 x = 10.f, y = 20.f, z = -15.f; -		F32 x1, y1, z1; -		F32 lowerxy = 0.f, upperxy = 1.0f, lowerz = -1.0f, upperz = 1.f; -		LLVector3 vec3(x,y,z); -		vec3.quantize16(lowerxy,upperxy,lowerz,upperz); -		x1 = U16_to_F32(F32_to_U16(x, lowerxy, upperxy), lowerxy, upperxy); -		y1 = U16_to_F32(F32_to_U16(y, lowerxy, upperxy), lowerxy, upperxy); -		z1 = U16_to_F32(F32_to_U16(z, lowerz,  upperz),  lowerz,  upperz); -		ensure("1:quantize16: Fail ", is_approx_equal(x1, vec3.mV[VX]) && is_approx_equal(y1, vec3.mV[VY]) && is_approx_equal(z1, vec3.mV[VZ])); -		LLVector3 vec3a(x,y,z); -		vec3a.quantize8(lowerxy,upperxy,lowerz,upperz); -		x1 = U8_to_F32(F32_to_U8(x, lowerxy, upperxy), lowerxy, upperxy); -		y1 = U8_to_F32(F32_to_U8(y, lowerxy, upperxy), lowerxy, upperxy); -		z1 = U8_to_F32(F32_to_U8(z, lowerz, upperz), lowerz, upperz); -		ensure("2:quantize8: Fail ", is_approx_equal(x1, vec3a.mV[VX]) && is_approx_equal(y1, vec3a.mV[VY]) && is_approx_equal(z1, vec3a.mV[VZ])); -	} - -	template<> template<> -	void v3math_object::test<35>() -	{ -		LLSD sd = LLSD::emptyArray(); -		sd[0] = 1.f; - -		LLVector3 parsed_1(sd); -		ensure("1:LLSD parse: Fail ", is_approx_equal(parsed_1.mV[VX], 1.f) && is_approx_equal(parsed_1.mV[VY], 0.f) && is_approx_equal(parsed_1.mV[VZ], 0.f)); - -		sd[1] = 2.f; -		LLVector3 parsed_2(sd); -		ensure("2:LLSD parse: Fail ", is_approx_equal(parsed_2.mV[VX], 1.f) && is_approx_equal(parsed_2.mV[VY], 2.f) && is_approx_equal(parsed_2.mV[VZ], 0.f)); - -		sd[2] = 3.f; -		LLVector3 parsed_3(sd); -		ensure("3:LLSD parse: Fail ", is_approx_equal(parsed_3.mV[VX], 1.f) && is_approx_equal(parsed_3.mV[VY], 2.f) && is_approx_equal(parsed_3.mV[VZ], 3.f)); -	} +    struct v3math_data +    { +    }; +    typedef test_group<v3math_data> v3math_test; +    typedef v3math_test::object v3math_object; +    tut::v3math_test v3math_testcase("v3math_h"); + +    template<> template<> +    void v3math_object::test<1>() +    { +        LLVector3 vec3; +        ensure("1:LLVector3:Fail to initialize ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); +        F32 x = 2.32f, y = 1.212f, z = -.12f; +        LLVector3 vec3a(x,y,z); +        ensure("2:LLVector3:Fail to initialize ", ((2.32f == vec3a.mV[VX]) && (1.212f == vec3a.mV[VY]) && (-.12f == vec3a.mV[VZ]))); +        const F32 vec[3] = {1.2f ,3.2f, -4.2f}; +        LLVector3 vec3b(vec); +        ensure("3:LLVector3:Fail to initialize ", ((1.2f == vec3b.mV[VX]) && (3.2f == vec3b.mV[VY]) && (-4.2f == vec3b.mV[VZ]))); +    } + +    template<> template<> +    void v3math_object::test<2>() +    { +        F32 x = 2.32f, y = 1.212f, z = -.12f; +        LLVector3 vec3(x,y,z); +        LLVector3d vector3d(vec3); +        LLVector3 vec3a(vector3d); +        ensure("1:LLVector3:Fail to initialize ", vec3 == vec3a); +        LLVector4 vector4(vec3); +        LLVector3 vec3b(vector4); +        ensure("2:LLVector3:Fail to initialize ", vec3 == vec3b); +    } + +    template<> template<> +    void v3math_object::test<3>() +    { +        S32 a = 231; +        LLSD llsd(a); +        LLVector3 vec3(llsd); +        LLSD sd = vec3.getValue(); +        LLVector3 vec3a(sd); +        ensure("1:LLVector3:Fail to initialize ", (vec3 == vec3a)); +    } + +    template<> template<> +    void v3math_object::test<4>() +    { +        S32 a = 231; +        LLSD llsd(a); +        LLVector3 vec3(llsd),vec3a; +        vec3a = vec3; +        ensure("1:Operator= Fail to initialize " ,(vec3 == vec3a)); +    } + +    template<> template<> +    void v3math_object::test<5>() +    { +        F32 x = 2.32f, y = 1.212f, z = -.12f; +        LLVector3 vec3(x,y,z); +        ensure("1:isFinite= Fail to initialize ", (TRUE == vec3.isFinite()));//need more test cases: +        vec3.clearVec(); +        ensure("2:clearVec:Fail to set values ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); +        vec3.setVec(x,y,z); +        ensure("3:setVec:Fail to set values ", ((2.32f == vec3.mV[VX]) && (1.212f == vec3.mV[VY]) && (-.12f == vec3.mV[VZ]))); +        vec3.zeroVec(); +        ensure("4:zeroVec:Fail to set values ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); +    } + +    template<> template<> +    void v3math_object::test<6>() +    { +        F32 x = 2.32f, y = 1.212f, z = -.12f; +        LLVector3 vec3(x,y,z),vec3a; +        vec3.abs(); +        ensure("1:abs:Fail ", ((x == vec3.mV[VX]) && (y == vec3.mV[VY]) && (-z == vec3.mV[VZ]))); +        vec3a.setVec(vec3); +        ensure("2:setVec:Fail to initialize ", (vec3a == vec3)); +        const F32 vec[3] = {1.2f ,3.2f, -4.2f}; +        vec3.clearVec(); +        vec3.setVec(vec); +        ensure("3:setVec:Fail to initialize ", ((1.2f == vec3.mV[VX]) && (3.2f == vec3.mV[VY]) && (-4.2f == vec3.mV[VZ]))); +        vec3a.clearVec(); +        LLVector3d vector3d(vec3); +        vec3a.setVec(vector3d); +        ensure("4:setVec:Fail to initialize ", (vec3 == vec3a)); +        LLVector4 vector4(vec3); +        vec3a.clearVec(); +        vec3a.setVec(vector4); +        ensure("5:setVec:Fail to initialize ", (vec3 == vec3a)); +    } + +    template<> template<> +    void v3math_object::test<7>() +    { +        F32 x = 2.32f, y = 3.212f, z = -.12f; +        F32 min = 0.0001f, max = 3.0f; +        LLVector3 vec3(x,y,z); +        ensure("1:clamp:Fail  ", TRUE == vec3.clamp(min, max) && x == vec3.mV[VX] && max == vec3.mV[VY] && min == vec3.mV[VZ]); +        x = 1.f, y = 2.2f, z = 2.8f; +        vec3.setVec(x,y,z); +        ensure("2:clamp:Fail  ", FALSE == vec3.clamp(min, max)); +    } + +    template<> template<> +    void v3math_object::test<8>() +    { +        F32 x = 2.32f, y = 1.212f, z = -.12f; +        LLVector3 vec3(x,y,z); +        ensure("1:magVecSquared:Fail ", is_approx_equal(vec3.magVecSquared(), (x*x + y*y + z*z))); +        ensure("2:magVec:Fail ", is_approx_equal(vec3.magVec(), (F32) sqrt(x*x + y*y + z*z))); +    } + +    template<> template<> +    void v3math_object::test<9>() +    { +        F32 x =-2.0f, y = -3.0f, z = 1.23f ; +        LLVector3 vec3(x,y,z); +        ensure("1:abs():Fail ", (TRUE == vec3.abs())); +        ensure("2:isNull():Fail", (FALSE == vec3.isNull()));    //Returns TRUE if vector has a _very_small_ length +        x =.00000001f, y = .000001001f, z = .000001001f; +        vec3.setVec(x,y,z); +        ensure("3:isNull(): Fail ", (TRUE == vec3.isNull())); +    } + +    template<> template<> +    void v3math_object::test<10>() +    { +        F32 x =-2.0f, y = -3.0f, z = 1.f ; +        LLVector3 vec3(x,y,z),vec3a; +        ensure("1:isExactlyZero():Fail ", (TRUE == vec3a.isExactlyZero())); +        vec3a = vec3a.scaleVec(vec3); +        ensure("2:scaleVec: Fail ", vec3a.mV[VX] == 0.f && vec3a.mV[VY] == 0.f && vec3a.mV[VZ] == 0.f); +        vec3a.setVec(x,y,z); +        vec3a = vec3a.scaleVec(vec3); +        ensure("3:scaleVec: Fail ", ((4 == vec3a.mV[VX]) && (9 == vec3a.mV[VY]) &&(1 == vec3a.mV[VZ]))); +        ensure("4:isExactlyZero():Fail ", (FALSE == vec3.isExactlyZero())); +    } + +    template<> template<> +    void v3math_object::test<11>() +    { +        F32 x =20.0f, y = 30.0f, z = 15.f ; +        F32 angle = 100.f; +        LLVector3 vec3(x,y,z),vec3a(1.f,2.f,3.f); +        vec3a = vec3a.rotVec(angle, vec3); +        LLVector3 vec3b(1.f,2.f,3.f); +        vec3b = vec3b.rotVec(angle, vec3); +        ensure_equals("rotVec():Fail" ,vec3b,vec3a); +    } + +    template<> template<> +    void v3math_object::test<12>() +    { +        F32 x =-2.0f, y = -3.0f, z = 1.f ; +        LLVector3 vec3(x,y,z); +        ensure("1:operator [] failed",( x ==  vec3[0])); +        ensure("2:operator [] failed",( y ==  vec3[1])); +        ensure("3:operator [] failed",( z ==  vec3[2])); + +        vec3.clearVec(); +        x = 23.f, y = -.2361f, z = 3.25; +        vec3.setVec(x,y,z); +        F32 &ref1 = vec3[0]; +        ensure("4:operator [] failed",( ref1 ==  vec3[0])); +        F32 &ref2 = vec3[1]; +        ensure("5:operator [] failed",( ref2 ==  vec3[1])); +        F32 &ref3 = vec3[2]; +        ensure("6:operator [] failed",( ref3 ==  vec3[2])); +    } + +    template<> template<> +    void v3math_object::test<13>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +        F32 val1, val2, val3; +        LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; +        vec3b = vec3 + vec3a ; +        val1 = x1+x2; +        val2 = y1+y2; +        val3 = z1+z2; +        ensure("1:operator+ failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); + +        vec3.clearVec(); +        vec3a.clearVec(); +        vec3b.clearVec(); +        x1 = -.235f, y1 = -24.32f,z1 = 2.13f,  x2 = -2.3f, y2 = 1.f, z2 = 34.21f; +        vec3.setVec(x1,y1,z1); +        vec3a.setVec(x2,y2,z2); +        vec3b = vec3 + vec3a; +        val1 = x1+x2; +        val2 = y1+y2; +        val3 = z1+z2; +        ensure("2:operator+ failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<14>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +        F32 val1, val2, val3; +        LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; +        vec3b = vec3 - vec3a ; +        val1 = x1-x2; +        val2 = y1-y2; +        val3 = z1-z2; +        ensure("1:operator- failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); + +        vec3.clearVec(); +        vec3a.clearVec(); +        vec3b.clearVec(); +        x1 = -.235f, y1 = -24.32f,z1 = 2.13f,  x2 = -2.3f, y2 = 1.f, z2 = 34.21f; +        vec3.setVec(x1,y1,z1); +        vec3a.setVec(x2,y2,z2); +        vec3b = vec3 - vec3a; +        val1 = x1-x2; +        val2 = y1-y2; +        val3 = z1-z2; +        ensure("2:operator- failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<15>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +        F32 val1, val2, val3; +        LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +        val1 = vec3 * vec3a; +        val2 = x1*x2 + y1*y2 + z1*z2; +        ensure_equals("1:operator* failed",val1,val2); + +        vec3a.clearVec(); +        F32 mulVal = 4.332f; +        vec3a = vec3 * mulVal; +        val1 = x1*mulVal; +        val2 = y1*mulVal; +        val3 = z1*mulVal; +        ensure("2:operator* failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); +        vec3a.clearVec(); +        vec3a = mulVal * vec3; +        ensure("3:operator* failed ", (val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<16>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +        F32 val1, val2, val3; +        LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; +        vec3b = vec3 % vec3a ; +        val1 = y1*z2 - y2*z1; +        val2 = z1*x2 -z2*x1; +        val3 = x1*y2-x2*y1; +        ensure("1:operator% failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); + +        vec3.clearVec(); +        vec3a.clearVec(); +        vec3b.clearVec(); +        x1 =112.f, y1 = 22.3f,z1 = 1.2f, x2 = -2.3f, y2 = 341.11f, z2 = 1234.234f; +        vec3.setVec(x1,y1,z1); +        vec3a.setVec(x2,y2,z2); +        vec3b = vec3 % vec3a ; +        val1 = y1*z2 - y2*z1; +        val2 = z1*x2 -z2*x1; +        val3 = x1*y2-x2*y1; +        ensure("2:operator% failed ", (val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<17>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, div = 3.2f; +        F32 t = 1.f / div, val1, val2, val3; +        LLVector3 vec3(x1,y1,z1), vec3a; +        vec3a = vec3 / div; +        val1 = x1 * t; +        val2 = y1 * t; +        val3 = z1 *t; +        ensure("1:operator/ failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ])); + +        vec3a.clearVec(); +        x1 = -.235f, y1 = -24.32f, z1 = .342f, div = -2.2f; +        t = 1.f / div; +        vec3.setVec(x1,y1,z1); +        vec3a = vec3 / div; +        val1 = x1 * t; +        val2 = y1 * t; +        val3 = z1 *t; +        ensure("2:operator/ failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<18>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; +        LLVector3 vec3(x1,y1,z1), vec3a(x1,y1,z1); +        ensure("1:operator== failed",(vec3 == vec3a)); + +        vec3a.clearVec(); +        x1 = -.235f, y1 = -24.32f, z1 = .342f; +        vec3.clearVec(); +        vec3a.clearVec(); +        vec3.setVec(x1,y1,z1); +        vec3a.setVec(x1,y1,z1); +        ensure("2:operator== failed ", (vec3 == vec3a)); +    } + +    template<> template<> +    void v3math_object::test<19>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.234f,z2 = 11.2f;; +        LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +        ensure("1:operator!= failed",(vec3a != vec3)); + +        vec3.clearVec(); +        vec3.clearVec(); +        vec3a.setVec(vec3); +        ensure("2:operator!= failed", ( FALSE == (vec3a != vec3))); +    } + +    template<> template<> +    void v3math_object::test<20>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.2f,z2 = 11.2f;; +        LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +        vec3a += vec3; +        F32 val1, val2, val3; +        val1 = x1+x2; +        val2 = y1+y2; +        val3 = z1+z2; +        ensure("1:operator+= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<21>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.2f,z2 = 11.2f;; +        LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +        vec3a -= vec3; +        F32 val1, val2, val3; +        val1 = x2-x1; +        val2 = y2-y1; +        val3 = z2-z1; +        ensure("1:operator-= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<22>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +        F32 val1,val2,val3; +        LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +        vec3a *= vec3; +        val1 = x1*x2; +        val2 = y1*y2; +        val3 = z1*z2; +        ensure("1:operator*= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); + +        F32 mulVal = 4.332f; +        vec3 *=mulVal; +        val1 = x1*mulVal; +        val2 = y1*mulVal; +        val3 = z1*mulVal; +        ensure("2:operator*= failed ", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]) && is_approx_equal(val3, vec3.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<23>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +        LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2),vec3b; +        vec3b = vec3a % vec3; +        vec3a %= vec3; +        ensure_equals("1:operator%= failed",vec3a,vec3b); +    } + +    template<> template<> +    void v3math_object::test<24>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, div = 3.2f; +        F32 t = 1.f / div, val1, val2, val3; +        LLVector3 vec3a(x1,y1,z1); +        vec3a /= div; +        val1 = x1 * t; +        val2 = y1 * t; +        val3 = z1 *t; +        ensure("1:operator/= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<25>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; +        LLVector3 vec3(x1,y1,z1), vec3a; +        vec3a = -vec3; +        ensure("1:operator- failed",(-vec3a == vec3)); +    } + +    template<> template<> +    void v3math_object::test<26>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; +        std::ostringstream stream1, stream2; +        LLVector3 vec3(x1,y1,z1), vec3a; +        stream1 << vec3; +        vec3a.setVec(x1,y1,z1); +        stream2 << vec3a; +        ensure("1:operator << failed",(stream1.str() == stream2.str())); +    } + +    template<> template<> +    void v3math_object::test<27>() +    { +        F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.11f, z2 = 1234.234f; +        LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +        ensure("1:operator< failed", (TRUE == (vec3 < vec3a))); +        x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 2.f, z2 = 1234.234f; +        vec3.setVec(x1,y1,z1); +        vec3a.setVec(x2,y2,z2); +        ensure("2:operator< failed ", (TRUE == (vec3 < vec3a))); +        x1 =2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, +        vec3.setVec(x1,y1,z1); +        vec3a.setVec(x2,y2,z2); +        ensure("3:operator< failed ", (FALSE == (vec3 < vec3a))); +    } + +    template<> template<> +    void v3math_object::test<28>() +    { +        F32 x1 =1.23f, y1 = 2.f,z1 = 4.f; +        std::string buf("1.23 2. 4"); +        LLVector3 vec3, vec3a(x1,y1,z1); +        LLVector3::parseVector3(buf, &vec3); +        ensure_equals("1:parseVector3 failed", vec3, vec3a); +    } + +    template<> template<> +    void v3math_object::test<29>() +    { +        F32 x1 =1.f, y1 = 2.f,z1 = 4.f; +        LLVector3 vec3(x1,y1,z1),vec3a,vec3b; +        vec3a.setVec(1,1,1); +        vec3a.scaleVec(vec3); +        ensure_equals("1:scaleVec failed", vec3, vec3a); +        vec3a.clearVec(); +        vec3a.setVec(x1,y1,z1); +        vec3a.scaleVec(vec3); +        ensure("2:scaleVec failed", ((1.f ==vec3a.mV[VX])&& (4.f ==vec3a.mV[VY]) && (16.f ==vec3a.mV[VZ]))); +    } + +    template<> template<> +    void v3math_object::test<30>() +    { +        F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.11f, z2 = 1234.234f; +        F32 val = 2.3f,val1,val2,val3; +        val1 = x1 + (x2 - x1)* val; +        val2 = y1 + (y2 - y1)* val; +        val3 = z1 + (z2 - z1)* val; +        LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2); +        LLVector3 vec3b = lerp(vec3,vec3a,val); +        ensure("1:lerp failed", ((val1 ==vec3b.mV[VX])&& (val2 ==vec3b.mV[VY]) && (val3 ==vec3b.mV[VZ]))); +    } + +    template<> template<> +    void v3math_object::test<31>() +    { +        F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f; +        F32 val1,val2; +        LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2); +        val1 = dist_vec(vec3,vec3a); +        val2 = (F32) sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); +        ensure_equals("1:dist_vec: Fail ",val2, val1); +        val1 = dist_vec_squared(vec3,vec3a); +        val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); +        ensure_equals("2:dist_vec_squared: Fail ",val2, val1); +        val1 = dist_vec_squared2D(vec3, vec3a); +        val2 =(x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2); +        ensure_equals("3:dist_vec_squared2D: Fail ",val2, val1); +    } + +    template<> template<> +    void v3math_object::test<32>() +    { +        F32 x =12.3524f, y = -342.f,z = 4.126341f; +        LLVector3 vec3(x,y,z); +        F32 mag = vec3.normVec(); +        mag = 1.f/ mag; +        F32 val1 = x* mag, val2 = y* mag, val3 = z* mag; +        ensure("1:normVec: Fail ", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]) && is_approx_equal(val3, vec3.mV[VZ])); +        x = 0.000000001f, y = 0.f, z = 0.f; +        vec3.clearVec(); +        vec3.setVec(x,y,z); +        mag = vec3.normVec(); +        val1 = x* mag, val2 = y* mag, val3 = z* mag; +        ensure("2:normVec: Fail ", (mag == 0.) && (0. == vec3.mV[VX]) && (0. == vec3.mV[VY])&& (0. == vec3.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<33>() +    { +        F32 x = -202.23412f, y = 123.2312f, z = -89.f; +        LLVector3 vec(x,y,z); +        vec.snap(2); +        ensure("1:snap: Fail ", is_approx_equal(-202.23f, vec.mV[VX]) && is_approx_equal(123.23f, vec.mV[VY]) && is_approx_equal(-89.f, vec.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<34>() +    { +        F32 x = 10.f, y = 20.f, z = -15.f; +        F32 x1, y1, z1; +        F32 lowerxy = 0.f, upperxy = 1.0f, lowerz = -1.0f, upperz = 1.f; +        LLVector3 vec3(x,y,z); +        vec3.quantize16(lowerxy,upperxy,lowerz,upperz); +        x1 = U16_to_F32(F32_to_U16(x, lowerxy, upperxy), lowerxy, upperxy); +        y1 = U16_to_F32(F32_to_U16(y, lowerxy, upperxy), lowerxy, upperxy); +        z1 = U16_to_F32(F32_to_U16(z, lowerz,  upperz),  lowerz,  upperz); +        ensure("1:quantize16: Fail ", is_approx_equal(x1, vec3.mV[VX]) && is_approx_equal(y1, vec3.mV[VY]) && is_approx_equal(z1, vec3.mV[VZ])); +        LLVector3 vec3a(x,y,z); +        vec3a.quantize8(lowerxy,upperxy,lowerz,upperz); +        x1 = U8_to_F32(F32_to_U8(x, lowerxy, upperxy), lowerxy, upperxy); +        y1 = U8_to_F32(F32_to_U8(y, lowerxy, upperxy), lowerxy, upperxy); +        z1 = U8_to_F32(F32_to_U8(z, lowerz, upperz), lowerz, upperz); +        ensure("2:quantize8: Fail ", is_approx_equal(x1, vec3a.mV[VX]) && is_approx_equal(y1, vec3a.mV[VY]) && is_approx_equal(z1, vec3a.mV[VZ])); +    } + +    template<> template<> +    void v3math_object::test<35>() +    { +        LLSD sd = LLSD::emptyArray(); +        sd[0] = 1.f; + +        LLVector3 parsed_1(sd); +        ensure("1:LLSD parse: Fail ", is_approx_equal(parsed_1.mV[VX], 1.f) && is_approx_equal(parsed_1.mV[VY], 0.f) && is_approx_equal(parsed_1.mV[VZ], 0.f)); + +        sd[1] = 2.f; +        LLVector3 parsed_2(sd); +        ensure("2:LLSD parse: Fail ", is_approx_equal(parsed_2.mV[VX], 1.f) && is_approx_equal(parsed_2.mV[VY], 2.f) && is_approx_equal(parsed_2.mV[VZ], 0.f)); + +        sd[2] = 3.f; +        LLVector3 parsed_3(sd); +        ensure("3:LLSD parse: Fail ", is_approx_equal(parsed_3.mV[VX], 1.f) && is_approx_equal(parsed_3.mV[VY], 2.f) && is_approx_equal(parsed_3.mV[VZ], 3.f)); +    }  } diff --git a/indra/llmath/tests/v4color_test.cpp b/indra/llmath/tests/v4color_test.cpp index d7eec3c87f..3b3adbda0d 100644 --- a/indra/llmath/tests/v4color_test.cpp +++ b/indra/llmath/tests/v4color_test.cpp @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -38,322 +38,322 @@  namespace tut  { -	struct v4color_data -	{ -	}; -	typedef test_group<v4color_data> v4color_test; -	typedef v4color_test::object v4color_object; -	tut::v4color_test v4color_testcase("v4color_h"); - -	template<> template<> -	void v4color_object::test<1>() -	{ -		LLColor4 llcolor4; -		ensure("1:LLColor4:Fail to initialize ", ((0 == llcolor4.mV[VX]) && (0 == llcolor4.mV[VY]) && (0 == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); - -		F32 r = 0x20, g = 0xFFFF, b = 0xFF, a = 0xAF; -		LLColor4 llcolor4a(r,g,b); -		ensure("2:LLColor4:Fail to initialize ", ((r == llcolor4a.mV[VX]) && (g == llcolor4a.mV[VY]) && (b == llcolor4a.mV[VZ])&& (1.0f == llcolor4a.mV[VW]))); -		 -		LLColor4 llcolor4b(r,g,b,a); -		ensure("3:LLColor4:Fail to initialize ", ((r == llcolor4b.mV[VX]) && (g == llcolor4b.mV[VY]) && (b == llcolor4b.mV[VZ])&& (a == llcolor4b.mV[VW]))); -		 -		const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; -		LLColor4 llcolor4c(vec); -		ensure("4:LLColor4:Fail to initialize ", ((vec[0] == llcolor4c.mV[VX]) && (vec[1] == llcolor4c.mV[VY]) && (vec[2] == llcolor4c.mV[VZ])&& (vec[3] == llcolor4c.mV[VW])));		 -		 -		LLColor3 llcolor3(-2.23f,1.01f,42.3f); -		F32 val = -.1f; -		LLColor4 llcolor4d(llcolor3,val); -		ensure("5:LLColor4:Fail to initialize ", ((llcolor3.mV[VX] == llcolor4d.mV[VX]) && (llcolor3.mV[VY] == llcolor4d.mV[VY]) && (llcolor3.mV[VZ] == llcolor4d.mV[VZ])&& (val == llcolor4d.mV[VW]))); - -		LLSD sd = llcolor4d.getValue(); -		LLColor4 llcolor4e(sd); -		ensure_equals("6:LLColor4:(LLSD) failed ", llcolor4d, llcolor4e); -		 -		U8 r1 = 0xF2, g1 = 0xFA, b1 = 0xBF; -		LLColor4U color4u(r1,g1,b1); -		LLColor4 llcolor4g(color4u); -		const F32 SCALE = 1.f/255.f; -		F32 r2 = r1*SCALE, g2 = g1* SCALE, b2 = b1* SCALE; -		ensure("7:LLColor4:Fail to initialize ", ((r2 == llcolor4g.mV[VX]) && (g2 == llcolor4g.mV[VY]) && (b2 == llcolor4g.mV[VZ]))); -	} - -	template<> template<> -	void v4color_object::test<2>() -	{ -		LLColor4 llcolor(1.0, 2.0, 3.0, 4.0); -		LLSD llsd = llcolor.getValue(); -		LLColor4 llcolor4(llsd), llcolor4a; -		llcolor4a.setValue(llsd); -		ensure("setValue: failed", (llcolor4 == llcolor4a)); -		LLSD sd = llcolor4a.getValue(); -		LLColor4 llcolor4b(sd); -		ensure("getValue: Failed ", (llcolor4b == llcolor4a)); -	} - -	template<> template<> -	void v4color_object::test<3>() -	{ -		F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0xAF; -		LLColor4 llcolor4(r,g,b,a); -		llcolor4.setToBlack(); -		ensure("setToBlack:Fail to set the black ", ((0 == llcolor4.mV[VX]) && (0 == llcolor4.mV[VY]) && (0 == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); - -		llcolor4.setToWhite(); -		ensure("setToWhite:Fail to set the white ", ((1.f == llcolor4.mV[VX]) && (1.f == llcolor4.mV[VY]) && (1.f == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); -	} - -	template<> template<> -	void v4color_object::test<4>() -	{ -		F32 r = 0x20, g = 0xFFFF, b = 0xFF, a = 0xAF; -		LLColor4 llcolor4; -		llcolor4.setVec(r,g,b); -		ensure("1:setVec:Fail to set the values ", ((r == llcolor4.mV[VX]) && (g == llcolor4.mV[VY]) && (b == llcolor4.mV[VZ])&& (1.f == llcolor4.mV[VW]))); - -		llcolor4.setVec(r,g,b,a); -		ensure("2:setVec:Fail to set the values ", ((r == llcolor4.mV[VX]) && (g == llcolor4.mV[VY]) && (b == llcolor4.mV[VZ])&& (a == llcolor4.mV[VW]))); - -		LLColor4 llcolor4a;  -		llcolor4a.setVec(llcolor4); -		ensure_equals("3:setVec:Fail to set the values ", llcolor4a,llcolor4); - -		LLColor3 llcolor3(-2.23f,1.01f,42.3f); -		llcolor4a.setVec(llcolor3); -		ensure("4:setVec:Fail to set the values ", ((llcolor3.mV[VX] == llcolor4a.mV[VX]) && (llcolor3.mV[VY] == llcolor4a.mV[VY]) && (llcolor3.mV[VZ] == llcolor4a.mV[VZ]))); - -		F32 val = -.33f; -		llcolor4a.setVec(llcolor3,val); -		ensure("4:setVec:Fail to set the values ", ((llcolor3.mV[VX] == llcolor4a.mV[VX]) && (llcolor3.mV[VY] == llcolor4a.mV[VY]) && (llcolor3.mV[VZ] == llcolor4a.mV[VZ]) && (val == llcolor4a.mV[VW]))); - -		const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; -		LLColor4 llcolor4c; -		llcolor4c.setVec(vec); -		ensure("5:setVec:Fail to initialize ", ((vec[0] == llcolor4c.mV[VX]) && (vec[1] == llcolor4c.mV[VY]) && (vec[2] == llcolor4c.mV[VZ])&& (vec[3] == llcolor4c.mV[VW])));		 - -		U8 r1 = 0xF2, g1 = 0xFA, b1= 0xBF; -		LLColor4U color4u(r1,g1,b1); -		llcolor4.setVec(color4u); -		const F32 SCALE = 1.f/255.f; -		F32 r2 = r1*SCALE, g2 = g1* SCALE, b2 = b1* SCALE; -		ensure("6:setVec:Fail to initialize ", ((r2 == llcolor4.mV[VX]) && (g2 == llcolor4.mV[VY]) && (b2 == llcolor4.mV[VZ]))); -	} - -	template<> template<> -	void v4color_object::test<5>() -	{ -		F32 alpha = 0xAF; -		LLColor4 llcolor4; -		llcolor4.setAlpha(alpha); -		ensure("setAlpha:Fail to initialize ", (alpha == llcolor4.mV[VW])); -	} - -	template<> template<> -	void v4color_object::test<6>() -	{ -		F32 r = 0x20, g = 0xFFFF, b = 0xFF; -		LLColor4 llcolor4(r,g,b); -		ensure("magVecSquared:Fail ", is_approx_equal(llcolor4.magVecSquared(), (r*r + g*g + b*b))); -		ensure("magVec:Fail ", is_approx_equal(llcolor4.magVec(), (F32) sqrt(r*r + g*g + b*b))); -	} - -	template<> template<> -	void v4color_object::test<7>() -	{ -		F32 r = 0x20, g = 0xFFFF, b = 0xFF; -		LLColor4 llcolor4(r,g,b); -		F32 vecMag = llcolor4.normVec(); -		F32 mag = (F32) sqrt(r*r + g*g + b*b); -		F32 oomag = 1.f / mag; -		F32 val1 = r * oomag, val2 = g * oomag,	val3 = b * oomag; -		ensure("1:normVec failed ", (is_approx_equal(val1, llcolor4.mV[0]) && is_approx_equal(val2, llcolor4.mV[1]) && is_approx_equal(val3, llcolor4.mV[2]) && is_approx_equal(vecMag, mag))); -	} - -	template<> template<> -	void v4color_object::test<8>() -	{ -		LLColor4 llcolor4; -		ensure("1:isOpaque failed ",(1 == llcolor4.isOpaque())); -		F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 1.f; -		llcolor4.setVec(r,g,b,a); -		ensure("2:isOpaque failed ",(1 == llcolor4.isOpaque())); -		a = 2.f; -		llcolor4.setVec(r,g,b,a); -		ensure("3:isOpaque failed ",(0 == llcolor4.isOpaque())); -	} - -	template<> template<> -	void v4color_object::test<9>() -	{ -		F32 r = 0x20, g = 0xFFFF, b = 0xFF; -		LLColor4 llcolor4(r,g,b); -		ensure("1:operator [] failed",( r ==  llcolor4[0]));	 -		ensure("2:operator [] failed",( g ==  llcolor4[1])); -		ensure("3:operator [] failed",( b ==  llcolor4[2])); - -		r = 0xA20, g = 0xFBFF, b = 0xFFF; -		llcolor4.setVec(r,g,b); -		F32 &ref1 = llcolor4[0]; -		ensure("4:operator [] failed",( ref1 ==  llcolor4[0])); -		F32 &ref2 = llcolor4[1]; -		ensure("5:operator [] failed",( ref2 ==  llcolor4[1])); -		F32 &ref3 = llcolor4[2]; -		ensure("6:operator [] failed",( ref3 ==  llcolor4[2])); -	} - -	template<> template<> -	void v4color_object::test<10>() -	{ -		F32 r = 0x20, g = 0xFFFF, b = 0xFF; -		LLColor3 llcolor3(r,g,b); -		LLColor4 llcolor4a,llcolor4b; -		llcolor4a = llcolor3; -		ensure("Operator=:Fail to initialize ", ((llcolor3.mV[0] == llcolor4a.mV[VX]) && (llcolor3.mV[1] == llcolor4a.mV[VY]) && (llcolor3.mV[2] == llcolor4a.mV[VZ]))); -		LLSD sd = llcolor4a.getValue(); -		llcolor4b = LLColor4(sd); -		ensure_equals("Operator= LLSD:Fail ", llcolor4a, llcolor4b); -	} - -	template<> template<> -	void v4color_object::test<11>() -	{ -		F32 r = 0x20, g = 0xFFFF, b = 0xFF; -		std::ostringstream stream1, stream2; -		LLColor4 llcolor4a(r,g,b),llcolor4b; -		stream1 << llcolor4a; -		llcolor4b.setVec(r,g,b); -		stream2 << llcolor4b; -		ensure("operator << failed ", (stream1.str() == stream2.str()));	 -	} - -	template<> template<> -	void v4color_object::test<12>() -	{ -		F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; -		F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; -		LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; -		llcolor4c = llcolor4b + llcolor4a; -		ensure("operator+:Fail to Add the values ",  (is_approx_equal(r1+r2,llcolor4c.mV[VX]) && is_approx_equal(g1+g2,llcolor4c.mV[VY]) && is_approx_equal(b1+b2,llcolor4c.mV[VZ]))); - -		llcolor4b += llcolor4a; -		ensure("operator+=:Fail to Add the values ",  (is_approx_equal(r1+r2,llcolor4b.mV[VX]) && is_approx_equal(g1+g2,llcolor4b.mV[VY]) && is_approx_equal(b1+b2,llcolor4b.mV[VZ]))); -	} - -	template<> template<> -	void v4color_object::test<13>() -	{ -		F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; -		F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; -		LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; -		llcolor4c = llcolor4a - llcolor4b; -		ensure("operator-:Fail to subtract the values ",  (is_approx_equal(r1-r2,llcolor4c.mV[VX]) && is_approx_equal(g1-g2,llcolor4c.mV[VY]) && is_approx_equal(b1-b2,llcolor4c.mV[VZ]))); - -		llcolor4a -= llcolor4b; -		ensure("operator-=:Fail to subtract the values ",  (is_approx_equal(r1-r2,llcolor4a.mV[VX]) && is_approx_equal(g1-g2,llcolor4a.mV[VY]) && is_approx_equal(b1-b2,llcolor4a.mV[VZ]))); -	} - -	template<> template<> -	void v4color_object::test<14>() -	{ -		F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; -		F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; -		LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; -		llcolor4c = llcolor4a * llcolor4b; -		ensure("1:operator*:Fail to multiply the values",  (is_approx_equal(r1*r2,llcolor4c.mV[VX]) && is_approx_equal(g1*g2,llcolor4c.mV[VY]) && is_approx_equal(b1*b2,llcolor4c.mV[VZ]))); -		 -		F32 mulVal = 3.33f; -		llcolor4c = llcolor4a * mulVal; -		ensure("2:operator*:Fail ",  (is_approx_equal(r1*mulVal,llcolor4c.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4c.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4c.mV[VZ]))); -		llcolor4c = mulVal * llcolor4a; -		ensure("3:operator*:Fail to multiply the values",  (is_approx_equal(r1*mulVal,llcolor4c.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4c.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4c.mV[VZ]))); - -		llcolor4a *= mulVal; -		ensure("4:operator*=:Fail to multiply the values ",  (is_approx_equal(r1*mulVal,llcolor4a.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4a.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4a.mV[VZ]))); - -		LLColor4 llcolor4d(r1,g1,b1),llcolor4e(r2,g2,b2); -		llcolor4e *= llcolor4d; -		ensure("5:operator*=:Fail to multiply the values ",  (is_approx_equal(r1*r2,llcolor4e.mV[VX]) && is_approx_equal(g1*g2,llcolor4e.mV[VY]) && is_approx_equal(b1*b2,llcolor4e.mV[VZ]))); -	} - -	template<> template<> -	void v4color_object::test<15>() -	{ -		F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0x30; -		F32 div = 12.345f; -		LLColor4 llcolor4a(r,g,b,a),llcolor4b; -		llcolor4b = llcolor4a % div;//chnage only alpha value nor r,g,b; -		ensure("1operator%:Fail ",  (is_approx_equal(r,llcolor4b.mV[VX]) && is_approx_equal(g,llcolor4b.mV[VY]) && is_approx_equal(b,llcolor4b.mV[VZ])&& is_approx_equal(div*a,llcolor4b.mV[VW]))); -		 -		llcolor4b = div % llcolor4a; -		ensure("2operator%:Fail ",  (is_approx_equal(r,llcolor4b.mV[VX]) && is_approx_equal(g,llcolor4b.mV[VY]) && is_approx_equal(b,llcolor4b.mV[VZ])&& is_approx_equal(div*a,llcolor4b.mV[VW]))); - -		llcolor4a %= div; -		ensure("operator%=:Fail ",  (is_approx_equal(a*div,llcolor4a.mV[VW]))); -	} - -	template<> template<> -	void v4color_object::test<16>() -	{ -		F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0x30; -		LLColor4 llcolor4a(r,g,b,a),llcolor4b; -		llcolor4b = llcolor4a; -		ensure("1:operator== failed to ensure the equality ", (llcolor4b == llcolor4a));	 -		F32 r1 = 0x2, g1 = 0xFF, b1 = 0xFA; -		LLColor3 llcolor3(r1,g1,b1); -		llcolor4b = llcolor3; -		ensure("2:operator== failed to ensure the equality ", (llcolor4b == llcolor3));	 -		ensure("2:operator!= failed to ensure the equality ", (llcolor4a != llcolor3)); -	} - -	template<> template<> -	void v4color_object::test<17>() -	{ -		F32 r = 0x20, g = 0xFFFF, b = 0xFF; -		LLColor4 llcolor4a(r,g,b),llcolor4b; -		LLColor3 llcolor3 = vec4to3(llcolor4a); -		ensure("vec4to3:Fail to convert vec4 to vec3 ",  (is_approx_equal(llcolor3.mV[VX],llcolor4a.mV[VX]) && is_approx_equal(llcolor3.mV[VY],llcolor4a.mV[VY]) && is_approx_equal(llcolor3.mV[VZ],llcolor4a.mV[VZ]))); -		llcolor4b = vec3to4(llcolor3); -		ensure_equals("vec3to4:Fail to convert vec3 to vec4 ",  llcolor4b, llcolor4a); -	} - -	template<> template<> -	void v4color_object::test<18>() -	{ -		F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF, val = 0x20; -		F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; -		LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; -		llcolor4c = lerp(llcolor4a,llcolor4b,val); -		ensure("lerp:Fail ",  (is_approx_equal(r1 + (r2 - r1)* val,llcolor4c.mV[VX]) && is_approx_equal(g1 + (g2 - g1)* val,llcolor4c.mV[VY]) && is_approx_equal(b1 + (b2 - b1)* val,llcolor4c.mV[VZ]))); -	} - -	template<> template<> -	void v4color_object::test<19>() -	{ -		F32 r = 12.0f, g = -2.3f, b = 1.32f, a = 5.0f; -		LLColor4 llcolor4a(r,g,b,a),llcolor4b; -		std::string color("red"); -		LLColor4::parseColor(color, &llcolor4b); -		ensure_equals("1:parseColor() failed to parse the color value ", llcolor4b, LLColor4::red); - -		color = "12.0, -2.3, 1.32, 5.0"; -		LLColor4::parseColor(color, &llcolor4b); -		llcolor4a = llcolor4a * (1.f / 255.f); -		ensure_equals("2:parseColor() failed to parse the color value ",  llcolor4a,llcolor4b); - -		color = "yellow5"; -		llcolor4a.setVec(r,g,b); -		LLColor4::parseColor(color, &llcolor4a); -		ensure_equals("3:parseColor() failed to parse the color value ", llcolor4a, LLColor4::yellow5); -	} - -	template<> template<> -	void v4color_object::test<20>() -	{ -		F32 r = 12.0f, g = -2.3f, b = 1.32f, a = 5.0f; -		LLColor4 llcolor4a(r,g,b,a),llcolor4b; -		std::string color("12.0, -2.3, 1.32, 5.0"); -		LLColor4::parseColor4(color, &llcolor4b); -		ensure_equals("parseColor4() failed to parse the color value ",  llcolor4a, llcolor4b); -	} +    struct v4color_data +    { +    }; +    typedef test_group<v4color_data> v4color_test; +    typedef v4color_test::object v4color_object; +    tut::v4color_test v4color_testcase("v4color_h"); + +    template<> template<> +    void v4color_object::test<1>() +    { +        LLColor4 llcolor4; +        ensure("1:LLColor4:Fail to initialize ", ((0 == llcolor4.mV[VX]) && (0 == llcolor4.mV[VY]) && (0 == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); + +        F32 r = 0x20, g = 0xFFFF, b = 0xFF, a = 0xAF; +        LLColor4 llcolor4a(r,g,b); +        ensure("2:LLColor4:Fail to initialize ", ((r == llcolor4a.mV[VX]) && (g == llcolor4a.mV[VY]) && (b == llcolor4a.mV[VZ])&& (1.0f == llcolor4a.mV[VW]))); + +        LLColor4 llcolor4b(r,g,b,a); +        ensure("3:LLColor4:Fail to initialize ", ((r == llcolor4b.mV[VX]) && (g == llcolor4b.mV[VY]) && (b == llcolor4b.mV[VZ])&& (a == llcolor4b.mV[VW]))); + +        const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; +        LLColor4 llcolor4c(vec); +        ensure("4:LLColor4:Fail to initialize ", ((vec[0] == llcolor4c.mV[VX]) && (vec[1] == llcolor4c.mV[VY]) && (vec[2] == llcolor4c.mV[VZ])&& (vec[3] == llcolor4c.mV[VW]))); + +        LLColor3 llcolor3(-2.23f,1.01f,42.3f); +        F32 val = -.1f; +        LLColor4 llcolor4d(llcolor3,val); +        ensure("5:LLColor4:Fail to initialize ", ((llcolor3.mV[VX] == llcolor4d.mV[VX]) && (llcolor3.mV[VY] == llcolor4d.mV[VY]) && (llcolor3.mV[VZ] == llcolor4d.mV[VZ])&& (val == llcolor4d.mV[VW]))); + +        LLSD sd = llcolor4d.getValue(); +        LLColor4 llcolor4e(sd); +        ensure_equals("6:LLColor4:(LLSD) failed ", llcolor4d, llcolor4e); + +        U8 r1 = 0xF2, g1 = 0xFA, b1 = 0xBF; +        LLColor4U color4u(r1,g1,b1); +        LLColor4 llcolor4g(color4u); +        const F32 SCALE = 1.f/255.f; +        F32 r2 = r1*SCALE, g2 = g1* SCALE, b2 = b1* SCALE; +        ensure("7:LLColor4:Fail to initialize ", ((r2 == llcolor4g.mV[VX]) && (g2 == llcolor4g.mV[VY]) && (b2 == llcolor4g.mV[VZ]))); +    } + +    template<> template<> +    void v4color_object::test<2>() +    { +        LLColor4 llcolor(1.0, 2.0, 3.0, 4.0); +        LLSD llsd = llcolor.getValue(); +        LLColor4 llcolor4(llsd), llcolor4a; +        llcolor4a.setValue(llsd); +        ensure("setValue: failed", (llcolor4 == llcolor4a)); +        LLSD sd = llcolor4a.getValue(); +        LLColor4 llcolor4b(sd); +        ensure("getValue: Failed ", (llcolor4b == llcolor4a)); +    } + +    template<> template<> +    void v4color_object::test<3>() +    { +        F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0xAF; +        LLColor4 llcolor4(r,g,b,a); +        llcolor4.setToBlack(); +        ensure("setToBlack:Fail to set the black ", ((0 == llcolor4.mV[VX]) && (0 == llcolor4.mV[VY]) && (0 == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); + +        llcolor4.setToWhite(); +        ensure("setToWhite:Fail to set the white ", ((1.f == llcolor4.mV[VX]) && (1.f == llcolor4.mV[VY]) && (1.f == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); +    } + +    template<> template<> +    void v4color_object::test<4>() +    { +        F32 r = 0x20, g = 0xFFFF, b = 0xFF, a = 0xAF; +        LLColor4 llcolor4; +        llcolor4.setVec(r,g,b); +        ensure("1:setVec:Fail to set the values ", ((r == llcolor4.mV[VX]) && (g == llcolor4.mV[VY]) && (b == llcolor4.mV[VZ])&& (1.f == llcolor4.mV[VW]))); + +        llcolor4.setVec(r,g,b,a); +        ensure("2:setVec:Fail to set the values ", ((r == llcolor4.mV[VX]) && (g == llcolor4.mV[VY]) && (b == llcolor4.mV[VZ])&& (a == llcolor4.mV[VW]))); + +        LLColor4 llcolor4a; +        llcolor4a.setVec(llcolor4); +        ensure_equals("3:setVec:Fail to set the values ", llcolor4a,llcolor4); + +        LLColor3 llcolor3(-2.23f,1.01f,42.3f); +        llcolor4a.setVec(llcolor3); +        ensure("4:setVec:Fail to set the values ", ((llcolor3.mV[VX] == llcolor4a.mV[VX]) && (llcolor3.mV[VY] == llcolor4a.mV[VY]) && (llcolor3.mV[VZ] == llcolor4a.mV[VZ]))); + +        F32 val = -.33f; +        llcolor4a.setVec(llcolor3,val); +        ensure("4:setVec:Fail to set the values ", ((llcolor3.mV[VX] == llcolor4a.mV[VX]) && (llcolor3.mV[VY] == llcolor4a.mV[VY]) && (llcolor3.mV[VZ] == llcolor4a.mV[VZ]) && (val == llcolor4a.mV[VW]))); + +        const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; +        LLColor4 llcolor4c; +        llcolor4c.setVec(vec); +        ensure("5:setVec:Fail to initialize ", ((vec[0] == llcolor4c.mV[VX]) && (vec[1] == llcolor4c.mV[VY]) && (vec[2] == llcolor4c.mV[VZ])&& (vec[3] == llcolor4c.mV[VW]))); + +        U8 r1 = 0xF2, g1 = 0xFA, b1= 0xBF; +        LLColor4U color4u(r1,g1,b1); +        llcolor4.setVec(color4u); +        const F32 SCALE = 1.f/255.f; +        F32 r2 = r1*SCALE, g2 = g1* SCALE, b2 = b1* SCALE; +        ensure("6:setVec:Fail to initialize ", ((r2 == llcolor4.mV[VX]) && (g2 == llcolor4.mV[VY]) && (b2 == llcolor4.mV[VZ]))); +    } + +    template<> template<> +    void v4color_object::test<5>() +    { +        F32 alpha = 0xAF; +        LLColor4 llcolor4; +        llcolor4.setAlpha(alpha); +        ensure("setAlpha:Fail to initialize ", (alpha == llcolor4.mV[VW])); +    } + +    template<> template<> +    void v4color_object::test<6>() +    { +        F32 r = 0x20, g = 0xFFFF, b = 0xFF; +        LLColor4 llcolor4(r,g,b); +        ensure("magVecSquared:Fail ", is_approx_equal(llcolor4.magVecSquared(), (r*r + g*g + b*b))); +        ensure("magVec:Fail ", is_approx_equal(llcolor4.magVec(), (F32) sqrt(r*r + g*g + b*b))); +    } + +    template<> template<> +    void v4color_object::test<7>() +    { +        F32 r = 0x20, g = 0xFFFF, b = 0xFF; +        LLColor4 llcolor4(r,g,b); +        F32 vecMag = llcolor4.normVec(); +        F32 mag = (F32) sqrt(r*r + g*g + b*b); +        F32 oomag = 1.f / mag; +        F32 val1 = r * oomag, val2 = g * oomag, val3 = b * oomag; +        ensure("1:normVec failed ", (is_approx_equal(val1, llcolor4.mV[0]) && is_approx_equal(val2, llcolor4.mV[1]) && is_approx_equal(val3, llcolor4.mV[2]) && is_approx_equal(vecMag, mag))); +    } + +    template<> template<> +    void v4color_object::test<8>() +    { +        LLColor4 llcolor4; +        ensure("1:isOpaque failed ",(1 == llcolor4.isOpaque())); +        F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 1.f; +        llcolor4.setVec(r,g,b,a); +        ensure("2:isOpaque failed ",(1 == llcolor4.isOpaque())); +        a = 2.f; +        llcolor4.setVec(r,g,b,a); +        ensure("3:isOpaque failed ",(0 == llcolor4.isOpaque())); +    } + +    template<> template<> +    void v4color_object::test<9>() +    { +        F32 r = 0x20, g = 0xFFFF, b = 0xFF; +        LLColor4 llcolor4(r,g,b); +        ensure("1:operator [] failed",( r ==  llcolor4[0])); +        ensure("2:operator [] failed",( g ==  llcolor4[1])); +        ensure("3:operator [] failed",( b ==  llcolor4[2])); + +        r = 0xA20, g = 0xFBFF, b = 0xFFF; +        llcolor4.setVec(r,g,b); +        F32 &ref1 = llcolor4[0]; +        ensure("4:operator [] failed",( ref1 ==  llcolor4[0])); +        F32 &ref2 = llcolor4[1]; +        ensure("5:operator [] failed",( ref2 ==  llcolor4[1])); +        F32 &ref3 = llcolor4[2]; +        ensure("6:operator [] failed",( ref3 ==  llcolor4[2])); +    } + +    template<> template<> +    void v4color_object::test<10>() +    { +        F32 r = 0x20, g = 0xFFFF, b = 0xFF; +        LLColor3 llcolor3(r,g,b); +        LLColor4 llcolor4a,llcolor4b; +        llcolor4a = llcolor3; +        ensure("Operator=:Fail to initialize ", ((llcolor3.mV[0] == llcolor4a.mV[VX]) && (llcolor3.mV[1] == llcolor4a.mV[VY]) && (llcolor3.mV[2] == llcolor4a.mV[VZ]))); +        LLSD sd = llcolor4a.getValue(); +        llcolor4b = LLColor4(sd); +        ensure_equals("Operator= LLSD:Fail ", llcolor4a, llcolor4b); +    } + +    template<> template<> +    void v4color_object::test<11>() +    { +        F32 r = 0x20, g = 0xFFFF, b = 0xFF; +        std::ostringstream stream1, stream2; +        LLColor4 llcolor4a(r,g,b),llcolor4b; +        stream1 << llcolor4a; +        llcolor4b.setVec(r,g,b); +        stream2 << llcolor4b; +        ensure("operator << failed ", (stream1.str() == stream2.str())); +    } + +    template<> template<> +    void v4color_object::test<12>() +    { +        F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; +        F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; +        LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; +        llcolor4c = llcolor4b + llcolor4a; +        ensure("operator+:Fail to Add the values ",  (is_approx_equal(r1+r2,llcolor4c.mV[VX]) && is_approx_equal(g1+g2,llcolor4c.mV[VY]) && is_approx_equal(b1+b2,llcolor4c.mV[VZ]))); + +        llcolor4b += llcolor4a; +        ensure("operator+=:Fail to Add the values ",  (is_approx_equal(r1+r2,llcolor4b.mV[VX]) && is_approx_equal(g1+g2,llcolor4b.mV[VY]) && is_approx_equal(b1+b2,llcolor4b.mV[VZ]))); +    } + +    template<> template<> +    void v4color_object::test<13>() +    { +        F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; +        F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; +        LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; +        llcolor4c = llcolor4a - llcolor4b; +        ensure("operator-:Fail to subtract the values ",  (is_approx_equal(r1-r2,llcolor4c.mV[VX]) && is_approx_equal(g1-g2,llcolor4c.mV[VY]) && is_approx_equal(b1-b2,llcolor4c.mV[VZ]))); + +        llcolor4a -= llcolor4b; +        ensure("operator-=:Fail to subtract the values ",  (is_approx_equal(r1-r2,llcolor4a.mV[VX]) && is_approx_equal(g1-g2,llcolor4a.mV[VY]) && is_approx_equal(b1-b2,llcolor4a.mV[VZ]))); +    } + +    template<> template<> +    void v4color_object::test<14>() +    { +        F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; +        F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; +        LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; +        llcolor4c = llcolor4a * llcolor4b; +        ensure("1:operator*:Fail to multiply the values",  (is_approx_equal(r1*r2,llcolor4c.mV[VX]) && is_approx_equal(g1*g2,llcolor4c.mV[VY]) && is_approx_equal(b1*b2,llcolor4c.mV[VZ]))); + +        F32 mulVal = 3.33f; +        llcolor4c = llcolor4a * mulVal; +        ensure("2:operator*:Fail ",  (is_approx_equal(r1*mulVal,llcolor4c.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4c.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4c.mV[VZ]))); +        llcolor4c = mulVal * llcolor4a; +        ensure("3:operator*:Fail to multiply the values",  (is_approx_equal(r1*mulVal,llcolor4c.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4c.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4c.mV[VZ]))); + +        llcolor4a *= mulVal; +        ensure("4:operator*=:Fail to multiply the values ",  (is_approx_equal(r1*mulVal,llcolor4a.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4a.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4a.mV[VZ]))); + +        LLColor4 llcolor4d(r1,g1,b1),llcolor4e(r2,g2,b2); +        llcolor4e *= llcolor4d; +        ensure("5:operator*=:Fail to multiply the values ",  (is_approx_equal(r1*r2,llcolor4e.mV[VX]) && is_approx_equal(g1*g2,llcolor4e.mV[VY]) && is_approx_equal(b1*b2,llcolor4e.mV[VZ]))); +    } + +    template<> template<> +    void v4color_object::test<15>() +    { +        F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0x30; +        F32 div = 12.345f; +        LLColor4 llcolor4a(r,g,b,a),llcolor4b; +        llcolor4b = llcolor4a % div;//chnage only alpha value nor r,g,b; +        ensure("1operator%:Fail ",  (is_approx_equal(r,llcolor4b.mV[VX]) && is_approx_equal(g,llcolor4b.mV[VY]) && is_approx_equal(b,llcolor4b.mV[VZ])&& is_approx_equal(div*a,llcolor4b.mV[VW]))); + +        llcolor4b = div % llcolor4a; +        ensure("2operator%:Fail ",  (is_approx_equal(r,llcolor4b.mV[VX]) && is_approx_equal(g,llcolor4b.mV[VY]) && is_approx_equal(b,llcolor4b.mV[VZ])&& is_approx_equal(div*a,llcolor4b.mV[VW]))); + +        llcolor4a %= div; +        ensure("operator%=:Fail ",  (is_approx_equal(a*div,llcolor4a.mV[VW]))); +    } + +    template<> template<> +    void v4color_object::test<16>() +    { +        F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0x30; +        LLColor4 llcolor4a(r,g,b,a),llcolor4b; +        llcolor4b = llcolor4a; +        ensure("1:operator== failed to ensure the equality ", (llcolor4b == llcolor4a)); +        F32 r1 = 0x2, g1 = 0xFF, b1 = 0xFA; +        LLColor3 llcolor3(r1,g1,b1); +        llcolor4b = llcolor3; +        ensure("2:operator== failed to ensure the equality ", (llcolor4b == llcolor3)); +        ensure("2:operator!= failed to ensure the equality ", (llcolor4a != llcolor3)); +    } + +    template<> template<> +    void v4color_object::test<17>() +    { +        F32 r = 0x20, g = 0xFFFF, b = 0xFF; +        LLColor4 llcolor4a(r,g,b),llcolor4b; +        LLColor3 llcolor3 = vec4to3(llcolor4a); +        ensure("vec4to3:Fail to convert vec4 to vec3 ",  (is_approx_equal(llcolor3.mV[VX],llcolor4a.mV[VX]) && is_approx_equal(llcolor3.mV[VY],llcolor4a.mV[VY]) && is_approx_equal(llcolor3.mV[VZ],llcolor4a.mV[VZ]))); +        llcolor4b = vec3to4(llcolor3); +        ensure_equals("vec3to4:Fail to convert vec3 to vec4 ",  llcolor4b, llcolor4a); +    } + +    template<> template<> +    void v4color_object::test<18>() +    { +        F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF, val = 0x20; +        F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; +        LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; +        llcolor4c = lerp(llcolor4a,llcolor4b,val); +        ensure("lerp:Fail ",  (is_approx_equal(r1 + (r2 - r1)* val,llcolor4c.mV[VX]) && is_approx_equal(g1 + (g2 - g1)* val,llcolor4c.mV[VY]) && is_approx_equal(b1 + (b2 - b1)* val,llcolor4c.mV[VZ]))); +    } + +    template<> template<> +    void v4color_object::test<19>() +    { +        F32 r = 12.0f, g = -2.3f, b = 1.32f, a = 5.0f; +        LLColor4 llcolor4a(r,g,b,a),llcolor4b; +        std::string color("red"); +        LLColor4::parseColor(color, &llcolor4b); +        ensure_equals("1:parseColor() failed to parse the color value ", llcolor4b, LLColor4::red); + +        color = "12.0, -2.3, 1.32, 5.0"; +        LLColor4::parseColor(color, &llcolor4b); +        llcolor4a = llcolor4a * (1.f / 255.f); +        ensure_equals("2:parseColor() failed to parse the color value ",  llcolor4a,llcolor4b); + +        color = "yellow5"; +        llcolor4a.setVec(r,g,b); +        LLColor4::parseColor(color, &llcolor4a); +        ensure_equals("3:parseColor() failed to parse the color value ", llcolor4a, LLColor4::yellow5); +    } + +    template<> template<> +    void v4color_object::test<20>() +    { +        F32 r = 12.0f, g = -2.3f, b = 1.32f, a = 5.0f; +        LLColor4 llcolor4a(r,g,b,a),llcolor4b; +        std::string color("12.0, -2.3, 1.32, 5.0"); +        LLColor4::parseColor4(color, &llcolor4b); +        ensure_equals("parseColor4() failed to parse the color value ",  llcolor4a, llcolor4b); +    }  } diff --git a/indra/llmath/tests/v4coloru_test.cpp b/indra/llmath/tests/v4coloru_test.cpp index 12e607a820..2b6ee952a3 100644 --- a/indra/llmath/tests/v4coloru_test.cpp +++ b/indra/llmath/tests/v4coloru_test.cpp @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -37,300 +37,300 @@  namespace tut  { -	struct v4coloru_data -	{ -	}; -	typedef test_group<v4coloru_data> v4coloru_test; -	typedef v4coloru_test::object v4coloru_object; -	tut::v4coloru_test v4coloru_testcase("v4coloru_h"); - -	template<> template<> -	void v4coloru_object::test<1>() -	{ -		LLColor4U llcolor4u; -		ensure("1:LLColor4u:Fail to initialize ", ((0 == llcolor4u.mV[VX]) && (0 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); - -		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; -		LLColor4U llcolor4u1(r,g,b); -		ensure("2:LLColor4u:Fail to initialize ", ((r == llcolor4u1.mV[VX]) && (g == llcolor4u1.mV[VY]) && (b == llcolor4u1.mV[VZ])&& (255 == llcolor4u1.mV[VW]))); -		 -		LLColor4U llcolor4u2(r,g,b,a); -		ensure("3:LLColor4u:Fail to initialize ", ((r == llcolor4u2.mV[VX]) && (g == llcolor4u2.mV[VY]) && (b == llcolor4u2.mV[VZ])&& (a == llcolor4u2.mV[VW]))); - -		const U8 vec[4] = {0x12,0xFF,0xAF,0x23}; -		LLColor4U llcolor4u3(vec); -		ensure("4:LLColor4u:Fail to initialize ", ((vec[0] == llcolor4u3.mV[VX]) && (vec[1] == llcolor4u3.mV[VY]) && (vec[2] == llcolor4u3.mV[VZ])&& (vec[3] == llcolor4u3.mV[VW])));		 - -		LLSD sd = llcolor4u3.getValue(); -		LLColor4U llcolor4u4(sd); -		ensure_equals("5:LLColor4u (LLSD) Failed ", llcolor4u4, llcolor4u3); -	} -	 -	template<> template<> -	void v4coloru_object::test<2>() -	{ -		LLColor4U llcolor4ua(1, 2, 3, 4); -		LLSD sd = llcolor4ua.getValue(); -		LLColor4U llcolor4u; -		llcolor4u.setValue(sd); -		ensure_equals("setValue(LLSD)/getValue Failed ", llcolor4u, llcolor4ua); -	} - -	template<> template<> -	void v4coloru_object::test<3>() -	{ -		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; -		LLColor4U llcolor4u(r,g,b,a); -		llcolor4u.setToBlack(); -		ensure("setToBlack:Fail to set black ", ((0 == llcolor4u.mV[VX]) && (0 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); - -		llcolor4u.setToWhite(); -		ensure("setToWhite:Fail to white ", ((255 == llcolor4u.mV[VX]) && (255 == llcolor4u.mV[VY]) && (255 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); -	} -	 -	template<> template<> -	void v4coloru_object::test<4>() -	{ -		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; -		LLColor4U llcolor4ua(r,g,b,a); -		LLSD sd = llcolor4ua.getValue(); -		LLColor4U llcolor4u = (LLColor4U)sd; -		ensure_equals("Operator=(LLSD) Failed ",  llcolor4u, llcolor4ua); -	} - -	template<> template<> -	void v4coloru_object::test<5>() -	{ -		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; -		LLColor4U llcolor4u; -		llcolor4u.setVec(r,g,b,a); -		ensure("1:setVec:Fail to set the values ", ((r == llcolor4u.mV[VX]) && (g == llcolor4u.mV[VY]) && (b == llcolor4u.mV[VZ])&& (a == llcolor4u.mV[VW]))); - -		llcolor4u.setToBlack(); -		llcolor4u.setVec(r,g,b); -		ensure("2:setVec:Fail to set the values ", ((r == llcolor4u.mV[VX]) && (g == llcolor4u.mV[VY]) && (b == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); - -		LLColor4U llcolor4u1; -		llcolor4u1.setVec(llcolor4u); -		ensure_equals("3:setVec:Fail to set the values ", llcolor4u1,llcolor4u); -		 -		const U8 vec[4] = {0x12,0xFF,0xAF,0x23}; -		LLColor4U llcolor4u2; -		llcolor4u2.setVec(vec); -		ensure("4:setVec:Fail to set the values ", ((vec[0] == llcolor4u2.mV[VX]) && (vec[1] == llcolor4u2.mV[VY]) && (vec[2] == llcolor4u2.mV[VZ])&& (vec[3] == llcolor4u2.mV[VW])));		 -	} -	 -	template<> template<> -	void v4coloru_object::test<6>() -	{ -		U8 alpha = 0x12; -		LLColor4U llcolor4u; -		llcolor4u.setAlpha(alpha); -		ensure("setAlpha:Fail to set alpha value ", (alpha == llcolor4u.mV[VW])); -	} -	 -	template<> template<> -	void v4coloru_object::test<7>() -	{ -		U8 r = 0x12, g = 0xFF, b = 0xAF; -		LLColor4U llcolor4u(r,g,b); -		ensure("magVecSquared:Fail ", is_approx_equal(llcolor4u.magVecSquared(), (F32)(r*r + g*g + b*b))); -		ensure("magVec:Fail ", is_approx_equal(llcolor4u.magVec(), (F32) sqrt((F32) (r*r + g*g + b*b)))); -	} - -	template<> template<> -	void v4coloru_object::test<8>() -	{ -		U8 r = 0x12, g = 0xFF, b = 0xAF; -		std::ostringstream stream1, stream2; -		LLColor4U llcolor4u1(r,g,b),llcolor4u2; -		stream1 << llcolor4u1; -		llcolor4u2.setVec(r,g,b); -		stream2 << llcolor4u2; -		ensure("operator << failed ", (stream1.str() == stream2.str()));	 -	} - -	template<> template<> -	void v4coloru_object::test<9>() -	{ -		U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; -		U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; -		LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; -		llcolor4u3 = llcolor4u1 + llcolor4u2; -		ensure_equals( -			"1a.operator+:Fail to Add the values ", -			llcolor4u3.mV[VX], -			(U8)(r1+r2)); -		ensure_equals( -			"1b.operator+:Fail to Add the values ", -			llcolor4u3.mV[VY], -			(U8)(g1+g2)); -		ensure_equals( -			"1c.operator+:Fail to Add the values ", -			llcolor4u3.mV[VZ], -			(U8)(b1+b2)); - -		llcolor4u2 += llcolor4u1; -		ensure_equals( -			"2a.operator+=:Fail to Add the values ", -			llcolor4u2.mV[VX], -			(U8)(r1+r2)); -		ensure_equals( -			"2b.operator+=:Fail to Add the values ", -			llcolor4u2.mV[VY], -			(U8)(g1+g2)); -		ensure_equals( -			"2c.operator+=:Fail to Add the values ", -			llcolor4u2.mV[VZ], -			(U8)(b1+b2)); -	} - -	template<> template<> -	void v4coloru_object::test<10>() -	{ -		U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; -		U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; -		LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; -		llcolor4u3 = llcolor4u1 - llcolor4u2; -		ensure_equals( -			"1a. operator-:Fail to Add the values ", -			llcolor4u3.mV[VX], -			(U8)(r1-r2)); -		ensure_equals( -			"1b. operator-:Fail to Add the values ", -			llcolor4u3.mV[VY], -			(U8)(g1-g2)); -		ensure_equals( -			"1c. operator-:Fail to Add the values ", -			llcolor4u3.mV[VZ], -			(U8)(b1-b2)); - -		llcolor4u1 -= llcolor4u2; -		ensure_equals( -			"2a. operator-=:Fail to Add the values ", -			llcolor4u1.mV[VX], -			(U8)(r1-r2)); -		ensure_equals( -			"2b. operator-=:Fail to Add the values ", -			llcolor4u1.mV[VY], -			(U8)(g1-g2)); -		ensure_equals( -			"2c. operator-=:Fail to Add the values ", -			llcolor4u1.mV[VZ], -			(U8)(b1-b2)); -	} - -	template<> template<> -	void v4coloru_object::test<11>() -	{ -		U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; -		U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; -		LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; -		llcolor4u3 = llcolor4u1 * llcolor4u2; -		ensure_equals( -			"1a. operator*:Fail to multiply the values", -			llcolor4u3.mV[VX], -			(U8)(r1*r2)); -		ensure_equals( -			"1b. operator*:Fail to multiply the values", -			llcolor4u3.mV[VY], -			(U8)(g1*g2)); -		ensure_equals( -			"1c. operator*:Fail to multiply the values", -			llcolor4u3.mV[VZ], -			(U8)(b1*b2)); -		 -		U8 mulVal = 123; -		llcolor4u1 *= mulVal; -		ensure_equals( -			"2a. operator*=:Fail to multiply the values", -			llcolor4u1.mV[VX], -			(U8)(r1*mulVal)); -		ensure_equals( -			"2b. operator*=:Fail to multiply the values", -			llcolor4u1.mV[VY], -			(U8)(g1*mulVal)); -		ensure_equals( -			"2c. operator*=:Fail to multiply the values", -			llcolor4u1.mV[VZ], -			(U8)(b1*mulVal)); -	} - -	template<> template<> -	void v4coloru_object::test<12>() -	{ -		U8 r = 0x12, g = 0xFF, b = 0xAF; -		LLColor4U llcolor4u(r,g,b),llcolor4u1; -		llcolor4u1 = llcolor4u; -		ensure("operator== failed to ensure the equality ", (llcolor4u1 == llcolor4u));	 -		llcolor4u1.setToBlack(); -		ensure("operator!= failed to ensure the equality ", (llcolor4u1 != llcolor4u));	 -	} - -	template<> template<> -	void v4coloru_object::test<13>() -	{ -		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 12; -		LLColor4U llcolor4u(r,g,b,a); -		U8 modVal = 45; -		llcolor4u %= modVal; -		ensure_equals("operator%=:Fail ", llcolor4u.mV[VW], (U8)(a * modVal)); -	} - -	template<> template<> -	void v4coloru_object::test<14>() -	{ -		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 12; -		LLColor4U llcolor4u1(r,g,b,a); -		std::string color("12, 23, 132, 50"); -		LLColor4U::parseColor4U(color, &llcolor4u1); -		ensure("parseColor4U() failed to parse the color value ", ((12 == llcolor4u1.mV[VX]) && (23 == llcolor4u1.mV[VY]) && (132 == llcolor4u1.mV[VZ])&& (50 == llcolor4u1.mV[VW]))); - -		color = "12, 23, 132"; -		ensure("2:parseColor4U() failed to parse the color value ",  (FALSE == LLColor4U::parseColor4U(color, &llcolor4u1))); - -		color = "12"; -		ensure("2:parseColor4U() failed to parse the color value ",  (FALSE == LLColor4U::parseColor4U(color, &llcolor4u1))); -	} - -	template<> template<> -	void v4coloru_object::test<15>() -	{ -		U8 r = 12, g = 123, b = 3, a = 2; -		LLColor4U llcolor4u(r,g,b,a),llcolor4u1; -		const F32 fVal = 3.f; -		llcolor4u1 = llcolor4u.multAll(fVal); -		ensure("multAll:Fail to multiply ", (((U8)ll_round(r * fVal) == llcolor4u1.mV[VX]) && (U8)ll_round(g * fVal) == llcolor4u1.mV[VY] -											&& ((U8)ll_round(b * fVal) == llcolor4u1.mV[VZ])&& ((U8)ll_round(a * fVal) == llcolor4u1.mV[VW])));		 -	} - -	template<> template<> -	void v4coloru_object::test<16>() -	{ -		U8 r1 = 12, g1 = 123, b1 = 3, a1 = 2; -		U8 r2 = 23, g2 = 230, b2 = 124, a2 = 255; -		LLColor4U llcolor4u(r1,g1,b1,a1),llcolor4u1(r2,g2,b2,a2); -		llcolor4u1 = llcolor4u1.addClampMax(llcolor4u); -		ensure("1:addClampMax():Fail to add the value ",  ((r1+r2 == llcolor4u1.mV[VX]) && (255 == llcolor4u1.mV[VY]) && (b1+b2 == llcolor4u1.mV[VZ])&& (255 == llcolor4u1.mV[VW]))); - -		r1 = 132, g1 = 3, b1 = 3, a1 = 2; -		r2 = 123, g2 = 230, b2 = 154, a2 = 25; -		LLColor4U llcolor4u2(r1,g1,b1,a1),llcolor4u3(r2,g2,b2,a2); -		llcolor4u3 = llcolor4u3.addClampMax(llcolor4u2); -		ensure("2:addClampMax():Fail to add the value ",  ((255 == llcolor4u3.mV[VX]) && (g1+g2 == llcolor4u3.mV[VY]) && (b1+b2 == llcolor4u3.mV[VZ])&& (a1+a2 == llcolor4u3.mV[VW]))); -	} - -	template<> template<> -	void v4coloru_object::test<17>() -	{ -		F32 r = 23.f, g = 12.32f, b = -12.3f; -		LLColor3 color3(r,g,b); -		LLColor4U llcolor4u; -		llcolor4u.setVecScaleClamp(color3); -		const S32 MAX_COLOR = 255; -		F32 color_scale_factor = MAX_COLOR/r; -		S32 r2 = ll_round(r * color_scale_factor); -		S32 g2 = ll_round(g * color_scale_factor); -		ensure("setVecScaleClamp():Fail to add the value ",  ((r2 == llcolor4u.mV[VX]) && (g2 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); -	} +    struct v4coloru_data +    { +    }; +    typedef test_group<v4coloru_data> v4coloru_test; +    typedef v4coloru_test::object v4coloru_object; +    tut::v4coloru_test v4coloru_testcase("v4coloru_h"); + +    template<> template<> +    void v4coloru_object::test<1>() +    { +        LLColor4U llcolor4u; +        ensure("1:LLColor4u:Fail to initialize ", ((0 == llcolor4u.mV[VX]) && (0 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + +        U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; +        LLColor4U llcolor4u1(r,g,b); +        ensure("2:LLColor4u:Fail to initialize ", ((r == llcolor4u1.mV[VX]) && (g == llcolor4u1.mV[VY]) && (b == llcolor4u1.mV[VZ])&& (255 == llcolor4u1.mV[VW]))); + +        LLColor4U llcolor4u2(r,g,b,a); +        ensure("3:LLColor4u:Fail to initialize ", ((r == llcolor4u2.mV[VX]) && (g == llcolor4u2.mV[VY]) && (b == llcolor4u2.mV[VZ])&& (a == llcolor4u2.mV[VW]))); + +        const U8 vec[4] = {0x12,0xFF,0xAF,0x23}; +        LLColor4U llcolor4u3(vec); +        ensure("4:LLColor4u:Fail to initialize ", ((vec[0] == llcolor4u3.mV[VX]) && (vec[1] == llcolor4u3.mV[VY]) && (vec[2] == llcolor4u3.mV[VZ])&& (vec[3] == llcolor4u3.mV[VW]))); + +        LLSD sd = llcolor4u3.getValue(); +        LLColor4U llcolor4u4(sd); +        ensure_equals("5:LLColor4u (LLSD) Failed ", llcolor4u4, llcolor4u3); +    } + +    template<> template<> +    void v4coloru_object::test<2>() +    { +        LLColor4U llcolor4ua(1, 2, 3, 4); +        LLSD sd = llcolor4ua.getValue(); +        LLColor4U llcolor4u; +        llcolor4u.setValue(sd); +        ensure_equals("setValue(LLSD)/getValue Failed ", llcolor4u, llcolor4ua); +    } + +    template<> template<> +    void v4coloru_object::test<3>() +    { +        U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; +        LLColor4U llcolor4u(r,g,b,a); +        llcolor4u.setToBlack(); +        ensure("setToBlack:Fail to set black ", ((0 == llcolor4u.mV[VX]) && (0 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + +        llcolor4u.setToWhite(); +        ensure("setToWhite:Fail to white ", ((255 == llcolor4u.mV[VX]) && (255 == llcolor4u.mV[VY]) && (255 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); +    } + +    template<> template<> +    void v4coloru_object::test<4>() +    { +        U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; +        LLColor4U llcolor4ua(r,g,b,a); +        LLSD sd = llcolor4ua.getValue(); +        LLColor4U llcolor4u = (LLColor4U)sd; +        ensure_equals("Operator=(LLSD) Failed ",  llcolor4u, llcolor4ua); +    } + +    template<> template<> +    void v4coloru_object::test<5>() +    { +        U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; +        LLColor4U llcolor4u; +        llcolor4u.setVec(r,g,b,a); +        ensure("1:setVec:Fail to set the values ", ((r == llcolor4u.mV[VX]) && (g == llcolor4u.mV[VY]) && (b == llcolor4u.mV[VZ])&& (a == llcolor4u.mV[VW]))); + +        llcolor4u.setToBlack(); +        llcolor4u.setVec(r,g,b); +        ensure("2:setVec:Fail to set the values ", ((r == llcolor4u.mV[VX]) && (g == llcolor4u.mV[VY]) && (b == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + +        LLColor4U llcolor4u1; +        llcolor4u1.setVec(llcolor4u); +        ensure_equals("3:setVec:Fail to set the values ", llcolor4u1,llcolor4u); + +        const U8 vec[4] = {0x12,0xFF,0xAF,0x23}; +        LLColor4U llcolor4u2; +        llcolor4u2.setVec(vec); +        ensure("4:setVec:Fail to set the values ", ((vec[0] == llcolor4u2.mV[VX]) && (vec[1] == llcolor4u2.mV[VY]) && (vec[2] == llcolor4u2.mV[VZ])&& (vec[3] == llcolor4u2.mV[VW]))); +    } + +    template<> template<> +    void v4coloru_object::test<6>() +    { +        U8 alpha = 0x12; +        LLColor4U llcolor4u; +        llcolor4u.setAlpha(alpha); +        ensure("setAlpha:Fail to set alpha value ", (alpha == llcolor4u.mV[VW])); +    } + +    template<> template<> +    void v4coloru_object::test<7>() +    { +        U8 r = 0x12, g = 0xFF, b = 0xAF; +        LLColor4U llcolor4u(r,g,b); +        ensure("magVecSquared:Fail ", is_approx_equal(llcolor4u.magVecSquared(), (F32)(r*r + g*g + b*b))); +        ensure("magVec:Fail ", is_approx_equal(llcolor4u.magVec(), (F32) sqrt((F32) (r*r + g*g + b*b)))); +    } + +    template<> template<> +    void v4coloru_object::test<8>() +    { +        U8 r = 0x12, g = 0xFF, b = 0xAF; +        std::ostringstream stream1, stream2; +        LLColor4U llcolor4u1(r,g,b),llcolor4u2; +        stream1 << llcolor4u1; +        llcolor4u2.setVec(r,g,b); +        stream2 << llcolor4u2; +        ensure("operator << failed ", (stream1.str() == stream2.str())); +    } + +    template<> template<> +    void v4coloru_object::test<9>() +    { +        U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; +        U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; +        LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; +        llcolor4u3 = llcolor4u1 + llcolor4u2; +        ensure_equals( +            "1a.operator+:Fail to Add the values ", +            llcolor4u3.mV[VX], +            (U8)(r1+r2)); +        ensure_equals( +            "1b.operator+:Fail to Add the values ", +            llcolor4u3.mV[VY], +            (U8)(g1+g2)); +        ensure_equals( +            "1c.operator+:Fail to Add the values ", +            llcolor4u3.mV[VZ], +            (U8)(b1+b2)); + +        llcolor4u2 += llcolor4u1; +        ensure_equals( +            "2a.operator+=:Fail to Add the values ", +            llcolor4u2.mV[VX], +            (U8)(r1+r2)); +        ensure_equals( +            "2b.operator+=:Fail to Add the values ", +            llcolor4u2.mV[VY], +            (U8)(g1+g2)); +        ensure_equals( +            "2c.operator+=:Fail to Add the values ", +            llcolor4u2.mV[VZ], +            (U8)(b1+b2)); +    } + +    template<> template<> +    void v4coloru_object::test<10>() +    { +        U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; +        U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; +        LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; +        llcolor4u3 = llcolor4u1 - llcolor4u2; +        ensure_equals( +            "1a. operator-:Fail to Add the values ", +            llcolor4u3.mV[VX], +            (U8)(r1-r2)); +        ensure_equals( +            "1b. operator-:Fail to Add the values ", +            llcolor4u3.mV[VY], +            (U8)(g1-g2)); +        ensure_equals( +            "1c. operator-:Fail to Add the values ", +            llcolor4u3.mV[VZ], +            (U8)(b1-b2)); + +        llcolor4u1 -= llcolor4u2; +        ensure_equals( +            "2a. operator-=:Fail to Add the values ", +            llcolor4u1.mV[VX], +            (U8)(r1-r2)); +        ensure_equals( +            "2b. operator-=:Fail to Add the values ", +            llcolor4u1.mV[VY], +            (U8)(g1-g2)); +        ensure_equals( +            "2c. operator-=:Fail to Add the values ", +            llcolor4u1.mV[VZ], +            (U8)(b1-b2)); +    } + +    template<> template<> +    void v4coloru_object::test<11>() +    { +        U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; +        U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; +        LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; +        llcolor4u3 = llcolor4u1 * llcolor4u2; +        ensure_equals( +            "1a. operator*:Fail to multiply the values", +            llcolor4u3.mV[VX], +            (U8)(r1*r2)); +        ensure_equals( +            "1b. operator*:Fail to multiply the values", +            llcolor4u3.mV[VY], +            (U8)(g1*g2)); +        ensure_equals( +            "1c. operator*:Fail to multiply the values", +            llcolor4u3.mV[VZ], +            (U8)(b1*b2)); + +        U8 mulVal = 123; +        llcolor4u1 *= mulVal; +        ensure_equals( +            "2a. operator*=:Fail to multiply the values", +            llcolor4u1.mV[VX], +            (U8)(r1*mulVal)); +        ensure_equals( +            "2b. operator*=:Fail to multiply the values", +            llcolor4u1.mV[VY], +            (U8)(g1*mulVal)); +        ensure_equals( +            "2c. operator*=:Fail to multiply the values", +            llcolor4u1.mV[VZ], +            (U8)(b1*mulVal)); +    } + +    template<> template<> +    void v4coloru_object::test<12>() +    { +        U8 r = 0x12, g = 0xFF, b = 0xAF; +        LLColor4U llcolor4u(r,g,b),llcolor4u1; +        llcolor4u1 = llcolor4u; +        ensure("operator== failed to ensure the equality ", (llcolor4u1 == llcolor4u)); +        llcolor4u1.setToBlack(); +        ensure("operator!= failed to ensure the equality ", (llcolor4u1 != llcolor4u)); +    } + +    template<> template<> +    void v4coloru_object::test<13>() +    { +        U8 r = 0x12, g = 0xFF, b = 0xAF, a = 12; +        LLColor4U llcolor4u(r,g,b,a); +        U8 modVal = 45; +        llcolor4u %= modVal; +        ensure_equals("operator%=:Fail ", llcolor4u.mV[VW], (U8)(a * modVal)); +    } + +    template<> template<> +    void v4coloru_object::test<14>() +    { +        U8 r = 0x12, g = 0xFF, b = 0xAF, a = 12; +        LLColor4U llcolor4u1(r,g,b,a); +        std::string color("12, 23, 132, 50"); +        LLColor4U::parseColor4U(color, &llcolor4u1); +        ensure("parseColor4U() failed to parse the color value ", ((12 == llcolor4u1.mV[VX]) && (23 == llcolor4u1.mV[VY]) && (132 == llcolor4u1.mV[VZ])&& (50 == llcolor4u1.mV[VW]))); + +        color = "12, 23, 132"; +        ensure("2:parseColor4U() failed to parse the color value ",  (FALSE == LLColor4U::parseColor4U(color, &llcolor4u1))); + +        color = "12"; +        ensure("2:parseColor4U() failed to parse the color value ",  (FALSE == LLColor4U::parseColor4U(color, &llcolor4u1))); +    } + +    template<> template<> +    void v4coloru_object::test<15>() +    { +        U8 r = 12, g = 123, b = 3, a = 2; +        LLColor4U llcolor4u(r,g,b,a),llcolor4u1; +        const F32 fVal = 3.f; +        llcolor4u1 = llcolor4u.multAll(fVal); +        ensure("multAll:Fail to multiply ", (((U8)ll_round(r * fVal) == llcolor4u1.mV[VX]) && (U8)ll_round(g * fVal) == llcolor4u1.mV[VY] +                                            && ((U8)ll_round(b * fVal) == llcolor4u1.mV[VZ])&& ((U8)ll_round(a * fVal) == llcolor4u1.mV[VW]))); +    } + +    template<> template<> +    void v4coloru_object::test<16>() +    { +        U8 r1 = 12, g1 = 123, b1 = 3, a1 = 2; +        U8 r2 = 23, g2 = 230, b2 = 124, a2 = 255; +        LLColor4U llcolor4u(r1,g1,b1,a1),llcolor4u1(r2,g2,b2,a2); +        llcolor4u1 = llcolor4u1.addClampMax(llcolor4u); +        ensure("1:addClampMax():Fail to add the value ",  ((r1+r2 == llcolor4u1.mV[VX]) && (255 == llcolor4u1.mV[VY]) && (b1+b2 == llcolor4u1.mV[VZ])&& (255 == llcolor4u1.mV[VW]))); + +        r1 = 132, g1 = 3, b1 = 3, a1 = 2; +        r2 = 123, g2 = 230, b2 = 154, a2 = 25; +        LLColor4U llcolor4u2(r1,g1,b1,a1),llcolor4u3(r2,g2,b2,a2); +        llcolor4u3 = llcolor4u3.addClampMax(llcolor4u2); +        ensure("2:addClampMax():Fail to add the value ",  ((255 == llcolor4u3.mV[VX]) && (g1+g2 == llcolor4u3.mV[VY]) && (b1+b2 == llcolor4u3.mV[VZ])&& (a1+a2 == llcolor4u3.mV[VW]))); +    } + +    template<> template<> +    void v4coloru_object::test<17>() +    { +        F32 r = 23.f, g = 12.32f, b = -12.3f; +        LLColor3 color3(r,g,b); +        LLColor4U llcolor4u; +        llcolor4u.setVecScaleClamp(color3); +        const S32 MAX_COLOR = 255; +        F32 color_scale_factor = MAX_COLOR/r; +        S32 r2 = ll_round(r * color_scale_factor); +        S32 g2 = ll_round(g * color_scale_factor); +        ensure("setVecScaleClamp():Fail to add the value ",  ((r2 == llcolor4u.mV[VX]) && (g2 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); +    }  } diff --git a/indra/llmath/tests/v4math_test.cpp b/indra/llmath/tests/v4math_test.cpp index 9779dfded3..07099cd417 100644 --- a/indra/llmath/tests/v4math_test.cpp +++ b/indra/llmath/tests/v4math_test.cpp @@ -7,25 +7,25 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -  +  #include "linden_common.h"  #include "../test/lltut.h"  #include "llsd.h" @@ -36,348 +36,348 @@  namespace tut  { -	struct v4math_data -	{ -	}; -	typedef test_group<v4math_data> v4math_test; -	typedef v4math_test::object v4math_object; -	tut::v4math_test v4math_testcase("v4math_h"); +    struct v4math_data +    { +    }; +    typedef test_group<v4math_data> v4math_test; +    typedef v4math_test::object v4math_object; +    tut::v4math_test v4math_testcase("v4math_h"); -	template<> template<> -	void v4math_object::test<1>() -	{ -		LLVector4 vec4; -		ensure("1:LLVector4:Fail to initialize " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); -		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; -		LLVector4 vec4a(x,y,z); -		ensure("2:LLVector4:Fail to initialize " ,((x == vec4a.mV[VX]) && (y == vec4a.mV[VY]) && (z == vec4a.mV[VZ])&& (1.0f == vec4a.mV[VW]))); -		LLVector4 vec4b(x,y,z,w); -		ensure("3:LLVector4:Fail to initialize " ,((x == vec4b.mV[VX]) && (y == vec4b.mV[VY]) && (z == vec4b.mV[VZ])&& (w == vec4b.mV[VW]))); -		const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; -		LLVector4 vec4c(vec); -		ensure("4:LLVector4:Fail to initialize " ,((vec[0] == vec4c.mV[VX]) && (vec[1] == vec4c.mV[VY]) && (vec[2] == vec4c.mV[VZ])&& (vec[3] == vec4c.mV[VW]))); -		LLVector3 vec3(-2.23f,1.01f,42.3f); -		LLVector4 vec4d(vec3); -		ensure("5:LLVector4:Fail to initialize " ,((vec3.mV[VX] == vec4d.mV[VX]) && (vec3.mV[VY] == vec4d.mV[VY]) && (vec3.mV[VZ] == vec4d.mV[VZ])&& (1.f == vec4d.mV[VW]))); -		F32 w1 = -.234f; -		LLVector4 vec4e(vec3,w1); -		ensure("6:LLVector4:Fail to initialize " ,((vec3.mV[VX] == vec4e.mV[VX]) && (vec3.mV[VY] == vec4e.mV[VY]) && (vec3.mV[VZ] == vec4e.mV[VZ])&& (w1 == vec4e.mV[VW]))); -	} +    template<> template<> +    void v4math_object::test<1>() +    { +        LLVector4 vec4; +        ensure("1:LLVector4:Fail to initialize " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); +        F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +        LLVector4 vec4a(x,y,z); +        ensure("2:LLVector4:Fail to initialize " ,((x == vec4a.mV[VX]) && (y == vec4a.mV[VY]) && (z == vec4a.mV[VZ])&& (1.0f == vec4a.mV[VW]))); +        LLVector4 vec4b(x,y,z,w); +        ensure("3:LLVector4:Fail to initialize " ,((x == vec4b.mV[VX]) && (y == vec4b.mV[VY]) && (z == vec4b.mV[VZ])&& (w == vec4b.mV[VW]))); +        const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; +        LLVector4 vec4c(vec); +        ensure("4:LLVector4:Fail to initialize " ,((vec[0] == vec4c.mV[VX]) && (vec[1] == vec4c.mV[VY]) && (vec[2] == vec4c.mV[VZ])&& (vec[3] == vec4c.mV[VW]))); +        LLVector3 vec3(-2.23f,1.01f,42.3f); +        LLVector4 vec4d(vec3); +        ensure("5:LLVector4:Fail to initialize " ,((vec3.mV[VX] == vec4d.mV[VX]) && (vec3.mV[VY] == vec4d.mV[VY]) && (vec3.mV[VZ] == vec4d.mV[VZ])&& (1.f == vec4d.mV[VW]))); +        F32 w1 = -.234f; +        LLVector4 vec4e(vec3,w1); +        ensure("6:LLVector4:Fail to initialize " ,((vec3.mV[VX] == vec4e.mV[VX]) && (vec3.mV[VY] == vec4e.mV[VY]) && (vec3.mV[VZ] == vec4e.mV[VZ])&& (w1 == vec4e.mV[VW]))); +    } -	template<> template<> -	void v4math_object::test<2>() -	{ -		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; -		LLVector4 vec4; -		vec4.setVec(x,y,z); -		ensure("1:setVec:Fail to initialize " ,((x == vec4.mV[VX]) && (y == vec4.mV[VY]) && (z == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); -		vec4.clearVec(); -		ensure("2:clearVec:Fail " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); -		vec4.setVec(x,y,z,w); -		ensure("3:setVec:Fail to initialize " ,((x == vec4.mV[VX]) && (y == vec4.mV[VY]) && (z == vec4.mV[VZ])&& (w == vec4.mV[VW]))); -		vec4.zeroVec(); -		ensure("4:zeroVec:Fail " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (0 == vec4.mV[VW]))); -		LLVector3 vec3(-2.23f,1.01f,42.3f); -		vec4.clearVec(); -		vec4.setVec(vec3); -		ensure("5:setVec:Fail to initialize " ,((vec3.mV[VX] == vec4.mV[VX]) && (vec3.mV[VY] == vec4.mV[VY]) && (vec3.mV[VZ] == vec4.mV[VZ])&& (1.f == vec4.mV[VW]))); -		F32 w1 = -.234f; -		vec4.zeroVec(); -		vec4.setVec(vec3,w1); -		ensure("6:setVec:Fail to initialize " ,((vec3.mV[VX] == vec4.mV[VX]) && (vec3.mV[VY] == vec4.mV[VY]) && (vec3.mV[VZ] == vec4.mV[VZ])&& (w1 == vec4.mV[VW]))); -		const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; -		LLVector4 vec4a; -		vec4a.setVec(vec); -		ensure("7:setVec:Fail to initialize " ,((vec[0] == vec4a.mV[VX]) && (vec[1] == vec4a.mV[VY]) && (vec[2] == vec4a.mV[VZ])&& (vec[3] == vec4a.mV[VW]))); -	} +    template<> template<> +    void v4math_object::test<2>() +    { +        F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +        LLVector4 vec4; +        vec4.setVec(x,y,z); +        ensure("1:setVec:Fail to initialize " ,((x == vec4.mV[VX]) && (y == vec4.mV[VY]) && (z == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); +        vec4.clearVec(); +        ensure("2:clearVec:Fail " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); +        vec4.setVec(x,y,z,w); +        ensure("3:setVec:Fail to initialize " ,((x == vec4.mV[VX]) && (y == vec4.mV[VY]) && (z == vec4.mV[VZ])&& (w == vec4.mV[VW]))); +        vec4.zeroVec(); +        ensure("4:zeroVec:Fail " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (0 == vec4.mV[VW]))); +        LLVector3 vec3(-2.23f,1.01f,42.3f); +        vec4.clearVec(); +        vec4.setVec(vec3); +        ensure("5:setVec:Fail to initialize " ,((vec3.mV[VX] == vec4.mV[VX]) && (vec3.mV[VY] == vec4.mV[VY]) && (vec3.mV[VZ] == vec4.mV[VZ])&& (1.f == vec4.mV[VW]))); +        F32 w1 = -.234f; +        vec4.zeroVec(); +        vec4.setVec(vec3,w1); +        ensure("6:setVec:Fail to initialize " ,((vec3.mV[VX] == vec4.mV[VX]) && (vec3.mV[VY] == vec4.mV[VY]) && (vec3.mV[VZ] == vec4.mV[VZ])&& (w1 == vec4.mV[VW]))); +        const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; +        LLVector4 vec4a; +        vec4a.setVec(vec); +        ensure("7:setVec:Fail to initialize " ,((vec[0] == vec4a.mV[VX]) && (vec[1] == vec4a.mV[VY]) && (vec[2] == vec4a.mV[VZ])&& (vec[3] == vec4a.mV[VW]))); +    } -	template<> template<> -	void v4math_object::test<3>() -	{ -		F32 x = 10.f, y = -2.3f, z = -.023f; -		LLVector4 vec4(x,y,z); -		ensure("magVec:Fail ", is_approx_equal(vec4.magVec(), (F32) sqrt(x*x + y*y + z*z))); -		ensure("magVecSquared:Fail ", is_approx_equal(vec4.magVecSquared(), (x*x + y*y + z*z))); -	} +    template<> template<> +    void v4math_object::test<3>() +    { +        F32 x = 10.f, y = -2.3f, z = -.023f; +        LLVector4 vec4(x,y,z); +        ensure("magVec:Fail ", is_approx_equal(vec4.magVec(), (F32) sqrt(x*x + y*y + z*z))); +        ensure("magVecSquared:Fail ", is_approx_equal(vec4.magVecSquared(), (x*x + y*y + z*z))); +    } -	template<> template<> -	void v4math_object::test<4>() -	{ -		F32 x = 10.f, y = -2.3f, z = -.023f; -		LLVector4 vec4(x,y,z); -		F32 mag = vec4.normVec(); -		mag = 1.f/ mag; -		ensure("1:normVec: Fail " ,is_approx_equal(mag*x,vec4.mV[VX]) && is_approx_equal(mag*y, vec4.mV[VY])&& is_approx_equal(mag*z, vec4.mV[VZ])); -		x = 0.000000001f, y = 0.000000001f, z = 0.000000001f; -		vec4.clearVec(); -		vec4.setVec(x,y,z); -		mag = vec4.normVec(); -		ensure("2:normVec: Fail " ,is_approx_equal(mag*x,vec4.mV[VX]) && is_approx_equal(mag*y, vec4.mV[VY])&& is_approx_equal(mag*z, vec4.mV[VZ])); -	} +    template<> template<> +    void v4math_object::test<4>() +    { +        F32 x = 10.f, y = -2.3f, z = -.023f; +        LLVector4 vec4(x,y,z); +        F32 mag = vec4.normVec(); +        mag = 1.f/ mag; +        ensure("1:normVec: Fail " ,is_approx_equal(mag*x,vec4.mV[VX]) && is_approx_equal(mag*y, vec4.mV[VY])&& is_approx_equal(mag*z, vec4.mV[VZ])); +        x = 0.000000001f, y = 0.000000001f, z = 0.000000001f; +        vec4.clearVec(); +        vec4.setVec(x,y,z); +        mag = vec4.normVec(); +        ensure("2:normVec: Fail " ,is_approx_equal(mag*x,vec4.mV[VX]) && is_approx_equal(mag*y, vec4.mV[VY])&& is_approx_equal(mag*z, vec4.mV[VZ])); +    } -	template<> template<> -	void v4math_object::test<5>() -	{ -		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; -		LLVector4 vec4(x,y,z,w); -		vec4.abs(); -		ensure("abs:Fail " ,((x == vec4.mV[VX]) && (-y == vec4.mV[VY]) && (-z == vec4.mV[VZ])&& (-w == vec4.mV[VW]))); -		vec4.clearVec(); -		ensure("isExactlyClear:Fail " ,(TRUE == vec4.isExactlyClear())); -		vec4.zeroVec(); -		ensure("isExactlyZero:Fail " ,(TRUE == vec4.isExactlyZero())); -	} +    template<> template<> +    void v4math_object::test<5>() +    { +        F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +        LLVector4 vec4(x,y,z,w); +        vec4.abs(); +        ensure("abs:Fail " ,((x == vec4.mV[VX]) && (-y == vec4.mV[VY]) && (-z == vec4.mV[VZ])&& (-w == vec4.mV[VW]))); +        vec4.clearVec(); +        ensure("isExactlyClear:Fail " ,(TRUE == vec4.isExactlyClear())); +        vec4.zeroVec(); +        ensure("isExactlyZero:Fail " ,(TRUE == vec4.isExactlyZero())); +    } -	template<> template<> -	void v4math_object::test<6>() -	{ -		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; -		LLVector4 vec4(x,y,z,w),vec4a; -		vec4a = vec4.scaleVec(vec4); -		ensure("scaleVec:Fail " ,(is_approx_equal(x*x, vec4a.mV[VX]) && is_approx_equal(y*y, vec4a.mV[VY]) && is_approx_equal(z*z, vec4a.mV[VZ])&& is_approx_equal(w*w, vec4a.mV[VW]))); -	} +    template<> template<> +    void v4math_object::test<6>() +    { +        F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +        LLVector4 vec4(x,y,z,w),vec4a; +        vec4a = vec4.scaleVec(vec4); +        ensure("scaleVec:Fail " ,(is_approx_equal(x*x, vec4a.mV[VX]) && is_approx_equal(y*y, vec4a.mV[VY]) && is_approx_equal(z*z, vec4a.mV[VZ])&& is_approx_equal(w*w, vec4a.mV[VW]))); +    } -	template<> template<> -	void v4math_object::test<7>() -	{ -		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; -		LLVector4 vec4(x,y,z,w); -		ensure("1:operator [] failed " ,( x ==  vec4[0]));	 -		ensure("2:operator [] failed " ,( y ==  vec4[1])); -		ensure("3:operator [] failed " ,( z ==  vec4[2])); -		ensure("4:operator [] failed " ,( w ==  vec4[3])); -		x = 23.f, y = -.2361f, z = 3.25; -		vec4.setVec(x,y,z); -		F32 &ref1 = vec4[0]; -		ensure("5:operator [] failed " ,( ref1 ==  vec4[0])); -		F32 &ref2 = vec4[1]; -		ensure("6:operator [] failed " ,( ref2 ==  vec4[1])); -		F32 &ref3 = vec4[2]; -		ensure("7:operator [] failed " ,( ref3 ==  vec4[2]));	 -		F32 &ref4 = vec4[3]; -		ensure("8:operator [] failed " ,( ref4 ==  vec4[3])); -	} +    template<> template<> +    void v4math_object::test<7>() +    { +        F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +        LLVector4 vec4(x,y,z,w); +        ensure("1:operator [] failed " ,( x ==  vec4[0])); +        ensure("2:operator [] failed " ,( y ==  vec4[1])); +        ensure("3:operator [] failed " ,( z ==  vec4[2])); +        ensure("4:operator [] failed " ,( w ==  vec4[3])); +        x = 23.f, y = -.2361f, z = 3.25; +        vec4.setVec(x,y,z); +        F32 &ref1 = vec4[0]; +        ensure("5:operator [] failed " ,( ref1 ==  vec4[0])); +        F32 &ref2 = vec4[1]; +        ensure("6:operator [] failed " ,( ref2 ==  vec4[1])); +        F32 &ref3 = vec4[2]; +        ensure("7:operator [] failed " ,( ref3 ==  vec4[2])); +        F32 &ref4 = vec4[3]; +        ensure("8:operator [] failed " ,( ref4 ==  vec4[3])); +    } -	template<> template<> -	void v4math_object::test<8>() -	{ -		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; -		const  F32 val[16] = { +    template<> template<> +    void v4math_object::test<8>() +    { +        F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +        const  F32 val[16] = {              1.f,  2.f,   3.f,    0.f,              .34f, .1f,   -.5f,   0.f,              2.f,  1.23f, 1.234f, 0.f,              .89f, 0.f,   0.f,    0.f          }; -		LLMatrix4 mat(val); -		LLVector4 vec4(x,y,z,w),vec4a; -		vec4.rotVec(mat); -		vec4a.setVec(x,y,z,w); -		vec4a.rotVec(mat); -		ensure_equals("1:rotVec: Fail " ,vec4a, vec4); -		F32 a = 2.32f, b = -23.2f, c = -34.1112f, d = 1.010112f; -		LLQuaternion q(a,b,c,d); -		LLVector4 vec4b(a,b,c,d),vec4c; -		vec4b.rotVec(q); -		vec4c.setVec(a, b, c, d); -		vec4c.rotVec(q); -		ensure_equals("2:rotVec: Fail " ,vec4b, vec4c); -	} -	 -	template<> template<> -	void v4math_object::test<9>() -	{ -		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; -		LLVector4 vec4(x,y,z,w),vec4a;; -		std::ostringstream stream1, stream2; -		stream1 << vec4; -		vec4a.setVec(x,y,z,w); -		stream2 << vec4a; -		ensure("operator << failed",(stream1.str() == stream2.str()));	 -	} -	 -	template<> template<> -	void v4math_object::test<10>() -	{ -		F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f, w1 = .23f; -		F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f, w2 = 1.3f; -		LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2),vec4b; -		vec4b = vec4a + vec4; -		ensure("1:operator+:Fail to initialize " ,(is_approx_equal(x1+x2,vec4b.mV[VX]) && is_approx_equal(y1+y2,vec4b.mV[VY]) && is_approx_equal(z1+z2,vec4b.mV[VZ]))); -		x1 = -2.45f, y1 = 2.1f, z1 = 3.0f; -		vec4.clearVec(); -		vec4a.clearVec(); -		vec4.setVec(x1,y1,z1); -		vec4a +=vec4; -		ensure_equals("2:operator+=: Fail to initialize", vec4a,vec4); -		vec4a += vec4; -		ensure("3:operator+=:Fail to initialize " ,(is_approx_equal(2*x1,vec4a.mV[VX]) && is_approx_equal(2*y1,vec4a.mV[VY]) && is_approx_equal(2*z1,vec4a.mV[VZ]))); -	} -	template<> template<> -	void v4math_object::test<11>() -	{ -		F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f, w1 = .23f; -		F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f, w2 = 1.3f; -		LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2),vec4b; -		vec4b = vec4a - vec4; -		ensure("1:operator-:Fail to initialize " ,(is_approx_equal(x2-x1,vec4b.mV[VX]) && is_approx_equal(y2-y1,vec4b.mV[VY]) && is_approx_equal(z2-z1,vec4b.mV[VZ]))); -		x1 = -2.45f, y1 = 2.1f, z1 = 3.0f; -		vec4.clearVec(); -		vec4a.clearVec(); -		vec4.setVec(x1,y1,z1); -		vec4a -=vec4; -		ensure_equals("2:operator-=: Fail to initialize" , vec4a,-vec4); -		vec4a -=vec4; -		ensure("3:operator-=:Fail to initialize " ,(is_approx_equal(-2*x1,vec4a.mV[VX]) && is_approx_equal(-2*y1,vec4a.mV[VY]) && is_approx_equal(-2*z1,vec4a.mV[VZ]))); -	} +        LLMatrix4 mat(val); +        LLVector4 vec4(x,y,z,w),vec4a; +        vec4.rotVec(mat); +        vec4a.setVec(x,y,z,w); +        vec4a.rotVec(mat); +        ensure_equals("1:rotVec: Fail " ,vec4a, vec4); +        F32 a = 2.32f, b = -23.2f, c = -34.1112f, d = 1.010112f; +        LLQuaternion q(a,b,c,d); +        LLVector4 vec4b(a,b,c,d),vec4c; +        vec4b.rotVec(q); +        vec4c.setVec(a, b, c, d); +        vec4c.rotVec(q); +        ensure_equals("2:rotVec: Fail " ,vec4b, vec4c); +    } + +    template<> template<> +    void v4math_object::test<9>() +    { +        F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +        LLVector4 vec4(x,y,z,w),vec4a;; +        std::ostringstream stream1, stream2; +        stream1 << vec4; +        vec4a.setVec(x,y,z,w); +        stream2 << vec4a; +        ensure("operator << failed",(stream1.str() == stream2.str())); +    } + +    template<> template<> +    void v4math_object::test<10>() +    { +        F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f, w1 = .23f; +        F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f, w2 = 1.3f; +        LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2),vec4b; +        vec4b = vec4a + vec4; +        ensure("1:operator+:Fail to initialize " ,(is_approx_equal(x1+x2,vec4b.mV[VX]) && is_approx_equal(y1+y2,vec4b.mV[VY]) && is_approx_equal(z1+z2,vec4b.mV[VZ]))); +        x1 = -2.45f, y1 = 2.1f, z1 = 3.0f; +        vec4.clearVec(); +        vec4a.clearVec(); +        vec4.setVec(x1,y1,z1); +        vec4a +=vec4; +        ensure_equals("2:operator+=: Fail to initialize", vec4a,vec4); +        vec4a += vec4; +        ensure("3:operator+=:Fail to initialize " ,(is_approx_equal(2*x1,vec4a.mV[VX]) && is_approx_equal(2*y1,vec4a.mV[VY]) && is_approx_equal(2*z1,vec4a.mV[VZ]))); +    } +    template<> template<> +    void v4math_object::test<11>() +    { +        F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f, w1 = .23f; +        F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f, w2 = 1.3f; +        LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2),vec4b; +        vec4b = vec4a - vec4; +        ensure("1:operator-:Fail to initialize " ,(is_approx_equal(x2-x1,vec4b.mV[VX]) && is_approx_equal(y2-y1,vec4b.mV[VY]) && is_approx_equal(z2-z1,vec4b.mV[VZ]))); +        x1 = -2.45f, y1 = 2.1f, z1 = 3.0f; +        vec4.clearVec(); +        vec4a.clearVec(); +        vec4.setVec(x1,y1,z1); +        vec4a -=vec4; +        ensure_equals("2:operator-=: Fail to initialize" , vec4a,-vec4); +        vec4a -=vec4; +        ensure("3:operator-=:Fail to initialize " ,(is_approx_equal(-2*x1,vec4a.mV[VX]) && is_approx_equal(-2*y1,vec4a.mV[VY]) && is_approx_equal(-2*z1,vec4a.mV[VZ]))); +    } -	template<> template<> -	void v4math_object::test<12>() -	{ -		F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f; -		F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f; -		LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2); -		F32 res = vec4 * vec4a; -		ensure("1:operator* failed " ,is_approx_equal(res, x1*x2 + y1*y2 + z1*z2)); -		vec4a.clearVec(); -		F32 mulVal = 4.2f; -		vec4a = vec4 * mulVal; -		ensure("2:operator* failed " ,is_approx_equal(x1*mulVal,vec4a.mV[VX]) && is_approx_equal(y1*mulVal, vec4a.mV[VY])&& is_approx_equal(z1*mulVal, vec4a.mV[VZ])); -		vec4a.clearVec(); -		vec4a = mulVal *  vec4 ; -		ensure("3:operator* failed " ,is_approx_equal(x1*mulVal, vec4a.mV[VX]) && is_approx_equal(y1*mulVal, vec4a.mV[VY])&& is_approx_equal(z1*mulVal, vec4a.mV[VZ])); -		vec4 *= mulVal; -		ensure("4:operator*= failed " ,is_approx_equal(x1*mulVal, vec4.mV[VX]) && is_approx_equal(y1*mulVal, vec4.mV[VY])&& is_approx_equal(z1*mulVal, vec4.mV[VZ])); -	} +    template<> template<> +    void v4math_object::test<12>() +    { +        F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f; +        F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f; +        LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2); +        F32 res = vec4 * vec4a; +        ensure("1:operator* failed " ,is_approx_equal(res, x1*x2 + y1*y2 + z1*z2)); +        vec4a.clearVec(); +        F32 mulVal = 4.2f; +        vec4a = vec4 * mulVal; +        ensure("2:operator* failed " ,is_approx_equal(x1*mulVal,vec4a.mV[VX]) && is_approx_equal(y1*mulVal, vec4a.mV[VY])&& is_approx_equal(z1*mulVal, vec4a.mV[VZ])); +        vec4a.clearVec(); +        vec4a = mulVal *  vec4 ; +        ensure("3:operator* failed " ,is_approx_equal(x1*mulVal, vec4a.mV[VX]) && is_approx_equal(y1*mulVal, vec4a.mV[VY])&& is_approx_equal(z1*mulVal, vec4a.mV[VZ])); +        vec4 *= mulVal; +        ensure("4:operator*= failed " ,is_approx_equal(x1*mulVal, vec4.mV[VX]) && is_approx_equal(y1*mulVal, vec4.mV[VY])&& is_approx_equal(z1*mulVal, vec4.mV[VZ])); +    } -	template<> template<> -	void v4math_object::test<13>() -	{ -		F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f; -		F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f; -		LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2),vec4b; -		vec4b = vec4 % vec4a; -		ensure("1:operator% failed " ,is_approx_equal(y1*z2 - y2*z1, vec4b.mV[VX]) && is_approx_equal(z1*x2 -z2*x1, vec4b.mV[VY]) && is_approx_equal(x1*y2-x2*y1, vec4b.mV[VZ]));  -		vec4 %= vec4a; -		ensure_equals("operator%= failed " ,vec4,vec4b);  -	} +    template<> template<> +    void v4math_object::test<13>() +    { +        F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f; +        F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f; +        LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2),vec4b; +        vec4b = vec4 % vec4a; +        ensure("1:operator% failed " ,is_approx_equal(y1*z2 - y2*z1, vec4b.mV[VX]) && is_approx_equal(z1*x2 -z2*x1, vec4b.mV[VY]) && is_approx_equal(x1*y2-x2*y1, vec4b.mV[VZ])); +        vec4 %= vec4a; +        ensure_equals("operator%= failed " ,vec4,vec4b); +    } -	template<> template<> -	void v4math_object::test<14>() -	{ -		F32 x = 1.f, y = 2.f, z = -1.1f,div = 4.2f; -		F32 t = 1.f / div; -		LLVector4 vec4(x,y,z), vec4a; -		vec4a = vec4/div; -		ensure("1:operator/ failed " ,is_approx_equal(x*t, vec4a.mV[VX]) && is_approx_equal(y*t, vec4a.mV[VY])&& is_approx_equal(z*t, vec4a.mV[VZ])); -		x = 1.23f, y = 4.f, z = -2.32f; -		vec4.clearVec(); -		vec4a.clearVec(); -		vec4.setVec(x,y,z); -		vec4a = vec4/div; -		ensure("2:operator/ failed " ,is_approx_equal(x*t, vec4a.mV[VX]) && is_approx_equal(y*t, vec4a.mV[VY])&& is_approx_equal(z*t, vec4a.mV[VZ])); -		vec4 /= div; -		ensure("3:operator/ failed " ,is_approx_equal(x*t, vec4.mV[VX]) && is_approx_equal(y*t, vec4.mV[VY])&& is_approx_equal(z*t, vec4.mV[VZ])); -	} +    template<> template<> +    void v4math_object::test<14>() +    { +        F32 x = 1.f, y = 2.f, z = -1.1f,div = 4.2f; +        F32 t = 1.f / div; +        LLVector4 vec4(x,y,z), vec4a; +        vec4a = vec4/div; +        ensure("1:operator/ failed " ,is_approx_equal(x*t, vec4a.mV[VX]) && is_approx_equal(y*t, vec4a.mV[VY])&& is_approx_equal(z*t, vec4a.mV[VZ])); +        x = 1.23f, y = 4.f, z = -2.32f; +        vec4.clearVec(); +        vec4a.clearVec(); +        vec4.setVec(x,y,z); +        vec4a = vec4/div; +        ensure("2:operator/ failed " ,is_approx_equal(x*t, vec4a.mV[VX]) && is_approx_equal(y*t, vec4a.mV[VY])&& is_approx_equal(z*t, vec4a.mV[VZ])); +        vec4 /= div; +        ensure("3:operator/ failed " ,is_approx_equal(x*t, vec4.mV[VX]) && is_approx_equal(y*t, vec4.mV[VY])&& is_approx_equal(z*t, vec4.mV[VZ])); +    } -	template<> template<> -	void v4math_object::test<15>() -	{ -		F32 x = 1.f, y = 2.f, z = -1.1f; -		LLVector4 vec4(x,y,z), vec4a; -		ensure("operator!= failed " ,(vec4 != vec4a)); -		vec4a = vec4; -		ensure("operator== failed " ,(vec4 ==vec4a));  -	} +    template<> template<> +    void v4math_object::test<15>() +    { +        F32 x = 1.f, y = 2.f, z = -1.1f; +        LLVector4 vec4(x,y,z), vec4a; +        ensure("operator!= failed " ,(vec4 != vec4a)); +        vec4a = vec4; +        ensure("operator== failed " ,(vec4 ==vec4a)); +    } -	template<> template<> -	void v4math_object::test<16>() -	{ -		F32 x = 1.f, y = 2.f, z = -1.1f; -		LLVector4 vec4(x,y,z), vec4a; -		vec4a = - vec4; -		ensure("operator- failed " , (vec4 == - vec4a));	 -	} +    template<> template<> +    void v4math_object::test<16>() +    { +        F32 x = 1.f, y = 2.f, z = -1.1f; +        LLVector4 vec4(x,y,z), vec4a; +        vec4a = - vec4; +        ensure("operator- failed " , (vec4 == - vec4a)); +    } -	template<> template<> -	void v4math_object::test<17>() -	{ -		F32 x = 1.f, y = 2.f, z = -1.1f,epsilon = .23425f; -		LLVector4 vec4(x,y,z), vec4a(x,y,z); -		ensure("1:are_parallel: Fail " ,(TRUE == are_parallel(vec4a,vec4,epsilon))); -		x = 21.f, y = 12.f, z = -123.1f; -		vec4a.clearVec(); -		vec4a.setVec(x,y,z); -		ensure("2:are_parallel: Fail " ,(FALSE == are_parallel(vec4a,vec4,epsilon))); -	} +    template<> template<> +    void v4math_object::test<17>() +    { +        F32 x = 1.f, y = 2.f, z = -1.1f,epsilon = .23425f; +        LLVector4 vec4(x,y,z), vec4a(x,y,z); +        ensure("1:are_parallel: Fail " ,(TRUE == are_parallel(vec4a,vec4,epsilon))); +        x = 21.f, y = 12.f, z = -123.1f; +        vec4a.clearVec(); +        vec4a.setVec(x,y,z); +        ensure("2:are_parallel: Fail " ,(FALSE == are_parallel(vec4a,vec4,epsilon))); +    } -	template<> template<> -	void v4math_object::test<18>() -	{ -		F32 x = 1.f, y = 2.f, z = -1.1f; -		F32 angle1, angle2; -		LLVector4 vec4(x,y,z), vec4a(x,y,z); -		angle1 = angle_between(vec4, vec4a); -		vec4.normVec(); -		vec4a.normVec(); -		angle2 = acos(vec4 * vec4a); -		ensure_approximately_equals("1:angle_between: Fail " ,angle1,angle2,8); -		F32 x1 = 21.f, y1 = 2.23f, z1 = -1.1f; -		LLVector4 vec4b(x,y,z), vec4c(x1,y1,z1); -		angle1 = angle_between(vec4b, vec4c); -		vec4b.normVec(); -		vec4c.normVec(); -		angle2 = acos(vec4b * vec4c); -		ensure_approximately_equals("2:angle_between: Fail " ,angle1,angle2,8); -	} +    template<> template<> +    void v4math_object::test<18>() +    { +        F32 x = 1.f, y = 2.f, z = -1.1f; +        F32 angle1, angle2; +        LLVector4 vec4(x,y,z), vec4a(x,y,z); +        angle1 = angle_between(vec4, vec4a); +        vec4.normVec(); +        vec4a.normVec(); +        angle2 = acos(vec4 * vec4a); +        ensure_approximately_equals("1:angle_between: Fail " ,angle1,angle2,8); +        F32 x1 = 21.f, y1 = 2.23f, z1 = -1.1f; +        LLVector4 vec4b(x,y,z), vec4c(x1,y1,z1); +        angle1 = angle_between(vec4b, vec4c); +        vec4b.normVec(); +        vec4c.normVec(); +        angle2 = acos(vec4b * vec4c); +        ensure_approximately_equals("2:angle_between: Fail " ,angle1,angle2,8); +    } -	template<> template<> -	void v4math_object::test<19>() -	{ -		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f; -		F32 val1,val2; -		LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2); -		val1 = dist_vec(vec4,vec4a); -		val2 = (F32) sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); -		ensure_equals("dist_vec: Fail ",val2, val1); -		val1 = dist_vec_squared(vec4,vec4a); -		val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); -		ensure_equals("dist_vec_squared: Fail ",val2, val1); -	} +    template<> template<> +    void v4math_object::test<19>() +    { +        F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f; +        F32 val1,val2; +        LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2); +        val1 = dist_vec(vec4,vec4a); +        val2 = (F32) sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); +        ensure_equals("dist_vec: Fail ",val2, val1); +        val1 = dist_vec_squared(vec4,vec4a); +        val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); +        ensure_equals("dist_vec_squared: Fail ",val2, val1); +    } -	template<> template<> -	void v4math_object::test<20>() -	{ -		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, w1 = -.23f, x2 = 1.3f, y2 = 1.f, z2 = 1.f,w2 = .12f; -		F32 val = 2.3f,val1,val2,val3,val4; -		LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2); -		val1 = x1 + (x2 - x1)* val; -		val2 = y1 + (y2 - y1)* val; -		val3 = z1 + (z2 - z1)* val; -		val4 = w1 + (w2 - w1)* val; -		LLVector4 vec4b = lerp(vec4,vec4a,val); -		LLVector4 check(val1, val2, val3, val4); -		ensure_equals("lerp failed", check, vec4b); -	} +    template<> template<> +    void v4math_object::test<20>() +    { +        F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, w1 = -.23f, x2 = 1.3f, y2 = 1.f, z2 = 1.f,w2 = .12f; +        F32 val = 2.3f,val1,val2,val3,val4; +        LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2); +        val1 = x1 + (x2 - x1)* val; +        val2 = y1 + (y2 - y1)* val; +        val3 = z1 + (z2 - z1)* val; +        val4 = w1 + (w2 - w1)* val; +        LLVector4 vec4b = lerp(vec4,vec4a,val); +        LLVector4 check(val1, val2, val3, val4); +        ensure_equals("lerp failed", check, vec4b); +    } -	template<> template<> -	void v4math_object::test<21>() -	{ -		F32 x = 1.f, y = 2.f, z = -1.1f; -		LLVector4 vec4(x,y,z); -		LLVector3 vec3 = vec4to3(vec4); -		ensure("vec4to3 failed", ((x == vec3.mV[VX])&& (y == vec3.mV[VY]) && (z == vec3.mV[VZ])));	 -		LLVector4 vec4a = vec3to4(vec3); -		ensure_equals("vec3to4 failed",vec4a,vec4);	 -	} +    template<> template<> +    void v4math_object::test<21>() +    { +        F32 x = 1.f, y = 2.f, z = -1.1f; +        LLVector4 vec4(x,y,z); +        LLVector3 vec3 = vec4to3(vec4); +        ensure("vec4to3 failed", ((x == vec3.mV[VX])&& (y == vec3.mV[VY]) && (z == vec3.mV[VZ]))); +        LLVector4 vec4a = vec3to4(vec3); +        ensure_equals("vec3to4 failed",vec4a,vec4); +    } -	template<> template<> -	void v4math_object::test<22>() -	{ -		F32 x = 1.f, y = 2.f, z = -1.1f; -		LLVector4 vec4(x,y,z); -		LLSD llsd = vec4.getValue(); -		LLVector3 vec3(llsd); -		LLVector4 vec4a = vec3to4(vec3); -		ensure_equals("getValue failed",vec4a,vec4);	 -	}		 +    template<> template<> +    void v4math_object::test<22>() +    { +        F32 x = 1.f, y = 2.f, z = -1.1f; +        LLVector4 vec4(x,y,z); +        LLSD llsd = vec4.getValue(); +        LLVector3 vec3(llsd); +        LLVector4 vec4a = vec3to4(vec3); +        ensure_equals("getValue failed",vec4a,vec4); +    }  } diff --git a/indra/llmath/tests/xform_test.cpp b/indra/llmath/tests/xform_test.cpp index 49870eef3c..ad56cdb15c 100644 --- a/indra/llmath/tests/xform_test.cpp +++ b/indra/llmath/tests/xform_test.cpp @@ -1,27 +1,27 @@ -/**  +/**   * @file xform_test.cpp   * @author Adroit - * @date March 2007  + * @date March 2007   * @brief Test cases for LLXform   *   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -33,213 +33,213 @@  namespace tut  { -	struct xform_test -	{ -	}; -	typedef test_group<xform_test> xform_test_t; -	typedef xform_test_t::object xform_test_object_t; -	tut::xform_test_t tut_xform_test("LLXForm"); - -	//test case for init(), getParent(), getRotation(), getPositionW(), getWorldRotation() fns. -	template<> template<> -	void xform_test_object_t::test<1>() -	{ -		LLXform xform_obj; -		LLVector3 emptyVec(0.f,0.f,0.f); -		LLVector3 initialScaleVec(1.f,1.f,1.f); - -		ensure("LLXform empty constructor failed: ", !xform_obj.getParent() && !xform_obj.isChanged() && -			xform_obj.getPosition() == emptyVec &&  -			(xform_obj.getRotation()).isIdentity() && -			xform_obj.getScale() == initialScaleVec &&  -			xform_obj.getPositionW() == emptyVec &&  -			(xform_obj.getWorldRotation()).isIdentity() && -			!xform_obj.getScaleChildOffset()); -	} - -	// test cases for  -	// setScale(const LLVector3& scale)  -	// setScale(const F32 x, const F32 y, const F32 z) -	// setRotation(const F32 x, const F32 y, const F32 z)  -	// setPosition(const F32 x, const F32 y, const F32 z)  -	// getLocalMat4(LLMatrix4 &mat) -	template<> template<> -	void xform_test_object_t::test<2>()	 -	{ -		LLMatrix4 llmat4; -		LLXform xform_obj; - -		F32 x = 3.6f; -		F32 y = 5.5f; -		F32 z = 4.2f; -		F32 w = 0.f; -		F32 posz = z + 2.122f; -		LLVector3 vec(x, y, z); -		xform_obj.setScale(x, y, z); -		xform_obj.setPosition(x, y, posz); -		ensure("setScale failed: ", xform_obj.getScale() == vec); - -		vec.setVec(x, y, posz); -		ensure("getPosition failed: ", xform_obj.getPosition() == vec); - -		x = x * 2.f; -		y = y + 2.3f; -		z = posz * 4.f;  -		vec.setVec(x, y, z); -		xform_obj.setPositionX(x); -		xform_obj.setPositionY(y); -		xform_obj.setPositionZ(z); -		ensure("setPositionX/Y/Z failed: ", xform_obj.getPosition() == vec); - -		xform_obj.setScaleChildOffset(TRUE); -		ensure("setScaleChildOffset failed: ", xform_obj.getScaleChildOffset()); - -		vec.setVec(x, y, z); - -		xform_obj.addPosition(vec); -		vec += vec; -		ensure("addPosition failed: ", xform_obj.getPosition() == vec); - -		xform_obj.setScale(vec); -		ensure("setScale vector failed: ", xform_obj.getScale() == vec); - -		LLQuaternion quat(x, y, z, w); -		xform_obj.setRotation(quat); -		ensure("setRotation quat failed: ", xform_obj.getRotation() == quat); - -		xform_obj.setRotation(x, y, z, w); -		ensure("getRotation 2 failed: ", xform_obj.getRotation() == quat); - -		xform_obj.setRotation(x, y, z); -		quat.setQuat(x,y,z);  -		ensure("setRotation xyz failed: ", xform_obj.getRotation() == quat); - -		// LLXform::setRotation(const F32 x, const F32 y, const F32 z)  -		//		Does normalization -		// LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s)  -		//		Simply copies the individual values - does not do any normalization.  -		// Is that the expected behavior? -	} - -	// test cases for inline BOOL setParent(LLXform *parent) and getParent() fn. -	template<> template<> -	void xform_test_object_t::test<3>()	 -	{		 -		LLXform xform_obj; -		LLXform par; -		LLXform grandpar; -		xform_obj.setParent(&par);  -		par.setParent(&grandpar);  -		ensure("setParent/getParent failed: ", &par == xform_obj.getParent()); -		ensure("getRoot failed: ", &grandpar == xform_obj.getRoot()); -		ensure("isRoot failed: ", grandpar.isRoot() && !par.isRoot() && !xform_obj.isRoot()); -		ensure("isRootEdit failed: ", grandpar.isRootEdit() && !par.isRootEdit() && !xform_obj.isRootEdit()); -	} - -	template<> template<> -	void xform_test_object_t::test<4>()	 -	{ -		LLXform xform_obj; -		xform_obj.setChanged(LLXform::TRANSLATED | LLXform::ROTATED | LLXform::SCALED); -		ensure("setChanged/isChanged failed: ", xform_obj.isChanged()); - -		xform_obj.clearChanged(LLXform::TRANSLATED | LLXform::ROTATED | LLXform::SCALED); -		ensure("clearChanged failed: ", !xform_obj.isChanged()); -		 -		LLVector3 llvect3(12.4f, -5.6f, 0.34f); -		xform_obj.setScale(llvect3); -		ensure("setScale did not set SCALED flag: ", xform_obj.isChanged(LLXform::SCALED)); -		xform_obj.setPosition(1.2f, 2.3f, 3.4f); -		ensure("setScale did not set TRANSLATED flag: ", xform_obj.isChanged(LLXform::TRANSLATED)); -		ensure("TRANSLATED reset SCALED flag: ", xform_obj.isChanged(LLXform::TRANSLATED | LLXform::SCALED)); -		xform_obj.clearChanged(LLXform::SCALED); -		ensure("reset SCALED failed: ", !xform_obj.isChanged(LLXform::SCALED)); -		xform_obj.setRotation(1, 2, 3, 4); -		ensure("ROTATION flag not set ", xform_obj.isChanged(LLXform::TRANSLATED | LLXform::ROTATED)); -		xform_obj.setScale(llvect3); -		ensure("ROTATION flag not set ", xform_obj.isChanged(LLXform::MOVED)); -	} - -	//to test init() and getWorldMatrix() fns. -	template<> template<> -	void xform_test_object_t::test<5>()	 -	{ -		LLXformMatrix formMatrix_obj; -		formMatrix_obj.init(); -		LLMatrix4 mat4_obj; -		 -		ensure("1. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[0][0]); -		ensure("2. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][1]); -		ensure("3. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][2]); -		ensure("4. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][3]); -		ensure("5. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][0]); -		ensure("6. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[1][1]); -		ensure("7. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][2]); -		ensure("8. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][3]); -		ensure("9. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][0]); -		ensure("10. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][1]); -		ensure("11. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[2][2]); -		ensure("12. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][3]); -		ensure("13. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][0]); -		ensure("14. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][1]); -		ensure("15. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][2]); -		ensure("16. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[3][3]); -	} - -	//to test mMin.clearVec() and mMax.clearVec() fns -	template<> template<> -	void xform_test_object_t::test<6>()	 -	{ -		LLXformMatrix formMatrix_obj; -		formMatrix_obj.init(); -		LLVector3 llmin_vec3; -		LLVector3 llmax_vec3; -		formMatrix_obj.getMinMax(llmin_vec3, llmax_vec3); -		ensure("1. The value is not NULL", 0.f == llmin_vec3.mV[0]); -		ensure("2. The value is not NULL", 0.f == llmin_vec3.mV[1]); -		ensure("3. The value is not NULL", 0.f == llmin_vec3.mV[2]); -		ensure("4. The value is not NULL", 0.f == llmin_vec3.mV[0]); -		ensure("5. The value is not NULL", 0.f == llmin_vec3.mV[1]); -		ensure("6. The value is not NULL", 0.f == llmin_vec3.mV[2]); -	} - -	//test case of update() fn. -	template<> template<> -	void xform_test_object_t::test<7>()	 -	{ -		LLXformMatrix formMatrix_obj; - -		LLXformMatrix parent; -		LLVector3 llvecpos(1.0, 2.0, 3.0); -		LLVector3 llvecpospar(10.0, 20.0, 30.0); -		formMatrix_obj.setPosition(llvecpos); -		parent.setPosition(llvecpospar); - -		LLVector3 llvecparentscale(1.0, 2.0, 0); -		parent.setScaleChildOffset(TRUE); -		parent.setScale(llvecparentscale); - -		LLQuaternion quat(1, 2, 3, 4); -		LLQuaternion quatparent(5, 6, 7, 8); -		formMatrix_obj.setRotation(quat); -		parent.setRotation(quatparent); -		formMatrix_obj.setParent(&parent); - -		parent.update(); -		formMatrix_obj.update(); - -		LLVector3 worldPos = llvecpos; -		worldPos.scaleVec(llvecparentscale); -		worldPos *= quatparent; -		worldPos += llvecpospar; - -		LLQuaternion worldRot = quat * quatparent;  - -		ensure("getWorldPosition failed: ", formMatrix_obj.getWorldPosition() == worldPos); -		ensure("getWorldRotation failed: ", formMatrix_obj.getWorldRotation() == worldRot); - -		ensure("getWorldPosition for parent failed: ", parent.getWorldPosition() == llvecpospar); -		ensure("getWorldRotation for parent failed: ", parent.getWorldRotation() == quatparent); -	} -}	 +    struct xform_test +    { +    }; +    typedef test_group<xform_test> xform_test_t; +    typedef xform_test_t::object xform_test_object_t; +    tut::xform_test_t tut_xform_test("LLXForm"); + +    //test case for init(), getParent(), getRotation(), getPositionW(), getWorldRotation() fns. +    template<> template<> +    void xform_test_object_t::test<1>() +    { +        LLXform xform_obj; +        LLVector3 emptyVec(0.f,0.f,0.f); +        LLVector3 initialScaleVec(1.f,1.f,1.f); + +        ensure("LLXform empty constructor failed: ", !xform_obj.getParent() && !xform_obj.isChanged() && +            xform_obj.getPosition() == emptyVec && +            (xform_obj.getRotation()).isIdentity() && +            xform_obj.getScale() == initialScaleVec && +            xform_obj.getPositionW() == emptyVec && +            (xform_obj.getWorldRotation()).isIdentity() && +            !xform_obj.getScaleChildOffset()); +    } + +    // test cases for +    // setScale(const LLVector3& scale) +    // setScale(const F32 x, const F32 y, const F32 z) +    // setRotation(const F32 x, const F32 y, const F32 z) +    // setPosition(const F32 x, const F32 y, const F32 z) +    // getLocalMat4(LLMatrix4 &mat) +    template<> template<> +    void xform_test_object_t::test<2>() +    { +        LLMatrix4 llmat4; +        LLXform xform_obj; + +        F32 x = 3.6f; +        F32 y = 5.5f; +        F32 z = 4.2f; +        F32 w = 0.f; +        F32 posz = z + 2.122f; +        LLVector3 vec(x, y, z); +        xform_obj.setScale(x, y, z); +        xform_obj.setPosition(x, y, posz); +        ensure("setScale failed: ", xform_obj.getScale() == vec); + +        vec.setVec(x, y, posz); +        ensure("getPosition failed: ", xform_obj.getPosition() == vec); + +        x = x * 2.f; +        y = y + 2.3f; +        z = posz * 4.f; +        vec.setVec(x, y, z); +        xform_obj.setPositionX(x); +        xform_obj.setPositionY(y); +        xform_obj.setPositionZ(z); +        ensure("setPositionX/Y/Z failed: ", xform_obj.getPosition() == vec); + +        xform_obj.setScaleChildOffset(TRUE); +        ensure("setScaleChildOffset failed: ", xform_obj.getScaleChildOffset()); + +        vec.setVec(x, y, z); + +        xform_obj.addPosition(vec); +        vec += vec; +        ensure("addPosition failed: ", xform_obj.getPosition() == vec); + +        xform_obj.setScale(vec); +        ensure("setScale vector failed: ", xform_obj.getScale() == vec); + +        LLQuaternion quat(x, y, z, w); +        xform_obj.setRotation(quat); +        ensure("setRotation quat failed: ", xform_obj.getRotation() == quat); + +        xform_obj.setRotation(x, y, z, w); +        ensure("getRotation 2 failed: ", xform_obj.getRotation() == quat); + +        xform_obj.setRotation(x, y, z); +        quat.setQuat(x,y,z); +        ensure("setRotation xyz failed: ", xform_obj.getRotation() == quat); + +        // LLXform::setRotation(const F32 x, const F32 y, const F32 z) +        //      Does normalization +        // LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s) +        //      Simply copies the individual values - does not do any normalization. +        // Is that the expected behavior? +    } + +    // test cases for inline BOOL setParent(LLXform *parent) and getParent() fn. +    template<> template<> +    void xform_test_object_t::test<3>() +    { +        LLXform xform_obj; +        LLXform par; +        LLXform grandpar; +        xform_obj.setParent(&par); +        par.setParent(&grandpar); +        ensure("setParent/getParent failed: ", &par == xform_obj.getParent()); +        ensure("getRoot failed: ", &grandpar == xform_obj.getRoot()); +        ensure("isRoot failed: ", grandpar.isRoot() && !par.isRoot() && !xform_obj.isRoot()); +        ensure("isRootEdit failed: ", grandpar.isRootEdit() && !par.isRootEdit() && !xform_obj.isRootEdit()); +    } + +    template<> template<> +    void xform_test_object_t::test<4>() +    { +        LLXform xform_obj; +        xform_obj.setChanged(LLXform::TRANSLATED | LLXform::ROTATED | LLXform::SCALED); +        ensure("setChanged/isChanged failed: ", xform_obj.isChanged()); + +        xform_obj.clearChanged(LLXform::TRANSLATED | LLXform::ROTATED | LLXform::SCALED); +        ensure("clearChanged failed: ", !xform_obj.isChanged()); + +        LLVector3 llvect3(12.4f, -5.6f, 0.34f); +        xform_obj.setScale(llvect3); +        ensure("setScale did not set SCALED flag: ", xform_obj.isChanged(LLXform::SCALED)); +        xform_obj.setPosition(1.2f, 2.3f, 3.4f); +        ensure("setScale did not set TRANSLATED flag: ", xform_obj.isChanged(LLXform::TRANSLATED)); +        ensure("TRANSLATED reset SCALED flag: ", xform_obj.isChanged(LLXform::TRANSLATED | LLXform::SCALED)); +        xform_obj.clearChanged(LLXform::SCALED); +        ensure("reset SCALED failed: ", !xform_obj.isChanged(LLXform::SCALED)); +        xform_obj.setRotation(1, 2, 3, 4); +        ensure("ROTATION flag not set ", xform_obj.isChanged(LLXform::TRANSLATED | LLXform::ROTATED)); +        xform_obj.setScale(llvect3); +        ensure("ROTATION flag not set ", xform_obj.isChanged(LLXform::MOVED)); +    } + +    //to test init() and getWorldMatrix() fns. +    template<> template<> +    void xform_test_object_t::test<5>() +    { +        LLXformMatrix formMatrix_obj; +        formMatrix_obj.init(); +        LLMatrix4 mat4_obj; + +        ensure("1. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[0][0]); +        ensure("2. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][1]); +        ensure("3. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][2]); +        ensure("4. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][3]); +        ensure("5. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][0]); +        ensure("6. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[1][1]); +        ensure("7. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][2]); +        ensure("8. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][3]); +        ensure("9. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][0]); +        ensure("10. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][1]); +        ensure("11. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[2][2]); +        ensure("12. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][3]); +        ensure("13. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][0]); +        ensure("14. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][1]); +        ensure("15. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][2]); +        ensure("16. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[3][3]); +    } + +    //to test mMin.clearVec() and mMax.clearVec() fns +    template<> template<> +    void xform_test_object_t::test<6>() +    { +        LLXformMatrix formMatrix_obj; +        formMatrix_obj.init(); +        LLVector3 llmin_vec3; +        LLVector3 llmax_vec3; +        formMatrix_obj.getMinMax(llmin_vec3, llmax_vec3); +        ensure("1. The value is not NULL", 0.f == llmin_vec3.mV[0]); +        ensure("2. The value is not NULL", 0.f == llmin_vec3.mV[1]); +        ensure("3. The value is not NULL", 0.f == llmin_vec3.mV[2]); +        ensure("4. The value is not NULL", 0.f == llmin_vec3.mV[0]); +        ensure("5. The value is not NULL", 0.f == llmin_vec3.mV[1]); +        ensure("6. The value is not NULL", 0.f == llmin_vec3.mV[2]); +    } + +    //test case of update() fn. +    template<> template<> +    void xform_test_object_t::test<7>() +    { +        LLXformMatrix formMatrix_obj; + +        LLXformMatrix parent; +        LLVector3 llvecpos(1.0, 2.0, 3.0); +        LLVector3 llvecpospar(10.0, 20.0, 30.0); +        formMatrix_obj.setPosition(llvecpos); +        parent.setPosition(llvecpospar); + +        LLVector3 llvecparentscale(1.0, 2.0, 0); +        parent.setScaleChildOffset(TRUE); +        parent.setScale(llvecparentscale); + +        LLQuaternion quat(1, 2, 3, 4); +        LLQuaternion quatparent(5, 6, 7, 8); +        formMatrix_obj.setRotation(quat); +        parent.setRotation(quatparent); +        formMatrix_obj.setParent(&parent); + +        parent.update(); +        formMatrix_obj.update(); + +        LLVector3 worldPos = llvecpos; +        worldPos.scaleVec(llvecparentscale); +        worldPos *= quatparent; +        worldPos += llvecpospar; + +        LLQuaternion worldRot = quat * quatparent; + +        ensure("getWorldPosition failed: ", formMatrix_obj.getWorldPosition() == worldPos); +        ensure("getWorldRotation failed: ", formMatrix_obj.getWorldRotation() == worldRot); + +        ensure("getWorldPosition for parent failed: ", parent.getWorldPosition() == llvecpospar); +        ensure("getWorldRotation for parent failed: ", parent.getWorldRotation() == quatparent); +    } +} diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp index a24571f2c8..ecbfe7378c 100644 --- a/indra/llmath/v2math.cpp +++ b/indra/llmath/v2math.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file v2math.cpp   * @brief LLVector2 class implementation.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -45,82 +45,82 @@ LLVector2 LLVector2::zero(0,0);  // Returns TRUE if data changed  BOOL LLVector2::abs()  { -	BOOL ret = FALSE; +    BOOL ret = FALSE; + +    if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = TRUE; } +    if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = TRUE; } -	if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = TRUE; } -	if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = TRUE; } -	 -	return ret; +    return ret;  }  F32 angle_between(const LLVector2& a, const LLVector2& b)  { -	LLVector2 an = a; -	LLVector2 bn = b; -	an.normVec(); -	bn.normVec(); -	F32 cosine = an * bn; -	F32 angle = (cosine >= 1.0f) ? 0.0f : -				(cosine <= -1.0f) ? F_PI : -				acos(cosine); -	return angle; +    LLVector2 an = a; +    LLVector2 bn = b; +    an.normVec(); +    bn.normVec(); +    F32 cosine = an * bn; +    F32 angle = (cosine >= 1.0f) ? 0.0f : +                (cosine <= -1.0f) ? F_PI : +                acos(cosine); +    return angle;  }  BOOL are_parallel(const LLVector2 &a, const LLVector2 &b, float epsilon)  { -	LLVector2 an = a; -	LLVector2 bn = b; -	an.normVec(); -	bn.normVec(); -	F32 dot = an * bn; -	if ( (1.0f - fabs(dot)) < epsilon) -	{ -		return TRUE; -	} -	return FALSE; +    LLVector2 an = a; +    LLVector2 bn = b; +    an.normVec(); +    bn.normVec(); +    F32 dot = an * bn; +    if ( (1.0f - fabs(dot)) < epsilon) +    { +        return TRUE; +    } +    return FALSE;  } -F32	dist_vec(const LLVector2 &a, const LLVector2 &b) +F32 dist_vec(const LLVector2 &a, const LLVector2 &b)  { -	F32 x = a.mV[0] - b.mV[0]; -	F32 y = a.mV[1] - b.mV[1]; -	return (F32) sqrt( x*x + y*y ); +    F32 x = a.mV[0] - b.mV[0]; +    F32 y = a.mV[1] - b.mV[1]; +    return (F32) sqrt( x*x + y*y );  } -F32	dist_vec_squared(const LLVector2 &a, const LLVector2 &b) +F32 dist_vec_squared(const LLVector2 &a, const LLVector2 &b)  { -	F32 x = a.mV[0] - b.mV[0]; -	F32 y = a.mV[1] - b.mV[1]; -	return x*x + y*y; +    F32 x = a.mV[0] - b.mV[0]; +    F32 y = a.mV[1] - b.mV[1]; +    return x*x + y*y;  } -F32	dist_vec_squared2D(const LLVector2 &a, const LLVector2 &b) +F32 dist_vec_squared2D(const LLVector2 &a, const LLVector2 &b)  { -	F32 x = a.mV[0] - b.mV[0]; -	F32 y = a.mV[1] - b.mV[1]; -	return x*x + y*y; +    F32 x = a.mV[0] - b.mV[0]; +    F32 y = a.mV[1] - b.mV[1]; +    return x*x + y*y;  }  LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u)  { -	return LLVector2( -		a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, -		a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u ); +    return LLVector2( +        a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, +        a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u );  }  LLSD LLVector2::getValue() const  { -	LLSD ret; -	ret[0] = mV[0]; -	ret[1] = mV[1]; -	return ret; +    LLSD ret; +    ret[0] = mV[0]; +    ret[1] = mV[1]; +    return ret;  }  void LLVector2::setValue(const LLSD& sd)  { -	mV[0] = (F32) sd[0].asReal(); -	mV[1] = (F32) sd[1].asReal(); +    mV[0] = (F32) sd[0].asReal(); +    mV[1] = (F32) sd[1].asReal();  } diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h index 2335a2e327..5c756a7f84 100644 --- a/indra/llmath/v2math.h +++ b/indra/llmath/v2math.h @@ -1,25 +1,25 @@ -/**  +/**   * @file v2math.h   * @brief LLVector2 class header file.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -40,110 +40,110 @@ static const U32 LENGTHOFVECTOR2 = 2;  class LLVector2  { -	public: -		F32 mV[LENGTHOFVECTOR2]; +    public: +        F32 mV[LENGTHOFVECTOR2]; -		static LLVector2 zero; +        static LLVector2 zero; -		LLVector2();							  // Initializes LLVector2 to (0, 0) -		LLVector2(F32 x, F32 y);			      // Initializes LLVector2 to (x. y) -		LLVector2(const F32 *vec);				  // Initializes LLVector2 to (vec[0]. vec[1]) +        LLVector2();                              // Initializes LLVector2 to (0, 0) +        LLVector2(F32 x, F32 y);                  // Initializes LLVector2 to (x. y) +        LLVector2(const F32 *vec);                // Initializes LLVector2 to (vec[0]. vec[1])          explicit LLVector2(const LLVector3 &vec); // Initializes LLVector2 to (vec[0]. vec[1])          explicit LLVector2(const LLSD &sd); -		 -		// Clears LLVector2 to (0, 0).  DEPRECATED - prefer zeroVec. -		void	clear(); -		void	setZero(); -		void	clearVec();	// deprecated -		void	zeroVec();	// deprecated - -		void	set(F32 x, F32 y);	        // Sets LLVector2 to (x, y) -		void	set(const LLVector2 &vec);	// Sets LLVector2 to vec -		void	set(const F32 *vec);			// Sets LLVector2 to vec - -		LLSD	getValue() const; -		void	setValue(const LLSD& sd); - -		void	setVec(F32 x, F32 y);	        // deprecated -		void	setVec(const LLVector2 &vec);	// deprecated -		void	setVec(const F32 *vec);			// deprecated - -		inline bool isFinite() const; // checks to see if all values of LLVector2 are finite - -		F32		length() const;				// Returns magnitude of LLVector2 -		F32		lengthSquared() const;		// Returns magnitude squared of LLVector2 -		F32		normalize();					// Normalizes and returns the magnitude of LLVector2 - -		F32		magVec() const;				// deprecated -		F32		magVecSquared() const;		// deprecated -		F32		normVec();					// deprecated - -		BOOL		abs();						// sets all values to absolute value of original value (first octant), returns TRUE if changed - -		const LLVector2&	scaleVec(const LLVector2& vec);				// scales per component by vec - -		BOOL isNull();			// Returns TRUE if vector has a _very_small_ length -		BOOL isExactlyZero() const		{ return !mV[VX] && !mV[VY]; } - -		F32 operator[](int idx) const { return mV[idx]; } -		F32 &operator[](int idx) { return mV[idx]; } -	 -		friend bool operator<(const LLVector2 &a, const LLVector2 &b);	// For sorting. x is "more significant" than y -		friend LLVector2 operator+(const LLVector2 &a, const LLVector2 &b);	// Return vector a + b -		friend LLVector2 operator-(const LLVector2 &a, const LLVector2 &b);	// Return vector a minus b -		friend F32 operator*(const LLVector2 &a, const LLVector2 &b);		// Return a dot b -		friend LLVector2 operator%(const LLVector2 &a, const LLVector2 &b);	// Return a cross b -		friend LLVector2 operator/(const LLVector2 &a, F32 k);				// Return a divided by scaler k -		friend LLVector2 operator*(const LLVector2 &a, F32 k);				// Return a times scaler k -		friend LLVector2 operator*(F32 k, const LLVector2 &a);				// Return a times scaler k -		friend bool operator==(const LLVector2 &a, const LLVector2 &b);		// Return a == b -		friend bool operator!=(const LLVector2 &a, const LLVector2 &b);		// Return a != b - -		friend const LLVector2& operator+=(LLVector2 &a, const LLVector2 &b);	// Return vector a + b -		friend const LLVector2& operator-=(LLVector2 &a, const LLVector2 &b);	// Return vector a minus b -		friend const LLVector2& operator%=(LLVector2 &a, const LLVector2 &b);	// Return a cross b -		friend const LLVector2& operator*=(LLVector2 &a, F32 k);				// Return a times scaler k -		friend const LLVector2& operator/=(LLVector2 &a, F32 k);				// Return a divided by scaler k - -		friend LLVector2 operator-(const LLVector2 &a);					// Return vector -a - -		friend std::ostream&	 operator<<(std::ostream& s, const LLVector2 &a);		// Stream a + +        // Clears LLVector2 to (0, 0).  DEPRECATED - prefer zeroVec. +        void    clear(); +        void    setZero(); +        void    clearVec(); // deprecated +        void    zeroVec();  // deprecated + +        void    set(F32 x, F32 y);          // Sets LLVector2 to (x, y) +        void    set(const LLVector2 &vec);  // Sets LLVector2 to vec +        void    set(const F32 *vec);            // Sets LLVector2 to vec + +        LLSD    getValue() const; +        void    setValue(const LLSD& sd); + +        void    setVec(F32 x, F32 y);           // deprecated +        void    setVec(const LLVector2 &vec);   // deprecated +        void    setVec(const F32 *vec);         // deprecated + +        inline bool isFinite() const; // checks to see if all values of LLVector2 are finite + +        F32     length() const;             // Returns magnitude of LLVector2 +        F32     lengthSquared() const;      // Returns magnitude squared of LLVector2 +        F32     normalize();                    // Normalizes and returns the magnitude of LLVector2 + +        F32     magVec() const;             // deprecated +        F32     magVecSquared() const;      // deprecated +        F32     normVec();                  // deprecated + +        BOOL        abs();                      // sets all values to absolute value of original value (first octant), returns TRUE if changed + +        const LLVector2&    scaleVec(const LLVector2& vec);             // scales per component by vec + +        BOOL isNull();          // Returns TRUE if vector has a _very_small_ length +        BOOL isExactlyZero() const      { return !mV[VX] && !mV[VY]; } + +        F32 operator[](int idx) const { return mV[idx]; } +        F32 &operator[](int idx) { return mV[idx]; } + +        friend bool operator<(const LLVector2 &a, const LLVector2 &b);  // For sorting. x is "more significant" than y +        friend LLVector2 operator+(const LLVector2 &a, const LLVector2 &b); // Return vector a + b +        friend LLVector2 operator-(const LLVector2 &a, const LLVector2 &b); // Return vector a minus b +        friend F32 operator*(const LLVector2 &a, const LLVector2 &b);       // Return a dot b +        friend LLVector2 operator%(const LLVector2 &a, const LLVector2 &b); // Return a cross b +        friend LLVector2 operator/(const LLVector2 &a, F32 k);              // Return a divided by scaler k +        friend LLVector2 operator*(const LLVector2 &a, F32 k);              // Return a times scaler k +        friend LLVector2 operator*(F32 k, const LLVector2 &a);              // Return a times scaler k +        friend bool operator==(const LLVector2 &a, const LLVector2 &b);     // Return a == b +        friend bool operator!=(const LLVector2 &a, const LLVector2 &b);     // Return a != b + +        friend const LLVector2& operator+=(LLVector2 &a, const LLVector2 &b);   // Return vector a + b +        friend const LLVector2& operator-=(LLVector2 &a, const LLVector2 &b);   // Return vector a minus b +        friend const LLVector2& operator%=(LLVector2 &a, const LLVector2 &b);   // Return a cross b +        friend const LLVector2& operator*=(LLVector2 &a, F32 k);                // Return a times scaler k +        friend const LLVector2& operator/=(LLVector2 &a, F32 k);                // Return a divided by scaler k + +        friend LLVector2 operator-(const LLVector2 &a);                 // Return vector -a + +        friend std::ostream&     operator<<(std::ostream& s, const LLVector2 &a);       // Stream a  }; -// Non-member functions  +// Non-member functions -F32	angle_between(const LLVector2 &a, const LLVector2 &b);	// Returns angle (radians) between a and b -BOOL are_parallel(const LLVector2 &a, const LLVector2 &b, F32 epsilon=F_APPROXIMATELY_ZERO);	// Returns TRUE if a and b are very close to parallel -F32	dist_vec(const LLVector2 &a, const LLVector2 &b);		// Returns distance between a and b -F32	dist_vec_squared(const LLVector2 &a, const LLVector2 &b);// Returns distance squared between a and b -F32	dist_vec_squared2D(const LLVector2 &a, const LLVector2 &b);// Returns distance squared between a and b ignoring Z component +F32 angle_between(const LLVector2 &a, const LLVector2 &b);  // Returns angle (radians) between a and b +BOOL are_parallel(const LLVector2 &a, const LLVector2 &b, F32 epsilon=F_APPROXIMATELY_ZERO);    // Returns TRUE if a and b are very close to parallel +F32 dist_vec(const LLVector2 &a, const LLVector2 &b);       // Returns distance between a and b +F32 dist_vec_squared(const LLVector2 &a, const LLVector2 &b);// Returns distance squared between a and b +F32 dist_vec_squared2D(const LLVector2 &a, const LLVector2 &b);// Returns distance squared between a and b ignoring Z component  LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u); // Returns a vector that is a linear interpolation between a and b  // Constructors  inline LLVector2::LLVector2(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; +    mV[VX] = 0.f; +    mV[VY] = 0.f;  }  inline LLVector2::LLVector2(F32 x, F32 y)  { -	mV[VX] = x; -	mV[VY] = y; +    mV[VX] = x; +    mV[VY] = y;  }  inline LLVector2::LLVector2(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY];  }  inline LLVector2::LLVector2(const LLVector3 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY];  }  inline LLVector2::LLVector2(const LLSD &sd) @@ -153,70 +153,70 @@ inline LLVector2::LLVector2(const LLSD &sd)  // Clear and Assignment Functions -inline void	LLVector2::clear(void) +inline void LLVector2::clear(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; +    mV[VX] = 0.f; +    mV[VY] = 0.f;  } -inline void	LLVector2::setZero(void) +inline void LLVector2::setZero(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; +    mV[VX] = 0.f; +    mV[VY] = 0.f;  }  // deprecated -inline void	LLVector2::clearVec(void) +inline void LLVector2::clearVec(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; +    mV[VX] = 0.f; +    mV[VY] = 0.f;  }  // deprecated -inline void	LLVector2::zeroVec(void) +inline void LLVector2::zeroVec(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; +    mV[VX] = 0.f; +    mV[VY] = 0.f;  } -inline void	LLVector2::set(F32 x, F32 y) +inline void LLVector2::set(F32 x, F32 y)  { -	mV[VX] = x; -	mV[VY] = y; +    mV[VX] = x; +    mV[VY] = y;  } -inline void	LLVector2::set(const LLVector2 &vec) +inline void LLVector2::set(const LLVector2 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY];  } -inline void	LLVector2::set(const F32 *vec) +inline void LLVector2::set(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY];  }  // deprecated -inline void	LLVector2::setVec(F32 x, F32 y) +inline void LLVector2::setVec(F32 x, F32 y)  { -	mV[VX] = x; -	mV[VY] = y; +    mV[VX] = x; +    mV[VY] = y;  }  // deprecated -inline void	LLVector2::setVec(const LLVector2 &vec) +inline void LLVector2::setVec(const LLVector2 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY];  }  // deprecated -inline void	LLVector2::setVec(const F32 *vec) +inline void LLVector2::setVec(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY];  } @@ -224,217 +224,217 @@ inline void	LLVector2::setVec(const F32 *vec)  inline F32 LLVector2::length(void) const  { -	return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]); +    return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]);  }  inline F32 LLVector2::lengthSquared(void) const  { -	return mV[0]*mV[0] + mV[1]*mV[1]; +    return mV[0]*mV[0] + mV[1]*mV[1];  } -inline F32		LLVector2::normalize(void) +inline F32      LLVector2::normalize(void)  { -	F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]); -	F32 oomag; +    F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]); +    F32 oomag; -	if (mag > FP_MAG_THRESHOLD) -	{ -		oomag = 1.f/mag; -		mV[0] *= oomag; -		mV[1] *= oomag; -	} -	else -	{ -		mV[0] = 0.f; -		mV[1] = 0.f; -		mag = 0; -	} -	return (mag); +    if (mag > FP_MAG_THRESHOLD) +    { +        oomag = 1.f/mag; +        mV[0] *= oomag; +        mV[1] *= oomag; +    } +    else +    { +        mV[0] = 0.f; +        mV[1] = 0.f; +        mag = 0; +    } +    return (mag);  }  // checker  inline bool LLVector2::isFinite() const  { -	return (llfinite(mV[VX]) && llfinite(mV[VY])); +    return (llfinite(mV[VX]) && llfinite(mV[VY]));  }  // deprecated -inline F32		LLVector2::magVec(void) const +inline F32      LLVector2::magVec(void) const  { -	return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]); +    return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]);  }  // deprecated -inline F32		LLVector2::magVecSquared(void) const +inline F32      LLVector2::magVecSquared(void) const  { -	return mV[0]*mV[0] + mV[1]*mV[1]; +    return mV[0]*mV[0] + mV[1]*mV[1];  }  // deprecated -inline F32		LLVector2::normVec(void) +inline F32      LLVector2::normVec(void)  { -	F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]); -	F32 oomag; +    F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]); +    F32 oomag; -	if (mag > FP_MAG_THRESHOLD) -	{ -		oomag = 1.f/mag; -		mV[0] *= oomag; -		mV[1] *= oomag; -	} -	else -	{ -		mV[0] = 0.f; -		mV[1] = 0.f; -		mag = 0; -	} -	return (mag); +    if (mag > FP_MAG_THRESHOLD) +    { +        oomag = 1.f/mag; +        mV[0] *= oomag; +        mV[1] *= oomag; +    } +    else +    { +        mV[0] = 0.f; +        mV[1] = 0.f; +        mag = 0; +    } +    return (mag);  } -inline const LLVector2&	LLVector2::scaleVec(const LLVector2& vec) +inline const LLVector2& LLVector2::scaleVec(const LLVector2& vec)  { -	mV[VX] *= vec.mV[VX]; -	mV[VY] *= vec.mV[VY]; +    mV[VX] *= vec.mV[VX]; +    mV[VY] *= vec.mV[VY]; -	return *this; +    return *this;  } -inline BOOL	LLVector2::isNull() +inline BOOL LLVector2::isNull()  { -	if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] ) -	{ -		return TRUE; -	} -	return FALSE; +    if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] ) +    { +        return TRUE; +    } +    return FALSE;  }  // LLVector2 Operators  // For sorting. By convention, x is "more significant" than y. -inline bool operator<(const LLVector2 &a, const LLVector2 &b)	 +inline bool operator<(const LLVector2 &a, const LLVector2 &b)  { -	if( a.mV[VX] == b.mV[VX] ) -	{ -		return a.mV[VY] < b.mV[VY]; -	} -	else -	{ -		return a.mV[VX] < b.mV[VX]; -	} +    if( a.mV[VX] == b.mV[VX] ) +    { +        return a.mV[VY] < b.mV[VY]; +    } +    else +    { +        return a.mV[VX] < b.mV[VX]; +    }  }  inline LLVector2 operator+(const LLVector2 &a, const LLVector2 &b)  { -	LLVector2 c(a); -	return c += b; +    LLVector2 c(a); +    return c += b;  }  inline LLVector2 operator-(const LLVector2 &a, const LLVector2 &b)  { -	LLVector2 c(a); -	return c -= b; +    LLVector2 c(a); +    return c -= b;  }  inline F32  operator*(const LLVector2 &a, const LLVector2 &b)  { -	return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1]); +    return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1]);  }  inline LLVector2 operator%(const LLVector2 &a, const LLVector2 &b)  { -	return LLVector2(a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1], a.mV[1]*b.mV[0] - b.mV[1]*a.mV[0]); +    return LLVector2(a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1], a.mV[1]*b.mV[0] - b.mV[1]*a.mV[0]);  }  inline LLVector2 operator/(const LLVector2 &a, F32 k)  { -	F32 t = 1.f / k; -	return LLVector2( a.mV[0] * t, a.mV[1] * t ); +    F32 t = 1.f / k; +    return LLVector2( a.mV[0] * t, a.mV[1] * t );  }  inline LLVector2 operator*(const LLVector2 &a, F32 k)  { -	return LLVector2( a.mV[0] * k, a.mV[1] * k ); +    return LLVector2( a.mV[0] * k, a.mV[1] * k );  }  inline LLVector2 operator*(F32 k, const LLVector2 &a)  { -	return LLVector2( a.mV[0] * k, a.mV[1] * k ); +    return LLVector2( a.mV[0] * k, a.mV[1] * k );  }  inline bool operator==(const LLVector2 &a, const LLVector2 &b)  { -	return (  (a.mV[0] == b.mV[0]) -			&&(a.mV[1] == b.mV[1])); +    return (  (a.mV[0] == b.mV[0]) +            &&(a.mV[1] == b.mV[1]));  }  inline bool operator!=(const LLVector2 &a, const LLVector2 &b)  { -	return (  (a.mV[0] != b.mV[0]) -			||(a.mV[1] != b.mV[1])); +    return (  (a.mV[0] != b.mV[0]) +            ||(a.mV[1] != b.mV[1]));  }  inline const LLVector2& operator+=(LLVector2 &a, const LLVector2 &b)  { -	a.mV[0] += b.mV[0]; -	a.mV[1] += b.mV[1]; -	return a; +    a.mV[0] += b.mV[0]; +    a.mV[1] += b.mV[1]; +    return a;  }  inline const LLVector2& operator-=(LLVector2 &a, const LLVector2 &b)  { -	a.mV[0] -= b.mV[0]; -	a.mV[1] -= b.mV[1]; -	return a; +    a.mV[0] -= b.mV[0]; +    a.mV[1] -= b.mV[1]; +    return a;  }  inline const LLVector2& operator%=(LLVector2 &a, const LLVector2 &b)  { -	LLVector2 ret(a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1], a.mV[1]*b.mV[0] - b.mV[1]*a.mV[0]); -	a = ret; -	return a; +    LLVector2 ret(a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1], a.mV[1]*b.mV[0] - b.mV[1]*a.mV[0]); +    a = ret; +    return a;  }  inline const LLVector2& operator*=(LLVector2 &a, F32 k)  { -	a.mV[0] *= k; -	a.mV[1] *= k; -	return a; +    a.mV[0] *= k; +    a.mV[1] *= k; +    return a;  }  inline const LLVector2& operator/=(LLVector2 &a, F32 k)  { -	F32 t = 1.f / k; -	a.mV[0] *= t; -	a.mV[1] *= t; -	return a; +    F32 t = 1.f / k; +    a.mV[0] *= t; +    a.mV[1] *= t; +    return a;  }  inline LLVector2 operator-(const LLVector2 &a)  { -	return LLVector2( -a.mV[0], -a.mV[1] ); +    return LLVector2( -a.mV[0], -a.mV[1] );  }  inline void update_min_max(LLVector2& min, LLVector2& max, const LLVector2& pos)  { -	for (U32 i = 0; i < 2; i++) -	{ -		if (min.mV[i] > pos.mV[i]) -		{ -			min.mV[i] = pos.mV[i]; -		} -		if (max.mV[i] < pos.mV[i]) -		{ -			max.mV[i] = pos.mV[i]; -		} -	} +    for (U32 i = 0; i < 2; i++) +    { +        if (min.mV[i] > pos.mV[i]) +        { +            min.mV[i] = pos.mV[i]; +        } +        if (max.mV[i] < pos.mV[i]) +        { +            max.mV[i] = pos.mV[i]; +        } +    }  } -inline std::ostream& operator<<(std::ostream& s, const LLVector2 &a)  +inline std::ostream& operator<<(std::ostream& s, const LLVector2 &a)  { -	s << "{ " << a.mV[VX] << ", " << a.mV[VY] << " }"; -	return s; +    s << "{ " << a.mV[VX] << ", " << a.mV[VY] << " }"; +    return s;  }  #endif diff --git a/indra/llmath/v3color.cpp b/indra/llmath/v3color.cpp index d38f48b11e..9fe9c8d5e5 100644 --- a/indra/llmath/v3color.cpp +++ b/indra/llmath/v3color.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file v3color.cpp   * @brief LLColor3 class implementation.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -36,118 +36,118 @@ LLColor3 LLColor3::grey (0.5f, 0.5f, 0.5f);  LLColor3::LLColor3(const LLColor4 &a)  { -	mV[0] = a.mV[0]; -	mV[1] = a.mV[1]; -	mV[2] = a.mV[2]; +    mV[0] = a.mV[0]; +    mV[1] = a.mV[1]; +    mV[2] = a.mV[2];  }  LLColor3::LLColor3(const LLVector4 &a)  { -	mV[0] = a.mV[0]; -	mV[1] = a.mV[1]; -	mV[2] = a.mV[2]; +    mV[0] = a.mV[0]; +    mV[1] = a.mV[1]; +    mV[2] = a.mV[2];  }  LLColor3::LLColor3(const LLSD &sd)  { -	setValue(sd); +    setValue(sd);  } -const LLColor3& LLColor3::operator=(const LLColor4 &a)  +const LLColor3& LLColor3::operator=(const LLColor4 &a)  { -	mV[0] = a.mV[0]; -	mV[1] = a.mV[1]; -	mV[2] = a.mV[2]; -	return (*this); +    mV[0] = a.mV[0]; +    mV[1] = a.mV[1]; +    mV[2] = a.mV[2]; +    return (*this);  } -std::ostream& operator<<(std::ostream& s, const LLColor3 &a)  +std::ostream& operator<<(std::ostream& s, const LLColor3 &a)  { -	s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << " }"; -	return s; +    s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << " }"; +    return s;  }  static F32 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )  { -	if ( valHUeIn < 0.0f ) valHUeIn += 1.0f; -	if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f; -	if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn ); -	if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In ); -	if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f ); -	return ( val1In ); +    if ( valHUeIn < 0.0f ) valHUeIn += 1.0f; +    if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f; +    if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn ); +    if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In ); +    if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f ); +    return ( val1In );  }  void LLColor3::setHSL ( F32 hValIn, F32 sValIn, F32 lValIn)  { -	if ( sValIn < 0.00001f ) -	{ -		mV[VRED] = lValIn; -		mV[VGREEN] = lValIn; -		mV[VBLUE] = lValIn; -	} -	else -	{ -		F32 interVal1; -		F32 interVal2; - -		if ( lValIn < 0.5f ) -			interVal2 = lValIn * ( 1.0f + sValIn ); -		else -			interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn ); - -		interVal1 = 2.0f * lValIn - interVal2; - -		mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) ); -		mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn ); -		mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) ); -	} +    if ( sValIn < 0.00001f ) +    { +        mV[VRED] = lValIn; +        mV[VGREEN] = lValIn; +        mV[VBLUE] = lValIn; +    } +    else +    { +        F32 interVal1; +        F32 interVal2; + +        if ( lValIn < 0.5f ) +            interVal2 = lValIn * ( 1.0f + sValIn ); +        else +            interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn ); + +        interVal1 = 2.0f * lValIn - interVal2; + +        mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) ); +        mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn ); +        mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) ); +    }  }  void LLColor3::calcHSL(F32* hue, F32* saturation, F32* luminance) const  { -	F32 var_R = mV[VRED]; -	F32 var_G = mV[VGREEN]; -	F32 var_B = mV[VBLUE]; - -	F32 var_Min = ( var_R < ( var_G < var_B ? var_G : var_B ) ? var_R : ( var_G < var_B ? var_G : var_B ) ); -	F32 var_Max = ( var_R > ( var_G > var_B ? var_G : var_B ) ? var_R : ( var_G > var_B ? var_G : var_B ) ); - -	F32 del_Max = var_Max - var_Min; - -	F32 L = ( var_Max + var_Min ) / 2.0f; -	F32 H = 0.0f; -	F32 S = 0.0f; - -	if ( del_Max == 0.0f ) -	{ -	   H = 0.0f; -	   S = 0.0f; -	} -	else -	{ -		if ( L < 0.5 ) -			S = del_Max / ( var_Max + var_Min ); -		else -			S = del_Max / ( 2.0f - var_Max - var_Min ); - -		F32 del_R = ( ( ( var_Max - var_R ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; -		F32 del_G = ( ( ( var_Max - var_G ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; -		F32 del_B = ( ( ( var_Max - var_B ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; - -		if ( var_R >= var_Max ) -			H = del_B - del_G; -		else -		if ( var_G >= var_Max ) -			H = ( 1.0f / 3.0f ) + del_R - del_B; -		else -		if ( var_B >= var_Max ) -			H = ( 2.0f / 3.0f ) + del_G - del_R; - -		if ( H < 0.0f ) H += 1.0f; -		if ( H > 1.0f ) H -= 1.0f; -	} - -	if (hue) *hue = H; -	if (saturation) *saturation = S; -	if (luminance) *luminance = L; +    F32 var_R = mV[VRED]; +    F32 var_G = mV[VGREEN]; +    F32 var_B = mV[VBLUE]; + +    F32 var_Min = ( var_R < ( var_G < var_B ? var_G : var_B ) ? var_R : ( var_G < var_B ? var_G : var_B ) ); +    F32 var_Max = ( var_R > ( var_G > var_B ? var_G : var_B ) ? var_R : ( var_G > var_B ? var_G : var_B ) ); + +    F32 del_Max = var_Max - var_Min; + +    F32 L = ( var_Max + var_Min ) / 2.0f; +    F32 H = 0.0f; +    F32 S = 0.0f; + +    if ( del_Max == 0.0f ) +    { +       H = 0.0f; +       S = 0.0f; +    } +    else +    { +        if ( L < 0.5 ) +            S = del_Max / ( var_Max + var_Min ); +        else +            S = del_Max / ( 2.0f - var_Max - var_Min ); + +        F32 del_R = ( ( ( var_Max - var_R ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; +        F32 del_G = ( ( ( var_Max - var_G ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; +        F32 del_B = ( ( ( var_Max - var_B ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; + +        if ( var_R >= var_Max ) +            H = del_B - del_G; +        else +        if ( var_G >= var_Max ) +            H = ( 1.0f / 3.0f ) + del_R - del_B; +        else +        if ( var_B >= var_Max ) +            H = ( 2.0f / 3.0f ) + del_G - del_R; + +        if ( H < 0.0f ) H += 1.0f; +        if ( H > 1.0f ) H -= 1.0f; +    } + +    if (hue) *hue = H; +    if (saturation) *saturation = S; +    if (luminance) *luminance = L;  } diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index d925f56e97..ea26e9eb76 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -1,25 +1,25 @@ -/**  +/**   * @file v3color.h   * @brief LLColor3 class header file.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -43,52 +43,52 @@ static const U32 LENGTHOFCOLOR3 = 3;  class LLColor3  {  public: -	F32 mV[LENGTHOFCOLOR3]; +    F32 mV[LENGTHOFCOLOR3]; -	static LLColor3 white; -	static LLColor3 black; -	static LLColor3 grey; +    static LLColor3 white; +    static LLColor3 black; +    static LLColor3 grey;  public: -	LLColor3();							// Initializes LLColor3 to (0, 0, 0) -	LLColor3(F32 r, F32 g, F32 b);		// Initializes LLColor3 to (r, g, b) -	LLColor3(const F32 *vec);			// Initializes LLColor3 to (vec[0]. vec[1], vec[2]) -	LLColor3(const char *color_string);       // html format color ie "#FFDDEE" -	explicit LLColor3(const LLColor4& color4);  // "explicit" to avoid automatic conversion -	explicit LLColor3(const LLVector4& vector4);  // "explicit" to avoid automatic conversion -	LLColor3(const LLSD& sd); -	 - -	LLSD getValue() const -	{ -		LLSD ret; -		ret[0] = mV[0]; -		ret[1] = mV[1]; -		ret[2] = mV[2]; -		return ret; -	} - -	void setValue(const LLSD& sd) -	{ -		mV[0] = (F32) sd[0].asReal();; -		mV[1] = (F32) sd[1].asReal();; -		mV[2] = (F32) sd[2].asReal();; -	} - -	void setHSL(F32 hue, F32 saturation, F32 luminance); -	void calcHSL(F32* hue, F32* saturation, F32* luminance) const; -	 -	const LLColor3&	setToBlack();					// Clears LLColor3 to (0, 0, 0) -	const LLColor3&	setToWhite();					// Zero LLColor3 to (0, 0, 0) -	 -	const LLColor3&	setVec(F32 x, F32 y, F32 z);	// deprecated -	const LLColor3&	setVec(const LLColor3 &vec);	// deprecated -	const LLColor3&	setVec(const F32 *vec);			// deprecated - -	const LLColor3&	set(F32 x, F32 y, F32 z);	// Sets LLColor3 to (x, y, z) -	const LLColor3&	set(const LLColor3 &vec);	// Sets LLColor3 to vec -	const LLColor3&	set(const F32 *vec);		// Sets LLColor3 to vec -     +    LLColor3();                         // Initializes LLColor3 to (0, 0, 0) +    LLColor3(F32 r, F32 g, F32 b);      // Initializes LLColor3 to (r, g, b) +    LLColor3(const F32 *vec);           // Initializes LLColor3 to (vec[0]. vec[1], vec[2]) +    LLColor3(const char *color_string);       // html format color ie "#FFDDEE" +    explicit LLColor3(const LLColor4& color4);  // "explicit" to avoid automatic conversion +    explicit LLColor3(const LLVector4& vector4);  // "explicit" to avoid automatic conversion +    LLColor3(const LLSD& sd); + + +    LLSD getValue() const +    { +        LLSD ret; +        ret[0] = mV[0]; +        ret[1] = mV[1]; +        ret[2] = mV[2]; +        return ret; +    } + +    void setValue(const LLSD& sd) +    { +        mV[0] = (F32) sd[0].asReal();; +        mV[1] = (F32) sd[1].asReal();; +        mV[2] = (F32) sd[2].asReal();; +    } + +    void setHSL(F32 hue, F32 saturation, F32 luminance); +    void calcHSL(F32* hue, F32* saturation, F32* luminance) const; + +    const LLColor3& setToBlack();                   // Clears LLColor3 to (0, 0, 0) +    const LLColor3& setToWhite();                   // Zero LLColor3 to (0, 0, 0) + +    const LLColor3& setVec(F32 x, F32 y, F32 z);    // deprecated +    const LLColor3& setVec(const LLColor3 &vec);    // deprecated +    const LLColor3& setVec(const F32 *vec);         // deprecated + +    const LLColor3& set(F32 x, F32 y, F32 z);   // Sets LLColor3 to (x, y, z) +    const LLColor3& set(const LLColor3 &vec);   // Sets LLColor3 to vec +    const LLColor3& set(const F32 *vec);        // Sets LLColor3 to vec +      // set from a vector of unknown type and size      // may leave some data unmodified      template<typename T> @@ -99,18 +99,18 @@ public:      template<typename T>      void write(std::vector<T>& v) const; -	F32		magVec() const;				// deprecated -	F32		magVecSquared() const;		// deprecated -	F32		normVec();					// deprecated +    F32     magVec() const;             // deprecated +    F32     magVecSquared() const;      // deprecated +    F32     normVec();                  // deprecated + +    F32     length() const;             // Returns magnitude of LLColor3 +    F32     lengthSquared() const;      // Returns magnitude squared of LLColor3 +    F32     normalize();                // Normalizes and returns the magnitude of LLColor3 -	F32		length() const;				// Returns magnitude of LLColor3 -	F32		lengthSquared() const;		// Returns magnitude squared of LLColor3 -	F32		normalize();				// Normalizes and returns the magnitude of LLColor3 +    F32     brightness() const;         // Returns brightness of LLColor3 -	F32		brightness() const;			// Returns brightness of LLColor3 +    const LLColor3& operator=(const LLColor4 &a); -	const LLColor3&	operator=(const LLColor4 &a); -	      LL_FORCE_INLINE LLColor3 divide(const LLColor3 &col2)      {          return LLColor3( @@ -128,27 +128,27 @@ public:                  mV[2] / l );      } -	friend std::ostream&	 operator<<(std::ostream& s, const LLColor3 &a);		// Print a -	friend LLColor3 operator+(const LLColor3 &a, const LLColor3 &b);	// Return vector a + b -	friend LLColor3 operator-(const LLColor3 &a, const LLColor3 &b);	// Return vector a minus b +    friend std::ostream&     operator<<(std::ostream& s, const LLColor3 &a);        // Print a +    friend LLColor3 operator+(const LLColor3 &a, const LLColor3 &b);    // Return vector a + b +    friend LLColor3 operator-(const LLColor3 &a, const LLColor3 &b);    // Return vector a minus b -	friend const LLColor3& operator+=(LLColor3 &a, const LLColor3 &b);	// Return vector a + b -	friend const LLColor3& operator-=(LLColor3 &a, const LLColor3 &b);	// Return vector a minus b -	friend const LLColor3& operator*=(LLColor3 &a, const LLColor3 &b); +    friend const LLColor3& operator+=(LLColor3 &a, const LLColor3 &b);  // Return vector a + b +    friend const LLColor3& operator-=(LLColor3 &a, const LLColor3 &b);  // Return vector a minus b +    friend const LLColor3& operator*=(LLColor3 &a, const LLColor3 &b); -	friend LLColor3 operator*(const LLColor3 &a, const LLColor3 &b);	// Return component wise a * b -	friend LLColor3 operator*(const LLColor3 &a, F32 k);				// Return a times scaler k -	friend LLColor3 operator*(F32 k, const LLColor3 &a);				// Return a times scaler k +    friend LLColor3 operator*(const LLColor3 &a, const LLColor3 &b);    // Return component wise a * b +    friend LLColor3 operator*(const LLColor3 &a, F32 k);                // Return a times scaler k +    friend LLColor3 operator*(F32 k, const LLColor3 &a);                // Return a times scaler k -	friend bool operator==(const LLColor3 &a, const LLColor3 &b);		// Return a == b -	friend bool operator!=(const LLColor3 &a, const LLColor3 &b);		// Return a != b +    friend bool operator==(const LLColor3 &a, const LLColor3 &b);       // Return a == b +    friend bool operator!=(const LLColor3 &a, const LLColor3 &b);       // Return a != b -	friend const LLColor3& operator*=(LLColor3 &a, F32 k);				// Return a times scaler k +    friend const LLColor3& operator*=(LLColor3 &a, F32 k);              // Return a times scaler k -	friend LLColor3 operator-(const LLColor3 &a);					// Return vector 1-rgb (inverse) +    friend LLColor3 operator-(const LLColor3 &a);                   // Return vector 1-rgb (inverse) -	inline void clamp(); -	inline void exp();	// Do an exponential on the color +    inline void clamp(); +    inline void exp();  // Do an exponential on the color  };  LLColor3 lerp(const LLColor3 &a, const LLColor3 &b, F32 u); @@ -156,343 +156,343 @@ LLColor3 lerp(const LLColor3 &a, const LLColor3 &b, F32 u);  void LLColor3::clamp()  { -	// Clamp the color... -	if (mV[0] < 0.f) -	{ -		mV[0] = 0.f; -	} -	else if (mV[0] > 1.f) -	{ -		mV[0] = 1.f; -	} -	if (mV[1] < 0.f) -	{ -		mV[1] = 0.f; -	} -	else if (mV[1] > 1.f) -	{ -		mV[1] = 1.f; -	} -	if (mV[2] < 0.f) -	{ -		mV[2] = 0.f; -	} -	else if (mV[2] > 1.f) -	{ -		mV[2] = 1.f; -	} -} - -// Non-member functions  -F32		distVec(const LLColor3 &a, const LLColor3 &b);		// Returns distance between a and b -F32		distVec_squared(const LLColor3 &a, const LLColor3 &b);// Returns distance squared between a and b +    // Clamp the color... +    if (mV[0] < 0.f) +    { +        mV[0] = 0.f; +    } +    else if (mV[0] > 1.f) +    { +        mV[0] = 1.f; +    } +    if (mV[1] < 0.f) +    { +        mV[1] = 0.f; +    } +    else if (mV[1] > 1.f) +    { +        mV[1] = 1.f; +    } +    if (mV[2] < 0.f) +    { +        mV[2] = 0.f; +    } +    else if (mV[2] > 1.f) +    { +        mV[2] = 1.f; +    } +} + +// Non-member functions +F32     distVec(const LLColor3 &a, const LLColor3 &b);      // Returns distance between a and b +F32     distVec_squared(const LLColor3 &a, const LLColor3 &b);// Returns distance squared between a and b  inline LLColor3::LLColor3(void)  { -	mV[0] = 0.f; -	mV[1] = 0.f; -	mV[2] = 0.f; +    mV[0] = 0.f; +    mV[1] = 0.f; +    mV[2] = 0.f;  }  inline LLColor3::LLColor3(F32 r, F32 g, F32 b)  { -	mV[VX] = r; -	mV[VY] = g; -	mV[VZ] = b; +    mV[VX] = r; +    mV[VY] = g; +    mV[VZ] = b;  }  inline LLColor3::LLColor3(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ];  }  #if LL_WINDOWS  # pragma warning( disable : 4996 ) // strncpy teh sux0r  #endif -inline LLColor3::LLColor3(const char* color_string) // takes a string of format "RRGGBB" where RR is hex 00..FF  +inline LLColor3::LLColor3(const char* color_string) // takes a string of format "RRGGBB" where RR is hex 00..FF  { -	if (strlen(color_string) <  6)		/* Flawfinder: ignore */ -	{ -		mV[0] = 0.f; -		mV[1] = 0.f; -		mV[2] = 0.f;		 -		return; -	} +    if (strlen(color_string) <  6)      /* Flawfinder: ignore */ +    { +        mV[0] = 0.f; +        mV[1] = 0.f; +        mV[2] = 0.f; +        return; +    } -	char tempstr[7]; -	strncpy(tempstr,color_string,6);		/* Flawfinder: ignore */ -	tempstr[6] = '\0'; -	mV[VZ] = (F32)strtol(&tempstr[4],NULL,16)/255.f; -	tempstr[4] = '\0'; -	mV[VY] = (F32)strtol(&tempstr[2],NULL,16)/255.f; -	tempstr[2] = '\0'; -	mV[VX] = (F32)strtol(&tempstr[0],NULL,16)/255.f; +    char tempstr[7]; +    strncpy(tempstr,color_string,6);        /* Flawfinder: ignore */ +    tempstr[6] = '\0'; +    mV[VZ] = (F32)strtol(&tempstr[4],NULL,16)/255.f; +    tempstr[4] = '\0'; +    mV[VY] = (F32)strtol(&tempstr[2],NULL,16)/255.f; +    tempstr[2] = '\0'; +    mV[VX] = (F32)strtol(&tempstr[0],NULL,16)/255.f;  } -inline const LLColor3&	LLColor3::setToBlack(void) +inline const LLColor3&  LLColor3::setToBlack(void)  { -	mV[0] = 0.f; -	mV[1] = 0.f; -	mV[2] = 0.f; -	return (*this); +    mV[0] = 0.f; +    mV[1] = 0.f; +    mV[2] = 0.f; +    return (*this);  } -inline const LLColor3&	LLColor3::setToWhite(void) +inline const LLColor3&  LLColor3::setToWhite(void)  { -	mV[0] = 1.f; -	mV[1] = 1.f; -	mV[2] = 1.f; -	return (*this); +    mV[0] = 1.f; +    mV[1] = 1.f; +    mV[2] = 1.f; +    return (*this);  } -inline const LLColor3&	LLColor3::set(F32 r, F32 g, F32 b) +inline const LLColor3&  LLColor3::set(F32 r, F32 g, F32 b)  { -	mV[0] = r; -	mV[1] = g; -	mV[2] = b; -	return (*this); +    mV[0] = r; +    mV[1] = g; +    mV[2] = b; +    return (*this);  } -inline const LLColor3&	LLColor3::set(const LLColor3 &vec) +inline const LLColor3&  LLColor3::set(const LLColor3 &vec)  { -	mV[0] = vec.mV[0]; -	mV[1] = vec.mV[1]; -	mV[2] = vec.mV[2]; -	return (*this); +    mV[0] = vec.mV[0]; +    mV[1] = vec.mV[1]; +    mV[2] = vec.mV[2]; +    return (*this);  } -inline const LLColor3&	LLColor3::set(const F32 *vec) +inline const LLColor3&  LLColor3::set(const F32 *vec)  { -	mV[0] = vec[0]; -	mV[1] = vec[1]; -	mV[2] = vec[2]; -	return (*this); +    mV[0] = vec[0]; +    mV[1] = vec[1]; +    mV[2] = vec[2]; +    return (*this);  }  // deprecated -inline const LLColor3&	LLColor3::setVec(F32 r, F32 g, F32 b) +inline const LLColor3&  LLColor3::setVec(F32 r, F32 g, F32 b)  { -	mV[0] = r; -	mV[1] = g; -	mV[2] = b; -	return (*this); +    mV[0] = r; +    mV[1] = g; +    mV[2] = b; +    return (*this);  }  // deprecated -inline const LLColor3&	LLColor3::setVec(const LLColor3 &vec) +inline const LLColor3&  LLColor3::setVec(const LLColor3 &vec)  { -	mV[0] = vec.mV[0]; -	mV[1] = vec.mV[1]; -	mV[2] = vec.mV[2]; -	return (*this); +    mV[0] = vec.mV[0]; +    mV[1] = vec.mV[1]; +    mV[2] = vec.mV[2]; +    return (*this);  }  // deprecated -inline const LLColor3&	LLColor3::setVec(const F32 *vec) +inline const LLColor3&  LLColor3::setVec(const F32 *vec)  { -	mV[0] = vec[0]; -	mV[1] = vec[1]; -	mV[2] = vec[2]; -	return (*this); +    mV[0] = vec[0]; +    mV[1] = vec[1]; +    mV[2] = vec[2]; +    return (*this);  } -inline F32		LLColor3::brightness(void) const +inline F32      LLColor3::brightness(void) const  { -	return (mV[0] + mV[1] + mV[2]) / 3.0f; +    return (mV[0] + mV[1] + mV[2]) / 3.0f;  } -inline F32		LLColor3::length(void) const +inline F32      LLColor3::length(void) const  { -	return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); +    return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);  } -inline F32		LLColor3::lengthSquared(void) const +inline F32      LLColor3::lengthSquared(void) const  { -	return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]; +    return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];  } -inline F32		LLColor3::normalize(void) +inline F32      LLColor3::normalize(void)  { -	F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); -	F32 oomag; +    F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); +    F32 oomag; -	if (mag) -	{ -		oomag = 1.f/mag; -		mV[0] *= oomag; -		mV[1] *= oomag; -		mV[2] *= oomag; -	} -	return (mag); +    if (mag) +    { +        oomag = 1.f/mag; +        mV[0] *= oomag; +        mV[1] *= oomag; +        mV[2] *= oomag; +    } +    return (mag);  }  // deprecated -inline F32		LLColor3::magVec(void) const +inline F32      LLColor3::magVec(void) const  { -	return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); +    return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);  }  // deprecated -inline F32		LLColor3::magVecSquared(void) const +inline F32      LLColor3::magVecSquared(void) const  { -	return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]; +    return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];  }  // deprecated -inline F32		LLColor3::normVec(void) +inline F32      LLColor3::normVec(void)  { -	F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); -	F32 oomag; +    F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); +    F32 oomag; -	if (mag) -	{ -		oomag = 1.f/mag; -		mV[0] *= oomag; -		mV[1] *= oomag; -		mV[2] *= oomag; -	} -	return (mag); +    if (mag) +    { +        oomag = 1.f/mag; +        mV[0] *= oomag; +        mV[1] *= oomag; +        mV[2] *= oomag; +    } +    return (mag);  }  inline void LLColor3::exp()  {  #if 0 -	mV[0] = ::exp(mV[0]); -	mV[1] = ::exp(mV[1]); -	mV[2] = ::exp(mV[2]); +    mV[0] = ::exp(mV[0]); +    mV[1] = ::exp(mV[1]); +    mV[2] = ::exp(mV[2]);  #else -	mV[0] = (F32)LL_FAST_EXP(mV[0]); -	mV[1] = (F32)LL_FAST_EXP(mV[1]); -	mV[2] = (F32)LL_FAST_EXP(mV[2]); +    mV[0] = (F32)LL_FAST_EXP(mV[0]); +    mV[1] = (F32)LL_FAST_EXP(mV[1]); +    mV[2] = (F32)LL_FAST_EXP(mV[2]);  #endif  }  inline LLColor3 operator+(const LLColor3 &a, const LLColor3 &b)  { -	return LLColor3( -		a.mV[0] + b.mV[0], -		a.mV[1] + b.mV[1], -		a.mV[2] + b.mV[2]); +    return LLColor3( +        a.mV[0] + b.mV[0], +        a.mV[1] + b.mV[1], +        a.mV[2] + b.mV[2]);  }  inline LLColor3 operator-(const LLColor3 &a, const LLColor3 &b)  { -	return LLColor3( -		a.mV[0] - b.mV[0], -		a.mV[1] - b.mV[1], -		a.mV[2] - b.mV[2]); +    return LLColor3( +        a.mV[0] - b.mV[0], +        a.mV[1] - b.mV[1], +        a.mV[2] - b.mV[2]);  }  inline LLColor3  operator*(const LLColor3 &a, const LLColor3 &b)  { -	return LLColor3( -		a.mV[0] * b.mV[0], -		a.mV[1] * b.mV[1], -		a.mV[2] * b.mV[2]); +    return LLColor3( +        a.mV[0] * b.mV[0], +        a.mV[1] * b.mV[1], +        a.mV[2] * b.mV[2]);  }  inline LLColor3 operator*(const LLColor3 &a, F32 k)  { -	return LLColor3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k ); +    return LLColor3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );  }  inline LLColor3 operator*(F32 k, const LLColor3 &a)  { -	return LLColor3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k ); +    return LLColor3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );  }  inline bool operator==(const LLColor3 &a, const LLColor3 &b)  { -	return (  (a.mV[0] == b.mV[0]) -			&&(a.mV[1] == b.mV[1]) -			&&(a.mV[2] == b.mV[2])); +    return (  (a.mV[0] == b.mV[0]) +            &&(a.mV[1] == b.mV[1]) +            &&(a.mV[2] == b.mV[2]));  }  inline bool operator!=(const LLColor3 &a, const LLColor3 &b)  { -	return (  (a.mV[0] != b.mV[0]) -			||(a.mV[1] != b.mV[1]) -			||(a.mV[2] != b.mV[2])); +    return (  (a.mV[0] != b.mV[0]) +            ||(a.mV[1] != b.mV[1]) +            ||(a.mV[2] != b.mV[2]));  }  inline const LLColor3 &operator*=(LLColor3 &a, const LLColor3 &b)  { -	a.mV[0] *= b.mV[0]; -	a.mV[1] *= b.mV[1]; -	a.mV[2] *= b.mV[2]; -	return a; +    a.mV[0] *= b.mV[0]; +    a.mV[1] *= b.mV[1]; +    a.mV[2] *= b.mV[2]; +    return a;  }  inline const LLColor3& operator+=(LLColor3 &a, const LLColor3 &b)  { -	a.mV[0] += b.mV[0]; -	a.mV[1] += b.mV[1]; -	a.mV[2] += b.mV[2]; -	return a; +    a.mV[0] += b.mV[0]; +    a.mV[1] += b.mV[1]; +    a.mV[2] += b.mV[2]; +    return a;  }  inline const LLColor3& operator-=(LLColor3 &a, const LLColor3 &b)  { -	a.mV[0] -= b.mV[0]; -	a.mV[1] -= b.mV[1]; -	a.mV[2] -= b.mV[2]; -	return a; +    a.mV[0] -= b.mV[0]; +    a.mV[1] -= b.mV[1]; +    a.mV[2] -= b.mV[2]; +    return a;  }  inline const LLColor3& operator*=(LLColor3 &a, F32 k)  { -	a.mV[0] *= k; -	a.mV[1] *= k; -	a.mV[2] *= k; -	return a; +    a.mV[0] *= k; +    a.mV[1] *= k; +    a.mV[2] *= k; +    return a;  }  inline LLColor3 operator-(const LLColor3 &a)  { -	return LLColor3( -		1.f - a.mV[0], -		1.f - a.mV[1], -		1.f - a.mV[2] ); +    return LLColor3( +        1.f - a.mV[0], +        1.f - a.mV[1], +        1.f - a.mV[2] );  }  // Non-member functions -inline F32		distVec(const LLColor3 &a, const LLColor3 &b) +inline F32      distVec(const LLColor3 &a, const LLColor3 &b)  { -	F32 x = a.mV[0] - b.mV[0]; -	F32 y = a.mV[1] - b.mV[1]; -	F32 z = a.mV[2] - b.mV[2]; -	return (F32) sqrt( x*x + y*y + z*z ); +    F32 x = a.mV[0] - b.mV[0]; +    F32 y = a.mV[1] - b.mV[1]; +    F32 z = a.mV[2] - b.mV[2]; +    return (F32) sqrt( x*x + y*y + z*z );  } -inline F32		distVec_squared(const LLColor3 &a, const LLColor3 &b) +inline F32      distVec_squared(const LLColor3 &a, const LLColor3 &b)  { -	F32 x = a.mV[0] - b.mV[0]; -	F32 y = a.mV[1] - b.mV[1]; -	F32 z = a.mV[2] - b.mV[2]; -	return x*x + y*y + z*z; +    F32 x = a.mV[0] - b.mV[0]; +    F32 y = a.mV[1] - b.mV[1]; +    F32 z = a.mV[2] - b.mV[2]; +    return x*x + y*y + z*z;  }  inline LLColor3 lerp(const LLColor3 &a, const LLColor3 &b, F32 u)  { -	return LLColor3( -		a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, -		a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, -		a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u); +    return LLColor3( +        a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, +        a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, +        a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);  }  inline const LLColor3 srgbColor3(const LLColor3 &a) { -	LLColor3 srgbColor; -	srgbColor.mV[0] = linearTosRGB(a.mV[0]); -	srgbColor.mV[1] = linearTosRGB(a.mV[1]); -	srgbColor.mV[2] = linearTosRGB(a.mV[2]); +    LLColor3 srgbColor; +    srgbColor.mV[0] = linearTosRGB(a.mV[0]); +    srgbColor.mV[1] = linearTosRGB(a.mV[1]); +    srgbColor.mV[2] = linearTosRGB(a.mV[2]); -	return srgbColor; +    return srgbColor;  }  inline const LLColor3 linearColor3p(const F32* v) { diff --git a/indra/llmath/v3colorutil.h b/indra/llmath/v3colorutil.h index 6d8cd9329b..62005f76a0 100644 --- a/indra/llmath/v3colorutil.h +++ b/indra/llmath/v3colorutil.h @@ -1,25 +1,25 @@ -/**  +/**   * @file v3color.h   * @brief LLColor3 class header file.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ diff --git a/indra/llmath/v3dmath.cpp b/indra/llmath/v3dmath.cpp index a50cb3c6ca..6ecd1a00ac 100644 --- a/indra/llmath/v3dmath.cpp +++ b/indra/llmath/v3dmath.cpp @@ -1,32 +1,32 @@ -/**  +/**   * @file v3dmath.cpp   * @brief LLVector3d class implementation.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */  #include "linden_common.h" -//#include <sstream>	// gcc 2.95.2 doesn't support sstream  +//#include <sstream>    // gcc 2.95.2 doesn't support sstream  #include "v3dmath.h" @@ -39,8 +39,8 @@  // LLVector3d  // WARNING: Don't use these for global const definitions! -// For example:  -//		const LLQuaternion(0.5f * F_PI, LLVector3d::zero); +// For example: +//      const LLQuaternion(0.5f * F_PI, LLVector3d::zero);  // at the top of a *.cpp file might not give you what you think.  const LLVector3d LLVector3d::zero(0,0,0);  const LLVector3d LLVector3d::x_axis(1, 0, 0); @@ -55,93 +55,93 @@ const LLVector3d LLVector3d::z_axis_neg(0, 0, -1);  // Returns TRUE if data changed.  BOOL LLVector3d::clamp(F64 min, F64 max)  { -	BOOL ret = FALSE; +    BOOL ret = FALSE; -	if (mdV[0] < min) { mdV[0] = min; ret = TRUE; } -	if (mdV[1] < min) { mdV[1] = min; ret = TRUE; } -	if (mdV[2] < min) { mdV[2] = min; ret = TRUE; } +    if (mdV[0] < min) { mdV[0] = min; ret = TRUE; } +    if (mdV[1] < min) { mdV[1] = min; ret = TRUE; } +    if (mdV[2] < min) { mdV[2] = min; ret = TRUE; } -	if (mdV[0] > max) { mdV[0] = max; ret = TRUE; } -	if (mdV[1] > max) { mdV[1] = max; ret = TRUE; } -	if (mdV[2] > max) { mdV[2] = max; ret = TRUE; } +    if (mdV[0] > max) { mdV[0] = max; ret = TRUE; } +    if (mdV[1] > max) { mdV[1] = max; ret = TRUE; } +    if (mdV[2] > max) { mdV[2] = max; ret = TRUE; } -	return ret; +    return ret;  }  // Sets all values to absolute value of their original values  // Returns TRUE if data changed  BOOL LLVector3d::abs()  { -	BOOL ret = FALSE; +    BOOL ret = FALSE; -	if (mdV[0] < 0.0) { mdV[0] = -mdV[0]; ret = TRUE; } -	if (mdV[1] < 0.0) { mdV[1] = -mdV[1]; ret = TRUE; } -	if (mdV[2] < 0.0) { mdV[2] = -mdV[2]; ret = TRUE; } +    if (mdV[0] < 0.0) { mdV[0] = -mdV[0]; ret = TRUE; } +    if (mdV[1] < 0.0) { mdV[1] = -mdV[1]; ret = TRUE; } +    if (mdV[2] < 0.0) { mdV[2] = -mdV[2]; ret = TRUE; } -	return ret; +    return ret;  } -std::ostream& operator<<(std::ostream& s, const LLVector3d &a)  +std::ostream& operator<<(std::ostream& s, const LLVector3d &a)  { -	s << "{ " << a.mdV[VX] << ", " << a.mdV[VY] << ", " << a.mdV[VZ] << " }"; -	return s; +    s << "{ " << a.mdV[VX] << ", " << a.mdV[VY] << ", " << a.mdV[VZ] << " }"; +    return s;  } -const LLVector3d& LLVector3d::operator=(const LLVector4 &a)  +const LLVector3d& LLVector3d::operator=(const LLVector4 &a)  { -	mdV[0] = a.mV[0]; -	mdV[1] = a.mV[1]; -	mdV[2] = a.mV[2]; -	return *this; +    mdV[0] = a.mV[0]; +    mdV[1] = a.mV[1]; +    mdV[2] = a.mV[2]; +    return *this;  } -const LLVector3d&	LLVector3d::rotVec(const LLMatrix3 &mat) +const LLVector3d&   LLVector3d::rotVec(const LLMatrix3 &mat)  { -	*this = *this * mat; -	return *this; +    *this = *this * mat; +    return *this;  } -const LLVector3d&	LLVector3d::rotVec(const LLQuaternion &q) +const LLVector3d&   LLVector3d::rotVec(const LLQuaternion &q)  { -	*this = *this * q; -	return *this; +    *this = *this * q; +    return *this;  } -const LLVector3d&	LLVector3d::rotVec(F64 angle, const LLVector3d &vec) +const LLVector3d&   LLVector3d::rotVec(F64 angle, const LLVector3d &vec)  { -	if ( !vec.isExactlyZero() && angle ) -	{ -		*this = *this * LLMatrix3((F32)angle, vec); -	} -	return *this; +    if ( !vec.isExactlyZero() && angle ) +    { +        *this = *this * LLMatrix3((F32)angle, vec); +    } +    return *this;  } -const LLVector3d&	LLVector3d::rotVec(F64 angle, F64 x, F64 y, F64 z) +const LLVector3d&   LLVector3d::rotVec(F64 angle, F64 x, F64 y, F64 z)  { -	LLVector3d vec(x, y, z); -	if ( !vec.isExactlyZero() && angle ) -	{ -		*this = *this * LLMatrix3((F32)angle, vec); -	} -	return *this; +    LLVector3d vec(x, y, z); +    if ( !vec.isExactlyZero() && angle ) +    { +        *this = *this * LLMatrix3((F32)angle, vec); +    } +    return *this;  }  BOOL LLVector3d::parseVector3d(const std::string& buf, LLVector3d* value)  { -	if( buf.empty() || value == NULL) -	{ -		return FALSE; -	} - -	LLVector3d v; -	S32 count = sscanf( buf.c_str(), "%lf %lf %lf", v.mdV + 0, v.mdV + 1, v.mdV + 2 ); -	if( 3 == count ) -	{ -		value->setVec( v ); -		return TRUE; -	} - -	return FALSE; +    if( buf.empty() || value == NULL) +    { +        return FALSE; +    } + +    LLVector3d v; +    S32 count = sscanf( buf.c_str(), "%lf %lf %lf", v.mdV + 0, v.mdV + 1, v.mdV + 2 ); +    if( 3 == count ) +    { +        value->setVec( v ); +        return TRUE; +    } + +    return FALSE;  } diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h index 4938273d5b..99c6905e70 100644 --- a/indra/llmath/v3dmath.h +++ b/indra/llmath/v3dmath.h @@ -1,25 +1,25 @@ -/**  +/**   * @file v3dmath.h   * @brief High precision 3 dimensional vector.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -32,101 +32,101 @@  class LLVector3d  { -	public: -		F64 mdV[3]; - -		const static LLVector3d zero; -		const static LLVector3d x_axis; -		const static LLVector3d y_axis; -		const static LLVector3d z_axis; -		const static LLVector3d x_axis_neg; -		const static LLVector3d y_axis_neg; -		const static LLVector3d z_axis_neg; - -		inline LLVector3d();							// Initializes LLVector3d to (0, 0, 0) -		inline LLVector3d(const F64 x, const F64 y, const F64 z);			// Initializes LLVector3d to (x. y, z) -		inline explicit LLVector3d(const F64 *vec);				// Initializes LLVector3d to (vec[0]. vec[1], vec[2]) -		inline explicit LLVector3d(const LLVector3 &vec); -		explicit LLVector3d(const LLSD& sd) -		{ -			setValue(sd); -		} - -		void setValue(const LLSD& sd) -		{ -			mdV[0] = sd[0].asReal(); -			mdV[1] = sd[1].asReal(); -			mdV[2] = sd[2].asReal(); -		} - -		LLSD getValue() const -		{ -			LLSD ret; -			ret[0] = mdV[0]; -			ret[1] = mdV[1]; -			ret[2] = mdV[2]; -			return ret; -		} - -		inline BOOL isFinite() const;									// checks to see if all values of LLVector3d are finite -		BOOL		clamp(const F64 min, const F64 max);		// Clamps all values to (min,max), returns TRUE if data changed -		BOOL		abs();						// sets all values to absolute value of original value (first octant), returns TRUE if changed - -		inline const LLVector3d&	clear();		// Clears LLVector3d to (0, 0, 0, 1) -		inline const LLVector3d&	clearVec();		// deprecated -		inline const LLVector3d&	setZero();		// Zero LLVector3d to (0, 0, 0, 0) -		inline const LLVector3d&	zeroVec();		// deprecated -		inline const LLVector3d&	set(const F64 x, const F64 y, const F64 z);	// Sets LLVector3d to (x, y, z, 1) -		inline const LLVector3d&	set(const LLVector3d &vec);	// Sets LLVector3d to vec -		inline const LLVector3d&	set(const F64 *vec);		// Sets LLVector3d to vec -		inline const LLVector3d&	set(const LLVector3 &vec); -		inline const LLVector3d&	setVec(const F64 x, const F64 y, const F64 z);	// deprecated -		inline const LLVector3d&	setVec(const LLVector3d &vec);	// deprecated -		inline const LLVector3d&	setVec(const F64 *vec);			// deprecated -		inline const LLVector3d&	setVec(const LLVector3 &vec);	// deprecated - -		F64		magVec() const;				// deprecated -		F64		magVecSquared() const;		// deprecated -		inline F64		normVec();					// deprecated - -		F64 length() const;			// Returns magnitude of LLVector3d -		F64 lengthSquared() const;	// Returns magnitude squared of LLVector3d -		inline F64 normalize();		// Normalizes and returns the magnitude of LLVector3d - -		const LLVector3d&	rotVec(const F64 angle, const LLVector3d &vec);	// Rotates about vec by angle radians -		const LLVector3d&	rotVec(const F64 angle, const F64 x, const F64 y, const F64 z);		// Rotates about x,y,z by angle radians -		const LLVector3d&	rotVec(const LLMatrix3 &mat);				// Rotates by LLMatrix4 mat -		const LLVector3d&	rotVec(const LLQuaternion &q);				// Rotates by LLQuaternion q - -		BOOL isNull() const;			// Returns TRUE if vector has a _very_small_ length -		BOOL isExactlyZero() const		{ return !mdV[VX] && !mdV[VY] && !mdV[VZ]; } - -		const LLVector3d&	operator=(const LLVector4 &a); - -		F64 operator[](int idx) const { return mdV[idx]; } -		F64 &operator[](int idx) { return mdV[idx]; } - -		friend LLVector3d operator+(const LLVector3d& a, const LLVector3d& b);	// Return vector a + b -		friend LLVector3d operator-(const LLVector3d& a, const LLVector3d& b);	// Return vector a minus b -		friend F64 operator*(const LLVector3d& a, const LLVector3d& b);		// Return a dot b -		friend LLVector3d operator%(const LLVector3d& a, const LLVector3d& b);	// Return a cross b -		friend LLVector3d operator*(const LLVector3d& a, const F64 k);				// Return a times scaler k -		friend LLVector3d operator/(const LLVector3d& a, const F64 k);				// Return a divided by scaler k -		friend LLVector3d operator*(const F64 k, const LLVector3d& a);				// Return a times scaler k -		friend bool operator==(const LLVector3d& a, const LLVector3d& b);		// Return a == b -		friend bool operator!=(const LLVector3d& a, const LLVector3d& b);		// Return a != b - -		friend const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b);	// Return vector a + b -		friend const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b);	// Return vector a minus b -		friend const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b);	// Return a cross b -		friend const LLVector3d& operator*=(LLVector3d& a, const F64 k);				// Return a times scaler k -		friend const LLVector3d& operator/=(LLVector3d& a, const F64 k);				// Return a divided by scaler k - -		friend LLVector3d operator-(const LLVector3d& a);					// Return vector -a - -		friend std::ostream&	 operator<<(std::ostream& s, const LLVector3d& a);		// Stream a - -		static BOOL parseVector3d(const std::string& buf, LLVector3d* value); +    public: +        F64 mdV[3]; + +        const static LLVector3d zero; +        const static LLVector3d x_axis; +        const static LLVector3d y_axis; +        const static LLVector3d z_axis; +        const static LLVector3d x_axis_neg; +        const static LLVector3d y_axis_neg; +        const static LLVector3d z_axis_neg; + +        inline LLVector3d();                            // Initializes LLVector3d to (0, 0, 0) +        inline LLVector3d(const F64 x, const F64 y, const F64 z);           // Initializes LLVector3d to (x. y, z) +        inline explicit LLVector3d(const F64 *vec);             // Initializes LLVector3d to (vec[0]. vec[1], vec[2]) +        inline explicit LLVector3d(const LLVector3 &vec); +        explicit LLVector3d(const LLSD& sd) +        { +            setValue(sd); +        } + +        void setValue(const LLSD& sd) +        { +            mdV[0] = sd[0].asReal(); +            mdV[1] = sd[1].asReal(); +            mdV[2] = sd[2].asReal(); +        } + +        LLSD getValue() const +        { +            LLSD ret; +            ret[0] = mdV[0]; +            ret[1] = mdV[1]; +            ret[2] = mdV[2]; +            return ret; +        } + +        inline BOOL isFinite() const;                                   // checks to see if all values of LLVector3d are finite +        BOOL        clamp(const F64 min, const F64 max);        // Clamps all values to (min,max), returns TRUE if data changed +        BOOL        abs();                      // sets all values to absolute value of original value (first octant), returns TRUE if changed + +        inline const LLVector3d&    clear();        // Clears LLVector3d to (0, 0, 0, 1) +        inline const LLVector3d&    clearVec();     // deprecated +        inline const LLVector3d&    setZero();      // Zero LLVector3d to (0, 0, 0, 0) +        inline const LLVector3d&    zeroVec();      // deprecated +        inline const LLVector3d&    set(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1) +        inline const LLVector3d&    set(const LLVector3d &vec); // Sets LLVector3d to vec +        inline const LLVector3d&    set(const F64 *vec);        // Sets LLVector3d to vec +        inline const LLVector3d&    set(const LLVector3 &vec); +        inline const LLVector3d&    setVec(const F64 x, const F64 y, const F64 z);  // deprecated +        inline const LLVector3d&    setVec(const LLVector3d &vec);  // deprecated +        inline const LLVector3d&    setVec(const F64 *vec);         // deprecated +        inline const LLVector3d&    setVec(const LLVector3 &vec);   // deprecated + +        F64     magVec() const;             // deprecated +        F64     magVecSquared() const;      // deprecated +        inline F64      normVec();                  // deprecated + +        F64 length() const;         // Returns magnitude of LLVector3d +        F64 lengthSquared() const;  // Returns magnitude squared of LLVector3d +        inline F64 normalize();     // Normalizes and returns the magnitude of LLVector3d + +        const LLVector3d&   rotVec(const F64 angle, const LLVector3d &vec); // Rotates about vec by angle radians +        const LLVector3d&   rotVec(const F64 angle, const F64 x, const F64 y, const F64 z);     // Rotates about x,y,z by angle radians +        const LLVector3d&   rotVec(const LLMatrix3 &mat);               // Rotates by LLMatrix4 mat +        const LLVector3d&   rotVec(const LLQuaternion &q);              // Rotates by LLQuaternion q + +        BOOL isNull() const;            // Returns TRUE if vector has a _very_small_ length +        BOOL isExactlyZero() const      { return !mdV[VX] && !mdV[VY] && !mdV[VZ]; } + +        const LLVector3d&   operator=(const LLVector4 &a); + +        F64 operator[](int idx) const { return mdV[idx]; } +        F64 &operator[](int idx) { return mdV[idx]; } + +        friend LLVector3d operator+(const LLVector3d& a, const LLVector3d& b);  // Return vector a + b +        friend LLVector3d operator-(const LLVector3d& a, const LLVector3d& b);  // Return vector a minus b +        friend F64 operator*(const LLVector3d& a, const LLVector3d& b);     // Return a dot b +        friend LLVector3d operator%(const LLVector3d& a, const LLVector3d& b);  // Return a cross b +        friend LLVector3d operator*(const LLVector3d& a, const F64 k);              // Return a times scaler k +        friend LLVector3d operator/(const LLVector3d& a, const F64 k);              // Return a divided by scaler k +        friend LLVector3d operator*(const F64 k, const LLVector3d& a);              // Return a times scaler k +        friend bool operator==(const LLVector3d& a, const LLVector3d& b);       // Return a == b +        friend bool operator!=(const LLVector3d& a, const LLVector3d& b);       // Return a != b + +        friend const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b);    // Return vector a + b +        friend const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b);    // Return vector a minus b +        friend const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b);    // Return a cross b +        friend const LLVector3d& operator*=(LLVector3d& a, const F64 k);                // Return a times scaler k +        friend const LLVector3d& operator/=(LLVector3d& a, const F64 k);                // Return a divided by scaler k + +        friend LLVector3d operator-(const LLVector3d& a);                   // Return vector -a + +        friend std::ostream&     operator<<(std::ostream& s, const LLVector3d& a);      // Stream a + +        static BOOL parseVector3d(const std::string& buf, LLVector3d* value);  }; @@ -134,55 +134,55 @@ typedef LLVector3d LLGlobalVec;  inline const LLVector3d &LLVector3d::set(const LLVector3 &vec)  { -	mdV[0] = vec.mV[0]; -	mdV[1] = vec.mV[1]; -	mdV[2] = vec.mV[2]; -	return *this; +    mdV[0] = vec.mV[0]; +    mdV[1] = vec.mV[1]; +    mdV[2] = vec.mV[2]; +    return *this;  }  inline const LLVector3d &LLVector3d::setVec(const LLVector3 &vec)  { -	mdV[0] = vec.mV[0]; -	mdV[1] = vec.mV[1]; -	mdV[2] = vec.mV[2]; -	return *this; +    mdV[0] = vec.mV[0]; +    mdV[1] = vec.mV[1]; +    mdV[2] = vec.mV[2]; +    return *this;  }  inline LLVector3d::LLVector3d(void)  { -	mdV[0] = 0.f; -	mdV[1] = 0.f; -	mdV[2] = 0.f; +    mdV[0] = 0.f; +    mdV[1] = 0.f; +    mdV[2] = 0.f;  }  inline LLVector3d::LLVector3d(const F64 x, const F64 y, const F64 z)  { -	mdV[VX] = x; -	mdV[VY] = y; -	mdV[VZ] = z; +    mdV[VX] = x; +    mdV[VY] = y; +    mdV[VZ] = z;  }  inline LLVector3d::LLVector3d(const F64 *vec)  { -	mdV[VX] = vec[VX]; -	mdV[VY] = vec[VY]; -	mdV[VZ] = vec[VZ]; +    mdV[VX] = vec[VX]; +    mdV[VY] = vec[VY]; +    mdV[VZ] = vec[VZ];  }  inline LLVector3d::LLVector3d(const LLVector3 &vec)  { -	mdV[VX] = vec.mV[VX]; -	mdV[VY] = vec.mV[VY]; -	mdV[VZ] = vec.mV[VZ]; +    mdV[VX] = vec.mV[VX]; +    mdV[VY] = vec.mV[VY]; +    mdV[VZ] = vec.mV[VZ];  }  /*  inline LLVector3d::LLVector3d(const LLVector3d ©)  { -	mdV[VX] = copy.mdV[VX]; -	mdV[VY] = copy.mdV[VY]; -	mdV[VZ] = copy.mdV[VZ]; +    mdV[VX] = copy.mdV[VX]; +    mdV[VY] = copy.mdV[VY]; +    mdV[VZ] = copy.mdV[VZ];  }  */ @@ -191,341 +191,341 @@ inline LLVector3d::LLVector3d(const LLVector3d ©)  // checker  inline BOOL LLVector3d::isFinite() const  { -	return (llfinite(mdV[VX]) && llfinite(mdV[VY]) && llfinite(mdV[VZ])); +    return (llfinite(mdV[VX]) && llfinite(mdV[VY]) && llfinite(mdV[VZ]));  }  // Clear and Assignment Functions -inline const LLVector3d&	LLVector3d::clear(void) +inline const LLVector3d&    LLVector3d::clear(void)  { -	mdV[0] = 0.f; -	mdV[1] = 0.f; -	mdV[2]= 0.f; -	return (*this); +    mdV[0] = 0.f; +    mdV[1] = 0.f; +    mdV[2]= 0.f; +    return (*this);  } -inline const LLVector3d&	LLVector3d::clearVec(void) +inline const LLVector3d&    LLVector3d::clearVec(void)  { -	mdV[0] = 0.f; -	mdV[1] = 0.f; -	mdV[2]= 0.f; -	return (*this); +    mdV[0] = 0.f; +    mdV[1] = 0.f; +    mdV[2]= 0.f; +    return (*this);  } -inline const LLVector3d&	LLVector3d::setZero(void) +inline const LLVector3d&    LLVector3d::setZero(void)  { -	mdV[0] = 0.f; -	mdV[1] = 0.f; -	mdV[2] = 0.f; -	return (*this); +    mdV[0] = 0.f; +    mdV[1] = 0.f; +    mdV[2] = 0.f; +    return (*this);  } -inline const LLVector3d&	LLVector3d::zeroVec(void) +inline const LLVector3d&    LLVector3d::zeroVec(void)  { -	mdV[0] = 0.f; -	mdV[1] = 0.f; -	mdV[2] = 0.f; -	return (*this); +    mdV[0] = 0.f; +    mdV[1] = 0.f; +    mdV[2] = 0.f; +    return (*this);  } -inline const LLVector3d&	LLVector3d::set(const F64 x, const F64 y, const F64 z) +inline const LLVector3d&    LLVector3d::set(const F64 x, const F64 y, const F64 z)  { -	mdV[VX] = x; -	mdV[VY] = y; -	mdV[VZ] = z; -	return (*this); +    mdV[VX] = x; +    mdV[VY] = y; +    mdV[VZ] = z; +    return (*this);  } -inline const LLVector3d&	LLVector3d::set(const LLVector3d &vec) +inline const LLVector3d&    LLVector3d::set(const LLVector3d &vec)  { -	mdV[0] = vec.mdV[0]; -	mdV[1] = vec.mdV[1]; -	mdV[2] = vec.mdV[2]; -	return (*this); +    mdV[0] = vec.mdV[0]; +    mdV[1] = vec.mdV[1]; +    mdV[2] = vec.mdV[2]; +    return (*this);  } -inline const LLVector3d&	LLVector3d::set(const F64 *vec) +inline const LLVector3d&    LLVector3d::set(const F64 *vec)  { -	mdV[0] = vec[0]; -	mdV[1] = vec[1]; -	mdV[2] = vec[2]; -	return (*this); +    mdV[0] = vec[0]; +    mdV[1] = vec[1]; +    mdV[2] = vec[2]; +    return (*this);  } -inline const LLVector3d&	LLVector3d::setVec(const F64 x, const F64 y, const F64 z) +inline const LLVector3d&    LLVector3d::setVec(const F64 x, const F64 y, const F64 z)  { -	mdV[VX] = x; -	mdV[VY] = y; -	mdV[VZ] = z; -	return (*this); +    mdV[VX] = x; +    mdV[VY] = y; +    mdV[VZ] = z; +    return (*this);  } -inline const LLVector3d&	LLVector3d::setVec(const LLVector3d &vec) +inline const LLVector3d&    LLVector3d::setVec(const LLVector3d &vec)  { -	mdV[0] = vec.mdV[0]; -	mdV[1] = vec.mdV[1]; -	mdV[2] = vec.mdV[2]; -	return (*this); +    mdV[0] = vec.mdV[0]; +    mdV[1] = vec.mdV[1]; +    mdV[2] = vec.mdV[2]; +    return (*this);  } -inline const LLVector3d&	LLVector3d::setVec(const F64 *vec) +inline const LLVector3d&    LLVector3d::setVec(const F64 *vec)  { -	mdV[0] = vec[0]; -	mdV[1] = vec[1]; -	mdV[2] = vec[2]; -	return (*this); +    mdV[0] = vec[0]; +    mdV[1] = vec[1]; +    mdV[2] = vec[2]; +    return (*this);  }  inline F64 LLVector3d::normVec(void)  { -	F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); -	F64 oomag; - -	if (mag > FP_MAG_THRESHOLD) -	{ -		oomag = 1.f/mag; -		mdV[0] *= oomag; -		mdV[1] *= oomag; -		mdV[2] *= oomag; -	} -	else -	{ -		mdV[0] = 0.f; -		mdV[1] = 0.f; -		mdV[2] = 0.f; -		mag = 0; -	} -	return (mag); +    F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); +    F64 oomag; + +    if (mag > FP_MAG_THRESHOLD) +    { +        oomag = 1.f/mag; +        mdV[0] *= oomag; +        mdV[1] *= oomag; +        mdV[2] *= oomag; +    } +    else +    { +        mdV[0] = 0.f; +        mdV[1] = 0.f; +        mdV[2] = 0.f; +        mag = 0; +    } +    return (mag);  }  inline F64 LLVector3d::normalize(void)  { -	F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); -	F64 oomag; - -	if (mag > FP_MAG_THRESHOLD) -	{ -		oomag = 1.f/mag; -		mdV[0] *= oomag; -		mdV[1] *= oomag; -		mdV[2] *= oomag; -	} -	else -	{ -		mdV[0] = 0.f; -		mdV[1] = 0.f; -		mdV[2] = 0.f; -		mag = 0; -	} -	return (mag); +    F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); +    F64 oomag; + +    if (mag > FP_MAG_THRESHOLD) +    { +        oomag = 1.f/mag; +        mdV[0] *= oomag; +        mdV[1] *= oomag; +        mdV[2] *= oomag; +    } +    else +    { +        mdV[0] = 0.f; +        mdV[1] = 0.f; +        mdV[2] = 0.f; +        mag = 0; +    } +    return (mag);  }  // LLVector3d Magnitude and Normalization Functions -inline F64	LLVector3d::magVec(void) const +inline F64  LLVector3d::magVec(void) const  { -	return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); +    return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);  } -inline F64	LLVector3d::magVecSquared(void) const +inline F64  LLVector3d::magVecSquared(void) const  { -	return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]; +    return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];  } -inline F64	LLVector3d::length(void) const +inline F64  LLVector3d::length(void) const  { -	return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); +    return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);  } -inline F64	LLVector3d::lengthSquared(void) const +inline F64  LLVector3d::lengthSquared(void) const  { -	return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]; +    return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];  }  inline LLVector3d operator+(const LLVector3d& a, const LLVector3d& b)  { -	LLVector3d c(a); -	return c += b; +    LLVector3d c(a); +    return c += b;  }  inline LLVector3d operator-(const LLVector3d& a, const LLVector3d& b)  { -	LLVector3d c(a); -	return c -= b; +    LLVector3d c(a); +    return c -= b;  }  inline F64  operator*(const LLVector3d& a, const LLVector3d& b)  { -	return (a.mdV[0]*b.mdV[0] + a.mdV[1]*b.mdV[1] + a.mdV[2]*b.mdV[2]); +    return (a.mdV[0]*b.mdV[0] + a.mdV[1]*b.mdV[1] + a.mdV[2]*b.mdV[2]);  }  inline LLVector3d operator%(const LLVector3d& a, const LLVector3d& b)  { -	return LLVector3d( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1] ); +    return LLVector3d( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1] );  }  inline LLVector3d operator/(const LLVector3d& a, const F64 k)  { -	F64 t = 1.f / k; -	return LLVector3d( a.mdV[0] * t, a.mdV[1] * t, a.mdV[2] * t ); +    F64 t = 1.f / k; +    return LLVector3d( a.mdV[0] * t, a.mdV[1] * t, a.mdV[2] * t );  }  inline LLVector3d operator*(const LLVector3d& a, const F64 k)  { -	return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k ); +    return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );  }  inline LLVector3d operator*(F64 k, const LLVector3d& a)  { -	return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k ); +    return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );  }  inline bool operator==(const LLVector3d& a, const LLVector3d& b)  { -	return (  (a.mdV[0] == b.mdV[0]) -			&&(a.mdV[1] == b.mdV[1]) -			&&(a.mdV[2] == b.mdV[2])); +    return (  (a.mdV[0] == b.mdV[0]) +            &&(a.mdV[1] == b.mdV[1]) +            &&(a.mdV[2] == b.mdV[2]));  }  inline bool operator!=(const LLVector3d& a, const LLVector3d& b)  { -	return (  (a.mdV[0] != b.mdV[0]) -			||(a.mdV[1] != b.mdV[1]) -			||(a.mdV[2] != b.mdV[2])); +    return (  (a.mdV[0] != b.mdV[0]) +            ||(a.mdV[1] != b.mdV[1]) +            ||(a.mdV[2] != b.mdV[2]));  }  inline const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b)  { -	a.mdV[0] += b.mdV[0]; -	a.mdV[1] += b.mdV[1]; -	a.mdV[2] += b.mdV[2]; -	return a; +    a.mdV[0] += b.mdV[0]; +    a.mdV[1] += b.mdV[1]; +    a.mdV[2] += b.mdV[2]; +    return a;  }  inline const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b)  { -	a.mdV[0] -= b.mdV[0]; -	a.mdV[1] -= b.mdV[1]; -	a.mdV[2] -= b.mdV[2]; -	return a; +    a.mdV[0] -= b.mdV[0]; +    a.mdV[1] -= b.mdV[1]; +    a.mdV[2] -= b.mdV[2]; +    return a;  }  inline const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b)  { -	LLVector3d ret( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1]); -	a = ret; -	return a; +    LLVector3d ret( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1]); +    a = ret; +    return a;  }  inline const LLVector3d& operator*=(LLVector3d& a, const F64 k)  { -	a.mdV[0] *= k; -	a.mdV[1] *= k; -	a.mdV[2] *= k; -	return a; +    a.mdV[0] *= k; +    a.mdV[1] *= k; +    a.mdV[2] *= k; +    return a;  }  inline const LLVector3d& operator/=(LLVector3d& a, const F64 k)  { -	F64 t = 1.f / k; -	a.mdV[0] *= t; -	a.mdV[1] *= t; -	a.mdV[2] *= t; -	return a; +    F64 t = 1.f / k; +    a.mdV[0] *= t; +    a.mdV[1] *= t; +    a.mdV[2] *= t; +    return a;  }  inline LLVector3d operator-(const LLVector3d& a)  { -	return LLVector3d( -a.mdV[0], -a.mdV[1], -a.mdV[2] ); +    return LLVector3d( -a.mdV[0], -a.mdV[1], -a.mdV[2] );  } -inline F64	dist_vec(const LLVector3d& a, const LLVector3d& b) +inline F64  dist_vec(const LLVector3d& a, const LLVector3d& b)  { -	F64 x = a.mdV[0] - b.mdV[0]; -	F64 y = a.mdV[1] - b.mdV[1]; -	F64 z = a.mdV[2] - b.mdV[2]; -	return (F32) sqrt( x*x + y*y + z*z ); +    F64 x = a.mdV[0] - b.mdV[0]; +    F64 y = a.mdV[1] - b.mdV[1]; +    F64 z = a.mdV[2] - b.mdV[2]; +    return (F32) sqrt( x*x + y*y + z*z );  } -inline F64	dist_vec_squared(const LLVector3d& a, const LLVector3d& b) +inline F64  dist_vec_squared(const LLVector3d& a, const LLVector3d& b)  { -	F64 x = a.mdV[0] - b.mdV[0]; -	F64 y = a.mdV[1] - b.mdV[1]; -	F64 z = a.mdV[2] - b.mdV[2]; -	return x*x + y*y + z*z; +    F64 x = a.mdV[0] - b.mdV[0]; +    F64 y = a.mdV[1] - b.mdV[1]; +    F64 z = a.mdV[2] - b.mdV[2]; +    return x*x + y*y + z*z;  } -inline F64	dist_vec_squared2D(const LLVector3d& a, const LLVector3d& b) +inline F64  dist_vec_squared2D(const LLVector3d& a, const LLVector3d& b)  { -	F64 x = a.mdV[0] - b.mdV[0]; -	F64 y = a.mdV[1] - b.mdV[1]; -	return x*x + y*y; +    F64 x = a.mdV[0] - b.mdV[0]; +    F64 y = a.mdV[1] - b.mdV[1]; +    return x*x + y*y;  }  inline LLVector3d lerp(const LLVector3d& a, const LLVector3d& b, const F64 u)  { -	return LLVector3d( -		a.mdV[VX] + (b.mdV[VX] - a.mdV[VX]) * u, -		a.mdV[VY] + (b.mdV[VY] - a.mdV[VY]) * u, -		a.mdV[VZ] + (b.mdV[VZ] - a.mdV[VZ]) * u); +    return LLVector3d( +        a.mdV[VX] + (b.mdV[VX] - a.mdV[VX]) * u, +        a.mdV[VY] + (b.mdV[VY] - a.mdV[VY]) * u, +        a.mdV[VZ] + (b.mdV[VZ] - a.mdV[VZ]) * u);  } -inline BOOL	LLVector3d::isNull() const +inline BOOL LLVector3d::isNull() const  { -	if ( F_APPROXIMATELY_ZERO > mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ] ) -	{ -		return TRUE; -	} -	return FALSE; +    if ( F_APPROXIMATELY_ZERO > mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ] ) +    { +        return TRUE; +    } +    return FALSE;  }  inline F64 angle_between(const LLVector3d& a, const LLVector3d& b)  { -	LLVector3d an = a; -	LLVector3d bn = b; -	an.normalize(); -	bn.normalize(); -	F64 cosine = an * bn; -	F64 angle = (cosine >= 1.0f) ? 0.0f : -				(cosine <= -1.0f) ? F_PI : -				acos(cosine); -	return angle; +    LLVector3d an = a; +    LLVector3d bn = b; +    an.normalize(); +    bn.normalize(); +    F64 cosine = an * bn; +    F64 angle = (cosine >= 1.0f) ? 0.0f : +                (cosine <= -1.0f) ? F_PI : +                acos(cosine); +    return angle;  }  inline BOOL are_parallel(const LLVector3d& a, const LLVector3d& b, const F64 epsilon)  { -	LLVector3d an = a; -	LLVector3d bn = b; -	an.normalize(); -	bn.normalize(); -	F64 dot = an * bn; -	if ( (1.0f - fabs(dot)) < epsilon) -	{ -		return TRUE; -	} -	return FALSE; +    LLVector3d an = a; +    LLVector3d bn = b; +    an.normalize(); +    bn.normalize(); +    F64 dot = an * bn; +    if ( (1.0f - fabs(dot)) < epsilon) +    { +        return TRUE; +    } +    return FALSE;  }  inline LLVector3d projected_vec(const LLVector3d& a, const LLVector3d& b)  { -	LLVector3d project_axis = b; -	project_axis.normalize(); -	return project_axis * (a * project_axis); +    LLVector3d project_axis = b; +    project_axis.normalize(); +    return project_axis * (a * project_axis);  }  inline LLVector3d inverse_projected_vec(const LLVector3d& a, const LLVector3d& b)  { -	LLVector3d normalized_a = a; -	normalized_a.normalize(); -	LLVector3d normalized_b = b; -	F64 b_length = normalized_b.normalize(); +    LLVector3d normalized_a = a; +    normalized_a.normalize(); +    LLVector3d normalized_b = b; +    F64 b_length = normalized_b.normalize(); -	F64 dot_product = normalized_a * normalized_b; -	return normalized_a * (b_length / dot_product); +    F64 dot_product = normalized_a * normalized_b; +    return normalized_a * (b_length / dot_product);  }  #endif // LL_V3DMATH_H diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index 93010d2250..a867b9f578 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file v3math.cpp   * @brief LLVector3 class implementation.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -39,8 +39,8 @@  // LLVector3  // WARNING: Don't use these for global const definitions! -// For example:  -//		const LLQuaternion(0.5f * F_PI, LLVector3::zero); +// For example: +//      const LLQuaternion(0.5f * F_PI, LLVector3::zero);  // at the top of a *.cpp file might not give you what you think.  const LLVector3 LLVector3::zero(0,0,0);  const LLVector3 LLVector3::x_axis(1.f, 0, 0); @@ -56,97 +56,97 @@ const LLVector3 LLVector3::all_one(1.f,1.f,1.f);  // Returns TRUE if data changed.  BOOL LLVector3::clamp(F32 min, F32 max)  { -	BOOL ret = FALSE; +    BOOL ret = FALSE; -	if (mV[0] < min) { mV[0] = min; ret = TRUE; } -	if (mV[1] < min) { mV[1] = min; ret = TRUE; } -	if (mV[2] < min) { mV[2] = min; ret = TRUE; } +    if (mV[0] < min) { mV[0] = min; ret = TRUE; } +    if (mV[1] < min) { mV[1] = min; ret = TRUE; } +    if (mV[2] < min) { mV[2] = min; ret = TRUE; } -	if (mV[0] > max) { mV[0] = max; ret = TRUE; } -	if (mV[1] > max) { mV[1] = max; ret = TRUE; } -	if (mV[2] > max) { mV[2] = max; ret = TRUE; } +    if (mV[0] > max) { mV[0] = max; ret = TRUE; } +    if (mV[1] > max) { mV[1] = max; ret = TRUE; } +    if (mV[2] > max) { mV[2] = max; ret = TRUE; } -	return ret; +    return ret;  } -// Clamps length to an upper limit.   +// Clamps length to an upper limit.  // Returns TRUE if the data changed  BOOL LLVector3::clampLength( F32 length_limit )  { -	BOOL changed = FALSE; - -	F32 len = length(); -	if (llfinite(len)) -	{ -		if ( len > length_limit) -		{ -			normalize(); -			if (length_limit < 0.f) -			{ -				length_limit = 0.f; -			} -			mV[0] *= length_limit; -			mV[1] *= length_limit; -			mV[2] *= length_limit; -			changed = TRUE; -		} -	} -	else -	{	// this vector may still be salvagable -		F32 max_abs_component = 0.f; -		for (S32 i = 0; i < 3; ++i) -		{ -			F32 abs_component = fabs(mV[i]); -			if (llfinite(abs_component)) -			{ -				if (abs_component > max_abs_component) -				{ -					max_abs_component = abs_component; -				} -			} -			else -			{ -				// no it can't be salvaged --> clear it -				clear(); -				changed = TRUE; -				break; -			} -		} -		if (!changed) -		{ -			// yes it can be salvaged --> -			// bring the components down before we normalize -			mV[0] /= max_abs_component; -			mV[1] /= max_abs_component; -			mV[2] /= max_abs_component; -			normalize(); - -			if (length_limit < 0.f) -			{ -				length_limit = 0.f; -			} -			mV[0] *= length_limit; -			mV[1] *= length_limit; -			mV[2] *= length_limit; -		} -	} - -	return changed; +    BOOL changed = FALSE; + +    F32 len = length(); +    if (llfinite(len)) +    { +        if ( len > length_limit) +        { +            normalize(); +            if (length_limit < 0.f) +            { +                length_limit = 0.f; +            } +            mV[0] *= length_limit; +            mV[1] *= length_limit; +            mV[2] *= length_limit; +            changed = TRUE; +        } +    } +    else +    {   // this vector may still be salvagable +        F32 max_abs_component = 0.f; +        for (S32 i = 0; i < 3; ++i) +        { +            F32 abs_component = fabs(mV[i]); +            if (llfinite(abs_component)) +            { +                if (abs_component > max_abs_component) +                { +                    max_abs_component = abs_component; +                } +            } +            else +            { +                // no it can't be salvaged --> clear it +                clear(); +                changed = TRUE; +                break; +            } +        } +        if (!changed) +        { +            // yes it can be salvaged --> +            // bring the components down before we normalize +            mV[0] /= max_abs_component; +            mV[1] /= max_abs_component; +            mV[2] /= max_abs_component; +            normalize(); + +            if (length_limit < 0.f) +            { +                length_limit = 0.f; +            } +            mV[0] *= length_limit; +            mV[1] *= length_limit; +            mV[2] *= length_limit; +        } +    } + +    return changed;  }  BOOL LLVector3::clamp(const LLVector3 &min_vec, const LLVector3 &max_vec)  { -	BOOL ret = FALSE; +    BOOL ret = FALSE; -	if (mV[0] < min_vec[0]) { mV[0] = min_vec[0]; ret = TRUE; } -	if (mV[1] < min_vec[1]) { mV[1] = min_vec[1]; ret = TRUE; } -	if (mV[2] < min_vec[2]) { mV[2] = min_vec[2]; ret = TRUE; } +    if (mV[0] < min_vec[0]) { mV[0] = min_vec[0]; ret = TRUE; } +    if (mV[1] < min_vec[1]) { mV[1] = min_vec[1]; ret = TRUE; } +    if (mV[2] < min_vec[2]) { mV[2] = min_vec[2]; ret = TRUE; } -	if (mV[0] > max_vec[0]) { mV[0] = max_vec[0]; ret = TRUE; } -	if (mV[1] > max_vec[1]) { mV[1] = max_vec[1]; ret = TRUE; } -	if (mV[2] > max_vec[2]) { mV[2] = max_vec[2]; ret = TRUE; } +    if (mV[0] > max_vec[0]) { mV[0] = max_vec[0]; ret = TRUE; } +    if (mV[1] > max_vec[1]) { mV[1] = max_vec[1]; ret = TRUE; } +    if (mV[2] > max_vec[2]) { mV[2] = max_vec[2]; ret = TRUE; } -	return ret; +    return ret;  } @@ -154,166 +154,166 @@ BOOL LLVector3::clamp(const LLVector3 &min_vec, const LLVector3 &max_vec)  // Returns TRUE if data changed  BOOL LLVector3::abs()  { -	BOOL ret = FALSE; +    BOOL ret = FALSE; -	if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = TRUE; } -	if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = TRUE; } -	if (mV[2] < 0.f) { mV[2] = -mV[2]; ret = TRUE; } +    if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = TRUE; } +    if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = TRUE; } +    if (mV[2] < 0.f) { mV[2] = -mV[2]; ret = TRUE; } -	return ret; +    return ret;  }  // Quatizations -void	LLVector3::quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz) +void    LLVector3::quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz)  { -	F32 x = mV[VX]; -	F32 y = mV[VY]; -	F32 z = mV[VZ]; +    F32 x = mV[VX]; +    F32 y = mV[VY]; +    F32 z = mV[VZ]; -	x = U16_to_F32(F32_to_U16(x, lowerxy, upperxy), lowerxy, upperxy); -	y = U16_to_F32(F32_to_U16(y, lowerxy, upperxy), lowerxy, upperxy); -	z = U16_to_F32(F32_to_U16(z, lowerz,  upperz),  lowerz,  upperz); +    x = U16_to_F32(F32_to_U16(x, lowerxy, upperxy), lowerxy, upperxy); +    y = U16_to_F32(F32_to_U16(y, lowerxy, upperxy), lowerxy, upperxy); +    z = U16_to_F32(F32_to_U16(z, lowerz,  upperz),  lowerz,  upperz); -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z;  } -void	LLVector3::quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz) +void    LLVector3::quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz)  { -	mV[VX] = U8_to_F32(F32_to_U8(mV[VX], lowerxy, upperxy), lowerxy, upperxy);; -	mV[VY] = U8_to_F32(F32_to_U8(mV[VY], lowerxy, upperxy), lowerxy, upperxy); -	mV[VZ] = U8_to_F32(F32_to_U8(mV[VZ], lowerz, upperz), lowerz, upperz); +    mV[VX] = U8_to_F32(F32_to_U8(mV[VX], lowerxy, upperxy), lowerxy, upperxy);; +    mV[VY] = U8_to_F32(F32_to_U8(mV[VY], lowerxy, upperxy), lowerxy, upperxy); +    mV[VZ] = U8_to_F32(F32_to_U8(mV[VZ], lowerz, upperz), lowerz, upperz);  } -void 	LLVector3::snap(S32 sig_digits) +void    LLVector3::snap(S32 sig_digits)  { -	mV[VX] = snap_to_sig_figs(mV[VX], sig_digits); -	mV[VY] = snap_to_sig_figs(mV[VY], sig_digits); -	mV[VZ] = snap_to_sig_figs(mV[VZ], sig_digits); +    mV[VX] = snap_to_sig_figs(mV[VX], sig_digits); +    mV[VY] = snap_to_sig_figs(mV[VY], sig_digits); +    mV[VZ] = snap_to_sig_figs(mV[VZ], sig_digits);  } -const LLVector3&	LLVector3::rotVec(const LLMatrix3 &mat) +const LLVector3&    LLVector3::rotVec(const LLMatrix3 &mat)  { -	*this = *this * mat; -	return *this; +    *this = *this * mat; +    return *this;  } -const LLVector3&	LLVector3::rotVec(const LLQuaternion &q) +const LLVector3&    LLVector3::rotVec(const LLQuaternion &q)  { -	*this = *this * q; -	return *this; +    *this = *this * q; +    return *this;  }  const LLVector3& LLVector3::transVec(const LLMatrix4& mat)  { -	setVec( -			mV[VX] * mat.mMatrix[VX][VX] +  -			mV[VY] * mat.mMatrix[VX][VY] +  -			mV[VZ] * mat.mMatrix[VX][VZ] + -			mat.mMatrix[VX][VW], -			  -			mV[VX] * mat.mMatrix[VY][VX] +  -			mV[VY] * mat.mMatrix[VY][VY] +  -			mV[VZ] * mat.mMatrix[VY][VZ] + -			mat.mMatrix[VY][VW], - -			mV[VX] * mat.mMatrix[VZ][VX] +  -			mV[VY] * mat.mMatrix[VZ][VY] +  -			mV[VZ] * mat.mMatrix[VZ][VZ] + -			mat.mMatrix[VZ][VW]); - -	return *this; +    setVec( +            mV[VX] * mat.mMatrix[VX][VX] + +            mV[VY] * mat.mMatrix[VX][VY] + +            mV[VZ] * mat.mMatrix[VX][VZ] + +            mat.mMatrix[VX][VW], + +            mV[VX] * mat.mMatrix[VY][VX] + +            mV[VY] * mat.mMatrix[VY][VY] + +            mV[VZ] * mat.mMatrix[VY][VZ] + +            mat.mMatrix[VY][VW], + +            mV[VX] * mat.mMatrix[VZ][VX] + +            mV[VY] * mat.mMatrix[VZ][VY] + +            mV[VZ] * mat.mMatrix[VZ][VZ] + +            mat.mMatrix[VZ][VW]); + +    return *this;  } -const LLVector3&	LLVector3::rotVec(F32 angle, const LLVector3 &vec) +const LLVector3&    LLVector3::rotVec(F32 angle, const LLVector3 &vec)  { -	if ( !vec.isExactlyZero() && angle ) -	{ -		*this = *this * LLQuaternion(angle, vec); -	} -	return *this; +    if ( !vec.isExactlyZero() && angle ) +    { +        *this = *this * LLQuaternion(angle, vec); +    } +    return *this;  } -const LLVector3&	LLVector3::rotVec(F32 angle, F32 x, F32 y, F32 z) +const LLVector3&    LLVector3::rotVec(F32 angle, F32 x, F32 y, F32 z)  { -	LLVector3 vec(x, y, z); -	if ( !vec.isExactlyZero() && angle ) -	{ -		*this = *this * LLQuaternion(angle, vec); -	} -	return *this; +    LLVector3 vec(x, y, z); +    if ( !vec.isExactlyZero() && angle ) +    { +        *this = *this * LLQuaternion(angle, vec); +    } +    return *this;  } -const LLVector3&	LLVector3::scaleVec(const LLVector3& vec) +const LLVector3&    LLVector3::scaleVec(const LLVector3& vec)  { -	mV[VX] *= vec.mV[VX]; -	mV[VY] *= vec.mV[VY]; -	mV[VZ] *= vec.mV[VZ]; +    mV[VX] *= vec.mV[VX]; +    mV[VY] *= vec.mV[VY]; +    mV[VZ] *= vec.mV[VZ]; -	return *this; +    return *this;  } -LLVector3			LLVector3::scaledVec(const LLVector3& vec) const +LLVector3           LLVector3::scaledVec(const LLVector3& vec) const  { -	LLVector3 ret = LLVector3(*this); -	ret.scaleVec(vec); -	return ret; +    LLVector3 ret = LLVector3(*this); +    ret.scaleVec(vec); +    return ret;  } -const LLVector3&	LLVector3::set(const LLVector3d &vec) +const LLVector3&    LLVector3::set(const LLVector3d &vec)  { -	mV[0] = (F32)vec.mdV[0]; -	mV[1] = (F32)vec.mdV[1]; -	mV[2] = (F32)vec.mdV[2]; -	return (*this); +    mV[0] = (F32)vec.mdV[0]; +    mV[1] = (F32)vec.mdV[1]; +    mV[2] = (F32)vec.mdV[2]; +    return (*this);  } -const LLVector3&	LLVector3::set(const LLVector4 &vec) +const LLVector3&    LLVector3::set(const LLVector4 &vec)  { -	mV[0] = vec.mV[0]; -	mV[1] = vec.mV[1]; -	mV[2] = vec.mV[2]; -	return (*this); +    mV[0] = vec.mV[0]; +    mV[1] = vec.mV[1]; +    mV[2] = vec.mV[2]; +    return (*this);  } -const LLVector3&	LLVector3::setVec(const LLVector3d &vec) +const LLVector3&    LLVector3::setVec(const LLVector3d &vec)  { -	mV[0] = (F32)vec.mdV[0]; -	mV[1] = (F32)vec.mdV[1]; -	mV[2] = (F32)vec.mdV[2]; -	return (*this); +    mV[0] = (F32)vec.mdV[0]; +    mV[1] = (F32)vec.mdV[1]; +    mV[2] = (F32)vec.mdV[2]; +    return (*this);  } -const LLVector3&	LLVector3::setVec(const LLVector4 &vec) +const LLVector3&    LLVector3::setVec(const LLVector4 &vec)  { -	mV[0] = vec.mV[0]; -	mV[1] = vec.mV[1]; -	mV[2] = vec.mV[2]; -	return (*this); +    mV[0] = vec.mV[0]; +    mV[1] = vec.mV[1]; +    mV[2] = vec.mV[2]; +    return (*this);  }  LLVector3::LLVector3(const LLVector2 &vec)  { -	mV[VX] = (F32)vec.mV[VX]; -	mV[VY] = (F32)vec.mV[VY]; -	mV[VZ] = 0; +    mV[VX] = (F32)vec.mV[VX]; +    mV[VY] = (F32)vec.mV[VY]; +    mV[VZ] = 0;  }  LLVector3::LLVector3(const LLVector3d &vec)  { -	mV[VX] = (F32)vec.mdV[VX]; -	mV[VY] = (F32)vec.mdV[VY]; -	mV[VZ] = (F32)vec.mdV[VZ]; +    mV[VX] = (F32)vec.mdV[VX]; +    mV[VY] = (F32)vec.mdV[VY]; +    mV[VZ] = (F32)vec.mdV[VZ];  }  LLVector3::LLVector3(const LLVector4 &vec)  { -	mV[VX] = (F32)vec.mV[VX]; -	mV[VY] = (F32)vec.mV[VY]; -	mV[VZ] = (F32)vec.mV[VZ]; +    mV[VX] = (F32)vec.mV[VX]; +    mV[VY] = (F32)vec.mV[VY]; +    mV[VZ] = (F32)vec.mV[VZ];  }  LLVector3::LLVector3(const LLVector4a& vec) @@ -324,23 +324,23 @@ LLVector3::LLVector3(const LLVector4a& vec)  LLVector3::LLVector3(const LLSD& sd)  { -	setValue(sd); +    setValue(sd);  }  LLSD LLVector3::getValue() const  { -	LLSD ret; -	ret[0] = mV[0]; -	ret[1] = mV[1]; -	ret[2] = mV[2]; -	return ret; +    LLSD ret; +    ret[0] = mV[0]; +    ret[1] = mV[1]; +    ret[2] = mV[2]; +    return ret;  }  void LLVector3::setValue(const LLSD& sd)  { -	mV[0] = (F32) sd[0].asReal(); -	mV[1] = (F32) sd[1].asReal(); -	mV[2] = (F32) sd[2].asReal(); +    mV[0] = (F32) sd[0].asReal(); +    mV[1] = (F32) sd[1].asReal(); +    mV[2] = (F32) sd[2].asReal();  }  const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &rot) @@ -349,31 +349,31 @@ const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &rot)      const F32 rx =   rot.mQ[VW] * a.mV[VX] + rot.mQ[VY] * a.mV[VZ] - rot.mQ[VZ] * a.mV[VY];      const F32 ry =   rot.mQ[VW] * a.mV[VY] + rot.mQ[VZ] * a.mV[VX] - rot.mQ[VX] * a.mV[VZ];      const F32 rz =   rot.mQ[VW] * a.mV[VZ] + rot.mQ[VX] * a.mV[VY] - rot.mQ[VY] * a.mV[VX]; -	 +      a.mV[VX] = - rw * rot.mQ[VX] +  rx * rot.mQ[VW] - ry * rot.mQ[VZ] + rz * rot.mQ[VY];      a.mV[VY] = - rw * rot.mQ[VY] +  ry * rot.mQ[VW] - rz * rot.mQ[VX] + rx * rot.mQ[VZ];      a.mV[VZ] = - rw * rot.mQ[VZ] +  rz * rot.mQ[VW] - rx * rot.mQ[VY] + ry * rot.mQ[VX]; -	return a; +    return a;  } -// static  +// static  BOOL LLVector3::parseVector3(const std::string& buf, LLVector3* value)  { -	if( buf.empty() || value == NULL) -	{ -		return FALSE; -	} - -	LLVector3 v; -	S32 count = sscanf( buf.c_str(), "%f %f %f", v.mV + 0, v.mV + 1, v.mV + 2 ); -	if( 3 == count ) -	{ -		value->setVec( v ); -		return TRUE; -	} - -	return FALSE; +    if( buf.empty() || value == NULL) +    { +        return FALSE; +    } + +    LLVector3 v; +    S32 count = sscanf( buf.c_str(), "%f %f %f", v.mV + 0, v.mV + 1, v.mV + 2 ); +    if( 3 == count ) +    { +        value->setVec( v ); +        return TRUE; +    } + +    return FALSE;  }  // Displacement from query point to nearest neighbor point on bounding box. diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 068f489020..0f4a4a07ae 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -5,21 +5,21 @@   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -45,122 +45,122 @@ static const U32 LENGTHOFVECTOR3 = 3;  class LLVector3  { -	public: -		F32 mV[LENGTHOFVECTOR3]; - -		static const LLVector3 zero; -		static const LLVector3 x_axis; -		static const LLVector3 y_axis; -		static const LLVector3 z_axis; -		static const LLVector3 x_axis_neg; -		static const LLVector3 y_axis_neg; -		static const LLVector3 z_axis_neg; -		static const LLVector3 all_one; - -		inline LLVector3();							// Initializes LLVector3 to (0, 0, 0) -		inline LLVector3(const F32 x, const F32 y, const F32 z);			// Initializes LLVector3 to (x. y, z) -		inline explicit LLVector3(const F32 *vec);				// Initializes LLVector3 to (vec[0]. vec[1], vec[2]) -		explicit LLVector3(const LLVector2 &vec);				// Initializes LLVector3 to (vec[0]. vec[1], 0) -		explicit LLVector3(const LLVector3d &vec);				// Initializes LLVector3 to (vec[0]. vec[1], vec[2]) -		explicit LLVector3(const LLVector4 &vec);				// Initializes LLVector4 to (vec[0]. vec[1], vec[2]) +    public: +        F32 mV[LENGTHOFVECTOR3]; + +        static const LLVector3 zero; +        static const LLVector3 x_axis; +        static const LLVector3 y_axis; +        static const LLVector3 z_axis; +        static const LLVector3 x_axis_neg; +        static const LLVector3 y_axis_neg; +        static const LLVector3 z_axis_neg; +        static const LLVector3 all_one; + +        inline LLVector3();                         // Initializes LLVector3 to (0, 0, 0) +        inline LLVector3(const F32 x, const F32 y, const F32 z);            // Initializes LLVector3 to (x. y, z) +        inline explicit LLVector3(const F32 *vec);              // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) +        explicit LLVector3(const LLVector2 &vec);               // Initializes LLVector3 to (vec[0]. vec[1], 0) +        explicit LLVector3(const LLVector3d &vec);              // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) +        explicit LLVector3(const LLVector4 &vec);               // Initializes LLVector4 to (vec[0]. vec[1], vec[2])          explicit LLVector3(const LLVector4a& vec);              // Initializes LLVector4 to (vec[0]. vec[1], vec[2])          explicit LLVector3(const LLSD& sd); -         - -		LLSD getValue() const; - -		void setValue(const LLSD& sd); - -		inline BOOL isFinite() const;									// checks to see if all values of LLVector3 are finite -		BOOL		clamp(F32 min, F32 max);		// Clamps all values to (min,max), returns TRUE if data changed -		BOOL		clamp(const LLVector3 &min_vec, const LLVector3 &max_vec); // Scales vector by another vector -		BOOL		clampLength( F32 length_limit );					// Scales vector to limit length to a value - -		void		quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);	// changes the vector to reflect quatization -		void		quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);	// changes the vector to reflect quatization -		void 		snap(S32 sig_digits);											// snaps x,y,z to sig_digits decimal places - -		BOOL		abs();						// sets all values to absolute value of original value (first octant), returns TRUE if changed -		 -		inline void	clear();						// Clears LLVector3 to (0, 0, 0) -		inline void	setZero();						// Clears LLVector3 to (0, 0, 0) -		inline void	clearVec();						// deprecated -		inline void	zeroVec();						// deprecated - -		inline void	set(F32 x, F32 y, F32 z);		// Sets LLVector3 to (x, y, z, 1) -		inline void	set(const LLVector3 &vec);		// Sets LLVector3 to vec -		inline void	set(const F32 *vec);			// Sets LLVector3 to vec -		const LLVector3& set(const LLVector4 &vec); -		const LLVector3& set(const LLVector3d &vec);// Sets LLVector3 to vec - -		inline void	setVec(F32 x, F32 y, F32 z);	// deprecated -		inline void	setVec(const LLVector3 &vec);	// deprecated -		inline void	setVec(const F32 *vec);			// deprecated - -		const LLVector3& setVec(const LLVector4 &vec);  // deprecated -		const LLVector3& setVec(const LLVector3d &vec);	// deprecated - -		F32		length() const;			// Returns magnitude of LLVector3 -		F32		lengthSquared() const;	// Returns magnitude squared of LLVector3 -		F32		magVec() const;			// deprecated -		F32		magVecSquared() const;	// deprecated - -		inline F32		normalize();	// Normalizes and returns the magnitude of LLVector3 -		inline F32		normVec();		// deprecated - -		inline BOOL inRange( F32 min, F32 max ) const; // Returns true if all values of the vector are between min and max - -		const LLVector3&	rotVec(F32 angle, const LLVector3 &vec);	// Rotates about vec by angle radians -		const LLVector3&	rotVec(F32 angle, F32 x, F32 y, F32 z);		// Rotates about x,y,z by angle radians -		const LLVector3&	rotVec(const LLMatrix3 &mat);				// Rotates by LLMatrix4 mat -		const LLVector3&	rotVec(const LLQuaternion &q);				// Rotates by LLQuaternion q -		const LLVector3&	transVec(const LLMatrix4& mat);				// Transforms by LLMatrix4 mat (mat * v) - -		const LLVector3&	scaleVec(const LLVector3& vec);				// scales per component by vec -		LLVector3			scaledVec(const LLVector3& vec) const;			// get a copy of this vector scaled by vec - -		BOOL isNull() const;			// Returns TRUE if vector has a _very_small_ length -		BOOL isExactlyZero() const		{ return !mV[VX] && !mV[VY] && !mV[VZ]; } - -		F32 operator[](int idx) const { return mV[idx]; } -		F32 &operator[](int idx) { return mV[idx]; } -	 -		friend LLVector3 operator+(const LLVector3 &a, const LLVector3 &b);	// Return vector a + b -		friend LLVector3 operator-(const LLVector3 &a, const LLVector3 &b);	// Return vector a minus b -		friend F32 operator*(const LLVector3 &a, const LLVector3 &b);		// Return a dot b -		friend LLVector3 operator%(const LLVector3 &a, const LLVector3 &b);	// Return a cross b -		friend LLVector3 operator*(const LLVector3 &a, F32 k);				// Return a times scaler k -		friend LLVector3 operator/(const LLVector3 &a, F32 k);				// Return a divided by scaler k -		friend LLVector3 operator*(F32 k, const LLVector3 &a);				// Return a times scaler k -		friend bool operator==(const LLVector3 &a, const LLVector3 &b);		// Return a == b -		friend bool operator!=(const LLVector3 &a, const LLVector3 &b);		// Return a != b -		// less than operator useful for using vectors as std::map keys -		friend bool operator<(const LLVector3 &a, const LLVector3 &b);		// Return a < b - -		friend const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b);	// Return vector a + b -		friend const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b);	// Return vector a minus b -		friend const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b);	// Return a cross b -		friend const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b);	// Returns a * b; -		friend const LLVector3& operator*=(LLVector3 &a, F32 k);				// Return a times scaler k -		friend const LLVector3& operator/=(LLVector3 &a, F32 k);				// Return a divided by scaler k -		friend const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &b);	// Returns a * b; - -		friend LLVector3 operator-(const LLVector3 &a);					// Return vector -a - -		friend std::ostream&	 operator<<(std::ostream& s, const LLVector3 &a);		// Stream a - -		static BOOL parseVector3(const std::string& buf, LLVector3* value); + + +        LLSD getValue() const; + +        void setValue(const LLSD& sd); + +        inline BOOL isFinite() const;                                   // checks to see if all values of LLVector3 are finite +        BOOL        clamp(F32 min, F32 max);        // Clamps all values to (min,max), returns TRUE if data changed +        BOOL        clamp(const LLVector3 &min_vec, const LLVector3 &max_vec); // Scales vector by another vector +        BOOL        clampLength( F32 length_limit );                    // Scales vector to limit length to a value + +        void        quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);   // changes the vector to reflect quatization +        void        quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz);    // changes the vector to reflect quatization +        void        snap(S32 sig_digits);                                           // snaps x,y,z to sig_digits decimal places + +        BOOL        abs();                      // sets all values to absolute value of original value (first octant), returns TRUE if changed + +        inline void clear();                        // Clears LLVector3 to (0, 0, 0) +        inline void setZero();                      // Clears LLVector3 to (0, 0, 0) +        inline void clearVec();                     // deprecated +        inline void zeroVec();                      // deprecated + +        inline void set(F32 x, F32 y, F32 z);       // Sets LLVector3 to (x, y, z, 1) +        inline void set(const LLVector3 &vec);      // Sets LLVector3 to vec +        inline void set(const F32 *vec);            // Sets LLVector3 to vec +        const LLVector3& set(const LLVector4 &vec); +        const LLVector3& set(const LLVector3d &vec);// Sets LLVector3 to vec + +        inline void setVec(F32 x, F32 y, F32 z);    // deprecated +        inline void setVec(const LLVector3 &vec);   // deprecated +        inline void setVec(const F32 *vec);         // deprecated + +        const LLVector3& setVec(const LLVector4 &vec);  // deprecated +        const LLVector3& setVec(const LLVector3d &vec); // deprecated + +        F32     length() const;         // Returns magnitude of LLVector3 +        F32     lengthSquared() const;  // Returns magnitude squared of LLVector3 +        F32     magVec() const;         // deprecated +        F32     magVecSquared() const;  // deprecated + +        inline F32      normalize();    // Normalizes and returns the magnitude of LLVector3 +        inline F32      normVec();      // deprecated + +        inline BOOL inRange( F32 min, F32 max ) const; // Returns true if all values of the vector are between min and max + +        const LLVector3&    rotVec(F32 angle, const LLVector3 &vec);    // Rotates about vec by angle radians +        const LLVector3&    rotVec(F32 angle, F32 x, F32 y, F32 z);     // Rotates about x,y,z by angle radians +        const LLVector3&    rotVec(const LLMatrix3 &mat);               // Rotates by LLMatrix4 mat +        const LLVector3&    rotVec(const LLQuaternion &q);              // Rotates by LLQuaternion q +        const LLVector3&    transVec(const LLMatrix4& mat);             // Transforms by LLMatrix4 mat (mat * v) + +        const LLVector3&    scaleVec(const LLVector3& vec);             // scales per component by vec +        LLVector3           scaledVec(const LLVector3& vec) const;          // get a copy of this vector scaled by vec + +        BOOL isNull() const;            // Returns TRUE if vector has a _very_small_ length +        BOOL isExactlyZero() const      { return !mV[VX] && !mV[VY] && !mV[VZ]; } + +        F32 operator[](int idx) const { return mV[idx]; } +        F32 &operator[](int idx) { return mV[idx]; } + +        friend LLVector3 operator+(const LLVector3 &a, const LLVector3 &b); // Return vector a + b +        friend LLVector3 operator-(const LLVector3 &a, const LLVector3 &b); // Return vector a minus b +        friend F32 operator*(const LLVector3 &a, const LLVector3 &b);       // Return a dot b +        friend LLVector3 operator%(const LLVector3 &a, const LLVector3 &b); // Return a cross b +        friend LLVector3 operator*(const LLVector3 &a, F32 k);              // Return a times scaler k +        friend LLVector3 operator/(const LLVector3 &a, F32 k);              // Return a divided by scaler k +        friend LLVector3 operator*(F32 k, const LLVector3 &a);              // Return a times scaler k +        friend bool operator==(const LLVector3 &a, const LLVector3 &b);     // Return a == b +        friend bool operator!=(const LLVector3 &a, const LLVector3 &b);     // Return a != b +        // less than operator useful for using vectors as std::map keys +        friend bool operator<(const LLVector3 &a, const LLVector3 &b);      // Return a < b + +        friend const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b);   // Return vector a + b +        friend const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b);   // Return vector a minus b +        friend const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b);   // Return a cross b +        friend const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b);   // Returns a * b; +        friend const LLVector3& operator*=(LLVector3 &a, F32 k);                // Return a times scaler k +        friend const LLVector3& operator/=(LLVector3 &a, F32 k);                // Return a divided by scaler k +        friend const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &b);    // Returns a * b; + +        friend LLVector3 operator-(const LLVector3 &a);                 // Return vector -a + +        friend std::ostream&     operator<<(std::ostream& s, const LLVector3 &a);       // Stream a + +        static BOOL parseVector3(const std::string& buf, LLVector3* value);  };  typedef LLVector3 LLSimLocalVec; -// Non-member functions  +// Non-member functions -F32	angle_between(const LLVector3 &a, const LLVector3 &b);	// Returns angle (radians) between a and b -BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon=F_APPROXIMATELY_ZERO);	// Returns TRUE if a and b are very close to parallel -F32	dist_vec(const LLVector3 &a, const LLVector3 &b);		// Returns distance between a and b -F32	dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b -F32	dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b ignoring Z component +F32 angle_between(const LLVector3 &a, const LLVector3 &b);  // Returns angle (radians) between a and b +BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon=F_APPROXIMATELY_ZERO);    // Returns TRUE if a and b are very close to parallel +F32 dist_vec(const LLVector3 &a, const LLVector3 &b);       // Returns distance between a and b +F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b +F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b ignoring Z component  LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b  LLVector3 inverse_projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a scaled such that projected_vec(inverse_projected_vec(a, b), b) == b;  LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec) @@ -171,31 +171,31 @@ bool box_valid_and_non_zero(const LLVector3* box);  inline LLVector3::LLVector3(void)  { -	mV[0] = 0.f; -	mV[1] = 0.f; -	mV[2] = 0.f; +    mV[0] = 0.f; +    mV[1] = 0.f; +    mV[2] = 0.f;  }  inline LLVector3::LLVector3(const F32 x, const F32 y, const F32 z)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z;  }  inline LLVector3::LLVector3(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ];  }  /*  inline LLVector3::LLVector3(const LLVector3 ©)  { -	mV[VX] = copy.mV[VX]; -	mV[VY] = copy.mV[VY]; -	mV[VZ] = copy.mV[VZ]; +    mV[VX] = copy.mV[VX]; +    mV[VY] = copy.mV[VY]; +    mV[VZ] = copy.mV[VZ];  }  */ @@ -204,409 +204,409 @@ inline LLVector3::LLVector3(const LLVector3 ©)  // checker  inline BOOL LLVector3::isFinite() const  { -	return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ])); +    return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]));  }  // Clear and Assignment Functions -inline void	LLVector3::clear(void) +inline void LLVector3::clear(void)  { -	mV[0] = 0.f; -	mV[1] = 0.f; -	mV[2] = 0.f; +    mV[0] = 0.f; +    mV[1] = 0.f; +    mV[2] = 0.f;  } -inline void	LLVector3::setZero(void) +inline void LLVector3::setZero(void)  { -	mV[0] = 0.f; -	mV[1] = 0.f; -	mV[2] = 0.f; +    mV[0] = 0.f; +    mV[1] = 0.f; +    mV[2] = 0.f;  } -inline void	LLVector3::clearVec(void) +inline void LLVector3::clearVec(void)  { -	mV[0] = 0.f; -	mV[1] = 0.f; -	mV[2] = 0.f; +    mV[0] = 0.f; +    mV[1] = 0.f; +    mV[2] = 0.f;  } -inline void	LLVector3::zeroVec(void) +inline void LLVector3::zeroVec(void)  { -	mV[0] = 0.f; -	mV[1] = 0.f; -	mV[2] = 0.f; +    mV[0] = 0.f; +    mV[1] = 0.f; +    mV[2] = 0.f;  } -inline void	LLVector3::set(F32 x, F32 y, F32 z) +inline void LLVector3::set(F32 x, F32 y, F32 z)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z;  } -inline void	LLVector3::set(const LLVector3 &vec) +inline void LLVector3::set(const LLVector3 &vec)  { -	mV[0] = vec.mV[0]; -	mV[1] = vec.mV[1]; -	mV[2] = vec.mV[2]; +    mV[0] = vec.mV[0]; +    mV[1] = vec.mV[1]; +    mV[2] = vec.mV[2];  } -inline void	LLVector3::set(const F32 *vec) +inline void LLVector3::set(const F32 *vec)  { -	mV[0] = vec[0]; -	mV[1] = vec[1]; -	mV[2] = vec[2]; +    mV[0] = vec[0]; +    mV[1] = vec[1]; +    mV[2] = vec[2];  }  // deprecated -inline void	LLVector3::setVec(F32 x, F32 y, F32 z) +inline void LLVector3::setVec(F32 x, F32 y, F32 z)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z;  }  // deprecated -inline void	LLVector3::setVec(const LLVector3 &vec) +inline void LLVector3::setVec(const LLVector3 &vec)  { -	mV[0] = vec.mV[0]; -	mV[1] = vec.mV[1]; -	mV[2] = vec.mV[2]; +    mV[0] = vec.mV[0]; +    mV[1] = vec.mV[1]; +    mV[2] = vec.mV[2];  }  // deprecated -inline void	LLVector3::setVec(const F32 *vec) +inline void LLVector3::setVec(const F32 *vec)  { -	mV[0] = vec[0]; -	mV[1] = vec[1]; -	mV[2] = vec[2]; +    mV[0] = vec[0]; +    mV[1] = vec[1]; +    mV[2] = vec[2];  }  inline F32 LLVector3::normalize(void)  { -	F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); -	F32 oomag; - -	if (mag > FP_MAG_THRESHOLD) -	{ -		oomag = 1.f/mag; -		mV[0] *= oomag; -		mV[1] *= oomag; -		mV[2] *= oomag; -	} -	else -	{ -		mV[0] = 0.f; -		mV[1] = 0.f; -		mV[2] = 0.f; -		mag = 0; -	} -	return (mag); +    F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); +    F32 oomag; + +    if (mag > FP_MAG_THRESHOLD) +    { +        oomag = 1.f/mag; +        mV[0] *= oomag; +        mV[1] *= oomag; +        mV[2] *= oomag; +    } +    else +    { +        mV[0] = 0.f; +        mV[1] = 0.f; +        mV[2] = 0.f; +        mag = 0; +    } +    return (mag);  }  // deprecated  inline F32 LLVector3::normVec(void)  { -	F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); -	F32 oomag; - -	if (mag > FP_MAG_THRESHOLD) -	{ -		oomag = 1.f/mag; -		mV[0] *= oomag; -		mV[1] *= oomag; -		mV[2] *= oomag; -	} -	else -	{ -		mV[0] = 0.f; -		mV[1] = 0.f; -		mV[2] = 0.f; -		mag = 0; -	} -	return (mag); +    F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); +    F32 oomag; + +    if (mag > FP_MAG_THRESHOLD) +    { +        oomag = 1.f/mag; +        mV[0] *= oomag; +        mV[1] *= oomag; +        mV[2] *= oomag; +    } +    else +    { +        mV[0] = 0.f; +        mV[1] = 0.f; +        mV[2] = 0.f; +        mag = 0; +    } +    return (mag);  }  // LLVector3 Magnitude and Normalization Functions -inline F32	LLVector3::length(void) const +inline F32  LLVector3::length(void) const  { -	return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); +    return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);  } -inline F32	LLVector3::lengthSquared(void) const +inline F32  LLVector3::lengthSquared(void) const  { -	return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]; +    return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];  } -inline F32	LLVector3::magVec(void) const +inline F32  LLVector3::magVec(void) const  { -	return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); +    return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);  } -inline F32	LLVector3::magVecSquared(void) const +inline F32  LLVector3::magVecSquared(void) const  { -	return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]; +    return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];  }  inline BOOL LLVector3::inRange( F32 min, F32 max ) const  { -	return mV[0] >= min && mV[0] <= max && -		   mV[1] >= min && mV[1] <= max && -		   mV[2] >= min && mV[2] <= max;		 +    return mV[0] >= min && mV[0] <= max && +           mV[1] >= min && mV[1] <= max && +           mV[2] >= min && mV[2] <= max;  }  inline LLVector3 operator+(const LLVector3 &a, const LLVector3 &b)  { -	LLVector3 c(a); -	return c += b; +    LLVector3 c(a); +    return c += b;  }  inline LLVector3 operator-(const LLVector3 &a, const LLVector3 &b)  { -	LLVector3 c(a); -	return c -= b; +    LLVector3 c(a); +    return c -= b;  }  inline F32  operator*(const LLVector3 &a, const LLVector3 &b)  { -	return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]); +    return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]);  }  inline LLVector3 operator%(const LLVector3 &a, const LLVector3 &b)  { -	return LLVector3( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1] ); +    return LLVector3( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1] );  }  inline LLVector3 operator/(const LLVector3 &a, F32 k)  { -	F32 t = 1.f / k; -	return LLVector3( a.mV[0] * t, a.mV[1] * t, a.mV[2] * t ); +    F32 t = 1.f / k; +    return LLVector3( a.mV[0] * t, a.mV[1] * t, a.mV[2] * t );  }  inline LLVector3 operator*(const LLVector3 &a, F32 k)  { -	return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k ); +    return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );  }  inline LLVector3 operator*(F32 k, const LLVector3 &a)  { -	return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k ); +    return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );  }  inline bool operator==(const LLVector3 &a, const LLVector3 &b)  { -	return (  (a.mV[0] == b.mV[0]) -			&&(a.mV[1] == b.mV[1]) -			&&(a.mV[2] == b.mV[2])); +    return (  (a.mV[0] == b.mV[0]) +            &&(a.mV[1] == b.mV[1]) +            &&(a.mV[2] == b.mV[2]));  }  inline bool operator!=(const LLVector3 &a, const LLVector3 &b)  { -	return (  (a.mV[0] != b.mV[0]) -			||(a.mV[1] != b.mV[1]) -			||(a.mV[2] != b.mV[2])); +    return (  (a.mV[0] != b.mV[0]) +            ||(a.mV[1] != b.mV[1]) +            ||(a.mV[2] != b.mV[2]));  }  inline bool operator<(const LLVector3 &a, const LLVector3 &b)  { -	return (a.mV[0] < b.mV[0] -			|| (a.mV[0] == b.mV[0] -				&& (a.mV[1] < b.mV[1] -					|| ((a.mV[1] == b.mV[1]) -						&& a.mV[2] < b.mV[2])))); +    return (a.mV[0] < b.mV[0] +            || (a.mV[0] == b.mV[0] +                && (a.mV[1] < b.mV[1] +                    || ((a.mV[1] == b.mV[1]) +                        && a.mV[2] < b.mV[2]))));  }  inline const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b)  { -	a.mV[0] += b.mV[0]; -	a.mV[1] += b.mV[1]; -	a.mV[2] += b.mV[2]; -	return a; +    a.mV[0] += b.mV[0]; +    a.mV[1] += b.mV[1]; +    a.mV[2] += b.mV[2]; +    return a;  }  inline const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b)  { -	a.mV[0] -= b.mV[0]; -	a.mV[1] -= b.mV[1]; -	a.mV[2] -= b.mV[2]; -	return a; +    a.mV[0] -= b.mV[0]; +    a.mV[1] -= b.mV[1]; +    a.mV[2] -= b.mV[2]; +    return a;  }  inline const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b)  { -	LLVector3 ret( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1]); -	a = ret; -	return a; +    LLVector3 ret( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1]); +    a = ret; +    return a;  }  inline const LLVector3& operator*=(LLVector3 &a, F32 k)  { -	a.mV[0] *= k; -	a.mV[1] *= k; -	a.mV[2] *= k; -	return a; +    a.mV[0] *= k; +    a.mV[1] *= k; +    a.mV[2] *= k; +    return a;  }  inline const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b)  { -	a.mV[0] *= b.mV[0]; -	a.mV[1] *= b.mV[1]; -	a.mV[2] *= b.mV[2]; -	return a; +    a.mV[0] *= b.mV[0]; +    a.mV[1] *= b.mV[1]; +    a.mV[2] *= b.mV[2]; +    return a;  }  inline const LLVector3& operator/=(LLVector3 &a, F32 k)  { -	F32 t = 1.f / k; -	a.mV[0] *= t; -	a.mV[1] *= t; -	a.mV[2] *= t; -	return a; +    F32 t = 1.f / k; +    a.mV[0] *= t; +    a.mV[1] *= t; +    a.mV[2] *= t; +    return a;  }  inline LLVector3 operator-(const LLVector3 &a)  { -	return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] ); +    return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] );  } -inline F32	dist_vec(const LLVector3 &a, const LLVector3 &b) +inline F32  dist_vec(const LLVector3 &a, const LLVector3 &b)  { -	F32 x = a.mV[0] - b.mV[0]; -	F32 y = a.mV[1] - b.mV[1]; -	F32 z = a.mV[2] - b.mV[2]; -	return (F32) sqrt( x*x + y*y + z*z ); +    F32 x = a.mV[0] - b.mV[0]; +    F32 y = a.mV[1] - b.mV[1]; +    F32 z = a.mV[2] - b.mV[2]; +    return (F32) sqrt( x*x + y*y + z*z );  } -inline F32	dist_vec_squared(const LLVector3 &a, const LLVector3 &b) +inline F32  dist_vec_squared(const LLVector3 &a, const LLVector3 &b)  { -	F32 x = a.mV[0] - b.mV[0]; -	F32 y = a.mV[1] - b.mV[1]; -	F32 z = a.mV[2] - b.mV[2]; -	return x*x + y*y + z*z; +    F32 x = a.mV[0] - b.mV[0]; +    F32 y = a.mV[1] - b.mV[1]; +    F32 z = a.mV[2] - b.mV[2]; +    return x*x + y*y + z*z;  } -inline F32	dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b) +inline F32  dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b)  { -	F32 x = a.mV[0] - b.mV[0]; -	F32 y = a.mV[1] - b.mV[1]; -	return x*x + y*y; +    F32 x = a.mV[0] - b.mV[0]; +    F32 y = a.mV[1] - b.mV[1]; +    return x*x + y*y;  }  inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b)  { -	F32 bb = b * b; -	if (bb > FP_MAG_THRESHOLD * FP_MAG_THRESHOLD) -	{ -		return ((a * b) / bb) * b; -	} -	else -	{ -		return b.zero; -	} +    F32 bb = b * b; +    if (bb > FP_MAG_THRESHOLD * FP_MAG_THRESHOLD) +    { +        return ((a * b) / bb) * b; +    } +    else +    { +        return b.zero; +    }  }  inline LLVector3 inverse_projected_vec(const LLVector3& a, const LLVector3& b)  { -	LLVector3 normalized_a = a; -	normalized_a.normalize(); -	LLVector3 normalized_b = b; -	F32 b_length = normalized_b.normalize(); +    LLVector3 normalized_a = a; +    normalized_a.normalize(); +    LLVector3 normalized_b = b; +    F32 b_length = normalized_b.normalize(); -	F32 dot_product = normalized_a * normalized_b; -	//NB: if a _|_ b, then returns an infinite vector -	return normalized_a * (b_length / dot_product); +    F32 dot_product = normalized_a * normalized_b; +    //NB: if a _|_ b, then returns an infinite vector +    return normalized_a * (b_length / dot_product);  }  inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b)  { -	return projected_vec(a, b); +    return projected_vec(a, b);  }  inline LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b)  { -	return a - projected_vec(a, b); +    return a - projected_vec(a, b);  }  inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u)  { -	return LLVector3( -		a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, -		a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, -		a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u); +    return LLVector3( +        a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, +        a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, +        a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);  } -inline BOOL	LLVector3::isNull() const +inline BOOL LLVector3::isNull() const  { -	if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ] ) -	{ -		return TRUE; -	} -	return FALSE; +    if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ] ) +    { +        return TRUE; +    } +    return FALSE;  }  inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos)  { -	for (U32 i = 0; i < 3; i++) -	{ -		if (min.mV[i] > pos.mV[i]) -		{ -			min.mV[i] = pos.mV[i]; -		} -		if (max.mV[i] < pos.mV[i]) -		{ -			max.mV[i] = pos.mV[i]; -		} -	} +    for (U32 i = 0; i < 3; i++) +    { +        if (min.mV[i] > pos.mV[i]) +        { +            min.mV[i] = pos.mV[i]; +        } +        if (max.mV[i] < pos.mV[i]) +        { +            max.mV[i] = pos.mV[i]; +        } +    }  }  inline void update_min_max(LLVector3& min, LLVector3& max, const F32* pos)  { -	for (U32 i = 0; i < 3; i++) -	{ -		if (min.mV[i] > pos[i]) -		{ -			min.mV[i] = pos[i]; -		} -		if (max.mV[i] < pos[i]) -		{ -			max.mV[i] = pos[i]; -		} -	} +    for (U32 i = 0; i < 3; i++) +    { +        if (min.mV[i] > pos[i]) +        { +            min.mV[i] = pos[i]; +        } +        if (max.mV[i] < pos[i]) +        { +            max.mV[i] = pos[i]; +        } +    }  }  inline F32 angle_between(const LLVector3& a, const LLVector3& b)  { -	F32 ab = a * b; // dotproduct -	if (ab == -0.0f) -	{ -		ab = 0.0f; // get rid of negative zero -	} -	LLVector3 c = a % b; // crossproduct -	return atan2f(sqrtf(c * c), ab); // return the angle +    F32 ab = a * b; // dotproduct +    if (ab == -0.0f) +    { +        ab = 0.0f; // get rid of negative zero +    } +    LLVector3 c = a % b; // crossproduct +    return atan2f(sqrtf(c * c), ab); // return the angle  }  inline BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon)  { -	LLVector3 an = a; -	LLVector3 bn = b; -	an.normalize(); -	bn.normalize(); -	F32 dot = an * bn; -	if ( (1.0f - fabs(dot)) < epsilon) -	{ -		return TRUE; -	} -	return FALSE; +    LLVector3 an = a; +    LLVector3 bn = b; +    an.normalize(); +    bn.normalize(); +    F32 dot = an * bn; +    if ( (1.0f - fabs(dot)) < epsilon) +    { +        return TRUE; +    } +    return FALSE;  } -inline std::ostream& operator<<(std::ostream& s, const LLVector3 &a)  +inline std::ostream& operator<<(std::ostream& s, const LLVector3 &a)  { -	s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << " }"; -	return s; +    s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << " }"; +    return s;  }  #endif diff --git a/indra/llmath/v4color.cpp b/indra/llmath/v4color.cpp index a8768bda35..497281c27e 100644 --- a/indra/llmath/v4color.cpp +++ b/indra/llmath/v4color.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file v4color.cpp   * @brief LLColor4 class implementation.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -38,20 +38,20 @@  ////////////////////////////////////////////////////////////////////////////// -LLColor4 LLColor4::red(		1.f, 0.f, 0.f, 1.f); -LLColor4 LLColor4::green(	0.f, 1.f, 0.f, 1.f); -LLColor4 LLColor4::blue(	0.f, 0.f, 1.f, 1.f); -LLColor4 LLColor4::black(	0.f, 0.f, 0.f, 1.f); -LLColor4 LLColor4::yellow(	1.f, 1.f, 0.f, 1.f); +LLColor4 LLColor4::red(     1.f, 0.f, 0.f, 1.f); +LLColor4 LLColor4::green(   0.f, 1.f, 0.f, 1.f); +LLColor4 LLColor4::blue(    0.f, 0.f, 1.f, 1.f); +LLColor4 LLColor4::black(   0.f, 0.f, 0.f, 1.f); +LLColor4 LLColor4::yellow(  1.f, 1.f, 0.f, 1.f);  LLColor4 LLColor4::magenta( 1.0f, 0.0f, 1.0f, 1.0f); -LLColor4 LLColor4::cyan(	0.0f, 1.0f, 1.0f, 1.0f); -LLColor4 LLColor4::white(	1.f, 1.f, 1.f, 1.f); -LLColor4 LLColor4::smoke(	0.5f, 0.5f, 0.5f, 0.5f); -LLColor4 LLColor4::grey(	0.5f, 0.5f, 0.5f, 1.0f); -LLColor4 LLColor4::orange(	1.f, 0.5, 0.f, 1.f ); -LLColor4 LLColor4::purple(	0.6f, 0.2f, 0.8f, 1.0f); -LLColor4 LLColor4::pink(	1.0f, 0.5f, 0.8f, 1.0f); -LLColor4 LLColor4::transparent(	0.f, 0.f, 0.f, 0.f ); +LLColor4 LLColor4::cyan(    0.0f, 1.0f, 1.0f, 1.0f); +LLColor4 LLColor4::white(   1.f, 1.f, 1.f, 1.f); +LLColor4 LLColor4::smoke(   0.5f, 0.5f, 0.5f, 0.5f); +LLColor4 LLColor4::grey(    0.5f, 0.5f, 0.5f, 1.0f); +LLColor4 LLColor4::orange(  1.f, 0.5, 0.f, 1.f ); +LLColor4 LLColor4::purple(  0.6f, 0.2f, 0.8f, 1.0f); +LLColor4 LLColor4::pink(    1.0f, 0.5f, 0.8f, 1.0f); +LLColor4 LLColor4::transparent( 0.f, 0.f, 0.f, 0.f );  ////////////////////////////////////////////////////////////////////////////// @@ -124,615 +124,615 @@ LLColor4 LLColor4::cyan6(0.2f, 0.6f, 0.6f, 1.0f);  // conversion  LLColor4::operator LLColor4U() const  { -	return LLColor4U( -		(U8)llclampb(ll_round(mV[VRED]*255.f)), -		(U8)llclampb(ll_round(mV[VGREEN]*255.f)), -		(U8)llclampb(ll_round(mV[VBLUE]*255.f)), -		(U8)llclampb(ll_round(mV[VALPHA]*255.f))); +    return LLColor4U( +        (U8)llclampb(ll_round(mV[VRED]*255.f)), +        (U8)llclampb(ll_round(mV[VGREEN]*255.f)), +        (U8)llclampb(ll_round(mV[VBLUE]*255.f)), +        (U8)llclampb(ll_round(mV[VALPHA]*255.f)));  }  LLColor4::LLColor4(const LLColor3 &vec, F32 a)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = a; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = a;  }  LLColor4::LLColor4(const LLColor4U& color4u)  { -	const F32 SCALE = 1.f/255.f; -	mV[VX] = color4u.mV[VX] * SCALE; -	mV[VY] = color4u.mV[VY] * SCALE; -	mV[VZ] = color4u.mV[VZ] * SCALE; -	mV[VW] = color4u.mV[VW] * SCALE; +    const F32 SCALE = 1.f/255.f; +    mV[VX] = color4u.mV[VX] * SCALE; +    mV[VY] = color4u.mV[VY] * SCALE; +    mV[VZ] = color4u.mV[VZ] * SCALE; +    mV[VW] = color4u.mV[VW] * SCALE;  }  LLColor4::LLColor4(const LLVector4& vector4)  { -	mV[VX] = vector4.mV[VX]; -	mV[VY] = vector4.mV[VY]; -	mV[VZ] = vector4.mV[VZ]; -	mV[VW] = vector4.mV[VW]; +    mV[VX] = vector4.mV[VX]; +    mV[VY] = vector4.mV[VY]; +    mV[VZ] = vector4.mV[VZ]; +    mV[VW] = vector4.mV[VW];  } -const LLColor4&	LLColor4::set(const LLColor4U& color4u) +const LLColor4& LLColor4::set(const LLColor4U& color4u)  { -	const F32 SCALE = 1.f/255.f; -	mV[VX] = color4u.mV[VX] * SCALE; -	mV[VY] = color4u.mV[VY] * SCALE; -	mV[VZ] = color4u.mV[VZ] * SCALE; -	mV[VW] = color4u.mV[VW] * SCALE; -	return (*this); +    const F32 SCALE = 1.f/255.f; +    mV[VX] = color4u.mV[VX] * SCALE; +    mV[VY] = color4u.mV[VY] * SCALE; +    mV[VZ] = color4u.mV[VZ] * SCALE; +    mV[VW] = color4u.mV[VW] * SCALE; +    return (*this);  } -const LLColor4&	LLColor4::set(const LLColor3 &vec) +const LLColor4& LLColor4::set(const LLColor3 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ];  //  no change to alpha! -//	mV[VW] = 1.f;   +//  mV[VW] = 1.f; -	return (*this); +    return (*this);  } -const LLColor4&	LLColor4::set(const LLColor3 &vec, F32 a) +const LLColor4& LLColor4::set(const LLColor3 &vec, F32 a)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = a; -	return (*this); +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = a; +    return (*this);  }  // deprecated -- use set() -const LLColor4&	LLColor4::setVec(const LLColor4U& color4u) +const LLColor4& LLColor4::setVec(const LLColor4U& color4u)  { -	const F32 SCALE = 1.f/255.f; -	mV[VX] = color4u.mV[VX] * SCALE; -	mV[VY] = color4u.mV[VY] * SCALE; -	mV[VZ] = color4u.mV[VZ] * SCALE; -	mV[VW] = color4u.mV[VW] * SCALE; -	return (*this); +    const F32 SCALE = 1.f/255.f; +    mV[VX] = color4u.mV[VX] * SCALE; +    mV[VY] = color4u.mV[VY] * SCALE; +    mV[VZ] = color4u.mV[VZ] * SCALE; +    mV[VW] = color4u.mV[VW] * SCALE; +    return (*this);  }  // deprecated -- use set() -const LLColor4&	LLColor4::setVec(const LLColor3 &vec) +const LLColor4& LLColor4::setVec(const LLColor3 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ];  //  no change to alpha! -//	mV[VW] = 1.f;   +//  mV[VW] = 1.f; -	return (*this); +    return (*this);  }  // deprecated -- use set() -const LLColor4&	LLColor4::setVec(const LLColor3 &vec, F32 a) +const LLColor4& LLColor4::setVec(const LLColor3 &vec, F32 a)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = a; -	return (*this); +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = a; +    return (*this);  }  void LLColor4::setValue(const LLSD& sd)  {  #if 0 -	// Clamping on setValue from LLSD is inconsistent with other set behavior -	F32 val; -	bool out_of_range = false; -	val = sd[0].asReal(); -	mV[0] = llclamp(val, 0.f, 1.f); -	out_of_range = mV[0] != val; - -	val = sd[1].asReal(); -	mV[1] = llclamp(val, 0.f, 1.f); -	out_of_range |= mV[1] != val; - -	val = sd[2].asReal(); -	mV[2] = llclamp(val, 0.f, 1.f); -	out_of_range |= mV[2] != val; - -	val = sd[3].asReal(); -	mV[3] = llclamp(val, 0.f, 1.f); -	out_of_range |= mV[3] != val; - -	if (out_of_range) -	{ -		LL_WARNS() << "LLSD color value out of range!" << LL_ENDL; -	} +    // Clamping on setValue from LLSD is inconsistent with other set behavior +    F32 val; +    bool out_of_range = false; +    val = sd[0].asReal(); +    mV[0] = llclamp(val, 0.f, 1.f); +    out_of_range = mV[0] != val; + +    val = sd[1].asReal(); +    mV[1] = llclamp(val, 0.f, 1.f); +    out_of_range |= mV[1] != val; + +    val = sd[2].asReal(); +    mV[2] = llclamp(val, 0.f, 1.f); +    out_of_range |= mV[2] != val; + +    val = sd[3].asReal(); +    mV[3] = llclamp(val, 0.f, 1.f); +    out_of_range |= mV[3] != val; + +    if (out_of_range) +    { +        LL_WARNS() << "LLSD color value out of range!" << LL_ENDL; +    }  #else -	mV[0] = (F32) sd[0].asReal(); -	mV[1] = (F32) sd[1].asReal(); -	mV[2] = (F32) sd[2].asReal(); -	mV[3] = (F32) sd[3].asReal(); +    mV[0] = (F32) sd[0].asReal(); +    mV[1] = (F32) sd[1].asReal(); +    mV[2] = (F32) sd[2].asReal(); +    mV[3] = (F32) sd[3].asReal();  #endif  }  const LLColor4& LLColor4::operator=(const LLColor3 &a)  { -	mV[VX] = a.mV[VX]; -	mV[VY] = a.mV[VY]; -	mV[VZ] = a.mV[VZ]; +    mV[VX] = a.mV[VX]; +    mV[VY] = a.mV[VY]; +    mV[VZ] = a.mV[VZ];  // converting from an rgb sets a=1 (opaque) -	mV[VW] = 1.f; -	return (*this); +    mV[VW] = 1.f; +    return (*this);  } -std::ostream& operator<<(std::ostream& s, const LLColor4 &a)  +std::ostream& operator<<(std::ostream& s, const LLColor4 &a)  { -	s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << ", " << a.mV[VW] << " }"; -	return s; +    s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << ", " << a.mV[VW] << " }"; +    return s;  }  bool operator==(const LLColor4 &a, const LLColor3 &b)  { -	return (  (a.mV[VX] == b.mV[VX]) -			&&(a.mV[VY] == b.mV[VY]) -			&&(a.mV[VZ] == b.mV[VZ])); +    return (  (a.mV[VX] == b.mV[VX]) +            &&(a.mV[VY] == b.mV[VY]) +            &&(a.mV[VZ] == b.mV[VZ]));  }  bool operator!=(const LLColor4 &a, const LLColor3 &b)  { -	return (  (a.mV[VX] != b.mV[VX]) -			||(a.mV[VY] != b.mV[VY]) -			||(a.mV[VZ] != b.mV[VZ])); +    return (  (a.mV[VX] != b.mV[VX]) +            ||(a.mV[VY] != b.mV[VY]) +            ||(a.mV[VZ] != b.mV[VZ]));  } -LLColor3	vec4to3(const LLColor4 &vec) +LLColor3    vec4to3(const LLColor4 &vec)  { -	LLColor3	temp(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); -	return temp; +    LLColor3    temp(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); +    return temp;  } -LLColor4	vec3to4(const LLColor3 &vec) +LLColor4    vec3to4(const LLColor3 &vec)  { -	LLColor3	temp(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); -	return temp; +    LLColor3    temp(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); +    return temp;  }  static F32 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )  { -	if ( valHUeIn < 0.0f ) valHUeIn += 1.0f; -	if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f; -	if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn ); -	if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In ); -	if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f ); -	return ( val1In ); +    if ( valHUeIn < 0.0f ) valHUeIn += 1.0f; +    if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f; +    if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn ); +    if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In ); +    if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f ); +    return ( val1In );  }  void LLColor4::setHSL ( F32 hValIn, F32 sValIn, F32 lValIn)  { -	if ( sValIn < 0.00001f ) -	{ -		mV[VRED] = lValIn; -		mV[VGREEN] = lValIn; -		mV[VBLUE] = lValIn; -	} -	else -	{ -		F32 interVal1; -		F32 interVal2; - -		if ( lValIn < 0.5f ) -			interVal2 = lValIn * ( 1.0f + sValIn ); -		else -			interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn ); - -		interVal1 = 2.0f * lValIn - interVal2; - -		mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) ); -		mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn ); -		mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) ); -	} +    if ( sValIn < 0.00001f ) +    { +        mV[VRED] = lValIn; +        mV[VGREEN] = lValIn; +        mV[VBLUE] = lValIn; +    } +    else +    { +        F32 interVal1; +        F32 interVal2; + +        if ( lValIn < 0.5f ) +            interVal2 = lValIn * ( 1.0f + sValIn ); +        else +            interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn ); + +        interVal1 = 2.0f * lValIn - interVal2; + +        mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) ); +        mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn ); +        mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) ); +    }  }  void LLColor4::calcHSL(F32* hue, F32* saturation, F32* luminance) const  { -	F32 var_R = mV[VRED]; -	F32 var_G = mV[VGREEN]; -	F32 var_B = mV[VBLUE]; - -	F32 var_Min = ( var_R < ( var_G < var_B ? var_G : var_B ) ? var_R : ( var_G < var_B ? var_G : var_B ) ); -	F32 var_Max = ( var_R > ( var_G > var_B ? var_G : var_B ) ? var_R : ( var_G > var_B ? var_G : var_B ) ); - -	F32 del_Max = var_Max - var_Min; - -	F32 L = ( var_Max + var_Min ) / 2.0f; -	F32 H = 0.0f; -	F32 S = 0.0f; - -	if ( del_Max == 0.0f ) -	{ -	   H = 0.0f; -	   S = 0.0f; -	} -	else -	{ -		if ( L < 0.5 ) -			S = del_Max / ( var_Max + var_Min ); -		else -			S = del_Max / ( 2.0f - var_Max - var_Min ); - -		F32 del_R = ( ( ( var_Max - var_R ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; -		F32 del_G = ( ( ( var_Max - var_G ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; -		F32 del_B = ( ( ( var_Max - var_B ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; - -		if ( var_R >= var_Max ) -			H = del_B - del_G; -		else -		if ( var_G >= var_Max ) -			H = ( 1.0f / 3.0f ) + del_R - del_B; -		else -		if ( var_B >= var_Max ) -			H = ( 2.0f / 3.0f ) + del_G - del_R; - -		if ( H < 0.0f ) H += 1.0f; -		if ( H > 1.0f ) H -= 1.0f; -	} - -	if (hue) *hue = H; -	if (saturation) *saturation = S; -	if (luminance) *luminance = L; +    F32 var_R = mV[VRED]; +    F32 var_G = mV[VGREEN]; +    F32 var_B = mV[VBLUE]; + +    F32 var_Min = ( var_R < ( var_G < var_B ? var_G : var_B ) ? var_R : ( var_G < var_B ? var_G : var_B ) ); +    F32 var_Max = ( var_R > ( var_G > var_B ? var_G : var_B ) ? var_R : ( var_G > var_B ? var_G : var_B ) ); + +    F32 del_Max = var_Max - var_Min; + +    F32 L = ( var_Max + var_Min ) / 2.0f; +    F32 H = 0.0f; +    F32 S = 0.0f; + +    if ( del_Max == 0.0f ) +    { +       H = 0.0f; +       S = 0.0f; +    } +    else +    { +        if ( L < 0.5 ) +            S = del_Max / ( var_Max + var_Min ); +        else +            S = del_Max / ( 2.0f - var_Max - var_Min ); + +        F32 del_R = ( ( ( var_Max - var_R ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; +        F32 del_G = ( ( ( var_Max - var_G ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; +        F32 del_B = ( ( ( var_Max - var_B ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; + +        if ( var_R >= var_Max ) +            H = del_B - del_G; +        else +        if ( var_G >= var_Max ) +            H = ( 1.0f / 3.0f ) + del_R - del_B; +        else +        if ( var_B >= var_Max ) +            H = ( 2.0f / 3.0f ) + del_G - del_R; + +        if ( H < 0.0f ) H += 1.0f; +        if ( H > 1.0f ) H -= 1.0f; +    } + +    if (hue) *hue = H; +    if (saturation) *saturation = S; +    if (luminance) *luminance = L;  }  // static  BOOL LLColor4::parseColor(const std::string& buf, LLColor4* color)  { -	if( buf.empty() || color == NULL) -	{ -		return FALSE; -	} - -	boost_tokenizer tokens(buf, boost::char_separator<char>(", ")); -	boost_tokenizer::iterator token_iter = tokens.begin(); -	if (token_iter == tokens.end()) -	{ -		return FALSE; -	} - -	// Grab the first token into a string, since we don't know -	// if this is a float or a color name. -	std::string color_name( (*token_iter) ); -	++token_iter; - -	if (token_iter != tokens.end()) -	{ -		// There are more tokens to read.  This must be a vector. -		LLColor4 v; -		LLStringUtil::convertToF32( color_name,  v.mV[VX] ); -		LLStringUtil::convertToF32( *token_iter, v.mV[VY] ); -		v.mV[VZ] = 0.0f; -		v.mV[VW] = 1.0f; - -		++token_iter; -		if (token_iter == tokens.end()) -		{ -			// This is a malformed vector. -			LL_WARNS() << "LLColor4::parseColor() malformed color " << buf << LL_ENDL; -		} -		else -		{ -			// There is a z-component. -			LLStringUtil::convertToF32( *token_iter, v.mV[VZ] ); - -			++token_iter; -			if (token_iter != tokens.end()) -			{ -				// There is an alpha component. -				LLStringUtil::convertToF32( *token_iter, v.mV[VW] ); -			} -		} - -		//  Make sure all values are between 0 and 1. -		if (v.mV[VX] > 1.f || v.mV[VY] > 1.f || v.mV[VZ] > 1.f || v.mV[VW] > 1.f) -		{ -			v = v * (1.f / 255.f); -		} -		color->set( v ); -	} -	else // Single value.  Read as a named color. -	{ -		// We have a color name -		if ( "red" == color_name ) -		{ -			color->set(LLColor4::red); -		} -		else if ( "red1" == color_name ) -		{ -			color->set(LLColor4::red1); -		} -		else if ( "red2" == color_name ) -		{ -			color->set(LLColor4::red2); -		} -		else if ( "red3" == color_name ) -		{ -			color->set(LLColor4::red3); -		} -		else if ( "red4" == color_name ) -		{ -			color->set(LLColor4::red4); -		} -		else if ( "red5" == color_name ) -		{ -			color->set(LLColor4::red5); -		} -		else if( "green" == color_name ) -		{ -			color->set(LLColor4::green); -		} -		else if( "green1" == color_name ) -		{ -			color->set(LLColor4::green1); -		} -		else if( "green2" == color_name ) -		{ -			color->set(LLColor4::green2); -		} -		else if( "green3" == color_name ) -		{ -			color->set(LLColor4::green3); -		} -		else if( "green4" == color_name ) -		{ -			color->set(LLColor4::green4); -		} -		else if( "green5" == color_name ) -		{ -			color->set(LLColor4::green5); -		} -		else if( "green6" == color_name ) -		{ -			color->set(LLColor4::green6); -		} -		else if( "blue" == color_name ) -		{ -			color->set(LLColor4::blue); -		} -		else if( "blue1" == color_name ) -		{ -			color->set(LLColor4::blue1); -		} -		else if( "blue2" == color_name ) -		{ -			color->set(LLColor4::blue2); -		} -		else if( "blue3" == color_name ) -		{ -			color->set(LLColor4::blue3); -		} -		else if( "blue4" == color_name ) -		{ -			color->set(LLColor4::blue4); -		} -		else if( "blue5" == color_name ) -		{ -			color->set(LLColor4::blue5); -		} -		else if( "blue6" == color_name ) -		{ -			color->set(LLColor4::blue6); -		} -		else if( "black" == color_name ) -		{ -			color->set(LLColor4::black); -		} -		else if( "white" == color_name ) -		{ -			color->set(LLColor4::white); -		} -		else if( "yellow" == color_name ) -		{ -			color->set(LLColor4::yellow); -		} -		else if( "yellow1" == color_name ) -		{ -			color->set(LLColor4::yellow1); -		} -		else if( "yellow2" == color_name ) -		{ -			color->set(LLColor4::yellow2); -		} -		else if( "yellow3" == color_name ) -		{ -			color->set(LLColor4::yellow3); -		} -		else if( "yellow4" == color_name ) -		{ -			color->set(LLColor4::yellow4); -		} -		else if( "yellow5" == color_name ) -		{ -			color->set(LLColor4::yellow5); -		} -		else if( "yellow6" == color_name ) -		{ -			color->set(LLColor4::yellow6); -		} -		else if( "magenta" == color_name ) -		{ -			color->set(LLColor4::magenta); -		} -		else if( "magenta1" == color_name ) -		{ -			color->set(LLColor4::magenta1); -		} -		else if( "magenta2" == color_name ) -		{ -			color->set(LLColor4::magenta2); -		} -		else if( "magenta3" == color_name ) -		{ -			color->set(LLColor4::magenta3); -		} -		else if( "magenta4" == color_name ) -		{ -			color->set(LLColor4::magenta4); -		} -		else if( "purple" == color_name ) -		{ -			color->set(LLColor4::purple); -		} -		else if( "purple1" == color_name ) -		{ -			color->set(LLColor4::purple1); -		} -		else if( "purple2" == color_name ) -		{ -			color->set(LLColor4::purple2); -		} -		else if( "purple3" == color_name ) -		{ -			color->set(LLColor4::purple3); -		} -		else if( "purple4" == color_name ) -		{ -			color->set(LLColor4::purple4); -		} -		else if( "purple5" == color_name ) -		{ -			color->set(LLColor4::purple5); -		} -		else if( "purple6" == color_name ) -		{ -			color->set(LLColor4::purple6); -		} -		else if( "pink" == color_name ) -		{ -			color->set(LLColor4::pink); -		} -		else if( "pink1" == color_name ) -		{ -			color->set(LLColor4::pink1); -		} -		else if( "pink2" == color_name ) -		{ -			color->set(LLColor4::pink2); -		} -		else if( "cyan" == color_name ) -		{ -			color->set(LLColor4::cyan); -		} -		else if( "cyan1" == color_name ) -		{ -			color->set(LLColor4::cyan1); -		} -		else if( "cyan2" == color_name ) -		{ -			color->set(LLColor4::cyan2); -		} -		else if( "cyan3" == color_name ) -		{ -			color->set(LLColor4::cyan3); -		} -		else if( "cyan4" == color_name ) -		{ -			color->set(LLColor4::cyan4); -		} -		else if( "cyan5" == color_name ) -		{ -			color->set(LLColor4::cyan5); -		} -		else if( "cyan6" == color_name ) -		{ -			color->set(LLColor4::cyan6); -		} -		else if( "smoke" == color_name ) -		{ -			color->set(LLColor4::smoke); -		} -		else if( "grey" == color_name ) -		{ -			color->set(LLColor4::grey); -		} -		else if( "grey1" == color_name ) -		{ -			color->set(LLColor4::grey1); -		} -		else if( "grey2" == color_name ) -		{ -			color->set(LLColor4::grey2); -		} -		else if( "grey3" == color_name ) -		{ -			color->set(LLColor4::grey3); -		} -		else if( "grey4" == color_name ) -		{ -			color->set(LLColor4::grey4); -		} -		else if( "orange" == color_name ) -		{ -			color->set(LLColor4::orange); -		} -		else if( "orange1" == color_name ) -		{ -			color->set(LLColor4::orange1); -		} -		else if( "orange2" == color_name ) -		{ -			color->set(LLColor4::orange2); -		} -		else if( "orange3" == color_name ) -		{ -			color->set(LLColor4::orange3); -		} -		else if( "orange4" == color_name ) -		{ -			color->set(LLColor4::orange4); -		} -		else if( "orange5" == color_name ) -		{ -			color->set(LLColor4::orange5); -		} -		else if( "orange6" == color_name ) -		{ -			color->set(LLColor4::orange6); -		} -		else if ( "clear" == color_name ) -		{ -			color->set(0.f, 0.f, 0.f, 0.f); -		} -		else -		{ -			LL_WARNS() << "invalid color " << color_name << LL_ENDL; -		} -	} - -	return TRUE; +    if( buf.empty() || color == NULL) +    { +        return FALSE; +    } + +    boost_tokenizer tokens(buf, boost::char_separator<char>(", ")); +    boost_tokenizer::iterator token_iter = tokens.begin(); +    if (token_iter == tokens.end()) +    { +        return FALSE; +    } + +    // Grab the first token into a string, since we don't know +    // if this is a float or a color name. +    std::string color_name( (*token_iter) ); +    ++token_iter; + +    if (token_iter != tokens.end()) +    { +        // There are more tokens to read.  This must be a vector. +        LLColor4 v; +        LLStringUtil::convertToF32( color_name,  v.mV[VX] ); +        LLStringUtil::convertToF32( *token_iter, v.mV[VY] ); +        v.mV[VZ] = 0.0f; +        v.mV[VW] = 1.0f; + +        ++token_iter; +        if (token_iter == tokens.end()) +        { +            // This is a malformed vector. +            LL_WARNS() << "LLColor4::parseColor() malformed color " << buf << LL_ENDL; +        } +        else +        { +            // There is a z-component. +            LLStringUtil::convertToF32( *token_iter, v.mV[VZ] ); + +            ++token_iter; +            if (token_iter != tokens.end()) +            { +                // There is an alpha component. +                LLStringUtil::convertToF32( *token_iter, v.mV[VW] ); +            } +        } + +        //  Make sure all values are between 0 and 1. +        if (v.mV[VX] > 1.f || v.mV[VY] > 1.f || v.mV[VZ] > 1.f || v.mV[VW] > 1.f) +        { +            v = v * (1.f / 255.f); +        } +        color->set( v ); +    } +    else // Single value.  Read as a named color. +    { +        // We have a color name +        if ( "red" == color_name ) +        { +            color->set(LLColor4::red); +        } +        else if ( "red1" == color_name ) +        { +            color->set(LLColor4::red1); +        } +        else if ( "red2" == color_name ) +        { +            color->set(LLColor4::red2); +        } +        else if ( "red3" == color_name ) +        { +            color->set(LLColor4::red3); +        } +        else if ( "red4" == color_name ) +        { +            color->set(LLColor4::red4); +        } +        else if ( "red5" == color_name ) +        { +            color->set(LLColor4::red5); +        } +        else if( "green" == color_name ) +        { +            color->set(LLColor4::green); +        } +        else if( "green1" == color_name ) +        { +            color->set(LLColor4::green1); +        } +        else if( "green2" == color_name ) +        { +            color->set(LLColor4::green2); +        } +        else if( "green3" == color_name ) +        { +            color->set(LLColor4::green3); +        } +        else if( "green4" == color_name ) +        { +            color->set(LLColor4::green4); +        } +        else if( "green5" == color_name ) +        { +            color->set(LLColor4::green5); +        } +        else if( "green6" == color_name ) +        { +            color->set(LLColor4::green6); +        } +        else if( "blue" == color_name ) +        { +            color->set(LLColor4::blue); +        } +        else if( "blue1" == color_name ) +        { +            color->set(LLColor4::blue1); +        } +        else if( "blue2" == color_name ) +        { +            color->set(LLColor4::blue2); +        } +        else if( "blue3" == color_name ) +        { +            color->set(LLColor4::blue3); +        } +        else if( "blue4" == color_name ) +        { +            color->set(LLColor4::blue4); +        } +        else if( "blue5" == color_name ) +        { +            color->set(LLColor4::blue5); +        } +        else if( "blue6" == color_name ) +        { +            color->set(LLColor4::blue6); +        } +        else if( "black" == color_name ) +        { +            color->set(LLColor4::black); +        } +        else if( "white" == color_name ) +        { +            color->set(LLColor4::white); +        } +        else if( "yellow" == color_name ) +        { +            color->set(LLColor4::yellow); +        } +        else if( "yellow1" == color_name ) +        { +            color->set(LLColor4::yellow1); +        } +        else if( "yellow2" == color_name ) +        { +            color->set(LLColor4::yellow2); +        } +        else if( "yellow3" == color_name ) +        { +            color->set(LLColor4::yellow3); +        } +        else if( "yellow4" == color_name ) +        { +            color->set(LLColor4::yellow4); +        } +        else if( "yellow5" == color_name ) +        { +            color->set(LLColor4::yellow5); +        } +        else if( "yellow6" == color_name ) +        { +            color->set(LLColor4::yellow6); +        } +        else if( "magenta" == color_name ) +        { +            color->set(LLColor4::magenta); +        } +        else if( "magenta1" == color_name ) +        { +            color->set(LLColor4::magenta1); +        } +        else if( "magenta2" == color_name ) +        { +            color->set(LLColor4::magenta2); +        } +        else if( "magenta3" == color_name ) +        { +            color->set(LLColor4::magenta3); +        } +        else if( "magenta4" == color_name ) +        { +            color->set(LLColor4::magenta4); +        } +        else if( "purple" == color_name ) +        { +            color->set(LLColor4::purple); +        } +        else if( "purple1" == color_name ) +        { +            color->set(LLColor4::purple1); +        } +        else if( "purple2" == color_name ) +        { +            color->set(LLColor4::purple2); +        } +        else if( "purple3" == color_name ) +        { +            color->set(LLColor4::purple3); +        } +        else if( "purple4" == color_name ) +        { +            color->set(LLColor4::purple4); +        } +        else if( "purple5" == color_name ) +        { +            color->set(LLColor4::purple5); +        } +        else if( "purple6" == color_name ) +        { +            color->set(LLColor4::purple6); +        } +        else if( "pink" == color_name ) +        { +            color->set(LLColor4::pink); +        } +        else if( "pink1" == color_name ) +        { +            color->set(LLColor4::pink1); +        } +        else if( "pink2" == color_name ) +        { +            color->set(LLColor4::pink2); +        } +        else if( "cyan" == color_name ) +        { +            color->set(LLColor4::cyan); +        } +        else if( "cyan1" == color_name ) +        { +            color->set(LLColor4::cyan1); +        } +        else if( "cyan2" == color_name ) +        { +            color->set(LLColor4::cyan2); +        } +        else if( "cyan3" == color_name ) +        { +            color->set(LLColor4::cyan3); +        } +        else if( "cyan4" == color_name ) +        { +            color->set(LLColor4::cyan4); +        } +        else if( "cyan5" == color_name ) +        { +            color->set(LLColor4::cyan5); +        } +        else if( "cyan6" == color_name ) +        { +            color->set(LLColor4::cyan6); +        } +        else if( "smoke" == color_name ) +        { +            color->set(LLColor4::smoke); +        } +        else if( "grey" == color_name ) +        { +            color->set(LLColor4::grey); +        } +        else if( "grey1" == color_name ) +        { +            color->set(LLColor4::grey1); +        } +        else if( "grey2" == color_name ) +        { +            color->set(LLColor4::grey2); +        } +        else if( "grey3" == color_name ) +        { +            color->set(LLColor4::grey3); +        } +        else if( "grey4" == color_name ) +        { +            color->set(LLColor4::grey4); +        } +        else if( "orange" == color_name ) +        { +            color->set(LLColor4::orange); +        } +        else if( "orange1" == color_name ) +        { +            color->set(LLColor4::orange1); +        } +        else if( "orange2" == color_name ) +        { +            color->set(LLColor4::orange2); +        } +        else if( "orange3" == color_name ) +        { +            color->set(LLColor4::orange3); +        } +        else if( "orange4" == color_name ) +        { +            color->set(LLColor4::orange4); +        } +        else if( "orange5" == color_name ) +        { +            color->set(LLColor4::orange5); +        } +        else if( "orange6" == color_name ) +        { +            color->set(LLColor4::orange6); +        } +        else if ( "clear" == color_name ) +        { +            color->set(0.f, 0.f, 0.f, 0.f); +        } +        else +        { +            LL_WARNS() << "invalid color " << color_name << LL_ENDL; +        } +    } + +    return TRUE;  }  // static  BOOL LLColor4::parseColor4(const std::string& buf, LLColor4* value)  { -	if( buf.empty() || value == NULL) -	{ -		return FALSE; -	} - -	LLColor4 v; -	S32 count = sscanf( buf.c_str(), "%f, %f, %f, %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 ); -	if (1 == count ) -	{ -		// try this format -		count = sscanf( buf.c_str(), "%f %f %f %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 ); -	} -	if( 4 == count ) -	{ -		value->setVec( v ); -		return TRUE; -	} - -	return FALSE; +    if( buf.empty() || value == NULL) +    { +        return FALSE; +    } + +    LLColor4 v; +    S32 count = sscanf( buf.c_str(), "%f, %f, %f, %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 ); +    if (1 == count ) +    { +        // try this format +        count = sscanf( buf.c_str(), "%f %f %f %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 ); +    } +    if( 4 == count ) +    { +        value->setVec( v ); +        return TRUE; +    } + +    return FALSE;  }  // EOF diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index daa61594fb..3168c8b43a 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -1,25 +1,25 @@ -/**  +/**   * @file v4color.h   * @brief LLColor4 class header file.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -44,56 +44,56 @@ static const U32 MAX_LENGTH_OF_COLOR_NAME = 15; //Give plenty of room for additi  class LLColor4  { -	public: -		F32 mV[LENGTHOFCOLOR4]; -		LLColor4();						// Initializes LLColor4 to (0, 0, 0, 1) -		LLColor4(F32 r, F32 g, F32 b);		// Initializes LLColor4 to (r, g, b, 1) -		LLColor4(F32 r, F32 g, F32 b, F32 a);		// Initializes LLColor4 to (r. g, b, a) -		LLColor4(const LLColor3 &vec, F32 a = 1.f);	// Initializes LLColor4 to (vec, a) -		explicit LLColor4(const LLSD& sd); -		explicit LLColor4(const F32 *vec);			// Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1) -		explicit LLColor4(U32 clr);							// Initializes LLColor4 to (r=clr>>24, etc)) -		explicit LLColor4(const LLColor4U& color4u);  // "explicit" to avoid automatic conversion -		explicit LLColor4(const LLVector4& vector4);  // "explicit" to avoid automatic conversion - -		LLSD getValue() const -		{ -			LLSD ret; -			ret[0] = mV[0]; -			ret[1] = mV[1]; -			ret[2] = mV[2]; -			ret[3] = mV[3]; -			return ret; -		} -	 -		void setValue(const LLSD& sd); - -		void setHSL(F32 hue, F32 saturation, F32 luminance); -		void calcHSL(F32* hue, F32* saturation, F32* luminance) const; - -		const LLColor4&	setToBlack();						// zero LLColor4 to (0, 0, 0, 1) -		const LLColor4&	setToWhite();						// zero LLColor4 to (0, 0, 0, 1) - -		const LLColor4&	setVec(F32 r, F32 g, F32 b, F32 a);	// deprecated -- use set() -		const LLColor4&	setVec(F32 r, F32 g, F32 b);		// deprecated -- use set() -		const LLColor4&	setVec(const LLColor4 &vec);		// deprecated -- use set() -		const LLColor4&	setVec(const LLColor3 &vec);		// deprecated -- use set() -		const LLColor4&	setVec(const LLColor3 &vec, F32 a);	// deprecated -- use set() -		const LLColor4&	setVec(const F32 *vec);				// deprecated -- use set() -		const LLColor4&	setVec(const LLColor4U& color4u); 	// deprecated -- use set() - -		const LLColor4&	set(F32 r, F32 g, F32 b, F32 a);	// Sets LLColor4 to (r, g, b, a) -		const LLColor4&	set(F32 r, F32 g, F32 b);	// Sets LLColor4 to (r, g, b) (no change in a) -		const LLColor4&	set(const LLColor4 &vec);	// Sets LLColor4 to vec -		const LLColor4&	set(const LLColor3 &vec);	// Sets LLColor4 to LLColor3 vec (no change in alpha) -		const LLColor4&	set(const LLColor3 &vec, F32 a);	// Sets LLColor4 to LLColor3 vec, with alpha specified -		const LLColor4&	set(const F32 *vec);			// Sets LLColor4 to vec -        const LLColor4&	set(const F64 *vec);			// Sets LLColor4 to (double)vec -        const LLColor4&	set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled. +    public: +        F32 mV[LENGTHOFCOLOR4]; +        LLColor4();                     // Initializes LLColor4 to (0, 0, 0, 1) +        LLColor4(F32 r, F32 g, F32 b);      // Initializes LLColor4 to (r, g, b, 1) +        LLColor4(F32 r, F32 g, F32 b, F32 a);       // Initializes LLColor4 to (r. g, b, a) +        LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a) +        explicit LLColor4(const LLSD& sd); +        explicit LLColor4(const F32 *vec);          // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1) +        explicit LLColor4(U32 clr);                         // Initializes LLColor4 to (r=clr>>24, etc)) +        explicit LLColor4(const LLColor4U& color4u);  // "explicit" to avoid automatic conversion +        explicit LLColor4(const LLVector4& vector4);  // "explicit" to avoid automatic conversion + +        LLSD getValue() const +        { +            LLSD ret; +            ret[0] = mV[0]; +            ret[1] = mV[1]; +            ret[2] = mV[2]; +            ret[3] = mV[3]; +            return ret; +        } + +        void setValue(const LLSD& sd); + +        void setHSL(F32 hue, F32 saturation, F32 luminance); +        void calcHSL(F32* hue, F32* saturation, F32* luminance) const; + +        const LLColor4& setToBlack();                       // zero LLColor4 to (0, 0, 0, 1) +        const LLColor4& setToWhite();                       // zero LLColor4 to (0, 0, 0, 1) + +        const LLColor4& setVec(F32 r, F32 g, F32 b, F32 a); // deprecated -- use set() +        const LLColor4& setVec(F32 r, F32 g, F32 b);        // deprecated -- use set() +        const LLColor4& setVec(const LLColor4 &vec);        // deprecated -- use set() +        const LLColor4& setVec(const LLColor3 &vec);        // deprecated -- use set() +        const LLColor4& setVec(const LLColor3 &vec, F32 a); // deprecated -- use set() +        const LLColor4& setVec(const F32 *vec);             // deprecated -- use set() +        const LLColor4& setVec(const LLColor4U& color4u);   // deprecated -- use set() + +        const LLColor4& set(F32 r, F32 g, F32 b, F32 a);    // Sets LLColor4 to (r, g, b, a) +        const LLColor4& set(F32 r, F32 g, F32 b);   // Sets LLColor4 to (r, g, b) (no change in a) +        const LLColor4& set(const LLColor4 &vec);   // Sets LLColor4 to vec +        const LLColor4& set(const LLColor3 &vec);   // Sets LLColor4 to LLColor3 vec (no change in alpha) +        const LLColor4& set(const LLColor3 &vec, F32 a);    // Sets LLColor4 to LLColor3 vec, with alpha specified +        const LLColor4& set(const F32 *vec);            // Sets LLColor4 to vec +        const LLColor4& set(const F64 *vec);            // Sets LLColor4 to (double)vec +        const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled.          // set from a vector of unknown type and size          // may leave some data unmodified -        template<typename T>  +        template<typename T>          const LLColor4& set(const std::vector<T>& v);          // write to a vector of unknown type and size @@ -101,250 +101,250 @@ class LLColor4          template<typename T>          void write(std::vector<T>& v) const; -		const LLColor4&    setAlpha(F32 a); - -		F32			magVec() const;				// deprecated -- use length() -		F32			magVecSquared() const;		// deprecated -- use lengthSquared() -		F32			normVec();					// deprecated -- use normalize() - -		F32			length() const;				// Returns magnitude of LLColor4 -		F32			lengthSquared() const;		// Returns magnitude squared of LLColor4 -		F32			normalize();				// deprecated -- use normalize() - -		BOOL		isOpaque() { return mV[VALPHA] == 1.f; } - -		F32 operator[](int idx) const { return mV[idx]; } -		F32 &operator[](int idx) { return mV[idx]; } -	 -	    const LLColor4& operator=(const LLColor3 &a);	// Assigns vec3 to vec4 and returns vec4 -		 -		bool operator<(const LLColor4& rhs) const; -		friend std::ostream&	 operator<<(std::ostream& s, const LLColor4 &a);		// Print a -		friend LLColor4 operator+(const LLColor4 &a, const LLColor4 &b);	// Return vector a + b -		friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b);	// Return vector a minus b -		friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b);	// Return component wise a * b -		friend LLColor4 operator*(const LLColor4 &a, F32 k);				// Return rgb times scaler k (no alpha change) +        const LLColor4&    setAlpha(F32 a); + +        F32         magVec() const;             // deprecated -- use length() +        F32         magVecSquared() const;      // deprecated -- use lengthSquared() +        F32         normVec();                  // deprecated -- use normalize() + +        F32         length() const;             // Returns magnitude of LLColor4 +        F32         lengthSquared() const;      // Returns magnitude squared of LLColor4 +        F32         normalize();                // deprecated -- use normalize() + +        BOOL        isOpaque() { return mV[VALPHA] == 1.f; } + +        F32 operator[](int idx) const { return mV[idx]; } +        F32 &operator[](int idx) { return mV[idx]; } + +        const LLColor4& operator=(const LLColor3 &a);   // Assigns vec3 to vec4 and returns vec4 + +        bool operator<(const LLColor4& rhs) const; +        friend std::ostream&     operator<<(std::ostream& s, const LLColor4 &a);        // Print a +        friend LLColor4 operator+(const LLColor4 &a, const LLColor4 &b);    // Return vector a + b +        friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b);    // Return vector a minus b +        friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b);    // Return component wise a * b +        friend LLColor4 operator*(const LLColor4 &a, F32 k);                // Return rgb times scaler k (no alpha change)          friend LLColor4 operator/(const LLColor4 &a, F32 k);                // Return rgb divided by scalar k (no alpha change) -		friend LLColor4 operator*(F32 k, const LLColor4 &a);				// Return rgb times scaler k (no alpha change) -		friend LLColor4 operator%(const LLColor4 &a, F32 k);				// Return alpha times scaler k (no rgb change) -		friend LLColor4 operator%(F32 k, const LLColor4 &a);				// Return alpha times scaler k (no rgb change) - -		friend bool operator==(const LLColor4 &a, const LLColor4 &b);		// Return a == b -		friend bool operator!=(const LLColor4 &a, const LLColor4 &b);		// Return a != b -		 -		friend bool operator==(const LLColor4 &a, const LLColor3 &b);		// Return a == b -		friend bool operator!=(const LLColor4 &a, const LLColor3 &b);		// Return a != b - -		friend const LLColor4& operator+=(LLColor4 &a, const LLColor4 &b);	// Return vector a + b -		friend const LLColor4& operator-=(LLColor4 &a, const LLColor4 &b);	// Return vector a minus b -		friend const LLColor4& operator*=(LLColor4 &a, F32 k);				// Return rgb times scaler k (no alpha change) -		friend const LLColor4& operator%=(LLColor4 &a, F32 k);				// Return alpha times scaler k (no rgb change) - -		friend const LLColor4& operator*=(LLColor4 &a, const LLColor4 &b); // Doesn't multiply alpha! (for lighting) - -		// conversion -		operator LLColor4U() const; - -		// Basic color values. -		static LLColor4 red; -		static LLColor4 green; -		static LLColor4 blue; -		static LLColor4 black; -		static LLColor4 white; -		static LLColor4 yellow; -		static LLColor4 magenta; -		static LLColor4 cyan; -		static LLColor4 smoke; -		static LLColor4 grey; -		static LLColor4 orange; -		static LLColor4 purple; -		static LLColor4 pink; -		static LLColor4 transparent; - -		// Extra color values. -		static LLColor4 grey1; -		static LLColor4 grey2; -		static LLColor4 grey3; -		static LLColor4 grey4; - -		static LLColor4 red1; -		static LLColor4 red2; -		static LLColor4 red3; -		static LLColor4 red4; -		static LLColor4 red5; - -		static LLColor4 green1; -		static LLColor4 green2; -		static LLColor4 green3; -		static LLColor4 green4; -		static LLColor4 green5; -		static LLColor4 green6; - -		static LLColor4 blue1; -		static LLColor4 blue2; -		static LLColor4 blue3; -		static LLColor4 blue4; -		static LLColor4 blue5; -		static LLColor4 blue6; - -		static LLColor4 yellow1; -		static LLColor4 yellow2; -		static LLColor4 yellow3; -		static LLColor4 yellow4; -		static LLColor4 yellow5; -		static LLColor4 yellow6; -		static LLColor4 yellow7; -		static LLColor4 yellow8; -		static LLColor4 yellow9; - -		static LLColor4 orange1; -		static LLColor4 orange2; -		static LLColor4 orange3; -		static LLColor4 orange4; -		static LLColor4 orange5; -		static LLColor4 orange6; - -		static LLColor4 magenta1; -		static LLColor4 magenta2; -		static LLColor4 magenta3; -		static LLColor4 magenta4; - -		static LLColor4 purple1; -		static LLColor4 purple2; -		static LLColor4 purple3; -		static LLColor4 purple4; -		static LLColor4 purple5; -		static LLColor4 purple6; - -		static LLColor4 pink1; -		static LLColor4 pink2; - -		static LLColor4 cyan1; -		static LLColor4 cyan2; -		static LLColor4 cyan3; -		static LLColor4 cyan4; -		static LLColor4 cyan5; -		static LLColor4 cyan6; -	 -		static BOOL parseColor(const std::string& buf, LLColor4* color); -		static BOOL parseColor4(const std::string& buf, LLColor4* color); - -		inline void clamp(); +        friend LLColor4 operator*(F32 k, const LLColor4 &a);                // Return rgb times scaler k (no alpha change) +        friend LLColor4 operator%(const LLColor4 &a, F32 k);                // Return alpha times scaler k (no rgb change) +        friend LLColor4 operator%(F32 k, const LLColor4 &a);                // Return alpha times scaler k (no rgb change) + +        friend bool operator==(const LLColor4 &a, const LLColor4 &b);       // Return a == b +        friend bool operator!=(const LLColor4 &a, const LLColor4 &b);       // Return a != b + +        friend bool operator==(const LLColor4 &a, const LLColor3 &b);       // Return a == b +        friend bool operator!=(const LLColor4 &a, const LLColor3 &b);       // Return a != b + +        friend const LLColor4& operator+=(LLColor4 &a, const LLColor4 &b);  // Return vector a + b +        friend const LLColor4& operator-=(LLColor4 &a, const LLColor4 &b);  // Return vector a minus b +        friend const LLColor4& operator*=(LLColor4 &a, F32 k);              // Return rgb times scaler k (no alpha change) +        friend const LLColor4& operator%=(LLColor4 &a, F32 k);              // Return alpha times scaler k (no rgb change) + +        friend const LLColor4& operator*=(LLColor4 &a, const LLColor4 &b); // Doesn't multiply alpha! (for lighting) + +        // conversion +        operator LLColor4U() const; + +        // Basic color values. +        static LLColor4 red; +        static LLColor4 green; +        static LLColor4 blue; +        static LLColor4 black; +        static LLColor4 white; +        static LLColor4 yellow; +        static LLColor4 magenta; +        static LLColor4 cyan; +        static LLColor4 smoke; +        static LLColor4 grey; +        static LLColor4 orange; +        static LLColor4 purple; +        static LLColor4 pink; +        static LLColor4 transparent; + +        // Extra color values. +        static LLColor4 grey1; +        static LLColor4 grey2; +        static LLColor4 grey3; +        static LLColor4 grey4; + +        static LLColor4 red1; +        static LLColor4 red2; +        static LLColor4 red3; +        static LLColor4 red4; +        static LLColor4 red5; + +        static LLColor4 green1; +        static LLColor4 green2; +        static LLColor4 green3; +        static LLColor4 green4; +        static LLColor4 green5; +        static LLColor4 green6; + +        static LLColor4 blue1; +        static LLColor4 blue2; +        static LLColor4 blue3; +        static LLColor4 blue4; +        static LLColor4 blue5; +        static LLColor4 blue6; + +        static LLColor4 yellow1; +        static LLColor4 yellow2; +        static LLColor4 yellow3; +        static LLColor4 yellow4; +        static LLColor4 yellow5; +        static LLColor4 yellow6; +        static LLColor4 yellow7; +        static LLColor4 yellow8; +        static LLColor4 yellow9; + +        static LLColor4 orange1; +        static LLColor4 orange2; +        static LLColor4 orange3; +        static LLColor4 orange4; +        static LLColor4 orange5; +        static LLColor4 orange6; + +        static LLColor4 magenta1; +        static LLColor4 magenta2; +        static LLColor4 magenta3; +        static LLColor4 magenta4; + +        static LLColor4 purple1; +        static LLColor4 purple2; +        static LLColor4 purple3; +        static LLColor4 purple4; +        static LLColor4 purple5; +        static LLColor4 purple6; + +        static LLColor4 pink1; +        static LLColor4 pink2; + +        static LLColor4 cyan1; +        static LLColor4 cyan2; +        static LLColor4 cyan3; +        static LLColor4 cyan4; +        static LLColor4 cyan5; +        static LLColor4 cyan6; + +        static BOOL parseColor(const std::string& buf, LLColor4* color); +        static BOOL parseColor4(const std::string& buf, LLColor4* color); + +        inline void clamp();  }; -// Non-member functions  -F32		distVec(const LLColor4 &a, const LLColor4 &b);			// Returns distance between a and b -F32		distVec_squared(const LLColor4 &a, const LLColor4 &b);	// Returns distance squared between a and b -LLColor3	vec4to3(const LLColor4 &vec); -LLColor4	vec3to4(const LLColor3 &vec); +// Non-member functions +F32     distVec(const LLColor4 &a, const LLColor4 &b);          // Returns distance between a and b +F32     distVec_squared(const LLColor4 &a, const LLColor4 &b);  // Returns distance squared between a and b +LLColor3    vec4to3(const LLColor4 &vec); +LLColor4    vec3to4(const LLColor3 &vec);  LLColor4 lerp(const LLColor4 &a, const LLColor4 &b, F32 u);  inline LLColor4::LLColor4(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; -	mV[VZ] = 0.f; -	mV[VW] = 1.f; +    mV[VX] = 0.f; +    mV[VY] = 0.f; +    mV[VZ] = 0.f; +    mV[VW] = 1.f;  }  inline LLColor4::LLColor4(const LLSD& sd)  { -	this->setValue(sd); +    this->setValue(sd);  }  inline LLColor4::LLColor4(F32 r, F32 g, F32 b)  { -	mV[VX] = r; -	mV[VY] = g; -	mV[VZ] = b; -	mV[VW] = 1.f; +    mV[VX] = r; +    mV[VY] = g; +    mV[VZ] = b; +    mV[VW] = 1.f;  }  inline LLColor4::LLColor4(F32 r, F32 g, F32 b, F32 a)  { -	mV[VX] = r; -	mV[VY] = g; -	mV[VZ] = b; -	mV[VW] = a; +    mV[VX] = r; +    mV[VY] = g; +    mV[VZ] = b; +    mV[VW] = a;  }  inline LLColor4::LLColor4(U32 clr)  { -	mV[VX] = (clr&0xff) * (1.0f/255.0f); -	mV[VY] = ((clr>>8)&0xff) * (1.0f/255.0f); -	mV[VZ] = ((clr>>16)&0xff) * (1.0f/255.0f); -	mV[VW] = (clr>>24) * (1.0f/255.0f); +    mV[VX] = (clr&0xff) * (1.0f/255.0f); +    mV[VY] = ((clr>>8)&0xff) * (1.0f/255.0f); +    mV[VZ] = ((clr>>16)&0xff) * (1.0f/255.0f); +    mV[VW] = (clr>>24) * (1.0f/255.0f);  }  inline LLColor4::LLColor4(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; -	mV[VW] = vec[VW]; +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ]; +    mV[VW] = vec[VW];  } -inline const LLColor4&	LLColor4::setToBlack(void) +inline const LLColor4&  LLColor4::setToBlack(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; -	mV[VZ] = 0.f; -	mV[VW] = 1.f; -	return (*this); +    mV[VX] = 0.f; +    mV[VY] = 0.f; +    mV[VZ] = 0.f; +    mV[VW] = 1.f; +    return (*this);  } -inline const LLColor4&	LLColor4::setToWhite(void) +inline const LLColor4&  LLColor4::setToWhite(void)  { -	mV[VX] = 1.f; -	mV[VY] = 1.f; -	mV[VZ] = 1.f; -	mV[VW] = 1.f; -	return (*this); +    mV[VX] = 1.f; +    mV[VY] = 1.f; +    mV[VZ] = 1.f; +    mV[VW] = 1.f; +    return (*this);  } -inline const LLColor4&	LLColor4::set(F32 x, F32 y, F32 z) +inline const LLColor4&  LLColor4::set(F32 x, F32 y, F32 z)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z;  //  no change to alpha! -//	mV[VW] = 1.f;   +//  mV[VW] = 1.f; -	return (*this); +    return (*this);  } -inline const LLColor4&	LLColor4::set(F32 x, F32 y, F32 z, F32 a) +inline const LLColor4&  LLColor4::set(F32 x, F32 y, F32 z, F32 a)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; -	mV[VW] = a;   -	return (*this); +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z; +    mV[VW] = a; +    return (*this);  } -inline const LLColor4&	LLColor4::set(const LLColor4 &vec) +inline const LLColor4&  LLColor4::set(const LLColor4 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = vec.mV[VW]; -	return (*this); +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = vec.mV[VW]; +    return (*this);  } -inline const LLColor4&	LLColor4::set(const F32 *vec) +inline const LLColor4&  LLColor4::set(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; -	mV[VW] = vec[VW]; -	return (*this); +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ]; +    mV[VW] = vec[VW]; +    return (*this);  } -inline const LLColor4&	LLColor4::set(const F64 *vec) +inline const LLColor4&  LLColor4::set(const F64 *vec)  {      mV[VX] = static_cast<F32>(vec[VX]);      mV[VY] = static_cast<F32>(vec[VY]); @@ -354,108 +354,108 @@ inline const LLColor4&	LLColor4::set(const F64 *vec)  }  // deprecated -inline const LLColor4&	LLColor4::setVec(F32 x, F32 y, F32 z) +inline const LLColor4&  LLColor4::setVec(F32 x, F32 y, F32 z)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z;  //  no change to alpha! -//	mV[VW] = 1.f;   +//  mV[VW] = 1.f; -	return (*this); +    return (*this);  }  // deprecated -inline const LLColor4&	LLColor4::setVec(F32 x, F32 y, F32 z, F32 a) +inline const LLColor4&  LLColor4::setVec(F32 x, F32 y, F32 z, F32 a)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; -	mV[VW] = a;   -	return (*this); +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z; +    mV[VW] = a; +    return (*this);  }  // deprecated -inline const LLColor4&	LLColor4::setVec(const LLColor4 &vec) +inline const LLColor4&  LLColor4::setVec(const LLColor4 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = vec.mV[VW]; -	return (*this); +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = vec.mV[VW]; +    return (*this);  }  // deprecated -inline const LLColor4&	LLColor4::setVec(const F32 *vec) +inline const LLColor4&  LLColor4::setVec(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; -	mV[VW] = vec[VW]; -	return (*this); +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ]; +    mV[VW] = vec[VW]; +    return (*this);  } -inline const LLColor4&	LLColor4::setAlpha(F32 a) +inline const LLColor4&  LLColor4::setAlpha(F32 a)  { -	mV[VW] = a; -	return (*this); +    mV[VW] = a; +    return (*this);  }  // LLColor4 Magnitude and Normalization Functions -inline F32		LLColor4::length(void) const +inline F32      LLColor4::length(void) const  { -	return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); +    return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);  } -inline F32		LLColor4::lengthSquared(void) const +inline F32      LLColor4::lengthSquared(void) const  { -	return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]; +    return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];  } -inline F32		LLColor4::normalize(void) +inline F32      LLColor4::normalize(void)  { -	F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); -	F32 oomag; +    F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); +    F32 oomag; -	if (mag) -	{ -		oomag = 1.f/mag; -		mV[VX] *= oomag; -		mV[VY] *= oomag; -		mV[VZ] *= oomag; -	} -	return (mag); +    if (mag) +    { +        oomag = 1.f/mag; +        mV[VX] *= oomag; +        mV[VY] *= oomag; +        mV[VZ] *= oomag; +    } +    return (mag);  }  // deprecated -inline F32		LLColor4::magVec(void) const +inline F32      LLColor4::magVec(void) const  { -	return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); +    return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);  }  // deprecated -inline F32		LLColor4::magVecSquared(void) const +inline F32      LLColor4::magVecSquared(void) const  { -	return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]; +    return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];  }  // deprecated -inline F32		LLColor4::normVec(void) +inline F32      LLColor4::normVec(void)  { -	F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); -	F32 oomag; +    F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); +    F32 oomag; -	if (mag) -	{ -		oomag = 1.f/mag; -		mV[VX] *= oomag; -		mV[VY] *= oomag; -		mV[VZ] *= oomag; -	} -	return (mag); +    if (mag) +    { +        oomag = 1.f/mag; +        mV[VX] *= oomag; +        mV[VY] *= oomag; +        mV[VZ] *= oomag; +    } +    return (mag);  }  // LLColor4 Operators @@ -463,39 +463,39 @@ inline F32		LLColor4::normVec(void)  inline LLColor4 operator+(const LLColor4 &a, const LLColor4 &b)  { -	return LLColor4( -		a.mV[VX] + b.mV[VX], -		a.mV[VY] + b.mV[VY], -		a.mV[VZ] + b.mV[VZ], -		a.mV[VW] + b.mV[VW]); +    return LLColor4( +        a.mV[VX] + b.mV[VX], +        a.mV[VY] + b.mV[VY], +        a.mV[VZ] + b.mV[VZ], +        a.mV[VW] + b.mV[VW]);  }  inline LLColor4 operator-(const LLColor4 &a, const LLColor4 &b)  { -	return LLColor4( -		a.mV[VX] - b.mV[VX], -		a.mV[VY] - b.mV[VY], -		a.mV[VZ] - b.mV[VZ], -		a.mV[VW] - b.mV[VW]); +    return LLColor4( +        a.mV[VX] - b.mV[VX], +        a.mV[VY] - b.mV[VY], +        a.mV[VZ] - b.mV[VZ], +        a.mV[VW] - b.mV[VW]);  }  inline LLColor4  operator*(const LLColor4 &a, const LLColor4 &b)  { -	return LLColor4( -		a.mV[VX] * b.mV[VX], -		a.mV[VY] * b.mV[VY], -		a.mV[VZ] * b.mV[VZ], -		a.mV[VW] * b.mV[VW]); +    return LLColor4( +        a.mV[VX] * b.mV[VX], +        a.mV[VY] * b.mV[VY], +        a.mV[VZ] * b.mV[VZ], +        a.mV[VW] * b.mV[VW]);  }  inline LLColor4 operator*(const LLColor4 &a, F32 k) -{	 -	// only affects rgb (not a!) -	return LLColor4( -		a.mV[VX] * k, -		a.mV[VY] * k, -		a.mV[VZ] * k, -		a.mV[VW]); +{ +    // only affects rgb (not a!) +    return LLColor4( +        a.mV[VX] * k, +        a.mV[VY] * k, +        a.mV[VZ] * k, +        a.mV[VW]);  }  inline LLColor4 operator/(const LLColor4 &a, F32 k) @@ -509,170 +509,170 @@ inline LLColor4 operator/(const LLColor4 &a, F32 k)  inline LLColor4 operator*(F32 k, const LLColor4 &a)  { -	// only affects rgb (not a!) -	return LLColor4( -		a.mV[VX] * k, -		a.mV[VY] * k, -		a.mV[VZ] * k, -		a.mV[VW]); +    // only affects rgb (not a!) +    return LLColor4( +        a.mV[VX] * k, +        a.mV[VY] * k, +        a.mV[VZ] * k, +        a.mV[VW]);  }  inline LLColor4 operator%(F32 k, const LLColor4 &a)  { -	// only affects alpha (not rgb!) -	return LLColor4( -		a.mV[VX], -		a.mV[VY], -		a.mV[VZ], -		a.mV[VW] * k); +    // only affects alpha (not rgb!) +    return LLColor4( +        a.mV[VX], +        a.mV[VY], +        a.mV[VZ], +        a.mV[VW] * k);  }  inline LLColor4 operator%(const LLColor4 &a, F32 k)  { -	// only affects alpha (not rgb!) -	return LLColor4( -		a.mV[VX], -		a.mV[VY], -		a.mV[VZ], -		a.mV[VW] * k); +    // only affects alpha (not rgb!) +    return LLColor4( +        a.mV[VX], +        a.mV[VY], +        a.mV[VZ], +        a.mV[VW] * k);  }  inline bool operator==(const LLColor4 &a, const LLColor4 &b)  { -	return (  (a.mV[VX] == b.mV[VX]) -			&&(a.mV[VY] == b.mV[VY]) -			&&(a.mV[VZ] == b.mV[VZ]) -			&&(a.mV[VW] == b.mV[VW])); +    return (  (a.mV[VX] == b.mV[VX]) +            &&(a.mV[VY] == b.mV[VY]) +            &&(a.mV[VZ] == b.mV[VZ]) +            &&(a.mV[VW] == b.mV[VW]));  }  inline bool operator!=(const LLColor4 &a, const LLColor4 &b)  { -	return (  (a.mV[VX] != b.mV[VX]) -			||(a.mV[VY] != b.mV[VY]) -			||(a.mV[VZ] != b.mV[VZ]) -			||(a.mV[VW] != b.mV[VW])); +    return (  (a.mV[VX] != b.mV[VX]) +            ||(a.mV[VY] != b.mV[VY]) +            ||(a.mV[VZ] != b.mV[VZ]) +            ||(a.mV[VW] != b.mV[VW]));  }  inline const LLColor4& operator+=(LLColor4 &a, const LLColor4 &b)  { -	a.mV[VX] += b.mV[VX]; -	a.mV[VY] += b.mV[VY]; -	a.mV[VZ] += b.mV[VZ]; -	a.mV[VW] += b.mV[VW]; -	return a; +    a.mV[VX] += b.mV[VX]; +    a.mV[VY] += b.mV[VY]; +    a.mV[VZ] += b.mV[VZ]; +    a.mV[VW] += b.mV[VW]; +    return a;  }  inline const LLColor4& operator-=(LLColor4 &a, const LLColor4 &b)  { -	a.mV[VX] -= b.mV[VX]; -	a.mV[VY] -= b.mV[VY]; -	a.mV[VZ] -= b.mV[VZ]; -	a.mV[VW] -= b.mV[VW]; -	return a; +    a.mV[VX] -= b.mV[VX]; +    a.mV[VY] -= b.mV[VY]; +    a.mV[VZ] -= b.mV[VZ]; +    a.mV[VW] -= b.mV[VW]; +    return a;  }  inline const LLColor4& operator*=(LLColor4 &a, F32 k)  { -	// only affects rgb (not a!) -	a.mV[VX] *= k; -	a.mV[VY] *= k; -	a.mV[VZ] *= k; -	return a; +    // only affects rgb (not a!) +    a.mV[VX] *= k; +    a.mV[VY] *= k; +    a.mV[VZ] *= k; +    return a;  }  inline const LLColor4& operator *=(LLColor4 &a, const LLColor4 &b)  { -	a.mV[VX] *= b.mV[VX]; -	a.mV[VY] *= b.mV[VY]; -	a.mV[VZ] *= b.mV[VZ]; -//	a.mV[VW] *= b.mV[VW]; -	return a; +    a.mV[VX] *= b.mV[VX]; +    a.mV[VY] *= b.mV[VY]; +    a.mV[VZ] *= b.mV[VZ]; +//  a.mV[VW] *= b.mV[VW]; +    return a;  }  inline const LLColor4& operator%=(LLColor4 &a, F32 k)  { -	// only affects alpha (not rgb!) -	a.mV[VW] *= k; -	return a; +    // only affects alpha (not rgb!) +    a.mV[VW] *= k; +    return a;  }  // Non-member functions -inline F32		distVec(const LLColor4 &a, const LLColor4 &b) +inline F32      distVec(const LLColor4 &a, const LLColor4 &b)  { -	LLColor4 vec = a - b; -	return (vec.length()); +    LLColor4 vec = a - b; +    return (vec.length());  } -inline F32		distVec_squared(const LLColor4 &a, const LLColor4 &b) +inline F32      distVec_squared(const LLColor4 &a, const LLColor4 &b)  { -	LLColor4 vec = a - b; -	return (vec.lengthSquared()); +    LLColor4 vec = a - b; +    return (vec.lengthSquared());  }  inline LLColor4 lerp(const LLColor4 &a, const LLColor4 &b, F32 u)  { -	return LLColor4( -		a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, -		a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, -		a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u, -		a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u); +    return LLColor4( +        a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, +        a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, +        a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u, +        a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u);  }  inline bool LLColor4::operator<(const LLColor4& rhs) const  { -	if (mV[0] != rhs.mV[0]) -	{ -		return mV[0] < rhs.mV[0]; -	} -	if (mV[1] != rhs.mV[1]) -	{ -		return mV[1] < rhs.mV[1]; -	} -	if (mV[2] != rhs.mV[2]) -	{ -		return mV[2] < rhs.mV[2]; -	} +    if (mV[0] != rhs.mV[0]) +    { +        return mV[0] < rhs.mV[0]; +    } +    if (mV[1] != rhs.mV[1]) +    { +        return mV[1] < rhs.mV[1]; +    } +    if (mV[2] != rhs.mV[2]) +    { +        return mV[2] < rhs.mV[2]; +    } -	return mV[3] < rhs.mV[3]; +    return mV[3] < rhs.mV[3];  }  void LLColor4::clamp()  { -	// Clamp the color... -	if (mV[0] < 0.f) -	{ -		mV[0] = 0.f; -	} -	else if (mV[0] > 1.f) -	{ -		mV[0] = 1.f; -	} -	if (mV[1] < 0.f) -	{ -		mV[1] = 0.f; -	} -	else if (mV[1] > 1.f) -	{ -		mV[1] = 1.f; -	} -	if (mV[2] < 0.f) -	{ -		mV[2] = 0.f; -	} -	else if (mV[2] > 1.f) -	{ -		mV[2] = 1.f; -	} -	if (mV[3] < 0.f) -	{ -		mV[3] = 0.f; -	} -	else if (mV[3] > 1.f) -	{ -		mV[3] = 1.f; -	} +    // Clamp the color... +    if (mV[0] < 0.f) +    { +        mV[0] = 0.f; +    } +    else if (mV[0] > 1.f) +    { +        mV[0] = 1.f; +    } +    if (mV[1] < 0.f) +    { +        mV[1] = 0.f; +    } +    else if (mV[1] > 1.f) +    { +        mV[1] = 1.f; +    } +    if (mV[2] < 0.f) +    { +        mV[2] = 0.f; +    } +    else if (mV[2] > 1.f) +    { +        mV[2] = 1.f; +    } +    if (mV[3] < 0.f) +    { +        mV[3] = 0.f; +    } +    else if (mV[3] > 1.f) +    { +        mV[3] = 1.f; +    }  }  // Return the given linear space color value in gamma corrected (sRGB) space diff --git a/indra/llmath/v4coloru.cpp b/indra/llmath/v4coloru.cpp index f1a2518cf3..92127933b2 100644 --- a/indra/llmath/v4coloru.cpp +++ b/indra/llmath/v4coloru.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file v4coloru.cpp   * @brief LLColor4U class implementation.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -43,7 +43,7 @@ LLColor4U LLColor4U::blue (  0,   0, 255, 255);  /* inlined to fix gcc compile link error  LLColor4U::operator LLColor4()  { -	return(LLColor4((F32)mV[VRED]/255.f,(F32)mV[VGREEN]/255.f,(F32)mV[VBLUE]/255.f,(F32)mV[VALPHA]/255.f)); +    return(LLColor4((F32)mV[VRED]/255.f,(F32)mV[VGREEN]/255.f,(F32)mV[VBLUE]/255.f,(F32)mV[VALPHA]/255.f));  }  */ @@ -53,10 +53,10 @@ LLColor4U::operator LLColor4()  /*  LLColor4U::LLColor4U(const LLColor3 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = 255; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = 255;  }  */ @@ -70,51 +70,51 @@ LLColor4U::LLColor4U(const LLColor3 &vec)  /*  LLColor4U LLColor4U::operator=(const LLColor3 &a)  { -	mV[VX] = a.mV[VX]; -	mV[VY] = a.mV[VY]; -	mV[VZ] = a.mV[VZ]; +    mV[VX] = a.mV[VX]; +    mV[VY] = a.mV[VY]; +    mV[VZ] = a.mV[VZ];  // converting from an rgb sets a=1 (opaque) -	mV[VW] = 255; -	return (*this); +    mV[VW] = 255; +    return (*this);  }  */ -std::ostream& operator<<(std::ostream& s, const LLColor4U &a)  +std::ostream& operator<<(std::ostream& s, const LLColor4U &a)  { -	s << "{ " << (S32)a.mV[VX] << ", " << (S32)a.mV[VY] << ", " << (S32)a.mV[VZ] << ", " << (S32)a.mV[VW] << " }"; -	return s; +    s << "{ " << (S32)a.mV[VX] << ", " << (S32)a.mV[VY] << ", " << (S32)a.mV[VZ] << ", " << (S32)a.mV[VW] << " }"; +    return s;  }  // static  BOOL LLColor4U::parseColor4U(const std::string& buf, LLColor4U* value)  { -	if( buf.empty() || value == NULL) -	{ -		return FALSE; -	} - -	U32 v[4]; -	S32 count = sscanf( buf.c_str(), "%u, %u, %u, %u", v + 0, v + 1, v + 2, v + 3 ); -	if (1 == count ) -	{ -		// try this format -		count = sscanf( buf.c_str(), "%u %u %u %u", v + 0, v + 1, v + 2, v + 3 ); -	} -	if( 4 != count ) -	{ -		return FALSE; -	} - -	for( S32 i = 0; i < 4; i++ ) -	{ -		if( v[i] > U8_MAX ) -		{ -			return FALSE; -		} -	} - -	value->set( U8(v[0]), U8(v[1]), U8(v[2]), U8(v[3]) ); -	return TRUE; +    if( buf.empty() || value == NULL) +    { +        return FALSE; +    } + +    U32 v[4]; +    S32 count = sscanf( buf.c_str(), "%u, %u, %u, %u", v + 0, v + 1, v + 2, v + 3 ); +    if (1 == count ) +    { +        // try this format +        count = sscanf( buf.c_str(), "%u %u %u %u", v + 0, v + 1, v + 2, v + 3 ); +    } +    if( 4 != count ) +    { +        return FALSE; +    } + +    for( S32 i = 0; i < 4; i++ ) +    { +        if( v[i] > U8_MAX ) +        { +            return FALSE; +        } +    } + +    value->set( U8(v[0]), U8(v[1]), U8(v[2]), U8(v[3]) ); +    return TRUE;  } diff --git a/indra/llmath/v4coloru.h b/indra/llmath/v4coloru.h index 0f2eff3d14..ecfecc167f 100644 --- a/indra/llmath/v4coloru.h +++ b/indra/llmath/v4coloru.h @@ -1,25 +1,25 @@ -/**  +/**   * @file v4coloru.h   * @brief The LLColor4U class.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -47,538 +47,538 @@ class LLColor4U  {  public: -	U8 mV[LENGTHOFCOLOR4U]; - -	LLColor4U();						// Initializes LLColor4U to (0, 0, 0, 1) -	LLColor4U(U8 r, U8 g, U8 b);		// Initializes LLColor4U to (r, g, b, 1) -	LLColor4U(U8 r, U8 g, U8 b, U8 a);		// Initializes LLColor4U to (r. g, b, a) -	LLColor4U(const U8 *vec);			// Initializes LLColor4U to (vec[0]. vec[1], vec[2], 1) -	explicit LLColor4U(const LLSD& sd) -	{ -		setValue(sd); -	} - -	void setValue(const LLSD& sd) -	{ -		mV[0] = sd[0].asInteger(); -		mV[1] = sd[1].asInteger(); -		mV[2] = sd[2].asInteger(); -		mV[3] = sd[3].asInteger(); -	} - -	LLSD getValue() const -	{ -		LLSD ret; -		ret[0] = mV[0]; -		ret[1] = mV[1]; -		ret[2] = mV[2]; -		ret[3] = mV[3]; -		return ret; -	} - -	const LLColor4U&	setToBlack();						// zero LLColor4U to (0, 0, 0, 1) -	const LLColor4U&	setToWhite();						// zero LLColor4U to (0, 0, 0, 1) - -	const LLColor4U&	set(U8 r, U8 g, U8 b, U8 a);// Sets LLColor4U to (r, g, b, a) -	const LLColor4U&	set(U8 r, U8 g, U8 b);		// Sets LLColor4U to (r, g, b) (no change in a) -	const LLColor4U&	set(const LLColor4U &vec);	// Sets LLColor4U to vec -	const LLColor4U&	set(const U8 *vec);			// Sets LLColor4U to vec - -	const LLColor4U&	setVec(U8 r, U8 g, U8 b, U8 a);	// deprecated -- use set() -	const LLColor4U&	setVec(U8 r, U8 g, U8 b);		// deprecated -- use set() -	const LLColor4U&	setVec(const LLColor4U &vec);	// deprecated -- use set() -	const LLColor4U&	setVec(const U8 *vec);			// deprecated -- use set() - -	const LLColor4U&    setAlpha(U8 a); - -	F32			magVec() const;				// deprecated -- use length() -	F32			magVecSquared() const;		// deprecated -- use lengthSquared() - -	F32			length() const;				// Returns magnitude squared of LLColor4U -	F32			lengthSquared() const;		// Returns magnitude squared of LLColor4U - -	friend std::ostream&	 operator<<(std::ostream& s, const LLColor4U &a);		// Print a -	friend LLColor4U operator+(const LLColor4U &a, const LLColor4U &b);	// Return vector a + b -	friend LLColor4U operator-(const LLColor4U &a, const LLColor4U &b);	// Return vector a minus b -	friend LLColor4U operator*(const LLColor4U &a, const LLColor4U &b);	// Return a * b -	friend bool operator==(const LLColor4U &a, const LLColor4U &b);		// Return a == b -	friend bool operator!=(const LLColor4U &a, const LLColor4U &b);		// Return a != b - -	friend const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b);	// Return vector a + b -	friend const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b);	// Return vector a minus b -	friend const LLColor4U& operator*=(LLColor4U &a, U8 k);				// Return rgb times scaler k (no alpha change) -	friend const LLColor4U& operator%=(LLColor4U &a, U8 k);				// Return alpha times scaler k (no rgb change) - -	LLColor4U addClampMax(const LLColor4U &color);						// Add and clamp the max - -	LLColor4U multAll(const F32 k);										// Multiply ALL channels by scalar k -	const LLColor4U& combine(); - -	inline void setVecScaleClamp(const LLColor3 &color); -	inline void setVecScaleClamp(const LLColor4 &color); - -	static BOOL parseColor4U(const std::string& buf, LLColor4U* value); - -	// conversion -	operator LLColor4() const -	{ -		return LLColor4(*this); -	} - -	U32 asRGBA() const; -	void fromRGBA( U32 aVal ); - -	static LLColor4U white; -	static LLColor4U black; -	static LLColor4U red; -	static LLColor4U green; -	static LLColor4U blue; +    U8 mV[LENGTHOFCOLOR4U]; + +    LLColor4U();                        // Initializes LLColor4U to (0, 0, 0, 1) +    LLColor4U(U8 r, U8 g, U8 b);        // Initializes LLColor4U to (r, g, b, 1) +    LLColor4U(U8 r, U8 g, U8 b, U8 a);      // Initializes LLColor4U to (r. g, b, a) +    LLColor4U(const U8 *vec);           // Initializes LLColor4U to (vec[0]. vec[1], vec[2], 1) +    explicit LLColor4U(const LLSD& sd) +    { +        setValue(sd); +    } + +    void setValue(const LLSD& sd) +    { +        mV[0] = sd[0].asInteger(); +        mV[1] = sd[1].asInteger(); +        mV[2] = sd[2].asInteger(); +        mV[3] = sd[3].asInteger(); +    } + +    LLSD getValue() const +    { +        LLSD ret; +        ret[0] = mV[0]; +        ret[1] = mV[1]; +        ret[2] = mV[2]; +        ret[3] = mV[3]; +        return ret; +    } + +    const LLColor4U&    setToBlack();                       // zero LLColor4U to (0, 0, 0, 1) +    const LLColor4U&    setToWhite();                       // zero LLColor4U to (0, 0, 0, 1) + +    const LLColor4U&    set(U8 r, U8 g, U8 b, U8 a);// Sets LLColor4U to (r, g, b, a) +    const LLColor4U&    set(U8 r, U8 g, U8 b);      // Sets LLColor4U to (r, g, b) (no change in a) +    const LLColor4U&    set(const LLColor4U &vec);  // Sets LLColor4U to vec +    const LLColor4U&    set(const U8 *vec);         // Sets LLColor4U to vec + +    const LLColor4U&    setVec(U8 r, U8 g, U8 b, U8 a); // deprecated -- use set() +    const LLColor4U&    setVec(U8 r, U8 g, U8 b);       // deprecated -- use set() +    const LLColor4U&    setVec(const LLColor4U &vec);   // deprecated -- use set() +    const LLColor4U&    setVec(const U8 *vec);          // deprecated -- use set() + +    const LLColor4U&    setAlpha(U8 a); + +    F32         magVec() const;             // deprecated -- use length() +    F32         magVecSquared() const;      // deprecated -- use lengthSquared() + +    F32         length() const;             // Returns magnitude squared of LLColor4U +    F32         lengthSquared() const;      // Returns magnitude squared of LLColor4U + +    friend std::ostream&     operator<<(std::ostream& s, const LLColor4U &a);       // Print a +    friend LLColor4U operator+(const LLColor4U &a, const LLColor4U &b); // Return vector a + b +    friend LLColor4U operator-(const LLColor4U &a, const LLColor4U &b); // Return vector a minus b +    friend LLColor4U operator*(const LLColor4U &a, const LLColor4U &b); // Return a * b +    friend bool operator==(const LLColor4U &a, const LLColor4U &b);     // Return a == b +    friend bool operator!=(const LLColor4U &a, const LLColor4U &b);     // Return a != b + +    friend const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b);   // Return vector a + b +    friend const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b);   // Return vector a minus b +    friend const LLColor4U& operator*=(LLColor4U &a, U8 k);             // Return rgb times scaler k (no alpha change) +    friend const LLColor4U& operator%=(LLColor4U &a, U8 k);             // Return alpha times scaler k (no rgb change) + +    LLColor4U addClampMax(const LLColor4U &color);                      // Add and clamp the max + +    LLColor4U multAll(const F32 k);                                     // Multiply ALL channels by scalar k +    const LLColor4U& combine(); + +    inline void setVecScaleClamp(const LLColor3 &color); +    inline void setVecScaleClamp(const LLColor4 &color); + +    static BOOL parseColor4U(const std::string& buf, LLColor4U* value); + +    // conversion +    operator LLColor4() const +    { +        return LLColor4(*this); +    } + +    U32 asRGBA() const; +    void fromRGBA( U32 aVal ); + +    static LLColor4U white; +    static LLColor4U black; +    static LLColor4U red; +    static LLColor4U green; +    static LLColor4U blue;  }; -// Non-member functions  -F32		distVec(const LLColor4U &a, const LLColor4U &b);			// Returns distance between a and b -F32		distVec_squared(const LLColor4U &a, const LLColor4U &b);	// Returns distance squared between a and b +// Non-member functions +F32     distVec(const LLColor4U &a, const LLColor4U &b);            // Returns distance between a and b +F32     distVec_squared(const LLColor4U &a, const LLColor4U &b);    // Returns distance squared between a and b  inline LLColor4U::LLColor4U()  { -	mV[VX] = 0; -	mV[VY] = 0; -	mV[VZ] = 0; -	mV[VW] = 255; +    mV[VX] = 0; +    mV[VY] = 0; +    mV[VZ] = 0; +    mV[VW] = 255;  }  inline LLColor4U::LLColor4U(U8 r, U8 g, U8 b)  { -	mV[VX] = r; -	mV[VY] = g; -	mV[VZ] = b; -	mV[VW] = 255; +    mV[VX] = r; +    mV[VY] = g; +    mV[VZ] = b; +    mV[VW] = 255;  }  inline LLColor4U::LLColor4U(U8 r, U8 g, U8 b, U8 a)  { -	mV[VX] = r; -	mV[VY] = g; -	mV[VZ] = b; -	mV[VW] = a; +    mV[VX] = r; +    mV[VY] = g; +    mV[VZ] = b; +    mV[VW] = a;  }  inline LLColor4U::LLColor4U(const U8 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; -	mV[VW] = vec[VW]; +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ]; +    mV[VW] = vec[VW];  }  /*  inline LLColor4U::operator LLColor4()  { -	return(LLColor4((F32)mV[VRED]/255.f,(F32)mV[VGREEN]/255.f,(F32)mV[VBLUE]/255.f,(F32)mV[VALPHA]/255.f)); +    return(LLColor4((F32)mV[VRED]/255.f,(F32)mV[VGREEN]/255.f,(F32)mV[VBLUE]/255.f,(F32)mV[VALPHA]/255.f));  }  */ -inline const LLColor4U&	LLColor4U::setToBlack(void) +inline const LLColor4U& LLColor4U::setToBlack(void)  { -	mV[VX] = 0; -	mV[VY] = 0; -	mV[VZ] = 0; -	mV[VW] = 255; -	return (*this); +    mV[VX] = 0; +    mV[VY] = 0; +    mV[VZ] = 0; +    mV[VW] = 255; +    return (*this);  } -inline const LLColor4U&	LLColor4U::setToWhite(void) +inline const LLColor4U& LLColor4U::setToWhite(void)  { -	mV[VX] = 255; -	mV[VY] = 255; -	mV[VZ] = 255; -	mV[VW] = 255; -	return (*this); +    mV[VX] = 255; +    mV[VY] = 255; +    mV[VZ] = 255; +    mV[VW] = 255; +    return (*this);  } -inline const LLColor4U&	LLColor4U::set(const U8 x, const U8 y, const U8 z) +inline const LLColor4U& LLColor4U::set(const U8 x, const U8 y, const U8 z)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z;  //  no change to alpha! -//	mV[VW] = 255;   +//  mV[VW] = 255; -	return (*this); +    return (*this);  } -inline const LLColor4U&	LLColor4U::set(const U8 r, const U8 g, const U8 b, U8 a) +inline const LLColor4U& LLColor4U::set(const U8 r, const U8 g, const U8 b, U8 a)  { -	mV[0] = r; -	mV[1] = g; -	mV[2] = b; -	mV[3] = a;   -	return (*this); +    mV[0] = r; +    mV[1] = g; +    mV[2] = b; +    mV[3] = a; +    return (*this);  } -inline const LLColor4U&	LLColor4U::set(const LLColor4U &vec) +inline const LLColor4U& LLColor4U::set(const LLColor4U &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = vec.mV[VW]; -	return (*this); +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = vec.mV[VW]; +    return (*this);  } -inline const LLColor4U&	LLColor4U::set(const U8 *vec) +inline const LLColor4U& LLColor4U::set(const U8 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; -	mV[VW] = vec[VW]; -	return (*this); +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ]; +    mV[VW] = vec[VW]; +    return (*this);  }  // deprecated -inline const LLColor4U&	LLColor4U::setVec(const U8 x, const U8 y, const U8 z) +inline const LLColor4U& LLColor4U::setVec(const U8 x, const U8 y, const U8 z)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z;  //  no change to alpha! -//	mV[VW] = 255;   +//  mV[VW] = 255; -	return (*this); +    return (*this);  }  // deprecated -inline const LLColor4U&	LLColor4U::setVec(const U8 r, const U8 g, const U8 b, U8 a) +inline const LLColor4U& LLColor4U::setVec(const U8 r, const U8 g, const U8 b, U8 a)  { -	mV[0] = r; -	mV[1] = g; -	mV[2] = b; -	mV[3] = a;   -	return (*this); +    mV[0] = r; +    mV[1] = g; +    mV[2] = b; +    mV[3] = a; +    return (*this);  }  // deprecated -inline const LLColor4U&	LLColor4U::setVec(const LLColor4U &vec) +inline const LLColor4U& LLColor4U::setVec(const LLColor4U &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = vec.mV[VW]; -	return (*this); +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = vec.mV[VW]; +    return (*this);  }  // deprecated -inline const LLColor4U&	LLColor4U::setVec(const U8 *vec) +inline const LLColor4U& LLColor4U::setVec(const U8 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; -	mV[VW] = vec[VW]; -	return (*this); +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ]; +    mV[VW] = vec[VW]; +    return (*this);  } -inline const LLColor4U&	LLColor4U::setAlpha(U8 a) +inline const LLColor4U& LLColor4U::setAlpha(U8 a)  { -	mV[VW] = a; -	return (*this); +    mV[VW] = a; +    return (*this);  }  // LLColor4U Magnitude and Normalization Functions -inline F32		LLColor4U::length(void) const +inline F32      LLColor4U::length(void) const  { -	return (F32) sqrt( ((F32)mV[VX]) * mV[VX] + ((F32)mV[VY]) * mV[VY] + ((F32)mV[VZ]) * mV[VZ] ); +    return (F32) sqrt( ((F32)mV[VX]) * mV[VX] + ((F32)mV[VY]) * mV[VY] + ((F32)mV[VZ]) * mV[VZ] );  } -inline F32		LLColor4U::lengthSquared(void) const +inline F32      LLColor4U::lengthSquared(void) const  { -	return ((F32)mV[VX]) * mV[VX] + ((F32)mV[VY]) * mV[VY] + ((F32)mV[VZ]) * mV[VZ]; +    return ((F32)mV[VX]) * mV[VX] + ((F32)mV[VY]) * mV[VY] + ((F32)mV[VZ]) * mV[VZ];  }  // deprecated -inline F32		LLColor4U::magVec(void) const +inline F32      LLColor4U::magVec(void) const  { -	return (F32) sqrt( ((F32)mV[VX]) * mV[VX] + ((F32)mV[VY]) * mV[VY] + ((F32)mV[VZ]) * mV[VZ] ); +    return (F32) sqrt( ((F32)mV[VX]) * mV[VX] + ((F32)mV[VY]) * mV[VY] + ((F32)mV[VZ]) * mV[VZ] );  }  // deprecated -inline F32		LLColor4U::magVecSquared(void) const +inline F32      LLColor4U::magVecSquared(void) const  { -	return ((F32)mV[VX]) * mV[VX] + ((F32)mV[VY]) * mV[VY] + ((F32)mV[VZ]) * mV[VZ]; +    return ((F32)mV[VX]) * mV[VX] + ((F32)mV[VY]) * mV[VY] + ((F32)mV[VZ]) * mV[VZ];  }  inline LLColor4U operator+(const LLColor4U &a, const LLColor4U &b)  { -	return LLColor4U( -		a.mV[VX] + b.mV[VX], -		a.mV[VY] + b.mV[VY], -		a.mV[VZ] + b.mV[VZ], -		a.mV[VW] + b.mV[VW]); +    return LLColor4U( +        a.mV[VX] + b.mV[VX], +        a.mV[VY] + b.mV[VY], +        a.mV[VZ] + b.mV[VZ], +        a.mV[VW] + b.mV[VW]);  }  inline LLColor4U operator-(const LLColor4U &a, const LLColor4U &b)  { -	return LLColor4U( -		a.mV[VX] - b.mV[VX], -		a.mV[VY] - b.mV[VY], -		a.mV[VZ] - b.mV[VZ], -		a.mV[VW] - b.mV[VW]); +    return LLColor4U( +        a.mV[VX] - b.mV[VX], +        a.mV[VY] - b.mV[VY], +        a.mV[VZ] - b.mV[VZ], +        a.mV[VW] - b.mV[VW]);  }  inline LLColor4U  operator*(const LLColor4U &a, const LLColor4U &b)  { -	return LLColor4U( -		a.mV[VX] * b.mV[VX], -		a.mV[VY] * b.mV[VY], -		a.mV[VZ] * b.mV[VZ], -		a.mV[VW] * b.mV[VW]); +    return LLColor4U( +        a.mV[VX] * b.mV[VX], +        a.mV[VY] * b.mV[VY], +        a.mV[VZ] * b.mV[VZ], +        a.mV[VW] * b.mV[VW]);  }  inline LLColor4U LLColor4U::addClampMax(const LLColor4U &color)  { -	return LLColor4U(llmin((S32)mV[VX] + color.mV[VX], 255), -					llmin((S32)mV[VY] + color.mV[VY], 255), -					llmin((S32)mV[VZ] + color.mV[VZ], 255), -					llmin((S32)mV[VW] + color.mV[VW], 255)); +    return LLColor4U(llmin((S32)mV[VX] + color.mV[VX], 255), +                    llmin((S32)mV[VY] + color.mV[VY], 255), +                    llmin((S32)mV[VZ] + color.mV[VZ], 255), +                    llmin((S32)mV[VW] + color.mV[VW], 255));  }  inline LLColor4U LLColor4U::multAll(const F32 k)  { -	// Round to nearest -	return LLColor4U( -		(U8)ll_round(mV[VX] * k), -		(U8)ll_round(mV[VY] * k), -		(U8)ll_round(mV[VZ] * k), -		(U8)ll_round(mV[VW] * k)); +    // Round to nearest +    return LLColor4U( +        (U8)ll_round(mV[VX] * k), +        (U8)ll_round(mV[VY] * k), +        (U8)ll_round(mV[VZ] * k), +        (U8)ll_round(mV[VW] * k));  }  /*  inline LLColor4U operator*(const LLColor4U &a, U8 k) -{	 -	// only affects rgb (not a!) -	return LLColor4U( -		a.mV[VX] * k, -		a.mV[VY] * k, -		a.mV[VZ] * k, -		a.mV[VW]); +{ +    // only affects rgb (not a!) +    return LLColor4U( +        a.mV[VX] * k, +        a.mV[VY] * k, +        a.mV[VZ] * k, +        a.mV[VW]);  }  inline LLColor4U operator*(U8 k, const LLColor4U &a)  { -	// only affects rgb (not a!) -	return LLColor4U( -		a.mV[VX] * k, -		a.mV[VY] * k, -		a.mV[VZ] * k, -		a.mV[VW]); +    // only affects rgb (not a!) +    return LLColor4U( +        a.mV[VX] * k, +        a.mV[VY] * k, +        a.mV[VZ] * k, +        a.mV[VW]);  }  inline LLColor4U operator%(U8 k, const LLColor4U &a)  { -	// only affects alpha (not rgb!) -	return LLColor4U( -		a.mV[VX], -		a.mV[VY], -		a.mV[VZ], -		a.mV[VW] * k ); +    // only affects alpha (not rgb!) +    return LLColor4U( +        a.mV[VX], +        a.mV[VY], +        a.mV[VZ], +        a.mV[VW] * k );  }  inline LLColor4U operator%(const LLColor4U &a, U8 k)  { -	// only affects alpha (not rgb!) -	return LLColor4U( -		a.mV[VX], -		a.mV[VY], -		a.mV[VZ], -		a.mV[VW] * k ); +    // only affects alpha (not rgb!) +    return LLColor4U( +        a.mV[VX], +        a.mV[VY], +        a.mV[VZ], +        a.mV[VW] * k );  }  */  inline bool operator==(const LLColor4U &a, const LLColor4U &b)  { -	return (  (a.mV[VX] == b.mV[VX]) -			&&(a.mV[VY] == b.mV[VY]) -			&&(a.mV[VZ] == b.mV[VZ]) -			&&(a.mV[VW] == b.mV[VW])); +    return (  (a.mV[VX] == b.mV[VX]) +            &&(a.mV[VY] == b.mV[VY]) +            &&(a.mV[VZ] == b.mV[VZ]) +            &&(a.mV[VW] == b.mV[VW]));  }  inline bool operator!=(const LLColor4U &a, const LLColor4U &b)  { -	return (  (a.mV[VX] != b.mV[VX]) -			||(a.mV[VY] != b.mV[VY]) -			||(a.mV[VZ] != b.mV[VZ]) -			||(a.mV[VW] != b.mV[VW])); +    return (  (a.mV[VX] != b.mV[VX]) +            ||(a.mV[VY] != b.mV[VY]) +            ||(a.mV[VZ] != b.mV[VZ]) +            ||(a.mV[VW] != b.mV[VW]));  }  inline const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b)  { -	a.mV[VX] += b.mV[VX]; -	a.mV[VY] += b.mV[VY]; -	a.mV[VZ] += b.mV[VZ]; -	a.mV[VW] += b.mV[VW]; -	return a; +    a.mV[VX] += b.mV[VX]; +    a.mV[VY] += b.mV[VY]; +    a.mV[VZ] += b.mV[VZ]; +    a.mV[VW] += b.mV[VW]; +    return a;  }  inline const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b)  { -	a.mV[VX] -= b.mV[VX]; -	a.mV[VY] -= b.mV[VY]; -	a.mV[VZ] -= b.mV[VZ]; -	a.mV[VW] -= b.mV[VW]; -	return a; +    a.mV[VX] -= b.mV[VX]; +    a.mV[VY] -= b.mV[VY]; +    a.mV[VZ] -= b.mV[VZ]; +    a.mV[VW] -= b.mV[VW]; +    return a;  }  inline const LLColor4U& operator*=(LLColor4U &a, U8 k)  { -	// only affects rgb (not a!) -	a.mV[VX] *= k; -	a.mV[VY] *= k; -	a.mV[VZ] *= k; -	return a; +    // only affects rgb (not a!) +    a.mV[VX] *= k; +    a.mV[VY] *= k; +    a.mV[VZ] *= k; +    return a;  }  inline const LLColor4U& operator%=(LLColor4U &a, U8 k)  { -	// only affects alpha (not rgb!) -	a.mV[VW] *= k; -	return a; +    // only affects alpha (not rgb!) +    a.mV[VW] *= k; +    return a;  } -inline F32		distVec(const LLColor4U &a, const LLColor4U &b) +inline F32      distVec(const LLColor4U &a, const LLColor4U &b)  { -	LLColor4U vec = a - b; -	return (vec.length()); +    LLColor4U vec = a - b; +    return (vec.length());  } -inline F32		distVec_squared(const LLColor4U &a, const LLColor4U &b) +inline F32      distVec_squared(const LLColor4U &a, const LLColor4U &b)  { -	LLColor4U vec = a - b; -	return (vec.lengthSquared()); +    LLColor4U vec = a - b; +    return (vec.lengthSquared());  }  void LLColor4U::setVecScaleClamp(const LLColor4& color)  { -	F32 color_scale_factor = 255.f; -	F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]); -	if (max_color > 1.f) -	{ -		color_scale_factor /= max_color; -	} -	const S32 MAX_COLOR = 255; -	S32 r = ll_round(color.mV[0] * color_scale_factor); -	if (r > MAX_COLOR) -	{ -		r = MAX_COLOR; -	} -	else if (r < 0) -	{ -		r = 0; -	} -	mV[0] = r; - -	S32 g = ll_round(color.mV[1] * color_scale_factor); -	if (g > MAX_COLOR) -	{ -		g = MAX_COLOR; -	} -	else if (g < 0) -	{ -		g = 0; -	} -	mV[1] = g; - -	S32 b = ll_round(color.mV[2] * color_scale_factor); -	if (b > MAX_COLOR) -	{ -		b = MAX_COLOR; -	} -	else if (b < 0) -	{ -		b = 0; -	} -	mV[2] = b; - -	// Alpha shouldn't be scaled, just clamped... -	S32 a = ll_round(color.mV[3] * MAX_COLOR); -	if (a > MAX_COLOR) -	{ -		a = MAX_COLOR; -	} -	else if (a < 0) -	{ -		a = 0; -	} -	mV[3] = a; +    F32 color_scale_factor = 255.f; +    F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]); +    if (max_color > 1.f) +    { +        color_scale_factor /= max_color; +    } +    const S32 MAX_COLOR = 255; +    S32 r = ll_round(color.mV[0] * color_scale_factor); +    if (r > MAX_COLOR) +    { +        r = MAX_COLOR; +    } +    else if (r < 0) +    { +        r = 0; +    } +    mV[0] = r; + +    S32 g = ll_round(color.mV[1] * color_scale_factor); +    if (g > MAX_COLOR) +    { +        g = MAX_COLOR; +    } +    else if (g < 0) +    { +        g = 0; +    } +    mV[1] = g; + +    S32 b = ll_round(color.mV[2] * color_scale_factor); +    if (b > MAX_COLOR) +    { +        b = MAX_COLOR; +    } +    else if (b < 0) +    { +        b = 0; +    } +    mV[2] = b; + +    // Alpha shouldn't be scaled, just clamped... +    S32 a = ll_round(color.mV[3] * MAX_COLOR); +    if (a > MAX_COLOR) +    { +        a = MAX_COLOR; +    } +    else if (a < 0) +    { +        a = 0; +    } +    mV[3] = a;  }  void LLColor4U::setVecScaleClamp(const LLColor3& color)  { -	F32 color_scale_factor = 255.f; -	F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]); -	if (max_color > 1.f) -	{ -		color_scale_factor /= max_color; -	} - -	const S32 MAX_COLOR = 255; -	S32 r = ll_round(color.mV[0] * color_scale_factor); -	if (r > MAX_COLOR) -	{ -		r = MAX_COLOR; -	} -	else -	if (r < 0) -	{ -		r = 0; -	} -	mV[0] = r; - -	S32 g = ll_round(color.mV[1] * color_scale_factor); -	if (g > MAX_COLOR) -	{ -		g = MAX_COLOR; -	} -	else -	if (g < 0) -	{ -		g = 0; -	} -	mV[1] = g; - -	S32 b = ll_round(color.mV[2] * color_scale_factor); -	if (b > MAX_COLOR) -	{ -		b = MAX_COLOR; -	} -	if (b < 0) -	{ -		b = 0; -	} -	mV[2] = b; - -	mV[3] = 255; +    F32 color_scale_factor = 255.f; +    F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]); +    if (max_color > 1.f) +    { +        color_scale_factor /= max_color; +    } + +    const S32 MAX_COLOR = 255; +    S32 r = ll_round(color.mV[0] * color_scale_factor); +    if (r > MAX_COLOR) +    { +        r = MAX_COLOR; +    } +    else +    if (r < 0) +    { +        r = 0; +    } +    mV[0] = r; + +    S32 g = ll_round(color.mV[1] * color_scale_factor); +    if (g > MAX_COLOR) +    { +        g = MAX_COLOR; +    } +    else +    if (g < 0) +    { +        g = 0; +    } +    mV[1] = g; + +    S32 b = ll_round(color.mV[2] * color_scale_factor); +    if (b > MAX_COLOR) +    { +        b = MAX_COLOR; +    } +    if (b < 0) +    { +        b = 0; +    } +    mV[2] = b; + +    mV[3] = 255;  }  inline U32 LLColor4U::asRGBA() const  { -	// Little endian: values are swapped in memory. The original code access the array like a U32, so we need to swap here +    // Little endian: values are swapped in memory. The original code access the array like a U32, so we need to swap here -	return (mV[3] << 24) | (mV[2] << 16) | (mV[1] << 8) | mV[0]; +    return (mV[3] << 24) | (mV[2] << 16) | (mV[1] << 8) | mV[0];  }  inline void LLColor4U::fromRGBA( U32 aVal )  { -	// Little endian: values are swapped in memory. The original code access the array like a U32, so we need to swap here +    // Little endian: values are swapped in memory. The original code access the array like a U32, so we need to swap here -	mV[ 0 ] = aVal & 0xFF; -	aVal >>= 8; -	mV[ 1 ] = aVal & 0xFF; -	aVal >>= 8; -	mV[ 2 ] = aVal & 0xFF; -	aVal >>= 8; -	mV[ 3 ] = aVal & 0xFF; +    mV[ 0 ] = aVal & 0xFF; +    aVal >>= 8; +    mV[ 1 ] = aVal & 0xFF; +    aVal >>= 8; +    mV[ 2 ] = aVal & 0xFF; +    aVal >>= 8; +    mV[ 3 ] = aVal & 0xFF;  } diff --git a/indra/llmath/v4math.cpp b/indra/llmath/v4math.cpp index 2782cf2966..8955145527 100644 --- a/indra/llmath/v4math.cpp +++ b/indra/llmath/v4math.cpp @@ -1,25 +1,25 @@ -/**  +/**   * @file v4math.cpp   * @brief LLVector4 class implementation.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -38,67 +38,67 @@  // Axis-Angle rotations  /* -const LLVector4&	LLVector4::rotVec(F32 angle, const LLVector4 &vec) +const LLVector4&    LLVector4::rotVec(F32 angle, const LLVector4 &vec)  { -	if ( !vec.isExactlyZero() && angle ) -	{ -		*this = *this * LLMatrix4(angle, vec); -	} -	return *this; +    if ( !vec.isExactlyZero() && angle ) +    { +        *this = *this * LLMatrix4(angle, vec); +    } +    return *this;  } -const LLVector4&	LLVector4::rotVec(F32 angle, F32 x, F32 y, F32 z) +const LLVector4&    LLVector4::rotVec(F32 angle, F32 x, F32 y, F32 z)  { -	LLVector3 vec(x, y, z); -	if ( !vec.isExactlyZero() && angle ) -	{ -		*this = *this * LLMatrix4(angle, vec); -	} -	return *this; +    LLVector3 vec(x, y, z); +    if ( !vec.isExactlyZero() && angle ) +    { +        *this = *this * LLMatrix4(angle, vec); +    } +    return *this;  }  */ -const LLVector4&	LLVector4::rotVec(const LLMatrix4 &mat) +const LLVector4&    LLVector4::rotVec(const LLMatrix4 &mat)  { -	*this = *this * mat; -	return *this; +    *this = *this * mat; +    return *this;  } -const LLVector4&	LLVector4::rotVec(const LLQuaternion &q) +const LLVector4&    LLVector4::rotVec(const LLQuaternion &q)  { -	*this = *this * q; -	return *this; +    *this = *this * q; +    return *this;  } -const LLVector4&	LLVector4::scaleVec(const LLVector4& vec) +const LLVector4&    LLVector4::scaleVec(const LLVector4& vec)  { -	mV[VX] *= vec.mV[VX]; -	mV[VY] *= vec.mV[VY]; -	mV[VZ] *= vec.mV[VZ]; -	mV[VW] *= vec.mV[VW]; +    mV[VX] *= vec.mV[VX]; +    mV[VY] *= vec.mV[VY]; +    mV[VZ] *= vec.mV[VZ]; +    mV[VW] *= vec.mV[VW]; -	return *this; +    return *this;  }  // Sets all values to absolute value of their original values  // Returns TRUE if data changed  BOOL LLVector4::abs()  { -	BOOL ret = FALSE; +    BOOL ret = FALSE; -	if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = TRUE; } -	if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = TRUE; } -	if (mV[2] < 0.f) { mV[2] = -mV[2]; ret = TRUE; } -	if (mV[3] < 0.f) { mV[3] = -mV[3]; ret = TRUE; } +    if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = TRUE; } +    if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = TRUE; } +    if (mV[2] < 0.f) { mV[2] = -mV[2]; ret = TRUE; } +    if (mV[3] < 0.f) { mV[3] = -mV[3]; ret = TRUE; } -	return ret; +    return ret;  } -std::ostream& operator<<(std::ostream& s, const LLVector4 &a)  +std::ostream& operator<<(std::ostream& s, const LLVector4 &a)  { -	s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << ", " << a.mV[VW] << " }"; -	return s; +    s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << ", " << a.mV[VW] << " }"; +    return s;  } @@ -106,37 +106,37 @@ std::ostream& operator<<(std::ostream& s, const LLVector4 &a)  F32 angle_between( const LLVector4& a, const LLVector4& b )  { -	LLVector4 an = a; -	LLVector4 bn = b; -	an.normalize(); -	bn.normalize(); -	F32 cosine = an * bn; -	F32 angle = (cosine >= 1.0f) ? 0.0f : -		(cosine <= -1.0f) ? F_PI : -		acos(cosine); -	return angle; +    LLVector4 an = a; +    LLVector4 bn = b; +    an.normalize(); +    bn.normalize(); +    F32 cosine = an * bn; +    F32 angle = (cosine >= 1.0f) ? 0.0f : +        (cosine <= -1.0f) ? F_PI : +        acos(cosine); +    return angle;  }  BOOL are_parallel(const LLVector4 &a, const LLVector4 &b, F32 epsilon)  { -	LLVector4 an = a; -	LLVector4 bn = b; -	an.normalize(); -	bn.normalize(); -	F32 dot = an * bn; -	if ( (1.0f - fabs(dot)) < epsilon) -		return TRUE; -	return FALSE; +    LLVector4 an = a; +    LLVector4 bn = b; +    an.normalize(); +    bn.normalize(); +    F32 dot = an * bn; +    if ( (1.0f - fabs(dot)) < epsilon) +        return TRUE; +    return FALSE;  }  LLVector3 vec4to3(const LLVector4 &vec)  { -	return LLVector3( vec.mV[VX], vec.mV[VY], vec.mV[VZ] ); +    return LLVector3( vec.mV[VX], vec.mV[VY], vec.mV[VZ] );  }  LLVector4 vec3to4(const LLVector3 &vec)  { -	return LLVector4(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); +    return LLVector4(vec.mV[VX], vec.mV[VY], vec.mV[VZ]);  } diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h index b8835ba2e4..7f0020af6b 100644 --- a/indra/llmath/v4math.h +++ b/indra/llmath/v4math.h @@ -1,25 +1,25 @@ -/**  +/**   * @file v4math.h   * @brief LLVector4 class header file.   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -42,28 +42,28 @@ static const U32 LENGTHOFVECTOR4 = 4;  class LLVector4  { -	public: -		F32 mV[LENGTHOFVECTOR4]; -		LLVector4();						// Initializes LLVector4 to (0, 0, 0, 1) -		explicit LLVector4(const F32 *vec);			// Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3]) -		explicit LLVector4(const F64 *vec);			// Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]); +    public: +        F32 mV[LENGTHOFVECTOR4]; +        LLVector4();                        // Initializes LLVector4 to (0, 0, 0, 1) +        explicit LLVector4(const F32 *vec);         // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3]) +        explicit LLVector4(const F64 *vec);         // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]);          explicit LLVector4(const LLVector2 &vec);          explicit LLVector4(const LLVector2 &vec, F32 z, F32 w); -		explicit LLVector4(const LLVector3 &vec);			// Initializes LLVector4 to (vec, 1) -		explicit LLVector4(const LLVector3 &vec, F32 w);	// Initializes LLVector4 to (vec, w) +        explicit LLVector4(const LLVector3 &vec);           // Initializes LLVector4 to (vec, 1) +        explicit LLVector4(const LLVector3 &vec, F32 w);    // Initializes LLVector4 to (vec, w)          explicit LLVector4(const LLSD &sd); -		LLVector4(F32 x, F32 y, F32 z);		// Initializes LLVector4 to (x. y, z, 1) -		LLVector4(F32 x, F32 y, F32 z, F32 w); - -		LLSD getValue() const -		{ -			LLSD ret; -			ret[0] = mV[0]; -			ret[1] = mV[1]; -			ret[2] = mV[2]; -			ret[3] = mV[3]; -			return ret; -		} +        LLVector4(F32 x, F32 y, F32 z);     // Initializes LLVector4 to (x. y, z, 1) +        LLVector4(F32 x, F32 y, F32 z, F32 w); + +        LLSD getValue() const +        { +            LLSD ret; +            ret[0] = mV[0]; +            ret[1] = mV[1]; +            ret[2] = mV[2]; +            ret[3] = mV[3]; +            return ret; +        }          void setValue(const LLSD& sd)          { @@ -74,118 +74,118 @@ class LLVector4          } -		inline BOOL isFinite() const;									// checks to see if all values of LLVector3 are finite - -		inline void	clear();		// Clears LLVector4 to (0, 0, 0, 1) -		inline void	clearVec();		// deprecated -		inline void	zeroVec();		// deprecated - -		inline void	set(F32 x, F32 y, F32 z);			// Sets LLVector4 to (x, y, z, 1) -		inline void	set(F32 x, F32 y, F32 z, F32 w);	// Sets LLVector4 to (x, y, z, w) -		inline void	set(const LLVector4 &vec);			// Sets LLVector4 to vec -		inline void	set(const LLVector3 &vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec -		inline void	set(const F32 *vec);				// Sets LLVector4 to vec - -		inline void	setVec(F32 x, F32 y, F32 z);		// deprecated -		inline void	setVec(F32 x, F32 y, F32 z, F32 w);	// deprecated -		inline void	setVec(const LLVector4 &vec);		// deprecated -		inline void	setVec(const LLVector3 &vec, F32 w = 1.f); // deprecated -		inline void	setVec(const F32 *vec);				// deprecated - -		F32	length() const;				// Returns magnitude of LLVector4 -		F32	lengthSquared() const;		// Returns magnitude squared of LLVector4 -		F32	normalize();				// Normalizes and returns the magnitude of LLVector4 - -		F32			magVec() const;				// deprecated -		F32			magVecSquared() const;		// deprecated -		F32			normVec();					// deprecated - -		// Sets all values to absolute value of their original values -		// Returns TRUE if data changed -		BOOL abs(); -		 -		BOOL isExactlyClear() const		{ return (mV[VW] == 1.0f) && !mV[VX] && !mV[VY] && !mV[VZ]; } -		BOOL isExactlyZero() const		{ return !mV[VW] && !mV[VX] && !mV[VY] && !mV[VZ]; } - -		const LLVector4&	rotVec(F32 angle, const LLVector4 &vec);	// Rotates about vec by angle radians -		const LLVector4&	rotVec(F32 angle, F32 x, F32 y, F32 z);		// Rotates about x,y,z by angle radians -		const LLVector4&	rotVec(const LLMatrix4 &mat);				// Rotates by MAT4 mat -		const LLVector4&	rotVec(const LLQuaternion &q);				// Rotates by QUAT q - -		const LLVector4&	scaleVec(const LLVector4& vec);	// Scales component-wise by vec - -		F32 operator[](int idx) const { return mV[idx]; } -		F32 &operator[](int idx) { return mV[idx]; } -	 -		friend std::ostream&	 operator<<(std::ostream& s, const LLVector4 &a);		// Print a -		friend LLVector4 operator+(const LLVector4 &a, const LLVector4 &b);	// Return vector a + b -		friend LLVector4 operator-(const LLVector4 &a, const LLVector4 &b);	// Return vector a minus b -		friend F32  operator*(const LLVector4 &a, const LLVector4 &b);		// Return a dot b -		friend LLVector4 operator%(const LLVector4 &a, const LLVector4 &b);	// Return a cross b -		friend LLVector4 operator/(const LLVector4 &a, F32 k);				// Return a divided by scaler k -		friend LLVector4 operator*(const LLVector4 &a, F32 k);				// Return a times scaler k -		friend LLVector4 operator*(F32 k, const LLVector4 &a);				// Return a times scaler k -		friend bool operator==(const LLVector4 &a, const LLVector4 &b);		// Return a == b -		friend bool operator!=(const LLVector4 &a, const LLVector4 &b);		// Return a != b - -		friend const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b);	// Return vector a + b -		friend const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b);	// Return vector a minus b -		friend const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b);	// Return a cross b -		friend const LLVector4& operator*=(LLVector4 &a, F32 k);				// Return a times scaler k -		friend const LLVector4& operator/=(LLVector4 &a, F32 k);				// Return a divided by scaler k - -		friend LLVector4 operator-(const LLVector4 &a);					// Return vector -a +        inline BOOL isFinite() const;                                   // checks to see if all values of LLVector3 are finite + +        inline void clear();        // Clears LLVector4 to (0, 0, 0, 1) +        inline void clearVec();     // deprecated +        inline void zeroVec();      // deprecated + +        inline void set(F32 x, F32 y, F32 z);           // Sets LLVector4 to (x, y, z, 1) +        inline void set(F32 x, F32 y, F32 z, F32 w);    // Sets LLVector4 to (x, y, z, w) +        inline void set(const LLVector4 &vec);          // Sets LLVector4 to vec +        inline void set(const LLVector3 &vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec +        inline void set(const F32 *vec);                // Sets LLVector4 to vec + +        inline void setVec(F32 x, F32 y, F32 z);        // deprecated +        inline void setVec(F32 x, F32 y, F32 z, F32 w); // deprecated +        inline void setVec(const LLVector4 &vec);       // deprecated +        inline void setVec(const LLVector3 &vec, F32 w = 1.f); // deprecated +        inline void setVec(const F32 *vec);             // deprecated + +        F32 length() const;             // Returns magnitude of LLVector4 +        F32 lengthSquared() const;      // Returns magnitude squared of LLVector4 +        F32 normalize();                // Normalizes and returns the magnitude of LLVector4 + +        F32         magVec() const;             // deprecated +        F32         magVecSquared() const;      // deprecated +        F32         normVec();                  // deprecated + +        // Sets all values to absolute value of their original values +        // Returns TRUE if data changed +        BOOL abs(); + +        BOOL isExactlyClear() const     { return (mV[VW] == 1.0f) && !mV[VX] && !mV[VY] && !mV[VZ]; } +        BOOL isExactlyZero() const      { return !mV[VW] && !mV[VX] && !mV[VY] && !mV[VZ]; } + +        const LLVector4&    rotVec(F32 angle, const LLVector4 &vec);    // Rotates about vec by angle radians +        const LLVector4&    rotVec(F32 angle, F32 x, F32 y, F32 z);     // Rotates about x,y,z by angle radians +        const LLVector4&    rotVec(const LLMatrix4 &mat);               // Rotates by MAT4 mat +        const LLVector4&    rotVec(const LLQuaternion &q);              // Rotates by QUAT q + +        const LLVector4&    scaleVec(const LLVector4& vec); // Scales component-wise by vec + +        F32 operator[](int idx) const { return mV[idx]; } +        F32 &operator[](int idx) { return mV[idx]; } + +        friend std::ostream&     operator<<(std::ostream& s, const LLVector4 &a);       // Print a +        friend LLVector4 operator+(const LLVector4 &a, const LLVector4 &b); // Return vector a + b +        friend LLVector4 operator-(const LLVector4 &a, const LLVector4 &b); // Return vector a minus b +        friend F32  operator*(const LLVector4 &a, const LLVector4 &b);      // Return a dot b +        friend LLVector4 operator%(const LLVector4 &a, const LLVector4 &b); // Return a cross b +        friend LLVector4 operator/(const LLVector4 &a, F32 k);              // Return a divided by scaler k +        friend LLVector4 operator*(const LLVector4 &a, F32 k);              // Return a times scaler k +        friend LLVector4 operator*(F32 k, const LLVector4 &a);              // Return a times scaler k +        friend bool operator==(const LLVector4 &a, const LLVector4 &b);     // Return a == b +        friend bool operator!=(const LLVector4 &a, const LLVector4 &b);     // Return a != b + +        friend const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b);   // Return vector a + b +        friend const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b);   // Return vector a minus b +        friend const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b);   // Return a cross b +        friend const LLVector4& operator*=(LLVector4 &a, F32 k);                // Return a times scaler k +        friend const LLVector4& operator/=(LLVector4 &a, F32 k);                // Return a divided by scaler k + +        friend LLVector4 operator-(const LLVector4 &a);                 // Return vector -a  }; -// Non-member functions  -F32 angle_between(const LLVector4 &a, const LLVector4 &b);		// Returns angle (radians) between a and b -BOOL are_parallel(const LLVector4 &a, const LLVector4 &b, F32 epsilon=F_APPROXIMATELY_ZERO);		// Returns TRUE if a and b are very close to parallel -F32	dist_vec(const LLVector4 &a, const LLVector4 &b);			// Returns distance between a and b -F32	dist_vec_squared(const LLVector4 &a, const LLVector4 &b);	// Returns distance squared between a and b -LLVector3	vec4to3(const LLVector4 &vec); -LLVector4	vec3to4(const LLVector3 &vec); +// Non-member functions +F32 angle_between(const LLVector4 &a, const LLVector4 &b);      // Returns angle (radians) between a and b +BOOL are_parallel(const LLVector4 &a, const LLVector4 &b, F32 epsilon=F_APPROXIMATELY_ZERO);        // Returns TRUE if a and b are very close to parallel +F32 dist_vec(const LLVector4 &a, const LLVector4 &b);           // Returns distance between a and b +F32 dist_vec_squared(const LLVector4 &a, const LLVector4 &b);   // Returns distance squared between a and b +LLVector3   vec4to3(const LLVector4 &vec); +LLVector4   vec3to4(const LLVector3 &vec);  LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u); // Returns a vector that is a linear interpolation between a and b  // Constructors  inline LLVector4::LLVector4(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; -	mV[VZ] = 0.f; -	mV[VW] = 1.f; +    mV[VX] = 0.f; +    mV[VY] = 0.f; +    mV[VZ] = 0.f; +    mV[VW] = 1.f;  }  inline LLVector4::LLVector4(F32 x, F32 y, F32 z)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; -	mV[VW] = 1.f; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z; +    mV[VW] = 1.f;  }  inline LLVector4::LLVector4(F32 x, F32 y, F32 z, F32 w)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; -	mV[VW] = w; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z; +    mV[VW] = w;  }  inline LLVector4::LLVector4(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; -	mV[VW] = vec[VW]; +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ]; +    mV[VW] = vec[VW];  }  inline LLVector4::LLVector4(const F64 *vec)  { -	mV[VX] = (F32) vec[VX]; -	mV[VY] = (F32) vec[VY]; -	mV[VZ] = (F32) vec[VZ]; -	mV[VW] = (F32) vec[VW]; +    mV[VX] = (F32) vec[VX]; +    mV[VY] = (F32) vec[VY]; +    mV[VZ] = (F32) vec[VZ]; +    mV[VW] = (F32) vec[VW];  }  inline LLVector4::LLVector4(const LLVector2 &vec) @@ -206,18 +206,18 @@ inline LLVector4::LLVector4(const LLVector2 &vec, F32 z, F32 w)  inline LLVector4::LLVector4(const LLVector3 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = 1.f; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = 1.f;  }  inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = w; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = w;  }  inline LLVector4::LLVector4(const LLSD &sd) @@ -228,310 +228,310 @@ inline LLVector4::LLVector4(const LLSD &sd)  inline BOOL LLVector4::isFinite() const  { -	return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW])); +    return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW]));  }  // Clear and Assignment Functions -inline void	LLVector4::clear(void) +inline void LLVector4::clear(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; -	mV[VZ] = 0.f; -	mV[VW] = 1.f; +    mV[VX] = 0.f; +    mV[VY] = 0.f; +    mV[VZ] = 0.f; +    mV[VW] = 1.f;  }  // deprecated -inline void	LLVector4::clearVec(void) +inline void LLVector4::clearVec(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; -	mV[VZ] = 0.f; -	mV[VW] = 1.f; +    mV[VX] = 0.f; +    mV[VY] = 0.f; +    mV[VZ] = 0.f; +    mV[VW] = 1.f;  }  // deprecated -inline void	LLVector4::zeroVec(void) +inline void LLVector4::zeroVec(void)  { -	mV[VX] = 0.f; -	mV[VY] = 0.f; -	mV[VZ] = 0.f; -	mV[VW] = 0.f; +    mV[VX] = 0.f; +    mV[VY] = 0.f; +    mV[VZ] = 0.f; +    mV[VW] = 0.f;  } -inline void	LLVector4::set(F32 x, F32 y, F32 z) +inline void LLVector4::set(F32 x, F32 y, F32 z)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; -	mV[VW] = 1.f; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z; +    mV[VW] = 1.f;  } -inline void	LLVector4::set(F32 x, F32 y, F32 z, F32 w) +inline void LLVector4::set(F32 x, F32 y, F32 z, F32 w)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; -	mV[VW] = w; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z; +    mV[VW] = w;  } -inline void	LLVector4::set(const LLVector4 &vec) +inline void LLVector4::set(const LLVector4 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = vec.mV[VW]; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = vec.mV[VW];  } -inline void	LLVector4::set(const LLVector3 &vec, F32 w) +inline void LLVector4::set(const LLVector3 &vec, F32 w)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = w; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = w;  } -inline void	LLVector4::set(const F32 *vec) +inline void LLVector4::set(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; -	mV[VW] = vec[VW]; +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ]; +    mV[VW] = vec[VW];  }  // deprecated -inline void	LLVector4::setVec(F32 x, F32 y, F32 z) +inline void LLVector4::setVec(F32 x, F32 y, F32 z)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; -	mV[VW] = 1.f; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z; +    mV[VW] = 1.f;  }  // deprecated -inline void	LLVector4::setVec(F32 x, F32 y, F32 z, F32 w) +inline void LLVector4::setVec(F32 x, F32 y, F32 z, F32 w)  { -	mV[VX] = x; -	mV[VY] = y; -	mV[VZ] = z; -	mV[VW] = w; +    mV[VX] = x; +    mV[VY] = y; +    mV[VZ] = z; +    mV[VW] = w;  }  // deprecated -inline void	LLVector4::setVec(const LLVector4 &vec) +inline void LLVector4::setVec(const LLVector4 &vec)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = vec.mV[VW]; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = vec.mV[VW];  }  // deprecated -inline void	LLVector4::setVec(const LLVector3 &vec, F32 w) +inline void LLVector4::setVec(const LLVector3 &vec, F32 w)  { -	mV[VX] = vec.mV[VX]; -	mV[VY] = vec.mV[VY]; -	mV[VZ] = vec.mV[VZ]; -	mV[VW] = w; +    mV[VX] = vec.mV[VX]; +    mV[VY] = vec.mV[VY]; +    mV[VZ] = vec.mV[VZ]; +    mV[VW] = w;  }  // deprecated -inline void	LLVector4::setVec(const F32 *vec) +inline void LLVector4::setVec(const F32 *vec)  { -	mV[VX] = vec[VX]; -	mV[VY] = vec[VY]; -	mV[VZ] = vec[VZ]; -	mV[VW] = vec[VW]; +    mV[VX] = vec[VX]; +    mV[VY] = vec[VY]; +    mV[VZ] = vec[VZ]; +    mV[VW] = vec[VW];  }  // LLVector4 Magnitude and Normalization Functions -inline F32		LLVector4::length(void) const +inline F32      LLVector4::length(void) const  { -	return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); +    return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);  } -inline F32		LLVector4::lengthSquared(void) const +inline F32      LLVector4::lengthSquared(void) const  { -	return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]; +    return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];  } -inline F32		LLVector4::magVec(void) const +inline F32      LLVector4::magVec(void) const  { -	return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); +    return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);  } -inline F32		LLVector4::magVecSquared(void) const +inline F32      LLVector4::magVecSquared(void) const  { -	return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]; +    return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];  }  // LLVector4 Operators  inline LLVector4 operator+(const LLVector4 &a, const LLVector4 &b)  { -	LLVector4 c(a); -	return c += b; +    LLVector4 c(a); +    return c += b;  }  inline LLVector4 operator-(const LLVector4 &a, const LLVector4 &b)  { -	LLVector4 c(a); -	return c -= b; +    LLVector4 c(a); +    return c -= b;  }  inline F32  operator*(const LLVector4 &a, const LLVector4 &b)  { -	return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]); +    return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]);  }  inline LLVector4 operator%(const LLVector4 &a, const LLVector4 &b)  { -	return LLVector4(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]); +    return LLVector4(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]);  }  inline LLVector4 operator/(const LLVector4 &a, F32 k)  { -	F32 t = 1.f / k; -	return LLVector4( a.mV[VX] * t, a.mV[VY] * t, a.mV[VZ] * t ); +    F32 t = 1.f / k; +    return LLVector4( a.mV[VX] * t, a.mV[VY] * t, a.mV[VZ] * t );  }  inline LLVector4 operator*(const LLVector4 &a, F32 k)  { -	return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k ); +    return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );  }  inline LLVector4 operator*(F32 k, const LLVector4 &a)  { -	return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k ); +    return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );  }  inline bool operator==(const LLVector4 &a, const LLVector4 &b)  { -	return (  (a.mV[VX] == b.mV[VX]) -			&&(a.mV[VY] == b.mV[VY]) -			&&(a.mV[VZ] == b.mV[VZ])); +    return (  (a.mV[VX] == b.mV[VX]) +            &&(a.mV[VY] == b.mV[VY]) +            &&(a.mV[VZ] == b.mV[VZ]));  }  inline bool operator!=(const LLVector4 &a, const LLVector4 &b)  { -	return (  (a.mV[VX] != b.mV[VX]) -			||(a.mV[VY] != b.mV[VY]) -			||(a.mV[VZ] != b.mV[VZ]) -			||(a.mV[VW] != b.mV[VW]) ); +    return (  (a.mV[VX] != b.mV[VX]) +            ||(a.mV[VY] != b.mV[VY]) +            ||(a.mV[VZ] != b.mV[VZ]) +            ||(a.mV[VW] != b.mV[VW]) );  }  inline const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b)  { -	a.mV[VX] += b.mV[VX]; -	a.mV[VY] += b.mV[VY]; -	a.mV[VZ] += b.mV[VZ]; -	return a; +    a.mV[VX] += b.mV[VX]; +    a.mV[VY] += b.mV[VY]; +    a.mV[VZ] += b.mV[VZ]; +    return a;  }  inline const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b)  { -	a.mV[VX] -= b.mV[VX]; -	a.mV[VY] -= b.mV[VY]; -	a.mV[VZ] -= b.mV[VZ]; -	return a; +    a.mV[VX] -= b.mV[VX]; +    a.mV[VY] -= b.mV[VY]; +    a.mV[VZ] -= b.mV[VZ]; +    return a;  }  inline const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b)  { -	LLVector4 ret(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]); -	a = ret; -	return a; +    LLVector4 ret(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]); +    a = ret; +    return a;  }  inline const LLVector4& operator*=(LLVector4 &a, F32 k)  { -	a.mV[VX] *= k; -	a.mV[VY] *= k; -	a.mV[VZ] *= k; -	return a; +    a.mV[VX] *= k; +    a.mV[VY] *= k; +    a.mV[VZ] *= k; +    return a;  }  inline const LLVector4& operator/=(LLVector4 &a, F32 k)  { -	F32 t = 1.f / k; -	a.mV[VX] *= t; -	a.mV[VY] *= t; -	a.mV[VZ] *= t; -	return a; +    F32 t = 1.f / k; +    a.mV[VX] *= t; +    a.mV[VY] *= t; +    a.mV[VZ] *= t; +    return a;  }  inline LLVector4 operator-(const LLVector4 &a)  { -	return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] ); +    return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] );  } -inline F32	dist_vec(const LLVector4 &a, const LLVector4 &b) +inline F32  dist_vec(const LLVector4 &a, const LLVector4 &b)  { -	LLVector4 vec = a - b; -	return (vec.length()); +    LLVector4 vec = a - b; +    return (vec.length());  } -inline F32	dist_vec_squared(const LLVector4 &a, const LLVector4 &b) +inline F32  dist_vec_squared(const LLVector4 &a, const LLVector4 &b)  { -	LLVector4 vec = a - b; -	return (vec.lengthSquared()); +    LLVector4 vec = a - b; +    return (vec.lengthSquared());  }  inline LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u)  { -	return LLVector4( -		a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, -		a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, -		a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u, -		a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u); +    return LLVector4( +        a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, +        a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, +        a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u, +        a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u);  } -inline F32		LLVector4::normalize(void) +inline F32      LLVector4::normalize(void)  { -	F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); -	F32 oomag; +    F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); +    F32 oomag; -	if (mag > FP_MAG_THRESHOLD) -	{ -		oomag = 1.f/mag; -		mV[VX] *= oomag; -		mV[VY] *= oomag; -		mV[VZ] *= oomag; -	} -	else -	{ -		mV[0] = 0.f; -		mV[1] = 0.f; -		mV[2] = 0.f; -		mag = 0; -	} -	return (mag); +    if (mag > FP_MAG_THRESHOLD) +    { +        oomag = 1.f/mag; +        mV[VX] *= oomag; +        mV[VY] *= oomag; +        mV[VZ] *= oomag; +    } +    else +    { +        mV[0] = 0.f; +        mV[1] = 0.f; +        mV[2] = 0.f; +        mag = 0; +    } +    return (mag);  }  // deprecated -inline F32		LLVector4::normVec(void) -{ -	F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); -	F32 oomag; - -	if (mag > FP_MAG_THRESHOLD) -	{ -		oomag = 1.f/mag; -		mV[VX] *= oomag; -		mV[VY] *= oomag; -		mV[VZ] *= oomag; -	} -	else -	{ -		mV[0] = 0.f; -		mV[1] = 0.f; -		mV[2] = 0.f; -		mag = 0; -	} -	return (mag); +inline F32      LLVector4::normVec(void) +{ +    F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); +    F32 oomag; + +    if (mag > FP_MAG_THRESHOLD) +    { +        oomag = 1.f/mag; +        mV[VX] *= oomag; +        mV[VY] *= oomag; +        mV[VZ] *= oomag; +    } +    else +    { +        mV[0] = 0.f; +        mV[1] = 0.f; +        mV[2] = 0.f; +        mag = 0; +    } +    return (mag);  }  // Because apparently some parts of the viewer use this for color info. diff --git a/indra/llmath/xform.cpp b/indra/llmath/xform.cpp index 5d8b93d5e8..6edad9664f 100644 --- a/indra/llmath/xform.cpp +++ b/indra/llmath/xform.cpp @@ -1,24 +1,24 @@ -/**  +/**   * @file xform.cpp   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -29,7 +29,7 @@  LLXform::LLXform()  { -	init(); +    init();  }  LLXform::~LLXform() @@ -39,27 +39,27 @@ LLXform::~LLXform()  // Link optimization - don't inline these LL_WARNS()  void LLXform::warn(const char* const msg)  { -	LL_WARNS() << msg << LL_ENDL; +    LL_WARNS() << msg << LL_ENDL;  }  LLXform* LLXform::getRoot() const  { -	const LLXform* root = this; -	while(root->mParent) -	{ -		root = root->mParent; -	} -	return (LLXform*)root; +    const LLXform* root = this; +    while(root->mParent) +    { +        root = root->mParent; +    } +    return (LLXform*)root;  }  BOOL LLXform::isRoot() const  { -	return (!mParent); +    return (!mParent);  }  BOOL LLXform::isRootEdit() const  { -	return (!mParent); +    return (!mParent);  }  LLXformMatrix::~LLXformMatrix() @@ -68,52 +68,52 @@ LLXformMatrix::~LLXformMatrix()  void LLXformMatrix::update()  { -	if (mParent)  -	{ -		mWorldPosition = mPosition; -		if (mParent->getScaleChildOffset()) -		{ -			mWorldPosition.scaleVec(mParent->getScale()); -		} -		mWorldPosition *= mParent->getWorldRotation(); -		mWorldPosition += mParent->getWorldPosition(); -		mWorldRotation = mRotation * mParent->getWorldRotation(); -	} -	else -	{ -		mWorldPosition = mPosition; -		mWorldRotation = mRotation; -	} +    if (mParent) +    { +        mWorldPosition = mPosition; +        if (mParent->getScaleChildOffset()) +        { +            mWorldPosition.scaleVec(mParent->getScale()); +        } +        mWorldPosition *= mParent->getWorldRotation(); +        mWorldPosition += mParent->getWorldPosition(); +        mWorldRotation = mRotation * mParent->getWorldRotation(); +    } +    else +    { +        mWorldPosition = mPosition; +        mWorldRotation = mRotation; +    }  }  void LLXformMatrix::updateMatrix(BOOL update_bounds)  { -	update(); +    update(); -	mWorldMatrix.initAll(mScale, mWorldRotation, mWorldPosition); +    mWorldMatrix.initAll(mScale, mWorldRotation, mWorldPosition); -	if (update_bounds && (mChanged & MOVED)) -	{ -		mMin.mV[0] = mMax.mV[0] = mWorldMatrix.mMatrix[3][0]; -		mMin.mV[1] = mMax.mV[1] = mWorldMatrix.mMatrix[3][1]; -		mMin.mV[2] = mMax.mV[2] = mWorldMatrix.mMatrix[3][2]; +    if (update_bounds && (mChanged & MOVED)) +    { +        mMin.mV[0] = mMax.mV[0] = mWorldMatrix.mMatrix[3][0]; +        mMin.mV[1] = mMax.mV[1] = mWorldMatrix.mMatrix[3][1]; +        mMin.mV[2] = mMax.mV[2] = mWorldMatrix.mMatrix[3][2]; -		F32 f0 = (fabs(mWorldMatrix.mMatrix[0][0])+fabs(mWorldMatrix.mMatrix[1][0])+fabs(mWorldMatrix.mMatrix[2][0])) * 0.5f; -		F32 f1 = (fabs(mWorldMatrix.mMatrix[0][1])+fabs(mWorldMatrix.mMatrix[1][1])+fabs(mWorldMatrix.mMatrix[2][1])) * 0.5f; -		F32 f2 = (fabs(mWorldMatrix.mMatrix[0][2])+fabs(mWorldMatrix.mMatrix[1][2])+fabs(mWorldMatrix.mMatrix[2][2])) * 0.5f; +        F32 f0 = (fabs(mWorldMatrix.mMatrix[0][0])+fabs(mWorldMatrix.mMatrix[1][0])+fabs(mWorldMatrix.mMatrix[2][0])) * 0.5f; +        F32 f1 = (fabs(mWorldMatrix.mMatrix[0][1])+fabs(mWorldMatrix.mMatrix[1][1])+fabs(mWorldMatrix.mMatrix[2][1])) * 0.5f; +        F32 f2 = (fabs(mWorldMatrix.mMatrix[0][2])+fabs(mWorldMatrix.mMatrix[1][2])+fabs(mWorldMatrix.mMatrix[2][2])) * 0.5f; -		mMin.mV[0] -= f0;  -		mMin.mV[1] -= f1;  -		mMin.mV[2] -= f2;  +        mMin.mV[0] -= f0; +        mMin.mV[1] -= f1; +        mMin.mV[2] -= f2; -		mMax.mV[0] += f0;  -		mMax.mV[1] += f1;  -		mMax.mV[2] += f2;  -	} +        mMax.mV[0] += f0; +        mMax.mV[1] += f1; +        mMax.mV[2] += f2; +    }  }  void LLXformMatrix::getMinMax(LLVector3& min, LLVector3& max) const  { -	min = mMin; -	max = mMax; +    min = mMin; +    max = mMax;  } diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h index 54b0f6d9ec..06ca526f4f 100644 --- a/indra/llmath/xform.h +++ b/indra/llmath/xform.h @@ -1,24 +1,24 @@ -/**  +/**   * @file xform.h   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library 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   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -30,286 +30,286 @@  #include "m4math.h"  #include "llquaternion.h" -const F32 MAX_OBJECT_Z 		= 4096.f; // should match REGION_HEIGHT_METERS, Pre-havok4: 768.f -const F32 MIN_OBJECT_Z 		= -256.f; +const F32 MAX_OBJECT_Z      = 4096.f; // should match REGION_HEIGHT_METERS, Pre-havok4: 768.f +const F32 MIN_OBJECT_Z      = -256.f;  const F32 DEFAULT_MAX_PRIM_SCALE = 64.f;  const F32 DEFAULT_MAX_PRIM_SCALE_NO_MESH = 10.f;  const F32 MIN_PRIM_SCALE = 0.01f; -const F32 MAX_PRIM_SCALE = 65536.f;	// something very high but not near FLT_MAX +const F32 MAX_PRIM_SCALE = 65536.f; // something very high but not near FLT_MAX  class LLXform  {  protected: -	LLVector3	  mPosition; -	LLQuaternion  mRotation;  -	LLVector3	  mScale; -	 -	//RN: TODO: move these world transform members to LLXformMatrix -	// as they are *never* updated or accessed in the base class -	LLVector3	  mWorldPosition; -	LLQuaternion  mWorldRotation; +    LLVector3     mPosition; +    LLQuaternion  mRotation; +    LLVector3     mScale; -	LLXform*      mParent; -	U32			  mChanged; +    //RN: TODO: move these world transform members to LLXformMatrix +    // as they are *never* updated or accessed in the base class +    LLVector3     mWorldPosition; +    LLQuaternion  mWorldRotation; -	BOOL		  mScaleChildOffset; +    LLXform*      mParent; +    U32           mChanged; + +    BOOL          mScaleChildOffset;  public: -	typedef enum e_changed_flags -	{ -		UNCHANGED  	= 0x00, -		TRANSLATED 	= 0x01, -		ROTATED		= 0x02, -		SCALED		= 0x04, -		SHIFTED		= 0x08, -		GEOMETRY	= 0x10, -		TEXTURE		= 0x20, -		MOVED       = TRANSLATED|ROTATED|SCALED, -		SILHOUETTE	= 0x40, -		ALL_CHANGED = 0x7f -	}EChangedFlags; - -	void init() -	{ -		mParent  = NULL; -		mChanged = UNCHANGED; -		mPosition.setVec(0,0,0); -		mRotation.loadIdentity(); -		mScale.   setVec(1,1,1); -		mWorldPosition.clearVec(); -		mWorldRotation.loadIdentity(); -		mScaleChildOffset = FALSE; -	} - -	 LLXform(); -	virtual ~LLXform(); - -	void getLocalMat4(LLMatrix4 &mat) const { mat.initAll(mScale, mRotation, mPosition); } - -	inline BOOL setParent(LLXform *parent); - -	inline void setPosition(const LLVector3& pos); -	inline void setPosition(const F32 x, const F32 y, const F32 z); -	inline void setPositionX(const F32 x); -	inline void setPositionY(const F32 y); -	inline void setPositionZ(const F32 z); -	inline void addPosition(const LLVector3& pos); - - -	inline void setScale(const LLVector3& scale); -	inline void setScale(const F32 x, const F32 y, const F32 z); -	inline void setRotation(const LLQuaternion& rot); -	inline void setRotation(const F32 x, const F32 y, const F32 z); -	inline void setRotation(const F32 x, const F32 y, const F32 z, const F32 s); - -	// Above functions must be inline for speed, but also -	// need to emit warnings.  LL_WARNS() causes inline LLError::CallSite -	// static objects that make more work for the linker. -	// Avoid inline LL_WARNS() by calling this function. -	void warn(const char* const msg); -	 -	void 		setChanged(const U32 bits)					{ mChanged |= bits; } -	BOOL		isChanged() const							{ return mChanged; } -	BOOL 		isChanged(const U32 bits) const				{ return mChanged & bits; } -	void 		clearChanged()								{ mChanged = 0; } -	void        clearChanged(U32 bits)                      { mChanged &= ~bits; } - -	void		setScaleChildOffset(BOOL scale)				{ mScaleChildOffset = scale; } -	BOOL		getScaleChildOffset()						{ return mScaleChildOffset; } - -	LLXform* getParent() const { return mParent; } -	LLXform* getRoot() const; -	virtual BOOL isRoot() const; -	virtual BOOL isRootEdit() const; - -	const LLVector3&	getPosition()  const	    { return mPosition; } -	const LLVector3&	getScale() const			{ return mScale; } -	const LLQuaternion& getRotation() const			{ return mRotation; } -	const LLVector3&	getPositionW() const		{ return mWorldPosition; } -	const LLQuaternion& getWorldRotation() const	{ return mWorldRotation; } -	const LLVector3&	getWorldPosition() const	{ return mWorldPosition; } +    typedef enum e_changed_flags +    { +        UNCHANGED   = 0x00, +        TRANSLATED  = 0x01, +        ROTATED     = 0x02, +        SCALED      = 0x04, +        SHIFTED     = 0x08, +        GEOMETRY    = 0x10, +        TEXTURE     = 0x20, +        MOVED       = TRANSLATED|ROTATED|SCALED, +        SILHOUETTE  = 0x40, +        ALL_CHANGED = 0x7f +    }EChangedFlags; + +    void init() +    { +        mParent  = NULL; +        mChanged = UNCHANGED; +        mPosition.setVec(0,0,0); +        mRotation.loadIdentity(); +        mScale.   setVec(1,1,1); +        mWorldPosition.clearVec(); +        mWorldRotation.loadIdentity(); +        mScaleChildOffset = FALSE; +    } + +     LLXform(); +    virtual ~LLXform(); + +    void getLocalMat4(LLMatrix4 &mat) const { mat.initAll(mScale, mRotation, mPosition); } + +    inline BOOL setParent(LLXform *parent); + +    inline void setPosition(const LLVector3& pos); +    inline void setPosition(const F32 x, const F32 y, const F32 z); +    inline void setPositionX(const F32 x); +    inline void setPositionY(const F32 y); +    inline void setPositionZ(const F32 z); +    inline void addPosition(const LLVector3& pos); + + +    inline void setScale(const LLVector3& scale); +    inline void setScale(const F32 x, const F32 y, const F32 z); +    inline void setRotation(const LLQuaternion& rot); +    inline void setRotation(const F32 x, const F32 y, const F32 z); +    inline void setRotation(const F32 x, const F32 y, const F32 z, const F32 s); + +    // Above functions must be inline for speed, but also +    // need to emit warnings.  LL_WARNS() causes inline LLError::CallSite +    // static objects that make more work for the linker. +    // Avoid inline LL_WARNS() by calling this function. +    void warn(const char* const msg); + +    void        setChanged(const U32 bits)                  { mChanged |= bits; } +    BOOL        isChanged() const                           { return mChanged; } +    BOOL        isChanged(const U32 bits) const             { return mChanged & bits; } +    void        clearChanged()                              { mChanged = 0; } +    void        clearChanged(U32 bits)                      { mChanged &= ~bits; } + +    void        setScaleChildOffset(BOOL scale)             { mScaleChildOffset = scale; } +    BOOL        getScaleChildOffset()                       { return mScaleChildOffset; } + +    LLXform* getParent() const { return mParent; } +    LLXform* getRoot() const; +    virtual BOOL isRoot() const; +    virtual BOOL isRootEdit() const; + +    const LLVector3&    getPosition()  const        { return mPosition; } +    const LLVector3&    getScale() const            { return mScale; } +    const LLQuaternion& getRotation() const         { return mRotation; } +    const LLVector3&    getPositionW() const        { return mWorldPosition; } +    const LLQuaternion& getWorldRotation() const    { return mWorldRotation; } +    const LLVector3&    getWorldPosition() const    { return mWorldPosition; }  };  class LLXformMatrix : public LLXform  {  public: -	LLXformMatrix() : LLXform() {}; -	virtual ~LLXformMatrix(); +    LLXformMatrix() : LLXform() {}; +    virtual ~LLXformMatrix(); -	const LLMatrix4&    getWorldMatrix() const      { return mWorldMatrix; } -	void setWorldMatrix (const LLMatrix4& mat)   { mWorldMatrix = mat; } +    const LLMatrix4&    getWorldMatrix() const      { return mWorldMatrix; } +    void setWorldMatrix (const LLMatrix4& mat)   { mWorldMatrix = mat; } -	void init() -	{ -		mWorldMatrix.setIdentity(); -		mMin.clearVec(); -		mMax.clearVec(); +    void init() +    { +        mWorldMatrix.setIdentity(); +        mMin.clearVec(); +        mMax.clearVec(); -		LLXform::init(); -	} +        LLXform::init(); +    } -	void update(); -	void updateMatrix(BOOL update_bounds = TRUE); -	void getMinMax(LLVector3& min,LLVector3& max) const; +    void update(); +    void updateMatrix(BOOL update_bounds = TRUE); +    void getMinMax(LLVector3& min,LLVector3& max) const;  protected: -	LLMatrix4	mWorldMatrix; -	LLVector3	mMin; -	LLVector3	mMax; +    LLMatrix4   mWorldMatrix; +    LLVector3   mMin; +    LLVector3   mMax;  };  BOOL LLXform::setParent(LLXform* parent)  { -	// Validate and make sure we're not creating a loop -	if (parent == mParent) -	{ -		return TRUE; -	} -	if (parent) -	{ -		LLXform *cur_par = parent->mParent; -		while (cur_par) -		{ -			if (cur_par == this) -			{ -				//warn("LLXform::setParent Creating loop when setting parent!"); -				return FALSE; -			} -			cur_par = cur_par->mParent; -		} -	} -	mParent = parent; -	return TRUE; +    // Validate and make sure we're not creating a loop +    if (parent == mParent) +    { +        return TRUE; +    } +    if (parent) +    { +        LLXform *cur_par = parent->mParent; +        while (cur_par) +        { +            if (cur_par == this) +            { +                //warn("LLXform::setParent Creating loop when setting parent!"); +                return FALSE; +            } +            cur_par = cur_par->mParent; +        } +    } +    mParent = parent; +    return TRUE;  } -void LLXform::setPosition(const LLVector3& pos)			 +void LLXform::setPosition(const LLVector3& pos)  { -	setChanged(TRANSLATED); -	if (pos.isFinite()) -		mPosition = pos;  -	else -	{ -		mPosition.clearVec(); -		warn("Non Finite in LLXform::setPosition(LLVector3)"); -	} +    setChanged(TRANSLATED); +    if (pos.isFinite()) +        mPosition = pos; +    else +    { +        mPosition.clearVec(); +        warn("Non Finite in LLXform::setPosition(LLVector3)"); +    }  }  void LLXform::setPosition(const F32 x, const F32 y, const F32 z)  { -	setChanged(TRANSLATED); -	if (llfinite(x) && llfinite(y) && llfinite(z)) -		mPosition.setVec(x,y,z);  -	else -	{ -		mPosition.clearVec(); -		warn("Non Finite in LLXform::setPosition(F32,F32,F32)"); -	} +    setChanged(TRANSLATED); +    if (llfinite(x) && llfinite(y) && llfinite(z)) +        mPosition.setVec(x,y,z); +    else +    { +        mPosition.clearVec(); +        warn("Non Finite in LLXform::setPosition(F32,F32,F32)"); +    }  }  void LLXform::setPositionX(const F32 x) -{  -	setChanged(TRANSLATED); -	if (llfinite(x)) -		mPosition.mV[VX] = x;  -	else -	{ -		mPosition.mV[VX] = 0.f; -		warn("Non Finite in LLXform::setPositionX"); -	} +{ +    setChanged(TRANSLATED); +    if (llfinite(x)) +        mPosition.mV[VX] = x; +    else +    { +        mPosition.mV[VX] = 0.f; +        warn("Non Finite in LLXform::setPositionX"); +    }  }  void LLXform::setPositionY(const F32 y) -{  -	setChanged(TRANSLATED); -	if (llfinite(y)) -		mPosition.mV[VY] = y;  -	else -	{ -		mPosition.mV[VY] = 0.f; -		warn("Non Finite in LLXform::setPositionY"); -	} +{ +    setChanged(TRANSLATED); +    if (llfinite(y)) +        mPosition.mV[VY] = y; +    else +    { +        mPosition.mV[VY] = 0.f; +        warn("Non Finite in LLXform::setPositionY"); +    }  }  void LLXform::setPositionZ(const F32 z) -{  -	setChanged(TRANSLATED); -	if (llfinite(z)) -		mPosition.mV[VZ] = z;  -	else -	{ -		mPosition.mV[VZ] = 0.f; -		warn("Non Finite in LLXform::setPositionZ"); -	} +{ +    setChanged(TRANSLATED); +    if (llfinite(z)) +        mPosition.mV[VZ] = z; +    else +    { +        mPosition.mV[VZ] = 0.f; +        warn("Non Finite in LLXform::setPositionZ"); +    }  }  void LLXform::addPosition(const LLVector3& pos) -{  -	setChanged(TRANSLATED); -	if (pos.isFinite()) -		mPosition += pos;  -	else -		warn("Non Finite in LLXform::addPosition"); +{ +    setChanged(TRANSLATED); +    if (pos.isFinite()) +        mPosition += pos; +    else +        warn("Non Finite in LLXform::addPosition");  }  void LLXform::setScale(const LLVector3& scale) -{  -	setChanged(SCALED); -	if (scale.isFinite()) -		mScale = scale;  -	else -	{ -		mScale.setVec(1.f, 1.f, 1.f); -		warn("Non Finite in LLXform::setScale"); -	} +{ +    setChanged(SCALED); +    if (scale.isFinite()) +        mScale = scale; +    else +    { +        mScale.setVec(1.f, 1.f, 1.f); +        warn("Non Finite in LLXform::setScale"); +    }  }  void LLXform::setScale(const F32 x, const F32 y, const F32 z) -{  -	setChanged(SCALED); -	if (llfinite(x) && llfinite(y) && llfinite(z)) -		mScale.setVec(x,y,z);  -	else -	{ -		mScale.setVec(1.f, 1.f, 1.f); -		warn("Non Finite in LLXform::setScale"); -	} +{ +    setChanged(SCALED); +    if (llfinite(x) && llfinite(y) && llfinite(z)) +        mScale.setVec(x,y,z); +    else +    { +        mScale.setVec(1.f, 1.f, 1.f); +        warn("Non Finite in LLXform::setScale"); +    }  }  void LLXform::setRotation(const LLQuaternion& rot) -{  -	setChanged(ROTATED); -	if (rot.isFinite()) -		mRotation = rot;  -	else -	{ -		mRotation.loadIdentity(); -		warn("Non Finite in LLXform::setRotation"); -	} +{ +    setChanged(ROTATED); +    if (rot.isFinite()) +        mRotation = rot; +    else +    { +        mRotation.loadIdentity(); +        warn("Non Finite in LLXform::setRotation"); +    }  } -void LLXform::setRotation(const F32 x, const F32 y, const F32 z)  -{  -	setChanged(ROTATED); -	if (llfinite(x) && llfinite(y) && llfinite(z)) -	{ -		mRotation.setQuat(x,y,z);  -	} -	else -	{ -		mRotation.loadIdentity(); -		warn("Non Finite in LLXform::setRotation"); -	} +void LLXform::setRotation(const F32 x, const F32 y, const F32 z) +{ +    setChanged(ROTATED); +    if (llfinite(x) && llfinite(y) && llfinite(z)) +    { +        mRotation.setQuat(x,y,z); +    } +    else +    { +        mRotation.loadIdentity(); +        warn("Non Finite in LLXform::setRotation"); +    }  } -void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s)  -{  -	setChanged(ROTATED); -	if (llfinite(x) && llfinite(y) && llfinite(z) && llfinite(s)) -	{ -		mRotation.mQ[VX] = x; mRotation.mQ[VY] = y; mRotation.mQ[VZ] = z; mRotation.mQ[VS] = s;  -	} -	else -	{ -		mRotation.loadIdentity(); -		warn("Non Finite in LLXform::setRotation"); -	} +void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s) +{ +    setChanged(ROTATED); +    if (llfinite(x) && llfinite(y) && llfinite(z) && llfinite(s)) +    { +        mRotation.mQ[VX] = x; mRotation.mQ[VY] = y; mRotation.mQ[VZ] = z; mRotation.mQ[VS] = s; +    } +    else +    { +        mRotation.loadIdentity(); +        warn("Non Finite in LLXform::setRotation"); +    }  }  #endif  | 
