Merge remote-tracking branch 'singu/master'

This commit is contained in:
Aleric Inglewood
2014-08-25 18:39:46 +02:00
389 changed files with 10426 additions and 10975 deletions

View File

@@ -0,0 +1,29 @@
INTEL LICENSE AGREEMENT
IMPORTANT - READ BEFORE COPYING OR USING.
Do not use or load this library and any associated materials (collectively,
the "Software") until you have read the following terms and conditions. By
loading or using the Software, you agree to the terms of this Agreement. If
you do not wish to so agree, do not use the Software.
LICENSE: Subject to the restrictions below, Intel Corporation ("Intel")
grants to you the permission to use, copy, distribute and prepare derivative
works of this Software for any purpose and without fee, provided, that
Intel's copyright notice appear in all copies of the Software files.
The distribution of derivative works of the Software is also subject to the
following limitations: you (i) are solely responsible to your customers for
any liability which may arise from the distribution, (ii) do not make any
statement that your product is "certified", or that its performance is
guaranteed, by Intel, and (iii) do not use Intel's name or trademarks to
market your product without written permission.
EXCLUSION OF ALL WARRANTIES. The Software is provided "AS IS" without any
express or implies warranty of any kind including warranties of
merchantability, noninfringement, or fitness for a particular purpose.
Intel does not warrant or assume responsibility for the accuracy or
completeness of any information contained within the Software.
As this Software is given free of charge, in no event shall Intel be liable
for any damages whatsoever arising out of the use of or inability to use the
Software, even if Intel has been adviced of the possibility of such damages.
Intel does not assume any responsibility for any errors which may appear in
this Software nor any responsibility to update it.

View File

@@ -293,7 +293,36 @@ void AIEngine::add(AIStateMachine* state_machine)
} }
} }
extern void print_statemachine_diagnostics(U64 total_clocks, U64 max_delta, AIEngine::queued_type::const_reference slowest_state_machine); #if STATE_MACHINE_PROFILING
// Called from AIStateMachine::mainloop
void print_statemachine_diagnostics(U64 total_clocks, AIStateMachine::StateTimerBase::TimeData& slowest_timer, AIEngine::queued_type::const_reference slowest_element)
{
AIStateMachine const& slowest_state_machine = slowest_element.statemachine();
F64 const tfactor = 1000 / calc_clock_frequency();
std::ostringstream msg;
U64 max_delta = slowest_timer.GetDuration();
if (total_clocks > max_delta)
{
msg << "AIStateMachine::mainloop did run for " << (total_clocks * tfactor) << " ms. The slowest ";
}
else
{
msg << "AIStateMachine::mainloop: A ";
}
msg << "state machine " << "(" << slowest_state_machine.getName() << ") " << "ran for " << (max_delta * tfactor) << " ms";
if (slowest_state_machine.getRuntime() > max_delta)
{
msg << " (" << (slowest_state_machine.getRuntime() * tfactor) << " ms in total now)";
}
msg << ".\n";
AIStateMachine::StateTimerBase::DumpTimers(msg);
llwarns << msg.str() << llendl;
}
#endif
// MAIN-THREAD // MAIN-THREAD
void AIEngine::mainloop(void) void AIEngine::mainloop(void)
@@ -305,28 +334,33 @@ void AIEngine::mainloop(void)
queued_element = engine_state_w->list.begin(); queued_element = engine_state_w->list.begin();
} }
U64 total_clocks = 0; U64 total_clocks = 0;
#ifndef LL_RELEASE_FOR_DOWNLOAD #if STATE_MACHINE_PROFILING
U64 max_delta = 0;
queued_type::value_type slowest_element(NULL); queued_type::value_type slowest_element(NULL);
AIStateMachine::StateTimerRoot::TimeData slowest_timer;
#endif #endif
while (queued_element != end) while (queued_element != end)
{ {
AIStateMachine& state_machine(queued_element->statemachine()); AIStateMachine& state_machine(queued_element->statemachine());
U64 start = get_clock_count(); AIStateMachine::StateTimerBase::TimeData time_data;
if (!state_machine.sleep(start)) if (!state_machine.sleep(get_clock_count()))
{ {
state_machine.multiplex(AIStateMachine::normal_run); AIStateMachine::StateTimerRoot timer(state_machine.getName());
state_machine.multiplex(AIStateMachine::normal_run);
time_data = timer.GetTimerData();
} }
U64 delta = get_clock_count() - start; if (U64 delta = time_data.GetDuration())
state_machine.add(delta);
total_clocks += delta;
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (delta > max_delta)
{ {
max_delta = delta; state_machine.add(delta);
slowest_element = *queued_element; total_clocks += delta;
} #if STATE_MACHINE_PROFILING
if (delta > slowest_timer.GetDuration())
{
slowest_element = *queued_element;
slowest_timer = time_data;
}
#endif #endif
}
bool active = state_machine.active(this); // This locks mState shortly, so it must be called before locking mEngineState because add() locks mEngineState while holding mState. bool active = state_machine.active(this); // This locks mState shortly, so it must be called before locking mEngineState because add() locks mEngineState while holding mState.
engine_state_type_wat engine_state_w(mEngineState); engine_state_type_wat engine_state_w(mEngineState);
if (!active) if (!active)
@@ -340,8 +374,8 @@ void AIEngine::mainloop(void)
} }
if (total_clocks >= sMaxCount) if (total_clocks >= sMaxCount)
{ {
#ifndef LL_RELEASE_FOR_DOWNLOAD #if STATE_MACHINE_PROFILING
print_statemachine_diagnostics(total_clocks, max_delta, slowest_element); print_statemachine_diagnostics(total_clocks, slowest_timer, slowest_element);
#endif #endif
Dout(dc::statemachine, "Sorting " << engine_state_w->list.size() << " state machines."); Dout(dc::statemachine, "Sorting " << engine_state_w->list.size() << " state machines.");
engine_state_w->list.sort(QueueElementComp()); engine_state_w->list.sort(QueueElementComp());
@@ -752,6 +786,22 @@ void AIStateMachine::multiplex(event_type event)
} }
} }
#if STATE_MACHINE_PROFILING
std::vector<AIStateMachine::StateTimerBase*> AIStateMachine::StateTimerBase::mTimerStack;
AIStateMachine::StateTimerBase::TimeData AIStateMachine::StateTimerBase::TimeData::sRoot("");
void AIStateMachine::StateTimer::TimeData::DumpTimer(std::ostringstream& msg, std::string prefix)
{
F64 const tfactor = 1000 / calc_clock_frequency();
msg << prefix << mName << " " << (mEnd - mStart)*tfactor << "ms" << std::endl;
prefix.push_back(' ');
std::vector<TimeData>::iterator it;
for (it = mChildren.begin(); it != mChildren.end(); ++it)
{
it->DumpTimer(msg, prefix);
}
}
#endif
AIStateMachine::state_type AIStateMachine::begin_loop(base_state_type base_state) AIStateMachine::state_type AIStateMachine::begin_loop(base_state_type base_state)
{ {
DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::begin_loop(" << state_str(base_state) << ") [" << (void*)this << "]"); DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::begin_loop(" << state_str(base_state) << ") [" << (void*)this << "]");

View File

@@ -36,6 +36,7 @@
#include "aithreadsafe.h" #include "aithreadsafe.h"
#include <llpointer.h> #include <llpointer.h>
#include "lltimer.h"
#include <list> #include <list>
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
@@ -98,11 +99,143 @@ class AIEngine
extern AIEngine gMainThreadEngine; extern AIEngine gMainThreadEngine;
extern AIEngine gStateMachineThreadEngine; extern AIEngine gStateMachineThreadEngine;
#ifndef STATE_MACHINE_PROFILING
#ifndef LL_RELEASE_FOR_DOWNLOAD
#define STATE_MACHINE_PROFILING 1
#endif
#endif
class AIStateMachine : public LLThreadSafeRefCount class AIStateMachine : public LLThreadSafeRefCount
{ {
public: public:
typedef U32 state_type; //!< The type of run_state typedef U32 state_type; //!< The type of run_state
// A simple timer class that will calculate time delta between ctor and GetTimerData call.
// Time data is stored as a nested TimeData object.
// If STATE_MACHINE_PROFILING is defined then a stack of all StateTimers from root is maintained for debug output.
class StateTimerBase
{
public:
class TimeData
{
friend class StateTimerBase;
public:
TimeData() : mStart(-1), mEnd(-1) {}
U64 GetDuration() { return mEnd - mStart; }
private:
U64 mStart, mEnd;
#if !STATE_MACHINE_PROFILING
TimeData(const std::string& name) : mStart(get_clock_count()), mEnd(get_clock_count()) {}
#else
TimeData(const std::string& name) : mName(name), mStart(get_clock_count()), mEnd(get_clock_count()) {}
void DumpTimer(std::ostringstream& msg, std::string prefix);
std::vector<TimeData> mChildren;
std::string mName;
static TimeData sRoot;
#endif
};
#if !STATE_MACHINE_PROFILING
StateTimerBase(const std::string& name) : mData(name) {}
~StateTimerBase() {}
protected:
TimeData mData;
// Return a copy of the underlying timer data.
// This allows the data live beyond the scope of the state timer.
public:
const TimeData GetTimerData()
{
mData.mEnd = get_clock_count(); //set mEnd to current time, since GetTimerData() will always be called before the dtor, obv.
return mData;
}
#else
protected:
// Ctors/dtors are hidden. Only StateTimerRoot and StateTimer are permitted to access them.
StateTimerBase() : mData(NULL) {}
~StateTimerBase()
{
// If mData is null then the timer was not registered due to being in the wrong thread or the root timer wasn't in the expected state.
if (!mData)
return;
mData->mEnd = get_clock_count();
mTimerStack.pop_back();
}
// Also hide internals from everything except StateTimerRoot and StateTimer
bool AddAsRoot(const std::string& name)
{
if (!is_main_thread())
return true; //Ignoring this timer, but pretending it was added.
if (!mTimerStack.empty())
return false;
TimeData::sRoot = TimeData(name);
mData = &TimeData::sRoot;
mData->mChildren.clear();
mTimerStack.push_back(this);
return true;
}
bool AddAsChild(const std::string& name)
{
if (!is_main_thread())
return true; //Ignoring this timer, but pretending it was added.
if (mTimerStack.empty())
return false;
mTimerStack.back()->mData->mChildren.push_back(TimeData(name));
mData = &mTimerStack.back()->mData->mChildren.back();
mTimerStack.push_back(this);
return true;
}
TimeData* mData;
static std::vector<StateTimerBase*> mTimerStack;
public:
// Debug spew
static void DumpTimers(std::ostringstream& msg)
{
TimeData::sRoot.DumpTimer(msg, "");
}
// Return a copy of the underlying timer data.
// This allows the data live beyond the scope of the state timer.
const TimeData GetTimerData() const
{
if (mData)
{
TimeData ret = *mData;
ret.mEnd = get_clock_count(); //set mEnd to current time, since GetTimerData() will always be called before the dtor, obv.
return ret;
}
return TimeData();
}
#endif
};
public:
#if !STATE_MACHINE_PROFILING
typedef StateTimerBase StateTimerRoot;
typedef StateTimerBase StateTimer;
#else
class StateTimerRoot : public StateTimerBase
{ //A StateTimerRoot can become a child if a root already exists.
public:
StateTimerRoot(const std::string& name)
{
if(!AddAsRoot(name))
AddAsChild(name);
}
};
class StateTimer : public StateTimerBase
{ //A StateTimer can never become a root
public:
StateTimer(const std::string& name)
{
AddAsChild(name);
}
};
#endif
protected: protected:
// The type of event that causes multiplex() to be called. // The type of event that causes multiplex() to be called.
enum event_type { enum event_type {
@@ -302,6 +435,9 @@ class AIStateMachine : public LLThreadSafeRefCount
void add(U64 count) { mRuntime += count; } void add(U64 count) { mRuntime += count; }
U64 getRuntime(void) const { return mRuntime; } U64 getRuntime(void) const { return mRuntime; }
// For diagnostics. Every derived class must override this.
virtual const char* getName() const = 0;
protected: protected:
virtual void initialize_impl(void) = 0; virtual void initialize_impl(void) = 0;
virtual void multiplex_impl(state_type run_state) = 0; virtual void multiplex_impl(state_type run_state) = 0;

View File

@@ -232,6 +232,13 @@ class AIStateMachineThread : public AIStateMachineThreadBase {
// Accessor. // Accessor.
THREAD_IMPL& thread_impl(void) { return mThreadImpl; } THREAD_IMPL& thread_impl(void) { return mThreadImpl; }
/*virtual*/ const char* getName() const
{
#define STRIZE(arg) #arg
return "AIStateMachineThread<"STRIZE(THREAD_IMPL)">";
#undef STRIZE
}
protected: protected:
/*virtual*/ AIThreadImpl& impl(void) { return mThreadImpl; } /*virtual*/ AIThreadImpl& impl(void) { return mThreadImpl; }
}; };

View File

@@ -98,6 +98,8 @@ class AITimer : public AIStateMachine {
*/ */
F64 getInterval(void) const { return mInterval; } F64 getInterval(void) const { return mInterval; }
/*virtual*/ const char* getName() const { return "AITimer"; }
protected: protected:
// Call finish() (or abort()), not delete. // Call finish() (or abort()), not delete.
/*virtual*/ ~AITimer() { DoutEntering(dc::statemachine(mSMDebug), "~AITimer() [" << (void*)this << "]"); mFrameTimer.cancel(); } /*virtual*/ ~AITimer() { DoutEntering(dc::statemachine(mSMDebug), "~AITimer() [" << (void*)this << "]"); mFrameTimer.cancel(); }

View File

@@ -221,6 +221,7 @@ class UnixSetup(PlatformSetup):
exe_suffixes = ('',) exe_suffixes = ('',)
def __init__(self): def __init__(self):
PlatformSetup.__init__(self)
super(UnixSetup, self).__init__() super(UnixSetup, self).__init__()
self.generator = 'Unix Makefiles' self.generator = 'Unix Makefiles'
@@ -263,6 +264,7 @@ class UnixSetup(PlatformSetup):
class LinuxSetup(UnixSetup): class LinuxSetup(UnixSetup):
def __init__(self): def __init__(self):
UnixSetup.__init__(self)
super(LinuxSetup, self).__init__() super(LinuxSetup, self).__init__()
try: try:
self.debian_sarge = open('/etc/debian_version').read().strip() == '3.1' self.debian_sarge = open('/etc/debian_version').read().strip() == '3.1'
@@ -384,6 +386,7 @@ class LinuxSetup(UnixSetup):
class DarwinSetup(UnixSetup): class DarwinSetup(UnixSetup):
def __init__(self): def __init__(self):
UnixSetup.__init__(self)
super(DarwinSetup, self).__init__() super(DarwinSetup, self).__init__()
self.generator = 'Xcode' self.generator = 'Xcode'
@@ -457,6 +460,7 @@ class WindowsSetup(PlatformSetup):
exe_suffixes = ('.exe', '.bat', '.com') exe_suffixes = ('.exe', '.bat', '.com')
def __init__(self): def __init__(self):
PlatformSetup.__init__(self)
super(WindowsSetup, self).__init__() super(WindowsSetup, self).__init__()
self._generator = None self._generator = None
self.incredibuild = False self.incredibuild = False
@@ -497,7 +501,10 @@ class WindowsSetup(PlatformSetup):
return 'win32' return 'win32'
def build_dirs(self): def build_dirs(self):
return ['build-' + self.generator] if self.word_size == 64:
return ['build-' + self.generator + '-Win64']
else:
return ['build-' + self.generator]
def cmake_commandline(self, src_dir, build_dir, opts, simple): def cmake_commandline(self, src_dir, build_dir, opts, simple):
args = dict( args = dict(

View File

@@ -983,19 +983,19 @@ BOOL LLAvatarAppearance::loadSkeletonNode ()
mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]); mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]);
mRoot->addChild(mMeshLOD[MESH_ID_HEAD]); mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
LLAvatarJoint *skull = (LLAvatarJoint*)mRoot->findJoint("mSkull"); LLJoint *skull = mRoot->findJoint("mSkull");
if (skull) if (skull)
{ {
skull->addChild(mMeshLOD[MESH_ID_HAIR] ); skull->addChild(mMeshLOD[MESH_ID_HAIR] );
} }
LLAvatarJoint *eyeL = (LLAvatarJoint*)mRoot->findJoint("mEyeLeft"); LLJoint *eyeL = mRoot->findJoint("mEyeLeft");
if (eyeL) if (eyeL)
{ {
eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] ); eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] );
} }
LLAvatarJoint *eyeR = (LLAvatarJoint*)mRoot->findJoint("mEyeRight"); LLJoint *eyeR = mRoot->findJoint("mEyeRight");
if (eyeR) if (eyeR)
{ {
eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] ); eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] );

View File

@@ -105,8 +105,9 @@ void LLAvatarJoint::setValid( BOOL valid, BOOL recursive )
for (child_list_t::iterator iter = mChildren.begin(); for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter) iter != mChildren.end(); ++iter)
{ {
LLAvatarJoint* joint = (LLAvatarJoint*)(*iter); LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->setValid(valid, TRUE); if (joint)
joint->setValid(valid, TRUE);
} }
} }
@@ -124,7 +125,8 @@ void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
iter != mChildren.end(); ++iter) iter != mChildren.end(); ++iter)
{ {
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter); LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->setSkeletonComponents(comp, recursive); if (joint)
joint->setSkeletonComponents(comp, recursive);
} }
} }
} }
@@ -138,8 +140,9 @@ void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
for (child_list_t::iterator iter = mChildren.begin(); for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter) iter != mChildren.end(); ++iter)
{ {
LLAvatarJoint* joint = (LLAvatarJoint*)(*iter); LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->setVisible(visible, recursive); if(joint)
joint->setVisible(visible, recursive);
} }
} }
} }
@@ -150,7 +153,8 @@ void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix
iter != mChildren.end(); ++iter) iter != mChildren.end(); ++iter)
{ {
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter); LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->updateFaceSizes(num_vertices, num_indices, pixel_area); if (joint)
joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
} }
} }
@@ -160,7 +164,8 @@ void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind,
iter != mChildren.end(); ++iter) iter != mChildren.end(); ++iter)
{ {
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter); LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->updateFaceData(face, pixel_area, damp_wind, terse_update); if (joint)
joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
} }
} }
@@ -170,7 +175,8 @@ void LLAvatarJoint::updateJointGeometry()
iter != mChildren.end(); ++iter) iter != mChildren.end(); ++iter)
{ {
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter); LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->updateJointGeometry(); if (joint)
joint->updateJointGeometry();
} }
} }
@@ -184,6 +190,9 @@ BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
iter != mChildren.end(); ++iter) iter != mChildren.end(); ++iter)
{ {
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter); LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
if (!joint)
continue;
F32 jointLOD = joint->getLOD(); F32 jointLOD = joint->getLOD();
if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD) if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD)
@@ -213,7 +222,8 @@ void LLAvatarJoint::dump()
iter != mChildren.end(); ++iter) iter != mChildren.end(); ++iter)
{ {
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter); LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->dump(); if (joint)
joint->dump();
} }
} }
@@ -260,7 +270,7 @@ void LLAvatarJointCollisionVolume::renderCollision()
updateWorldMatrix(); updateWorldMatrix();
gGL.pushMatrix(); gGL.pushMatrix();
gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] ); gGL.multMatrix( mXform.getWorldMatrix() );
gGL.diffuseColor3f( 0.f, 0.f, 1.f ); gGL.diffuseColor3f( 0.f, 0.f, 1.f );

View File

@@ -83,30 +83,28 @@ LLSkinJoint::~LLSkinJoint()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// LLSkinJoint::setupSkinJoint() // LLSkinJoint::setupSkinJoint()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint) void LLSkinJoint::setupSkinJoint( LLJoint *joint)
{ {
mRootToJointSkinOffset.clearVec();
mRootToParentJointSkinOffset.clearVec();
// find the named joint // find the named joint
mJoint = joint; if (!(mJoint = joint))
if ( !mJoint )
{ {
llinfos << "Can't find joint" << llendl; llinfos << "Can't find joint" << llendl;
return;
} }
// compute the inverse root skin matrix // compute the inverse root skin matrix
mRootToJointSkinOffset.clearVec(); do
LLVector3 rootSkinOffset;
while (joint)
{ {
rootSkinOffset += joint->getSkinOffset(); mRootToJointSkinOffset -= joint->getSkinOffset();
joint = (LLAvatarJoint*)joint->getParent(); } while (joint = joint->getParent());
}
mRootToJointSkinOffset = -rootSkinOffset;
mRootToParentJointSkinOffset = mRootToJointSkinOffset; mRootToParentJointSkinOffset = mRootToJointSkinOffset;
mRootToParentJointSkinOffset += mJoint->getSkinOffset(); mRootToParentJointSkinOffset += mJoint->getSkinOffset();
return TRUE; return;
} }
@@ -307,15 +305,14 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh )
for (jn = 0; jn < numJointNames; jn++) for (jn = 0; jn < numJointNames; jn++)
{ {
//llinfos << "Setting up joint " << jointNames[jn] << llendl; //llinfos << "Setting up joint " << jointNames[jn] << llendl;
LLAvatarJoint* joint = (LLAvatarJoint*)(getRoot()->findJoint(jointNames[jn]) ); mSkinJoints[jn].setupSkinJoint( getRoot()->findJoint(jointNames[jn]) );
mSkinJoints[jn].setupSkinJoint( joint );
} }
} }
// setup joint array // setup joint array
if (!mMesh->isLOD()) if (!mMesh->isLOD())
{ {
setupJoint((LLAvatarJoint*)getRoot()); setupJoint(getRoot());
} }
// llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl; // llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl;
@@ -324,7 +321,7 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// setupJoint() // setupJoint()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint) void LLAvatarJointMesh::setupJoint(LLJoint* current_joint)
{ {
// llinfos << "Mesh: " << getName() << llendl; // llinfos << "Mesh: " << getName() << llendl;
@@ -345,7 +342,7 @@ void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == &current_joint->getParent()->getWorldMatrix()) if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == &current_joint->getParent()->getWorldMatrix())
{ {
// ...then just add ourselves // ...then just add ourselves
LLAvatarJoint* jointp = js.mJoint; LLJoint* jointp = js.mJoint;
mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js)); mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js));
// llinfos << "joint " << joint_count << js.mJoint->getName() << llendl; // llinfos << "joint " << joint_count << js.mJoint->getName() << llendl;
// joint_count++; // joint_count++;
@@ -366,8 +363,9 @@ void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin(); for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
iter != current_joint->mChildren.end(); ++iter) iter != current_joint->mChildren.end(); ++iter)
{ {
LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter); LLAvatarJoint* child_joint = dynamic_cast<LLAvatarJoint*>(*iter);
setupJoint(child_joint); if(child_joint)
setupJoint(child_joint);
} }
} }

View File

@@ -49,9 +49,9 @@ class LLSkinJoint
public: public:
LLSkinJoint(); LLSkinJoint();
~LLSkinJoint(); ~LLSkinJoint();
BOOL setupSkinJoint( LLAvatarJoint *joint); void setupSkinJoint( LLJoint *joint);
LLAvatarJoint *mJoint; LLJoint* mJoint;
LLVector3 mRootToJointSkinOffset; LLVector3 mRootToJointSkinOffset;
LLVector3 mRootToParentJointSkinOffset; LLVector3 mRootToParentJointSkinOffset;
}; };
@@ -122,7 +122,7 @@ public:
void setMesh( LLPolyMesh *mesh ); void setMesh( LLPolyMesh *mesh );
// Sets up joint matrix data for rendering // Sets up joint matrix data for rendering
void setupJoint(LLAvatarJoint* current_joint); void setupJoint(LLJoint* current_joint);
// Sets ID for picking // Sets ID for picking
void setMeshID( S32 id ) {mMeshID = id;} void setMeshID( S32 id ) {mMeshID = id;}

View File

@@ -231,9 +231,9 @@ BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
mBaseCoords = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); mBaseCoords = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
mBaseNormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); mBaseNormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
mBaseBinormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a)); mBaseBinormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
mTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); mTexCoords = (LLVector2*) ll_aligned_malloc_16((numVertices+numVertices%2)*sizeof(LLVector2));
mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16((numVertices+numVertices%2)*sizeof(LLVector2));
mWeights = (F32*) ll_aligned_malloc_16(numVertices*sizeof(F32)); mWeights = (F32*) ll_aligned_malloc_16(((numVertices)*sizeof(F32)+0xF) & ~0xF);
for (i = 0; i < numVertices; i++) for (i = 0; i < numVertices; i++)
{ {
mBaseCoords[i].clear(); mBaseCoords[i].clear();

View File

@@ -146,10 +146,10 @@ public:
class LLJointRenderData class LLJointRenderData
{ {
public: public:
LLJointRenderData(const LLMatrix4* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint) {} LLJointRenderData(const LLMatrix4a* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint) {}
~LLJointRenderData(){} ~LLJointRenderData(){}
const LLMatrix4* mWorldMatrix; const LLMatrix4a* mWorldMatrix;
LLSkinJoint* mSkinJoint; LLSkinJoint* mSkinJoint;
}; };

View File

@@ -154,13 +154,13 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin(); for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
iter != joint->mChildren.end(); ++iter) iter != joint->mChildren.end(); ++iter)
{ {
LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter); LLAvatarJoint* child_joint = dynamic_cast<LLAvatarJoint*>(*iter);
if (child_joint->inheritScale()) if (child_joint && child_joint->inheritScale())
{ {
LLVector3 childDeformation = LLVector3(child_joint->getScale()); LLVector3 childDeformation = LLVector3(child_joint->getScale());
childDeformation.scaleVec(bone_info->mScaleDeformation); childDeformation.scaleVec(bone_info->mScaleDeformation);
mJointScales[child_joint] = childDeformation; mJointScales[child_joint] = childDeformation;
} }
} }
if (bone_info->mHasPositionDeformation) if (bone_info->mHasPositionDeformation)

View File

@@ -68,6 +68,15 @@ class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
{ {
friend class LLPolySkeletalDistortion; friend class LLPolySkeletalDistortion;
public: public:
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
LLPolySkeletalDistortionInfo(); LLPolySkeletalDistortionInfo();
/*virtual*/ ~LLPolySkeletalDistortionInfo() {}; /*virtual*/ ~LLPolySkeletalDistortionInfo() {};
@@ -77,12 +86,12 @@ public:
protected: protected:
typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t; typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
bone_info_list_t mBoneInfoList; bone_info_list_t mBoneInfoList;
}; } LL_ALIGN_POSTFIX(16);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// LLPolySkeletalDeformation // LLPolySkeletalDeformation
// A set of joint scale data for deforming the avatar mesh // A set of joint scale data for deforming the avatar mesh
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
LL_ALIGN_PREFIX(16)
class LLPolySkeletalDistortion : public LLViewerVisualParam class LLPolySkeletalDistortion : public LLViewerVisualParam
{ {
public: public:

View File

@@ -72,21 +72,11 @@ LLCharacter::~LLCharacter()
delete param; delete param;
} }
U32 i ; bool erased = vector_replace_with_last(sInstances,this);
U32 size = sInstances.size() ;
for(i = 0 ; i < size ; i++)
{
if(sInstances[i] == this)
{
break ;
}
}
llassert_always(i < size) ; llassert_always(erased) ;
llassert_always(sAllowInstancesChange) ; llassert_always(sAllowInstancesChange) ;
sInstances[i] = sInstances[size - 1] ;
sInstances.pop_back() ;
} }

View File

