Automated merge from mesh-development

meow-7.2.2
Loren Shih 2011-01-04 11:00:14 -05:00
commit 5fe826945c
14 changed files with 1551 additions and 1169 deletions

View File

@ -42,7 +42,6 @@ LLCamera::LLCamera() :
mPlaneCount(6),
mFrustumCornerDist(0.f)
{
alignPlanes();
calculateFrustumPlanes();
}
@ -53,7 +52,6 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p
mPlaneCount(6),
mFrustumCornerDist(0.f)
{
alignPlanes();
mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE;
@ -67,19 +65,6 @@ LLCamera::~LLCamera()
}
const LLCamera& LLCamera::operator=(const LLCamera& rhs)
{
memcpy(this, &rhs, sizeof(LLCamera));
alignPlanes();
LLVector4a::memcpyNonAliased16((F32*) mAgentPlanes, (F32*) rhs.mAgentPlanes, 4*7*sizeof(F32));
return *this;
}
void LLCamera::alignPlanes()
{
mAgentPlanes = (LLPlane*) LL_NEXT_ALIGNED_ADDRESS<U8>(mAgentPlaneBuffer);
}
// ---------------- LLCamera::getFoo() member functions ----------------
F32 LLCamera::getMinView() const
@ -100,11 +85,11 @@ F32 LLCamera::getMaxView() const
// ---------------- LLCamera::setFoo() member functions ----------------
void LLCamera::setUserClipPlane(LLPlane plane)
void LLCamera::setUserClipPlane(LLPlane& plane)
{
mPlaneCount = 7;
mAgentPlanes[6] = plane;
mPlaneMask[6] = calcPlaneMask(plane);
mPlaneMask[6] = plane.calcPlaneMask();
}
void LLCamera::disableUserClipPlane()
@ -190,38 +175,33 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
};
U8 mask = 0;
S32 result = 2;
bool result = false;
LLVector4a rscale, maxp, minp;
LLSimdScalar d;
for (U32 i = 0; i < mPlaneCount; i++)
{
mask = mPlaneMask[i];
if (mask == 0xff)
if (mask != 0xff)
{
continue;
}
const LLPlane& p = mAgentPlanes[i];
const LLVector4a& n = reinterpret_cast<const LLVector4a&>(p);
float d = p.mV[3];
LLVector4a rscale;
rscale.setMul(radius, scaler[mask]);
LLVector4a minp, maxp;
minp.setSub(center, rscale);
maxp.setAdd(center, rscale);
if (n.dot3(minp) > -d)
{
return 0;
}
if (n.dot3(maxp) > -d)
{
result = 1;
const LLPlane& p(mAgentPlanes[i]);
p.getAt<3>(d);
rscale.setMul(radius, scaler[mask]);
minp.setSub(center, rscale);
d = -d;
if (p.dot3(minp).getF32() > d)
{
return 0;
}
if(!result)
{
maxp.setAdd(center, rscale);
result = (p.dot3(maxp).getF32() > d);
}
}
}
return result;
return result?1:2;
}
@ -239,43 +219,33 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
};
U8 mask = 0;
S32 result = 2;
bool result = false;
LLVector4a rscale, maxp, minp;
LLSimdScalar d;
for (U32 i = 0; i < mPlaneCount; i++)
{
if (i == 5)
{
continue;
}
mask = mPlaneMask[i];
if (mask == 0xff)
if ((i != 5) && (mask != 0xff))
{
continue;
}
const LLPlane& p = mAgentPlanes[i];
const LLVector4a& n = reinterpret_cast<const LLVector4a&>(p);
float d = p.mV[3];
LLVector4a rscale;
rscale.setMul(radius, scaler[mask]);
LLVector4a minp, maxp;
minp.setSub(center, rscale);
maxp.setAdd(center, rscale);
if (n.dot3(minp) > -d)
{
return 0;
}
if (n.dot3(maxp) > -d)
{
result = 1;
const LLPlane& p(mAgentPlanes[i]);
p.getAt<3>(d);
rscale.setMul(radius, scaler[mask]);
minp.setSub(center, rscale);
d = -d;
if (p.dot3(minp).getF32() > d)
{
return 0;
}
if(!result)
{
maxp.setAdd(center, rscale);
result = (p.dot3(maxp).getF32() > d);
}
}
}
return result;
return result?1:2;
}
int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius)
@ -396,28 +366,22 @@ int LLCamera::sphereInFrustumOld(const LLVector3 &sphere_center, const F32 radiu
int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) const
{
// Returns 1 if sphere is in frustum, 0 if not.
int res = 2;
bool res = false;
for (int i = 0; i < 6; i++)
{
if (mPlaneMask[i] == 0xff)
if (mPlaneMask[i] != 0xff)
{
continue;
}
float d = mAgentPlanes[i].dist(sphere_center);
float d = mAgentPlanes[i].dist(sphere_center);
if (d > radius)
{
return 0;
}
if (d > -radius)
{
res = 1;
if (d > radius)
{
return 0;
}
res = res || (d > -radius);
}
}
return res;
return res?1:2;
}
@ -569,25 +533,6 @@ LLPlane planeFromPoints(LLVector3 p1, LLVector3 p2, LLVector3 p3)
return LLPlane(p1, n);
}
U8 LLCamera::calcPlaneMask(const LLPlane& plane)
{
U8 mask = 0;
if (plane.mV[0] >= 0)
{
mask |= 1;
}
if (plane.mV[1] >= 0)
{
mask |= 2;
}
if (plane.mV[2] >= 0)
{
mask |= 4;
}
return mask;
}
void LLCamera::ignoreAgentFrustumPlane(S32 idx)
{
@ -597,13 +542,12 @@ void LLCamera::ignoreAgentFrustumPlane(S32 idx)
}
mPlaneMask[idx] = 0xff;
mAgentPlanes[idx].clearVec();
mAgentPlanes[idx].clear();
}
void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
{
alignPlanes();
for (int i = 0; i < 8; i++)
{
mAgentFrustum[i] = frust[i];
@ -636,7 +580,7 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
//cache plane octant facing mask for use in AABBInFrustum
for (U32 i = 0; i < mPlaneCount; i++)
{
mPlaneMask[i] = calcPlaneMask(mAgentPlanes[i]);
mPlaneMask[i] = mAgentPlanes[i].calcPlaneMask();
}
}
@ -689,9 +633,10 @@ void LLCamera::calculateWorldFrustumPlanes()
F32 d;
LLVector3 center = mOrigin - mXAxis*mNearPlane;
mWorldPlanePos = center;
LLVector3 pnorm;
for (int p=0; p<4; p++)
{
LLVector3 pnorm = LLVector3(mLocalPlanes[p]);
mLocalPlanes[p].getVector3(pnorm);
LLVector3 norm = rotateToAbsolute(pnorm);
norm.normVec();
d = -(center * norm);
@ -701,13 +646,15 @@ void LLCamera::calculateWorldFrustumPlanes()
LLVector3 zaxis(0, 0, 1.0f);
F32 yaw = getYaw();
{
LLVector3 tnorm = LLVector3(mLocalPlanes[PLANE_LEFT]);
LLVector3 tnorm;
mLocalPlanes[PLANE_LEFT].getVector3(tnorm);
tnorm.rotVec(yaw, zaxis);
d = -(mOrigin * tnorm);
mHorizPlanes[HORIZ_PLANE_LEFT] = LLPlane(tnorm, d);
}
{
LLVector3 tnorm = LLVector3(mLocalPlanes[PLANE_RIGHT]);
LLVector3 tnorm;
mLocalPlanes[PLANE_RIGHT].getVector3(tnorm);
tnorm.rotVec(yaw, zaxis);
d = -(mOrigin * tnorm);
mHorizPlanes[HORIZ_PLANE_RIGHT] = LLPlane(tnorm, d);

View File

@ -79,8 +79,6 @@ public:
{
*this = rhs;
}
const LLCamera& operator=(const LLCamera& rhs);
enum {
PLANE_LEFT = 0,
@ -119,6 +117,9 @@ public:
};
private:
LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
U8 mPlaneMask[8]; // 8 for alignment
F32 mView; // angle between top and bottom frustum planes in radians.
F32 mAspect; // width/height
S32 mViewHeightInPixels; // for ViewHeightInPixels() only
@ -132,10 +133,6 @@ private:
LLPlane mWorldPlanes[PLANE_NUM];
LLPlane mHorizPlanes[HORIZ_PLANE_NUM];
LLPlane* mAgentPlanes; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
U8 mAgentPlaneBuffer[sizeof(LLPlane)*8];
U8 mPlaneMask[7];
U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
LLVector3 mWorldPlanePos; // Position of World Planes (may be offset from camera)
@ -149,11 +146,9 @@ public:
LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
virtual ~LLCamera();
void alignPlanes();
void setUserClipPlane(LLPlane plane);
void setUserClipPlane(LLPlane& plane);
void disableUserClipPlane();
U8 calcPlaneMask(const LLPlane& plane);
virtual void setView(F32 vertical_fov_rads);
void setViewHeightInPixels(S32 height);
void setAspect(F32 new_aspect);

View File

@ -36,19 +36,23 @@
// The plane normal = [A, B, C]
// The closest approach = D / sqrt(A*A + B*B + C*C)
class LLPlane : public LLVector4
class LLPlane
{
public:
// Constructors
LLPlane() {}; // no default constructor
LLPlane(const LLVector3 &p0, F32 d) { setVec(p0, d); }
LLPlane(const LLVector3 &p0, const LLVector3 &n) { setVec(p0, n); }
void setVec(const LLVector3 &p0, F32 d) { LLVector4::setVec(p0[0], p0[1], p0[2], d); }
void setVec(const LLVector3 &p0, const LLVector3 &n)
inline void setVec(const LLVector3 &p0, F32 d) { mV.set(p0[0], p0[1], p0[2], d); }
// Set
inline void setVec(const LLVector3 &p0, const LLVector3 &n)
{
F32 d = -(p0 * n);
setVec(n, d);
}
void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2)
inline void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2)
{
LLVector3 u, v, w;
u = p1 - p0;
@ -58,8 +62,38 @@ public:
F32 d = -(w * p0);
setVec(w, d);
}
LLPlane& operator=(const LLVector4& v2) { LLVector4::setVec(v2[0],v2[1],v2[2],v2[3]); return *this;}
inline LLPlane& operator=(const LLVector4& v2) { mV.set(v2[0],v2[1],v2[2],v2[3]); return *this;}
inline LLPlane& operator=(const LLVector4a& v2) { mV.set(v2[0],v2[1],v2[2],v2[3]); return *this;}
inline void set(const LLPlane& p2) { mV = p2.mV; }
//
F32 dist(const LLVector3 &v2) const { return mV[0]*v2[0] + mV[1]*v2[1] + mV[2]*v2[2] + mV[3]; }
inline LLSimdScalar dot3(const LLVector4a& b) const { return mV.dot3(b); }
// Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates
// the data at the whole vector level or you will incur a substantial penalty. Consider using the splat functions instead
inline F32 operator[](const S32 idx) const { return mV[idx]; }
// preferable when index is known at compile time
template <int N> LL_FORCE_INLINE void getAt(LLSimdScalar& v) const { v = mV.getScalarAt<N>(); }
// reset the vector to 0, 0, 0, 1
inline void clear() { mV.set(0, 0, 0, 1); }
inline void getVector3(LLVector3& vec) const { vec.set(mV[0], mV[1], mV[2]); }
// Retrieve the mask indicating which of the x, y, or z axis are greater or equal to zero.
inline U8 calcPlaneMask()
{
return mV.greaterEqual(LLVector4a::getZero()).getGatheredBits() & LLVector4Logical::MASK_XYZ;
}
private:
LLVector4a mV;
};

View File

@ -67,7 +67,7 @@ public:
extern const LLVector4a LL_V4A_ZERO;
return LL_V4A_ZERO;
}
// Return a vector of all epsilon, where epsilon is a small float suitable for approximate equality checks
static inline const LLVector4a& getEpsilon()
{

View File

@ -1878,21 +1878,57 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
}
else
{ //no exact match found, get closest point
iter = mSkinWeights.begin();
weight_map::iterator best = iter;
const F32 epsilon = 2.f/65536;
weight_map::iterator iter_up = mSkinWeights.lower_bound(pos);
weight_map::iterator iter_down = ++iter_up;
weight_map::iterator best = iter_up;
F32 min_dist = (iter->first - pos).magVecSquared();
while (++iter != mSkinWeights.end())
{
F32 dist = (iter->first - pos).magVecSquared();
if (dist < min_dist)
bool done = false;
while (!done)
{ //search up and down mSkinWeights from lower bound of pos until a
//match is found within epsilon. If no match is found within epsilon,
//return closest match
done = true;
if (iter_up != mSkinWeights.end() && ++iter_up != mSkinWeights.end())
{
best = iter;
min_dist = dist;
done = false;
F32 dist = (iter_up->first - pos).magVecSquared();
if (dist < epsilon)
{
return iter_up->second;
}
if (dist < min_dist)
{
best = iter_up;
min_dist = dist;
}
}
if (iter_down != mSkinWeights.begin() && --iter_down != mSkinWeights.begin())
{
done = false;
F32 dist = (iter_down->first - pos).magVecSquared();
if (dist < epsilon)
{
return iter_down->second;
}
if (dist < min_dist)
{
best = iter_down;
min_dist = dist;
}
}
}
return best->second;
}
}

