From 47a5f12ce05ed08aa9bc5599dfff9e4cf9b83e44 Mon Sep 17 00:00:00 2001 From: prep linden Date: Wed, 17 Nov 2010 12:41:04 -0500 Subject: Implemented support for parsing bone offsets from a Collada file when no skeletal node is present. --- indra/newview/llfloatermodelpreview.cpp | 1383 +++++++++++++++++-------------- indra/newview/llfloatermodelpreview.h | 7 + 2 files changed, 747 insertions(+), 643 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index a37469422d..d3da7533ec 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -112,7 +112,7 @@ std::string limit_name[] = "medium limit", "high limit", "physics limit", - + "I went off the end of the limit_name array. Me so smart." }; @@ -123,7 +123,7 @@ std::string info_name[] = "medium info", "high info", "physics info", - + "I went off the end of the info_name array. Me so smart." }; @@ -137,7 +137,7 @@ bool validate_face(const LLVolumeFace& face) return false; } } - + return true; } @@ -156,39 +156,39 @@ bool validate_model(const LLModel* mdl) llwarns << "Face has no vertices." << llendl; return false; } - + if (mdl->getVolumeFace(i).mNumIndices == 0) { llwarns << "Face has no indices." << llendl; return false; } - + if (!validate_face(mdl->getVolumeFace(i))) { return false; } } - + return true; } BOOL stop_gloderror() { GLuint error = glodGetError(); - + if (error != GLOD_NO_ERROR) { llwarns << "GLOD error detected, cannot generate LOD: " << std::hex << error << llendl; return TRUE; } - + return FALSE; } LLPhysicsDecompFloater::LLPhysicsDecompFloater(LLSD& key) : LLFloater(key) { - + } LLPhysicsDecompFloater::~LLPhysicsDecompFloater() @@ -204,14 +204,14 @@ class LLMeshFilePicker : public LLFilePickerThread public: LLFloaterModelPreview* mFMP; S32 mLOD; - + LLMeshFilePicker(LLFloaterModelPreview* fmp, S32 lod) - : LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA) + : LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA) { mFMP = fmp; mLOD = lod; } - + virtual void notify(const std::string& filename) { mFMP->mModelPreview->loadModel(mFile, mLOD); @@ -223,7 +223,7 @@ public: // LLFloaterModelPreview() //----------------------------------------------------------------------------- LLFloaterModelPreview::LLFloaterModelPreview(const LLSD& key) : - LLFloater(key) +LLFloater(key) { sInstance = this; mLastMouseX = 0; @@ -242,27 +242,27 @@ BOOL LLFloaterModelPreview::postBuild() { return FALSE; } - + childSetCommitCallback("high detail combo", onHighLODCommit, this); childSetCommitCallback("medium detail combo", onMediumLODCommit, this); childSetCommitCallback("low detail combo", onLowLODCommit, this); childSetCommitCallback("lowest detail combo", onLowestLODCommit, this); childSetCommitCallback("physics detail combo", onPhysicsLODCommit, this); - - + + childSetCommitCallback("high limit", onHighLimitCommit, this); childSetCommitCallback("medium limit", onMediumLimitCommit, this); childSetCommitCallback("low limit", onLowLimitCommit, this); childSetCommitCallback("lowest limit", onLowestLimitCommit, this); childSetCommitCallback("physics limit", onPhysicsLimitCommit, this); - + childSetCommitCallback("smooth normals", onSmoothNormalsCommit, this); - + childSetCommitCallback("show edges", onShowEdgesCommit, this); childSetCommitCallback("auto fill", onAutoFillCommit, this); - + childSetTextArg("status", "[STATUS]", getString("status_idle")); - + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) { if (lod == LLModel::LOD_PHYSICS) @@ -279,36 +279,36 @@ BOOL LLFloaterModelPreview::postBuild() std::string msg = getString("required"); childSetTextArg(info_name[lod], "[MESSAGE]", msg); } - + childSetVisible(limit_name[lod], FALSE); } - + //childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount)); childSetAction("ok_btn", onUpload, this); - + childSetAction("consolidate", onConsolidate, this); childSetAction("scrub materials", onScrubMaterials, this); - + childSetAction("decompose_btn", onDecompose, this); - + childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this); childSetCommitCallback("upload_skin", onUploadSkinCommit, this); childSetCommitCallback("upload_joints", onUploadJointsCommit, this); - + childSetCommitCallback("debug scale", onDebugScaleCommit, this); - + childDisable("upload_skin"); childDisable("upload_joints"); - + const U32 width = 512; const U32 height = 512; - + mPreviewRect.set(getRect().getWidth()-PREVIEW_HPAD-width, - PREVIEW_HPAD+height, - getRect().getWidth()-PREVIEW_HPAD, - PREVIEW_HPAD); - + PREVIEW_HPAD+height, + getRect().getWidth()-PREVIEW_HPAD, + PREVIEW_HPAD); + mModelPreview = new LLModelPreview(512, 512, this); mModelPreview->setPreviewTarget(16.f); @@ -321,7 +321,7 @@ BOOL LLFloaterModelPreview::postBuild() LLFloaterModelPreview::~LLFloaterModelPreview() { sInstance = NULL; - + if ( mModelPreview->containsRiggedAsset() ) { gAgentAvatarp->resetJointPositions(); @@ -333,7 +333,7 @@ LLFloaterModelPreview::~LLFloaterModelPreview() { LLImageGL::deleteTextures(1, &mGLName ); } - + if (mDecompFloater) { mDecompFloater->closeFloater(); @@ -344,7 +344,7 @@ LLFloaterModelPreview::~LLFloaterModelPreview() void LLFloaterModelPreview::loadModel(S32 lod) { mLoading = TRUE; - + (new LLMeshFilePicker(this, lod))->getFile(); } @@ -363,7 +363,7 @@ void LLFloaterModelPreview::setLODMode(S32 lod, S32 mode) { mModelPreview->clearModel(lod); } - + mModelPreview->refresh(); mModelPreview->calcResourceCost(); } @@ -376,21 +376,21 @@ void LLFloaterModelPreview::setLODMode(S32 lod, S32 mode) mModelPreview->mLODMode[lod] = mode; mModelPreview->genLODs(lod); } - + mModelPreview->setPreviewLOD(lod); LLSpinCtrl* lim = getChild(limit_name[lod], TRUE); - + if (mode == 2) //triangle count { U32 tri_count = 0; for (LLModelLoader::model_list::iterator iter = mModelPreview->mBaseModel.begin(); - iter != mModelPreview->mBaseModel.end(); ++iter) + iter != mModelPreview->mBaseModel.end(); ++iter) { tri_count += (*iter)->getNumTriangles(); } - + lim->setMaxValue(tri_count); lim->setVisible(TRUE); } @@ -419,7 +419,7 @@ void LLFloaterModelPreview::onDebugScaleCommit(LLUICtrl*,void* userdata) { return; } - + fp->mModelPreview->calcResourceCost(); } @@ -432,7 +432,7 @@ void LLFloaterModelPreview::onUploadJointsCommit(LLUICtrl*,void* userdata) { return; } - + fp->mModelPreview->refresh(); } @@ -445,12 +445,12 @@ void LLFloaterModelPreview::onUploadSkinCommit(LLUICtrl*,void* userdata) { return; } - + fp->mModelPreview->refresh(); fp->mModelPreview->resetPreviewTarget(); fp->mModelPreview->clearBuffers(); } - + //static void LLFloaterModelPreview::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata) { @@ -460,9 +460,9 @@ void LLFloaterModelPreview::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata) { return; } - + S32 which_mode = 0; - + LLCtrlSelectionInterface* iface = fp->childGetSelectionInterface("preview_lod_combo"); if (iface) { @@ -480,9 +480,9 @@ void LLFloaterModelPreview::setLODMode(S32 lod, void* userdata) { return; } - + S32 which_mode = 0; - + std::string combo_name[] = { "lowest detail combo", @@ -490,16 +490,16 @@ void LLFloaterModelPreview::setLODMode(S32 lod, void* userdata) "medium detail combo", "high detail combo", "physics detail combo", - + "I went off the end of the combo_name array. Me so smart." }; - + LLCtrlSelectionInterface* iface = fp->childGetSelectionInterface(combo_name[lod]); if (iface) { which_mode = iface->getFirstSelectedIndex(); } - + fp->setLODMode(lod, which_mode); } @@ -542,9 +542,9 @@ void LLFloaterModelPreview::setLimit(S32 lod, void* userdata) { return; } - + S32 limit = fp->childGetValue(limit_name[lod]).asInteger(); - + fp->setLimit(lod, limit); } @@ -583,7 +583,7 @@ void LLFloaterModelPreview::onPhysicsLimitCommit(LLUICtrl* ctrl, void* userdata) void LLFloaterModelPreview::onSmoothNormalsCommit(LLUICtrl* ctrl, void* userdata) { LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; - + fp->mModelPreview->smoothNormals(); } @@ -591,7 +591,7 @@ void LLFloaterModelPreview::onSmoothNormalsCommit(LLUICtrl* ctrl, void* userdata void LLFloaterModelPreview::onShowEdgesCommit(LLUICtrl* ctrl, void* userdata) { LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; - + fp->mModelPreview->refresh(); } @@ -599,7 +599,7 @@ void LLFloaterModelPreview::onShowEdgesCommit(LLUICtrl* ctrl, void* userdata) void LLFloaterModelPreview::onExplodeCommit(LLUICtrl* ctrl, void* userdata) { LLFloaterModelPreview* fp = LLFloaterModelPreview::sInstance; - + fp->mModelPreview->refresh(); } @@ -607,7 +607,7 @@ void LLFloaterModelPreview::onExplodeCommit(LLUICtrl* ctrl, void* userdata) void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata) { LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; - + fp->mModelPreview->genLODs(); } @@ -619,7 +619,7 @@ void LLFloaterModelPreview::draw() { LLFloater::draw(); LLRect r = getRect(); - + mModelPreview->update(); if (!mLoading) @@ -629,7 +629,7 @@ void LLFloaterModelPreview::draw() childSetTextArg("description_label", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost)); childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size())); - + if (mDecompFloater) { if (mCurRequest.notNull()) @@ -642,9 +642,9 @@ void LLFloaterModelPreview::draw() mDecompFloater->childSetText("status", idle); } } - + U32 resource_cost = mModelPreview->mResourceCost*10; - + if (childGetValue("upload_textures").asBoolean()) { resource_cost += mModelPreview->mTextureSet.size()*10; @@ -655,7 +655,7 @@ void LLFloaterModelPreview::draw() if (mModelPreview) { gGL.color3f(1.f, 1.f, 1.f); - + gGL.getTexUnit(0)->bind(mModelPreview); gGL.begin( LLRender::QUADS ); @@ -670,7 +670,7 @@ void LLFloaterModelPreview::draw() gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mTop); } gGL.end(); - + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } } @@ -689,7 +689,7 @@ BOOL LLFloaterModelPreview::handleMouseDown(S32 x, S32 y, MASK mask) mLastMouseY = y; return TRUE; } - + return LLFloater::handleMouseDown(x, y, mask); } @@ -709,7 +709,7 @@ BOOL LLFloaterModelPreview::handleMouseUp(S32 x, S32 y, MASK mask) BOOL LLFloaterModelPreview::handleHover (S32 x, S32 y, MASK mask) { MASK local_mask = mask & ~MASK_ALT; - + if (mModelPreview && hasMouseCapture()) { if (local_mask == MASK_PAN) @@ -726,20 +726,20 @@ BOOL LLFloaterModelPreview::handleHover (S32 x, S32 y, MASK mask) } else { - + F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f; mModelPreview->rotate(yaw_radians, 0.f); mModelPreview->zoom(zoom_amt); } - + mModelPreview->refresh(); LLUI::setMousePositionLocal(this, mLastMouseX, mLastMouseY); } - + if (!mPreviewRect.pointInRect(x, y) || !mModelPreview) { return LLFloater::handleHover(x, y, mask); @@ -756,7 +756,7 @@ BOOL LLFloaterModelPreview::handleHover (S32 x, S32 y, MASK mask) { gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN); } - + return TRUE; } @@ -770,7 +770,7 @@ BOOL LLFloaterModelPreview::handleScrollWheel(S32 x, S32 y, S32 clicks) mModelPreview->zoom((F32)clicks * -0.2f); mModelPreview->refresh(); } - + return TRUE; } @@ -782,7 +782,7 @@ void LLFloaterModelPreview::onPhysicsParamCommit(LLUICtrl* ctrl, void* data) llinfos << "convex decomposition tool is a stub on this platform. cannot get decomp." << llendl; return; } - + if (sInstance) { LLCDParam* param = (LLCDParam*) data; @@ -796,7 +796,7 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data) LLCDStageData* stage = (LLCDStageData*) data; LLModel* mdl = NULL; - + if (sInstance) { if (sInstance->mCurRequest.notNull()) @@ -804,7 +804,7 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data) llinfos << "Decomposition request still pending." << llendl; return; } - + if (sInstance->mModelPreview) { if (sInstance->mDecompFloater) @@ -840,12 +840,12 @@ void LLFloaterModelPreview::showDecompFloater() { LLSD key; mDecompFloater = new LLPhysicsDecompFloater(key); - + S32 left = 20; S32 right = 320; - + S32 cur_y = 30; - + { //add status text LLTextBox::Params p; @@ -853,8 +853,8 @@ void LLFloaterModelPreview::showDecompFloater() p.rect(LLRect(left, cur_y, right-80, cur_y-20)); mDecompFloater->addChild(LLUICtrlFactory::create(p)); } - - + + { //add cancel button LLButton::Params p; p.name("Cancel"); @@ -864,25 +864,25 @@ void LLFloaterModelPreview::showDecompFloater() button->setCommitCallback(onPhysicsStageCancel, NULL); mDecompFloater->addChild(button); } - + cur_y += 30; - - + + 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(¶m); } - + for (S32 j = stage_count-1; j >= 0; --j) { LLButton::Params p; @@ -896,29 +896,29 @@ void LLFloaterModelPreview::showDecompFloater() cur_y += 30; // protected against stub by stage_count being 0 for stub above LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback); - + llinfos << "Physics decomp stage " << stage[j].mName << " (" << j << ") parameters:" << llendl; llinfos << "------------------------------------" << llendl; - + 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 : ""); - + std::string type = "unknown"; - + llinfos << name << " - " << description << llendl; - + if (param[i].mType == LLCDParam::LLCD_FLOAT) { mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat); llinfos << "Type: float, Default: " << param[i].mDefault.mFloat << llendl; - + LLSliderCtrl::Params p; p.name(name); p.label(name); @@ -956,7 +956,7 @@ void LLFloaterModelPreview::showDecompFloater() { mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool); llinfos << "Type: boolean, Default: " << (param[i].mDefault.mBool ? "True" : "False") << llendl; - + LLCheckBoxCtrl::Params p; p.rect(LLRect(left, cur_y, right, cur_y-20)); p.name(name); @@ -973,11 +973,11 @@ void LLFloaterModelPreview::showDecompFloater() S32 cur_x = left; mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue); llinfos << "Type: enum, Default: " << param[i].mDefault.mIntOrEnumValue << llendl; - + { //add label LLTextBox::Params p; const LLFontGL* font = (LLFontGL*) p.font(); - + p.rect(LLRect(left, cur_y, left+font->getWidth(name), cur_y-20)); p.name(name); p.label(name); @@ -986,37 +986,37 @@ void LLFloaterModelPreview::showDecompFloater() mDecompFloater->addChild(text_box); cur_x += text_box->getRect().getWidth(); } - + { //add combo_box LLComboBox::Params p; p.rect(LLRect(cur_x, cur_y, right-right/4, cur_y-20)); p.name(name); p.label(name); p.tool_tip(description); - + llinfos << "Accepted values: " << llendl; LLComboBox* combo_box = LLUICtrlFactory::create(p); for (S32 k = 0; k < param[i].mDetails.mEnumValues.mNumEnums; ++k) { llinfos << param[i].mDetails.mEnumValues.mEnumsArray[k].mValue - << " - " << param[i].mDetails.mEnumValues.mEnumsArray[k].mName << llendl; - + << " - " << param[i].mDetails.mEnumValues.mEnumsArray[k].mName << llendl; + combo_box->add(param[i].mDetails.mEnumValues.mEnumsArray[k].mName, - LLSD::Integer(param[i].mDetails.mEnumValues.mEnumsArray[k].mValue)); + LLSD::Integer(param[i].mDetails.mEnumValues.mEnumsArray[k].mValue)); } combo_box->setValue(param[i].mDefault.mIntOrEnumValue); combo_box->setCommitCallback(onPhysicsParamCommit, (void*) ¶m[i]); mDecompFloater->addChild(combo_box); cur_y += 30; - + } - + llinfos << "----" << llendl; } llinfos << "-----------------------------" << llendl; } } - + cur_y += 30; //explode slider { @@ -1030,11 +1030,11 @@ void LLFloaterModelPreview::showDecompFloater() p.name("explode"); p.rect(LLRect(left, cur_y, right, cur_y-20)); LLSliderCtrl* slider = LLUICtrlFactory::create(p); - + mDecompFloater->addChild(slider); cur_y += 30; } - + //mesh render checkbox { LLCheckBoxCtrl::Params p; @@ -1045,7 +1045,7 @@ void LLFloaterModelPreview::showDecompFloater() check->setValue(true); mDecompFloater->addChild(check); } - + //hull render checkbox { LLCheckBoxCtrl::Params p; @@ -1056,7 +1056,7 @@ void LLFloaterModelPreview::showDecompFloater() check->setValue(true); mDecompFloater->addChild(check); } - + { //submesh combo box label LLTextBox::Params p; p.label("Model"); @@ -1066,7 +1066,7 @@ void LLFloaterModelPreview::showDecompFloater() text_box->setValue("Model"); mDecompFloater->addChild(text_box); } - + { //add submesh combo box LLComboBox::Params p; @@ -1082,16 +1082,16 @@ void LLFloaterModelPreview::showDecompFloater() mDecompFloater->addChild(combo_box); cur_y += 30; } - + mDecompFloater->childSetCommitCallback("model", LLFloaterModelPreview::refresh, LLFloaterModelPreview::sInstance); mDecompFloater->childSetCommitCallback("render_mesh", LLFloaterModelPreview::refresh, LLFloaterModelPreview::sInstance); mDecompFloater->childSetCommitCallback("render_hull", LLFloaterModelPreview::refresh, LLFloaterModelPreview::sInstance); - + mDecompFloater->setRect(LLRect(10, cur_y+20, right+20, 10)); } - + mDecompFloater->childSetCommitCallback("explode", LLFloaterModelPreview::onExplodeCommit, this); - + mDecompFloater->openFloater(); } @@ -1136,7 +1136,7 @@ LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* prev mJointMap["mAnkleLeft"] = "mAnkleLeft"; mJointMap["mFootLeft"] = "mFootLeft"; mJointMap["mToeLeft"] = "mToeLeft"; - + mJointMap["avatar_mPelvis"] = "mPelvis"; mJointMap["avatar_mTorso"] = "mTorso"; mJointMap["avatar_mChest"] = "mChest"; @@ -1163,8 +1163,8 @@ LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* prev mJointMap["avatar_mAnkleLeft"] = "mAnkleLeft"; mJointMap["avatar_mFootLeft"] = "mFootLeft"; mJointMap["avatar_mToeLeft"] = "mToeLeft"; - - + + mJointMap["hip"] = "mPelvis"; mJointMap["abdomen"] = "mTorso"; mJointMap["chest"] = "mChest"; @@ -1200,7 +1200,7 @@ void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4 LLVector4a( 1,-1,-1), LLVector4a( 1,-1, 1), }; - + for (S32 j = 0; j < model->getNumVolumeFaces(); ++j) { const LLVolumeFace& face = model->getVolumeFace(j); @@ -1211,15 +1211,15 @@ void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4 LLVector4a size; size.setSub(face.mExtents[1],face.mExtents[0]); size.mul(0.5f); - + for (U32 i = 0; i < 8; i++) { LLVector4a t; t.setMul(size, box[i]); t.add(center); - + LLVector4a v; - + mat.affineTransform(t, v); if (first_transform) @@ -1239,11 +1239,11 @@ void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& { LLVector4a mina, maxa; LLMatrix4a mata; - + mata.loadu(mat); mina.load3(min.mV); maxa.load3(max.mV); - + stretch_extents(model, mata, mina, maxa, first_transform); min.set(mina.getF32ptr()); @@ -1254,32 +1254,32 @@ void LLModelLoader::run() { DAE dae; domCOLLADA* dom = dae.open(mFilename); - + if (dom) { daeDatabase* db = dae.getDatabase(); - + daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH); - + daeDocument* doc = dae.getDoc(mFilename); if (!doc) { llwarns << "can't find internal doc" << llendl; return; } - + daeElement* root = doc->getDomRoot(); if (!root) { llwarns << "document has no root" << llendl; return; } - + //get unit scale mTransform.setIdentity(); - + domAsset::domUnit* unit = daeSafeCast(root->getDescendant(daeElement::matchType(domAsset::domUnit::ID()))); - + if (unit) { F32 meter = unit->getMeter(); @@ -1287,14 +1287,14 @@ void LLModelLoader::run() mTransform.mMatrix[1][1] = meter; mTransform.mMatrix[2][2] = meter; } - + //get up axis rotation LLMatrix4 rotation; - + domUpAxisType up = UPAXISTYPE_Y_UP; // default is Y_UP domAsset::domUp_axis* up_axis = - daeSafeCast(root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID()))); - + daeSafeCast(root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID()))); + if (up_axis) { up = up_axis->getValue(); @@ -1308,20 +1308,20 @@ void LLModelLoader::run() { rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f); } - + rotation *= mTransform; mTransform = rotation; - - + + for (daeInt idx = 0; idx < count; ++idx) { //build map of domEntities to LLModel domMesh* mesh = NULL; db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH); - + if (mesh) { LLPointer model = LLModel::loadModelFromDomMesh(mesh); - + if (model.notNull() && validate_model(model)) { mModelList.push_back(model); @@ -1329,13 +1329,13 @@ void LLModelLoader::run() } } } - + count = db->getElementCount(NULL, COLLADA_TYPE_SKIN); for (daeInt idx = 0; idx < count; ++idx) { //add skinned meshes as instances domSkin* skin = NULL; db->getElement((daeElement**) &skin, idx, NULL, COLLADA_TYPE_SKIN); - + if (skin) { domGeometry* geom = daeSafeCast(skin->getSource().getElement()); @@ -1351,7 +1351,7 @@ void LLModelLoader::run() LLVector3 mesh_scale_vector; LLVector3 mesh_translation_vector; model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); - + LLMatrix4 normalized_transformation; normalized_transformation.setTranslation(mesh_translation_vector); @@ -1359,13 +1359,13 @@ void LLModelLoader::run() mesh_scale.initScale(mesh_scale_vector); mesh_scale *= normalized_transformation; normalized_transformation = mesh_scale; - + glh::matrix4f inv_mat((F32*) normalized_transformation.mMatrix); inv_mat = inv_mat.inverse(); LLMatrix4 inverse_normalized_transformation(inv_mat.m); - + domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix(); - + if (bind_mat) { //get bind shape matrix domFloat4x4& dom_value = bind_mat->getValue(); @@ -1377,28 +1377,28 @@ void LLModelLoader::run() model->mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4]; } } - + LLMatrix4 trans = normalized_transformation; trans *= model->mBindShapeMatrix; model->mBindShapeMatrix = trans; - + } - + /*{ - LLMatrix4 rotation; - if (up == UPAXISTYPE_X_UP) - { - rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f); - } - else if (up == UPAXISTYPE_Z_UP) - { - rotation.initRotation(90.0f * DEG_TO_RAD, 90.0f * DEG_TO_RAD, 0.0f); - } - - rotation *= model->mBindShapeMatrix; - model->mBindShapeMatrix = rotation; - }*/ - + LLMatrix4 rotation; + if (up == UPAXISTYPE_X_UP) + { + rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f); + } + else if (up == UPAXISTYPE_Z_UP) + { + rotation.initRotation(90.0f * DEG_TO_RAD, 90.0f * DEG_TO_RAD, 0.0f); + } + + rotation *= model->mBindShapeMatrix; + model->mBindShapeMatrix = rotation; + }*/ + //The joint transfom map that we'll populate below std::map jointTransforms; jointTransforms.clear(); @@ -1406,9 +1406,40 @@ void LLModelLoader::run() //Some collada setup for accessing the skeleton daeElement* pElement = 0; dae.getDatabase()->getElement( &pElement, 0, 0, "skeleton" ); + //Try to get at the skeletal instance controller domInstance_controller::domSkeleton* pSkeleton = daeSafeCast( pElement ); - if ( pSkeleton ) - { + bool missingSkeletonOrScene = false; + + //If no skeleton, do a breadth-first search to get at specific joints + if ( !pSkeleton ) + { + daeElement* pScene = root->getDescendant("visual_scene"); + if ( !pScene ) + { + llwarns<<"No visual scene - unable to parse bone offsets "< > children = pScene->getChildren(); + S32 childCount = children.getCount(); + + //Process any children that are joints + //Not all children are joints, some code be ambient lights, cameras, geometry etc.. + for (S32 i = 0; i < childCount; ++i) + { + domNode* pNode = daeSafeCast(children[i]); + if ( isNodeAJoint( pNode ) ) + { + processJointNode( pNode, jointTransforms ); + } + } + } + } + else + //Has Skeleton + { //Get the root node of the skeleton daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); if ( pSkeletonRootNode ) @@ -1416,7 +1447,7 @@ void LLModelLoader::run() //Once we have the root node - start acccessing it's joint components const int jointCnt = mJointMap.size(); std::map :: const_iterator jointIt = mJointMap.begin(); - bool missingID = false; + //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. for ( int i=0; i( resolver.getElement() ); - if ( pJoint ) - { - //Pull out the translate id and store it in the jointTranslations map - daeSIDResolver jointResolver( pJoint, "./translate" ); - domTranslate* pTranslate = daeSafeCast( jointResolver.getElement() ); - - LLMatrix4 workingTransform; - - //Translation via SID - if ( pTranslate ) - { - domFloat3 jointTrans = pTranslate->getValue(); - LLVector3 singleJointTranslation( jointTrans[0], jointTrans[1], jointTrans[2] ); - workingTransform.setTranslation( singleJointTranslation ); - } - else - { - //Translation via child from element - daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); - if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) - { - llwarns<< "The found element is not a translate node" <( pTranslateElement ); - domFloat3 translateChild = pTranslateChild->getValue(); - LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] ); - workingTransform.setTranslation( singleJointTranslation ); - } - } - //Store the joint transform w/respect to it's name. - jointTransforms[(*jointIt).second.c_str()] = workingTransform; + + //Setup the resolver + daeSIDResolver resolver( pSkeletonRootNode, str ); + + //Look for the joint + domNode* pJoint = daeSafeCast( resolver.getElement() ); + if ( pJoint ) + { + //Pull out the translate id and store it in the jointTranslations map + daeSIDResolver jointResolver( pJoint, "./translate" ); + domTranslate* pTranslate = daeSafeCast( jointResolver.getElement() ); + + LLMatrix4 workingTransform; + + //Translation via SID + if ( pTranslate ) + { + extractTranslation( pTranslate, workingTransform ); + } + else + { + //Translation via child from element + daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); + if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) + { + llwarns<< "The found element is not a translate node" <getJoint( lookingForJoint ); - if ( pJoint ) - { - pJoint->storeCurrentXform( jointTransform.getTranslation() ); - } - else - { - //Most likely an error in the asset. - llwarns<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << llendl; - } - //Reposition the avatars pelvis (avPos+offset) - //if ( !strcmp( (*jointIt).first.c_str(),"mPelvis" ) ) - if ( lookingForJoint == "mPelvis" ) - { - const LLVector3& pos = gAgentAvatarp->getCharacterPosition(); - gAgentAvatarp->setPelvisOffset( true, jointTransform.getTranslation() ); - gAgentAvatarp->setPosition( pos + jointTransform.getTranslation() ); - } - } - } - } - else - { - llwarns<<"No root node in this skeleton" << llendl; - } - } - else - { - llwarns<<"No skeleton in this asset" << llendl; + }//got skeleton? } + if ( !missingSkeletonOrScene ) + { + //Set the joint translations on the avatar + //The joints are reset in the dtor + const int jointCnt = mJointMap.size(); + std::map :: const_iterator jointIt = mJointMap.begin(); + for ( int i=0; igetJoint( lookingForJoint ); + if ( pJoint ) + { + pJoint->storeCurrentXform( jointTransform.getTranslation() ); + } + else + { + //Most likely an error in the asset. + llwarns<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << llendl; + } + //Reposition the avatars pelvis (avPos+offset) + if ( lookingForJoint == "mPelvis" ) + { + const LLVector3& pos = gAgentAvatarp->getCharacterPosition(); + gAgentAvatarp->setPelvisOffset( true, jointTransform.getTranslation() ); + gAgentAvatarp->setPosition( pos + jointTransform.getTranslation() ); + } + } + } + } //missingSkeletonOrScene + + domSkin::domJoints* joints = skin->getJoints(); - + domInputLocal_Array& joint_input = joints->getInput_array(); - + for (size_t i = 0; i < joint_input.getCount(); ++i) { domInputLocal* input = joint_input.get(i); xsNMTOKEN semantic = input->getSemantic(); - + if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0) { //found joint source, fill model->mJointMap and model->mJointList daeElement* elem = input->getSource().getElement(); @@ -1533,13 +1556,13 @@ void LLModelLoader::run() if (source) { - + domName_array* names_source = source->getName_array(); if (names_source) { domListOfNames &names = names_source->getValue(); - + for (size_t j = 0; j < names.getCount(); ++j) { std::string name(names.get(j)); @@ -1557,7 +1580,7 @@ void LLModelLoader::run() if (names_source) { xsIDREFS& names = names_source->getValue(); - + for (size_t j = 0; j < names.getCount(); ++j) { std::string name(names.get(j).getID()); @@ -1582,11 +1605,11 @@ void LLModelLoader::run() { domListOfFloats& transform = t->getValue(); S32 count = transform.getCount()/16; - + for (S32 k = 0; k < count; ++k) { LLMatrix4 mat; - + for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) @@ -1594,14 +1617,14 @@ void LLModelLoader::run() mat.mMatrix[i][j] = transform[k*16 + i + j*4]; } } - + model->mInvBindMatrix.push_back(mat); } } } } } - + //We need to construct the alternate bind matrix (which contains the new joint positions) //in the same order as they were stored in the joint buffer. The joints associated //with the skeleton are not stored in the same order as they are in the exported joint buffer. @@ -1652,10 +1675,10 @@ void LLModelLoader::run() } LLVector3 v(pos[j], pos[j+1], pos[j+2]); - + //transform from COLLADA space to volume space v = v * inverse_normalized_transformation; - + model->mPosition.push_back(v); } } @@ -1663,7 +1686,7 @@ void LLModelLoader::run() } } } - + //grab skin weights array domSkin::domVertex_weights* weights = skin->getVertex_weights(); if (weights) @@ -1681,44 +1704,44 @@ void LLModelLoader::run() } } } - + if (vertex_weights) { domListOfFloats& w = vertex_weights->getValue(); domListOfUInts& vcount = weights->getVcount()->getValue(); domListOfInts& v = weights->getV()->getValue(); - + U32 c_idx = 0; for (size_t vc_idx = 0; vc_idx < vcount.getCount(); ++vc_idx) { //for each vertex daeUInt count = vcount[vc_idx]; - + //create list of weights that influence this vertex LLModel::weight_list weight_list; - + for (daeUInt i = 0; i < count; ++i) { //for each weight daeInt joint_idx = v[c_idx++]; daeInt weight_idx = v[c_idx++]; - + if (joint_idx == -1) { //ignore bindings to bind_shape_matrix continue; } - + F32 weight_value = w[weight_idx]; - + weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value)); } - + //sort by joint weight std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater()); - + std::vector wght; F32 total = 0.f; - + for (U32 i = 0; i < llmin((U32) 4, (U32) weight_list.size()); ++i) { //take up to 4 most significant weights if (weight_list[i].mWeight > 0.f) @@ -1736,7 +1759,7 @@ void LLModelLoader::run() wght[i].mWeight *= scale; } } - + model->mSkinWeights[model->mPosition[vc_idx]] = wght; } @@ -1754,78 +1777,153 @@ void LLModelLoader::run() } } } - + daeElement* scene = root->getDescendant("visual_scene"); if (!scene) { llwarns << "document has no visual_scene" << llendl; return; } - + processElement(scene); - + mPreview->loadModelCallback(mLod); } } - -daeElement* LLModelLoader::getChildFromElement( daeElement* pElement, std::string const & name ) -{ - daeElement* pChildOfElement = pElement->getChild( name.c_str() ); - if ( pChildOfElement ) - { - return pChildOfElement; - } - llwarns<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << llendl; - return NULL; -} + +bool LLModelLoader::isNodeAJoint( domNode* pNode ) +{ + if ( mJointMap.find( pNode->getName() ) != mJointMap.end() ) + { + return true; + } + + return false; +} + +void LLModelLoader::extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ) +{ + domFloat3 jointTrans = pTranslate->getValue(); + LLVector3 singleJointTranslation( jointTrans[0], jointTrans[1], jointTrans[2] ); + transform.setTranslation( singleJointTranslation ); +} + +void LLModelLoader::extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ) +{ + domTranslate* pTranslateChild = dynamic_cast( pTranslateElement ); + domFloat3 translateChild = pTranslateChild->getValue(); + LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] ); + transform.setTranslation( singleJointTranslation ); +} + +void LLModelLoader::processJointNode( domNode* pNode, std::map& jointTransforms ) +{ + //llwarns<<"ProcessJointNode# Node:" <getName()<( jointResolver.getElement() ); + + //Translation via SID was successful + if ( pTranslate ) + { + extractTranslation( pTranslate, workingTransform ); + } + else + { + //Translation via child from element + daeElement* pTranslateElement = getChildFromElement( pNode, "translate" ); + if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) + { + llwarns<< "The found element is not a translate node" <getName() ] = workingTransform; + + //2. handle the nodes children + + //Gather and handle the incoming nodes children + daeTArray< daeSmartRef > childOfChild = pNode->getChildren(); + S32 childOfChildCount = childOfChild.getCount(); + + for (S32 i = 0; i < childOfChildCount; ++i) + { + domNode* pChildNode = daeSafeCast( childOfChild[i] ); + if ( pChildNode ) + { + processJointNode( pChildNode, jointTransforms ); + } + } +} + +daeElement* LLModelLoader::getChildFromElement( daeElement* pElement, std::string const & name ) +{ + daeElement* pChildOfElement = pElement->getChild( name.c_str() ); + if ( pChildOfElement ) + { + return pChildOfElement; + } + llwarns<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << llendl; + return NULL; +} void LLModelLoader::processElement(daeElement* element) { LLMatrix4 saved_transform = mTransform; - + domTranslate* translate = daeSafeCast(element); if (translate) { domFloat3 dom_value = translate->getValue(); - + LLMatrix4 translation; translation.setTranslation(LLVector3(dom_value[0], dom_value[1], dom_value[2])); translation *= mTransform; mTransform = translation; } - + domRotate* rotate = daeSafeCast(element); if (rotate) { domFloat4 dom_value = rotate->getValue(); - + LLMatrix4 rotation; rotation.initRotTrans(dom_value[3] * DEG_TO_RAD, LLVector3(dom_value[0], dom_value[1], dom_value[2]), LLVector3(0, 0, 0)); - + rotation *= mTransform; mTransform = rotation; } - + domScale* scale = daeSafeCast(element); if (scale) { domFloat3 dom_value = scale->getValue(); - + LLMatrix4 scaling; scaling.initScale(LLVector3(dom_value[0], dom_value[1], dom_value[2])); - + scaling *= mTransform; mTransform = scaling; } - + domMatrix* matrix = daeSafeCast(element); if (matrix) { domFloat4x4 dom_value = matrix->getValue(); - + LLMatrix4 matrix_transform; - + for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) @@ -1837,7 +1935,7 @@ void LLModelLoader::processElement(daeElement* element) matrix_transform *= mTransform; mTransform = matrix_transform; } - + domInstance_geometry* instance_geo = daeSafeCast(element); if (instance_geo) { @@ -1851,14 +1949,14 @@ void LLModelLoader::processElement(daeElement* element) if (model) { LLMatrix4 transformation = mTransform; - + std::vector materials = getMaterials(model, instance_geo); - + // adjust the transformation to compensate for mesh normalization LLVector3 mesh_scale_vector; LLVector3 mesh_translation_vector; model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); - + LLMatrix4 mesh_translation; mesh_translation.setTranslation(mesh_translation_vector); mesh_translation *= transformation; @@ -1870,13 +1968,13 @@ void LLModelLoader::processElement(daeElement* element) transformation = mesh_scale; mScene[transformation].push_back(LLModelInstance(model, transformation, materials)); - + stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform); } } } } - + domInstance_node* instance_node = daeSafeCast(element); if (instance_node) { @@ -1886,14 +1984,14 @@ void LLModelLoader::processElement(daeElement* element) processElement(instance); } } - + //process children daeTArray< daeSmartRef > children = element->getChildren(); for (S32 i = 0; i < children.getCount(); i++) { processElement(children[i]); } - + domNode* node = daeSafeCast(element); if (node) { //this element was a node, restore transform before processiing siblings @@ -1907,40 +2005,40 @@ std::vector LLModelLoader::getMaterials(LLModel* model, domIns for (int i = 0; i < model->mMaterialList.size(); i++) { LLImportMaterial import_material; - + domInstance_material* instance_mat = NULL; - + domBind_material::domTechnique_common* technique = - daeSafeCast(instance_geo->getDescendant(daeElement::matchType(domBind_material::domTechnique_common::ID()))); - + daeSafeCast(instance_geo->getDescendant(daeElement::matchType(domBind_material::domTechnique_common::ID()))); + if (technique) { daeTArray< daeSmartRef > inst_materials = technique->getChildrenByType(); for (int j = 0; j < inst_materials.getCount(); j++) { std::string symbol(inst_materials[j]->getSymbol()); - + if (symbol == model->mMaterialList[i]) // found the binding { instance_mat = inst_materials[j]; } } } - + if (instance_mat) { domMaterial* material = daeSafeCast(instance_mat->getTarget().getElement()); if (material) { domInstance_effect* instance_effect = - daeSafeCast(material->getDescendant(daeElement::matchType(domInstance_effect::ID()))); + daeSafeCast(material->getDescendant(daeElement::matchType(domInstance_effect::ID()))); if (instance_effect) { domEffect* effect = daeSafeCast(instance_effect->getUrl().getElement()); if (effect) { domProfile_COMMON* profile = - daeSafeCast(effect->getDescendant(daeElement::matchType(domProfile_COMMON::ID()))); + daeSafeCast(effect->getDescendant(daeElement::matchType(domProfile_COMMON::ID()))); if (profile) { import_material = profileToMaterial(profile); @@ -1952,7 +2050,7 @@ std::vector LLModelLoader::getMaterials(LLModel* model, domIns materials.push_back(import_material); } - + return materials; } @@ -1960,12 +2058,12 @@ LLImportMaterial LLModelLoader::profileToMaterial(domProfile_COMMON* material) { LLImportMaterial mat; mat.mFullbright = FALSE; - + daeElement* diffuse = material->getDescendant("diffuse"); if (diffuse) { domCommon_color_or_texture_type_complexType::domTexture* texture = - daeSafeCast(diffuse->getDescendant("texture")); + daeSafeCast(diffuse->getDescendant("texture")); if (texture) { domCommon_newparam_type_Array newparams = material->getNewparam_array(); @@ -1989,10 +2087,10 @@ LLImportMaterial LLModelLoader::profileToMaterial(domProfile_COMMON* material) if (init) { std::string filename = cdom::uriToNativePath(init->getValue().str()); - + mat.mDiffuseMap = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + filename, TRUE, LLViewerTexture::BOOST_PREVIEW); mat.mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, this->mPreview, NULL, FALSE); - + mat.mDiffuseMap->forceToSaveRawImage(); mat.mDiffuseMapFilename = filename; mat.mDiffuseMapLabel = getElementLabel(material); @@ -2005,7 +2103,7 @@ LLImportMaterial LLModelLoader::profileToMaterial(domProfile_COMMON* material) } domCommon_color_or_texture_type_complexType::domColor* color = - daeSafeCast(diffuse->getDescendant("color")); + daeSafeCast(diffuse->getDescendant("color")); if (color) { domFx_color_common domfx_color = color->getValue(); @@ -2013,7 +2111,7 @@ LLImportMaterial LLModelLoader::profileToMaterial(domProfile_COMMON* material) mat.mDiffuseColor = value; } } - + daeElement* emission = material->getDescendant("emission"); if (emission) { @@ -2023,7 +2121,7 @@ LLImportMaterial LLModelLoader::profileToMaterial(domProfile_COMMON* material) mat.mFullbright = TRUE; } } - + return mat; } @@ -2036,13 +2134,13 @@ std::string LLModelLoader::getElementLabel(daeElement *element) { return name; } - + // if we have an ID attribute, use it if (element->getID()) { return std::string(element->getID()); } - + // if we have a parent, use it daeElement* parent = element->getParent(); if (parent) @@ -2053,21 +2151,21 @@ std::string LLModelLoader::getElementLabel(daeElement *element) { return name; } - + // if parent has an ID, use it if (parent->getID()) { return std::string(parent->getID()); } } - + // try to use our type daeString element_name = element->getElementName(); if (element_name) { return std::string(element_name); } - + // if all else fails, use "object" return std::string("object"); } @@ -2076,13 +2174,13 @@ LLColor4 LLModelLoader::getDaeColor(daeElement* element) { LLColor4 value; domCommon_color_or_texture_type_complexType::domColor* color = - daeSafeCast(element->getDescendant("color")); + daeSafeCast(element->getDescendant("color")); if (color) { domFx_color_common domfx_color = color->getValue(); value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]); } - + return value; } @@ -2102,17 +2200,17 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloaterModelPreview* fmp mPreviewLOD = 3; mModelLoader = NULL; mDirty = false; - + for (U32 i = 0; i < LLModel::NUM_LODS; i++) { mLODMode[i] = 1; mLimit[i] = 0; } - + mLODMode[0] = 0; - + mFMP = fmp; - + glodInit(); } @@ -2123,7 +2221,7 @@ LLModelPreview::~LLModelPreview() delete mModelLoader; mModelLoader = NULL; } - + //*HACK : *TODO : turn this back on when we understand why this crashes //glodShutdown(); } @@ -2131,40 +2229,40 @@ LLModelPreview::~LLModelPreview() U32 LLModelPreview::calcResourceCost() { rebuildUploadData(); - + U32 cost = 0; std::set accounted; U32 num_points = 0; U32 num_hulls = 0; - + F32 debug_scale = mFMP->childGetValue("debug scale").asReal(); - + F32 streaming_cost = 0.f; - + for (U32 i = 0; i < mUploadData.size(); ++i) { LLModelInstance& instance = mUploadData[i]; - + if (accounted.find(instance.mModel) == accounted.end()) { accounted.insert(instance.mModel); - + LLModel::convex_hull_decomposition& decomp = - instance.mLOD[LLModel::LOD_PHYSICS] ? - instance.mLOD[LLModel::LOD_PHYSICS]->mConvexHullDecomp : - instance.mModel->mConvexHullDecomp; - + instance.mLOD[LLModel::LOD_PHYSICS] ? + instance.mLOD[LLModel::LOD_PHYSICS]->mConvexHullDecomp : + instance.mModel->mConvexHullDecomp; + LLSD ret = LLModel::writeModel( - "", - instance.mLOD[4], - instance.mLOD[3], - instance.mLOD[2], - instance.mLOD[1], - instance.mLOD[0], - decomp, - mFMP->childGetValue("upload_skin").asBoolean(), - mFMP->childGetValue("upload_joints").asBoolean(), - TRUE); + "", + instance.mLOD[4], + instance.mLOD[3], + instance.mLOD[2], + instance.mLOD[1], + instance.mLOD[0], + decomp, + mFMP->childGetValue("upload_skin").asBoolean(), + mFMP->childGetValue("upload_joints").asBoolean(), + TRUE); cost += gMeshRepo.calcResourceCost(ret); num_hulls += decomp.size(); @@ -2172,12 +2270,12 @@ U32 LLModelPreview::calcResourceCost() { num_points += decomp[i].size(); } - + //calculate streaming cost LLMatrix4 transformation = instance.mTransform; - + LLVector3 position = LLVector3(0, 0, 0) * transformation; - + LLVector3 x_transformed = LLVector3(1, 0, 0) * transformation - position; LLVector3 y_transformed = LLVector3(0, 1, 0) * transformation - position; LLVector3 z_transformed = LLVector3(0, 0, 1) * transformation - position; @@ -2185,13 +2283,13 @@ U32 LLModelPreview::calcResourceCost() F32 y_length = y_transformed.normalize(); F32 z_length = z_transformed.normalize(); LLVector3 scale = LLVector3(x_length, y_length, z_length); - + F32 radius = scale.length()*debug_scale; - + streaming_cost += LLMeshRepository::getStreamingCost(ret, radius); } } - + 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)); @@ -2199,7 +2297,7 @@ U32 LLModelPreview::calcResourceCost() mFMP->childSetTextArg("dimensions", "[X]", llformat("%.3f", mPreviewScale[0]*scale)); mFMP->childSetTextArg("dimensions", "[Y]", llformat("%.3f", mPreviewScale[1]*scale)); mFMP->childSetTextArg("dimensions", "[Z]", llformat("%.3f", mPreviewScale[2]*scale)); - + updateStatusMessages(); return cost; @@ -2209,30 +2307,30 @@ void LLModelPreview::rebuildUploadData() { mUploadData.clear(); mTextureSet.clear(); - + //fill uploaddata instance vectors from scene data - + LLSpinCtrl* scale_spinner = mFMP->getChild("debug scale"); - + if (!scale_spinner) { llerrs << "floater_model_preview.xml MUST contain debug scale spinner." << llendl; } - + F32 scale = scale_spinner->getValue().asReal(); - + LLMatrix4 scale_mat; scale_mat.initScale(LLVector3(scale, scale, scale)); - + F32 max_scale = 0.f; - + for (LLModelLoader::scene::iterator iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter) { //for each transform in scene LLMatrix4 mat = iter->first; - + // compute position LLVector3 position = LLVector3(0, 0, 0) * mat; - + // compute scale LLVector3 x_transformed = LLVector3(1, 0, 0) * mat - position; LLVector3 y_transformed = LLVector3(0, 1, 0) * mat - position; @@ -2244,13 +2342,13 @@ void LLModelPreview::rebuildUploadData() max_scale = llmax(llmax(llmax(max_scale, x_length), y_length), z_length); mat *= scale_mat; - + for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) { //for each instance with said transform applied LLModelInstance instance = *model_iter; - + LLModel* base_model = instance.mModel; - + S32 idx = 0; for (idx = 0; idx < mBaseModel.size(); ++idx) { //find reference instance for this model @@ -2259,7 +2357,7 @@ void LLModelPreview::rebuildUploadData() break; } } - + for (U32 i = 0; i < LLModel::NUM_LODS; i++) { //fill LOD slots based on reference model index if (!mModel[i].empty()) @@ -2271,16 +2369,16 @@ void LLModelPreview::rebuildUploadData() instance.mLOD[i] = NULL; } } - + instance.mTransform = mat; mUploadData.push_back(instance); } } - + F32 max_import_scale = DEFAULT_MAX_PRIM_SCALE/max_scale; - + scale_spinner->setMaxValue(max_import_scale); - + if (max_import_scale < scale) { scale_spinner->setValue(max_import_scale); @@ -2294,7 +2392,7 @@ void LLModelPreview::clearModel(S32 lod) { return; } - + mVertexBuffer[lod].clear(); mModel[lod].clear(); mScene[lod].clear(); @@ -2309,7 +2407,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod) delete mModelLoader; mModelLoader = NULL; } - + if (filename.empty()) { if (mBaseModel.empty()) @@ -2318,11 +2416,11 @@ void LLModelPreview::loadModel(std::string filename, S32 lod) // if we don't have a base model to show for high LOD. mFMP->closeFloater(false); } - + mFMP->mLoading = false; return; } - + if (lod == 3 && !mGroup.empty()) { for (std::map, U32>::iterator iter = mGroup.begin(); iter != mGroup.end(); ++iter) @@ -2330,29 +2428,29 @@ void LLModelPreview::loadModel(std::string filename, S32 lod) glodDeleteGroup(iter->second); stop_gloderror(); } - + for (std::map, U32>::iterator iter = mObject.begin(); iter != mObject.end(); ++iter) { glodDeleteObject(iter->second); stop_gloderror(); } - + mGroup.clear(); mObject.clear(); } - + mModelLoader = new LLModelLoader(filename, lod, this); - + mModelLoader->start(); - + mFMP->childSetTextArg("status", "[STATUS]", mFMP->getString("status_reading_file")); - + if (mFMP->childGetValue("description_form").asString().empty()) { std::string name = gDirUtilp->getBaseFileName(filename, true); mFMP->childSetValue("description_form", name); } - + mFMP->openFloater(); } @@ -2367,7 +2465,7 @@ void LLModelPreview::clearIncompatible(S32 lod) mModel[i].clear(); mScene[i].clear(); mVertexBuffer[i].clear(); - + if (i == LLModel::LOD_HIGH) { mBaseModel = mModel[lod]; @@ -2386,7 +2484,7 @@ void LLModelPreview::loadModelCallback(S32 lod) { return; } - + mModel[lod] = mModelLoader->mModelList; mScene[lod] = mModelLoader->mScene; mVertexBuffer[lod].clear(); @@ -2395,7 +2493,7 @@ void LLModelPreview::loadModelCallback(S32 lod) { mPhysicsMesh.clear(); } - + setPreviewLOD(lod); @@ -2406,9 +2504,9 @@ void LLModelPreview::loadModelCallback(S32 lod) mVertexBuffer[5].clear(); //mModel[lod] = NULL; } - + clearIncompatible(lod); - + mDirty = true; resetPreviewTarget(); @@ -2427,28 +2525,28 @@ void LLModelPreview::resetPreviewTarget() void LLModelPreview::smoothNormals() { S32 which_lod = mPreviewLOD; - - + + if (which_lod > 4 || which_lod < 0 || mModel[which_lod].empty()) { return; } - + F32 angle_cutoff = mFMP->childGetValue("edge threshold").asReal(); - + angle_cutoff *= DEG_TO_RAD; - + if (which_lod == 3 && !mBaseModel.empty()) { for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) { (*iter)->smoothNormals(angle_cutoff); } - + mVertexBuffer[5].clear(); } - + for (LLModelLoader::model_list::iterator iter = mModel[which_lod].begin(); iter != mModel[which_lod].end(); ++iter) { (*iter)->smoothNormals(angle_cutoff); @@ -2456,22 +2554,22 @@ void LLModelPreview::smoothNormals() mVertexBuffer[which_lod].clear(); refresh(); - + } void LLModelPreview::consolidate() { std::map > composite; - + LLMatrix4 identity; - + //bake out each node in current scene to composite for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) { //for each transform in current scene LLMatrix4 mat = iter->first; glh::matrix4f inv_trans = glh::matrix4f((F32*) mat.mMatrix).inverse().transpose(); LLMatrix4 norm_mat(inv_trans.m); - + for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) { //for each instance with that transform LLModelInstance& source_instance = *model_iter; @@ -2481,15 +2579,15 @@ void LLModelPreview::consolidate() { llerrs << "Invalid model found!" << llendl; } - + for (S32 i = 0; i < source->getNumVolumeFaces(); ++i) { //for each face in instance const LLVolumeFace& src_face = source->getVolumeFace(i); LLImportMaterial& source_material = source_instance.mMaterial[i]; - + //get model in composite that is composite for this material LLModel* model = NULL; - + if (composite.find(source_material) != composite.end()) { model = composite[source_material].rbegin()->mModel; @@ -2498,7 +2596,7 @@ void LLModelPreview::consolidate() model = NULL; } } - + if (model == NULL) { //no model found, make new model std::vector materials; @@ -2510,91 +2608,91 @@ void LLModelPreview::consolidate() model->setNumVolumeFaces(0); composite[source_material].push_back(LLModelInstance(model, identity, materials)); } - + model->appendFace(src_face, source->mMaterialList[i], mat, norm_mat); } } } - - + + //condense composite into as few LLModel instances as possible LLModelLoader::model_list new_model; std::vector instance_list; LLVolumeParams volume_params; volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - + std::vector empty_material; LLModelInstance cur_instance(new LLModel(volume_params, 0.f), identity, empty_material); cur_instance.mModel->setNumVolumeFaces(0); - + BOOL first_transform = TRUE; - + LLModelLoader::scene new_scene; LLVector3 min,max; - + for (std::map >::iterator iter = composite.begin(); - iter != composite.end(); - ++iter) + iter != composite.end(); + ++iter) { std::map >::iterator next_iter = iter; ++next_iter; for (std::vector::iterator instance_iter = iter->second.begin(); - instance_iter != iter->second.end(); - ++instance_iter) + instance_iter != iter->second.end(); + ++instance_iter) { LLModel* source = instance_iter->mModel; - + if (instance_iter->mMaterial.size() != 1) { llerrs << "WTF?" << llendl; } - + if (source->getNumVolumeFaces() != 1) { llerrs << "WTF?" << llendl; } - + if (source->mMaterialList.size() != 1) { llerrs << "WTF?" << llendl; } - + cur_instance.mModel->addFace(source->getVolumeFace(0)); cur_instance.mMaterial.push_back(instance_iter->mMaterial[0]); cur_instance.mModel->mMaterialList.push_back(source->mMaterialList[0]); - + BOOL last_model = FALSE; - + std::vector::iterator next_instance = instance_iter; ++next_instance; - + if (next_iter == composite.end() && next_instance == iter->second.end()) { last_model = TRUE; } - + if (last_model || cur_instance.mModel->getNumVolumeFaces() >= MAX_MODEL_FACES) { cur_instance.mModel->mLabel = source->mLabel; - + cur_instance.mModel->optimizeVolumeFaces(); cur_instance.mModel->normalizeVolumeFaces(); - + if (!validate_model(cur_instance.mModel)) { llerrs << "Invalid model detected." << llendl; } - + new_model.push_back(cur_instance.mModel); - + LLMatrix4 transformation = LLMatrix4(); - + // adjust the transformation to compensate for mesh normalization LLVector3 mesh_scale_vector; LLVector3 mesh_translation_vector; cur_instance.mModel->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); - + LLMatrix4 mesh_translation; mesh_translation.setTranslation(mesh_translation_vector); mesh_translation *= transformation; @@ -2604,12 +2702,12 @@ void LLModelPreview::consolidate() mesh_scale.initScale(mesh_scale_vector); mesh_scale *= transformation; transformation = mesh_scale; - + cur_instance.mTransform = transformation; - + new_scene[transformation].push_back(cur_instance); stretch_extents(cur_instance.mModel, transformation, min, max, first_transform); - + if (!last_model) { cur_instance = LLModelInstance(new LLModel(volume_params, 0.f), identity, empty_material); @@ -2618,24 +2716,24 @@ void LLModelPreview::consolidate() } } } - + mScene[mPreviewLOD] = new_scene; mModel[mPreviewLOD] = new_model; mVertexBuffer[mPreviewLOD].clear(); - + if (mPreviewLOD == LLModel::LOD_HIGH) { mBaseScene = new_scene; mBaseModel = new_model; mVertexBuffer[5].clear(); } - + mPreviewTarget = (min+max)*0.5f; mPreviewScale = (max-min)*0.5f; setPreviewTarget(mPreviewScale.magVec()*2.f); - + clearIncompatible(mPreviewLOD); - + mResourceCost = calcResourceCost(); refresh(); } @@ -2652,7 +2750,7 @@ void LLModelPreview::scrubMaterials() for (S32 i = 0; i < source->getNumVolumeFaces(); ++i) { //for each face in instance LLImportMaterial& source_material = source_instance.mMaterial[i]; - + //clear material info source_material.mDiffuseColor = LLColor4(1,1,1,1); source_material.mDiffuseMap = NULL; @@ -2662,17 +2760,17 @@ void LLModelPreview::scrubMaterials() } } } - - + + mVertexBuffer[mPreviewLOD].clear(); - + if (mPreviewLOD == LLModel::LOD_HIGH) { mBaseScene = mScene[mPreviewLOD]; mBaseModel = mModel[mPreviewLOD]; mVertexBuffer[5].clear(); } - + mResourceCost = calcResourceCost(); refresh(); } @@ -2698,26 +2796,26 @@ void LLModelPreview::genLODs(S32 which_lod) { return; } - + if (which_lod == LLModel::LOD_PHYSICS) { //clear physics mesh map mPhysicsMesh.clear(); } - + LLVertexBuffer::unbind(); - + stop_gloderror(); static U32 cur_name = 1; - + S32 limit = -1; - + if (which_lod != -1) { limit = mLimit[which_lod]; } - + U32 triangle_count = 0; - + for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) { LLModel* mdl = *iter; @@ -2726,11 +2824,11 @@ void LLModelPreview::genLODs(S32 which_lod) triangle_count += mdl->getVolumeFace(i).mNumIndices/3; } } - + U32 base_triangle_count = triangle_count; - + U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; - + if (mGroup[mBaseModel[0]] == 0) { //clear LOD maps mGroup.clear(); @@ -2738,7 +2836,7 @@ void LLModelPreview::genLODs(S32 which_lod) mPercentage.clear(); mPatch.clear(); } - + for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) { //build GLOD objects for each model in base model list LLModel* mdl = *iter; @@ -2746,32 +2844,32 @@ void LLModelPreview::genLODs(S32 which_lod) { mGroup[mdl] = cur_name++; mObject[mdl] = cur_name++; - + glodNewGroup(mGroup[mdl]); stop_gloderror(); - + glodGroupParameteri(mGroup[mdl], GLOD_ADAPT_MODE, GLOD_TRIANGLE_BUDGET); stop_gloderror(); - + glodGroupParameteri(mGroup[mdl], GLOD_ERROR_MODE, GLOD_OBJECT_SPACE_ERROR); stop_gloderror(); - + glodGroupParameterf(mGroup[mdl], GLOD_OBJECT_SPACE_ERROR_THRESHOLD, 0.025f); stop_gloderror(); - + glodNewObject(mObject[mdl], mGroup[mdl], GLOD_DISCRETE); stop_gloderror(); - + if (iter == mBaseModel.begin() && !mdl->mSkinWeights.empty()) { //regenerate vertex buffer for skinned models to prevent animation feedback during LOD generation mVertexBuffer[5].clear(); } - + if (mVertexBuffer[5].empty()) { genBuffers(5, false); } - + U32 tri_count = 0; for (U32 i = 0; i < mVertexBuffer[5][mdl].size(); ++i) { @@ -2784,10 +2882,10 @@ void LLModelPreview::genLODs(S32 which_lod) tri_count += num_indices/3; stop_gloderror(); } - + //store what percentage of total model (in terms of triangle count) this model makes up mPercentage[mdl] = (F32) tri_count / (F32) base_triangle_count; - + //build glodobject glodBuildObject(mObject[mdl]); if (stop_gloderror()) @@ -2796,18 +2894,18 @@ void LLModelPreview::genLODs(S32 which_lod) stop_gloderror(); glodDeleteObject(mObject[mdl]); stop_gloderror(); - + mGroup[mdl] = 0; mObject[mdl] = 0; - + if (which_lod == -1) { mModel[LLModel::LOD_HIGH] = mBaseModel; } - + return; } - + } //generating LODs for all entries, or this entry has a triangle budget @@ -2817,11 +2915,11 @@ void LLModelPreview::genLODs(S32 which_lod) glodGroupParameterf(mGroup[mdl], GLOD_OBJECT_SPACE_ERROR_THRESHOLD, 0.025f); stop_gloderror(); } - - + + S32 start = LLModel::LOD_HIGH; S32 end = 0; - + if (which_lod != -1) { start = end = which_lod; @@ -2836,7 +2934,7 @@ void LLModelPreview::genLODs(S32 which_lod) "high detail combo", "physics detail combo" }; - + std::string limit_name[] = { "lowest limit", @@ -2845,7 +2943,7 @@ void LLModelPreview::genLODs(S32 which_lod) "high limit", "physics limit" }; - + for (S32 lod = start; lod >= end; --lod) { if (which_lod == -1) @@ -2859,59 +2957,59 @@ void LLModelPreview::genLODs(S32 which_lod) { triangle_count = limit; } - + LLComboBox* combo_box = mFMP->findChild(combo_name[lod]); combo_box->setCurrentByIndex(2); - + LLSpinCtrl* lim = mFMP->getChild(limit_name[lod], TRUE); lim->setMaxValue(base_triangle_count); lim->setVisible(true); - + mModel[lod].clear(); mModel[lod].resize(mBaseModel.size()); mVertexBuffer[lod].clear(); - + U32 actual_tris = 0; U32 actual_verts = 0; U32 submeshes = 0; - + for (U32 mdl_idx = 0; mdl_idx < mBaseModel.size(); ++mdl_idx) { LLModel* base = mBaseModel[mdl_idx]; - + U32 target_count = U32(mPercentage[base]*triangle_count); - + if (target_count < 4) { target_count = 4; } - + glodGroupParameteri(mGroup[base], GLOD_MAX_TRIANGLES, target_count); stop_gloderror(); - + glodAdaptGroup(mGroup[base]); stop_gloderror(); - + GLint patch_count = 0; glodGetObjectParameteriv(mObject[base], GLOD_NUM_PATCHES, &patch_count); stop_gloderror(); - + LLVolumeParams volume_params; volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); mModel[lod][mdl_idx] = new LLModel(volume_params, 0.f); - + GLint* sizes = new GLint[patch_count*2]; glodGetObjectParameteriv(mObject[base], GLOD_PATCH_SIZES, sizes); stop_gloderror(); - + GLint* names = new GLint[patch_count]; glodGetObjectParameteriv(mObject[base], GLOD_PATCH_NAMES, names); stop_gloderror(); - + mModel[lod][mdl_idx]->setNumVolumeFaces(patch_count); LLModel* target_model = mModel[lod][mdl_idx]; - + for (GLint i = 0; i < patch_count; ++i) { LLPointer buff = new LLVertexBuffer(type_mask, 0); @@ -2931,29 +3029,29 @@ void LLModelPreview::genLODs(S32 which_lod) } buff->validateRange(0, buff->getNumVerts()-1, buff->getNumIndices(), 0); - + LLStrider pos; LLStrider norm; LLStrider tc; LLStrider index; - + buff->getVertexStrider(pos); buff->getNormalStrider(norm); buff->getTexCoord0Strider(tc); buff->getIndexStrider(index); - - + + target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices()); actual_tris += buff->getNumIndices()/3; actual_verts += buff->getNumVerts(); ++submeshes; - + if (!validate_face(target_model->getVolumeFace(names[i]))) { llerrs << "Invalid face generated during LOD generation." << llendl; } } - + //blind copy skin weights and just take closest skin weight to point on //decimated mesh for now (auto-generating LODs with skin weights is still a bit //of an open problem). @@ -2966,20 +3064,20 @@ void LLModelPreview::genLODs(S32 which_lod) target_model->mAlternateBindMatrix = base->mAlternateBindMatrix; //copy material list target_model->mMaterialList = base->mMaterialList; - + if (!validate_model(target_model)) { llerrs << "Invalid model generated when creating LODs" << llendl; } - + delete [] sizes; delete [] names; } - + //rebuild scene based on mBaseScene mScene[lod].clear(); mScene[lod] = mBaseScene; - + for (U32 i = 0; i < mBaseModel.size(); ++i) { LLModel* mdl = mBaseModel[i]; @@ -2999,19 +3097,19 @@ void LLModelPreview::genLODs(S32 which_lod) } } } - + mResourceCost = calcResourceCost(); - + /*if (which_lod == -1 && mScene[LLModel::LOD_PHYSICS].empty()) - { //build physics scene - mScene[LLModel::LOD_PHYSICS] = mScene[LLModel::LOD_LOW]; - mModel[LLModel::LOD_PHYSICS] = mModel[LLModel::LOD_LOW]; - - for (U32 i = 1; i < mModel[LLModel::LOD_PHYSICS].size(); ++i) - { - mPhysicsQ.push(mModel[LLModel::LOD_PHYSICS][i]); - } - }*/ + { //build physics scene + mScene[LLModel::LOD_PHYSICS] = mScene[LLModel::LOD_LOW]; + mModel[LLModel::LOD_PHYSICS] = mModel[LLModel::LOD_LOW]; + + for (U32 i = 1; i < mModel[LLModel::LOD_PHYSICS].size(); ++i) + { + mPhysicsQ.push(mModel[LLModel::LOD_PHYSICS][i]); + } + }*/ } void LLModelPreview::updateStatusMessages() @@ -3025,30 +3123,30 @@ void LLModelPreview::updateStatusMessages() S32 total_tris[LLModel::NUM_LODS]; S32 total_verts[LLModel::NUM_LODS]; S32 total_submeshes[LLModel::NUM_LODS]; - + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) { //initialize total for this lod to 0 total_tris[lod] = total_verts[lod] = total_submeshes[lod] = 0; - + for (U32 i = 0; i < mModel[lod].size(); ++i) { //for each model in the lod S32 cur_tris = 0; S32 cur_verts = 0; S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces(); - + for (S32 j = 0; j < cur_submeshes; ++j) { //for each submesh (face), add triangles and vertices to current total const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j); cur_tris += face.mNumIndices/3; cur_verts += face.mNumVertices; } - + //add this model to the lod total total_tris[lod] += cur_tris; total_verts[lod] += cur_verts; total_submeshes[lod] += cur_submeshes; - + //store this model's counts to asset data tris[lod].push_back(cur_tris); verts[lod].push_back(cur_verts); @@ -3056,21 +3154,21 @@ void LLModelPreview::updateStatusMessages() } } - + std::string upload_message; - + mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[TRIANGLES]", llformat("%d", total_tris[LLModel::LOD_PHYSICS])); - + for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod) { mFMP->childSetTextArg(info_name[lod], "[TRIANGLES]", llformat("%d", total_tris[lod])); mFMP->childSetTextArg(info_name[lod], "[VERTICES]", llformat("%d", total_verts[lod])); mFMP->childSetTextArg(info_name[lod], "[SUBMESHES]", llformat("%d", total_submeshes[lod])); - + std::string message = "good"; const U32 lod_high = LLModel::LOD_HIGH; - + if (lod != lod_high) { if (total_submeshes[lod] && total_submeshes[lod] != total_submeshes[lod_high]) @@ -3088,7 +3186,7 @@ void LLModelPreview::updateStatusMessages() for (U32 i = 0; i < verts[lod].size(); ++i) { S32 max_verts = verts[lod+1][i]; - + if (verts[lod][i] > max_verts) { message = "too_heavy"; @@ -3097,10 +3195,10 @@ void LLModelPreview::updateStatusMessages() } } } - + mFMP->childSetTextArg(info_name[lod], "[MESSAGE]", mFMP->getString(message)); } - + if (upload_message.empty()) { mFMP->childSetTextArg("upload_message", "[MESSAGE]", std::string("")); @@ -3135,9 +3233,9 @@ void LLModelPreview::genBuffers(S32 lod, bool avatar_preview) U32 tri_count = 0; U32 vertex_count = 0; U32 mesh_count = 0; - + LLModelLoader::model_list* model = NULL; - + if (lod < 0 || lod > 4) { model = &mBaseModel; @@ -3147,16 +3245,16 @@ void LLModelPreview::genBuffers(S32 lod, bool avatar_preview) { model = &(mModel[lod]); } - + if (!mVertexBuffer[lod].empty()) { mVertexBuffer[lod].clear(); } - + mVertexBuffer[lod].clear(); - + LLModelLoader::model_list::iterator base_iter = mBaseModel.begin(); - + for (LLModelLoader::model_list::iterator iter = model->begin(); iter != model->end(); ++iter) { LLModel* mdl = *iter; @@ -3164,47 +3262,47 @@ void LLModelPreview::genBuffers(S32 lod, bool avatar_preview) { continue; } - + LLModel* base_mdl = *base_iter; base_iter++; - + for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) { const LLVolumeFace &vf = mdl->getVolumeFace(i); U32 num_vertices = vf.mNumVertices; U32 num_indices = vf.mNumIndices; - + if (!num_vertices || ! num_indices) { continue; } - + LLVertexBuffer* vb = NULL; bool skinned = avatar_preview && !mdl->mSkinWeights.empty(); - + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; if (skinned) { mask |= LLVertexBuffer::MAP_WEIGHT4; } - + vb = new LLVertexBuffer(mask, 0); vb->allocateBuffer(num_vertices, num_indices, TRUE); - + LLStrider vertex_strider; LLStrider normal_strider; LLStrider tc_strider; LLStrider index_strider; LLStrider weights_strider; - + vb->getVertexStrider(vertex_strider); vb->getNormalStrider(normal_strider); vb->getTexCoord0Strider(tc_strider); vb->getIndexStrider(index_strider); - + if (skinned) { vb->getWeight4Strider(weights_strider); @@ -3213,22 +3311,22 @@ void LLModelPreview::genBuffers(S32 lod, bool avatar_preview) LLVector4a::memcpyNonAliased16((F32*) vertex_strider.get(), (F32*) vf.mPositions, num_vertices*4*sizeof(F32)); LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32)); - + if (skinned) { for (U32 i = 0; i < num_vertices; i++) { //find closest weight to vf.mVertices[i].mPosition LLVector3 pos(vf.mPositions[i].getF32ptr()); - + const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos); - + LLVector4 w(0,0,0,0); if (weight_list.size() > 4) { llerrs << "WTF?" << llendl; } - + for (U32 i = 0; i < weight_list.size(); ++i) { F32 wght = llmin(weight_list[i].mWeight, 0.999999f); @@ -3239,19 +3337,19 @@ void LLModelPreview::genBuffers(S32 lod, bool avatar_preview) *(weights_strider++) = w; } } - + // build indices for (U32 i = 0; i < num_indices; i++) { *(index_strider++) = vf.mIndices[i]; } - + mVertexBuffer[lod][mdl].push_back(vb); - + vertex_count += num_vertices; tri_count += num_indices/3; ++mesh_count; - + } } } @@ -3272,33 +3370,33 @@ BOOL LLModelPreview::render() { LLMutexLock lock(this); mNeedsUpdate = FALSE; - + S32 width = getWidth(); S32 height = getHeight(); - + LLGLSUIDefault def; LLGLDisable no_blend(GL_BLEND); LLGLEnable cull(GL_CULL_FACE); LLGLDepthTest depth(GL_TRUE); LLGLDisable fog(GL_FOG); - + glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); glOrtho(0.0f, width, 0.0f, height, -1.0f, 1.0f); - + glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); glLoadIdentity(); - + gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - + gl_rect_2d_simple( width, height ); - + bool avatar_preview = false; bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean(); bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean(); - + for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) { for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) @@ -3311,19 +3409,19 @@ BOOL LLModelPreview::render() } } } - + if (upload_skin && !avatar_preview) { mFMP->childSetValue("upload_skin", false); upload_skin = false; } - + if (!upload_skin && upload_joints) { mFMP->childSetValue("upload_joints", false); upload_joints = false; } - + if (!avatar_preview) { mFMP->childDisable("upload_skin"); @@ -3332,7 +3430,7 @@ BOOL LLModelPreview::render() { mFMP->childEnable("upload_skin"); } - + if (!upload_skin) { mFMP->childDisable("upload_joints"); @@ -3341,125 +3439,125 @@ BOOL LLModelPreview::render() { mFMP->childEnable("upload_joints"); } - + avatar_preview = avatar_preview && upload_skin; - - + + mFMP->childSetEnabled("consolidate", !avatar_preview); F32 explode = mFMP->mDecompFloater ? mFMP->mDecompFloater->childGetValue("explode").asReal() : 0.f; - + glMatrixMode(GL_PROJECTION); gGL.popMatrix(); - + glMatrixMode(GL_MODELVIEW); gGL.popMatrix(); - + glClear(GL_DEPTH_BUFFER_BIT); - + LLViewerCamera::getInstance()->setAspect((F32) width / height ); LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); - + LLVector3 target_pos = mPreviewTarget; LLVector3 offset = mCameraOffset; - + F32 z_near = llmax(mCameraDistance-mPreviewScale.magVec(), 0.001f); F32 z_far = mCameraDistance+mPreviewScale.magVec(); - + if (avatar_preview) { target_pos = gAgentAvatarp->getPositionAgent(); z_near = 0.01f; z_far = 1024.f; mCameraDistance = 16.f; - + //render avatar previews every frame refresh(); } - + LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * - LLQuaternion(mCameraYaw, LLVector3::z_axis); - + LLQuaternion(mCameraYaw, LLVector3::z_axis); + LLQuaternion av_rot = camera_rot; LLViewerCamera::getInstance()->setOriginAndLookAt( - target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera - LLVector3::z_axis, // up - target_pos); // point of interest - + target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera + LLVector3::z_axis, // up + target_pos); // point of interest + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, width, height, FALSE, z_near, z_far); - + stop_glerror(); - + gPipeline.enableLightsAvatar(); - + gGL.pushMatrix(); const F32 BRIGHTNESS = 0.9f; gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); LLGLEnable normalize(GL_NORMALIZE); - + if (!mBaseModel.empty() && mVertexBuffer[5].empty()) { genBuffers(-1, avatar_preview); //genBuffers(3); //genLODs(); } - + bool physics = (mPreviewLOD == LLModel::LOD_PHYSICS); - + S32 physics_idx = -1; - + bool render_mesh = true; bool render_hull = false; - + if (physics && mFMP->mDecompFloater) { physics_idx = mFMP->mDecompFloater->childGetValue("model").asInteger(); render_mesh = mFMP->mDecompFloater->childGetValue("render_mesh").asBoolean(); render_hull = mFMP->mDecompFloater->childGetValue("render_hull").asBoolean(); } - + if (!mModel[mPreviewLOD].empty()) { if (mVertexBuffer[mPreviewLOD].empty()) { genBuffers(mPreviewLOD, avatar_preview); } - + if (!avatar_preview) { //for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) { LLModelInstance& instance = *iter; - + gGL.pushMatrix(); LLMatrix4 mat = instance.mTransform; - + glMultMatrixf((GLfloat*) mat.mMatrix); //for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) { //LLModelInstance& instance = *model_iter; LLModel* model = instance.mLOD[mPreviewLOD]; - + if (!model) { continue; } - + //if (instance.mTransform != mat) //{ // llerrs << "WTF?" << llendl; //} - + if (render_mesh) { for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i) { LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; - + buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); if (physics) { @@ -3484,11 +3582,11 @@ BOOL LLModelPreview::render() } } } - + buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); glColor3f(0.4f, 0.4f, 0.4f); - + if (mFMP->childGetValue("show edges").asBoolean()) { glLineWidth(3.f); @@ -3499,16 +3597,16 @@ BOOL LLModelPreview::render() } } } - + if (render_hull) { LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread; if (decomp) { LLMutexLock(decomp->mMutex); - + std::map, std::vector > >::iterator iter = - mPhysicsMesh.find(model); + mPhysicsMesh.find(model); if (iter != mPhysicsMesh.end()) { for (U32 i = 0; i < iter->second.size(); ++i) @@ -3516,28 +3614,28 @@ BOOL LLModelPreview::render() if (explode > 0.f) { gGL.pushMatrix(); - + LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters; offset *= explode; - + gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); } - + static std::vector hull_colors; - + if (i+1 >= hull_colors.size()) { hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255)); } - + LLVertexBuffer* buff = iter->second[i]; if (buff) { buff->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL); - + glColor4ubv(hull_colors[i].mV); buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts()); - + if (mFMP->childGetValue("show edges").asBoolean()) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -3548,7 +3646,7 @@ BOOL LLModelPreview::render() glLineWidth(1.f); } } - + if (explode > 0.f) { gGL.popMatrix(); @@ -3556,15 +3654,15 @@ BOOL LLModelPreview::render() } } } - + //mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[HULLS]", llformat("%d",decomp->mHulls.size())); //mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[POINTS]", llformat("%d",decomp->mTotalPoints)); } } - + gGL.popMatrix(); } - + if (physics) { mPreviewLOD = LLModel::LOD_PHYSICS; @@ -3574,29 +3672,29 @@ BOOL LLModelPreview::render() { LLVOAvatarSelf* avatar = gAgentAvatarp; target_pos = avatar->getPositionAgent(); - + LLViewerCamera::getInstance()->setOriginAndLookAt( - target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera - LLVector3::z_axis, // up - target_pos); // point of interest - + target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera + LLVector3::z_axis, // up + target_pos); // point of interest + avatar->renderCollisionVolumes(); - + for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) { for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) { LLModelInstance& instance = *model_iter; LLModel* model = instance.mModel; - + if (!model->mSkinWeights.empty()) { for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i) { LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; - + const LLVolumeFace& face = model->getVolumeFace(i); - + LLStrider position; buffer->getVertexStrider(position); @@ -3604,7 +3702,7 @@ BOOL LLModelPreview::render() buffer->getWeight4Strider(weight); //quick 'n dirty software vertex skinning - + //build matrix palette LLMatrix4 mat[64]; for (U32 j = 0; j < model->mJointList.size(); ++j) @@ -3616,55 +3714,55 @@ BOOL LLModelPreview::render() mat[j] *= joint->getWorldMatrix(); } } - + for (U32 j = 0; j < buffer->getRequestedVerts(); ++j) { LLMatrix4 final_mat; final_mat.mMatrix[0][0] = final_mat.mMatrix[1][1] = final_mat.mMatrix[2][2] = final_mat.mMatrix[3][3] = 0.f; - + LLVector4 wght; S32 idx[4]; - + F32 scale = 0.f; for (U32 k = 0; k < 4; k++) { F32 w = weight[j].mV[k]; - + idx[k] = (S32) floorf(w); wght.mV[k] = w - floorf(w); scale += wght.mV[k]; } - + wght *= 1.f/scale; - + for (U32 k = 0; k < 4; k++) { F32* src = (F32*) mat[idx[k]].mMatrix; F32* dst = (F32*) final_mat.mMatrix; - + F32 w = wght.mV[k]; - + for (U32 l = 0; l < 16; l++) { dst[l] += src[l]*w; } } - + //VECTORIZE THIS LLVector3 v(face.mPositions[j].getF32ptr()); v = v * model->mBindShapeMatrix; v = v * final_mat; - + position[j] = v; } - + buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); glColor3f(0.4f, 0.4f, 0.4f); - + if (mFMP->childGetValue("show edges").asBoolean()) { glLineWidth(3.f); @@ -3679,9 +3777,9 @@ BOOL LLModelPreview::render() } } } - + gGL.popMatrix(); - + return TRUE; } @@ -3699,7 +3797,7 @@ void LLModelPreview::refresh() void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians) { mCameraYaw = mCameraYaw + yaw_radians; - + mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f); } @@ -3709,7 +3807,7 @@ void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians) void LLModelPreview::zoom(F32 zoom_amt) { F32 new_zoom = mCameraZoom+zoom_amt; - + mCameraZoom = llclamp(new_zoom, 1.f, 10.f); } @@ -3757,17 +3855,17 @@ void LLFloaterModelPreview::onBrowseLowestLOD(void* data) void LLFloaterModelPreview::onUpload(void* user_data) { LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data; - + if (mp->mDecompFloater) { mp->mDecompFloater->closeFloater(); } - + mp->mModelPreview->rebuildUploadData(); - + gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, - mp->childGetValue("upload_textures").asBoolean(), mp->childGetValue("upload_skin"), mp->childGetValue("upload_joints")); - + mp->childGetValue("upload_textures").asBoolean(), mp->childGetValue("upload_skin"), mp->childGetValue("upload_joints")); + mp->closeFloater(false); } @@ -3818,15 +3916,15 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL mContinue = 1; mModel = mdl; 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) { @@ -3835,17 +3933,17 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL { 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; } } @@ -3874,4 +3972,3 @@ void LLFloaterModelPreview::DecompRequest::completed() } } - diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index e58596449b..65d46e5891 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -46,6 +46,8 @@ class LLFloaterModelPreview; class daeElement; class domProfile_COMMON; class domInstance_geometry; +class domNode; +class domTranslate; class LLPhysicsDecompFloater : public LLFloater { @@ -103,6 +105,11 @@ public: LLColor4 getDaeColor(daeElement* element); daeElement* getChildFromElement( daeElement* pElement, std::string const & name ); + bool isNodeAJoint( domNode* pNode ); + void processJointNode( domNode* pNode, std::map& jointTransforms ); + void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ); + void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ); + //map of avatar joints as named in COLLADA assets to internal joint names std::map mJointMap; -- cgit v1.2.3 From 29852bc012afbed303159b895ae8dc9448500ca5 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 17 Nov 2010 15:01:41 -0500 Subject: SH-476 FIX. Map tiles were failing when numeric addrs were substituted in amazon S3 image queries --- indra/newview/llmeshrepository.cpp | 54 +++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 24 deletions(-) mode change 100644 => 100755 indra/newview/llmeshrepository.cpp (limited to 'indra') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp old mode 100644 new mode 100755 index 94ed2697c5..b26f2dd0de --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -105,36 +105,42 @@ U32 get_volume_memory_size(const LLVolume* volume) std::string scrub_host_name(std::string http_url) { //curl loves to abuse the DNS cache, so scrub host names out of urls where trivial to prevent DNS timeouts + + if (http_url.empty()) + { + return http_url; + } + // Not safe to scrub amazon paths + if (http_url.find("s3.amazonaws.com") != std::string::npos) + { + return http_url; + } + std::string::size_type begin_host = http_url.find("://")+3; + std::string host_string = http_url.substr(begin_host); - if (!http_url.empty()) + std::string::size_type end_host = host_string.find(":"); + if (end_host == std::string::npos) { - std::string::size_type begin_host = http_url.find("://")+3; - std::string host_string = http_url.substr(begin_host); - - std::string::size_type end_host = host_string.find(":"); - if (end_host == std::string::npos) - { - end_host = host_string.find("/"); - } - - host_string = host_string.substr(0, end_host); + end_host = host_string.find("/"); + } + + host_string = host_string.substr(0, end_host); + + std::string::size_type idx = http_url.find(host_string); + + hostent* ent = gethostbyname(host_string.c_str()); + + if (ent && ent->h_length > 0) + { + U8* addr = (U8*) ent->h_addr_list[0]; - std::string::size_type idx = http_url.find(host_string); - - hostent* ent = gethostbyname(host_string.c_str()); - - if (ent && ent->h_length > 0) + std::string ip_string = llformat("%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); + if (!ip_string.empty() && !host_string.empty() && idx != std::string::npos) { - U8* addr = (U8*) ent->h_addr_list[0]; - - std::string ip_string = llformat("%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); - if (!ip_string.empty() && !host_string.empty() && idx != std::string::npos) - { - http_url.replace(idx, host_string.length(), ip_string); - } + http_url.replace(idx, host_string.length(), ip_string); } } - + return http_url; } -- cgit v1.2.3 From 48e2ec0340272efcb5caa7c5affaabfbf8d69c78 Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Wed, 17 Nov 2010 20:04:30 -0500 Subject: SH-480 FIX meshes are not added to objects folder on upload curl host scrubbing was causing object creation for mesh prims to fail. Commenting out the offending lines so we can have a functional release. Will file a separate bug for Vir to investigate when/if we can re-enable host scrubbing on these URLs for a future release. Approach approved by davep. --- indra/newview/llmeshrepository.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index f00a8565f7..1313033f4e 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1409,8 +1409,8 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, mUploadObjectAssetCapability = gAgent.getRegion()->getCapability("UploadObjectAsset"); mNewInventoryCapability = gAgent.getRegion()->getCapability("NewFileAgentInventoryVariablePrice"); - mUploadObjectAssetCapability = scrub_host_name(mUploadObjectAssetCapability); - mNewInventoryCapability = scrub_host_name(mNewInventoryCapability); + //mUploadObjectAssetCapability = scrub_host_name(mUploadObjectAssetCapability); + //mNewInventoryCapability = scrub_host_name(mNewInventoryCapability); mOrigin += gAgent.getAtAxis() * scale.magVec(); } -- cgit v1.2.3