@@ -312,19 +312,15 @@ void LLJoint::setWorldPosition( const LLVector3& pos )
return; return;
} }
LLMatrix4 temp_matrix = getWorldMatrix(); LLMatrix4a temp_matrix = getWorldMatrix();
temp_matrix.mMatrix[VW][VX] = pos.mV[VX]; temp_matrix.setTranslate_affine(pos);
temp_matrix.mMatrix[VW][VY] = pos.mV[VY];
temp_matrix.mMatrix[VW][VZ] = pos.mV[VZ];
LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix(); LLMatrix4a invParentWorldMatrix = mParent->getWorldMatrix();
LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert(); invParentWorldMatrix.invert();
temp_matrix *= invParentWorldMatrix; invParentWorldMatrix.mul(temp_matrix);
LLVector3 localPos( temp_matrix.mMatrix[VW][VX], LLVector3 localPos( invParentWorldMatrix.getRow<LLMatrix4a::ROW_TRANS>().getF32ptr() );
temp_matrix.mMatrix[VW][VY],
temp_matrix.mMatrix[VW][VZ] );
setPosition( localPos ); setPosition( localPos );
} }
@@ -384,18 +380,18 @@ void LLJoint::setWorldRotation( const LLQuaternion& rot )
return; return;
} }
LLMatrix4 temp_mat(rot); LLMatrix4a parentWorldMatrix = mParent->getWorldMatrix();
LLQuaternion2 rota(rot);
LLMatrix4a temp_mat(rota);
LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix(); LLMatrix4a invParentWorldMatrix = mParent->getWorldMatrix();
parentWorldMatrix.mMatrix[VW][VX] = 0; invParentWorldMatrix.setTranslate_affine(LLVector3(0.f));
parentWorldMatrix.mMatrix[VW][VY] = 0;
parentWorldMatrix.mMatrix[VW][VZ] = 0;
LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert(); invParentWorldMatrix.invert();
temp_mat *= invParentWorldMatrix; invParentWorldMatrix.mul(temp_mat);
setRotation(LLQuaternion(temp_mat)); setRotation(LLQuaternion(LLMatrix4(invParentWorldMatrix.getF32ptr())));
} }
@@ -425,7 +421,7 @@ void LLJoint::setScale( const LLVector3& scale )
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// getWorldMatrix() // getWorldMatrix()
//-------------------------------------------------------------------- //--------------------------------------------------------------------
const LLMatrix4 &LLJoint::getWorldMatrix() const LLMatrix4a &LLJoint::getWorldMatrix()
{ {
updateWorldMatrixParent(); updateWorldMatrixParent();

View File

@@ -162,7 +162,7 @@ public:
void setScale( const LLVector3& scale ); void setScale( const LLVector3& scale );
// get/set world matrix // get/set world matrix
const LLMatrix4 &getWorldMatrix(); const LLMatrix4a &getWorldMatrix();
void setWorldMatrix( const LLMatrix4& mat ); void setWorldMatrix( const LLMatrix4& mat );
void updateWorldMatrixChildren(); void updateWorldMatrixChildren();

View File

@@ -171,12 +171,14 @@ void LLJointSolverRP3::solve()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// get the poleVector in world space // get the poleVector in world space
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
LLMatrix4 worldJointAParentMat; LLVector3 poleVec = mPoleVector;
if ( mJointA->getParent() ) if ( mJointA->getParent() )
{ {
worldJointAParentMat = mJointA->getParent()->getWorldMatrix(); LLVector4a pole_veca;
pole_veca.load3(mPoleVector.mV);
mJointA->getParent()->getWorldMatrix().rotate(pole_veca,pole_veca);
poleVec.set(pole_veca.getF32ptr());
} }
LLVector3 poleVec = rotate_vector( mPoleVector, worldJointAParentMat );
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// compute the following: // compute the following:

View File

@@ -286,40 +286,38 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if ( mTrackAnkles ) if ( mTrackAnkles )
{ {
LLVector4 dirLeft4 = mAnkleLeftJoint.getWorldMatrix().getFwdRow4(); const LLVector4a& dirLeft4 = mAnkleLeftJoint.getWorldMatrix().getRow<LLMatrix4a::ROW_FWD>();
LLVector4 dirRight4 = mAnkleRightJoint.getWorldMatrix().getFwdRow4(); const LLVector4a& dirRight4 = mAnkleRightJoint.getWorldMatrix().getRow<LLMatrix4a::ROW_FWD>();
LLVector3 dirLeft = vec4to3( dirLeft4 );
LLVector3 dirRight = vec4to3( dirRight4 );
LLVector3 up; LLVector4a up;
LLVector3 dir; LLVector4a dir;
LLVector3 left; LLVector4a left;
up = mNormalLeft; up.load3(mNormalLeft.mV);
up.normVec(); up.normalize3fast();
if (mFlipFeet) if (mFlipFeet)
{ {
up *= -1.0f; up.negate();
} }
dir = dirLeft; dir = dirLeft4;
dir.normVec(); dir.normalize3fast();
left = up % dir; left.setCross3(up,dir);
left.normVec(); left.normalize3fast();
dir = left % up; dir.setCross3(left,up);
mRotationLeft = LLQuaternion( dir, left, up ); mRotationLeft = LLQuaternion( LLVector3(dir.getF32ptr()), LLVector3(left.getF32ptr()), LLVector3(up.getF32ptr()));
up = mNormalRight; up.load3(mNormalRight.mV);
up.normVec(); up.normalize3fast();
if (mFlipFeet) if (mFlipFeet)
{ {
up *= -1.0f; up.negate();
} }
dir = dirRight; dir = dirRight4;
dir.normVec(); dir.normalize3fast();
left = up % dir; left.setCross3(up,dir);
left.normVec(); left.normalize3fast();
dir = left % up; dir.setCross3(left,up);
mRotationRight = LLQuaternion( dir, left, up ); mRotationRight = LLQuaternion( LLVector3(dir.getF32ptr()), LLVector3(left.getF32ptr()), LLVector3(up.getF32ptr()));
} }
mAnkleLeftJoint.setWorldRotation( mRotationLeft ); mAnkleLeftJoint.setWorldRotation( mRotationLeft );
mAnkleRightJoint.setWorldRotation( mRotationRight ); mAnkleRightJoint.setWorldRotation( mRotationRight );

View File

@@ -254,7 +254,6 @@ set(llcommon_HEADER_FILES
metapropertyt.h metapropertyt.h
reflective.h reflective.h
reflectivet.h reflectivet.h
roles_constants.h
stdenums.h stdenums.h
stdtypes.h stdtypes.h
string_table.h string_table.h

View File

@@ -239,14 +239,14 @@ inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_ty
// //
//Singu note: This has been generalized to support a broader range of sequence containers //Singu note: This has been generalized to support a broader range of sequence containers
template <typename T> template <typename T>
inline typename T::iterator vector_replace_with_last(T& invec, typename T::iterator& iter) inline typename T::iterator vector_replace_with_last(T& invec, typename T::iterator iter)
{ {
typename T::iterator last = invec.end(); --last; typename T::iterator last = invec.end();
if (iter == invec.end()) if (iter == invec.end())
{ {
return iter; return iter;
} }
else if (iter == last) else if (iter == --last)
{ {
invec.pop_back(); invec.pop_back();
return invec.end(); return invec.end();

View File

@@ -118,16 +118,6 @@ enum EAddPosition
ADD_BOTTOM ADD_BOTTOM
}; };
enum LLGroupChange
{
GC_PROPERTIES,
GC_MEMBER_DATA,
GC_ROLE_DATA,
GC_ROLE_MEMBER_DATA,
GC_TITLES,
GC_ALL
};
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// DEPRECATED - create new, more specific files for shared enums/constants // DEPRECATED - create new, more specific files for shared enums/constants
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@@ -178,7 +178,7 @@ BOOL LLInventoryObject::importLegacyStream(std::istream& input_stream)
while(input_stream.good()) while(input_stream.good())
{ {
input_stream.getline(buffer, MAX_STRING); input_stream.getline(buffer, MAX_STRING);
sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */ if (sscanf(buffer, " %254s %254s", keyword, valuestr) < 1) continue;
if(0 == strcmp("{",keyword)) if(0 == strcmp("{",keyword))
{ {
continue; continue;
@@ -610,7 +610,7 @@ BOOL LLInventoryItem::importFile(LLFILE* fp)
buffer[0] = '\0'; buffer[0] = '\0';
} }
sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */ if (sscanf(buffer, " %254s %254s", keyword, valuestr) < 1) continue;
if(0 == strcmp("{",keyword)) if(0 == strcmp("{",keyword))
{ {
continue; continue;
@@ -813,10 +813,10 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
while(success && input_stream.good()) while(success && input_stream.good())
{ {
input_stream.getline(buffer, MAX_STRING); input_stream.getline(buffer, MAX_STRING);
sscanf( /* Flawfinder: ignore */ if (sscanf(
buffer, buffer,
" %254s %254s", " %254s %254s",
keyword, valuestr); keyword, valuestr) < 1) continue;
if(0 == strcmp("{",keyword)) if(0 == strcmp("{",keyword))
{ {
continue; continue;
@@ -1489,10 +1489,10 @@ BOOL LLInventoryCategory::importFile(LLFILE* fp)
buffer[0] = '\0'; buffer[0] = '\0';
} }
sscanf( /* Flawfinder: ignore */ if (sscanf(
buffer, buffer,
" %254s %254s", " %254s %254s",
keyword, valuestr); keyword, valuestr) < 1) continue;
if(0 == strcmp("{",keyword)) if(0 == strcmp("{",keyword))
{ {
continue; continue;
@@ -1568,10 +1568,10 @@ BOOL LLInventoryCategory::importLegacyStream(std::istream& input_stream)
while(input_stream.good()) while(input_stream.good())
{ {
input_stream.getline(buffer, MAX_STRING); input_stream.getline(buffer, MAX_STRING);
sscanf( /* Flawfinder: ignore */ if (sscanf(
buffer, buffer,
" %254s %254s", " %254s %254s",
keyword, valuestr); keyword, valuestr) < 1) continue;
if(0 == strcmp("{",keyword)) if(0 == strcmp("{",keyword))
{ {
continue; continue;

View File

@@ -2,31 +2,25 @@
* @file llcoordframe.cpp * @file llcoordframe.cpp
* @brief LLCoordFrame class implementation. * @brief LLCoordFrame class implementation.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file llcoordframe.h * @file llcoordframe.h
* @brief LLCoordFrame class header file. * @brief LLCoordFrame class header file.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -1,31 +1,25 @@
/** /**
* @file llinterp.h * @file llinterp.h
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -3,31 +3,25 @@
* @author Andrew Meadows * @author Andrew Meadows
* @brief Simple line class that can compute nearest approach between two lines * @brief Simple line class that can compute nearest approach between two lines
* *
* $LicenseInfo:firstyear=2006&license=viewergpl$ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -4,31 +4,25 @@
* @author Andrew Meadows * @author Andrew Meadows
* @brief Simple line for computing nearest approach between two infinite lines * @brief Simple line for computing nearest approach between two infinite lines
* *
* $LicenseInfo:firstyear=2006&license=viewergpl$ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -30,6 +30,7 @@
#include <cmath> #include <cmath>
#include <cstdlib> #include <cstdlib>
#include <vector> #include <vector>
#include <limits>
#include "lldefs.h" #include "lldefs.h"
//#include "llstl.h" // *TODO: Remove when LLString is gone //#include "llstl.h" // *TODO: Remove when LLString is gone
//#include "llstring.h" // *TODO: Remove when LLString is gone //#include "llstring.h" // *TODO: Remove when LLString is gone
@@ -72,15 +73,21 @@ const F32 F_E = 2.71828182845904523536f;
const F32 F_SQRT2 = 1.4142135623730950488016887242097f; const F32 F_SQRT2 = 1.4142135623730950488016887242097f;
const F32 F_SQRT3 = 1.73205080756888288657986402541f; const F32 F_SQRT3 = 1.73205080756888288657986402541f;
const F32 OO_SQRT2 = 0.7071067811865475244008443621049f; const F32 OO_SQRT2 = 0.7071067811865475244008443621049f;
const F32 OO_SQRT3 = 0.577350269189625764509f;
const F32 DEG_TO_RAD = 0.017453292519943295769236907684886f; const F32 DEG_TO_RAD = 0.017453292519943295769236907684886f;
const F32 RAD_TO_DEG = 57.295779513082320876798154814105f; const F32 RAD_TO_DEG = 57.295779513082320876798154814105f;
const F32 F_APPROXIMATELY_ZERO = 0.00001f; const F32 F_APPROXIMATELY_ZERO = 0.00001f;
const F32 F_LN10 = 2.3025850929940456840179914546844f;
const F32 OO_LN10 = 0.43429448190325182765112891891661f;
const F32 F_LN2 = 0.69314718056f; const F32 F_LN2 = 0.69314718056f;
const F32 OO_LN2 = 1.4426950408889634073599246810019f; const F32 OO_LN2 = 1.4426950408889634073599246810019f;
const F32 F_ALMOST_ZERO = 0.0001f; const F32 F_ALMOST_ZERO = 0.0001f;
const F32 F_ALMOST_ONE = 1.0f - F_ALMOST_ZERO; 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? // BUG: Eliminate in favor of F_APPROXIMATELY_ZERO above?
const F32 FP_MAG_THRESHOLD = 0.0000001f; const F32 FP_MAG_THRESHOLD = 0.0000001f;
@@ -111,6 +118,12 @@ inline bool is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f <
// WARNING: Infinity is comparable with F32_MAX and negative // WARNING: Infinity is comparable with F32_MAX and negative
// infinity is comparable with F32_MIN // infinity is comparable with F32_MIN
// handles negative and positive zeros
inline bool is_zero(F32 x)
{
return (*(U32*)(&x) & 0x7fffffff) == 0;
}
inline bool is_approx_equal(F32 x, F32 y) inline bool is_approx_equal(F32 x, F32 y)
{ {
const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02; const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02;

View File

@@ -24,7 +24,6 @@
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
#include "sys.h"
#include "llmath.h" #include "llmath.h"
static LL_ALIGN_16(const F32 M_IDENT_3A[12]) = static LL_ALIGN_16(const F32 M_IDENT_3A[12]) =

View File

@@ -40,6 +40,7 @@
// 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. // rotation matrix.
LL_ALIGN_PREFIX(16)
class LLMatrix3a class LLMatrix3a
{ {
public: public:
@@ -113,8 +114,9 @@ protected:
LL_ALIGN_16(LLVector4a mColumns[3]); LL_ALIGN_16(LLVector4a mColumns[3]);
}; } LL_ALIGN_POSTFIX(16);
LL_ALIGN_PREFIX(16)
class LLRotation : public LLMatrix3a class LLRotation : public LLMatrix3a
{ {
public: public:
@@ -123,6 +125,6 @@ public:
// Returns true if this rotation is orthonormal with det ~= 1 // Returns true if this rotation is orthonormal with det ~= 1
inline bool isOkRotation() const; inline bool isOkRotation() const;
}; } LL_ALIGN_POSTFIX(16);
#endif #endif

View File

@@ -31,10 +31,72 @@
#include "m4math.h" #include "m4math.h"
#include "m3math.h" #include "m3math.h"
LL_ALIGN_PREFIX(16)
class LLMatrix4a class LLMatrix4a
{ {
public: private:
LL_ALIGN_16(LLVector4a mMatrix[4]); LL_ALIGN_16(LLVector4a mMatrix[4]);
public:
enum
{
ROW_FWD = 0,
ROW_LEFT,
ROW_UP,
ROW_TRANS
};
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
LLMatrix4a()
{}
LLMatrix4a(const LLQuad& q1,const LLQuad& q2,const LLQuad& q3,const LLQuad& q4)
{
mMatrix[0] = q1;
mMatrix[1] = q2;
mMatrix[2] = q3;
mMatrix[3] = q4;
}
LLMatrix4a(const LLQuaternion2& quat)
{
const LLVector4a& xyzw = quat.getVector4a();
LLVector4a nyxwz = _mm_shuffle_ps(xyzw, xyzw, _MM_SHUFFLE(2,3,0,1));
nyxwz.negate();
const LLVector4a xnyynx = _mm_unpacklo_ps(xyzw,nyxwz);
const LLVector4a znwwnz = _mm_unpackhi_ps(xyzw,nyxwz);
LLMatrix4a mata;
mata.setRow<0>(_mm_shuffle_ps(xyzw, xnyynx, _MM_SHUFFLE(0,1,2,3)));
mata.setRow<1>(_mm_shuffle_ps(znwwnz, xyzw, _MM_SHUFFLE(1,0,2,3)));
mata.setRow<2>(_mm_shuffle_ps(xnyynx, xyzw, _MM_SHUFFLE(2,3,3,2)));
mata.setRow<3>(_mm_shuffle_ps(xnyynx, znwwnz, _MM_SHUFFLE(2,3,1,3)));
LLMatrix4a matb;
matb.setRow<0>(_mm_shuffle_ps(xyzw, xnyynx, _MM_SHUFFLE(3,1,2,3)));
matb.setRow<1>(_mm_shuffle_ps(znwwnz, xnyynx, _MM_SHUFFLE(1,0,2,3)));
matb.setRow<2>(_mm_shuffle_ps(xnyynx, znwwnz, _MM_SHUFFLE(3,2,3,2)));
matb.setRow<3>(xyzw);
setMul(matb,mata);
}
inline F32* getF32ptr()
{
return mMatrix[0].getF32ptr();
}
inline const F32* getF32ptr() const
{
return mMatrix[0].getF32ptr();
}
inline void clear() inline void clear()
{ {
@@ -44,13 +106,21 @@ public:
mMatrix[3].clear(); mMatrix[3].clear();
} }
inline void setIdentity()
{
static __m128 ones = _mm_set_ps(1.f,0.f,0.f,1.f);
mMatrix[0] = _mm_movelh_ps(ones,_mm_setzero_ps());
mMatrix[1] = _mm_movehl_ps(_mm_setzero_ps(),ones);
mMatrix[2] = _mm_movelh_ps(_mm_setzero_ps(),ones);
mMatrix[3] = _mm_movehl_ps(ones,_mm_setzero_ps());
}
inline void loadu(const LLMatrix4& src) inline void loadu(const LLMatrix4& src)
{ {
mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]); mMatrix[0].loadua(src.mMatrix[0]);
mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]); mMatrix[1].loadua(src.mMatrix[1]);
mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]); mMatrix[2].loadua(src.mMatrix[2]);
mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]); mMatrix[3].loadua(src.mMatrix[3]);
} }
inline void loadu(const LLMatrix3& src) inline void loadu(const LLMatrix3& src)
@@ -61,6 +131,14 @@ public:
mMatrix[3].set(0,0,0,1.f); mMatrix[3].set(0,0,0,1.f);
} }
inline void loadu(const F32* src)
{
mMatrix[0].loadua(src+0);
mMatrix[1].loadua(src+4);
mMatrix[2].loadua(src+8);
mMatrix[3].loadua(src+12);
}
inline void add(const LLMatrix4a& rhs) inline void add(const LLMatrix4a& rhs)
{ {
mMatrix[0].add(rhs.mMatrix[0]); mMatrix[0].add(rhs.mMatrix[0]);
@@ -69,6 +147,75 @@ public:
mMatrix[3].add(rhs.mMatrix[3]); mMatrix[3].add(rhs.mMatrix[3]);
} }
inline void mul(const LLMatrix4a& rhs)
{
//Not using rotate4 to avoid extra copy of *this.
LLVector4a x0,y0,z0,w0;
LLVector4a x1,y1,z1,w1;
LLVector4a x2,y2,z2,w2;
LLVector4a x3,y3,z3,w3;
//16 shuffles
x0.splat<0>(rhs.mMatrix[0]);
x1.splat<0>(rhs.mMatrix[1]);
x2.splat<0>(rhs.mMatrix[2]);
x3.splat<0>(rhs.mMatrix[3]);
y0.splat<1>(rhs.mMatrix[0]);
y1.splat<1>(rhs.mMatrix[1]);
y2.splat<1>(rhs.mMatrix[2]);
y3.splat<1>(rhs.mMatrix[3]);
z0.splat<2>(rhs.mMatrix[0]);
z1.splat<2>(rhs.mMatrix[1]);
z2.splat<2>(rhs.mMatrix[2]);
z3.splat<2>(rhs.mMatrix[3]);
w0.splat<3>(rhs.mMatrix[0]);
w1.splat<3>(rhs.mMatrix[1]);
w2.splat<3>(rhs.mMatrix[2]);
w3.splat<3>(rhs.mMatrix[3]);
//16 muls
x0.mul(mMatrix[0]);
x1.mul(mMatrix[0]);
x2.mul(mMatrix[0]);
x3.mul(mMatrix[0]);
y0.mul(mMatrix[1]);
y1.mul(mMatrix[1]);
y2.mul(mMatrix[1]);
y3.mul(mMatrix[1]);
z0.mul(mMatrix[2]);
z1.mul(mMatrix[2]);
z2.mul(mMatrix[2]);
z3.mul(mMatrix[2]);
w0.mul(mMatrix[3]);
w1.mul(mMatrix[3]);
w2.mul(mMatrix[3]);
w3.mul(mMatrix[3]);
//12 adds
x0.add(y0);
z0.add(w0);
x1.add(y1);
z1.add(w1);
x2.add(y2);
z2.add(w2);
x3.add(y3);
z3.add(w3);
mMatrix[0].setAdd(x0,z0);
mMatrix[1].setAdd(x1,z1);
mMatrix[2].setAdd(x2,z2);
mMatrix[3].setAdd(x3,z3);
}
inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2) inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2)
{ {
mMatrix[0] = r0; mMatrix[0] = r0;
@@ -76,6 +223,44 @@ public:
mMatrix[2] = r2; mMatrix[2] = r2;
} }
template<int N>
inline void setRow(const LLVector4a& row)
{
mMatrix[N] = row;
}
template<int N>
inline const LLVector4a& getRow() const
{
return mMatrix[N];
}
template<int N>
inline LLVector4a& getRow()
{
return mMatrix[N];
}
template<int N>
inline void setColumn(const LLVector4a& col)
{
mMatrix[0].copyComponent<N>(col.getScalarAt<0>());
mMatrix[1].copyComponent<N>(col.getScalarAt<1>());
mMatrix[2].copyComponent<N>(col.getScalarAt<2>());
mMatrix[3].copyComponent<N>(col.getScalarAt<3>());
}
template<int N>
inline LLVector4a getColumn()
{
LLVector4a v;
v.copyComponent<0>(mMatrix[0].getScalarAt<N>());
v.copyComponent<1>(mMatrix[1].getScalarAt<N>());
v.copyComponent<2>(mMatrix[2].getScalarAt<N>());
v.copyComponent<3>(mMatrix[3].getScalarAt<N>());
return v;
}
inline void setMul(const LLMatrix4a& m, const F32 s) inline void setMul(const LLMatrix4a& m, const F32 s)
{ {
mMatrix[0].setMul(m.mMatrix[0], s); mMatrix[0].setMul(m.mMatrix[0], s);
@@ -84,6 +269,14 @@ public:
mMatrix[3].setMul(m.mMatrix[3], s); mMatrix[3].setMul(m.mMatrix[3], s);
} }
inline void setMul(const LLMatrix4a& m0, const LLMatrix4a& m1)
{
m0.rotate4(m1.mMatrix[0],mMatrix[0]);
m0.rotate4(m1.mMatrix[1],mMatrix[1]);
m0.rotate4(m1.mMatrix[2],mMatrix[2]);
m0.rotate4(m1.mMatrix[3],mMatrix[3]);
}
inline void setLerp(const LLMatrix4a& a, const LLMatrix4a& b, F32 w) inline void setLerp(const LLMatrix4a& a, const LLMatrix4a& b, F32 w)
{ {
LLVector4a d0,d1,d2,d3; LLVector4a d0,d1,d2,d3;
@@ -107,13 +300,14 @@ public:
//Singu Note: Don't mess with this. It's intentionally different from LL's. //Singu Note: Don't mess with this. It's intentionally different from LL's.
// Note how res isn't manipulated until the very end. // Note how res isn't manipulated until the very end.
//Fast(er). Treats v[VW] as 0.f
inline void rotate(const LLVector4a& v, LLVector4a& res) const inline void rotate(const LLVector4a& v, LLVector4a& res) const
{ {
LLVector4a x,y,z; LLVector4a x,y,z;
x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); x.splat<0>(v);
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); y.splat<1>(v);
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); z.splat<2>(v);
x.mul(mMatrix[0]); x.mul(mMatrix[0]);
y.mul(mMatrix[1]); y.mul(mMatrix[1]);
@@ -123,14 +317,15 @@ public:
res.setAdd(x,z); res.setAdd(x,z);
} }
//Proper. v[VW] as v[VW]
inline void rotate4(const LLVector4a& v, LLVector4a& res) const inline void rotate4(const LLVector4a& v, LLVector4a& res) const
{ {
LLVector4a x,y,z,w; LLVector4a x,y,z,w;
x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); x.splat<0>(v);
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); y.splat<1>(v);
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); z.splat<2>(v);
w = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3)); w.splat<3>(v);
x.mul(mMatrix[0]); x.mul(mMatrix[0]);
y.mul(mMatrix[1]); y.mul(mMatrix[1]);
@@ -142,13 +337,14 @@ public:
res.setAdd(x,z); res.setAdd(x,z);
} }
//Fast(er). Treats v[VW] as 1.f
inline void affineTransform(const LLVector4a& v, LLVector4a& res) const inline void affineTransform(const LLVector4a& v, LLVector4a& res) const
{ {
LLVector4a x,y,z; LLVector4a x,y,z;
x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); x.splat<0>(v);
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); y.splat<1>(v);
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); z.splat<2>(v);
x.mul(mMatrix[0]); x.mul(mMatrix[0]);
y.mul(mMatrix[1]); y.mul(mMatrix[1]);
@@ -158,6 +354,348 @@ public:
z.add(mMatrix[3]); z.add(mMatrix[3]);
res.setAdd(x,z); res.setAdd(x,z);
} }
};
inline void perspectiveTransform(const LLVector4a& v, LLVector4a& res) const
{
LLVector4a x,y,z,s,t,p,q;
x.splat<0>(v);
y.splat<1>(v);
z.splat<2>(v);
s.splat<3>(mMatrix[0]);
t.splat<3>(mMatrix[1]);
p.splat<3>(mMatrix[2]);
q.splat<3>(mMatrix[3]);
s.mul(x);
t.mul(y);
p.mul(z);
q.add(s);
t.add(p);
q.add(t);
x.mul(mMatrix[0]);
y.mul(mMatrix[1]);
z.mul(mMatrix[2]);
x.add(y);
z.add(mMatrix[3]);
res.setAdd(x,z);
res.div(q);
}
inline void transpose()
{
__m128 q1 = _mm_unpackhi_ps(mMatrix[0],mMatrix[1]);
__m128 q2 = _mm_unpacklo_ps(mMatrix[0],mMatrix[1]);
__m128 q3 = _mm_unpacklo_ps(mMatrix[2],mMatrix[3]);
__m128 q4 = _mm_unpackhi_ps(mMatrix[2],mMatrix[3]);
mMatrix[0] = _mm_movelh_ps(q2,q3);
mMatrix[1] = _mm_movehl_ps(q3,q2);
mMatrix[2] = _mm_movelh_ps(q1,q4);
mMatrix[3] = _mm_movehl_ps(q4,q1);
}
// Following procedure adapted from:
// http://software.intel.com/en-us/articles/optimized-matrix-library-for-use-with-the-intel-pentiumr-4-processors-sse2-instructions/
//
// License/Copyright Statement:
//
// Copyright (c) 2001 Intel Corporation.
//
// Permition is granted to use, copy, distribute and prepare derivative works
// of this library for any purpose and without fee, provided, that the above
// copyright notice and this statement appear in all copies.
// Intel makes no representations about the suitability of this library for
// any purpose, and specifically disclaims all warranties.
// See LEGAL-intel_matrixlib.TXT for all the legal information.
inline float invert()
{
LL_ALIGN_16(const unsigned int Sign_PNNP[4]) = { 0x00000000, 0x80000000, 0x80000000, 0x00000000 };
// The inverse is calculated using "Divide and Conquer" technique. The
// original matrix is divide into four 2x2 sub-matrices. Since each
// register holds four matrix element, the smaller matrices are
// represented as a registers. Hence we get a better locality of the
// calculations.
LLVector4a A = _mm_movelh_ps(mMatrix[0], mMatrix[1]), // the four sub-matrices
B = _mm_movehl_ps(mMatrix[1], mMatrix[0]),
C = _mm_movelh_ps(mMatrix[2], mMatrix[3]),
D = _mm_movehl_ps(mMatrix[3], mMatrix[2]);
LLVector4a iA, iB, iC, iD, // partial inverse of the sub-matrices
DC, AB;
LLSimdScalar dA, dB, dC, dD; // determinant of the sub-matrices
LLSimdScalar det, d, d1, d2;
LLVector4a rd;
// AB = A# * B
AB.setMul(_mm_shuffle_ps(A,A,0x0F), B);
AB.sub(_mm_mul_ps(_mm_shuffle_ps(A,A,0xA5), _mm_shuffle_ps(B,B,0x4E)));
// DC = D# * C
DC.setMul(_mm_shuffle_ps(D,D,0x0F), C);
DC.sub(_mm_mul_ps(_mm_shuffle_ps(D,D,0xA5), _mm_shuffle_ps(C,C,0x4E)));
// dA = |A|
dA = _mm_mul_ps(_mm_shuffle_ps(A, A, 0x5F),A);
dA -= _mm_movehl_ps(dA,dA);
// dB = |B|
dB = _mm_mul_ps(_mm_shuffle_ps(B, B, 0x5F),B);
dB -= _mm_movehl_ps(dB,dB);
// dC = |C|
dC = _mm_mul_ps(_mm_shuffle_ps(C, C, 0x5F),C);
dC -= _mm_movehl_ps(dC,dC);
// dD = |D|
dD = _mm_mul_ps(_mm_shuffle_ps(D, D, 0x5F),D);
dD -= _mm_movehl_ps(dD,dD);
// d = trace(AB*DC) = trace(A#*B*D#*C)
d = _mm_mul_ps(_mm_shuffle_ps(DC,DC,0xD8),AB);
// iD = C*A#*B
iD.setMul(_mm_shuffle_ps(C,C,0xA0), _mm_movelh_ps(AB,AB));
iD.add(_mm_mul_ps(_mm_shuffle_ps(C,C,0xF5), _mm_movehl_ps(AB,AB)));
// iA = B*D#*C
iA.setMul(_mm_shuffle_ps(B,B,0xA0), _mm_movelh_ps(DC,DC));
iA.add(_mm_mul_ps(_mm_shuffle_ps(B,B,0xF5), _mm_movehl_ps(DC,DC)));
// d = trace(AB*DC) = trace(A#*B*D#*C) [continue]
d = _mm_add_ps(d, _mm_movehl_ps(d, d));
d += _mm_shuffle_ps(d, d, 1);
d1 = dA*dD;
d2 = dB*dC;
// iD = D*|A| - C*A#*B
iD.setSub(_mm_mul_ps(D,_mm_shuffle_ps(dA,dA,0)), iD);
// iA = A*|D| - B*D#*C;
iA.setSub(_mm_mul_ps(A,_mm_shuffle_ps(dD,dD,0)), iA);
// det = |A|*|D| + |B|*|C| - trace(A#*B*D#*C)
det = d1+d2-d;
__m128 is_zero_mask = _mm_cmpeq_ps(det,_mm_setzero_ps());
rd = _mm_div_ss(_mm_set_ss(1.f),_mm_or_ps(_mm_andnot_ps(is_zero_mask, det), _mm_and_ps(is_zero_mask, _mm_set_ss(1.f))));
#ifdef ZERO_SINGULAR
rd = _mm_and_ps(_mm_cmpneq_ss(det,_mm_setzero_ps()), rd);
#endif
// iB = D * (A#B)# = D*B#*A
iB.setMul(D, _mm_shuffle_ps(AB,AB,0x33));
iB.sub(_mm_mul_ps(_mm_shuffle_ps(D,D,0xB1), _mm_shuffle_ps(AB,AB,0x66)));
// iC = A * (D#C)# = A*C#*D
iC.setMul(A, _mm_shuffle_ps(DC,DC,0x33));
iC.sub(_mm_mul_ps(_mm_shuffle_ps(A,A,0xB1), _mm_shuffle_ps(DC,DC,0x66)));
rd = _mm_shuffle_ps(rd,rd,0);
rd = _mm_xor_ps(rd, _mm_load_ps((const float*)Sign_PNNP));
// iB = C*|B| - D*B#*A
iB.setSub(_mm_mul_ps(C,_mm_shuffle_ps(dB,dB,0)), iB);
// iC = B*|C| - A*C#*D;
iC.setSub(_mm_mul_ps(B,_mm_shuffle_ps(dC,dC,0)), iC);
// iX = iX / det
iA.mul(rd);
iB.mul(rd);
iC.mul(rd);
iD.mul(rd);
mMatrix[0] = _mm_shuffle_ps(iA,iB,0x77);
mMatrix[1] = _mm_shuffle_ps(iA,iB,0x22);
mMatrix[2] = _mm_shuffle_ps(iC,iD,0x77);
mMatrix[3] = _mm_shuffle_ps(iC,iD,0x22);
F32 ret;
_mm_store_ss(&ret,det);
return ret;
}
//=============Affine transformation matrix only=========================
//Multiply matrix with a pure translation matrix.
inline void applyTranslation_affine(const F32& x, const F32& y, const F32& z)
{
const LLVector4a xyz0(x,y,z,0); //load
LLVector4a xxxx;
xxxx.splat<0>(xyz0);
LLVector4a yyyy;
yyyy.splat<1>(xyz0);
LLVector4a zzzz;
zzzz.splat<2>(xyz0);
LLVector4a sum1;
LLVector4a sum2;
LLVector4a sum3;
sum1.setMul(xxxx,mMatrix[0]);
sum2.setMul(yyyy,mMatrix[1]);
sum3.setMul(zzzz,mMatrix[2]);
mMatrix[3].add(sum1);
mMatrix[3].add(sum2);
mMatrix[3].add(sum3);
}
//Multiply matrix with a pure translation matrix.
inline void applyTranslation_affine(const LLVector3& trans)
{
applyTranslation_affine(trans.mV[VX],trans.mV[VY],trans.mV[VZ]);
}
//Multiply matrix with a pure scale matrix.
inline void applyScale_affine(const F32& x, const F32& y, const F32& z)
{
const LLVector4a xyz0(x,y,z,0); //load
LLVector4a xxxx;
xxxx.splat<0>(xyz0);
LLVector4a yyyy;
yyyy.splat<1>(xyz0);
LLVector4a zzzz;
zzzz.splat<2>(xyz0);
mMatrix[0].mul(xxxx);
mMatrix[1].mul(yyyy);
mMatrix[2].mul(zzzz);
}
//Multiply matrix with a pure scale matrix.
inline void applyScale_affine(const LLVector3& scale)
{
applyScale_affine(scale.mV[VX],scale.mV[VY],scale.mV[VZ]);
}
//Multiply matrix with a pure scale matrix.
inline void applyScale_affine(const F32& s)
{
const LLVector4a scale(s); //load
mMatrix[0].mul(scale);
mMatrix[1].mul(scale);
mMatrix[2].mul(scale);
}
//Direct addition to row3.
inline void translate_affine(const LLVector3& trans)
{
LLVector4a translation;
translation.load3(trans.mV);
mMatrix[3].add(translation);
}
//Direct assignment of row3.
inline void setTranslate_affine(const LLVector3& trans)
{
static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[3*4]);
LLVector4a translation;
translation.load3(trans.mV);
mMatrix[3].setSelectWithMask(mask,mMatrix[3],translation);
}
inline void mul_affine(const LLMatrix4a& rhs)
{
LLVector4a x0,y0,z0;
LLVector4a x1,y1,z1;
LLVector4a x2,y2,z2;
LLVector4a x3,y3,z3;
//12 shuffles
x0.splat<0>(rhs.mMatrix[0]);
x1.splat<0>(rhs.mMatrix[1]);
x2.splat<0>(rhs.mMatrix[2]);
x3.splat<0>(rhs.mMatrix[3]);
y0.splat<1>(rhs.mMatrix[0]);
y1.splat<1>(rhs.mMatrix[1]);
y2.splat<1>(rhs.mMatrix[2]);
y3.splat<1>(rhs.mMatrix[3]);
z0.splat<2>(rhs.mMatrix[0]);
z1.splat<2>(rhs.mMatrix[1]);
z2.splat<2>(rhs.mMatrix[2]);
z3.splat<2>(rhs.mMatrix[3]);
//12 muls
x0.mul(mMatrix[0]);
x1.mul(mMatrix[0]);
x2.mul(mMatrix[0]);
x3.mul(mMatrix[0]);
y0.mul(mMatrix[1]);
y1.mul(mMatrix[1]);
y2.mul(mMatrix[1]);
y3.mul(mMatrix[1]);
z0.mul(mMatrix[2]);
z1.mul(mMatrix[2]);
z2.mul(mMatrix[2]);
z3.mul(mMatrix[2]);
//9 adds
x0.add(y0);
x1.add(y1);
x2.add(y2);
x3.add(y3);
z3.add(mMatrix[3]);
mMatrix[0].setAdd(x0,z0);
mMatrix[1].setAdd(x1,z1);
mMatrix[2].setAdd(x2,z2);
mMatrix[3].setAdd(x3,z3);
}
inline void extractRotation_affine()
{
static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[3*4]);
mMatrix[0].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[0]);
mMatrix[1].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[1]);
mMatrix[2].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[2]);
mMatrix[3].setSelectWithMask(mask,LLVector4a(1.f),_mm_setzero_ps());
}
//======================Logic====================
private:
template<bool mins> inline void init_foos(LLMatrix4a& foos) const
{
static bool done(false);
if (done) return;
const LLVector4a delta(0.0001f);
foos.setIdentity();
foos.getRow<0>().sub(delta);
foos.getRow<1>().sub(delta);
foos.getRow<2>().sub(delta);
foos.getRow<3>().sub(delta);
done = true;
}
public:
inline bool isIdentity() const
{
static LLMatrix4a mins;
static LLMatrix4a maxs;
init_foos<false>(mins);
init_foos<true>(maxs);
LLVector4a mask1 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[0],mins.getRow<0>()), _mm_cmplt_ps(mMatrix[0],maxs.getRow<0>()));
LLVector4a mask2 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[1],mins.getRow<1>()), _mm_cmplt_ps(mMatrix[1],maxs.getRow<1>()));
LLVector4a mask3 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[2],mins.getRow<2>()), _mm_cmplt_ps(mMatrix[2],maxs.getRow<2>()));
LLVector4a mask4 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[3],mins.getRow<3>()), _mm_cmplt_ps(mMatrix[3],maxs.getRow<3>()));
mask1 = _mm_and_ps(mask1,mask2);
mask2 = _mm_and_ps(mask3,mask4);
return _mm_movemask_epi8(_mm_castps_si128(_mm_and_ps(mask1, mask2))) == 0xFFFF;
}
} LL_ALIGN_POSTFIX(16);
#endif #endif

View File

@@ -2,36 +2,28 @@
* @file llmodularmath.cpp * @file llmodularmath.cpp
* @brief LLModularMath class implementation * @brief LLModularMath class implementation
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlife.com/developers/opensource/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*
*/ */
#include "linden_common.h" #include "linden_common.h"
// implementation is all in the header, this include dep ensures the unit test is rerun if the implementation changes. // implementation is all in the header, this include dep ensures the unit test is rerun if the implementation changes.

View File

@@ -2,31 +2,25 @@
* @file llmodularmath.h * @file llmodularmath.h
* @brief Useful modular math functions. * @brief Useful modular math functions.
* *
* $LicenseInfo:firstyear=2008&license=viewergpl$ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
*
* Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -932,10 +932,10 @@ protected:
MIN = 3 MIN = 3
} eDName; } eDName;
LLVector4a mCenter; LL_ALIGN_16(LLVector4a mCenter);
LLVector4a mSize; LL_ALIGN_16(LLVector4a mSize);
LLVector4a mMax; LL_ALIGN_16(LLVector4a mMax);
LLVector4a mMin; LL_ALIGN_16(LLVector4a mMin);
oct_node* mParent; oct_node* mParent;
U8 mOctant; U8 mOctant;
@@ -965,6 +965,26 @@ public:
{ {
} }
#ifdef LL_OCTREE_POOLS
void* operator new(size_t size)
{
return LLOctreeNode<T>::getPool(size).malloc();
}
void operator delete(void* ptr)
{
LLOctreeNode<T>::getPool(sizeof(LLOctreeNode<T>)).free(ptr);
}
#else
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
#endif
bool balance() bool balance()
{ {
if (this->getChildCount() == 1 && if (this->getChildCount() == 1 &&

View File

@@ -1,31 +1,25 @@
/** /**
* @file llperlin.cpp * @file llperlin.cpp
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -1,31 +1,25 @@
/** /**
* @file llperlin.h * @file llperlin.h
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -101,7 +101,7 @@ public:
} }
private: private:
LLVector4a mV; LL_ALIGN_16(LLVector4a mV);
} LL_ALIGN_POSTFIX(16); } LL_ALIGN_POSTFIX(16);

View File

@@ -58,34 +58,40 @@ LLQuaternion::LLQuaternion(const LLMatrix3 &mat)
LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec) LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec)
{ {
LLVector3 v(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
v.normalize(); if (mag > FP_MAG_THRESHOLD)
{
F32 c, s; angle *= 0.5;
c = cosf(angle*0.5f); F32 c = cosf(angle);
s = sinf(angle*0.5f); F32 s = sinf(angle) / mag;
mQ[VX] = vec.mV[VX] * s;
mQ[VX] = v.mV[VX] * s; mQ[VY] = vec.mV[VY] * s;
mQ[VY] = v.mV[VY] * s; mQ[VZ] = vec.mV[VZ] * s;
mQ[VZ] = v.mV[VZ] * s; mQ[VW] = c;
mQ[VW] = c; }
normalize(); else
{
loadIdentity();
}
} }
LLQuaternion::LLQuaternion(F32 angle, const LLVector3 &vec) LLQuaternion::LLQuaternion(F32 angle, const LLVector3 &vec)
{ {
LLVector3 v(vec); F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
v.normalize(); if (mag > FP_MAG_THRESHOLD)
{
F32 c, s; angle *= 0.5;
c = cosf(angle*0.5f); F32 c = cosf(angle);
s = sinf(angle*0.5f); F32 s = sinf(angle) / mag;
mQ[VX] = vec.mV[VX] * s;
mQ[VX] = v.mV[VX] * s; mQ[VY] = vec.mV[VY] * s;
mQ[VY] = v.mV[VY] * s; mQ[VZ] = vec.mV[VZ] * s;
mQ[VZ] = v.mV[VZ] * s; mQ[VW] = c;
mQ[VW] = c; }
normalize(); else
{
loadIdentity();
}
} }
LLQuaternion::LLQuaternion(const LLVector3 &x_axis, LLQuaternion::LLQuaternion(const LLVector3 &x_axis,
@@ -136,57 +142,61 @@ void LLQuaternion::quantize8(F32 lower, F32 upper)
const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, F32 x, F32 y, F32 z) const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, F32 x, F32 y, F32 z)
{ {
LLVector3 vec(x, y, z); F32 mag = sqrtf(x * x + y * y + z * z);
vec.normalize(); if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5f; angle *= 0.5;
F32 c, s; F32 c = cosf(angle);
c = cosf(angle); F32 s = sinf(angle) / mag;
s = sinf(angle); mQ[VX] = x * s;
mQ[VY] = y * s;
mQ[VX] = vec.mV[VX]*s; mQ[VZ] = z * s;
mQ[VY] = vec.mV[VY]*s; mQ[VW] = c;
mQ[VZ] = vec.mV[VZ]*s; }
mQ[VW] = c; else
{
normalize(); loadIdentity();
}
return (*this); return (*this);
} }
const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector3 &vec) const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector3 &vec)
{ {
LLVector3 v(vec); F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
v.normalize(); if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5f; angle *= 0.5;
F32 c, s; F32 c = cosf(angle);
c = cosf(angle); F32 s = sinf(angle) / mag;
s = sinf(angle); mQ[VX] = vec.mV[VX] * s;
mQ[VY] = vec.mV[VY] * s;
mQ[VX] = v.mV[VX]*s; mQ[VZ] = vec.mV[VZ] * s;
mQ[VY] = v.mV[VY]*s; mQ[VW] = c;
mQ[VZ] = v.mV[VZ]*s; }
mQ[VW] = c; else
{
normalize(); loadIdentity();
}
return (*this); return (*this);
} }
const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector4 &vec) const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector4 &vec)
{ {
LLVector3 v(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
v.normalize(); if (mag > FP_MAG_THRESHOLD)
{
F32 c, s; angle *= 0.5;
c = cosf(angle*0.5f); F32 c = cosf(angle);
s = sinf(angle*0.5f); F32 s = sinf(angle) / mag;
mQ[VX] = vec.mV[VX] * s;
mQ[VX] = v.mV[VX]*s; mQ[VY] = vec.mV[VY] * s;
mQ[VY] = v.mV[VY]*s; mQ[VZ] = vec.mV[VZ] * s;
mQ[VZ] = v.mV[VZ]*s; mQ[VW] = c;
mQ[VW] = c; }
else
normalize(); {
loadIdentity();
}
return (*this); return (*this);
} }
@@ -219,68 +229,80 @@ const LLQuaternion& LLQuaternion::set(const LLMatrix4 &mat)
// deprecated // deprecated
const LLQuaternion& LLQuaternion::setQuat(F32 angle, F32 x, F32 y, F32 z) const LLQuaternion& LLQuaternion::setQuat(F32 angle, F32 x, F32 y, F32 z)
{ {
LLVector3 vec(x, y, z); F32 mag = sqrtf(x * x + y * y + z * z);
vec.normalize(); if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5f; angle *= 0.5;
F32 c, s; F32 c = cosf(angle);
c = cosf(angle); F32 s = sinf(angle) / mag;
s = sinf(angle); mQ[VX] = x * s;
mQ[VY] = y * s;
mQ[VX] = vec.mV[VX]*s; mQ[VZ] = z * s;
mQ[VY] = vec.mV[VY]*s; mQ[VW] = c;
mQ[VZ] = vec.mV[VZ]*s; }
mQ[VW] = c; else
{
normalize(); loadIdentity();
}
return (*this); return (*this);
} }
// deprecated // deprecated
const LLQuaternion& LLQuaternion::setQuat(F32 angle, const LLVector3 &vec) const LLQuaternion& LLQuaternion::setQuat(F32 angle, const LLVector3 &vec)
{ {
LLVector3 v(vec); F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
v.normalize(); if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5f; angle *= 0.5;
F32 c, s; F32 c = cosf(angle);
c = cosf(angle); F32 s = sinf(angle) / mag;
s = sinf(angle); mQ[VX] = vec.mV[VX] * s;
mQ[VY] = vec.mV[VY] * s;
mQ[VX] = v.mV[VX]*s; mQ[VZ] = vec.mV[VZ] * s;
mQ[VY] = v.mV[VY]*s; mQ[VW] = c;
mQ[VZ] = v.mV[VZ]*s; }
mQ[VW] = c; else
{
normalize(); loadIdentity();
}
return (*this); return (*this);
} }
const LLQuaternion& LLQuaternion::setQuat(F32 angle, const LLVector4 &vec) const LLQuaternion& LLQuaternion::setQuat(F32 angle, const LLVector4 &vec)
{ {
LLVector3 v(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
v.normalize(); if (mag > FP_MAG_THRESHOLD)
{
F32 c, s; angle *= 0.5;
c = cosf(angle*0.5f); F32 c = cosf(angle);
s = sinf(angle*0.5f); F32 s = sinf(angle) / mag;
mQ[VX] = vec.mV[VX] * s;
mQ[VX] = v.mV[VX]*s; mQ[VY] = vec.mV[VY] * s;
mQ[VY] = v.mV[VY]*s; mQ[VZ] = vec.mV[VZ] * s;
mQ[VZ] = v.mV[VZ]*s; mQ[VW] = c;
mQ[VW] = c; }
else
normalize(); {
loadIdentity();
}
return (*this); return (*this);
} }
const LLQuaternion& LLQuaternion::setQuat(F32 roll, F32 pitch, F32 yaw) const LLQuaternion& LLQuaternion::setQuat(F32 roll, F32 pitch, F32 yaw)
{ {
LLMatrix3 rot_mat(roll, pitch, yaw); roll *= 0.5f;
rot_mat.orthogonalize(); pitch *= 0.5f;
*this = rot_mat.quaternion(); yaw *= 0.5f;
F32 sinX = sinf(roll);
normalize(); 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); return (*this);
} }
@@ -425,68 +447,44 @@ LLMatrix4 LLQuaternion::getMatrix4(void) const
// calculate the shortest rotation from a to b // calculate the shortest rotation from a to b
void LLQuaternion::shortestArc(const LLVector3 &a, const LLVector3 &b) void LLQuaternion::shortestArc(const LLVector3 &a, const LLVector3 &b)
{ {
// Make a local copy of both vectors. F32 ab = a * b; // dotproduct
LLVector3 vec_a = a; LLVector3 c = a % b; // crossproduct
LLVector3 vec_b = b; F32 cc = c * c; // squared length of the crossproduct
if (ab * ab + cc) // test if the arguments have sufficient magnitude
// Make sure neither vector is zero length. Also normalize
// the vectors while we are at it.
F32 vec_a_mag = vec_a.normalize();
F32 vec_b_mag = vec_b.normalize();
if (vec_a_mag < F_APPROXIMATELY_ZERO ||
vec_b_mag < F_APPROXIMATELY_ZERO)
{ {
// Can't calculate a rotation from this. if (cc > 0.0f) // test if the arguments are (anti)parallel
// Just return ZERO_ROTATION instead.
loadIdentity();
return;
}
// Create an axis to rotate around, and the cos of the angle to rotate.
LLVector3 axis = vec_a % vec_b;
F32 cos_theta = vec_a * vec_b;
// Check the angle between the vectors to see if they are parallel or anti-parallel.
if (cos_theta > 1.0 - F_APPROXIMATELY_ZERO)
{
// a and b are parallel. No rotation is necessary.
loadIdentity();
}
else if (cos_theta < -1.0 + F_APPROXIMATELY_ZERO)
{
// a and b are anti-parallel.
// Rotate 180 degrees around some orthogonal axis.
// Find the projection of the x-axis onto a, and try
// using the vector between the projection and the x-axis
// as the orthogonal axis.
LLVector3 proj = vec_a.mV[VX] / (vec_a * vec_a) * vec_a;
LLVector3 ortho_axis(1.f, 0.f, 0.f);
ortho_axis -= proj;
// Turn this into an orthonormal axis.
F32 ortho_length = ortho_axis.normalize();
// If the axis' length is 0, then our guess at an orthogonal axis
// was wrong (a is parallel to the x-axis).
if (ortho_length < F_APPROXIMATELY_ZERO)
{ {
// Use the z-axis instead. F32 s = sqrtf(ab * ab + cc) + ab; // note: don't try to optimize this line
ortho_axis.setVec(0.f, 0.f, 1.f); 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;
}
} }
// Construct a quaternion from this orthonormal axis.
mQ[VX] = ortho_axis.mV[VX];
mQ[VY] = ortho_axis.mV[VY];
mQ[VZ] = ortho_axis.mV[VZ];
mQ[VW] = 0.f;
}
else
{
// a and b are NOT parallel or anti-parallel.
// Return the rotation between these vectors.
F32 theta = (F32)acos(cos_theta);
setAngleAxis(theta, axis);
} }
loadIdentity();
} }
// constrains rotation to a cone angle specified in radians // constrains rotation to a cone angle specified in radians
@@ -838,79 +836,82 @@ LLQuaternion::Order StringToOrder( const char *str )
void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const
{ {
F32 cos_a = mQ[VW]; F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]); // length of the vector-component
if (cos_a > 1.0f) cos_a = 1.0f; if (v > FP_MAG_THRESHOLD)
if (cos_a < -1.0f) cos_a = -1.0f;
F32 sin_a = (F32) sqrt( 1.0f - cos_a * cos_a );
if ( fabs( sin_a ) < 0.0005f )
sin_a = 1.0f;
else
sin_a = 1.f/sin_a;
F32 temp_angle = 2.0f * (F32) acos( cos_a );
if (temp_angle > F_PI)
{ {
// The (angle,axis) pair should never have angles outside [PI, -PI] F32 oomag = 1.0f / v;
// since we want the _shortest_ (angle,axis) solution. F32 w = mQ[VW];
// Since acos is defined for [0, PI], and we multiply by 2.0, we if (mQ[VW] < 0.0f)
// can push the angle outside the acceptible range. {
// When this happens we set the angle to the other portion of a w = -w; // make VW positive
// full 2PI rotation, and negate the axis, which reverses the oomag = -oomag; // invert the axis
// direction of the rotation (by the right-hand rule). }
*angle = 2.f * F_PI - temp_angle; vec.mV[VX] = mQ[VX] * oomag; // normalize the axis
vec.mV[VX] = - mQ[VX] * sin_a; vec.mV[VY] = mQ[VY] * oomag;
vec.mV[VY] = - mQ[VY] * sin_a; vec.mV[VZ] = mQ[VZ] * oomag;
vec.mV[VZ] = - mQ[VZ] * sin_a; *angle = 2.0f * atan2f(v, w); // get the angle
} }
else else
{ {
*angle = temp_angle; *angle = 0.0f; // no rotation
vec.mV[VX] = mQ[VX] * sin_a; vec.mV[VX] = 0.0f; // around some dummy axis
vec.mV[VY] = mQ[VY] * sin_a; vec.mV[VY] = 0.0f;
vec.mV[VZ] = mQ[VZ] * sin_a; vec.mV[VZ] = 1.0f;
} }
} }
// quaternion does not need to be normalized // quaternion does not need to be normalized
void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const
{ {
LLMatrix3 rot_mat(*this); F32 sx = 2 * (mQ[VX] * mQ[VW] - mQ[VY] * mQ[VZ]); // sine of the roll
rot_mat.orthogonalize(); F32 sy = 2 * (mQ[VY] * mQ[VW] + mQ[VX] * mQ[VZ]); // sine of the pitch
rot_mat.getEulerAngles(roll, pitch, yaw); 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
// // NOTE: LLQuaternion's are actually inverted with respect to F32 cx = ys - xz; // cosine of the roll
// // the matrices, so this code also assumes inverted quaternions F32 cy = sqrtf(sx * sx + cx * cx); // cosine of the pitch
// // (-x, -y, -z, w). The result is that roll,pitch,yaw are applied if (cy > GIMBAL_THRESHOLD) // no gimbal lock
// // in reverse order (yaw,pitch,roll). {
// F32 x = -mQ[VX], y = -mQ[VY], z = -mQ[VZ], w = mQ[VW]; *roll = atan2f(sx, cx);
// F64 m20 = 2.0*(x*z-y*w); *pitch = atan2f(sy, cy);
// if (1.0f - fabsf(m20) < F_APPROXIMATELY_ZERO) *yaw = atan2f(2 * (mQ[VZ] * mQ[VW] - mQ[VX] * mQ[VY]), ys + xz);
// { }
// *roll = 0.0f; else // gimbal lock
// *pitch = (F32)asin(m20); {
// *yaw = (F32)atan2(2.0*(x*y-z*w), 1.0 - 2.0*(x*x+z*z)); if (sy > 0)
// } {
// else *pitch = F_PI_BY_TWO;
// { *yaw = 2 * atan2f(mQ[VZ] + mQ[VX], mQ[VW] + mQ[VY]);
// *roll = (F32)atan2(-2.0*(y*z+x*w), 1.0-2.0*(x*x+y*y)); }
// *pitch = (F32)asin(m20); else
// *yaw = (F32)atan2(-2.0*(x*y+z*w), 1.0-2.0*(y*y+z*z)); {
// } *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 // Saves space by using the fact that our quaternions are normalized
LLVector3 LLQuaternion::packToVector3() const 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 ) if( mQ[VW] >= 0 )
{ {
return LLVector3( mQ[VX], mQ[VY], mQ[VZ] ); return LLVector3( x, y , z );
} }
else else
{ {
return LLVector3( -mQ[VX], -mQ[VY], -mQ[VZ] ); return LLVector3( -x, -y, -z );
} }
} }

View File

@@ -304,43 +304,29 @@ inline const LLQuaternion& LLQuaternion::setQuat(const F32 *q)
return (*this); return (*this);
} }
// There may be a cheaper way that avoids the sqrt.
// Does sin_a = VX*VX + VY*VY + VZ*VZ?
// Copied from Matrix and Quaternion FAQ 1.12
inline void LLQuaternion::getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const inline void LLQuaternion::getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const
{ {
F32 cos_a = mQ[VW]; F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]); // length of the vector-component
if (cos_a > 1.0f) cos_a = 1.0f; if (v > FP_MAG_THRESHOLD)
if (cos_a < -1.0f) cos_a = -1.0f;
F32 sin_a = (F32) sqrt( 1.0f - cos_a * cos_a );
if ( fabs( sin_a ) < 0.0005f )
sin_a = 1.0f;
else
sin_a = 1.f/sin_a;
F32 temp_angle = 2.0f * (F32) acos( cos_a );
if (temp_angle > F_PI)
{ {
// The (angle,axis) pair should never have angles outside [PI, -PI] F32 oomag = 1.0f / v;
// since we want the _shortest_ (angle,axis) solution. F32 w = mQ[VW];
// Since acos is defined for [0, PI], and we multiply by 2.0, we if (w < 0.0f)
// can push the angle outside the acceptible range. {
// When this happens we set the angle to the other portion of a w = -w; // make VW positive
// full 2PI rotation, and negate the axis, which reverses the oomag = -oomag; // invert the axis
// direction of the rotation (by the right-hand rule). }
*angle = 2.f * F_PI - temp_angle; *x = mQ[VX] * oomag; // normalize the axis
*x = - mQ[VX] * sin_a; *y = mQ[VY] * oomag;
*y = - mQ[VY] * sin_a; *z = mQ[VZ] * oomag;
*z = - mQ[VZ] * sin_a; *angle = 2.0f * atan2f(v, w); // get the angle
} }
else else
{ {
*angle = temp_angle; *angle = 0.0f; // no rotation
*x = mQ[VX] * sin_a; *x = 0.0f; // around some dummy axis
*y = mQ[VY] * sin_a; *y = 0.0f;
*z = mQ[VZ] * sin_a; *z = 1.0f;
} }
} }

View File

@@ -40,6 +40,7 @@
///////////////////////////// /////////////////////////////
#include "llquaternion.h" #include "llquaternion.h"
LL_ALIGN_PREFIX(16)
class LLQuaternion2 class LLQuaternion2
{ {
public: public:
@@ -84,6 +85,8 @@ public:
// Quantize this quaternion to 16 bit precision // Quantize this quaternion to 16 bit precision
inline void quantize16(); inline void quantize16();
inline void mul(const LLQuaternion2& b);
///////////////////////// /////////////////////////
// Quaternion inspection // Quaternion inspection
///////////////////////// /////////////////////////
@@ -98,8 +101,8 @@ public:
protected: protected:
LLVector4a mQ; LL_ALIGN_16(LLVector4a mQ);
}; } LL_ALIGN_POSTFIX(16);
#endif #endif

View File

@@ -50,6 +50,39 @@ inline LLVector4a& LLQuaternion2::getVector4aRw()
return mQ; return mQ;
} }
inline void LLQuaternion2::mul(const LLQuaternion2& b)
{
static LL_ALIGN_16(const unsigned int signMask[4]) = { 0x0, 0x0, 0x0, 0x80000000 };
LLVector4a sum1, sum2, prod1, prod2, prod3, prod4;
const LLVector4a& va = mQ;
const LLVector4a& vb = b.getVector4a();
// [VX] [VY] [VZ] [VW]
//prod1: +wx +wy +wz +ww Bwwww*Axyzw
//prod2: +xw +yw +zw -xx Bxyzx*Awwwx [VW] sign flip
//prod3: +yz +zx +xy -yy Byzxy*Azxyy [VW] sign flip
//prod4: -zy -xz -yx -zz Bzxyz*Ayzzz
const LLVector4a Bwwww = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(3,3,3,3));
const LLVector4a Bxyzx = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(0,2,1,0));
const LLVector4a Awwwx = _mm_shuffle_ps(va,va,_MM_SHUFFLE(0,3,3,3));
const LLVector4a Byzxy = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(1,0,2,1));
const LLVector4a Azxyy = _mm_shuffle_ps(va,va,_MM_SHUFFLE(1,1,0,2));
const LLVector4a Bzxyz = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(2,1,0,2));
const LLVector4a Ayzxz = _mm_shuffle_ps(va,va,_MM_SHUFFLE(2,0,2,1));
prod1.setMul(Bwwww,va);
prod2.setMul(Bxyzx,Awwwx);
prod3.setMul(Byzxy,Azxyy);
prod4.setMul(Bzxyz,Ayzxz);
sum1.setAdd(prod2,prod3);
sum1 = _mm_xor_ps(sum1, _mm_load_ps((const float*)signMask));
sum2.setSub(prod1,prod4);
mQ.setAdd(sum1,sum2);
}
///////////////////////// /////////////////////////
// Quaternion modification // Quaternion modification
///////////////////////// /////////////////////////

View File

@@ -128,7 +128,7 @@ public:
inline void loadua(const F32* src); inline void loadua(const F32* src);
// Load only three floats beginning at address 'src'. Slowest method. // Load only three floats beginning at address 'src'. Slowest method.
inline void load3(const F32* src); inline void load3(const F32* src, const F32 w=0.f);
// Store to a 16-byte aligned memory address // Store to a 16-byte aligned memory address
inline void store4a(F32* dst) const; inline void store4a(F32* dst) const;
@@ -171,6 +171,9 @@ public:
// Set all 4 elements to element i of v, with i NOT known at compile time // Set all 4 elements to element i of v, with i NOT known at compile time
inline void splat(const LLVector4a& v, U32 i); inline void splat(const LLVector4a& v, U32 i);
// Sets element N to that of src's element N. Much cleaner than.. {LLVector4Logical mask; mask.clear(); mask.setElement<N>(); target.setSelectWithMask(mask,src,target);}
template <int N> inline void copyComponent(const LLVector4a& src);
// Select bits from sourceIfTrue and sourceIfFalse according to bits in mask // Select bits from sourceIfTrue and sourceIfFalse according to bits in mask
inline void setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse ); inline void setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse );
@@ -282,6 +285,8 @@ public:
void quantize8( const LLVector4a& low, const LLVector4a& high ); void quantize8( const LLVector4a& low, const LLVector4a& high );
void quantize16( const LLVector4a& low, const LLVector4a& high ); void quantize16( const LLVector4a& low, const LLVector4a& high );
void negate();
//////////////////////////////////// ////////////////////////////////////
// LOGICAL // LOGICAL
//////////////////////////////////// ////////////////////////////////////

View File

@@ -41,11 +41,11 @@ inline void LLVector4a::loadua(const F32* src)
} }
// Load only three floats beginning at address 'src'. Slowest method. // Load only three floats beginning at address 'src'. Slowest method.
inline void LLVector4a::load3(const F32* src) inline void LLVector4a::load3(const F32* src, const F32 w)
{ {
// mQ = { 0.f, src[2], src[1], src[0] } = { W, Z, Y, X } // mQ = { 0.f, src[2], src[1], src[0] } = { W, Z, Y, X }
// NB: This differs from the convention of { Z, Y, X, W } // NB: This differs from the convention of { Z, Y, X, W }
mQ = _mm_set_ps(0.f, src[2], src[1], src[0]); mQ = _mm_set_ps(w, src[2], src[1], src[0]);
} }
// Store to a 16-byte aligned memory address // Store to a 16-byte aligned memory address
@@ -154,6 +154,13 @@ inline void LLVector4a::splat(const LLVector4a& v, U32 i)
} }
} }
// Sets element N to that of src's element N
template <int N> inline void LLVector4a::copyComponent(const LLVector4a& src)
{
static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[N*4]);
setSelectWithMask(mask,src,mQ);
}
// Select bits from sourceIfTrue and sourceIfFalse according to bits in mask // Select bits from sourceIfTrue and sourceIfFalse according to bits in mask
inline void LLVector4a::setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse ) inline void LLVector4a::setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse )
{ {
@@ -529,6 +536,11 @@ inline void LLVector4a::clamp( const LLVector4a& low, const LLVector4a& high )
setSelectWithMask( lowMask, low, *this ); setSelectWithMask( lowMask, low, *this );
} }
inline void LLVector4a::negate()
{
static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 };
mQ = _mm_xor_ps(*reinterpret_cast<const LLQuad*>(signMask), mQ);
}
//////////////////////////////////// ////////////////////////////////////
// LOGICAL // LOGICAL

View File

@@ -79,7 +79,7 @@ public:
{ {
static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
ll_assert_aligned(allOnes,16); ll_assert_aligned(allOnes,16);
mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) ); mQ = _mm_andnot_ps( mQ, _mm_load_ps((F32*)(allOnes)));
return *this; return *this;
} }
@@ -115,7 +115,7 @@ public:
template<int N> void setElement() template<int N> void setElement()
{ {
mQ = _mm_or_ps( mQ, *reinterpret_cast<const LLQuad*>(S_V4LOGICAL_MASK_TABLE + 4*N) ); mQ = _mm_or_ps( mQ, _mm_load_ps( (F32*)&S_V4LOGICAL_MASK_TABLE[4*N] ) );
} }
private: private:

View File

@@ -50,7 +50,6 @@
#include "llstl.h" #include "llstl.h"
#include "llsdserialize.h" #include "llsdserialize.h"
#include "llvector4a.h" #include "llvector4a.h"
#include "llmatrix4a.h"
#include "lltimer.h" #include "lltimer.h"
#define DEBUG_SILHOUETTE_BINORMALS 0 #define DEBUG_SILHOUETTE_BINORMALS 0
@@ -1649,7 +1648,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
F32 t = (F32)i * mStep; F32 t = (F32)i * mStep;
mPath[i].mPos.set(0, mPath[i].mPos.set(0,
lerp(0, -sin(F_PI*params.getTwist()*t)*0.5f,t), lerp(0, -sin(F_PI*params.getTwist()*t)*0.5f,t),
lerp(-0.5, cos(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), mPath[i].mScale.set(lerp(1,params.getScale().mV[0],t),
lerp(1,params.getScale().mV[1],t), 0,1); lerp(1,params.getScale().mV[1],t), 0,1);
mPath[i].mTexT = t; mPath[i].mTexT = t;
@@ -2184,7 +2183,7 @@ BOOL LLVolume::generate()
0, 0, scale[2], 0, 0, 0, scale[2], 0,
0, 0, 0, 1 }; 0, 0, 0, 1 };
LLMatrix4 rot((F32*) mPathp->mPath[s].mRot.mMatrix); LLMatrix4 rot(mPathp->mPath[s].mRot.getF32ptr());
LLMatrix4 scale_mat(sc); LLMatrix4 scale_mat(sc);
scale_mat *= rot; scale_mat *= rot;
@@ -3670,15 +3669,13 @@ S32 LLVolume::getNumTriangles(S32* vcount) const
void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices, void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
std::vector<LLVector3> &normals, std::vector<LLVector3> &normals,
const LLVector3& obj_cam_vec_in, const LLVector3& obj_cam_vec_in,
const LLMatrix4& mat_in, const LLMatrix4a& mat_in,
const LLMatrix3& norm_mat_in, const LLMatrix4a& norm_mat_in,
S32 face_mask) S32 face_mask)
{ {
LLMatrix4a mat; const LLMatrix4a& mat = mat_in;
mat.loadu(mat_in);
LLMatrix4a norm_mat; const LLMatrix4a& norm_mat = norm_mat_in;
norm_mat.loadu(norm_mat_in);
LLVector4a obj_cam_vec; LLVector4a obj_cam_vec;
obj_cam_vec.load3(obj_cam_vec_in.mV); obj_cam_vec.load3(obj_cam_vec_in.mV);

View File

@@ -27,6 +27,9 @@
#ifndef LL_LLVOLUME_H #ifndef LL_LLVOLUME_H
#define LL_LLVOLUME_H #define LL_LLVOLUME_H
#ifdef IN_PCH
#error "llvolume.h should not be in pch include chain."
#endif
#include <iostream> #include <iostream>
class LLProfileParams; class LLProfileParams;
@@ -747,10 +750,10 @@ public:
class PathPt class PathPt
{ {
public: public:
LLMatrix4a mRot; LL_ALIGN_16(LLMatrix4a mRot);
LLVector4a mPos; LL_ALIGN_16(LLVector4a mPos);
LLVector4a mScale; LL_ALIGN_16(LLVector4a mScale);
F32 mTexT; F32 mTexT;
F32 pad[3]; //for alignment F32 pad[3]; //for alignment
PathPt() PathPt()
@@ -1017,8 +1020,8 @@ public:
void generateSilhouetteVertices(std::vector<LLVector3> &vertices, void generateSilhouetteVertices(std::vector<LLVector3> &vertices,
std::vector<LLVector3> &normals, std::vector<LLVector3> &normals,
const LLVector3& view_vec, const LLVector3& view_vec,
const LLMatrix4& mat, const LLMatrix4a& mat,
const LLMatrix3& norm_mat, const LLMatrix4a& norm_mat,
S32 face_index); S32 face_index);
//get the face index of the face that intersects with the given line segment at the point //get the face index of the face that intersects with the given line segment at the point

View File

@@ -2,31 +2,25 @@
* @file llvolumemgr.h * @file llvolumemgr.h
* @brief LLVolumeMgr class. * @brief LLVolumeMgr class.
* *
* $LicenseInfo:firstyear=2002&license=viewergpl$ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -127,13 +127,14 @@ public:
LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
}; };
LL_ALIGN_PREFIX(16)
class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle> class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle>
{ {
public: public:
const LLVolumeFace* mFace; const LLVolumeFace* mFace;
LLVector4a mStart; LL_ALIGN_16(LLVector4a mStart);
LLVector4a mDir; LL_ALIGN_16(LLVector4a mDir);
LLVector4a mEnd; LL_ALIGN_16(LLVector4a mEnd);
LLVector4a* mIntersection; LLVector4a* mIntersection;
LLVector2* mTexCoord; LLVector2* mTexCoord;
LLVector4a* mNormal; LLVector4a* mNormal;
@@ -148,7 +149,7 @@ public:
void traverse(const LLOctreeNode<LLVolumeTriangle>* node); void traverse(const LLOctreeNode<LLVolumeTriangle>* node);
virtual void visit(const LLOctreeNode<LLVolumeTriangle>* node); virtual void visit(const LLOctreeNode<LLVolumeTriangle>* node);
}; } LL_ALIGN_POSTFIX(16);
class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle> class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle>
{ {

View File

@@ -2,31 +2,25 @@
* @file m3math.cpp * @file m3math.cpp
* @brief LLMatrix3 class implementation. * @brief LLMatrix3 class implementation.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file m3math.h * @file m3math.h
* @brief LLMatrix3 class header file. * @brief LLMatrix3 class header file.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file m4math.cpp * @file m4math.cpp
* @brief LLMatrix4 class implementation. * @brief LLMatrix4 class implementation.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -684,37 +678,6 @@ const LLMatrix4& LLMatrix4::initMatrix(const LLMatrix3 &mat, const LLVector4 &
// LLMatrix4 Operators // LLMatrix4 Operators
/* Not implemented to help enforce code consistency with the syntax of
row-major notation. This is a Good Thing.
LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b)
{
// Operate "to the right" on column-vector b
LLVector4 vec;
vec.mV[VX] = a.mMatrix[VX][VX] * b.mV[VX] +
a.mMatrix[VY][VX] * b.mV[VY] +
a.mMatrix[VZ][VX] * b.mV[VZ] +
a.mMatrix[VW][VX] * b.mV[VW];
vec.mV[VY] = a.mMatrix[VX][VY] * b.mV[VX] +
a.mMatrix[VY][VY] * b.mV[VY] +
a.mMatrix[VZ][VY] * b.mV[VZ] +
a.mMatrix[VW][VY] * b.mV[VW];
vec.mV[VZ] = a.mMatrix[VX][VZ] * b.mV[VX] +
a.mMatrix[VY][VZ] * b.mV[VY] +
a.mMatrix[VZ][VZ] * b.mV[VZ] +
a.mMatrix[VW][VZ] * b.mV[VW];
vec.mV[VW] = a.mMatrix[VX][VW] * b.mV[VX] +
a.mMatrix[VY][VW] * b.mV[VY] +
a.mMatrix[VZ][VW] * b.mV[VZ] +
a.mMatrix[VW][VW] * b.mV[VW];
return vec;
}
*/
LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b) LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b)
{ {
// Operate "to the left" on row-vector a // Operate "to the left" on row-vector a

View File

@@ -2,31 +2,25 @@
* @file m4math.h * @file m4math.h
* @brief LLMatrix4 class header file. * @brief LLMatrix4 class header file.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -229,9 +223,6 @@ public:
// Operators // Operators
// //
// Not implemented to enforce code that agrees with symbolic syntax
// friend LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b); // Apply rotation a to vector b
// friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b); // Return a * b // 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 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 const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b); // Return full transform of a by matrix b

View File

@@ -2,31 +2,25 @@
* @file raytrace.cpp * @file raytrace.cpp
* @brief Functions called by box object scripts. * @brief Functions called by box object scripts.
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file raytrace.h * @file raytrace.h
* @brief Ray intersection tests for primitives. * @brief Ray intersection tests for primitives.
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file v2math.cpp * @file v2math.cpp
* @brief LLVector2 class implementation. * @brief LLVector2 class implementation.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file v2math.h * @file v2math.h
* @brief LLVector2 class header file. * @brief LLVector2 class header file.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file v3color.cpp * @file v3color.cpp
* @brief LLColor3 class implementation. * @brief LLColor3 class implementation.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file v3color.h * @file v3color.h
* @brief LLColor3 class header file. * @brief LLColor3 class header file.
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -39,6 +33,7 @@ class LLVector4;
#include "llerror.h" #include "llerror.h"
#include "llmath.h" #include "llmath.h"
#include "llsd.h" #include "llsd.h"
#include <string.h>
// LLColor3 = |r g b| // LLColor3 = |r g b|

View File

@@ -2,31 +2,25 @@
* @file v3dmath.cpp * @file v3dmath.cpp
* @brief LLVector3d class implementation. * @brief LLVector3d class implementation.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -72,17 +72,22 @@ class LLVector3d
BOOL clamp(const F64 min, const F64 max); // Clamps all values to (min,max), returns TRUE if data changed 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 BOOL abs(); // sets all values to absolute value of original value (first octant), returns TRUE if changed
inline const LLVector3d& clearVec(); // Clears LLVector3d to (0, 0, 0, 1) 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& setZero(); // Zero LLVector3d to (0, 0, 0, 0)
inline const LLVector3d& zeroVec(); // deprecated inline const LLVector3d& zeroVec(); // deprecated
inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1) inline const LLVector3d& set(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1)
inline const LLVector3d& setVec(const LLVector3d &vec); // Sets LLVector3d to vec inline const LLVector3d& set(const LLVector3d &vec); // Sets LLVector3d to vec
inline const LLVector3d& setVec(const F64 *vec); // Sets LLVector3d to vec inline const LLVector3d& set(const F64 *vec); // Sets LLVector3d to vec
inline const LLVector3d& setVec(const LLVector3 &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; // Returns magnitude of LLVector3d F64 magVec() const; // deprecated
F64 magVecSquared() const; // Returns magnitude squared of LLVector3d F64 magVecSquared() const; // deprecated
inline F64 normVec(); // Normalizes and returns the magnitude of LLVector3d inline F64 normVec(); // deprecated
F64 length() const; // Returns magnitude of LLVector3d F64 length() const; // Returns magnitude of LLVector3d
F64 lengthSquared() const; // Returns magnitude squared of LLVector3d F64 lengthSquared() const; // Returns magnitude squared of LLVector3d
@@ -127,7 +132,15 @@ class LLVector3d
typedef LLVector3d LLGlobalVec; typedef LLVector3d LLGlobalVec;
const LLVector3d &LLVector3d::setVec(const LLVector3 &vec) 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;
}
inline const LLVector3d &LLVector3d::setVec(const LLVector3 &vec)
{ {
mdV[0] = vec.mV[0]; mdV[0] = vec.mV[0];
mdV[1] = vec.mV[1]; mdV[1] = vec.mV[1];
@@ -184,6 +197,14 @@ inline BOOL LLVector3d::isFinite() const
// Clear and Assignment Functions // Clear and Assignment Functions
inline const LLVector3d& LLVector3d::clear(void)
{
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[0] = 0.f;
@@ -208,6 +229,30 @@ inline const LLVector3d& LLVector3d::zeroVec(void)
return (*this); return (*this);
} }
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);
}
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);
}
inline const LLVector3d& LLVector3d::set(const F64 *vec)
{
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[VX] = x;
@@ -472,4 +517,15 @@ inline LLVector3d projected_vec(const LLVector3d &a, const LLVector3d &b)
return project_axis * (a * project_axis); 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();
F64 dot_product = normalized_a * normalized_b;
return normalized_a * (b_length / dot_product);
}
#endif // LL_V3DMATH_H #endif // LL_V3DMATH_H

View File

@@ -2,31 +2,25 @@
* @file v3math.cpp * @file v3math.cpp
* @brief LLVector3 class implementation. * @brief LLVector3 class implementation.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -159,6 +159,7 @@ F32 dist_vec(const LLVector3 &a, const LLVector3 &b); // Returns distance betwe
F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared 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 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 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) LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec)
LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec) LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec)
LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b
@@ -490,9 +491,27 @@ inline F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b)
inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b) inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b)
{ {
LLVector3 project_axis = b; F32 bb = b * b;
project_axis.normalize(); if (bb > FP_MAG_THRESHOLD * FP_MAG_THRESHOLD)
return project_axis * (a * project_axis); {
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();
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) inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b)
@@ -556,15 +575,13 @@ inline void update_min_max(LLVector3& min, LLVector3& max, const F32* pos)
inline F32 angle_between(const LLVector3& a, const LLVector3& b) inline F32 angle_between(const LLVector3& a, const LLVector3& b)
{ {
LLVector3 an = a; F32 ab = a * b; // dotproduct
LLVector3 bn = b; if (ab == -0.0f)
an.normalize(); {
bn.normalize(); ab = 0.0f; // get rid of negative zero
F32 cosine = an * bn; }
F32 angle = (cosine >= 1.0f) ? 0.0f : LLVector3 c = a % b; // crossproduct
(cosine <= -1.0f) ? F_PI : return atan2f(sqrtf(c * c), ab); // return the angle
(F32)acos(cosine);
return angle;
} }
inline BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon) inline BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon)

View File

@@ -2,31 +2,25 @@
* @file v4coloru.cpp * @file v4coloru.cpp
* @brief LLColor4U class implementation. * @brief LLColor4U class implementation.
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file v4math.cpp * @file v4math.cpp
* @brief LLVector4 class implementation. * @brief LLVector4 class implementation.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file v4math.h * @file v4math.h
* @brief LLVector4 class header file. * @brief LLVector4 class header file.
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -1,31 +1,25 @@
/** /**
* @file xform.cpp * @file xform.cpp
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -42,7 +36,7 @@ LLXform::~LLXform()
{ {
} }
// Link optimization - don't inline these llwarns // Link optimization - don't inline these LL_WARNS()
void LLXform::warn(const char* const msg) void LLXform::warn(const char* const msg)
{ {
llwarns << msg << llendl; llwarns << msg << llendl;
@@ -96,30 +90,29 @@ void LLXformMatrix::updateMatrix(BOOL update_bounds)
{ {
update(); update();
mWorldMatrix.initAll(mScale, mWorldRotation, mWorldPosition); LLMatrix4 world_matrix;
world_matrix.initAll(mScale, mWorldRotation, mWorldPosition);
mWorldMatrix.loadu(world_matrix);
if (update_bounds && (mChanged & MOVED)) if (update_bounds && (mChanged & MOVED))
{ {
mMin.mV[0] = mMax.mV[0] = mWorldMatrix.mMatrix[3][0]; mMax = mMin = mWorldMatrix.getRow<3>();
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; LLVector4a total_sum,sum1,sum2;
F32 f1 = (fabs(mWorldMatrix.mMatrix[0][1])+fabs(mWorldMatrix.mMatrix[1][1])+fabs(mWorldMatrix.mMatrix[2][1])) * 0.5f; total_sum.setAbs(mWorldMatrix.getRow<0>());
F32 f2 = (fabs(mWorldMatrix.mMatrix[0][2])+fabs(mWorldMatrix.mMatrix[1][2])+fabs(mWorldMatrix.mMatrix[2][2])) * 0.5f; sum1.setAbs(mWorldMatrix.getRow<1>());
sum2.setAbs(mWorldMatrix.getRow<2>());
sum1.add(sum2);
total_sum.add(sum1);
total_sum.mul(.5f);
mMin.mV[0] -= f0; mMax.add(total_sum);
mMin.mV[1] -= f1; mMin.sub(total_sum);
mMin.mV[2] -= f2;
mMax.mV[0] += f0;
mMax.mV[1] += f1;
mMax.mV[2] += f2;
} }
} }
void LLXformMatrix::getMinMax(LLVector3& min, LLVector3& max) const void LLXformMatrix::getMinMax(LLVector3& min, LLVector3& max) const
{ {
min = mMin; min.set(mMin.getF32ptr());
max = mMax; max.set(mMax.getF32ptr());
} }

View File

@@ -28,6 +28,7 @@
#include "v3math.h" #include "v3math.h"
#include "m4math.h" #include "m4math.h"
#include "llmatrix4a.h"
#include "llquaternion.h" #include "llquaternion.h"
const F32 MAX_OBJECT_Z = 4096.f; // should match REGION_HEIGHT_METERS, Pre-havok4: 768.f const F32 MAX_OBJECT_Z = 4096.f; // should match REGION_HEIGHT_METERS, Pre-havok4: 768.f
@@ -103,9 +104,9 @@ public:
inline void setRotation(const F32 x, const F32 y, const F32 z, const F32 s); inline void setRotation(const F32 x, const F32 y, const F32 z, const F32 s);
// Above functions must be inline for speed, but also // Above functions must be inline for speed, but also
// need to emit warnings. llwarns causes inline LLError::CallSite // need to emit warnings. LL_WARNS() causes inline LLError::CallSite
// static objects that make more work for the linker. // static objects that make more work for the linker.
// Avoid inline llwarns by calling this function. // Avoid inline LL_WARNS() by calling this function.
void warn(const char* const msg); void warn(const char* const msg);
void setChanged(const U32 bits) { mChanged |= bits; } void setChanged(const U32 bits) { mChanged |= bits; }
@@ -130,20 +131,21 @@ public:
const LLVector3& getWorldPosition() const { return mWorldPosition; } const LLVector3& getWorldPosition() const { return mWorldPosition; }
}; };
LL_ALIGN_PREFIX(16)
class LLXformMatrix : public LLXform class LLXformMatrix : public LLXform
{ {
public: public:
LLXformMatrix() : LLXform() {}; LLXformMatrix() : LLXform() {};
virtual ~LLXformMatrix(); virtual ~LLXformMatrix();
const LLMatrix4& getWorldMatrix() const { return mWorldMatrix; } const LLMatrix4a& getWorldMatrix() const { return mWorldMatrix; }
void setWorldMatrix (const LLMatrix4& mat) { mWorldMatrix = mat; } void setWorldMatrix (const LLMatrix4a& mat) { mWorldMatrix = mat; }
void init() void init()
{ {
mWorldMatrix.setIdentity(); mWorldMatrix.setIdentity();
mMin.clearVec(); mMin.clear();
mMax.clearVec(); mMax.clear();
LLXform::init(); LLXform::init();
} }
@@ -153,11 +155,11 @@ public:
void getMinMax(LLVector3& min,LLVector3& max) const; void getMinMax(LLVector3& min,LLVector3& max) const;
protected: protected:
LLMatrix4 mWorldMatrix; LL_ALIGN_16(LLMatrix4a mWorldMatrix);
LLVector3 mMin; LL_ALIGN_16(LLVector4a mMin);
LLVector3 mMax; LL_ALIGN_16(LLVector4a mMax);
}; } LL_ALIGN_POSTFIX(16);
BOOL LLXform::setParent(LLXform* parent) BOOL LLXform::setParent(LLXform* parent)
{ {

View File

@@ -610,7 +610,7 @@ void AIPerService::purge(void)
per_service_w->mCapabilityType[i].mQueuedRequests.clear(); per_service_w->mCapabilityType[i].mQueuedRequests.clear();
if (is_approved((AICapabilityType)i)) if (is_approved((AICapabilityType)i))
{ {
llassert(total_queued_w->approved >= s); llassert(total_queued_w->approved >= (S32)s);
total_queued_w->approved -= s; total_queued_w->approved -= s;
} }
} }

View File

@@ -936,6 +936,7 @@ P(fetchScriptLimitsRegionSummaryResponder);
P(fnPtrResponder); P(fnPtrResponder);
P(floaterPermsResponder); P(floaterPermsResponder);
P2(gamingDataReceived, transfer_22s_connect_10s); P2(gamingDataReceived, transfer_22s_connect_10s);
P(groupBanDataResponder);
P2(groupMemberDataResponder, transfer_300s); P2(groupMemberDataResponder, transfer_300s);
P2(groupProposalBallotResponder, transfer_300s); P2(groupProposalBallotResponder, transfer_300s);
P(homeLocationResponder); P(homeLocationResponder);

View File

@@ -794,6 +794,7 @@ void LLAvatarNameCache::setUseDisplayNames(bool use)
if (use != sUseDisplayNames) if (use != sUseDisplayNames)
{ {
sUseDisplayNames = use; sUseDisplayNames = use;
LL_DEBUGS("AvNameCache") << "Display names are now: " << (use ? "on" : "off") << LL_ENDL;
// flush our cache // flush our cache
sCache.clear(); sCache.clear();

View File

@@ -78,6 +78,8 @@ const U64 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23);
const U64 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26); const U64 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26);
const U64 REGION_FLAGS_BLOCK_FLYOVER = (1 << 27);
const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28); const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29); const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);

View File

@@ -91,15 +91,17 @@ void LLTemplateMessageReader::getData(const char *blockname, const char *varname
} }
LLMsgBlkData *msg_block_data = iter->second; LLMsgBlkData *msg_block_data = iter->second;
LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep]; LLMsgBlkData::msg_var_data_map_t &var_data_map = msg_block_data->mMemberVarData;
if (!vardata.getName()) if (var_data_map.find(vnamep) == var_data_map.end())
{ {
llerrs << "Variable "<< vnamep << " not in message " llerrs << "Variable "<< vnamep << " not in message "
<< mCurrentRMessageData->mName<< " block " << bnamep << llendl; << mCurrentRMessageData->mName<< " block " << bnamep << llendl;
return; return;
} }
LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep];
if (size && size != vardata.getSize()) if (size && size != vardata.getSize())
{ {
llerrs << "Msg " << mCurrentRMessageData->mName llerrs << "Msg " << mCurrentRMessageData->mName
@@ -284,7 +286,7 @@ void LLTemplateMessageReader::getU8(const char *block, const char *var,
void LLTemplateMessageReader::getBOOL(const char *block, const char *var, void LLTemplateMessageReader::getBOOL(const char *block, const char *var,
BOOL &b, S32 blocknum ) BOOL &b, S32 blocknum )
{ {
U8 value; U8 value(0);
getData(block, var, &value, sizeof(U8), blocknum); getData(block, var, &value, sizeof(U8), blocknum);
b = (BOOL) value; b = (BOOL) value;
} }

View File

@@ -78,7 +78,7 @@ LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, std::string cons
LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, AIPerService::Approvement* approved, LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, AIPerService::Approvement* approved,
bool keepalive, bool is_auth, bool compression) : bool keepalive, bool is_auth, bool compression) :
mAction(action), mURL(url), mKeepAlive(keepalive), mIsAuth(is_auth), mNoCompression(!compression), mAction(action), mURL(url), mKeepAlive(keepalive), mIsAuth(is_auth), mNoCompression(!compression),
mBody(body), mResponder(responder), mHeaders(headers), mResponderNameCache(responder ? responder->getName() : "<uninitialized>") mBody(body), mResponder(responder), mHeaders(headers), mResponderNameCache(std::string("LLURLRequest:") + std::string(responder ? responder->getName() : "<uninitialized>"))
{ {
if (approved) if (approved)
{ {
@@ -276,32 +276,4 @@ bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w)
return rv; return rv;
} }
// Called from AIStateMachine::mainloop, but put here because we don't want to include llurlrequest.h there of course.
void print_statemachine_diagnostics(U64 total_clocks, U64 max_delta, AIEngine::queued_type::const_reference slowest_element)
{
AIStateMachine const& slowest_state_machine = slowest_element.statemachine();
LLURLRequest const* request = dynamic_cast<LLURLRequest const*>(&slowest_state_machine);
F64 const tfactor = 1000 / calc_clock_frequency();
std::ostringstream msg;
if (total_clocks > max_delta)
{
msg << "AIStateMachine::mainloop did run for " << (total_clocks * tfactor) << " ms. The slowest ";
}
else
{
msg << "AIStateMachine::mainloop: A ";
}
msg << "state machine ";
if (request)
{
msg << "(" << request->getResponderName() << ") ";
}
msg << "ran for " << (max_delta * tfactor) << " ms";
if (slowest_state_machine.getRuntime() > max_delta)
{
msg << " (" << (slowest_state_machine.getRuntime() * tfactor) << " ms in total now)";
}
msg << ".";
llwarns << msg.str() << llendl;
}

View File

@@ -72,7 +72,7 @@ class LLURLRequest : public AICurlEasyRequestStateMachine {
/** /**
* @brief Cached value of responder->getName() as passed to the constructor. * @brief Cached value of responder->getName() as passed to the constructor.
*/ */
char const* getResponderName(void) const { return mResponderNameCache; } /*virtual*/ const char* getName() const { return mResponderNameCache.c_str(); }
protected: protected:
// Call abort(), not delete. // Call abort(), not delete.
@@ -113,7 +113,7 @@ class LLURLRequest : public AICurlEasyRequestStateMachine {
U32 mBodySize; U32 mBodySize;
LLHTTPClient::ResponderPtr mResponder; LLHTTPClient::ResponderPtr mResponder;
AIHTTPHeaders mHeaders; AIHTTPHeaders mHeaders;
char const* mResponderNameCache; std::string mResponderNameCache;
protected: protected:
// Handle initializing the object. // Handle initializing the object.

View File

@@ -31,6 +31,7 @@
#include "llconvexdecomposition.h" #include "llconvexdecomposition.h"
#include "llsdserialize.h" #include "llsdserialize.h"
#include "llvector4a.h" #include "llvector4a.h"
#include "llmatrix4a.h"
#if LL_MSVC #if LL_MSVC
#pragma warning (push) #pragma warning (push)
#pragma warning (disable : 4068) #pragma warning (disable : 4068)
@@ -172,6 +173,11 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
return LLModel::BAD_ELEMENT; return LLModel::BAD_ELEMENT;
} }
if (!pos_source)
{
llwarns << "Unable to process mesh without position data; invalid model; invalid model." << llendl;
return LLModel::BAD_ELEMENT;
}
domPRef p = tri->getP(); domPRef p = tri->getP();
domListOfUInts& idx = p->getValue(); domListOfUInts& idx = p->getValue();
@@ -181,12 +187,6 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy ; domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy ;
domListOfFloats& n = norm_source ? norm_source->getFloat_array()->getValue() : dummy ; domListOfFloats& n = norm_source ? norm_source->getFloat_array()->getValue() : dummy ;
if (pos_source)
{
face.mExtents[0].set(v[0], v[1], v[2]);
face.mExtents[1].set(v[0], v[1], v[2]);
}
LLVolumeFace::VertexMapData::PointMap point_map; LLVolumeFace::VertexMapData::PointMap point_map;
U32 index_count = idx.getCount(); U32 index_count = idx.getCount();
@@ -194,6 +194,15 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
U32 tc_count = tc_source ? tc.getCount() : 0; U32 tc_count = tc_source ? tc.getCount() : 0;
U32 norm_count = norm_source ? n.getCount() : 0; U32 norm_count = norm_source ? n.getCount() : 0;
if (vertex_count == 0)
{
llwarns << "Unable to process mesh with empty position array; invalid model." << llendl;
return LLModel::BAD_ELEMENT;
}
face.mExtents[0].set(v[0], v[1], v[2]);
face.mExtents[1].set(v[0], v[1], v[2]);
for (U32 i = 0; i < index_count; i += idx_stride) for (U32 i = 0; i < index_count; i += idx_stride)
{ {
LLVolumeFace::VertexData cv; LLVolumeFace::VertexData cv;

View File

@@ -74,6 +74,11 @@ set(llrender_HEADER_FILES
set_source_files_properties(${llrender_HEADER_FILES} set_source_files_properties(${llrender_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE) PROPERTIES HEADER_FILE_ONLY TRUE)
# Workaround hack for clang bugs
if (DARWIN)
set_property(SOURCE llgl.cpp PROPERTY COMPILE_FLAGS -O1)
endif (DARWIN)
list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES}) list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES})
add_library (llrender ${llrender_SOURCE_FILES}) add_library (llrender ${llrender_SOURCE_FILES})

View File

@@ -34,6 +34,7 @@
#include "v3dmath.h" #include "v3dmath.h"
#include "m3math.h" #include "m3math.h"
#include "m4math.h" #include "m4math.h"
#include "llmatrix4a.h"
#include "llrender.h" #include "llrender.h"
#include "llglslshader.h" #include "llglslshader.h"
@@ -265,18 +266,19 @@ void LLCubeMap::setMatrix(S32 stage)
gGL.getTexUnit(stage)->activate(); gGL.getTexUnit(stage)->activate();
} }
LLVector3 x(gGLModelView+0); LLVector3 x(gGLModelView.getRow<0>().getF32ptr());
LLVector3 y(gGLModelView+4); LLVector3 y(gGLModelView.getRow<1>().getF32ptr());
LLVector3 z(gGLModelView+8); LLVector3 z(gGLModelView.getRow<2>().getF32ptr());
LLMatrix3 mat3; LLMatrix3 mat3;
mat3.setRows(x,y,z); mat3.setRows(x,y,z);
LLMatrix4 trans(mat3); LLMatrix4a trans;
trans.loadu(mat3);
trans.transpose(); trans.transpose();
gGL.matrixMode(LLRender::MM_TEXTURE); gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.pushMatrix(); gGL.pushMatrix();
gGL.loadMatrix((F32 *)trans.mMatrix); gGL.loadMatrix(trans);
gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.matrixMode(LLRender::MM_MODELVIEW);
/*if (stage > 0) /*if (stage > 0)

View File

@@ -444,6 +444,7 @@ LLGLManager::LLGLManager() :
mHasDebugOutput(FALSE), mHasDebugOutput(FALSE),
mHasAdaptiveVsync(FALSE), mHasAdaptiveVsync(FALSE),
mHasTextureSwizzle(FALSE),
mIsATI(FALSE), mIsATI(FALSE),
mIsNVIDIA(FALSE), mIsNVIDIA(FALSE),
@@ -1382,6 +1383,35 @@ void flush_glerror()
glGetError(); glGetError();
} }
const std::string getGLErrorString(GLenum error)
{
switch(error)
{
case GL_NO_ERROR:
return "No Error";
case GL_INVALID_ENUM:
return "Invalid Enum";
case GL_INVALID_VALUE:
return "Invalid Value";
case GL_INVALID_OPERATION:
return "Invalid Operation";
case GL_INVALID_FRAMEBUFFER_OPERATION:
return "Invalid Framebuffer Operation";
case GL_OUT_OF_MEMORY:
return "Out of Memory";
case GL_STACK_UNDERFLOW:
return "Stack Underflow";
case GL_STACK_OVERFLOW:
return "Stack Overflow";
#ifdef GL_TABLE_TOO_LARGE
case GL_TABLE_TOO_LARGE:
return "Table too large";
#endif
default:
return "UNKNOWN ERROR";
}
}
//this function outputs gl error to the log file, does not crash the code. //this function outputs gl error to the log file, does not crash the code.
void log_glerror() void log_glerror()
{ {
@@ -1394,17 +1424,8 @@ void log_glerror()
error = glGetError(); error = glGetError();
while (LL_UNLIKELY(error)) while (LL_UNLIKELY(error))
{ {
GLubyte const * gl_error_msg = gluErrorString(error); std::string gl_error_msg = getGLErrorString(error);
if (NULL != gl_error_msg) llwarns << "GL Error: 0x" << std::hex << error << std::dec << " GL Error String: " << gl_error_msg << llendl;
{
llwarns << "GL Error: " << error << " GL Error String: " << gl_error_msg << llendl ;
}
else
{
// gluErrorString returns NULL for some extensions' error codes.
// you'll probably have to grep for the number in glext.h.
llwarns << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << llendl;
}
error = glGetError(); error = glGetError();
} }
} }
@@ -1418,27 +1439,13 @@ void do_assert_glerror()
while (LL_UNLIKELY(error)) while (LL_UNLIKELY(error))
{ {
quit = TRUE; quit = TRUE;
GLubyte const * gl_error_msg = gluErrorString(error);
if (NULL != gl_error_msg)
{
LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL;
LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL;
if (gDebugSession) std::string gl_error_msg = getGLErrorString(error);
{ LL_WARNS("RenderState") << "GL Error: 0x" << std::hex << error << std::dec << LL_ENDL;
gFailLog << "GL Error:" << gl_error_msg << std::endl; LL_WARNS("RenderState") << "GL Error String: " << gl_error_msg << LL_ENDL;
} if (gDebugSession)
}
else
{ {
// gluErrorString returns NULL for some extensions' error codes. gFailLog << "GL Error: 0x" << std::hex << error << std::dec << " GL Error String: " << gl_error_msg << std::endl;
// you'll probably have to grep for the number in glext.h.
LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
if (gDebugSession)
{
gFailLog << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << std::endl;
}
} }
error = glGetError(); error = glGetError();
} }
@@ -1662,10 +1669,6 @@ void LLGLState::checkTextureChannels(const std::string& msg)
GLint stackDepth = 0; GLint stackDepth = 0;
glh::matrix4f mat;
glh::matrix4f identity;
identity.identity();
for (GLint i = 1; i < gGLManager.mNumTextureUnits; i++) for (GLint i = 1; i < gGLManager.mNumTextureUnits; i++)
{ {
gGL.getTexUnit(i)->activate(); gGL.getTexUnit(i)->activate();
@@ -1685,10 +1688,11 @@ void LLGLState::checkTextureChannels(const std::string& msg)
} }
} }
glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m); LLMatrix4a mat;
glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.mMatrix);
stop_glerror(); stop_glerror();
if (mat != identity) if (!mat.isIdentity())
{ {
error = TRUE; error = TRUE;
LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL; LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
@@ -2179,7 +2183,7 @@ void parse_glsl_version(S32& major, S32& minor)
LLStringUtil::convertToS32(minor_str, minor); LLStringUtil::convertToS32(minor_str, minor);
} }
LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply) LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const LLMatrix4a& modelview, const LLMatrix4a& projection, bool apply)
{ {
mApply = apply; mApply = apply;
@@ -2194,27 +2198,42 @@ LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& mode
void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d) void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
{ {
glh::matrix4f& P = mProjection; LLMatrix4a& P = mProjection;
glh::matrix4f& M = mModelview; LLMatrix4a& M = mModelview;
glh::matrix4f invtrans_MVP = (P * M).inverse().transpose(); LLMatrix4a invtrans_MVP;
glh::vec4f oplane(a,b,c,d); invtrans_MVP.setMul(P,M);
glh::vec4f cplane; invtrans_MVP.invert();
invtrans_MVP.mult_matrix_vec(oplane, cplane); invtrans_MVP.transpose();
cplane /= fabs(cplane[2]); // normalize such that depth is not scaled LLVector4a oplane(a,b,c,d);
cplane[3] -= 1; LLVector4a cplane;
LLVector4a cplane_splat;
LLVector4a cplane_neg;
if(cplane[2] < 0) invtrans_MVP.rotate4(oplane,cplane);
cplane *= -1;
cplane_splat.splat<2>(cplane);
cplane_splat.setAbs(cplane_splat);
cplane.div(cplane_splat);
cplane.sub(LLVector4a(0.f,0.f,0.f,1.f));
cplane_splat.splat<2>(cplane);
cplane_neg = cplane;
cplane_neg.negate();
cplane.setSelectWithMask( cplane_splat.lessThan( _mm_setzero_ps() ), cplane_neg, cplane );
LLMatrix4a suffix;
suffix.setIdentity();
suffix.setColumn<2>(cplane);
LLMatrix4a newP;
newP.setMul(suffix,P);
glh::matrix4f suffix;
suffix.set_row(2, cplane);
glh::matrix4f newP = suffix * P;
gGL.matrixMode(LLRender::MM_PROJECTION); gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix(); gGL.pushMatrix();
gGL.loadMatrix(newP.m); gGL.loadMatrix(newP);
gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m); //gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m);
gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.matrixMode(LLRender::MM_MODELVIEW);
} }
@@ -2403,19 +2422,18 @@ void LLGLDepthTest::checkState()
} }
} }
LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer) LLGLSquashToFarClip::LLGLSquashToFarClip(const LLMatrix4a& P_in, U32 layer)
{ {
LLMatrix4a P = P_in;
F32 depth = 0.99999f - 0.0001f * layer; F32 depth = 0.99999f - 0.0001f * layer;
for (U32 i = 0; i < 4; i++) LLVector4a col = P.getColumn<3>();
{ col.mul(depth);
P.element(2, i) = P.element(3, i) * depth; P.setColumn<2>(col);
}
gGL.matrixMode(LLRender::MM_PROJECTION); gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix(); gGL.pushMatrix();
gGL.loadMatrix(P.m); gGL.loadMatrix(P);
gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.matrixMode(LLRender::MM_MODELVIEW);
} }

View File

@@ -38,12 +38,12 @@
#include "llstring.h" #include "llstring.h"
#include "stdtypes.h" #include "stdtypes.h"
#include "v4math.h" #include "v4math.h"
#include "llmatrix4a.h"
#include "llplane.h" #include "llplane.h"
#include "llgltypes.h" #include "llgltypes.h"
#include "llinstancetracker.h" #include "llinstancetracker.h"
#include "llglheaders.h" #include "llglheaders.h"
#include "glh/glh_linear.h"
extern BOOL gDebugGL; extern BOOL gDebugGL;
extern BOOL gDebugSession; extern BOOL gDebugSession;
@@ -321,21 +321,23 @@ public:
Does not stack. Does not stack.
Caches inverse of projection matrix used in gGLObliqueProjectionInverse Caches inverse of projection matrix used in gGLObliqueProjectionInverse
*/ */
LL_ALIGN_PREFIX(16)
class LLGLUserClipPlane class LLGLUserClipPlane
{ {
public: public:
LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply = true); LLGLUserClipPlane(const LLPlane& plane, const LLMatrix4a& modelview, const LLMatrix4a& projection, bool apply = true);
~LLGLUserClipPlane(); ~LLGLUserClipPlane();
void setPlane(F32 a, F32 b, F32 c, F32 d); void setPlane(F32 a, F32 b, F32 c, F32 d);
private: private:
bool mApply;
glh::matrix4f mProjection; LL_ALIGN_16(LLMatrix4a mProjection);
glh::matrix4f mModelview; LL_ALIGN_16(LLMatrix4a mModelview);
};
bool mApply;
} LL_ALIGN_POSTFIX(16);
/* /*
Modify and load projection matrix to push depth values to far clip plane. Modify and load projection matrix to push depth values to far clip plane.
@@ -348,7 +350,7 @@ private:
class LLGLSquashToFarClip class LLGLSquashToFarClip
{ {
public: public:
LLGLSquashToFarClip(glh::matrix4f projection, U32 layer = 0); LLGLSquashToFarClip(const LLMatrix4a& projection, U32 layer = 0);
~LLGLSquashToFarClip(); ~LLGLSquashToFarClip();
}; };
@@ -455,8 +457,6 @@ public:
void wait(); void wait();
}; };
extern LLMatrix4 gGLObliqueProjectionInverse;
#include "llglstates.h" #include "llglstates.h"
void init_glstates(); void init_glstates();

View File

@@ -41,7 +41,6 @@
# include "GL/glx.h" # include "GL/glx.h"
# define GL_GLEXT_PROTOTYPES 1 # define GL_GLEXT_PROTOTYPES 1
# include "GL/glext.h" # include "GL/glext.h"
# include "GL/glu.h"
# include "GL/glx.h" # include "GL/glx.h"
# define GLX_GLXEXT_PROTOTYPES 1 # define GLX_GLXEXT_PROTOTYPES 1
# include "GL/glxext.h" # include "GL/glxext.h"
@@ -266,7 +265,6 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
#define GL_GLEXT_PROTOTYPES 1 #define GL_GLEXT_PROTOTYPES 1
#include "GL/gl.h" #include "GL/gl.h"
#include "GL/glext.h" #include "GL/glext.h"
#include "GL/glu.h"
// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly // The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly
# define __APPLE__ # define __APPLE__
@@ -282,7 +280,6 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
// quotes so we get libraries/.../GL/ version // quotes so we get libraries/.../GL/ version
#include "GL/gl.h" #include "GL/gl.h"
#include "GL/glext.h" #include "GL/glext.h"
#include "GL/glu.h"
#if LL_LINUX && !LL_MESA_HEADLESS #if LL_LINUX && !LL_MESA_HEADLESS
@@ -551,7 +548,6 @@ extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#include <GL/gl.h> #include <GL/gl.h>
#include <GL/glu.h>
// quotes so we get libraries/.../GL/ version // quotes so we get libraries/.../GL/ version
#include "GL/glext.h" #include "GL/glext.h"
@@ -789,7 +785,6 @@ extern PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB;
// LL_DARWIN // LL_DARWIN
#include <OpenGL/gl.h> #include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#define GL_EXT_separate_specular_color 1 #define GL_EXT_separate_specular_color 1
#include <OpenGL/glext.h> #include <OpenGL/glext.h>

View File

@@ -468,6 +468,8 @@ LLImageGL::~LLImageGL()
sCount--; sCount--;
} }
const S8 INVALID_OFFSET = -99 ;
void LLImageGL::init(BOOL usemipmaps) void LLImageGL::init(BOOL usemipmaps)
{ {
// keep these members in the same order as declared in llimagehl.h // keep these members in the same order as declared in llimagehl.h
@@ -484,14 +486,12 @@ void LLImageGL::init(BOOL usemipmaps)
mHasExplicitFormat = FALSE; mHasExplicitFormat = FALSE;
mAutoGenMips = FALSE; mAutoGenMips = FALSE;
mCanMask = TRUE;
mIsMask = FALSE; mIsMask = FALSE;
mMaskRMSE = 1.f ; mMaskRMSE = 1.f ;
mNeedsAlphaAndPickMask = FALSE ;
mNeedsAlphaAndPickMask = TRUE ;
mAlphaStride = 0 ; mAlphaStride = 0 ;
mAlphaOffset = 0 ; mAlphaOffset = INVALID_OFFSET ;
mGLTextureCreated = FALSE ; mGLTextureCreated = FALSE ;
mTexName = 0; mTexName = 0;
@@ -1709,7 +1709,6 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b
} }
//Used by media in V2 //Used by media in V2
const S8 INVALID_OFFSET = -99 ;
void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask) void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask)
{ {
if(mNeedsAlphaAndPickMask != need_mask) if(mNeedsAlphaAndPickMask != need_mask)
@@ -1723,7 +1722,6 @@ void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask)
else //do not need alpha mask else //do not need alpha mask
{ {
mAlphaOffset = INVALID_OFFSET ; mAlphaOffset = INVALID_OFFSET ;
mCanMask = FALSE;
} }
} }
} }
@@ -1746,8 +1744,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
mAlphaStride = 2; mAlphaStride = 2;
break; break;
case GL_RGB: case GL_RGB:
mNeedsAlphaAndPickMask = FALSE ; setNeedsAlphaAndPickMask(FALSE);
mCanMask = FALSE;
return ; //no alpha channel. return ; //no alpha channel.
case GL_RGBA: case GL_RGBA:
mAlphaStride = 4; mAlphaStride = 4;
@@ -1793,15 +1790,14 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
{ {
llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl; llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl;
mNeedsAlphaAndPickMask = FALSE ; setNeedsAlphaAndPickMask(FALSE);
mCanMask = FALSE;
} }
} }
//std::map<LLGLuint, std::list<std::pair<std::string,std::string> > > sTextureMaskMap; //std::map<LLGLuint, std::list<std::pair<std::string,std::string> > > sTextureMaskMap;
void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h) void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
{ {
if(!mNeedsAlphaAndPickMask || !mCanMask) if(!mNeedsAlphaAndPickMask)
{ {
return ; return ;
} }

View File

@@ -135,7 +135,7 @@ public:
BOOL getHasGLTexture() const { return mTexName != 0; } BOOL getHasGLTexture() const { return mTexName != 0; }
LLGLuint getTexName() const { return mTexName; } LLGLuint getTexName() const { return mTexName; }
BOOL getIsAlphaMask(const F32 max_rmse) const { return mCanMask && (max_rmse < 0.f ? (bool)mIsMask : (mMaskRMSE <= max_rmse)); } BOOL getIsAlphaMask(const F32 max_rmse) const { return mNeedsAlphaAndPickMask && (max_rmse < 0.f ? (bool)mIsMask : (mMaskRMSE <= max_rmse)); }
BOOL getIsResident(BOOL test_now = FALSE); // not const BOOL getIsResident(BOOL test_now = FALSE); // not const
@@ -185,7 +185,6 @@ private:
S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents) S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents)
S8 mAutoGenMips; S8 mAutoGenMips;
BOOL mCanMask;
BOOL mIsMask; BOOL mIsMask;
F32 mMaskRMSE; F32 mMaskRMSE;
BOOL mNeedsAlphaAndPickMask; BOOL mNeedsAlphaAndPickMask;

View File

@@ -43,6 +43,7 @@
#include "llsdutil_math.h" #include "llsdutil_math.h"
#include "llvertexbuffer.h" #include "llvertexbuffer.h"
#include "llfasttimer.h" #include "llfasttimer.h"
#include "llmatrix4a.h"
extern LLGLSLShader gPostColorFilterProgram; extern LLGLSLShader gPostColorFilterProgram;
extern LLGLSLShader gPostNightVisionProgram; extern LLGLSLShader gPostNightVisionProgram;
@@ -305,21 +306,21 @@ public:
{ {
addSetting(mStrength); addSetting(mStrength);
} }
/*virtual*/ bool isEnabled() const { return LLPostProcessShader::isEnabled() && llabs(gGLModelView[0] - gGLPreviousModelView[0]) > .0000001; } /*virtual*/ bool isEnabled() const { return LLPostProcessShader::isEnabled() && llabs(gGLModelView.getF32ptr()[0] - gGLPreviousModelView.getF32ptr()[0]) > .0000001; }
/*virtual*/ S32 getColorChannel() const { return 0; } /*virtual*/ S32 getColorChannel() const { return 0; }
/*virtual*/ S32 getDepthChannel() const { return 1; } /*virtual*/ S32 getDepthChannel() const { return 1; }
/*virtual*/ QuadType preDraw() /*virtual*/ QuadType preDraw()
{ {
glh::matrix4f inv_proj(gGLModelView); LLMatrix4a inv_proj;
inv_proj.mult_left(gGLProjection); inv_proj.setMul(gGLProjection,gGLModelView);
inv_proj = inv_proj.inverse(); inv_proj.invert();
glh::matrix4f prev_proj(gGLPreviousModelView); LLMatrix4a prev_proj;
prev_proj.mult_left(gGLProjection); prev_proj.setMul(gGLProjection,gGLPreviousModelView);
LLVector2 screen_rect = LLPostProcess::getInstance()->getDimensions(); LLVector2 screen_rect = LLPostProcess::getInstance()->getDimensions();
getShader().uniformMatrix4fv(sPrevProj, 1, GL_FALSE, prev_proj.m); getShader().uniformMatrix4fv(sPrevProj, 1, GL_FALSE, prev_proj.getF32ptr());
getShader().uniformMatrix4fv(sInvProj, 1, GL_FALSE, inv_proj.m); getShader().uniformMatrix4fv(sInvProj, 1, GL_FALSE, inv_proj.getF32ptr());
getShader().uniform2fv(sScreenRes, 1, screen_rect.mV); getShader().uniform2fv(sScreenRes, 1, screen_rect.mV);
getShader().uniform1i(sBlurStrength, mStrength); getShader().uniform1i(sBlurStrength, mStrength);

View File

@@ -35,17 +35,18 @@
#include "llrendertarget.h" #include "llrendertarget.h"
#include "lltexture.h" #include "lltexture.h"
#include "llshadermgr.h" #include "llshadermgr.h"
#include "llmatrix4a.h"
LLRender gGL; LLRender gGL;
// Handy copies of last good GL matrices // Handy copies of last good GL matrices
//Would be best to migrate these to LLMatrix4a and LLVector4a, but that's too divergent right now. //Would be best to migrate these to LLMatrix4a and LLVector4a, but that's too divergent right now.
LL_ALIGN_16(F32 gGLModelView[16]); LLMatrix4a gGLModelView;
LL_ALIGN_16(F32 gGLLastModelView[16]); LLMatrix4a gGLLastModelView;
LL_ALIGN_16(F32 gGLPreviousModelView[16]); LLMatrix4a gGLPreviousModelView;
LL_ALIGN_16(F32 gGLLastProjection[16]); LLMatrix4a gGLLastProjection;
LL_ALIGN_16(F32 gGLProjection[16]); LLMatrix4a gGLProjection;
LL_ALIGN_16(S32 gGLViewport[4]); S32 gGLViewport[4];
U32 LLRender::sUICalls = 0; U32 LLRender::sUICalls = 0;
U32 LLRender::sUIVerts = 0; U32 LLRender::sUIVerts = 0;
@@ -928,12 +929,12 @@ void LLLightState::setPosition(const LLVector4& position)
} }
else else
{ //transform position by current modelview matrix { //transform position by current modelview matrix
glh::vec4f pos(position.mV); LLVector4a pos;
pos.loadua(position.mV);
const glh::matrix4f& mat = gGL.getModelviewMatrix(); gGL.getModelviewMatrix().rotate4(pos,pos);
mat.mult_matrix_vec(pos);
mPosition.set(pos.v); mPosition.set(pos.getF32ptr());
} }
} }
@@ -1014,12 +1015,12 @@ void LLLightState::setSpotDirection(const LLVector3& direction)
} }
else else
{ //transform direction by current modelview matrix { //transform direction by current modelview matrix
glh::vec3f dir(direction.mV); LLVector4a dir;
dir.load3(direction.mV);
const glh::matrix4f& mat = gGL.getModelviewMatrix(); gGL.getModelviewMatrix().rotate(dir,dir);
mat.mult_matrix_dir(dir);
mSpotDirection.set(dir.v); mSpotDirection.set(dir.getF32ptr());
} }
} }
@@ -1066,6 +1067,18 @@ LLRender::LLRender()
} }
mLightHash = 0; mLightHash = 0;
//Init base matrix for each mode
for(S32 i = 0; i < NUM_MATRIX_MODES; ++i)
{
mMatrix[i][0].setIdentity();
}
gGLModelView.setIdentity();
gGLLastModelView.setIdentity();
gGLPreviousModelView.setIdentity();
gGLLastProjection.setIdentity();
gGLProjection.setIdentity();
} }
LLRender::~LLRender() LLRender::~LLRender()
@@ -1188,12 +1201,11 @@ void LLRender::syncMatrices()
}; };
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
static LLMatrix4a cached_mvp;
static glh::matrix4f cached_mvp;
static U32 cached_mvp_mdv_hash = 0xFFFFFFFF; static U32 cached_mvp_mdv_hash = 0xFFFFFFFF;
static U32 cached_mvp_proj_hash = 0xFFFFFFFF; static U32 cached_mvp_proj_hash = 0xFFFFFFFF;
static glh::matrix4f cached_normal; static LLMatrix4a cached_normal;
static U32 cached_normal_hash = 0xFFFFFFFF; static U32 cached_normal_hash = 0xFFFFFFFF;
if (shader) if (shader)
@@ -1205,9 +1217,9 @@ void LLRender::syncMatrices()
U32 i = MM_MODELVIEW; U32 i = MM_MODELVIEW;
if (mMatHash[i] != shader->mMatHash[i]) if (mMatHash[i] != shader->mMatHash[i])
{ //update modelview, normal, and MVP { //update modelview, normal, and MVP
glh::matrix4f& mat = mMatrix[i][mMatIdx[i]]; const LLMatrix4a& mat = mMatrix[i][mMatIdx[i]];
shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m); shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.getF32ptr());
shader->mMatHash[i] = mMatHash[i]; shader->mMatHash[i] = mMatHash[i];
//update normal matrix //update normal matrix
@@ -1216,20 +1228,20 @@ void LLRender::syncMatrices()
{ {
if (cached_normal_hash != mMatHash[i]) if (cached_normal_hash != mMatHash[i])
{ {
cached_normal = mat.inverse().transpose(); cached_normal = mat;
cached_normal.invert();
cached_normal.transpose();
cached_normal_hash = mMatHash[i]; cached_normal_hash = mMatHash[i];
} }
glh::matrix4f& norm = cached_normal; const LLMatrix4a& norm = cached_normal;
F32 norm_mat[] = LLVector3 norms[3];
{ norms[0].set(norm.getRow<0>().getF32ptr());
norm.m[0], norm.m[1], norm.m[2], norms[1].set(norm.getRow<1>().getF32ptr());
norm.m[4], norm.m[5], norm.m[6], norms[2].set(norm.getRow<2>().getF32ptr());
norm.m[8], norm.m[9], norm.m[10]
};
shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat); shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norms[0].mV);
} }
//update MVP matrix //update MVP matrix
@@ -1241,13 +1253,12 @@ void LLRender::syncMatrices()
if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
{ {
cached_mvp = mat; cached_mvp.setMul(mMatrix[proj][mMatIdx[proj]], mat);
cached_mvp.mult_left(mMatrix[proj][mMatIdx[proj]]);
cached_mvp_mdv_hash = mMatHash[i]; cached_mvp_mdv_hash = mMatHash[i];
cached_mvp_proj_hash = mMatHash[MM_PROJECTION]; cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
} }
shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m); shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.getF32ptr());
} }
} }
@@ -1255,9 +1266,9 @@ void LLRender::syncMatrices()
i = MM_PROJECTION; i = MM_PROJECTION;
if (mMatHash[i] != shader->mMatHash[i]) if (mMatHash[i] != shader->mMatHash[i])
{ //update projection matrix, normal, and MVP { //update projection matrix, normal, and MVP
glh::matrix4f& mat = mMatrix[i][mMatIdx[i]]; const LLMatrix4a& mat = mMatrix[i][mMatIdx[i]];
shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m); shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.getF32ptr());
shader->mMatHash[i] = mMatHash[i]; shader->mMatHash[i] = mMatHash[i];
if (!mvp_done) if (!mvp_done)
@@ -1269,13 +1280,12 @@ void LLRender::syncMatrices()
if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
{ {
U32 mdv = MM_MODELVIEW; U32 mdv = MM_MODELVIEW;
cached_mvp = mat; cached_mvp.setMul(mat,mMatrix[mdv][mMatIdx[mdv]]);
cached_mvp.mult_right(mMatrix[mdv][mMatIdx[mdv]]);
cached_mvp_mdv_hash = mMatHash[MM_MODELVIEW]; cached_mvp_mdv_hash = mMatHash[MM_MODELVIEW];
cached_mvp_proj_hash = mMatHash[MM_PROJECTION]; cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
} }
shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m); shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.getF32ptr());
} }
} }
} }
@@ -1284,7 +1294,7 @@ void LLRender::syncMatrices()
{ {
if (mMatHash[i] != shader->mMatHash[i]) if (mMatHash[i] != shader->mMatHash[i])
{ {
shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].m); shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].getF32ptr());
shader->mMatHash[i] = mMatHash[i]; shader->mMatHash[i] = mMatHash[i];
} }
} }
@@ -1312,7 +1322,7 @@ void LLRender::syncMatrices()
if (mMatHash[i] != mCurMatHash[i]) if (mMatHash[i] != mCurMatHash[i])
{ {
glMatrixMode(mode[i]); glMatrixMode(mode[i]);
glLoadMatrixf(mMatrix[i][mMatIdx[i]].m); glLoadMatrixf(mMatrix[i][mMatIdx[i]].getF32ptr());
mCurMatHash[i] = mMatHash[i]; mCurMatHash[i] = mMatHash[i];
} }
} }
@@ -1323,7 +1333,7 @@ void LLRender::syncMatrices()
{ {
gGL.getTexUnit(i-2)->activate(); gGL.getTexUnit(i-2)->activate();
glMatrixMode(mode[i]); glMatrixMode(mode[i]);
glLoadMatrixf(mMatrix[i][mMatIdx[i]].m); glLoadMatrixf(mMatrix[i][mMatIdx[i]].getF32ptr());
mCurMatHash[i] = mMatHash[i]; mCurMatHash[i] = mMatHash[i];
} }
} }
@@ -1332,32 +1342,143 @@ void LLRender::syncMatrices()
stop_glerror(); stop_glerror();
} }
LLMatrix4a LLRender::genRot(const GLfloat& a, const LLVector4a& axis) const
{
F32 r = a * DEG_TO_RAD;
F32 c = cosf(r);
F32 s = sinf(r);
F32 ic = 1.f-c;
const LLVector4a add1(c,axis[VZ]*s,-axis[VY]*s); //1,z,-y
const LLVector4a add2(-axis[VZ]*s,c,axis[VX]*s); //-z,1,x
const LLVector4a add3(axis[VY]*s,-axis[VX]*s,c); //y,-x,1
LLVector4a axis_x;
axis_x.splat<0>(axis);
LLVector4a axis_y;
axis_y.splat<1>(axis);
LLVector4a axis_z;
axis_z.splat<2>(axis);
LLVector4a c_axis;
c_axis.setMul(axis,ic);
LLMatrix4a rot_mat;
rot_mat.getRow<0>().setMul(c_axis,axis_x);
rot_mat.getRow<0>().add(add1);
rot_mat.getRow<1>().setMul(c_axis,axis_y);
rot_mat.getRow<1>().add(add2);
rot_mat.getRow<2>().setMul(c_axis,axis_z);
rot_mat.getRow<2>().add(add3);
rot_mat.setRow<3>(LLVector4a(0,0,0,1));
return rot_mat;
}
LLMatrix4a LLRender::genOrtho(const GLfloat& left, const GLfloat& right, const GLfloat& bottom, const GLfloat& top, const GLfloat& zNear, const GLfloat& zFar) const
{
LLMatrix4a ortho_mat;
ortho_mat.setRow<0>(LLVector4a(2.f/(right-left),0,0));
ortho_mat.setRow<1>(LLVector4a(0,2.f/(top-bottom),0));
ortho_mat.setRow<2>(LLVector4a(0,0,-2.f/(zFar-zNear)));
ortho_mat.setRow<3>(LLVector4a(-(right+left)/(right-left),-(top+bottom)/(top-bottom),-(zFar+zNear)/(zFar-zNear),1));
return ortho_mat;
}
LLMatrix4a LLRender::genPersp(const GLfloat& fovy, const GLfloat& aspect, const GLfloat& zNear, const GLfloat& zFar) const
{
GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f);
LLMatrix4a persp_mat;
persp_mat.setRow<0>(LLVector4a(f/aspect,0,0));
persp_mat.setRow<1>(LLVector4a(0,f,0));
persp_mat.setRow<2>(LLVector4a(0,0,(zFar+zNear)/(zNear-zFar),-1.f));
persp_mat.setRow<3>(LLVector4a(0,0,(2.f*zFar*zNear)/(zNear-zFar),0));
return persp_mat;
}
LLMatrix4a LLRender::genLook(const LLVector3& pos_in, const LLVector3& dir_in, const LLVector3& up_in) const
{
const LLVector4a pos(pos_in.mV[VX],pos_in.mV[VY],pos_in.mV[VZ],1.f);
LLVector4a dir(dir_in.mV[VX],dir_in.mV[VY],dir_in.mV[VZ]);
const LLVector4a up(up_in.mV[VX],up_in.mV[VY],up_in.mV[VZ]);
LLVector4a left_norm;
left_norm.setCross3(dir,up);
left_norm.normalize3fast();
LLVector4a up_norm;
up_norm.setCross3(left_norm,dir);
up_norm.normalize3fast();
LLVector4a& dir_norm = dir;
dir.normalize3fast();
LLVector4a left_dot;
left_dot.setAllDot3(left_norm,pos);
left_dot.negate();
LLVector4a up_dot;
up_dot.setAllDot3(up_norm,pos);
up_dot.negate();
LLVector4a dir_dot;
dir_dot.setAllDot3(dir_norm,pos);
dir_norm.negate();
LLMatrix4a lookat_mat;
lookat_mat.setRow<0>(left_norm);
lookat_mat.setRow<1>(up_norm);
lookat_mat.setRow<2>(dir_norm);
lookat_mat.setRow<3>(LLVector4a(0,0,0,1));
lookat_mat.getRow<0>().copyComponent<3>(left_dot);
lookat_mat.getRow<1>().copyComponent<3>(up_dot);
lookat_mat.getRow<2>().copyComponent<3>(dir_dot);
lookat_mat.transpose();
return lookat_mat;
}
const LLMatrix4a& LLRender::genNDCtoWC() const
{
static LLMatrix4a mat(
LLVector4a(.5f,0,0,0),
LLVector4a(0,.5f,0,0),
LLVector4a(0,0,.5f,0),
LLVector4a(.5f,.5f,.5f,1.f));
return mat;
}
void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
{ {
if( llabs(x) < F_APPROXIMATELY_ZERO &&
llabs(y) < F_APPROXIMATELY_ZERO &&
llabs(z) < F_APPROXIMATELY_ZERO)
{
return;
}
flush(); flush();
{ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].applyTranslation_affine(x,y,z);
glh::matrix4f trans_mat(1,0,0,x, mMatHash[mMatrixMode]++;
0,1,0,y,
0,0,1,z,
0,0,0,1);
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(trans_mat);
mMatHash[mMatrixMode]++;
}
} }
void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z) void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
{ {
if( (llabs(x-1.f)) < F_APPROXIMATELY_ZERO &&
(llabs(y-1.f)) < F_APPROXIMATELY_ZERO &&
(llabs(z-1.f)) < F_APPROXIMATELY_ZERO)
{
return;
}
flush(); flush();
{ {
glh::matrix4f scale_mat(x,0,0,0, mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].applyScale_affine(x,y,z);
0,y,0,0,
0,0,z,0,
0,0,0,1);
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(scale_mat);
mMatHash[mMatrixMode]++; mMatHash[mMatrixMode]++;
} }
} }
@@ -1366,38 +1487,156 @@ void LLRender::ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zF
{ {
flush(); flush();
{ LLMatrix4a ortho_mat;
ortho_mat.setRow<0>(LLVector4a(2.f/(right-left),0,0));
ortho_mat.setRow<1>(LLVector4a(0,2.f/(top-bottom),0));
ortho_mat.setRow<2>(LLVector4a(0,0,-2.f/(zFar-zNear)));
ortho_mat.setRow<3>(LLVector4a(-(right+left)/(right-left),-(top+bottom)/(top-bottom),-(zFar+zNear)/(zFar-zNear),1));
glh::matrix4f ortho_mat(2.f/(right-left),0,0, -(right+left)/(right-left), mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mul_affine(ortho_mat);
0,2.f/(top-bottom),0, -(top+bottom)/(top-bottom), mMatHash[mMatrixMode]++;
0,0,-2.f/(zFar-zNear), -(zFar+zNear)/(zFar-zNear), }
0,0,0,1);
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(ortho_mat); void LLRender::rotatef(const LLMatrix4a& rot)
mMatHash[mMatrixMode]++; {
} flush();
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mul_affine(rot);
mMatHash[mMatrixMode]++;
} }
void LLRender::rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z) void LLRender::rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z)
{ {
if( llabs(a) < F_APPROXIMATELY_ZERO ||
llabs(a-360.f) < F_APPROXIMATELY_ZERO)
{
return;
}
flush(); flush();
{ rotatef(genRot(a,x,y,z));
F32 r = a * DEG_TO_RAD; }
F32 c = cosf(r); //LLRender::projectf & LLRender::unprojectf adapted from gluProject & gluUnproject in Mesa's GLU 9.0 library.
F32 s = sinf(r); // License/Copyright Statement:
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice including the dates of first publication and
* either this permission notice or a reference to
* http://oss.sgi.com/projects/FreeB/
* shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of Silicon Graphics, Inc.
* shall not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization from
* Silicon Graphics, Inc.
*/
F32 ic = 1.f-c; bool LLRender::projectf(const LLVector3& object, const LLMatrix4a& modelview, const LLMatrix4a& projection, const LLRect& viewport, LLVector3& windowCoordinate)
{
//Begin SSE intrinsics
glh::matrix4f rot_mat(x*x*ic+c, x*y*ic-z*s, x*z*ic+y*s, 0, // Declare locals
x*y*ic+z*s, y*y*ic+c, y*z*ic-x*s, 0, const LLVector4a obj_vector(object.mV[VX],object.mV[VY],object.mV[VZ]);
x*z*ic-y*s, y*z*ic+x*s, z*z*ic+c, 0, const LLVector4a one(1.f);
0,0,0,1); LLVector4a temp_vec; //Scratch vector
LLVector4a w; //Splatted W-component.
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(rot_mat); modelview.affineTransform(obj_vector, temp_vec); //temp_vec = modelview * obj_vector;
mMatHash[mMatrixMode]++;
} //Passing temp_matrix as v and res is safe. res not altered until after all other calculations
projection.rotate4(temp_vec, temp_vec); //temp_vec = projection * temp_vec
w.splat<3>(temp_vec); //w = temp_vec.wwww
//If w == 0.f, use 1.f instead.
LLVector4a div;
div.setSelectWithMask( w.equal( _mm_setzero_ps() ), one, w ); //float div = (w[N] == 0.f ? 1.f : w[N]);
temp_vec.div(div); //temp_vec /= div;
//Map x, y to range 0-1
temp_vec.mul(.5f);
temp_vec.add(.5f);
LLVector4Logical mask = temp_vec.equal(_mm_setzero_ps());
if(mask.areAllSet(LLVector4Logical::MASK_W))
return false;
//End SSE intrinsics
//Window coordinates
windowCoordinate[0]=temp_vec[VX]*viewport.getWidth()+viewport.mLeft;
windowCoordinate[1]=temp_vec[VY]*viewport.getHeight()+viewport.mBottom;
//This is only correct when glDepthRange(0.0, 1.0)
windowCoordinate[2]=temp_vec[VZ];
return true;
}
bool LLRender::unprojectf(const LLVector3& windowCoordinate, const LLMatrix4a& modelview, const LLMatrix4a& projection, const LLRect& viewport, LLVector3& object)
{
//Begin SSE intrinsics
// Declare locals
static const LLVector4a one(1.f);
static const LLVector4a two(2.f);
LLVector4a norm_view(
((windowCoordinate.mV[VX] - (F32)viewport.mLeft) / (F32)viewport.getWidth()),
((windowCoordinate.mV[VY] - (F32)viewport.mBottom) / (F32)viewport.getHeight()),
windowCoordinate.mV[VZ],
1.f);
LLMatrix4a inv_mat; //Inverse transformation matrix
LLVector4a temp_vec; //Scratch vector
LLVector4a w; //Splatted W-component.
inv_mat.setMul(projection,modelview); //inv_mat = projection*modelview
float det = inv_mat.invert();
//Normalize. -1.0 : +1.0
norm_view.mul(two); // norm_view *= vec4(.2f)
norm_view.sub(one); // norm_view -= vec4(1.f)
inv_mat.rotate4(norm_view,temp_vec); //inv_mat * norm_view
w.splat<3>(temp_vec); //w = temp_vec.wwww
//If w == 0.f, use 1.f instead. Defer return if temp_vec.w == 0.f until after all SSE intrinsics.
LLVector4a div;
div.setSelectWithMask( w.equal( _mm_setzero_ps() ), one, w ); //float div = (w[N] == 0.f ? 1.f : w[N]);
temp_vec.div(div); //temp_vec /= div;
LLVector4Logical mask = temp_vec.equal(_mm_setzero_ps());
if(mask.areAllSet(LLVector4Logical::MASK_W))
return false;
//End SSE intrinsics
if(det == 0.f)
return false;
object.set(temp_vec.getF32ptr());
return true;
} }
void LLRender::pushMatrix() void LLRender::pushMatrix()
@@ -1433,24 +1672,21 @@ void LLRender::popMatrix()
} }
} }
void LLRender::loadMatrix(const GLfloat* m) void LLRender::loadMatrix(const LLMatrix4a& mat)
{ {
flush(); flush();
{
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].set_value((GLfloat*) m); mMatrix[mMatrixMode][mMatIdx[mMatrixMode]] = mat;
mMatHash[mMatrixMode]++; mMatHash[mMatrixMode]++;
}
} }
void LLRender::multMatrix(const GLfloat* m) void LLRender::multMatrix(const LLMatrix4a& mat)
{ {
flush(); flush();
{
glh::matrix4f mat((GLfloat*) m);
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(mat); mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mul_affine(mat);
mMatHash[mMatrixMode]++; mMatHash[mMatrixMode]++;
}
} }
void LLRender::matrixMode(U32 mode) void LLRender::matrixMode(U32 mode)
@@ -1479,20 +1715,16 @@ void LLRender::loadIdentity()
{ {
flush(); flush();
{ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].setIdentity();
llassert_always(mMatrixMode < NUM_MATRIX_MODES) ; mMatHash[mMatrixMode]++;
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity();
mMatHash[mMatrixMode]++;
}
} }
const glh::matrix4f& LLRender::getModelviewMatrix() const LLMatrix4a& LLRender::getModelviewMatrix()
{ {
return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]]; return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
} }
const glh::matrix4f& LLRender::getProjectionMatrix() const LLMatrix4a& LLRender::getProjectionMatrix()
{ {
return mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]]; return mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
} }