View File

@ -1831,7 +1831,7 @@ LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& mode
mModelview = modelview;
mProjection = projection;
setPlane(p.mV[0], p.mV[1], p.mV[2], p.mV[3]);
setPlane(p[0], p[1], p[2], p[3]);
}
void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)

View File

@ -276,7 +276,10 @@ BOOL LLFloaterModelPreview::postBuild()
return FALSE;
}
setViewOption("show_textures", true);
childSetAction("lod_browse", onBrowseLOD, this);
@ -393,13 +396,22 @@ LLFloaterModelPreview::~LLFloaterModelPreview()
void LLFloaterModelPreview::onViewOptionChecked(const LLSD& userdata)
{
mViewOption[userdata.asString()] = !mViewOption[userdata.asString()];
mModelPreview->refresh();
if (mModelPreview)
{
mModelPreview->mViewOption[userdata.asString()] = !mModelPreview->mViewOption[userdata.asString()];
mModelPreview->refresh();
}
}
bool LLFloaterModelPreview::isViewOptionChecked(const LLSD& userdata)
{
return mViewOption[userdata.asString()];
if (mModelPreview)
{
return mModelPreview->mViewOption[userdata.asString()];
}
return false;
}
bool LLFloaterModelPreview::isViewOptionEnabled(const LLSD& userdata)
@ -422,11 +434,6 @@ void LLFloaterModelPreview::disableViewOption(const std::string& option)
setViewOptionEnabled(option, false);
}
void LLFloaterModelPreview::setViewOption(const std::string& option, bool value)
{
mViewOption[option] = value;
}
void LLFloaterModelPreview::loadModel(S32 lod)
{
mModelPreview->mLoading = true;
@ -1562,11 +1569,23 @@ void LLModelLoader::run()
//add instance to scene for this model
LLMatrix4 transform;
LLMatrix4 transformation = mTransform;
// adjust the transformation to compensate for mesh normalization
LLMatrix4 mesh_translation;
mesh_translation.setTranslation(mesh_translation_vector);
mesh_translation *= transformation;
transformation = mesh_translation;
LLMatrix4 mesh_scale;
mesh_scale.initScale(mesh_scale_vector);
mesh_scale *= transformation;
transformation = mesh_scale;
std::vector<LLImportMaterial> materials;
materials.resize(model->getNumVolumeFaces());
mScene[transform].push_back(LLModelInstance(model, transform, materials));
stretch_extents(model, transform, mExtents[0], mExtents[1], mFirstTransform);
mScene[transformation].push_back(LLModelInstance(model, transformation, materials));
stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
}
}
}
@ -2019,6 +2038,8 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
mBuildBorderMode = GLOD_BORDER_UNLOCK;
mBuildOperator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE;
mViewOption["show_textures"] = false;
mFMP = fmp;
glodInit();
@ -2055,6 +2076,7 @@ U32 LLModelPreview::calcResourceCost()
F32 debug_scale = mFMP->childGetValue("import_scale").asReal();
F32 streaming_cost = 0.f;
F32 physics_cost = 0.f;
for (U32 i = 0; i < mUploadData.size(); ++i)
{
LLModelInstance& instance = mUploadData[i];
@ -2109,6 +2131,7 @@ U32 LLModelPreview::calcResourceCost()
//mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[HULLS]", llformat("%d",num_hulls));
//mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[POINTS]", llformat("%d",num_points));
mFMP->childSetTextArg("streaming cost", "[COST]", llformat("%.3f", streaming_cost));
mFMP->childSetTextArg("physics cost", "[COST]", llformat("%.3f", physics_cost));
F32 scale = mFMP->childGetValue("import_scale").asReal()*2.f;
mFMP->childSetTextArg("import_dimensions", "[X]", llformat("%.3f", mPreviewScale[0]*scale));
mFMP->childSetTextArg("import_dimensions", "[Y]", llformat("%.3f", mPreviewScale[1]*scale));
@ -3265,13 +3288,14 @@ void LLModelPreview::updateStatusMessages()
if (!fmp->isViewOptionEnabled("show_physics"))
{
fmp->enableViewOption("show_physics");
fmp->setViewOption("show_physics", true);
mViewOption["show_physics"] = true;
}
}
else
{
fmp->disableViewOption("show_physics");
fmp->setViewOption("show_physics", false);
mViewOption["show_physics"] = false;
}
//bool use_hull = fmp->childGetValue("physics_use_hull").asBoolean();
@ -3596,21 +3620,11 @@ BOOL LLModelPreview::render()
LLMutexLock lock(this);
mNeedsUpdate = FALSE;
bool edges = false;
bool joint_positions = false;
bool skin_weight = false;
bool textures = false;
bool physics = false;
LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
if (fmp)
{
edges = fmp->isViewOptionChecked("show_edges");
joint_positions = fmp->isViewOptionChecked("show_joint_positions");
skin_weight = fmp->isViewOptionChecked("show_skin_weight");
textures = fmp->isViewOptionChecked("show_textures");
physics = fmp->isViewOptionChecked("show_physics");
}
bool edges = mViewOption["show_edges"];
bool joint_positions = mViewOption["show_joint_positions"];
bool skin_weight = mViewOption["show_skin_weight"];
bool textures = mViewOption["show_textures"];
bool physics = mViewOption["show_physics"];
S32 width = getWidth();
S32 height = getHeight();
@ -3643,6 +3657,8 @@ BOOL LLModelPreview::render()
gGL.popMatrix();
}
LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
bool has_skin_weights = false;
bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean();
bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean();
@ -3674,7 +3690,7 @@ BOOL LLModelPreview::render()
mFMP->childDisable("upload_skin");
if (fmp)
{
fmp->setViewOption("show_skin_weight", false);
mViewOption["show_skin_weight"] = false;
fmp->disableViewOption("show_skin_weight");
fmp->disableViewOption("show_joint_positions");
}

