Merge branch 'master' of D:/Dev/phoenix-firestorm-mesh-upload

master
Ansariel 2020-04-23 18:29:50 +02:00
commit 10552d2459
20 changed files with 1087 additions and 354 deletions

View File

@ -429,7 +429,7 @@ void showJointScaleOverrides( const LLJoint& joint, const std::string& note, con
bool LLJoint::aboveJointPosThreshold(const LLVector3& pos) const
{
LLVector3 diff = pos - getDefaultPosition();
const F32 max_joint_pos_offset = 0.0001f; // 0.1 mm
const F32 max_joint_pos_offset = LL_JOINT_TRESHOLD_POS_OFFSET; // 0.1 mm
return diff.lengthSquared() > max_joint_pos_offset * max_joint_pos_offset;
}
@ -532,7 +532,7 @@ void LLJoint::clearAttachmentPosOverrides()
// getAllAttachmentPosOverrides()
//--------------------------------------------------------------------
void LLJoint::getAllAttachmentPosOverrides(S32& num_pos_overrides,
std::set<LLVector3>& distinct_pos_overrides)
std::set<LLVector3>& distinct_pos_overrides) const
{
num_pos_overrides = m_attachmentPosOverrides.count();
LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin();
@ -546,7 +546,7 @@ void LLJoint::getAllAttachmentPosOverrides(S32& num_pos_overrides,
// getAllAttachmentScaleOverrides()
//--------------------------------------------------------------------
void LLJoint::getAllAttachmentScaleOverrides(S32& num_scale_overrides,
std::set<LLVector3>& distinct_scale_overrides)
std::set<LLVector3>& distinct_scale_overrides) const
{
num_scale_overrides = m_attachmentScaleOverrides.count();
LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin();

View File

@ -79,6 +79,8 @@ const U32 LL_FACE_JOINT_NUM = (LL_CHARACTER_MAX_ANIMATED_JOINTS-2);
const S32 LL_CHARACTER_MAX_PRIORITY = 7;
const F32 LL_MAX_PELVIS_OFFSET = 5.f;
const F32 LL_JOINT_TRESHOLD_POS_OFFSET = 0.0001f; //0.1 mm
class LLVector3OverrideMap
{
public:
@ -313,9 +315,9 @@ public:
void showAttachmentScaleOverrides(const std::string& av_info) const;
void getAllAttachmentPosOverrides(S32& num_pos_overrides,
std::set<LLVector3>& distinct_pos_overrides);
std::set<LLVector3>& distinct_pos_overrides) const;
void getAllAttachmentScaleOverrides(S32& num_scale_overrides,
std::set<LLVector3>& distinct_scale_overrides);
std::set<LLVector3>& distinct_scale_overrides) const;
// These are used in checks of whether a pos/scale override is considered significant.
bool aboveJointPosThreshold(const LLVector3& pos) const;

View File

@ -139,7 +139,7 @@ LLModelLoader::LLModelLoader(
, mStateCallback(state_cb)
, mOpaqueData(opaque_userdata)
, mRigValidJointUpload(true)
, mLegacyRigValid(true)
, mLegacyRigFlags(0)
, mNoNormalize(false)
, mNoOptimize(false)
, mCacheOnlyHitIfRigged(false)
@ -148,6 +148,7 @@ LLModelLoader::LLModelLoader(
{
assert_main_thread();
sActiveLoaderList.push_back(this) ;
mWarningsArray = LLSD::emptyArray();
}
LLModelLoader::~LLModelLoader()
@ -158,6 +159,7 @@ LLModelLoader::~LLModelLoader()
void LLModelLoader::run()
{
mWarningsArray.clear();
doLoadModel();
doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this));
}
@ -402,7 +404,7 @@ void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::st
//2. It is suitable for upload as standard av with just skin weights
bool isJointPositionUploadOK = isRigSuitableForJointPositionUpload( jointListFromAsset );
bool isRigLegacyOK = isRigLegacy( jointListFromAsset );
U32 legacy_rig_flags = determineRigLegacyFlags( jointListFromAsset );
// It's OK that both could end up being true.
@ -416,19 +418,16 @@ void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::st
setRigValidForJointPositionUpload( false );
}
if ( !isRigLegacyOK)
{
// This starts out true, becomes false if false for any loaded
// mesh.
setLegacyRigValid( false );
}
legacy_rig_flags |= getLegacyRigFlags();
// This starts as 0, changes if any loaded mesh has issues
setLegacyRigFlags(legacy_rig_flags);
}
//-----------------------------------------------------------------------------
// isRigLegacy()
// determineRigLegacyFlags()
//-----------------------------------------------------------------------------
bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAsset )
U32 LLModelLoader::determineRigLegacyFlags( const std::vector<std::string> &jointListFromAsset )
{
//No joints in asset
if ( jointListFromAsset.size() == 0 )
@ -441,7 +440,12 @@ bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAs
{
LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL;
LL_WARNS() << "Skinning disabled due to too many joints" << LL_ENDL;
return false;
LLSD args;
args["Message"] = "TooManyJoint";
args["[JOINTS]"] = LLSD::Integer(jointListFromAsset.size());
args["[MAX]"] = LLSD::Integer(mMaxJointsPerMesh);
mWarningsArray.append(args);
return LEGACY_RIG_FLAG_TOO_MANY_JOINTS;
}
// Unknown joints in asset
@ -452,16 +456,24 @@ bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAs
if (mJointMap.find(*it)==mJointMap.end())
{
LL_WARNS() << "Rigged to unrecognized joint name " << *it << LL_ENDL;
LLSD args;
args["Message"] = "UnrecognizedJoint";
args["[NAME]"] = *it;
mWarningsArray.append(args);
unknown_joint_count++;
}
}
if (unknown_joint_count>0)
{
LL_WARNS() << "Skinning disabled due to unknown joints" << LL_ENDL;
return false;
LLSD args;
args["Message"] = "UnknownJoints";
args["[COUNT]"] = LLSD::Integer(unknown_joint_count);
mWarningsArray.append(args);
return LEGACY_RIG_FLAG_UNKNOWN_JOINT;
}
return true;
return LEGACY_RIG_OK;
}
//-----------------------------------------------------------------------------
// isRigSuitableForJointPositionUpload()

View File

@ -42,6 +42,10 @@ typedef std::deque<std::string> JointNameSet;
const S32 SLM_SUPPORTED_VERSION = 3;
const S32 NUM_LOD = 4;
const U32 LEGACY_RIG_OK = 0;
const U32 LEGACY_RIG_FLAG_TOO_MANY_JOINTS = 1;
const U32 LEGACY_RIG_FLAG_UNKNOWN_JOINT = 2;
class LLModelLoader : public LLThread
{
public:
@ -166,7 +170,7 @@ public:
void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset );
//Determines if a rig is a legacy from the joint list
bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );
U32 determineRigLegacyFlags( const std::vector<std::string> &jointListFromAsset );
//Determines if a rig is suitable for upload
bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset );
@ -174,8 +178,9 @@ public:
const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
const bool isLegacyRigValid( void ) const { return mLegacyRigValid; }
void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }
const bool isLegacyRigValid(void) const { return mLegacyRigFlags == 0; }
U32 getLegacyRigFlags() const { return mLegacyRigFlags; }
void setLegacyRigFlags( U32 rigFlags ) { mLegacyRigFlags = rigFlags; }
//-----------------------------------------------------------------------------
// isNodeAJoint()
@ -185,6 +190,9 @@ public:
return name != NULL && mJointMap.find(name) != mJointMap.end();
}
const LLSD logOut() const { return mWarningsArray; }
void clearLog() { mWarningsArray.clear(); }
protected:
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
std::vector< std::string > toStringVector( std::vector< JointKey > const &aIn ) const
@ -205,13 +213,15 @@ protected:
void* mOpaqueData;
bool mRigValidJointUpload;
bool mLegacyRigValid;
U32 mLegacyRigFlags;
bool mNoNormalize;
bool mNoOptimize;
JointTransformMap mJointTransformMap;
LLSD mWarningsArray; // preview floater will pull logs from here
static std::list<LLModelLoader*> sActiveLoaderList;
static bool isAlive(LLModelLoader* loader) ;
};

View File

@ -770,6 +770,11 @@ void LLButton::draw()
{
glow_color = highlighting_color;
}
else
{
// will fade from highlight color
glow_color = flash_color;
}
}
}

View File

@ -207,6 +207,7 @@ public:
void setFlashing( bool b, bool force_flashing = false );
BOOL getFlashing() const { return mFlashing; }
LLFlashTimer* getFlashTimer() {return mFlashingTimer;}
void setFlashColor(const LLUIColor &color) { mFlashBgColor = color; };
void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
LLFontGL::HAlign getHAlign() const { return mHAlign; }

View File