View File

@@ -38,18 +38,19 @@
#include "v3math.h" #include "v3math.h"
#include "v4coloru.h" #include "v4coloru.h"
#include "v4math.h" #include "v4math.h"
#include "llmatrix4a.h"
#include "llalignedarray.h" #include "llalignedarray.h"
#include "llstrider.h" #include "llstrider.h"
#include "llpointer.h" #include "llpointer.h"
#include "llglheaders.h" #include "llglheaders.h"
#include "llmatrix4a.h" #include "llrect.h"
#include "glh/glh_linear.h"
class LLVertexBuffer; class LLVertexBuffer;
class LLCubeMap; class LLCubeMap;
class LLImageGL; class LLImageGL;
class LLRenderTarget; class LLRenderTarget;
class LLTexture ; class LLTexture ;
class LLMatrix4a;
#define LL_MATRIX_STACK_DEPTH 32 #define LL_MATRIX_STACK_DEPTH 32
@@ -257,6 +258,8 @@ protected:
F32 mSpotExponent; F32 mSpotExponent;
F32 mSpotCutoff; F32 mSpotCutoff;
}; };
LL_ALIGN_PREFIX(16)
class LLRender class LLRender
{ {
friend class LLTexUnit; friend class LLTexUnit;
@@ -343,21 +346,32 @@ public:
// Needed when the render context has changed and invalidated the current state // Needed when the render context has changed and invalidated the current state
void refreshState(void); void refreshState(void);
LLMatrix4a genRot(const GLfloat& a, const LLVector4a& axis) const;
LLMatrix4a genRot(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z) const { return genRot(a,LLVector4a(x,y,z)); }
LLMatrix4a genOrtho(const GLfloat& left, const GLfloat& right, const GLfloat& bottom, const GLfloat& top, const GLfloat& znear, const GLfloat& zfar) const;
LLMatrix4a genPersp(const GLfloat& fovy, const GLfloat& aspect, const GLfloat& znear, const GLfloat& zfar) const;
LLMatrix4a genLook(const LLVector3& pos_in, const LLVector3& dir_in, const LLVector3& up_in) const;
const LLMatrix4a& genNDCtoWC() const;
void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z); void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z); void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
//rotatef requires generation of a transform matrix involving sine/cosine. If rotating by a constant value, use genRot, store the result in a static variable, and pass that var to rotatef.
void rotatef(const LLMatrix4a& rot);
void rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z); void rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z);
void ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar); void ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar);
bool projectf(const LLVector3& object, const LLMatrix4a& modelview, const LLMatrix4a& projection, const LLRect& viewport, LLVector3& windowCoordinate);
bool unprojectf(const LLVector3& windowCoordinate, const LLMatrix4a& modelview, const LLMatrix4a& projection, const LLRect& viewport, LLVector3& object);
void pushMatrix(); void pushMatrix();
void popMatrix(); void popMatrix();
void loadMatrix(const GLfloat* m); void loadMatrix(const LLMatrix4a& mat);
void loadIdentity(); void loadIdentity();
void multMatrix(const GLfloat* m); void multMatrix(const LLMatrix4a& mat);
void matrixMode(U32 mode); void matrixMode(U32 mode);
U32 getMatrixMode(); U32 getMatrixMode();
const glh::matrix4f& getModelviewMatrix(); const LLMatrix4a& getModelviewMatrix();
const glh::matrix4f& getProjectionMatrix(); const LLMatrix4a& getProjectionMatrix();
void syncMatrices(); void syncMatrices();
void syncLightState(); void syncLightState();
@@ -447,7 +461,7 @@ private:
U32 mMatrixMode; U32 mMatrixMode;
U32 mMatIdx[NUM_MATRIX_MODES]; U32 mMatIdx[NUM_MATRIX_MODES];
U32 mMatHash[NUM_MATRIX_MODES]; U32 mMatHash[NUM_MATRIX_MODES];
glh::matrix4f mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH]; LL_ALIGN_16(LLMatrix4a mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH]);
U32 mCurMatHash[NUM_MATRIX_MODES]; U32 mCurMatHash[NUM_MATRIX_MODES];
U32 mLightHash; U32 mLightHash;
LLColor4 mAmbientLightColor; LLColor4 mAmbientLightColor;
@@ -478,13 +492,14 @@ private:
LLAlignedArray<LLVector4a, 64> mUIOffset; LLAlignedArray<LLVector4a, 64> mUIOffset;
LLAlignedArray<LLVector4a, 64> mUIScale; LLAlignedArray<LLVector4a, 64> mUIScale;
}; } LL_ALIGN_POSTFIX(16);
extern F32 gGLModelView[16];
extern F32 gGLLastModelView[16]; extern LLMatrix4a gGLModelView;
extern F32 gGLLastProjection[16]; extern LLMatrix4a gGLLastModelView;
extern F32 gGLPreviousModelView[16]; extern LLMatrix4a gGLLastProjection;
extern F32 gGLProjection[16]; extern LLMatrix4a gGLPreviousModelView;
extern LLMatrix4a gGLProjection;
extern S32 gGLViewport[4]; extern S32 gGLViewport[4];
extern LLRender gGL; extern LLRender gGL;