View File

@ -1,337 +1,333 @@
/**
* @file llfloatermodelpreview.h
* @brief LLFloaterModelPreview class definition
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERMODELPREVIEW_H
#define LL_LLFLOATERMODELPREVIEW_H
#include "llfloaternamedesc.h"
#include "lldynamictexture.h"
#include "llquaternion.h"
#include "llmeshrepository.h"
#include "llmodel.h"
#include "llthread.h"
#include "llviewermenufile.h"
class LLComboBox;
class LLJoint;
class LLViewerJointMesh;
class LLVOAvatar;
class LLTextBox;
class LLVertexBuffer;
class LLModelPreview;
class LLFloaterModelPreview;
class daeElement;
class domProfile_COMMON;
class domInstance_geometry;
class domNode;
class domTranslate;
class LLMenuButton;
class LLToggleableMenu;
const S32 NUM_LOD = 4;
class LLModelLoader : public LLThread
{
public:
typedef enum
{
STARTING = 0,
READING_FILE,
CREATING_FACES,
GENERATING_VERTEX_BUFFERS,
GENERATING_LOD,
DONE,
ERROR_PARSING, //basically loading failed
} eLoadState;
U32 mState;
std::string mFilename;
S32 mLod;
LLModelPreview* mPreview;
LLMatrix4 mTransform;
BOOL mFirstTransform;
LLVector3 mExtents[2];
std::map<daeElement*, LLPointer<LLModel> > mModel;
typedef std::vector<LLPointer<LLModel> > model_list;
model_list mModelList;
typedef std::vector<LLModelInstance> model_instance_list;
typedef std::map<LLMatrix4, model_instance_list > scene;
scene mScene;
typedef std::queue<LLPointer<LLModel> > model_queue;
//queue of models that need a physics rep
model_queue mPhysicsQ;
LLModelLoader(std::string filename, S32 lod, LLModelPreview* preview);
virtual void run();
void processElement(daeElement* element);
std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo);
LLImportMaterial profileToMaterial(domProfile_COMMON* material);
std::string getElementLabel(daeElement *element);
LLColor4 getDaeColor(daeElement* element);
daeElement* getChildFromElement( daeElement* pElement, std::string const & name );
bool isNodeAJoint( domNode* pNode );
void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
void setLoadState( U32 state ) { mState = state; }
U32 getLoadState( void ) { return mState; }
//map of avatar joints as named in COLLADA assets to internal joint names
std::map<std::string, std::string> mJointMap;
};
class LLFloaterModelPreview : public LLFloater
{
public:
class DecompRequest : public LLPhysicsDecomp::Request
{
public:
S32 mContinue;
LLPointer<LLModel> mModel;
DecompRequest(const std::string& stage, LLModel* mdl);
virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
virtual void completed();
};
static LLFloaterModelPreview* sInstance;
LLFloaterModelPreview(const LLSD& key);
virtual ~LLFloaterModelPreview();
virtual BOOL postBuild();
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
BOOL handleMouseUp(S32 x, S32 y, MASK mask);
BOOL handleHover(S32 x, S32 y, MASK mask);
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
static void onMouseCaptureLostModelPreview(LLMouseHandler*);
static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
static void onBrowseLOD(void* data);
static void onUpload(void* data);
static void onClearMaterials(void* data);
static void onModelDecompositionComplete(LLModel* model, std::vector<LLPointer<LLVertexBuffer> >& physics_mesh);
static void refresh(LLUICtrl* ctrl, void* data);
void updateResourceCost();
void loadModel(S32 lod);
void onViewOptionChecked(const LLSD& userdata);
bool isViewOptionChecked(const LLSD& userdata);
bool isViewOptionEnabled(const LLSD& userdata);
void setViewOptionEnabled(const std::string& option, bool enabled);
void enableViewOption(const std::string& option);
void disableViewOption(const std::string& option);
void setViewOption(const std::string& option, bool value);
protected:
friend class LLModelPreview;
friend class LLMeshFilePicker;
friend class LLPhysicsDecomp;
static void onImportScaleCommit(LLUICtrl*, void*);
static void onUploadJointsCommit(LLUICtrl*,void*);
static void onUploadSkinCommit(LLUICtrl*,void*);
static void onPreviewLODCommit(LLUICtrl*,void*);
static void onGenerateNormalsCommit(LLUICtrl*,void*);
static void onAutoFillCommit(LLUICtrl*,void*);
static void onLODParamCommit(LLUICtrl*,void*);
static void onExplodeCommit(LLUICtrl*, void*);
static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata);
static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata);
static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata);
static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata);
static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata);
static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata);
static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata);
static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata);
void draw();
void initDecompControls();
void setStatusMessage(const std::string& msg);
LLModelPreview* mModelPreview;
LLPhysicsDecomp::decomp_params mDecompParams;
S32 mLastMouseX;
S32 mLastMouseY;
LLRect mPreviewRect;
U32 mGLName;
static S32 sUploadAmount;
std::set<LLPointer<DecompRequest> > mCurRequest;
std::string mStatusMessage;
/**
* @file llfloatermodelpreview.h
* @brief LLFloaterModelPreview class definition
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERMODELPREVIEW_H
#define LL_LLFLOATERMODELPREVIEW_H
#include "llfloaternamedesc.h"
#include "lldynamictexture.h"
#include "llquaternion.h"
#include "llmeshrepository.h"
#include "llmodel.h"
#include "llthread.h"
#include "llviewermenufile.h"
class LLComboBox;
class LLJoint;
class LLViewerJointMesh;
class LLVOAvatar;
class LLTextBox;
class LLVertexBuffer;
class LLModelPreview;
class LLFloaterModelPreview;
class daeElement;
class domProfile_COMMON;
class domInstance_geometry;
class domNode;
class domTranslate;
class LLMenuButton;
class LLToggleableMenu;
const S32 NUM_LOD = 4;
class LLModelLoader : public LLThread
{
public:
typedef enum
{
STARTING = 0,
READING_FILE,
CREATING_FACES,
GENERATING_VERTEX_BUFFERS,
GENERATING_LOD,
DONE,
ERROR_PARSING, //basically loading failed
} eLoadState;
U32 mState;
std::string mFilename;
S32 mLod;
LLModelPreview* mPreview;
LLMatrix4 mTransform;
BOOL mFirstTransform;
LLVector3 mExtents[2];
std::map<daeElement*, LLPointer<LLModel> > mModel;
typedef std::vector<LLPointer<LLModel> > model_list;
model_list mModelList;
typedef std::vector<LLModelInstance> model_instance_list;
typedef std::map<LLMatrix4, model_instance_list > scene;
scene mScene;
typedef std::queue<LLPointer<LLModel> > model_queue;
//queue of models that need a physics rep
model_queue mPhysicsQ;
LLModelLoader(std::string filename, S32 lod, LLModelPreview* preview);
virtual void run();
void processElement(daeElement* element);
std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo);
LLImportMaterial profileToMaterial(domProfile_COMMON* material);
std::string getElementLabel(daeElement *element);
LLColor4 getDaeColor(daeElement* element);
daeElement* getChildFromElement( daeElement* pElement, std::string const & name );
bool isNodeAJoint( domNode* pNode );
void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
void setLoadState( U32 state ) { mState = state; }
U32 getLoadState( void ) { return mState; }
//map of avatar joints as named in COLLADA assets to internal joint names
std::map<std::string, std::string> mJointMap;
};
class LLFloaterModelPreview : public LLFloater
{
public:
class DecompRequest : public LLPhysicsDecomp::Request
{
public:
S32 mContinue;
LLPointer<LLModel> mModel;
DecompRequest(const std::string& stage, LLModel* mdl);
virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
virtual void completed();
};
static LLFloaterModelPreview* sInstance;
LLFloaterModelPreview(const LLSD& key);
virtual ~LLFloaterModelPreview();
virtual BOOL postBuild();
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
BOOL handleMouseUp(S32 x, S32 y, MASK mask);
BOOL handleHover(S32 x, S32 y, MASK mask);
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
static void onMouseCaptureLostModelPreview(LLMouseHandler*);
static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
static void onBrowseLOD(void* data);
static void onUpload(void* data);
static void onClearMaterials(void* data);
static void refresh(LLUICtrl* ctrl, void* data);
void updateResourceCost();
void loadModel(S32 lod);
void onViewOptionChecked(const LLSD& userdata);
bool isViewOptionChecked(const LLSD& userdata);
bool isViewOptionEnabled(const LLSD& userdata);
void setViewOptionEnabled(const std::string& option, bool enabled);
void enableViewOption(const std::string& option);
void disableViewOption(const std::string& option);
protected:
friend class LLModelPreview;
friend class LLMeshFilePicker;
friend class LLPhysicsDecomp;
static void onImportScaleCommit(LLUICtrl*, void*);
static void onUploadJointsCommit(LLUICtrl*,void*);
static void onUploadSkinCommit(LLUICtrl*,void*);
static void onPreviewLODCommit(LLUICtrl*,void*);
static void onGenerateNormalsCommit(LLUICtrl*,void*);
static void onAutoFillCommit(LLUICtrl*,void*);
static void onLODParamCommit(LLUICtrl*,void*);
static void onExplodeCommit(LLUICtrl*, void*);
static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata);
static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata);
static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata);
static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata);
static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata);
static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata);
static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata);
static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata);
void draw();
void initDecompControls();
void setStatusMessage(const std::string& msg);
LLModelPreview* mModelPreview;
LLPhysicsDecomp::decomp_params mDecompParams;
S32 mLastMouseX;
S32 mLastMouseY;
LLRect mPreviewRect;
U32 mGLName;
static S32 sUploadAmount;
std::set<LLPointer<DecompRequest> > mCurRequest;
std::string mStatusMessage;
//use "disabled" as false by default
std::map<std::string, bool> mViewOptionDisabled;
//store which lod mode each LOD is using
// 0 - load from file
// 1 - auto generate
// 2 - None
S32 mLODMode[4];
LLMenuButton* mViewOptionMenuButton;
LLToggleableMenu* mViewOptionMenu;
LLMutex* mStatusLock;
};
class LLMeshFilePicker : public LLFilePickerThread
{
public:
LLMeshFilePicker(LLModelPreview* mp, S32 lod);
virtual void notify(const std::string& filename);
private:
LLModelPreview* mMP;
S32 mLOD;
};
class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
{
public:
LLModelPreview(S32 width, S32 height, LLFloater* fmp);
virtual ~LLModelPreview();
void resetPreviewTarget();
void setPreviewTarget(F32 distance);
void setTexture(U32 name) { mTextureName = name; }
void setPhysicsFromLOD(S32 lod);
BOOL render();
void update();
void genBuffers(S32 lod, bool skinned);
void clearBuffers();
void refresh();
void rotate(F32 yaw_radians, F32 pitch_radians);
void zoom(F32 zoom_amt);
void pan(F32 right, F32 up);
virtual BOOL needsRender() { return mNeedsUpdate; }
void setPreviewLOD(S32 lod);
void clearModel(S32 lod);
void loadModel(std::string filename, S32 lod);
void loadModelCallback(S32 lod);
void genLODs(S32 which_lod = -1, U32 decimation = 3);
void generateNormals();
void consolidate();
void clearMaterials();
U32 calcResourceCost();
void rebuildUploadData();
void clearIncompatible(S32 lod);
void updateStatusMessages();
bool containsRiggedAsset( void );
void clearGLODGroup();
static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
protected:
friend class LLFloaterModelPreview;
friend class LLFloaterModelWizard;
friend class LLFloaterModelPreview::DecompRequest;
friend class LLPhysicsDecomp;
LLFloater* mFMP;
BOOL mNeedsUpdate;
bool mDirty;
bool mGenLOD;
U32 mTextureName;
F32 mCameraDistance;
F32 mCameraYaw;
F32 mCameraPitch;
F32 mCameraZoom;
LLVector3 mCameraOffset;
LLVector3 mPreviewTarget;
LLVector3 mPreviewScale;
S32 mPreviewLOD;
U32 mResourceCost;
std::string mLODFile[LLModel::NUM_LODS];
bool mLoading;
std::map<std::string, bool> mViewOption;
//use "disabled" as false by default
std::map<std::string, bool> mViewOptionDisabled;
//store which lod mode each LOD is using
// 0 - load from file
// 1 - auto generate
// 2 - None
S32 mLODMode[4];
LLMenuButton* mViewOptionMenuButton;
LLToggleableMenu* mViewOptionMenu;
LLMutex* mStatusLock;
};
class LLMeshFilePicker : public LLFilePickerThread
{
public:
LLMeshFilePicker(LLModelPreview* mp, S32 lod);
virtual void notify(const std::string& filename);
private:
LLModelPreview* mMP;
S32 mLOD;
};
class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
{
public:
LLModelPreview(S32 width, S32 height, LLFloater* fmp);
virtual ~LLModelPreview();
void resetPreviewTarget();
void setPreviewTarget(F32 distance);
void setTexture(U32 name) { mTextureName = name; }
void setPhysicsFromLOD(S32 lod);
BOOL render();
void update();
void genBuffers(S32 lod, bool skinned);
void clearBuffers();
void refresh();
void rotate(F32 yaw_radians, F32 pitch_radians);
void zoom(F32 zoom_amt);
void pan(F32 right, F32 up);
virtual BOOL needsRender() { return mNeedsUpdate; }
void setPreviewLOD(S32 lod);
void clearModel(S32 lod);
void loadModel(std::string filename, S32 lod);
void loadModelCallback(S32 lod);
void genLODs(S32 which_lod = -1, U32 decimation = 3);
void generateNormals();
void consolidate();
void clearMaterials();
U32 calcResourceCost();
void rebuildUploadData();
void clearIncompatible(S32 lod);
void updateStatusMessages();
bool containsRiggedAsset( void );
void clearGLODGroup();
static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
protected:
friend class LLFloaterModelPreview;
friend class LLFloaterModelWizard;
friend class LLFloaterModelPreview::DecompRequest;
friend class LLPhysicsDecomp;
LLFloater* mFMP;
BOOL mNeedsUpdate;
bool mDirty;
bool mGenLOD;
U32 mTextureName;
F32 mCameraDistance;
F32 mCameraYaw;
F32 mCameraPitch;
F32 mCameraZoom;
LLVector3 mCameraOffset;
LLVector3 mPreviewTarget;
LLVector3 mPreviewScale;
S32 mPreviewLOD;
U32 mResourceCost;
std::string mLODFile[LLModel::NUM_LODS];
bool mLoading;
//GLOD object parameters (must rebuild object if these change)
F32 mBuildShareTolerance;
U32 mBuildQueueMode;
U32 mBuildOperator;
U32 mBuildBorderMode;
LLModelLoader* mModelLoader;
LLModelLoader::scene mScene[LLModel::NUM_LODS];
LLModelLoader::scene mBaseScene;
LLModelLoader::model_list mModel[LLModel::NUM_LODS];
LLModelLoader::model_list mBaseModel;
U32 mGroup;
std::map<LLPointer<LLModel>, U32> mObject;
U32 mMaxTriangleLimit;
std::map<LLPointer<LLModel>, std::vector<LLPointer<LLVertexBuffer> > > mPhysicsMesh;
LLMeshUploadThread::instance_list mUploadData;
std::set<LLPointer<LLViewerFetchedTexture> > mTextureSet;
//map of vertex buffers to models (one vertex buffer in vector per face in model
std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1];
};
#endif // LL_LLFLOATERMODELPREVIEW_H
//GLOD object parameters (must rebuild object if these change)
F32 mBuildShareTolerance;
U32 mBuildQueueMode;
U32 mBuildOperator;
U32 mBuildBorderMode;
LLModelLoader* mModelLoader;
LLModelLoader::scene mScene[LLModel::NUM_LODS];
LLModelLoader::scene mBaseScene;
LLModelLoader::model_list mModel[LLModel::NUM_LODS];
LLModelLoader::model_list mBaseModel;
U32 mGroup;
std::map<LLPointer<LLModel>, U32> mObject;
U32 mMaxTriangleLimit;
std::map<LLPointer<LLModel>, std::vector<LLPointer<LLVertexBuffer> > > mPhysicsMesh;
LLMeshUploadThread::instance_list mUploadData;
std::set<LLPointer<LLViewerFetchedTexture> > mTextureSet;
//map of vertex buffers to models (one vertex buffer in vector per face in model
std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1];
};
#endif // LL_LLFLOATERMODELPREVIEW_H

View File

@ -35,10 +35,11 @@
#include "llfloatermodelwizard.h"
#include "llfloatermodelpreview.h"
#include "llfloaterreg.h"
#include "llslider.h"
#include "llsliderctrl.h"
#include "lltoolmgr.h"
#include "llviewerwindow.h"
LLFloaterModelWizard* LLFloaterModelWizard::sInstance = NULL;
static const std::string stateNames[]={
"choose_file",
@ -50,8 +51,12 @@ static const std::string stateNames[]={
LLFloaterModelWizard::LLFloaterModelWizard(const LLSD& key)
: LLFloater(key)
{
sInstance = this;
}
LLFloaterModelWizard::~LLFloaterModelWizard()
{
sInstance = NULL;
}
void LLFloaterModelWizard::setState(int state)
{
mState = state;
@ -69,6 +74,34 @@ void LLFloaterModelWizard::setState(int state)
if (state == OPTIMIZE)
{
mModelPreview->genLODs(-1);
mModelPreview->mViewOption["show_physics"] = false;
}
if (state == PHYSICS)
{
mModelPreview->setPhysicsFromLOD(1);
mModelPreview->mViewOption["show_physics"] = true;
getChild<LLView>("next")->setVisible(true);
getChild<LLView>("upload")->setVisible(false);
}
if (state == REVIEW)
{
executePhysicsStage("Decompose");
getChild<LLView>("close")->setVisible(false);
getChild<LLView>("next")->setVisible(false);
getChild<LLView>("back")->setVisible(true);
getChild<LLView>("upload")->setVisible(true);
getChild<LLView>("cancel")->setVisible(true);
}
if (state == UPLOAD)
{
getChild<LLView>("close")->setVisible(true);
getChild<LLView>("back")->setVisible(false);
getChild<LLView>("upload")->setVisible(false);
getChild<LLView>("cancel")->setVisible(false);
}
}
@ -227,6 +260,161 @@ BOOL LLFloaterModelWizard::handleScrollWheel(S32 x, S32 y, S32 clicks)
return TRUE;
}
void LLFloaterModelWizard::initDecompControls()
{
LLSD key;
static const LLCDStageData* stage = NULL;
static S32 stage_count = 0;
if (!stage && LLConvexDecomposition::getInstance() != NULL)
{
stage_count = LLConvexDecomposition::getInstance()->getStages(&stage);
}
static const LLCDParam* param = NULL;
static S32 param_count = 0;
if (!param && LLConvexDecomposition::getInstance() != NULL)
{
param_count = LLConvexDecomposition::getInstance()->getParameters(&param);
}
for (S32 j = stage_count-1; j >= 0; --j)
{
gMeshRepo.mDecompThread->mStageID[stage[j].mName] = j;
// protected against stub by stage_count being 0 for stub above
LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback);
for (S32 i = 0; i < param_count; ++i)
{
if (param[i].mStage != j)
{
continue;
}
std::string name(param[i].mName ? param[i].mName : "");
std::string description(param[i].mDescription ? param[i].mDescription : "");
if (param[i].mType == LLCDParam::LLCD_FLOAT)
{
mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat);
}
else if (param[i].mType == LLCDParam::LLCD_INTEGER)
{
mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
}
else if (param[i].mType == LLCDParam::LLCD_BOOLEAN)
{
mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool);
}
else if (param[i].mType == LLCDParam::LLCD_ENUM)
{
mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
}
}
}
mDecompParams["Simplify Method"] = 0; // set it to retain %
}
//static
void LLFloaterModelWizard::executePhysicsStage(std::string stage_name)
{
if (sInstance)
{
F64 physics_accuracy = sInstance->getChild<LLSliderCtrl>("physics_slider")->getValue().asReal();
sInstance->mDecompParams["Retain%"] = physics_accuracy;
if (!sInstance->mCurRequest.empty())
{
llinfos << "Decomposition request still pending." << llendl;
return;
}
if (sInstance->mModelPreview)
{
for (S32 i = 0; i < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size(); ++i)
{
LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i];
DecompRequest* request = new DecompRequest(stage_name, mdl);
sInstance->mCurRequest.insert(request);
gMeshRepo.mDecompThread->submitRequest(request);
}
}
}
}
LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl)
{
mStage = stage;
mContinue = 1;
mModel = mdl;
mDecompID = &mdl->mDecompID;
mParams = sInstance->mDecompParams;
//copy out positions and indices
if (mdl)
{
U16 index_offset = 0;
mPositions.clear();
mIndices.clear();
//queue up vertex positions and indices
for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = mdl->getVolumeFace(i);
if (mPositions.size() + face.mNumVertices > 65535)
{
continue;
}
for (U32 j = 0; j < face.mNumVertices; ++j)
{
mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr()));
}
for (U32 j = 0; j < face.mNumIndices; ++j)
{
mIndices.push_back(face.mIndices[j]+index_offset);
}
index_offset += face.mNumVertices;
}
}
}
S32 LLFloaterModelWizard::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2)
{
setStatusMessage(llformat("%s: %d/%d", status, p1, p2));
return mContinue;
}
void LLFloaterModelWizard::DecompRequest::completed()
{ //called from the main thread
mModel->setConvexHullDecomposition(mHull);
if (sInstance)
{
if (sInstance->mModelPreview)
{
sInstance->mModelPreview->mPhysicsMesh[mModel] = mHullMesh;
sInstance->mModelPreview->mDirty = true;
LLFloaterModelWizard::sInstance->mModelPreview->refresh();
}
sInstance->mCurRequest.erase(this);
}
if (mStage == "Decompose")
{
executePhysicsStage("Simplify");
}
}
BOOL LLFloaterModelWizard::postBuild()
{
@ -236,13 +424,13 @@ BOOL LLFloaterModelWizard::postBuild()
getChild<LLUICtrl>("browse")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this));
getChild<LLUICtrl>("cancel")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this));
getChild<LLUICtrl>("close")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this));
getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickBack, this));
getChild<LLUICtrl>("next")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickNext, this));
childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this);
getChild<LLUICtrl>("preview_lod_combo")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1));
getChild<LLUICtrl>("accuracy_slider")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onAccuracyPerformance, this, _2));
childSetAction("ok_btn", onUpload, this);
getChild<LLUICtrl>("upload")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onUpload, this));
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
enable_registrar.add("Next.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableNext, this));
@ -262,19 +450,20 @@ BOOL LLFloaterModelWizard::postBuild()
childSetTextArg("import_dimensions", "[Y]", LLStringUtil::null);
childSetTextArg("import_dimensions", "[Z]", LLStringUtil::null);
initDecompControls();
return TRUE;
}
void LLFloaterModelWizard::onUpload(void* user_data)
{
LLFloaterModelWizard* mp = (LLFloaterModelWizard*) user_data;
void LLFloaterModelWizard::onUpload()
{
mModelPreview->rebuildUploadData();
mp->mModelPreview->rebuildUploadData();
gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
childGetValue("upload_textures").asBoolean(), childGetValue("upload_skin"), childGetValue("upload_joints"));
gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale,
mp->childGetValue("upload_textures").asBoolean(), mp->childGetValue("upload_skin"), mp->childGetValue("upload_joints"));
setState(UPLOAD);
mp->closeFloater(false);
}
@ -287,11 +476,9 @@ void LLFloaterModelWizard::onAccuracyPerformance(const LLSD& data)
mModelPreview->refresh();
}
void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata)
void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl)
{
LLFloaterModelWizard *fp =(LLFloaterModelWizard *)userdata;
if (!fp->mModelPreview)
if (!mModelPreview)
{
return;
}
@ -302,7 +489,7 @@ void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata)
which_mode = (NUM_LOD-1)-combo->getFirstSelectedIndex(); // combo box list of lods is in reverse order
fp->mModelPreview->setPreviewLOD(which_mode);
mModelPreview->setPreviewLOD(which_mode);
}
void LLFloaterModelWizard::draw()

View File

@ -26,13 +26,35 @@
#ifndef LLFLOATERMODELWIZARD_H
#define LLFLOATERMODELWIZARD_H
#include "llmeshrepository.h"
#include "llmodel.h"
#include "llthread.h"
class LLModelPreview;
class LLFloaterModelWizard : public LLFloater
{
public:
class DecompRequest : public LLPhysicsDecomp::Request
{
public:
S32 mContinue;
LLPointer<LLModel> mModel;
DecompRequest(const std::string& stage, LLModel* mdl);
virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
virtual void completed();
};
static LLFloaterModelWizard* sInstance;
LLFloaterModelWizard(const LLSD& key);
virtual ~LLFloaterModelWizard() {};
virtual ~LLFloaterModelWizard();
/*virtual*/ BOOL postBuild();
void draw();
@ -41,6 +63,14 @@ public:
BOOL handleHover(S32 x, S32 y, MASK mask);
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
void initDecompControls();
LLPhysicsDecomp::decomp_params mDecompParams;
std::set<LLPointer<DecompRequest> > mCurRequest;
std::string mStatusMessage;
static void executePhysicsStage(std::string stage_name);
private:
enum EWizardState
{
@ -59,9 +89,9 @@ private:
bool onEnableNext();
bool onEnableBack();
void loadModel();
static void onPreviewLODCommit(LLUICtrl*,void*);
void onPreviewLODCommit(LLUICtrl*);
void onAccuracyPerformance(const LLSD& data);
static void onUpload(void* data);
void onUpload();
LLModelPreview* mModelPreview;
LLRect mPreviewRect;

View File

@ -4384,12 +4384,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL);
LLDrawable* drawablep = *drawable_iter;
if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
{
continue;
}
if (drawablep->isState(LLDrawable::REBUILD_ALL))
if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) )
{
LLVOVolume* vobj = drawablep->getVOVolume();
vobj->preRebuild();

View File

@ -7859,7 +7859,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.popRenderTypeMask();
LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd));
LLPlane npnorm(-pnorm, -pd);
LLViewerCamera::getInstance()->setUserClipPlane(npnorm);
LLPipeline::sUseOcclusion = occlusion;
LLGLState::checkStates();
@ -8059,14 +8060,13 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
}
//get set of planes on bounding box
std::vector<LLPlane> bp;
bp.push_back(LLPlane(min, LLVector3(-1,0,0)));
bp.push_back(LLPlane(min, LLVector3(0,-1,0)));
bp.push_back(LLPlane(min, LLVector3(0,0,-1)));
bp.push_back(LLPlane(max, LLVector3(1,0,0)));
bp.push_back(LLPlane(max, LLVector3(0,1,0)));
bp.push_back(LLPlane(max, LLVector3(0,0,1)));
LLPlane bp[] = {
LLPlane(min, LLVector3(-1,0,0)),
LLPlane(min, LLVector3(0,-1,0)),
LLPlane(min, LLVector3(0,0,-1)),
LLPlane(max, LLVector3(1,0,0)),
LLPlane(max, LLVector3(0,1,0)),
LLPlane(max, LLVector3(0,0,1))};
//potential points
std::vector<LLVector3> pp;
@ -8114,7 +8114,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
const LLPlane& cp = camera.getAgentPlane(j);
const LLVector3& v1 = pp[bs[i*2+0]];
const LLVector3& v2 = pp[bs[i*2+1]];
const LLVector3 n(cp.mV);
LLVector3 n;
cp.getVector3(n);
LLVector3 line = v1-v2;
@ -8128,8 +8129,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
LLVector3 intersect = v2+line*t;
pp.push_back(intersect);
}
}
}
}
//camera frustum line segments
const U32 fs[] =
@ -8160,7 +8161,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
const LLVector3& v1 = pp[fs[i*2+0]+8];
const LLVector3& v2 = pp[fs[i*2+1]+8];
const LLPlane& cp = bp[j];
const LLVector3 n(cp.mV);
LLVector3 n;
cp.getVector3(n);
LLVector3 line = v1-v2;
@ -8175,7 +8177,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
pp.push_back(intersect);
}
}
}
}
LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f),
max+LLVector3(0.05f,0.05f,0.05f) };

View File

@ -69,7 +69,7 @@
Resource Cost: [COST]
</text>
<text left="25" top_pad="5" width="140" follows="bottom|left" height="15" name="physics cost">
Physics Cost: Unknown
Physics Cost: [COST]
</text>
<text left="25" top_pad="5" follows="bottom|left" height="15" name="upload fee">
Upload Fee: N/A

File diff suppressed because it is too large Load Diff