@ -136,6 +136,7 @@ LLScrollListCtrl::Params::Params()
primary_sort_only("primary_sort_only", false), // <FS:Ansariel> Option to only sort by one column
mouse_wheel_opaque("mouse_wheel_opaque", false),
commit_on_keyboard_movement("commit_on_keyboard_movement", true),
commit_on_selection_change("commit_on_selection_change", false),
heading_height("heading_height"),
page_lines("page_lines", 0),
background_visible("background_visible"),
@ -166,7 +167,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mMaxSelectable(0),
mAllowKeyboardMovement(true),
mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
mCommitOnSelectionChange(false),
mCommitOnSelectionChange(p.commit_on_selection_change),
mSelectionChanged(false),
mNeedsScroll(false),
mCanSelect(true),

View File

@ -97,6 +97,7 @@ public:
// behavioral flags
Optional<bool> multi_select,
commit_on_keyboard_movement,
commit_on_selection_change,
mouse_wheel_opaque;
// display flags

View File

@ -39,7 +39,6 @@
#include "llfloater.h"
#include "lltrans.h"
//----------------------------------------------------------------------------
// Implementation Notes:
@ -224,6 +223,7 @@ LLTabContainer::Params::Params()
last_tab("last_tab"),
use_custom_icon_ctrl("use_custom_icon_ctrl", false),
open_tabs_on_drag_and_drop("open_tabs_on_drag_and_drop", false),
enable_tabs_flashing("enable_tabs_flashing", false),
tab_icon_ctrl_pad("tab_icon_ctrl_pad", 0),
use_ellipses("use_ellipses"),
label_shadow("label_shadow",false), // no drop shadowed labels by default -Zi
@ -269,6 +269,7 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
mOpenTabsOnDragAndDrop(p.open_tabs_on_drag_and_drop),
mTabIconCtrlPad(p.tab_icon_ctrl_pad),
mUseTabEllipses(p.use_ellipses),
mEnableTabsFlashing(p.enable_tabs_flashing),
mDropShadowedText(p.label_shadow) // support for drop shadowed tab labels -Zi
{
// AO: Treat the IM tab container specially
@ -1248,6 +1249,9 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
p.pad_right(2);
}
// inits flash timer
p.button_flash_enable = mEnableTabsFlashing;
// <FS:Ansariel> Enable tab flashing
p.button_flash_enable(LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableButtonFlashing"));
p.button_flash_count(LLUI::getInstance()->mSettingGroups["config"]->getS32("FlashCount"));
@ -1803,6 +1807,16 @@ void LLTabContainer::setTabPanelFlashing(LLPanel* child, BOOL state )
}
}
void LLTabContainer::setTabPanelFlashing(LLPanel* child, BOOL state, LLUIColor color)
{
LLTabTuple* tuple = getTabByPanel(child);
if (tuple)
{
tuple->mButton->setFlashColor(color);
tuple->mButton->setFlashing(state);
}
}
void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const LLColor4& color)
{
LLTabTuple* tuple = getTabByPanel(child);

View File

@ -123,6 +123,11 @@ public:
* Open tabs on hover in drag and drop situations
*/
Optional<bool> open_tabs_on_drag_and_drop;
/**
* Enable tab flashing
*/
Optional<bool> enable_tabs_flashing;
/**
* Paddings for LLIconCtrl in case of LLCustomButtonIconCtrl usage(use_custom_icon_ctrl = true)
@ -215,6 +220,7 @@ public:
BOOL getTabPanelFlashing(LLPanel* child);
void setTabPanelFlashing(LLPanel* child, BOOL state);
void setTabPanelFlashing(LLPanel* child, BOOL state, LLUIColor color);
void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white);
void setTabImage(LLPanel* child, const LLUUID& img_id, const LLColor4& color = LLColor4::white);
void setTabImage(LLPanel* child, LLIconCtrl* icon);
@ -343,6 +349,7 @@ private:
bool mCustomIconCtrlUsed;
bool mOpenTabsOnDragAndDrop;
bool mEnableTabsFlashing;
S32 mTabIconCtrlPad;
bool mUseTabEllipses;
};

View File

@ -2426,6 +2426,18 @@ void LLTextBase::needsReflow(S32 index)
// [/SL:KB]
}
S32 LLTextBase::removeFirstLine()
{
if (!mLineInfoList.empty())
{
S32 length = getLineEnd(0);
deselect();
removeStringNoUndo(0, length);
return length;
}
return 0;
}
void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params)
{
segment_vec_t segments;

View File

@ -435,8 +435,7 @@ public:
virtual void setText(const LLStringExplicit &utf8str , const LLStyle::Params& input_params = LLStyle::Params()); // uses default style
virtual std::string getText() const;
void setMaxTextLength(S32 length) { mMaxTextByteLength = length; }
// <FS:Ansariel> Getter for mMaxTextByteLength
S32 getMaxTextLength() const { return mMaxTextByteLength; }
S32 getMaxTextLength() { return mMaxTextByteLength; }
// wide-char versions
void setWText(const LLWString& text);
@ -465,6 +464,7 @@ public:
S32 getLength() const { return getWText().length(); }
S32 getLineCount() const { return mLineInfoList.size(); }
S32 removeFirstLine(); // returns removed length
void addDocumentChild(LLView* view);
void removeDocumentChild(LLView* view);

View File

@ -75,6 +75,7 @@
#include "llsdserialize.h"
#include "llsliderctrl.h"
#include "llspinctrl.h"
#include "lltabcontainer.h"
#include "lltoggleablemenu.h"
#include "lltrans.h"
#include "llvfile.h"
@ -82,6 +83,7 @@
#include "llcallbacklist.h"
#include "llviewerobjectlist.h"
#include "llanimationstates.h"
#include "llviewertexteditor.h"
#include "llviewernetwork.h"
#include "llviewershadermgr.h"
// <AW: opensim-limits>
@ -110,6 +112,8 @@ const double RETAIN_COEFFICIENT = 100;
// So this const is used as a size of Smooth combobox list.
const S32 SMOOTH_VALUES_NUMBER = 10;
const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f;
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
@ -266,7 +270,10 @@ void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LL
LLFloaterModelPreview::LLFloaterModelPreview(const LLSD& key) :
LLFloaterModelUploadBase(key),
mUploadBtn(NULL),
mCalculateBtn(NULL)
mCalculateBtn(NULL),
mUploadLogText(NULL),
mTabContainer(NULL),
mAvatarTabIndex(0)
{
sInstance = this;
mLastMouseX = 0;
@ -335,7 +342,8 @@ BOOL LLFloaterModelPreview::postBuild()
getChild<LLCheckBoxCtrl>("show_edges")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_physics")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_textures")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_skin_weight")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_skin_weight")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onShowSkinWeightChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_joint_overrides")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_joint_positions")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_uv_guide")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); // <FS:Beq> - Add UV guide overlay to pmesh preview
@ -343,6 +351,13 @@ BOOL LLFloaterModelPreview::postBuild()
childDisable("upload_joints");
childDisable("lock_scale_if_joint_position");
childSetVisible("skin_too_many_joints", false);
childSetVisible("skin_unknown_joint", false);
childSetVisible("warning_title", false);
childSetVisible("warning_message", false);
childSetVisible("status", false);
initDecompControls();
LLView* preview_panel = getChild<LLView>("preview_panel");
@ -432,6 +447,12 @@ BOOL LLFloaterModelPreview::postBuild()
mUploadBtn = getChild<LLButton>("ok_btn");
mCalculateBtn = getChild<LLButton>("calculate_btn");
mUploadLogText = getChild<LLViewerTextEditor>("log_text");
mTabContainer = getChild<LLTabContainer>("import_tab");
LLPanel *panel = mTabContainer->getPanelByName("avatar_panel");
mAvatarTabIndex = mTabContainer->getIndexForPanel(panel);
panel->getChild<LLScrollListCtrl>("joints_list")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onJointListSelection, this));
if (LLConvexDecomposition::getInstance() != NULL)
{
@ -501,6 +522,15 @@ void LLFloaterModelPreview::onUploadOptionChecked(LLUICtrl* ctrl)
toggleCalculateButton(true);
}
void LLFloaterModelPreview::onShowSkinWeightChecked(LLUICtrl* ctrl)
{
if (mModelPreview)
{
mModelPreview->mCameraOffset.clearVec();
onViewOptionChecked(ctrl);
}
}
void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
{
if (mModelPreview)
@ -585,6 +615,8 @@ void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, boo
void LLFloaterModelPreview::onClickCalculateBtn()
{
clearLogTab();
mModelPreview->rebuildUploadData();
bool upload_skinweights = childGetValue("upload_skin").asBoolean();
@ -611,6 +643,82 @@ void LLFloaterModelPreview::onClickCalculateBtn()
mUploadBtn->setEnabled(false);
}
void populate_list_with_map(LLScrollListCtrl *list, const std::map<std::string, LLVector3> &vector_map)
{
if (vector_map.empty())
{
return;
}
S32 count = 0;
LLScrollListCell::Params cell_params;
cell_params.font = LLFontGL::getFontSansSerif();
// Start out right justifying numeric displays
cell_params.font_halign = LLFontGL::HCENTER;
std::map<std::string, LLVector3>::const_iterator iter = vector_map.begin();
std::map<std::string, LLVector3>::const_iterator end = vector_map.end();
while (iter != end)
{
LLScrollListItem::Params item_params;
item_params.value = LLSD::Integer(count);
cell_params.column = "model_name";
cell_params.value = iter->first;
item_params.columns.add(cell_params);
cell_params.column = "axis_x";
cell_params.value = iter->second.mV[VX];
item_params.columns.add(cell_params);
cell_params.column = "axis_y";
cell_params.value = iter->second.mV[VY];
item_params.columns.add(cell_params);
cell_params.column = "axis_z";
cell_params.value = iter->second.mV[VZ];
item_params.columns.add(cell_params);
list->addRow(item_params);
count++;
iter++;
}
}
void LLFloaterModelPreview::onJointListSelection()
{
S32 display_lod = mModelPreview->mPreviewLOD;
LLPanel *panel = mTabContainer->getPanelByName("avatar_panel");
LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
LLScrollListCtrl *joints_pos = panel->getChild<LLScrollListCtrl>("pos_overrides_list");
LLScrollListCtrl *joints_scale = panel->getChild<LLScrollListCtrl>("scale_overrides_list");
LLTextBox *joint_pos_descr = panel->getChild<LLTextBox>("pos_overrides_descr");
joints_pos->deleteAllItems();
joints_scale->deleteAllItems();
LLScrollListItem *selected = joints_list->getFirstSelected();
if (selected)
{
std::string label = selected->getValue().asString();
LLJointOverrideData &data = mJointOverrides[display_lod][label];
populate_list_with_map(joints_pos, data.mPosOverrides);
joint_pos_descr->setTextArg("[JOINT]", label);
mSelectedJointName = label;
}
else
{
// temporary value (shouldn't happen)
std::string label = "mPelvis";
joint_pos_descr->setTextArg("[JOINT]", label);
mSelectedJointName.clear();
}
// Note: We can make a version of renderBones() to highlight selected joint
}
void LLFloaterModelPreview::onDescriptionKeystroke(LLUICtrl* ctrl)
{
// Workaround for SL-4186, server doesn't allow name changes after 'calculate' stage
@ -762,7 +870,6 @@ void LLFloaterModelPreview::draw3dPreview()
gGL.getTexUnit(0)->bind(mModelPreview);
LLView* preview_panel = getChild<LLView>("preview_panel");
if (!preview_panel)
@ -1383,6 +1490,215 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl
gViewerWindow->showCursor();
}
//-----------------------------------------------------------------------------
// addStringToLog()
//-----------------------------------------------------------------------------
//static
void LLFloaterModelPreview::addStringToLog(const std::string& message, const LLSD& args, bool flash, S32 lod)
{
if (sInstance && sInstance->hasString(message))
{
std::string str;
switch (lod)
{
case LLModel::LOD_IMPOSTOR: str = "LOD0 "; break;
case LLModel::LOD_LOW: str = "LOD1 "; break;
case LLModel::LOD_MEDIUM: str = "LOD2 "; break;
case LLModel::LOD_PHYSICS: str = "PHYS "; break;
case LLModel::LOD_HIGH: str = "LOD3 "; break;
default: break;
}
LLStringUtil::format_map_t args_msg;
LLSD::map_const_iterator iter = args.beginMap();
LLSD::map_const_iterator end = args.endMap();
for (; iter != end; ++iter)
{
args_msg[iter->first] = iter->second.asString();
}
str += sInstance->getString(message, args_msg);
sInstance->addStringToLogTab(str, flash);
}
}
// static
void LLFloaterModelPreview::addStringToLog(const std::string& str, bool flash)
{
if (sInstance)
{
sInstance->addStringToLogTab(str, flash);
}
}
// static
void LLFloaterModelPreview::addStringToLog(const std::ostringstream& strm, bool flash)
{
if (sInstance)
{
sInstance->addStringToLogTab(strm.str(), flash);
}
}
void LLFloaterModelPreview::clearAvatarTab()
{
LLPanel *panel = mTabContainer->getPanelByName("avatar_panel");
LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
joints_list->deleteAllItems();
LLScrollListCtrl *joints_pos = panel->getChild<LLScrollListCtrl>("pos_overrides_list");
joints_pos->deleteAllItems(); mSelectedJointName.clear();
for (U32 i = 0; i < LLModel::NUM_LODS; ++i)
{
mJointOverrides[i].clear();
}
LLTextBox *joint_total_descr = panel->getChild<LLTextBox>("conflicts_description");
joint_total_descr->setTextArg("[CONFLICTS]", llformat("%d", 0));
joint_total_descr->setTextArg("[JOINTS_COUNT]", llformat("%d", 0));
LLTextBox *joint_pos_descr = panel->getChild<LLTextBox>("pos_overrides_descr");
joint_pos_descr->setTextArg("[JOINT]", std::string("mPelvis")); // Might be better to hide it
}
void LLFloaterModelPreview::updateAvatarTab()
{
S32 display_lod = mModelPreview->mPreviewLOD;
if (mModelPreview->mModel[display_lod].empty())
{
mSelectedJointName.clear();
return;
}
// Joints will be listed as long as they are listed in mAlternateBindMatrix
// even if they are for some reason identical to defaults.
// Todo: Are overrides always identical for all lods? They normally are, but there might be situations where they aren't.
if (mJointOverrides[display_lod].empty())
{
// populate map
for (LLModelLoader::scene::iterator iter = mModelPreview->mScene[display_lod].begin(); iter != mModelPreview->mScene[display_lod].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;
const LLMeshSkinInfo *skin = &model->mSkinInfo;
if (skin->mAlternateBindMatrix.size() > 0)
{
U32 count = LLSkinningUtil::getMeshJointCount(skin);
for (U32 j = 0; j < count; ++j)
{
const LLVector3& jointPos = skin->mAlternateBindMatrix[j].getTranslation();
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j].mName];
if (data.mPosOverrides.size() > 0
&& (data.mPosOverrides.begin()->second - jointPos).lengthSquared() > (LL_JOINT_TRESHOLD_POS_OFFSET * LL_JOINT_TRESHOLD_POS_OFFSET))
{
// File contains multiple meshes with conflicting joint offsets
// preview may be incorrect, upload result might wary (depends onto
// mesh_id that hasn't been generated yet).
data.mHasConflicts = true;
}
data.mPosOverrides[model->getName()] = jointPos;
}
}
}
}
}
LLPanel *panel = mTabContainer->getPanelByName("avatar_panel");
LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
if (joints_list->isEmpty())
{
// Populate table
std::map<std::string, std::string> joint_alias_map;
mModelPreview->getJointAliases(joint_alias_map);
S32 conflicts = 0;
joint_override_data_map_t::iterator joint_iter = mJointOverrides[display_lod].begin();
joint_override_data_map_t::iterator joint_end = mJointOverrides[display_lod].end();
while (joint_iter != joint_end)
{
const std::string& listName = joint_iter->first;
LLScrollListItem::Params item_params;
item_params.value(listName);
LLScrollListCell::Params cell_params;
cell_params.font = LLFontGL::getFontSansSerif();
cell_params.value = listName;
if (joint_alias_map.find(listName) == joint_alias_map.end())
{
// Missing names
cell_params.color = LLColor4::red;
}
if (joint_iter->second.mHasConflicts)
{
// Conflicts
cell_params.color = LLColor4::orange;
conflicts++;
}
item_params.columns.add(cell_params);
joints_list->addRow(item_params, ADD_BOTTOM);
joint_iter++;
}
joints_list->selectFirstItem();
LLScrollListItem *selected = joints_list->getFirstSelected();
if (selected)
{
mSelectedJointName = selected->getValue().asString();
}
LLTextBox *joint_conf_descr = panel->getChild<LLTextBox>("conflicts_description");
joint_conf_descr->setTextArg("[CONFLICTS]", llformat("%d", conflicts));
joint_conf_descr->setTextArg("[JOINTS_COUNT]", llformat("%d", mJointOverrides[display_lod].size()));
}
}
//-----------------------------------------------------------------------------
// addStringToLogTab()
//-----------------------------------------------------------------------------
void LLFloaterModelPreview::addStringToLogTab(const std::string& str, bool flash)
{
if (str.empty())
{
return;
}
LLWString text = utf8str_to_wstring(str);
S32 add_text_len = text.length() + 1; // newline
S32 editor_max_len = mUploadLogText->getMaxTextLength();
if (add_text_len > editor_max_len)
{
return;
}
LLPanel* panel = mTabContainer->getPanelByName("logs_panel");
// Make sure we have space for new string
S32 editor_text_len = mUploadLogText->getLength();
while (editor_max_len < (editor_text_len + add_text_len))
{
editor_text_len -= mUploadLogText->removeFirstLine();
}
mUploadLogText->appendText(str, true);
if (flash && mTabContainer->getCurrentPanel() != panel)
{
// This will makes colors pale due to "glow_type = LLRender::BT_ALPHA"
// So instead of using "MenuItemFlashBgColor" added stronger color
static LLUIColor sFlashBgColor(LLColor4U(255, 99, 0));
mTabContainer->setTabPanelFlashing(panel, true, sFlashBgColor);
}
}
//-----------------------------------------------------------------------------
// LLModelPreview
//-----------------------------------------------------------------------------
@ -1392,7 +1708,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
, mLodsQuery()
, mLodsWithParsingError()
, mPelvisZOffset( 0.0f )
, mLegacyRigValid( false )
, mLegacyRigFlags( U32_MAX )
, mRigValidJointUpload( false )
, mPhysicsSearchLOD( LLModel::LOD_PHYSICS )
, mResetJoints( false )
@ -1824,8 +2140,14 @@ void LLModelPreview::rebuildUploadData()
LLQuaternion identity;
if (!bind_rot.isEqualEps(identity,0.01f))
{
LL_WARNS() << "non-identity bind shape rot. mat is " << high_lod_model->mSkinInfo.mBindShapeMatrix
<< " bind_rot " << bind_rot << LL_ENDL;
std::ostringstream out;
out << "non-identity bind shape rot. mat is ";
out << high_lod_model->mSkinInfo.mBindShapeMatrix;
out << " bind_rot ";
out << bind_rot;
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
setLoadState( LLModelLoader::WARNING_BIND_SHAPE_ORIENTATION );
}
}
@ -2000,7 +2322,11 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
if (lod < LLModel::LOD_IMPOSTOR || lod > LLModel::NUM_LODS - 1)
{
LL_WARNS() << "Invalid level of detail: " << lod << LL_ENDL;
std::ostringstream out;
out << "Invalid level of detail: ";
out << lod;
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, true);
assert(lod >= LLModel::LOD_IMPOSTOR && lod < LLModel::NUM_LODS);
return;
}
@ -2187,7 +2513,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
// Copy determinations about rig so UI will reflect them
//
setRigValidForJointPositionUpload(mModelLoader->isRigValidForJointPositionUpload());
setLegacyRigValid(mModelLoader->isLegacyRigValid());
setLegacyRigFlags(mModelLoader->getLegacyRigFlags());
mModelLoader->loadTextures() ;
@ -2197,7 +2523,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
mBaseScene.clear();
bool skin_weights = false;
bool joint_positions = false;
bool joint_overrides = false;
bool lock_scale_if_joint_position = false;
for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
@ -2244,7 +2570,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
if (!list_iter->mModel->mSkinInfo.mAlternateBindMatrix.empty())
{
joint_positions = true;
joint_overrides = true;
}
if (list_iter->mModel->mSkinInfo.mLockScaleIfJointPosition)
{
@ -2267,12 +2593,18 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
fmp->childSetValue("upload_skin", true);
}
if (joint_positions)
{
if (joint_overrides)
{
fmp->enableViewOption("show_joint_overrides");
mViewOption["show_joint_overrides"] = true;
fmp->enableViewOption("show_joint_positions");
mViewOption["show_joint_positions"] = true;
fmp->childSetValue("upload_joints", true);
}
else
{
fmp->clearAvatarTab();
}
if (lock_scale_if_joint_position)
{
@ -2377,7 +2709,12 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
if (importerDebug)
{
LL_WARNS() << "Loded model name " << mModel[loaded_lod][idx]->mLabel << " for LOD " << loaded_lod << " doesn't match the base model. Renaming to " << name << LL_ENDL;
std::ostringstream out;
out << "Loded model name " << mModel[loaded_lod][idx]->mLabel;
out << " for LOD " << loaded_lod;
out << " doesn't match the base model. Renaming to " << name;
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
}
mModel[loaded_lod][idx]->mLabel = name;
@ -2401,7 +2738,6 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
mLoading = false;
if (mFMP)
{
mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->set(FALSE);
if (!mBaseModel.empty())
{
const std::string& model_name = mBaseModel[0]->getName();
@ -2410,6 +2746,10 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
{
description_form->setText(model_name);
}
// Add info to log that loading is complete (purpose: separator between loading and other logs)
LLSD args;
args["MODEL_NAME"] = model_name; // Teoretically shouldn't be empty, but might be better idea to add filename here
LLFloaterModelPreview::addStringToLog("ModelLoaded", args, false, loaded_lod);
}
}
refresh();
@ -2535,7 +2875,10 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
// Allow LoD from -1 to LLModel::LOD_PHYSICS
if (which_lod < -1 || which_lod > LLModel::NUM_LODS - 1)
{
LL_WARNS() << "Invalid level of detail: " << which_lod << LL_ENDL;
std::ostringstream out;
out << "Invalid level of detail: " << which_lod;
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
assert(which_lod >= -1 && which_lod < LLModel::NUM_LODS);
return;
}
@ -3595,7 +3938,10 @@ void LLModelPreview::updateLodControls(S32 lod)
{
if (lod < LLModel::LOD_IMPOSTOR || lod > LLModel::LOD_HIGH)
{
LL_WARNS() << "Invalid level of detail: " << lod << LL_ENDL;
std::ostringstream out;
out << "Invalid level of detail: " << lod;
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
assert(lod >= LLModel::LOD_IMPOSTOR && lod <= LLModel::LOD_HIGH);
return;
}
@ -3791,9 +4137,12 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
if (!vb->allocateBuffer(num_vertices, num_indices, TRUE))
{
// We are likely to crash due this failure, if this happens, find a way to gracefully stop preview
LL_WARNS() << "Failed to allocate Vertex Buffer for model preview "
<< num_vertices << " vertices and "
<< num_indices << " indices" << LL_ENDL;
std::ostringstream out;
out << "Failed to allocate Vertex Buffer for model preview ";
out << num_vertices << " vertices and ";
out << num_indices << " indices";
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, true);
}
LLStrider<LLVector3> vertex_strider;
@ -3945,8 +4294,21 @@ void LLModelPreview::loadedCallback(
LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
if (pPreview && !LLModelPreview::sIgnoreLoadedCallback)
{
pPreview->loadModelCallback(lod);
}
// Load loader's warnings into floater's log tab
const LLSD out = pPreview->mModelLoader->logOut();
LLSD::array_const_iterator iter_out = out.beginArray();
LLSD::array_const_iterator end_out = out.endArray();
for (; iter_out != end_out; ++iter_out)
{
if (iter_out->has("Message"))
{
LLFloaterModelPreview::addStringToLog(iter_out->get("Message"), *iter_out, true, pPreview->mModelLoader->mLod);
}
}
pPreview->mModelLoader->clearLog();
pPreview->loadModelCallback(lod); // removes mModelLoader in some cases
}
}
void LLModelPreview::stateChangedCallback(U32 state,void* opaque)
@ -4035,11 +4397,13 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget )
pTarget->setNumVolumeFaces( faceCnt+1 );
pTarget->setVolumeFaceData( faceCnt+1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices() );
}
}
//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
// Todo: we shouldn't be setting all those UI elements on render.
// Note: Render happens each frame with skinned avatars
BOOL LLModelPreview::render()
{
assert_main_thread();
@ -4050,6 +4414,7 @@ BOOL LLModelPreview::render()
bool use_shaders = LLGLSLShader::sNoFixedFunction;
bool edges = mViewOption["show_edges"];
bool joint_overrides = mViewOption["show_joint_overrides"];
bool joint_positions = mViewOption["show_joint_positions"];
bool skin_weight = mViewOption["show_skin_weight"];
bool textures = mViewOption["show_textures"];
@ -4136,13 +4501,26 @@ BOOL LLModelPreview::render()
if (has_skin_weights && lodsReady())
{ //model has skin weights, enable view options for skin weights and joint positions
if (fmp && isLegacyRigValid() )
{
fmp->enableViewOption("show_skin_weight");
fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
mFMP->childEnable("upload_skin");
mFMP->childSetValue("show_skin_weight", skin_weight);
}
U32 flags = getLegacyRigFlags();
if (fmp)
{
if (flags == LEGACY_RIG_OK)
{
fmp->enableViewOption("show_skin_weight");
fmp->setViewOptionEnabled("show_joint_overrides", skin_weight);
fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
mFMP->childEnable("upload_skin");
mFMP->childSetValue("show_skin_weight", skin_weight);
}
else if ((flags & LEGACY_RIG_FLAG_TOO_MANY_JOINTS) > 0)
{
mFMP->childSetVisible("skin_too_many_joints", true);
}
else if ((flags & LEGACY_RIG_FLAG_UNKNOWN_JOINT) > 0)
{
mFMP->childSetVisible("skin_unknown_joint", true);
}
}
}
else
{
@ -4151,6 +4529,7 @@ BOOL LLModelPreview::render()
{
mViewOption["show_skin_weight"] = false;
fmp->disableViewOption("show_skin_weight");
fmp->disableViewOption("show_joint_overrides");
fmp->disableViewOption("show_joint_positions");
skin_weight = false;
@ -4174,11 +4553,19 @@ BOOL LLModelPreview::render()
if (upload_skin && upload_joints)
{
mFMP->childEnable("lock_scale_if_joint_position");
if (fmp)
{
fmp->updateAvatarTab();
}
}
else
{
mFMP->childDisable("lock_scale_if_joint_position");
mFMP->childSetValue("lock_scale_if_joint_position", false);
if (fmp)
{
fmp->clearAvatarTab();
}
}
//Only enable joint offsets if it passed the earlier critiquing
@ -4209,10 +4596,9 @@ BOOL LLModelPreview::render()
if (skin_weight)
{
target_pos = getPreviewAvatar()->getPositionAgent();
target_pos = getPreviewAvatar()->getPositionAgent() + offset;
z_near = 0.01f;
z_far = 1024.f;
mCameraDistance = 16.f;
//render avatar previews every frame
refresh();
@ -4230,8 +4616,9 @@ BOOL LLModelPreview::render()
LLQuaternion(mCameraYaw, LLVector3::z_axis);
LLQuaternion av_rot = camera_rot;
F32 camera_distance = skin_weight ? SKIN_WEIGHT_CAMERA_DISTANCE : mCameraDistance;
LLViewerCamera::getInstance()->setOriginAndLookAt(
target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera
target_pos + ((LLVector3(camera_distance, 0.f, 0.f) + offset) * av_rot), // camera
LLVector3::z_axis, // up
target_pos); // point of interest
@ -4343,8 +4730,8 @@ BOOL LLModelPreview::render()
else
{
gGL.diffuseColor4fv(static_cast<LLColor4>(base_col).mV);
}
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.diffuseColor4fv(static_cast<LLColor4>(edge_col).mV);
@ -4572,9 +4959,14 @@ BOOL LLModelPreview::render()
else
{
target_pos = getPreviewAvatar()->getPositionAgent();
getPreviewAvatar()->clearAttachmentOverrides(); // removes pelvis fixup
LLUUID fake_mesh_id;
fake_mesh_id.generate();
getPreviewAvatar()->addPelvisFixup(mPelvisZOffset, fake_mesh_id);
bool pelvis_recalc = false;
LLViewerCamera::getInstance()->setOriginAndLookAt(
target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera
target_pos + ((LLVector3(camera_distance, 0.f, 0.f) + offset) * av_rot), // camera
LLVector3::z_axis, // up
target_pos); // point of interest
@ -4587,6 +4979,51 @@ BOOL LLModelPreview::render()
if (!model->mSkinWeights.empty())
{
const LLMeshSkinInfo *skin = &model->mSkinInfo;
LLSkinningUtil::initJointNums(&model->mSkinInfo, getPreviewAvatar());// inits skin->mJointNums if nessesary
U32 count = LLSkinningUtil::getMeshJointCount(skin);
if (joint_overrides && skin->mAlternateBindMatrix.size() > 0)
{
// mesh_id is used to determine which mesh gets to
// set the joint offset, in the event of a conflict. Since
// we don't know the mesh id yet, we can't guarantee that
// joint offsets will be applied with the same priority as
// in the uploaded model. If the file contains multiple
// meshes with conflicting joint offsets, preview may be
// incorrect.
LLUUID fake_mesh_id;
fake_mesh_id.generate();
for (U32 j = 0; j < count; ++j)
{
LLJoint *joint = getPreviewAvatar()->getJoint(skin->mJointNums[j]);
if (joint)
{
const LLVector3& jointPos = skin->mAlternateBindMatrix[j].getTranslation();
if (joint->aboveJointPosThreshold(jointPos))
{
bool override_changed;
joint->addAttachmentPosOverride(jointPos, fake_mesh_id, "model", override_changed);
if (override_changed)
{
//If joint is a pelvis then handle old/new pelvis to foot values
if (joint->getName() == "mPelvis")// or skin->mJointNames[j]
{
pelvis_recalc = true;
}
}
if (skin->mLockScaleIfJointPosition)
{
// Note that unlike positions, there's no threshold check here,
// just a lock at the default value.
joint->addAttachmentScaleOverride(joint->getDefaultScale(), fake_mesh_id, "model");
}
}
}
}
}
for (U32 i = 0, e = mVertexBuffer[mPreviewLOD][model].size(); i < e; ++i)
{
LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
@ -4604,16 +5041,14 @@ BOOL LLModelPreview::render()
//quick 'n dirty software vertex skinning
//build matrix palette
//<FS:Beq> use Mat4a part of the caching changes, no point in using the cache itself in the preview though.
//LLMatrix4 mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
const LLMeshSkinInfo *skin = &model->mSkinInfo;
U32 count = LLSkinningUtil::getMeshJointCount(skin);
//<FS:Beq> use Mat4a part of the caching changes, no point in using the cache itself in the preview though.
//LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count,
// skin, getPreviewAvatar());
LLSkinningUtil::initSkinningMatrixPalette(mat, count,
skin, getPreviewAvatar());
//</FS:Beq>
LLMatrix4a bind_shape_matrix;
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
U32 max_joints = LLSkinningUtil::getMaxJointCount();
@ -4691,13 +5126,25 @@ BOOL LLModelPreview::render()
gDebugProgram.bind();
}
getPreviewAvatar()->renderCollisionVolumes();
getPreviewAvatar()->renderBones();
if (fmp->mTabContainer->getCurrentPanelIndex() == fmp->mAvatarTabIndex)
{
getPreviewAvatar()->renderBones(fmp->mSelectedJointName);
}
else
{
getPreviewAvatar()->renderBones();
}
if (shader)
{
shader->bind();
}
}
if (pelvis_recalc)
{
// size/scale recalculation
getPreviewAvatar()->postPelvisSetRecalc();
}
}
}
@ -4742,8 +5189,10 @@ void LLModelPreview::zoom(F32 zoom_amt)
void LLModelPreview::pan(F32 right, F32 up)
{
mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
bool skin_weight = mViewOption["show_skin_weight"];
F32 camera_distance = skin_weight ? SKIN_WEIGHT_CAMERA_DISTANCE : mCameraDistance;
mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * camera_distance / mCameraZoom, -1.f, 1.f);
mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * camera_distance / mCameraZoom, -1.f, 1.f);
}
void LLModelPreview::setPreviewLOD(S32 lod)
@ -4758,14 +5207,6 @@ void LLModelPreview::setPreviewLOD(S32 lod)
combo_box->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
mFMP->childSetValue("lod_file_" + lod_name[mPreviewLOD], mLODFile[mPreviewLOD]);
// <FS:Ansariel> Doesn't exist as of 16-06-2017
//LLComboBox* combo_box2 = mFMP->getChild<LLComboBox>("preview_lod_combo2");
//combo_box2->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
//
//LLComboBox* combo_box3 = mFMP->getChild<LLComboBox>("preview_lod_combo3");
//combo_box3->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
// </FS:Ansariel>
LLColor4 highlight_color = LLUIColorTable::instance().getColor("MeshImportTableHighlightColor");
LLColor4 normal_color = LLUIColorTable::instance().getColor("MeshImportTableNormalColor");
@ -4778,6 +5219,13 @@ void LLModelPreview::setPreviewLOD(S32 lod)
mFMP->childSetColor(lod_triangles_name[i], color);
mFMP->childSetColor(lod_vertices_name[i], color);
}
LLFloaterModelPreview* fmp = (LLFloaterModelPreview*)mFMP;
if (fmp)
{
// make preview repopulate tab
fmp->clearAvatarTab();
}
}
refresh();
updateStatusMessages();
@ -4795,8 +5243,11 @@ void LLFloaterModelPreview::onReset(void* user_data)
{
assert_main_thread();
LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) user_data;
fmp->childDisable("reset_btn");
fmp->clearLogTab();
fmp->clearAvatarTab();
LLModelPreview* mp = fmp->mModelPreview;
std::string filename = mp->mLODFile[LLModel::LOD_HIGH];
@ -4815,6 +5266,7 @@ void LLFloaterModelPreview::onUpload(void* user_data)
assert_main_thread();
LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data;
mp->clearLogTab();
mp->mUploadBtn->setEnabled(false);
@ -4915,6 +5367,11 @@ void LLFloaterModelPreview::setStatusMessage(const std::string& msg)
mStatusMessage = msg;
}
void LLFloaterModelPreview::toggleCalculateButton()
{
toggleCalculateButton(true);
}
void LLFloaterModelPreview::modelUpdated(bool calculate_visible)
{
mModelPhysicsFee.clear();
@ -5003,8 +5460,6 @@ void LLFloaterModelPreview::resetUploadOptions()
childSetValue("lod_file_" + lod_name[lod], "");
}
getChild<LLComboBox>("physics_lod_combo")->setCurrentByIndex(0);
for(auto& p : mDefaultDecompParams)
{
std::string ctrl_name(p.first);
@ -5014,6 +5469,15 @@ void LLFloaterModelPreview::resetUploadOptions()
ctrl->setValue(p.second);
}
}
getChild<LLComboBox>("physics_lod_combo")->setCurrentByIndex(0);
getChild<LLComboBox>("Cosine%")->setCurrentByIndex(0);
}
void LLFloaterModelPreview::clearLogTab()
{
mUploadLogText->clear();
LLPanel* panel = mTabContainer->getPanelByName("logs_panel");
mTabContainer->setTabPanelFlashing(panel, false);
}
void LLFloaterModelPreview::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url)
@ -5056,7 +5520,11 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
void LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason, const LLSD& result)
{
LL_WARNS() << "LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << LL_ENDL;
std::ostringstream out;
out << "LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(" << status;
out << " : " << reason << ")";
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
doOnIdleOneTime(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, true));
if (result.has("upload_price"))

View File

@ -57,7 +57,19 @@ class domController;
class domSkin;
class domMesh;
class LLMenuButton;
class LLTabContainer;
class LLToggleableMenu;
class LLViewerTextEditor;
class LLJointOverrideData
{
public:
LLJointOverrideData() : mHasConflicts(false) {};
std::map<std::string, LLVector3> mPosOverrides;
bool mHasConflicts;
};
typedef std::map<std::string, LLJointOverrideData> joint_override_data_map_t;
class LLFloaterModelPreview : public LLFloaterModelUploadBase
{
@ -93,6 +105,11 @@ public:
static void onMouseCaptureLostModelPreview(LLMouseHandler*);
static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
static void addStringToLog(const std::string& message, const LLSD& args, bool flash, S32 lod = -1);
static void addStringToLog(const std::string& str, bool flash);
static void addStringToLog(const std::ostringstream& strm, bool flash);
void clearAvatarTab(); // clears table
void updateAvatarTab(); // populates table and data as nessesary
void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
void setPreviewLOD(S32 lod);
@ -115,6 +132,7 @@ public:
void setViewOptionEnabled(const std::string& option, bool enabled);
void enableViewOption(const std::string& option);
void disableViewOption(const std::string& option);
void onShowSkinWeightChecked(LLUICtrl* ctrl);
bool isModelLoading();
@ -177,7 +195,8 @@ protected:
// FIXME - this function and mStatusMessage have no visible effect, and the
// actual status messages are managed by directly manipulation of
// the UI element.
void setStatusMessage(const std::string& msg);
void setStatusMessage(const std::string& msg);
void addStringToLogTab(const std::string& str, bool flash);
LLModelPreview* mModelPreview;
@ -206,24 +225,34 @@ protected:
LLSD mModelPhysicsFee;
private:
void onClickCalculateBtn();
void onClickCalculateBtn();
void onJointListSelection();
void onLoDSourceCommit(S32 lod);
void modelUpdated(bool calculate_visible);
// Toggles between "Calculate weights & fee" and "Upload" buttons.
void toggleCalculateButton();
void toggleCalculateButton(bool visible);
// resets display options of model preview to their defaults.
void resetDisplayOptions();
void resetUploadOptions();
void clearLogTab();
void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
LLButton* mUploadBtn;
LLButton* mCalculateBtn;
LLViewerTextEditor* mUploadLogText;
LLTabContainer* mTabContainer;
S32 mAvatarTabIndex; // just to avoid any issues in case of xml changes
std::string mSelectedJointName;
joint_override_data_map_t mJointOverrides[LLModel::NUM_LODS];
};
class LLMeshFilePicker : public LLFilePickerThread
@ -302,8 +331,9 @@ public:
void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
//Accessors for the legacy rigs
const bool isLegacyRigValid( void ) const { return mLegacyRigValid; }
void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }
const bool isLegacyRigValid( void ) const { return mLegacyRigFlags == 0; }
U32 getLegacyRigFlags() const { return mLegacyRigFlags; }
void setLegacyRigFlags( U32 rigFlags ) { mLegacyRigFlags = rigFlags; }
static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
static bool lodQueryCallback();
@ -418,7 +448,7 @@ private:
float mPelvisZOffset;
bool mRigValidJointUpload;
bool mLegacyRigValid;
U32 mLegacyRigFlags;
bool mLastJointUpdate;

View File

@ -1700,13 +1700,16 @@ void LLVOAvatar::renderCollisionVolumes()
}
}
void LLVOAvatar::renderBones()
void LLVOAvatar::renderBones(const std::string &selected_joint)
{
LLGLEnable blend(GL_BLEND);
avatar_joint_list_t::iterator iter = mSkeleton.begin();
avatar_joint_list_t::iterator end = mSkeleton.end();
avatar_joint_list_t::iterator end = mSkeleton.end();
// For selected joints
static LLVector3 SELECTED_COLOR_OCCLUDED(1.0f, 1.0f, 0.0f);
static LLVector3 SELECTED_COLOR_VISIBLE(0.5f, 0.5f, 0.5f);
// For bones with position overrides defined
static LLVector3 OVERRIDE_COLOR_OCCLUDED(1.0f, 0.0f, 0.0f);
static LLVector3 OVERRIDE_COLOR_VISIBLE(0.5f, 0.5f, 0.5f);
@ -1733,7 +1736,18 @@ void LLVOAvatar::renderBones()
LLVector3 pos;
LLUUID mesh_id;
if (jointp->hasAttachmentPosOverride(pos,mesh_id))
F32 sphere_scale = SPHERE_SCALEF;
// We are in render, so it is preferable to implement selection
// in a different way, but since this is for debug/preview, this
// is low priority
if (jointp->getName() == selected_joint)
{
sphere_scale *= 16.f;
occ_color = SELECTED_COLOR_OCCLUDED;
visible_color = SELECTED_COLOR_VISIBLE;
}
else if (jointp->hasAttachmentPosOverride(pos,mesh_id))
{
occ_color = OVERRIDE_COLOR_OCCLUDED;
visible_color = OVERRIDE_COLOR_VISIBLE;
@ -1754,7 +1768,6 @@ void LLVOAvatar::renderBones()
LLVector3 begin_pos(0,0,0);
LLVector3 end_pos(jointp->getEnd());
F32 sphere_scale = SPHERE_SCALEF;
gGL.pushMatrix();
gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] );

View File

@ -467,7 +467,7 @@ public:
F32 getLastSkinTime() { return mLastSkinTime; }
U32 renderTransparent(BOOL first_pass);
void renderCollisionVolumes();
void renderBones();
void renderBones(const std::string &selected_joint = std::string());
void renderJoints();
static void deleteCachedImages(bool clearAll=true);
static void destroyGL();

View File

@ -88,6 +88,16 @@
<string name="tbd">
folgt
</string>
<string name="TooManyJoint">
Skinning wurde wegen zu vieler Gelenke deaktiviert: [JOINTS], Maximum: [MAX]
</string>
<string name="UnrecognizedJoint">
Geriggt an einem unbekannten Gelenk: [NAME]
</string>
<string name="UnknownJoints">
Skinning wurde wegen [COUNT] unbekannter Gelenke deaktiviert.
</string>
<panel name="left_panel">
<panel name="model_name_representation_panel">
<text name="name_label">
@ -282,6 +292,19 @@
</panel>
</panel>
<panel label="Hochladeoptionen" name="modifiers_panel">
<text name="scale_label">
Skalierung (1=keine):
</text>
<spinner name="import_scale" value="1.0"/>
<text name="dimensions_label">
Dimensionen:
</text>
<text name="import_dimensions">
[X] X [Y] X [Z]
</text>
<check_box label="Texturen einschließen" name="upload_textures"/>
</panel>
<panel label="Übersteuerung" title="Avatar" name="avatar_panel">
<text name="scale_label">
Skalierung (1=keine):
</text>
@ -296,9 +319,9 @@
<text name="include_label">
Nur für Avatarmodelle:
</text>
<check_box label="Skingewicht einschließen" name="upload_skin"/>
<check_box label="Gelenkpositionen einschließen" name="upload_joints"/>
<check_box label="Skala sperren, wenn Gelenkposition definiert ist" name="lock_scale_if_joint_position"/>
<check_box label="Skingewicht einschließen" name="upload_skin" top_pad="0"/>
<check_box label="Gelenkpositionen einschließen" name="upload_joints" top_pad="2"/>
<check_box label="Skala sperren, wenn Gelenkposition definiert ist" name="lock_scale_if_joint_position" top_pad="15"/>
<check_box label="An Avatarform anpassen" name="deform"/>
<radio_group name="deform_base">
<radio_item label="Mann" name="0"/>
@ -309,8 +332,29 @@
Z-Offset (Av. anheben / senken):
</text>
<spinner name="pelvis_offset" value="0.0"/>
<panel name="avatar_model_hint_panel">
<text name="avatar_model_hint_text">
<text name="skin_too_many_joints" text_color="Orange">
Zu viele skingewichtete Gelenke
</text>
<text name="skin_unknown_joint">
Modell hat unbekannte Gelenke
</text>
<text name="joints_descr">
Gelenke:
</text>
<text name="conflicts_description">
[CONFLICTS] Konflikte in [JOINTS_COUNT] Gelenk(e)
</text>
<text name="pos_overrides_descr">
Position übersteuert für Gelenk '[JOINT]':
</text>
<scroll_list name="pos_overrides_list">
<scroll_list.columns label="Modell" name="model_name"/>
<scroll_list.columns label="X" name="axis_x"/>
<scroll_list.columns label="Y" name="axis_y"/>
<scroll_list.columns label="Z" name="axis_z"/>
</scroll_list>
<panel name="avatar_model_hint_panel" left="380" width="230">
<text name="avatar_model_hint_text" width="220">
Hinweis:
Zu viele Objekte nutzen unnötigerweise den Standard-Anhängepunkt (Rechte Hand).
@ -318,6 +362,7 @@ Bitte ziehen Sie einen anderen Anhängepunkt nahe der Objektposition in Betracht
</text>
</panel>
</panel>
<panel label="Protokoll" name="logs_panel" />
</tab_container>
<panel name="weights_and_warning_panel">
<button label="Gewichte und Gebühr berechnen" name="calculate_btn" tool_tip="Gewichte und Gebühr berechnen" width="200"/>
@ -339,7 +384,7 @@ Bitte ziehen Sie einen anderen Anhängepunkt nahe der Objektposition in Betracht
<text name="server_weight">
Server: [SIM]
</text>
<panel name="physics_costs_panel">
<panel name="price_breakdown_panel">
<text name="price_breakdown_title">
Kosten-Aufstellung
</text>
@ -360,7 +405,7 @@ Niedrig:
Niedrigste:
</text>
-->
<panel name="physics_breakdown_panel">
<panel name="physics_costs_panel">
<text name="physics_breakdown_title">
Physik-Kosten
</text>
@ -370,56 +415,42 @@ Mesh:
Analysiert:
</text>
</panel>
<panel name="preview_controls_panel">
<panel name="preview_controls_inner_panel">
<text name="preview_controls_title">
Vorschau-Einstellungen:
</text>
<combo_box name="preview_lod_combo" tool_tip="Detailstufe zur Anzeige in Vorschaudarstellung">
<combo_item name="high">
Hoch
</combo_item>
<combo_item name="medium">
Mittel
</combo_item>
<combo_item name="low">
Niedrig
</combo_item>
<combo_item name="lowest">
Niedrigste
</combo_item>
</combo_box>
</panel>
<text name="label_display">
Anzeige...
</text>
<check_box label="Kanten" name="show_edges"/>
<check_box label="Texturen" name="show_textures"/>
<check_box label="UV-Hilfe" name="show_uv_guide"/>
<check_box label="Physik" name="show_physics"/>
<check_box label="Skingew." name="show_skin_weight"/>
<check_box label="Gelenke" name="show_joint_positions"/>
<text name="exploder_label" width="105">
Vorschaudehnung:
</text>
<slider name="physics_explode" width="80"/>
</panel>
<text name="warning_title" width="60">
HINWEIS:
</text>
<text name="warning_message">
Sie haben keine Berechtigung zum Hochladen von Netzmodellen. [[VURL] Weitere Infos], wie Sie sich zertifizieren lassen können.
Sie haben keine Berechtigung zum Hochladen von Netzmodellen. [[VURL] Infos] zur Zertifizierung.
</text>
<text name="status">
[STATUS]
</text>
</panel>
</panel>
<text name="lod_label">
Vorschau:
</text>
<panel name="right_panel">
<text name="lod_label">
Vorschau:
<combo_box name="preview_lod_combo" tool_tip="Dargestelltes LOD in der Vorschau">
<combo_item name="high">Hoch</combo_item>
<combo_item name="medium">Mittel</combo_item>
<combo_item name="low">Niedrig</combo_item>
<combo_item name="lowest">Niedrigstes </combo_item>
</combo_box>
<text name="physics_explode_label" width="105">
Vorschaudehnung:
</text>
<text name="label_display">
Anzeigen:
</text>
<check_box label="Kanten" name="show_edges"/>
<check_box label="Texturen" name="show_textures"/>
<check_box label="UV-Hilfe" name="show_uv_guide"/>
<check_box label="Physik" name="show_physics"/>
<check_box label="Skingewichte" name="show_skin_weight"/>
<check_box label="Gelenkpos.-Übersteuer." name="show_joint_overrides"/>
<check_box label="Gelenke" name="show_joint_positions"/>
<text name="exploder_label" width="105">
Vorschaudehnung:
</text>
</panel>
<panel name="lower_right_panel">
</panel>
</floater>

View File

@ -4,11 +4,10 @@
can_drag_on_left="false"
can_minimize="true"
can_resize="true"
height="575"
min_height="600"
width="1024"
top="0"
min_width="1024"
height="590"
min_height="590"
width="960"
min_width="960"
name="Model Preview"
title="Upload Model"
help_topic="upload_model">
@ -43,6 +42,12 @@
<string name="decomposing">Analyzing...</string>
<string name="simplifying">Simplifying...</string>
<string name="tbd">TBD</string>
<!-- Warnings and info from model loader-->
<string name="TooManyJoint">Skinning disabled due to too many joints: [JOINTS], maximum: [MAX]</string>
<string name="UnrecognizedJoint">Rigged to unrecognized joint name [NAME]</string>
<string name="UnknownJoints">Skinning disabled due to [COUNT] unknown joints</string>
<string name="ModelLoaded">Model [MODEL_NAME] loaded</string>
<panel
follows="top|left"
@ -51,7 +56,7 @@
left="3"
name="left_panel"
top_pad="0"
width="630">
width="635">
<panel
follows="all"
height="50"
@ -63,7 +68,7 @@
follows="top|left"
layout="topleft"
height="15"
left="15"
left="2"
name="name_label"
text_color="White"
top="0"
@ -82,12 +87,13 @@
</panel>
<tab_container
follows="top|left"
top_pad="15"
top_pad="0"
left="0"
height="300"
height="330"
width="635"
name="import_tab"
tab_position="top">
tab_position="top"
enable_tabs_flashing="true">
<!-- LOD PANEL -->
<panel
help_topic="upload_model_lod"
@ -98,12 +104,12 @@
<view_border
bevel_style="none"
follows="top|left"
height="275"
height="306"
layout="topleft"
left="3"
name="lod_tab_border"
top_pad="0"
width="629" />
width="619" />
<text
follows="left|top"
height="18"
@ -736,7 +742,7 @@
<view_border
bevel_style="none"
follows="top|left"
height="275"
height="306"
layout="topleft"
left="3"
name="physics_tab_border"
@ -1111,7 +1117,7 @@
<view_border
bevel_style="none"
follows="top|left"
height="275"
height="306"
layout="topleft"
left="3"
name="border"
@ -1162,76 +1168,174 @@
label="Include textures"
left="20"
top_pad="20"/>
<view_border
bevel_style="none"
follows="top|left"
height="0"
layout="topleft"
name="border"
top_pad="20"
width="579"/>
<text
follows="top|left"
height="15"
left="20"
name="include_label"
text_color="White"
top_pad="20"
width="150">
For avatar models only:
</text>
<check_box
follows="top|left"
height="15"
label="Include skin weight"
name="upload_skin"
top_pad="15"/>
<check_box
follows="top|left"
height="15"
label="Include joint positions"
name="upload_joints"
top_pad="15"/>
<check_box
follows="top|left"
height="15"
label="Lock scale if joint position defined"
name="lock_scale_if_joint_position"
top_pad="15"/>
<text
follows="top|left"
height="15"
layout="topleft"
left="220"
name="pelvis_offset_label"
text_color="White"
top="134"
width="250">
Z offset (raise or lower avatar):
</text>
<spinner
follows="top|left"
height="20"
min_val="-3.00"
max_val="3.0"
name="pelvis_offset"
top_pad="10"
value="0.0"
width="80"/>
</panel>
<panel
label="Overrides"
layout="topleft"
name="avatar_panel"
title="Avatar">
<view_border
bevel_style="none"
follows="top|left"
height="306"
layout="topleft"
left="3"
name="avatar_tab_border"
top_pad="0"
width="619" />
<check_box
follows="top|left"
height="15"
label="Include skin weight"
label_text.text_color="White"
name="upload_skin"
top="8"
left="10"/>
<check_box
follows="top|left"
height="15"
label="Include joint positions"
label_text.text_color="White"
name="upload_joints"
left_delta="0"
top_pad="7"/>
<check_box
follows="top|left"
height="15"
label="Lock scale if joint position defined"
label_text.text_color="White"
label_text.wrap="true"
label_text.width="180"
name="lock_scale_if_joint_position"
top_pad="7"/>
<text
follows="top|left"
height="15"
layout="topleft"
left="225"
name="pelvis_offset_label"
text_color="White"
top="8"
width="200">
Z offset (raise or lower avatar):
</text>
<spinner
follows="top|left"
height="20"
min_val="-3.00"
max_val="3.0"
name="pelvis_offset"
top_pad="10"
value="0.0"
width="80"/>
<text
follows="top|left"
height="17"
left="425"
name="skin_too_many_joints"
text_color="Orange"
top="7"
width="195"
word_wrap="true">
Too many skinned joints
</text>
<text
follows="top|left"
height="32"
left="425"
name="skin_unknown_joint"
text_color="Orange"
top="8"
width="195"
word_wrap="true">
Model has an unknown joint(s)
</text>
<text
layout="topleft"
follows="top|left"
height="15"
left="10"
name="joints_descr"
top="73"
width="150">
Joints:
</text>
<scroll_list
layout="topleft"
follows="top|left"
name="joints_list"
column_padding="0"
draw_heading="false"
draw_stripes="false"
commit_on_selection_change="true"
heading_height="23"
height="199"
left_delta="0"
top_pad="0"
width="205"/>
<text
layout="topleft"
follows="top|left"
height="15"
left_delta="0"
name="conflicts_description"
top_pad="2"
width="205">
[CONFLICTS] conflicts in [JOINTS_COUNT] joints
</text>
<text
layout="topleft"
follows="top|left"
height="15"
left_pad="10"
name="pos_overrides_descr"
top="73"
width="300">
Position overrides for joint '[JOINT]':
</text>
<scroll_list
layout="topleft"
follows="top|left"
name="pos_overrides_list"
column_padding="0"
draw_heading="true"
draw_stripes="false"
heading_height="23"
height="100"
left_delta="0"
top_pad="0"
width="385">
<scroll_list.columns
label="Model"
name="model_name"
relative_width="0.49" />
<scroll_list.columns
label="X"
name="axis_x"
relative_width="0.17" />
<scroll_list.columns
label="Y"
name="axis_y"
relative_width="0.17" />
<scroll_list.columns
label="Z"
name="axis_z"
relative_width="0.17" />
</scroll_list>
<panel
follows="top|left"
layout="topleft"
border="true"
left="400"
height="165"
top="100"
border="true"
left="410"
height="110"
top_pad="5"
width="200"
name="avatar_model_hint_panel"
>
<text
left="5"
width="190"
height="165"
height="110"
name="avatar_model_hint_text"
wrap="true"
word_wrap="true"
@ -1242,17 +1346,50 @@ Too many items use the default (right hand) unnecessarily.
Please consider using an attachment point close to the item's position on the body.
</text>
</panel>
</panel>
</panel>
<panel
label="Log"
layout="topleft"
name="logs_panel">
<view_border
bevel_style="none"
follows="top|left"
height="306"
layout="topleft"
left="3"
name="log_tab_border"
top_pad="0"
width="619" />
<text_editor
type="string"
length="1"
embedded_items="false"
follows="top|left"
font="SansSerif"
ignore_tab="false"
layout="topleft"
height="267"
left="4"
top="4"
right="-21"
max_length="65536"
name="log_text"
parse_urls="true"
spellcheck="false"
read_only="true"
word_wrap="true">
</text_editor>
</panel>
</tab_container>
<panel
follows="top|left|bottom"
layout="topleft"
height="197"
height="195"
left="4"
border="true"
name="weights_and_warning_panel"
top_pad="3"
width="629">
width="619">
<button
follows="top|left"
label="Calculate weights &amp; fee"
@ -1354,7 +1491,7 @@ Please consider using an attachment point close to the item's position on the bo
top_pad="5"
layout="topleft"
left="6"
name="physics_costs_panel"
name="price_breakdown_panel"
width="120"
height="100">
<text
@ -1437,7 +1574,7 @@ Lowest:
border="true"
layout="topleft"
left_pad="15"
name="physics_breakdown_panel"
name="physics_costs_panel"
width="120"
height="100">
<text
@ -1481,113 +1618,6 @@ Analysed:
[PHU]
</text>-->
</panel>
<panel
follows="top|left"
layout="topleft"
left_pad="100"
height="100"
border="true"
name="preview_controls_panel"
width="260">
<panel
name="preview_controls_inner_panel"
height="18" >
<text
height="18"
layout="topleft"
name="preview_controls_title"
left="3"
width="150">
Preview controls
</text>
<combo_box
can_resize="false"
follows="top|left"
left="-85"
top_delta="-2"
height="18"
layout="topleft"
name="preview_lod_combo"
width="80"
tool_tip="LOD to view in preview render">
<combo_item name="high"> High </combo_item>
<combo_item name="medium"> Medium </combo_item>
<combo_item name="low"> Low </combo_item>
<combo_item name="lowest"> Lowest </combo_item>
</combo_box>
</panel>
<view_border
bevel_style="none"
follows="top|left"
height="0"
layout="topleft"
left="3"
name="preview_controls_border"
top_pad="5"
halign="center"
width="250"/>
<check_box
follows="top|left"
label="Edges"
layout="topleft"
name="show_edges"
width="70"
left="0"
top_pad="10"/>
<check_box
follows="top|left"
label="Textures"
layout="topleft"
name="show_textures"
left_pad="0"/>
<check_box
follows="top|left"
label="UV guide"
layout="topleft"
name="show_uv_guide"
left_pad="0"/>
<check_box
follows="top|left"
top_pad="10"
left="0"
width="70"
label="Physics"
name="show_physics"/>
<text
layout="topleft"
follows="top|left"
left_pad="2"
height="16"
width="80"
name="exploder_label">
Explode hulls
</text>
<slider
name="physics_explode"
show_text="false"
top_delta="1"
follows="top|left"
valign="center"
left_pad="2"
min_val="0.0"
max_val="3.0"
width="100"/>
<check_box
follows="top|left"
top_pad="15"
label="Weights"
layout="topleft"
width="70"
name="show_skin_weight"
left="0"/>
<check_box
follows="top|left"
label="Joints"
height="0"
layout="topleft"
name="show_joint_positions"
left_pad="0"/>
</panel>
<!-- ========== NOTE MESSAGE ========== -->
<text
font="SansSerif"
@ -1596,7 +1626,7 @@ Analysed:
name="warning_title"
top_pad="5"
text_color="DrYellow"
visible="false"
visible="true"
width="40">
NOTE:
</text>
@ -1609,45 +1639,140 @@ Analysed:
parse_urls="true"
top_delta="0"
wrap="true"
width="462"
visible="false">
width="530"
visible="true">
You dont have rights to upload mesh models. [[VURL] Find out how] to get certified.
</text>
<text text_color="Yellow" layout="topleft" top_pad="-1" left="6" name="status">
<text
text_color="Yellow"
layout="topleft"
top_pad="-2"
left="6"
name="status">
[STATUS]
</text>
</panel>
</panel>
<text
follows="left|top"
layout="topleft"
left="630"
name="lod_label"
text_color="White"
top="4"
height="15"
width="290">
Preview:
</text>
<panel
follows="top|left|bottom|right"
can_resize="true"
follows="all"
layout="topleft"
border="true"
bevel_style="none"
name="preview_panel"
top_pad="4"
width="325"
height="408"/>
<panel
follows="right|bottom"
can_resize="false"
height="140"
layout="topleft"
name="right_panel"
top="0"
left="640"
background_visible="true"
width="375"
height="570">
<!--<text
top_pad="5"
width="340">
<combo_box
top_pad="3"
follows="left|top"
height="18"
layout="topleft"
name="preview_lod_combo"
width="150"
tool_tip="LOD to view in preview render">
<combo_item name="high"> High </combo_item>
<combo_item name="medium"> Medium </combo_item>
<combo_item name="low"> Low </combo_item>
<combo_item name="lowest"> Lowest </combo_item>
</combo_box>
<text
follows="top|left"
layout="topleft"
left="0"
name="lod_label"
text_color="White"
top="13"
height="15"
width="290">
Preview:
</text>-->
top="5"
left_pad="10"
name="label_display"
width="100">
Display:
</text>
<check_box
follows="top|left"
label="Edges"
label_text.text_color="White"
layout="topleft"
left_delta="0"
name="show_edges"
top_pad="8">
</check_box>
<check_box
follows="top|left"
label="Physics"
label_text.text_color="White"
layout="topleft"
name="show_physics"
top_pad="8">
</check_box>
<check_box
follows="top|left"
label="Textures"
label_text.text_color="White"
layout="topleft"
name="show_textures"
top_pad="8">
</check_box>
<check_box
follows="top|left"
label="Skin weights"
label_text.text_color="White"
layout="topleft"
name="show_skin_weight"
top_pad="8">
</check_box>
<check_box
follows="top|left"
label="Joint position overrides"
label_text.text_color="White"
word_wrap="down"
width="150"
layout="topleft"
name="show_joint_overrides"
top_pad="8">
</check_box>
<check_box
follows="top|left"
label="Joints"
label_text.text_color="White"
layout="topleft"
name="show_joint_positions"
top_pad="8">
</check_box>
<text
follows="top|left"
layout="topleft"
left="2"
name="physics_explode_label"
top="85"
width="150">
Preview Spread:
</text>
<slider
name="physics_explode"
follows="top|left"
top="100"
left="0"
min_val="0.0"
max_val="3.0"
height="20"
width="150"/>
</panel>
<panel
border="true"
bevel_style="none"
follows="top|left|right|bottom"
layout="topleft"
name="preview_panel"
top="5"
height="560"
width="375"
/>
</floater>

View File

@ -19,5 +19,6 @@
name="Preview Tabs"
tab_position="bottom"
top="0"
width="448" />
width="448"
enable_tabs_flashing="true"/>
</multi_floater>

View File

@ -204,7 +204,7 @@ Rozważ użycie innego punktu doczepienia, bliżej do pozycji obiektu na ciele.
<text name="server_weight">
Serwer: [SIM]
</text>
<panel name="physics_costs_panel">
<panel name="price_breakdown_panel">
<text name="price_breakdown_title">
Podział kosztów
</text>
@ -223,7 +223,7 @@ Wysokie:
Niskie:
Najniższe:
</text>
<panel name="physics_breakdown_panel">
<panel name="physics_costs_panel">
<text name="physics_breakdown_title">
Koszty fizyki
</text>