View File

@@ -2044,6 +2044,10 @@ bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index,
{ {
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range); return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
} }
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector4a,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range) bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
{ {
return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range); return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range);

View File

@@ -250,6 +250,7 @@ public:
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getNormalStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);

View File

@@ -909,6 +909,19 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char)
return result; return result;
} }
BOOL LLComboBox::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
if (mList->getVisible()) return mList->handleScrollWheel(x, y, clicks);
if (mAllowTextEntry) // We might be editable
if (!mList->getFirstSelected()) // We aren't in the list, don't kill their text
return false;
setCurrentByIndex(llclamp(getCurrentIndex() + clicks, 0, getItemCount() - 1));
prearrangeList();
onCommit();
return true;
}
void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative) void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative)
{ {
mAllowTextEntry = allow; mAllowTextEntry = allow;
@@ -924,6 +937,7 @@ void LLComboBox::setTextEntry(const LLStringExplicit& text)
if (mTextEntry) if (mTextEntry)
{ {
mTextEntry->setText(text); mTextEntry->setText(text);
mTextEntry->setCursor(0); // Singu Note: Move the cursor over to the beginning
mHasAutocompletedText = FALSE; mHasAutocompletedText = FALSE;
updateSelection(); updateSelection();
} }

View File

@@ -76,6 +76,7 @@ public:
virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect);
virtual BOOL handleKeyHere(KEY key, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char); virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
// LLUICtrl interface // LLUICtrl interface
virtual void clear(); // select nothing virtual void clear(); // select nothing

View File

@@ -571,6 +571,9 @@ void LLFloater::open() /* Flawfinder: ignore */
setVisibleAndFrontmost(mAutoFocus); setVisibleAndFrontmost(mAutoFocus);
} }
if (!getControlName().empty())
setControlValue(true);
onOpen(); onOpen();
} }
@@ -633,6 +636,9 @@ void LLFloater::close(bool app_quitting)
} }
} }
if (!app_quitting && !getControlName().empty())
setControlValue(false);
// Let floater do cleanup. // Let floater do cleanup.
onClose(app_quitting); onClose(app_quitting);
} }

View File

@@ -1543,6 +1543,8 @@ class UpdateItemSM : public AIStateMachine
static void add(UpdateItem const& ui); static void add(UpdateItem const& ui);
/*virtual*/ const char* getName() const { return "UpdateItemSM"; }
private: private:
static UpdateItemSM* sSelf; static UpdateItemSM* sSelf;
typedef std::deque<UpdateItem> updateQueue_type; typedef std::deque<UpdateItem> updateQueue_type;

View File

@@ -46,16 +46,36 @@
static LLRegisterWidget<LLRadioGroup> r("radio_group"); static LLRegisterWidget<LLRadioGroup> r("radio_group");
/*
* A checkbox control with use_radio_style == true.
*/
class LLRadioCtrl : public LLCheckBoxCtrl
{
public:
LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const std::string& value = "", const LLFontGL* font = NULL, commit_callback_t commit_callback = NULL);
/*virtual*/ ~LLRadioCtrl();
virtual LLXMLNodePtr getXML(bool save_children = true) const;
/*virtual*/ void setValue(const LLSD& value);
LLSD getPayload() { return mPayload; }
protected:
friend class LLUICtrlFactory;
LLSD mPayload; // stores data that this item represents in the radio group
};
LLRadioGroup::LLRadioGroup(const std::string& name, const LLRect& rect, LLRadioGroup::LLRadioGroup(const std::string& name, const LLRect& rect,
S32 initial_index, commit_callback_t commit_callback, S32 initial_index, commit_callback_t commit_callback,
BOOL border) : bool border, bool allow_deselect) :
LLUICtrl(name, rect, TRUE, commit_callback, FOLLOWS_LEFT | FOLLOWS_TOP), LLUICtrl(name, rect, TRUE, commit_callback, FOLLOWS_LEFT | FOLLOWS_TOP),
mSelectedIndex(initial_index) mSelectedIndex(initial_index),
mAllowDeselect(allow_deselect)
{ {
init(border); init(border);
} }
void LLRadioGroup::init(BOOL border) void LLRadioGroup::init(bool border)
{ {
if (border) if (border)
{ {
@@ -67,12 +87,19 @@ void LLRadioGroup::init(BOOL border)
} }
LLRadioGroup::~LLRadioGroup() LLRadioGroup::~LLRadioGroup()
{ {
} }
// virtual
BOOL LLRadioGroup::postBuild()
{
if (!mRadioButtons.empty())
{
mRadioButtons[0]->setTabStop(true);
}
return TRUE;
}
// virtual // virtual
void LLRadioGroup::setEnabled(BOOL enabled) void LLRadioGroup::setEnabled(BOOL enabled)
@@ -133,16 +160,39 @@ void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled)
BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event) BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event)
{ {
if (index < 0 || index >= (S32)mRadioButtons.size()) if ((S32)mRadioButtons.size() <= index )
{ {
return FALSE; return FALSE;
} }
if (mSelectedIndex >= 0)
{
LLRadioCtrl* old_radio_item = mRadioButtons[mSelectedIndex];
old_radio_item->setTabStop(false);
old_radio_item->setValue( FALSE );
}
else
{
mRadioButtons[0]->setTabStop(false);
}
mSelectedIndex = index; mSelectedIndex = index;
if (mSelectedIndex >= 0)
{
LLRadioCtrl* radio_item = mRadioButtons[mSelectedIndex];
radio_item->setTabStop(true);
radio_item->setValue( TRUE );
if (hasFocus())
{
radio_item->focusFirstItem(FALSE, FALSE);
}
}
if (!from_event) if (!from_event)
{ {
setControlValue(getSelectedIndex()); setControlValue(getValue());
} }
return TRUE; return TRUE;
@@ -207,41 +257,23 @@ BOOL LLRadioGroup::handleKeyHere(KEY key, MASK mask)
return handled; return handled;
} }
void LLRadioGroup::draw() BOOL LLRadioGroup::handleMouseDown(S32 x, S32 y, MASK mask)
{ {
S32 current_button = 0; // grab focus preemptively, before child button takes mousecapture
//
BOOL take_focus = FALSE; if (hasTabStop())
if (gFocusMgr.childHasKeyboardFocus(this))
{ {
take_focus = TRUE; focusFirstItem(FALSE, FALSE);
} }
for (button_list_t::iterator iter = mRadioButtons.begin(); return LLUICtrl::handleMouseDown(x, y, mask);
iter != mRadioButtons.end(); ++iter)
{
LLRadioCtrl* radio = *iter;
BOOL selected = (current_button == mSelectedIndex);
radio->setValue( selected );
if (take_focus && selected && !gFocusMgr.childHasKeyboardFocus(radio))
{
// don't flash keyboard focus when navigating via keyboard
BOOL DONT_FLASH = FALSE;
radio->focusFirstItem(FALSE, DONT_FLASH);
}
current_button++;
}
LLView::draw();
} }
// When adding a button, we need to ensure that the radio // When adding a button, we need to ensure that the radio
// group gets a message when the button is clicked. // group gets a message when the button is clicked.
LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font ) LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font, const std::string& payload)
{ {
// Highlight will get fixed in draw method above LLRadioCtrl* radio = new LLRadioCtrl(name, rect, label, payload, font, boost::bind(&LLRadioGroup::onClickButton, this, _1));
LLRadioCtrl* radio = new LLRadioCtrl(name, rect, label, font, boost::bind(&LLRadioGroup::onClickButton, this, _1));
addChild(radio); addChild(radio);
mRadioButtons.push_back(radio); mRadioButtons.push_back(radio);
return radio; return radio;
@@ -252,7 +284,7 @@ LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::st
void LLRadioGroup::onClickButton(LLUICtrl* ctrl) void LLRadioGroup::onClickButton(LLUICtrl* ctrl)
{ {
// llinfos << "LLRadioGroup::onClickButton" << llendl; // LL_INFOS() << "LLRadioGroup::onClickButton" << LL_ENDL;
LLRadioCtrl* clicked_radio = dynamic_cast<LLRadioCtrl*>(ctrl); LLRadioCtrl* clicked_radio = dynamic_cast<LLRadioCtrl*>(ctrl);
if (!clicked_radio) if (!clicked_radio)
return; return;
@@ -263,9 +295,15 @@ void LLRadioGroup::onClickButton(LLUICtrl* ctrl)
LLRadioCtrl* radio = *iter; LLRadioCtrl* radio = *iter;
if (radio == clicked_radio) if (radio == clicked_radio)
{ {
// llinfos << "clicked button " << counter << llendl; if (index == mSelectedIndex && mAllowDeselect)
setSelectedIndex(index); {
setControlValue(index); // don't select anything
setSelectedIndex(-1);
}
else
{
setSelectedIndex(index);
}
// BUG: Calls click callback even if button didn't actually change // BUG: Calls click callback even if button didn't actually change
onCommit(); onCommit();
@@ -281,13 +319,12 @@ void LLRadioGroup::onClickButton(LLUICtrl* ctrl)
void LLRadioGroup::setValue( const LLSD& value ) void LLRadioGroup::setValue( const LLSD& value )
{ {
std::string value_name = value.asString();
int idx = 0; int idx = 0;
for (button_list_t::const_iterator iter = mRadioButtons.begin(); for (button_list_t::const_iterator iter = mRadioButtons.begin();
iter != mRadioButtons.end(); ++iter) iter != mRadioButtons.end(); ++iter)
{ {
LLRadioCtrl* radio = *iter; LLRadioCtrl* radio = *iter;
if (radio->getName() == value_name) if (radio->getPayload().asString() == value.asString())
{ {
setSelectedIndex(idx); setSelectedIndex(idx);
idx = -1; idx = -1;
@@ -304,8 +341,7 @@ void LLRadioGroup::setValue( const LLSD& value )
} }
else else
{ {
llwarns << "LLRadioGroup::setValue: radio_item with name=\"" << value_name << "\" not found, radio_group values are set by radio_item name not value. Falling back on LLUICtrl::setValue." << llendl; setSelectedIndex(-1, TRUE);
LLUICtrl::setValue(value);
} }
} }
} }
@@ -317,7 +353,7 @@ LLSD LLRadioGroup::getValue() const
for (button_list_t::const_iterator iter = mRadioButtons.begin(); for (button_list_t::const_iterator iter = mRadioButtons.begin();
iter != mRadioButtons.end(); ++iter) iter != mRadioButtons.end(); ++iter)
{ {
if (idx == index) return LLSD((*iter)->getName()); if (idx == index) return LLSD((*iter)->getPayload());
++idx; ++idx;
} }
return LLSD(); return LLSD();
@@ -333,6 +369,7 @@ LLXMLNodePtr LLRadioGroup::getXML(bool save_children) const
// Attributes // Attributes
node->createChild("draw_border", TRUE)->setBoolValue(mHasBorder); node->createChild("draw_border", TRUE)->setBoolValue(mHasBorder);
node->createChild("allow_deselect", TRUE)->setBoolValue(mAllowDeselect);
// Contents // Contents
@@ -355,8 +392,11 @@ LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
U32 initial_value = 0; U32 initial_value = 0;
node->getAttributeU32("initial_value", initial_value); node->getAttributeU32("initial_value", initial_value);
BOOL draw_border = TRUE; bool draw_border = true;
node->getAttributeBOOL("draw_border", draw_border); node->getAttribute_bool("draw_border", draw_border);
bool allow_deselect = false;
node->getAttribute_bool("allow_deselect", allow_deselect);
LLRect rect; LLRect rect;
createRect(node, rect, parent, LLRect()); createRect(node, rect, parent, LLRect());
@@ -365,7 +405,8 @@ LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
rect, rect,
initial_value, initial_value,
NULL, NULL,
draw_border); draw_border,
allow_deselect);
const std::string& contents = node->getValue(); const std::string& contents = node->getValue();
@@ -406,7 +447,13 @@ LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
createRect(child, item_rect, radio_group, rect); createRect(child, item_rect, radio_group, rect);
std::string item_label = child->getTextContents(); std::string item_label = child->getTextContents();
LLRadioCtrl* radio = radio_group->addRadioButton("radio", item_label, item_rect, font); child->getAttributeString("label", item_label);
std::string item_name("radio");
child->getAttributeString("name", item_name);
std::string payload(item_name); // Support old-style name as payload
child->getAttributeString("value", payload);
child->getAttributeString("initial_value", payload); // Synonym
LLRadioCtrl* radio = radio_group->addRadioButton(item_name, item_label, item_rect, font, payload);
radio->initFromXML(child, radio_group); radio->initFromXML(child, radio_group);
} }
@@ -432,11 +479,10 @@ LLUUID LLRadioGroup::getCurrentID() const
BOOL LLRadioGroup::setSelectedByValue(const LLSD& value, BOOL selected) BOOL LLRadioGroup::setSelectedByValue(const LLSD& value, BOOL selected)
{ {
S32 idx = 0; S32 idx = 0;
std::string value_string = value.asString();
for (button_list_t::const_iterator iter = mRadioButtons.begin(); for (button_list_t::const_iterator iter = mRadioButtons.begin();
iter != mRadioButtons.end(); ++iter) iter != mRadioButtons.end(); ++iter)
{ {
if((*iter)->getName() == value_string) if((*iter)->getPayload().asString() == value.asString())
{ {
setSelectedIndex(idx); setSelectedIndex(idx);
return TRUE; return TRUE;
@@ -455,11 +501,10 @@ LLSD LLRadioGroup::getSelectedValue()
BOOL LLRadioGroup::isSelected(const LLSD& value) const BOOL LLRadioGroup::isSelected(const LLSD& value) const
{ {
S32 idx = 0; S32 idx = 0;
std::string value_string = value.asString();
for (button_list_t::const_iterator iter = mRadioButtons.begin(); for (button_list_t::const_iterator iter = mRadioButtons.begin();
iter != mRadioButtons.end(); ++iter) iter != mRadioButtons.end(); ++iter)
{ {
if((*iter)->getName() == value_string) if((*iter)->getPayload().asString() == value.asString())
{ {
if (idx == mSelectedIndex) if (idx == mSelectedIndex)
{ {
@@ -481,6 +526,17 @@ BOOL LLRadioGroup::operateOnAll(EOperation op)
return FALSE; return FALSE;
} }
LLRadioCtrl::LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const std::string& value, const LLFontGL* font, commit_callback_t commit_callback)
: LLCheckBoxCtrl(name, rect, label, font, commit_callback, FALSE, RADIO_STYLE),
mPayload(value)
{
setTabStop(FALSE);
// use name as default "Value" for backwards compatibility
if (value.empty())
{
mPayload = name;
}
}
LLRadioCtrl::~LLRadioCtrl() LLRadioCtrl::~LLRadioCtrl()
{ {
@@ -499,7 +555,7 @@ LLXMLNodePtr LLRadioCtrl::getXML(bool save_children) const
node->setName(LL_RADIO_ITEM_TAG); node->setName(LL_RADIO_ITEM_TAG);
node->setStringValue(getLabel()); node->createChild("value", TRUE)->setStringValue(mPayload);
return node; return node;
} }

View File

@@ -37,26 +37,6 @@
#include "llcheckboxctrl.h" #include "llcheckboxctrl.h"
#include "llctrlselectioninterface.h" #include "llctrlselectioninterface.h"
/*
* A checkbox control with use_radio_style == true.
*/
class LLRadioCtrl : public LLCheckBoxCtrl
{
public:
LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const LLFontGL* font = NULL,
commit_callback_t commit_callback = NULL) :
LLCheckBoxCtrl(name, rect, label, font, commit_callback, FALSE, RADIO_STYLE)
{
setTabStop(FALSE);
}
/*virtual*/ ~LLRadioCtrl();
virtual LLXMLNodePtr getXML(bool save_children = true) const;
/*virtual*/ void setValue(const LLSD& value);
};
/* /*
* An invisible view containing multiple mutually exclusive toggling * An invisible view containing multiple mutually exclusive toggling
* buttons (usually radio buttons). Automatically handles the mutex * buttons (usually radio buttons). Automatically handles the mutex
@@ -66,25 +46,32 @@ class LLRadioGroup
: public LLUICtrl, public LLCtrlSelectionInterface : public LLUICtrl, public LLCtrlSelectionInterface
{ {
public: public:
// Radio group constructor. Doesn't rely on
// needing a control // Radio group constructor. Doesn't rely on needing a control
LLRadioGroup(const std::string& name, const LLRect& rect, LLRadioGroup(const std::string& name, const LLRect& rect,
S32 initial_index, S32 initial_index,
commit_callback_t commit_callback, commit_callback_t commit_callback,
BOOL border = TRUE); bool border = true, bool allow_deselect = false);
protected:
friend class LLUICtrlFactory;
public:
virtual ~LLRadioGroup(); virtual ~LLRadioGroup();
virtual BOOL postBuild();
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleKeyHere(KEY key, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual void setEnabled(BOOL enabled); virtual void setEnabled(BOOL enabled);
virtual LLXMLNodePtr getXML(bool save_children = true) const; virtual LLXMLNodePtr getXML(bool save_children = true) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
void setIndexEnabled(S32 index, BOOL enabled); void setIndexEnabled(S32 index, BOOL enabled);
// return the index value of the selected item // return the index value of the selected item
S32 getSelectedIndex() const { return mSelectedIndex; } S32 getSelectedIndex() const { return mSelectedIndex; }
// set the index value programatically // set the index value programatically
BOOL setSelectedIndex(S32 index, BOOL from_event = FALSE); BOOL setSelectedIndex(S32 index, BOOL from_event = FALSE);
@@ -92,14 +79,10 @@ public:
virtual void setValue(const LLSD& value ); virtual void setValue(const LLSD& value );
virtual LLSD getValue() const; virtual LLSD getValue() const;
// Draw the group, but also fix the highlighting based on the control.
void draw();
// You must use this method to add buttons to a radio group. // You must use this method to add buttons to a radio group.
// Don't use addChild -- it won't set the callback function // Don't use addChild -- it won't set the callback function
// correctly. // correctly.
LLRadioCtrl* addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font); class LLRadioCtrl* addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font, const std::string& payload = "");
LLRadioCtrl* getRadioButton(const S32& index) { return mRadioButtons[index]; }
// Update the control as needed. Userdata must be a pointer to the button. // Update the control as needed. Userdata must be a pointer to the button.
void onClickButton(LLUICtrl* clicked_radio); void onClickButton(LLUICtrl* clicked_radio);
@@ -123,14 +106,15 @@ public:
private: private:
// protected function shared by the two constructors. // protected function shared by the two constructors.
void init(BOOL border); void init(bool border);
S32 mSelectedIndex; S32 mSelectedIndex;
typedef std::vector<LLRadioCtrl*> button_list_t;
typedef std::vector<class LLRadioCtrl*> button_list_t;
button_list_t mRadioButtons; button_list_t mRadioButtons;
BOOL mHasBorder; bool mHasBorder;
bool mAllowDeselect; // user can click on an already selected option to deselect it
}; };
#endif #endif

View File

@@ -62,13 +62,13 @@ LLDir_Win32::LLDir_Win32()
if((*pSHGetKnownFolderPath)(FOLDERID_RoamingAppData, 0, NULL, &pPath) == S_OK) if((*pSHGetKnownFolderPath)(FOLDERID_RoamingAppData, 0, NULL, &pPath) == S_OK)
wcscpy_s(w_str,pPath); wcscpy_s(w_str,pPath);
else else
SHGetSpecialFolderPath(NULL, w_str, CSIDL_APPDATA, TRUE); SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
if(pPath) if(pPath)
CoTaskMemFree(pPath); CoTaskMemFree(pPath);
} }
else //XP doesn't support SHGetKnownFolderPath else //XP doesn't support SHGetKnownFolderPath
{ {
SHGetSpecialFolderPath(NULL, w_str, CSIDL_APPDATA, TRUE); SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
} }
mOSUserDir = utf16str_to_utf8str(llutf16string(w_str)); mOSUserDir = utf16str_to_utf8str(llutf16string(w_str));
@@ -91,13 +91,13 @@ LLDir_Win32::LLDir_Win32()
if((*pSHGetKnownFolderPath)(FOLDERID_LocalAppData, 0, NULL, &pPath) == S_OK) if((*pSHGetKnownFolderPath)(FOLDERID_LocalAppData, 0, NULL, &pPath) == S_OK)
wcscpy_s(w_str,pPath); wcscpy_s(w_str,pPath);
else else
SHGetSpecialFolderPath(NULL, w_str, CSIDL_LOCAL_APPDATA, TRUE); SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
if(pPath) if(pPath)
CoTaskMemFree(pPath); CoTaskMemFree(pPath);
} }
else //XP doesn't support SHGetKnownFolderPath else //XP doesn't support SHGetKnownFolderPath
{ {
SHGetSpecialFolderPath(NULL, w_str, CSIDL_LOCAL_APPDATA, TRUE); SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
} }
if(shell) if(shell)

File diff suppressed because it is too large Load Diff

View File

@@ -2,31 +2,25 @@
* @file lldxhardware.cpp * @file lldxhardware.cpp
* @brief LLDXHardware implementation * @brief LLDXHardware implementation
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -40,9 +34,12 @@
#include <dxdiag.h> #include <dxdiag.h>
#undef INITGUID #undef INITGUID
#include <wbemidl.h>
#include <boost/tokenizer.hpp> #include <boost/tokenizer.hpp>
#include "lldxhardware.h" #include "lldxhardware.h"
#include "llerror.h" #include "llerror.h"
#include "llstring.h" #include "llstring.h"
@@ -59,11 +56,160 @@ LLDXHardware gDXHardware;
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName) typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc,
OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel,
RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities );
HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
{ {
HRESULT hr; HRESULT hr;
bool bGotMemory = false;
HRESULT hrCoInitialize = S_OK;
IWbemLocator* pIWbemLocator = nullptr;
IWbemServices* pIWbemServices = nullptr;
BSTR pNamespace = nullptr;
*pdwAdapterRam = 0;
hrCoInitialize = CoInitialize( 0 );
hr = CoCreateInstance( CLSID_WbemLocator,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
( LPVOID* )&pIWbemLocator );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) ) wprintf( L"WMI: CoCreateInstance failed: 0x%0.8x\n", hr );
#endif
if( SUCCEEDED( hr ) && pIWbemLocator )
{
// Using the locator, connect to WMI in the given namespace.
pNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );
hr = pIWbemLocator->ConnectServer( pNamespace, nullptr, nullptr, 0L,
0L, nullptr, nullptr, &pIWbemServices );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) ) wprintf( L"WMI: pIWbemLocator->ConnectServer failed: 0x%0.8x\n", hr );
#endif
if( SUCCEEDED( hr ) && pIWbemServices != 0 )
{
HINSTANCE hinstOle32 = nullptr;
hinstOle32 = LoadLibraryW( L"ole32.dll" );
if( hinstOle32 )
{
PfnCoSetProxyBlanket pfnCoSetProxyBlanket = nullptr;
pfnCoSetProxyBlanket = ( PfnCoSetProxyBlanket )GetProcAddress( hinstOle32, "CoSetProxyBlanket" );
if( pfnCoSetProxyBlanket != 0 )
{
// Switch security level to IMPERSONATE.
pfnCoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0 );
}
FreeLibrary( hinstOle32 );
}
IEnumWbemClassObject* pEnumVideoControllers = nullptr;
BSTR pClassName = nullptr;
pClassName = SysAllocString( L"Win32_VideoController" );
hr = pIWbemServices->CreateInstanceEnum( pClassName, 0,
nullptr, &pEnumVideoControllers );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) ) wprintf( L"WMI: pIWbemServices->CreateInstanceEnum failed: 0x%0.8x\n", hr );
#endif
if( SUCCEEDED( hr ) && pEnumVideoControllers )
{
IWbemClassObject* pVideoControllers[10] = {0};
DWORD uReturned = 0;
BSTR pPropName = nullptr;
// Get the first one in the list
pEnumVideoControllers->Reset();
hr = pEnumVideoControllers->Next( 5000, // timeout in 5 seconds
10, // return the first 10
pVideoControllers,
&uReturned );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) ) wprintf( L"WMI: pEnumVideoControllers->Next failed: 0x%0.8x\n", hr );
if( uReturned == 0 ) wprintf( L"WMI: pEnumVideoControllers uReturned == 0\n" );
#endif
VARIANT var;
if( SUCCEEDED( hr ) )
{
bool bFound = false;
for( UINT iController = 0; iController < uReturned; iController++ )
{
if ( !pVideoControllers[iController] )
continue;
pPropName = SysAllocString( L"PNPDeviceID" );
hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) )
wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr );
#endif
if( SUCCEEDED( hr ) )
{
if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 )
bFound = true;
}
VariantClear( &var );
if( pPropName ) SysFreeString( pPropName );
if( bFound )
{
pPropName = SysAllocString( L"AdapterRAM" );
hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) )
wprintf( L"WMI: pVideoControllers[iController]->Get AdapterRAM failed: 0x%0.8x\n",
hr );
#endif
if( SUCCEEDED( hr ) )
{
bGotMemory = true;
*pdwAdapterRam = var.ulVal;
}
VariantClear( &var );
if( pPropName ) SysFreeString( pPropName );
break;
}
SAFE_RELEASE( pVideoControllers[iController] );
}
}
}
if( pClassName )
SysFreeString( pClassName );
SAFE_RELEASE( pEnumVideoControllers );
}
if( pNamespace )
SysFreeString( pNamespace );
SAFE_RELEASE( pIWbemServices );
}
SAFE_RELEASE( pIWbemLocator );
if( SUCCEEDED( hrCoInitialize ) )
CoUninitialize();
if( bGotMemory )
return S_OK;
else
return E_FAIL;
}
void get_wstring(IDxDiagContainer* containerp, WCHAR* wszPropName, WCHAR* wszPropValue, int outputSize)
{
HRESULT hr;
VARIANT var; VARIANT var;
WCHAR wszPropValue[256];
VariantInit( &var ); VariantInit( &var );
hr = containerp->GetProp(wszPropName, &var ); hr = containerp->GetProp(wszPropName, &var );
@@ -82,13 +228,19 @@ std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName)
wcscpy( wszPropValue, (var.boolVal) ? L"true" : L"false" ); /* Flawfinder: ignore */ wcscpy( wszPropValue, (var.boolVal) ? L"true" : L"false" ); /* Flawfinder: ignore */
break; break;
case VT_BSTR: case VT_BSTR:
wcsncpy( wszPropValue, var.bstrVal, 255 ); /* Flawfinder: ignore */ wcsncpy( wszPropValue, var.bstrVal, outputSize-1 ); /* Flawfinder: ignore */
wszPropValue[255] = 0; wszPropValue[outputSize-1] = 0;
break; break;
} }
} }
// Clear the variant (this is needed to free BSTR memory) // Clear the variant (this is needed to free BSTR memory)
VariantClear( &var ); VariantClear( &var );
}
std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName)
{
WCHAR wszPropValue[256];
get_wstring(containerp, wszPropName, wszPropValue, 256);
return utf16str_to_utf8str(wszPropValue); return utf16str_to_utf8str(wszPropValue);
} }
@@ -126,7 +278,7 @@ BOOL LLVersion::set(const std::string &version_string)
} }
if (count < 4) if (count < 4)
{ {
//llwarns << "Potentially bogus version string!" << version_string << llendl; //LL_WARNS() << "Potentially bogus version string!" << version_string << LL_ENDL;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
mFields[i] = 0; mFields[i] = 0;
@@ -177,6 +329,7 @@ std::string LLDXDriverFile::dump()
LLDXDevice::~LLDXDevice() LLDXDevice::~LLDXDevice()
{ {
for_each(mDriverFiles.begin(), mDriverFiles.end(), DeletePairedPointer()); for_each(mDriverFiles.begin(), mDriverFiles.end(), DeletePairedPointer());
mDriverFiles.clear();
} }
std::string LLDXDevice::dump() std::string LLDXDevice::dump()
@@ -236,6 +389,7 @@ LLDXHardware::LLDXHardware()
void LLDXHardware::cleanup() void LLDXHardware::cleanup()
{ {
// for_each(mDevices.begin(), mDevices.end(), DeletePairedPointer()); // for_each(mDevices.begin(), mDevices.end(), DeletePairedPointer());
// mDevices.clear();
} }
/* /*
@@ -365,8 +519,18 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
goto LCleanup; goto LCleanup;
} }
// Get the English VRAM string DWORD vram = 0;
WCHAR deviceID[512];
get_wstring(device_containerp, L"szDeviceID", deviceID, 512);
if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram)))
{ {
mVRAM = vram/(1024*1024);
}
else
{ // Get the English VRAM string
std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish"); std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish");
// We don't need the device any more // We don't need the device any more

View File

@@ -30,7 +30,6 @@
#if LL_MESA_HEADLESS #if LL_MESA_HEADLESS
#include "llwindow.h" #include "llwindow.h"
#include "GL/glu.h"
#include "GL/osmesa.h" #include "GL/osmesa.h"
class LLWindowMesaHeadless : public LLWindow class LLWindowMesaHeadless : public LLWindow

View File

@@ -38,6 +38,7 @@
// Linden library includes // Linden library includes
#include "llerror.h" #include "llerror.h"
#include "llfasttimer.h"
#include "llgl.h" #include "llgl.h"
#include "llstring.h" #include "llstring.h"
#include "lldir.h" #include "lldir.h"
@@ -58,8 +59,6 @@
#include <dinput.h> #include <dinput.h>
#include <Dbt.h.> #include <Dbt.h.>
#include "llfasttimer.h"
// culled from winuser.h // culled from winuser.h
#ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */ #ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */
const S32 WM_MOUSEWHEEL = 0x020A; const S32 WM_MOUSEWHEEL = 0x020A;
@@ -87,6 +86,18 @@ void show_window_creation_error(const std::string& title)
LL_WARNS("Window") << title << LL_ENDL; LL_WARNS("Window") << title << LL_ENDL;
} }
HGLRC SafeCreateContext(HDC hdc)
{
__try
{
return wglCreateContext(hdc);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return NULL;
}
}
//static //static
BOOL LLWindowWin32::sIsClassRegistered = FALSE; BOOL LLWindowWin32::sIsClassRegistered = FALSE;
@@ -161,10 +172,9 @@ LLWinImm LLWinImm::sTheInstance;
LLWinImm::LLWinImm() : mHImmDll(NULL) LLWinImm::LLWinImm() : mHImmDll(NULL)
{ {
// Check system metrics // Check system metrics
if ( !GetSystemMetrics( SM_DBCSENABLED ) ) if ( !GetSystemMetrics( SM_IMMENABLED ) )
return; return;
mHImmDll = LoadLibraryA("Imm32"); mHImmDll = LoadLibraryA("Imm32");
if (mHImmDll != NULL) if (mHImmDll != NULL)
{ {
@@ -205,7 +215,7 @@ LLWinImm::LLWinImm() : mHImmDll(NULL)
// the case, since it is very unusual; these APIs are available from // the case, since it is very unusual; these APIs are available from
// the beginning, and all versions of IMM32.DLL should have them all. // the beginning, and all versions of IMM32.DLL should have them all.
// Unfortunately, this code may be executed before initialization of // Unfortunately, this code may be executed before initialization of
// the logging channel (llwarns), and we can't do it here... Yes, this // the logging channel (LL_WARNS()), and we can't do it here... Yes, this
// is one of disadvantages to use static constraction to DLL loading. // is one of disadvantages to use static constraction to DLL loading.
FreeLibrary(mHImmDll); FreeLibrary(mHImmDll);
mHImmDll = NULL; mHImmDll = NULL;
@@ -554,6 +564,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
if (closest_refresh == 0) if (closest_refresh == 0)
{ {
LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL; LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL;
//success = FALSE;
if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode))
{ {
@@ -660,7 +671,7 @@ LLWindowWin32::~LLWindowWin32()
delete [] mSupportedResolutions; delete [] mSupportedResolutions;
mSupportedResolutions = NULL; mSupportedResolutions = NULL;
delete mWindowClassName; delete [] mWindowClassName;
mWindowClassName = NULL; mWindowClassName = NULL;
} }
@@ -749,7 +760,7 @@ void LLWindowWin32::close()
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
// Don't process events in our mainWindowProc any longer. // Don't process events in our mainWindowProc any longer.
SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, NULL); SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, NULL); // <alchemy/>
// Make sure we don't leave a blank toolbar button. // Make sure we don't leave a blank toolbar button.
ShowWindow(mWindowHandle, SW_HIDE); ShowWindow(mWindowHandle, SW_HIDE);
@@ -1012,7 +1023,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co
dw_ex_style = WS_EX_APPWINDOW; dw_ex_style = WS_EX_APPWINDOW;
dw_style = WS_POPUP; dw_style = WS_POPUP;
// Move window borders out not to cover window contents // Move window borders out not to cover window contents.
// This converts client rect to window rect, i.e. expands it by the window border size.
AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style); AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style);
} }
// If it failed, we don't want to run fullscreen // If it failed, we don't want to run fullscreen
@@ -1059,7 +1071,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co
mhInstance, mhInstance,
NULL); NULL);
LL_INFOS("Window") << "window is created." << llendl ; LL_INFOS("Window") << "window is created." << LL_ENDL ;
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// Create GL drawing context // Create GL drawing context
@@ -1092,7 +1104,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co
return FALSE; return FALSE;
} }
LL_INFOS("Window") << "Device context retrieved." << llendl ; LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ;
if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd)))
{ {
@@ -1102,7 +1114,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co
return FALSE; return FALSE;
} }
LL_INFOS("Window") << "Pixel format chosen." << llendl ; LL_INFOS("Window") << "Pixel format chosen." << LL_ENDL ;
// Verify what pixel format we actually received. // Verify what pixel format we actually received.
if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR),
@@ -1115,35 +1127,35 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co
} }
// (EXP-1765) dump pixel data to see if there is a pattern that leads to unreproducible crash // (EXP-1765) dump pixel data to see if there is a pattern that leads to unreproducible crash
LL_INFOS("Window") << "--- begin pixel format dump ---" << llendl ; LL_INFOS("Window") << "--- begin pixel format dump ---" << LL_ENDL ;
LL_INFOS("Window") << "pixel_format is " << pixel_format << llendl ; LL_INFOS("Window") << "pixel_format is " << pixel_format << LL_ENDL ;
LL_INFOS("Window") << "pfd.nSize: " << pfd.nSize << llendl ; LL_INFOS("Window") << "pfd.nSize: " << pfd.nSize << LL_ENDL ;
LL_INFOS("Window") << "pfd.nVersion: " << pfd.nVersion << llendl ; LL_INFOS("Window") << "pfd.nVersion: " << pfd.nVersion << LL_ENDL ;
LL_INFOS("Window") << "pfd.dwFlags: 0x" << std::hex << pfd.dwFlags << std::dec << llendl ; LL_INFOS("Window") << "pfd.dwFlags: 0x" << std::hex << pfd.dwFlags << std::dec << LL_ENDL ;
LL_INFOS("Window") << "pfd.iPixelType: " << (int)pfd.iPixelType << llendl ; LL_INFOS("Window") << "pfd.iPixelType: " << (int)pfd.iPixelType << LL_ENDL ;
LL_INFOS("Window") << "pfd.cColorBits: " << (int)pfd.cColorBits << llendl ; LL_INFOS("Window") << "pfd.cColorBits: " << (int)pfd.cColorBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cRedBits: " << (int)pfd.cRedBits << llendl ; LL_INFOS("Window") << "pfd.cRedBits: " << (int)pfd.cRedBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cRedShift: " << (int)pfd.cRedShift << llendl ; LL_INFOS("Window") << "pfd.cRedShift: " << (int)pfd.cRedShift << LL_ENDL ;
LL_INFOS("Window") << "pfd.cGreenBits: " << (int)pfd.cGreenBits << llendl ; LL_INFOS("Window") << "pfd.cGreenBits: " << (int)pfd.cGreenBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cGreenShift: " << (int)pfd.cGreenShift << llendl ; LL_INFOS("Window") << "pfd.cGreenShift: " << (int)pfd.cGreenShift << LL_ENDL ;
LL_INFOS("Window") << "pfd.cBlueBits: " << (int)pfd.cBlueBits << llendl ; LL_INFOS("Window") << "pfd.cBlueBits: " << (int)pfd.cBlueBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cBlueShift: " << (int)pfd.cBlueShift << llendl ; LL_INFOS("Window") << "pfd.cBlueShift: " << (int)pfd.cBlueShift << LL_ENDL ;
LL_INFOS("Window") << "pfd.cAlphaBits: " << (int)pfd.cAlphaBits << llendl ; LL_INFOS("Window") << "pfd.cAlphaBits: " << (int)pfd.cAlphaBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cAlphaShift: " << (int)pfd.cAlphaShift << llendl ; LL_INFOS("Window") << "pfd.cAlphaShift: " << (int)pfd.cAlphaShift << LL_ENDL ;
LL_INFOS("Window") << "pfd.cAccumBits: " << (int)pfd.cAccumBits << llendl ; LL_INFOS("Window") << "pfd.cAccumBits: " << (int)pfd.cAccumBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cAccumRedBits: " << (int)pfd.cAccumRedBits << llendl ; LL_INFOS("Window") << "pfd.cAccumRedBits: " << (int)pfd.cAccumRedBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cAccumGreenBits: " << (int)pfd.cAccumGreenBits << llendl ; LL_INFOS("Window") << "pfd.cAccumGreenBits: " << (int)pfd.cAccumGreenBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cAccumBlueBits: " << (int)pfd.cAccumBlueBits << llendl ; LL_INFOS("Window") << "pfd.cAccumBlueBits: " << (int)pfd.cAccumBlueBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cAccumAlphaBits: " << (int)pfd.cAccumAlphaBits << llendl ; LL_INFOS("Window") << "pfd.cAccumAlphaBits: " << (int)pfd.cAccumAlphaBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cDepthBits: " << (int)pfd.cDepthBits << llendl ; LL_INFOS("Window") << "pfd.cDepthBits: " << (int)pfd.cDepthBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cStencilBits: " << (int)pfd.cStencilBits << llendl ; LL_INFOS("Window") << "pfd.cStencilBits: " << (int)pfd.cStencilBits << LL_ENDL ;
LL_INFOS("Window") << "pfd.cAuxBuffers: " << (int)pfd.cAuxBuffers << llendl ; LL_INFOS("Window") << "pfd.cAuxBuffers: " << (int)pfd.cAuxBuffers << LL_ENDL ;
LL_INFOS("Window") << "pfd.iLayerType: " << (int)pfd.iLayerType << llendl ; LL_INFOS("Window") << "pfd.iLayerType: " << (int)pfd.iLayerType << LL_ENDL ;
LL_INFOS("Window") << "pfd.bReserved: " << (int)pfd.bReserved << llendl ; LL_INFOS("Window") << "pfd.bReserved: " << (int)pfd.bReserved << LL_ENDL ;
LL_INFOS("Window") << "pfd.dwLayerMask: " << pfd.dwLayerMask << llendl ; LL_INFOS("Window") << "pfd.dwLayerMask: " << pfd.dwLayerMask << LL_ENDL ;
LL_INFOS("Window") << "pfd.dwVisibleMask: " << pfd.dwVisibleMask << llendl ; LL_INFOS("Window") << "pfd.dwVisibleMask: " << pfd.dwVisibleMask << LL_ENDL ;
LL_INFOS("Window") << "pfd.dwDamageMask: " << pfd.dwDamageMask << llendl ; LL_INFOS("Window") << "pfd.dwDamageMask: " << pfd.dwDamageMask << LL_ENDL ;
LL_INFOS("Window") << "--- end pixel format dump ---" << llendl ; LL_INFOS("Window") << "--- end pixel format dump ---" << LL_ENDL ;
if (pfd.cColorBits < 32) if (pfd.cColorBits < 32)
{ {
@@ -1169,7 +1181,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co
return FALSE; return FALSE;
} }
if (!(mhRC = wglCreateContext(mhDC))) if (!(mhRC = SafeCreateContext(mhDC)))
{ {
close(); close();
OSMessageBox(mCallbacks->translateString("MBGLContextErr"), OSMessageBox(mCallbacks->translateString("MBGLContextErr"),
@@ -1185,7 +1197,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co
return FALSE; return FALSE;
} }
LL_INFOS("Window") << "Drawing context is created." << llendl ; LL_INFOS("Window") << "Drawing context is created." << LL_ENDL ;
gGLManager.initWGL(); gGLManager.initWGL();
@@ -1323,142 +1335,15 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co
LL_INFOS("Window") << "Choosing pixel formats: " << num_formats << " pixel formats returned" << LL_ENDL; LL_INFOS("Window") << "Choosing pixel formats: " << num_formats << " pixel formats returned" << LL_ENDL;
} }
LL_INFOS("Window") << "pixel formats done." << llendl ; LL_INFOS("Window") << "pixel formats done." << LL_ENDL ;
/*for(int i = 0; i <= num_formats-1; ++i)
{
GLint query[] = { WGL_SAMPLE_BUFFERS_ARB,
WGL_SAMPLES_ARB,
WGL_NUMBER_PIXEL_FORMATS_ARB,
WGL_DRAW_TO_WINDOW_ARB,
WGL_DRAW_TO_BITMAP_ARB,
WGL_ACCELERATION_ARB,
WGL_NEED_PALETTE_ARB,
WGL_NEED_SYSTEM_PALETTE_ARB,
WGL_SWAP_LAYER_BUFFERS_ARB,
WGL_SWAP_METHOD_ARB,
WGL_NUMBER_OVERLAYS_ARB,
WGL_NUMBER_UNDERLAYS_ARB,
WGL_TRANSPARENT_ARB,
WGL_TRANSPARENT_RED_VALUE_ARB,
WGL_TRANSPARENT_GREEN_VALUE_ARB,
WGL_TRANSPARENT_BLUE_VALUE_ARB,
WGL_TRANSPARENT_ALPHA_VALUE_ARB,
WGL_TRANSPARENT_INDEX_VALUE_ARB,
WGL_SHARE_DEPTH_ARB,
WGL_SHARE_STENCIL_ARB,
WGL_SHARE_ACCUM_ARB,
WGL_SUPPORT_GDI_ARB,
WGL_SUPPORT_OPENGL_ARB,
WGL_DOUBLE_BUFFER_ARB,
WGL_STEREO_ARB,
WGL_PIXEL_TYPE_ARB,
WGL_COLOR_BITS_ARB,
WGL_RED_BITS_ARB,
WGL_RED_SHIFT_ARB,
WGL_GREEN_BITS_ARB,
WGL_GREEN_SHIFT_ARB,
WGL_BLUE_BITS_ARB,
WGL_BLUE_SHIFT_ARB,
WGL_ALPHA_BITS_ARB,
WGL_ALPHA_SHIFT_ARB,
WGL_ACCUM_BITS_ARB,
WGL_ACCUM_RED_BITS_ARB,
WGL_ACCUM_GREEN_BITS_ARB,
WGL_ACCUM_BLUE_BITS_ARB,
WGL_ACCUM_ALPHA_BITS_ARB,
WGL_DEPTH_BITS_ARB,
WGL_STENCIL_BITS_ARB,
WGL_AUX_BUFFERS_ARB};
std::string names[] = { "WGL_SAMPLE_BUFFERS_ARB",
"WGL_SAMPLES_ARB",
"WGL_NUMBER_PIXEL_FORMATS_ARB",
"WGL_DRAW_TO_WINDOW_ARB",
"WGL_DRAW_TO_BITMAP_ARB",
"WGL_ACCELERATION_ARB",
"WGL_NEED_PALETTE_ARB",
"WGL_NEED_SYSTEM_PALETTE_ARB",
"WGL_SWAP_LAYER_BUFFERS_ARB",
"WGL_SWAP_METHOD_ARB",
"WGL_NUMBER_OVERLAYS_ARB",
"WGL_NUMBER_UNDERLAYS_ARB",
"WGL_TRANSPARENT_ARB",
"WGL_TRANSPARENT_RED_VALUE_ARB",
"WGL_TRANSPARENT_GREEN_VALUE_ARB",
"WGL_TRANSPARENT_BLUE_VALUE_ARB",
"WGL_TRANSPARENT_ALPHA_VALUE_ARB",
"WGL_TRANSPARENT_INDEX_VALUE_ARB",
"WGL_SHARE_DEPTH_ARB",
"WGL_SHARE_STENCIL_ARB",
"WGL_SHARE_ACCUM_ARB",
"WGL_SUPPORT_GDI_ARB",
"WGL_SUPPORT_OPENGL_ARB",
"WGL_DOUBLE_BUFFER_ARB",
"WGL_STEREO_ARB",
"WGL_PIXEL_TYPE_ARB",
"WGL_COLOR_BITS_ARB",
"WGL_RED_BITS_ARB",
"WGL_RED_SHIFT_ARB",
"WGL_GREEN_BITS_ARB",
"WGL_GREEN_SHIFT_ARB",
"WGL_BLUE_BITS_ARB",
"WGL_BLUE_SHIFT_ARB",
"WGL_ALPHA_BITS_ARB",
"WGL_ALPHA_SHIFT_ARB",
"WGL_ACCUM_BITS_ARB",
"WGL_ACCUM_RED_BITS_ARB",
"WGL_ACCUM_GREEN_BITS_ARB",
"WGL_ACCUM_BLUE_BITS_ARB",
"WGL_ACCUM_ALPHA_BITS_ARB",
"WGL_DEPTH_BITS_ARB",
"WGL_STENCIL_BITS_ARB",
"WGL_AUX_BUFFERS_ARB"};
S32 results[sizeof(query)/sizeof(query[0])]={0};
if(wglGetPixelFormatAttribivARB(mhDC, pixel_formats[i], 0, sizeof(query)/sizeof(query[0]), query, results))
{
llinfos << i << ":" << llendl;
for(int j = 0; j < sizeof(query)/sizeof(query[0]); ++j)
{
switch(results[j])
{
case WGL_NO_ACCELERATION_ARB:
llinfos << " " << names[j] << " = " << "WGL_NO_ACCELERATION_ARB" << llendl;
break;
case WGL_GENERIC_ACCELERATION_ARB:
llinfos << " " << names[j] << " = " << "WGL_GENERIC_ACCELERATION_ARB" << llendl;
break;
case WGL_FULL_ACCELERATION_ARB:
llinfos << " " << names[j] << " = " << "WGL_FULL_ACCELERATION_ARB" << llendl;
break;
case WGL_SWAP_EXCHANGE_ARB:
llinfos << " " << names[j] << " = " << "WGL_SWAP_EXCHANGE_ARB" << llendl;
break;
case WGL_SWAP_COPY_ARB:
llinfos << " " << names[j] << " = " << "WGL_SWAP_COPY_ARB" << llendl;
break;
case WGL_SWAP_UNDEFINED_ARB:
llinfos << " " << names[j] << " = " << "WGL_SWAP_UNDEFINED_ARB" << llendl;
break;
case WGL_TYPE_RGBA_ARB:
llinfos << " " << names[j] << " = " << "WGL_TYPE_RGBA_ARB" << llendl;
break;
case WGL_TYPE_COLORINDEX_ARB:
llinfos << " " << names[j] << " = " << "WGL_TYPE_COLORINDEX_ARB" << llendl;
break;
default:
llinfos << " " << names[j] << " = " << results[j] << llendl;
}
}
}
}*/
//Singu note: Reversed order of this loop. Generally, choosepixelformat returns an array with the closer matches towards the start. //Singu note: Reversed order of this loop. Generally, choosepixelformat returns an array with the closer matches towards the start.
S32 swap_method = 0; S32 swap_method = 0;
S32 cur_format = 0;//num_formats-1; S32 cur_format = 0;//num_formats-1;
GLint swap_query = WGL_SWAP_METHOD_ARB; GLint swap_query = WGL_SWAP_METHOD_ARB;
BOOL found_format = FALSE; BOOL found_format = FALSE;
while (!found_format && wglGetPixelFormatAttribivARB(mhDC, pixel_formats[cur_format], 0, 1, &swap_query, &swap_method)) while (!found_format && wglGetPixelFormatAttribivARB(mhDC, pixel_formats[cur_format], 0, 1, &swap_query, &swap_method))
{ {
if (swap_method == WGL_SWAP_UNDEFINED_ARB /*|| cur_format <= 0*/) if (swap_method == WGL_SWAP_UNDEFINED_ARB /*|| cur_format <= 0*/)
@@ -1507,7 +1392,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, co
mhInstance, mhInstance,
NULL); NULL);
LL_INFOS("Window") << "recreate window done." << llendl ; LL_INFOS("Window") << "recreate window done." << LL_ENDL ;
if (!(mhDC = GetDC(mWindowHandle))) if (!(mhDC = GetDC(mWindowHandle)))
{ {
@@ -1747,6 +1632,7 @@ BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position)
return FALSE; return FALSE;
} }
// Inform the application of the new mouse position (needed for per-frame // Inform the application of the new mouse position (needed for per-frame
// hover/picking to function). // hover/picking to function).
mCallbacks->handleMouseMove(this, position.convert(), (MASK)0); mCallbacks->handleMouseMove(this, position.convert(), (MASK)0);
@@ -1996,7 +1882,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// This helps prevent avatar walking after maximizing the window by double-clicking the title bar. // This helps prevent avatar walking after maximizing the window by double-clicking the title bar.
static bool sHandleLeftMouseUp = true; static bool sHandleLeftMouseUp = true;
LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr(h_wnd, GWLP_USERDATA); // Ignore the double click received right after activating app.
// This is to avoid triggering double click teleport after returning focus (see MAINT-3786).
static bool sHandleDoubleClick = true;
LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr(h_wnd, GWLP_USERDATA); // <alchemy/>
if (NULL != window_imp) if (NULL != window_imp)
@@ -2123,6 +2013,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
} }
} }
if (!activating)
{
sHandleDoubleClick = false;
}
window_imp->mCallbacks->handleActivateApp(window_imp, activating); window_imp->mCallbacks->handleActivateApp(window_imp, activating);
break; break;
@@ -2347,6 +2242,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_NCLBUTTONDOWN"); window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_NCLBUTTONDOWN");
// A click in a non-client area, e.g. title bar or window border. // A click in a non-client area, e.g. title bar or window border.
sHandleLeftMouseUp = false; sHandleLeftMouseUp = false;
sHandleDoubleClick = true;
} }
break; break;
@@ -2391,6 +2287,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
//case WM_RBUTTONDBLCLK: //case WM_RBUTTONDBLCLK:
{ {
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDBLCLK"); window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDBLCLK");
if (!sHandleDoubleClick)
{
sHandleDoubleClick = true;
//break; // <singu/> Broke first double click every session.
}
// Because we move the cursor position in the app, we need to query // Because we move the cursor position in the app, we need to query
// to find out where the cursor at the time the event is handled. // to find out where the cursor at the time the event is handled.
// If we don't do this, many clicks could get buffered up, and if the // If we don't do this, many clicks could get buffered up, and if the
@@ -3379,7 +3282,6 @@ void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url, bool async)
{ {
sei.fMask = SEE_MASK_ASYNCOK; sei.fMask = SEE_MASK_ASYNCOK;
} }
else else
{ {
sei.fMask = SEE_MASK_FLAG_DDEWAIT; sei.fMask = SEE_MASK_FLAG_DDEWAIT;

View File

@@ -594,7 +594,8 @@ void parse_string();
"REGION_FLAG_SANDBOX" { count(); yylval.ival = REGION_FLAGS_SANDBOX; return(INTEGER_CONSTANT); } "REGION_FLAG_SANDBOX" { count(); yylval.ival = REGION_FLAGS_SANDBOX; return(INTEGER_CONSTANT); }
"REGION_FLAG_DISABLE_COLLISIONS" { count(); yylval.ival = REGION_FLAGS_SKIP_COLLISIONS; return(INTEGER_CONSTANT); } "REGION_FLAG_DISABLE_COLLISIONS" { count(); yylval.ival = REGION_FLAGS_SKIP_COLLISIONS; return(INTEGER_CONSTANT); }
"REGION_FLAG_DISABLE_PHYSICS" { count(); yylval.ival = REGION_FLAGS_SKIP_PHYSICS; return(INTEGER_CONSTANT); } "REGION_FLAG_DISABLE_PHYSICS" { count(); yylval.ival = REGION_FLAGS_SKIP_PHYSICS; return(INTEGER_CONSTANT); }
"REGION_FLAG_BLOCK_FLY" { count(); yylval.ival = REGION_FLAGS_BLOCK_FLY; return(INTEGER_CONSTANT); } "REGION_FLAG_BLOCK_FLY" { count(); yylval.ival = REGION_FLAGS_BLOCK_FLY; return(INTEGER_CONSTANT); }
"REGION_FLAG_BLOCK_FLYOVER" { count(); yylval.ival = REGION_FLAGS_BLOCK_FLYOVER; return(INTEGER_CONSTANT); }
"REGION_FLAG_ALLOW_DIRECT_TELEPORT" { count(); yylval.ival = REGION_FLAGS_ALLOW_DIRECT_TELEPORT; return(INTEGER_CONSTANT); } "REGION_FLAG_ALLOW_DIRECT_TELEPORT" { count(); yylval.ival = REGION_FLAGS_ALLOW_DIRECT_TELEPORT; return(INTEGER_CONSTANT); }
"REGION_FLAG_RESTRICT_PUSHOBJECT" { count(); yylval.ival = REGION_FLAGS_RESTRICT_PUSHOBJECT; return(INTEGER_CONSTANT); } "REGION_FLAG_RESTRICT_PUSHOBJECT" { count(); yylval.ival = REGION_FLAGS_RESTRICT_PUSHOBJECT; return(INTEGER_CONSTANT); }

Some files were not shown because too many files have changed in this diff Show More