Hooked up underlying material fetching mechanism and added material-related structures. Not integrated into rendering pipeline.
This commit is contained in:
@@ -941,6 +941,7 @@ P(lcl_responder);
|
|||||||
P(MPImportGetResponder);
|
P(MPImportGetResponder);
|
||||||
P(MPImportPostResponder);
|
P(MPImportPostResponder);
|
||||||
P(mapLayerResponder);
|
P(mapLayerResponder);
|
||||||
|
P(materialsResponder);
|
||||||
P2(maturityPreferences, transfer_30s_connect_10s);
|
P2(maturityPreferences, transfer_30s_connect_10s);
|
||||||
P(mediaDataClientResponder);
|
P(mediaDataClientResponder);
|
||||||
P(mediaTypeResponder);
|
P(mediaTypeResponder);
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ include_directories(
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(llprimitive_SOURCE_FILES
|
set(llprimitive_SOURCE_FILES
|
||||||
|
llmaterialid.cpp
|
||||||
|
llmaterial.cpp
|
||||||
llmaterialtable.cpp
|
llmaterialtable.cpp
|
||||||
llmediaentry.cpp
|
llmediaentry.cpp
|
||||||
llmodel.cpp
|
llmodel.cpp
|
||||||
@@ -37,6 +39,8 @@ set(llprimitive_HEADER_FILES
|
|||||||
CMakeLists.txt
|
CMakeLists.txt
|
||||||
|
|
||||||
legacy_object_types.h
|
legacy_object_types.h
|
||||||
|
llmaterial.h
|
||||||
|
llmaterialid.h
|
||||||
llmaterialtable.h
|
llmaterialtable.h
|
||||||
llmediaentry.h
|
llmediaentry.h
|
||||||
llmodel.h
|
llmodel.h
|
||||||
|
|||||||
227
indra/llprimitive/llmaterial.cpp
Normal file
227
indra/llprimitive/llmaterial.cpp
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
/**
|
||||||
|
* @file llmaterial.cpp
|
||||||
|
* @brief Material definition
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "linden_common.h"
|
||||||
|
|
||||||
|
#include "llmaterial.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Materials cap parameters
|
||||||
|
*/
|
||||||
|
#define MATERIALS_CAP_NORMAL_MAP_FIELD "NormMap"
|
||||||
|
#define MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD "NormOffsetX"
|
||||||
|
#define MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD "NormOffsetY"
|
||||||
|
#define MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD "NormRepeatX"
|
||||||
|
#define MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD "NormRepeatY"
|
||||||
|
#define MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD "NormRotation"
|
||||||
|
|
||||||
|
#define MATERIALS_CAP_SPECULAR_MAP_FIELD "SpecMap"
|
||||||
|
#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD "SpecOffsetX"
|
||||||
|
#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD "SpecOffsetY"
|
||||||
|
#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD "SpecRepeatX"
|
||||||
|
#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD "SpecRepeatY"
|
||||||
|
#define MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD "SpecRotation"
|
||||||
|
|
||||||
|
#define MATERIALS_CAP_SPECULAR_COLOR_FIELD "SpecColor"
|
||||||
|
#define MATERIALS_CAP_SPECULAR_EXP_FIELD "SpecExp"
|
||||||
|
#define MATERIALS_CAP_ENV_INTENSITY_FIELD "EnvIntensity"
|
||||||
|
#define MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD "AlphaMaskCutoff"
|
||||||
|
#define MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD "DiffuseAlphaMode"
|
||||||
|
|
||||||
|
const LLColor4U LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR(255,255,255,255);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Materials constants
|
||||||
|
*/
|
||||||
|
|
||||||
|
const F32 MATERIALS_MULTIPLIER = 10000.f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename T> T getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type)
|
||||||
|
{
|
||||||
|
if ( (data.has(field)) && (field_type == data[field].type()) )
|
||||||
|
{
|
||||||
|
return (T)data[field];
|
||||||
|
}
|
||||||
|
llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl;
|
||||||
|
return (T)LLSD();
|
||||||
|
}
|
||||||
|
|
||||||
|
// GCC didn't like the generic form above for some reason
|
||||||
|
template<> LLUUID getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type)
|
||||||
|
{
|
||||||
|
if ( (data.has(field)) && (field_type == data[field].type()) )
|
||||||
|
{
|
||||||
|
return data[field].asUUID();
|
||||||
|
}
|
||||||
|
llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl;
|
||||||
|
return LLUUID::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LLMaterial class
|
||||||
|
*/
|
||||||
|
|
||||||
|
const LLMaterial LLMaterial::null;
|
||||||
|
|
||||||
|
LLMaterial::LLMaterial()
|
||||||
|
: mNormalOffsetX(0.0f)
|
||||||
|
, mNormalOffsetY(0.0f)
|
||||||
|
, mNormalRepeatX(1.0f)
|
||||||
|
, mNormalRepeatY(1.0f)
|
||||||
|
, mNormalRotation(0.0f)
|
||||||
|
, mSpecularOffsetX(0.0f)
|
||||||
|
, mSpecularOffsetY(0.0f)
|
||||||
|
, mSpecularRepeatX(1.0f)
|
||||||
|
, mSpecularRepeatY(1.0f)
|
||||||
|
, mSpecularRotation(0.0f)
|
||||||
|
, mSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR)
|
||||||
|
, mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT)
|
||||||
|
, mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)
|
||||||
|
, mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
|
||||||
|
, mAlphaMaskCutoff(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMaterial::LLMaterial(const LLSD& material_data)
|
||||||
|
{
|
||||||
|
fromLLSD(material_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSD LLMaterial::asLLSD() const
|
||||||
|
{
|
||||||
|
LLSD material_data;
|
||||||
|
|
||||||
|
material_data[MATERIALS_CAP_NORMAL_MAP_FIELD] = mNormalID;
|
||||||
|
material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD] = llround(mNormalOffsetX * MATERIALS_MULTIPLIER);
|
||||||
|
material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD] = llround(mNormalOffsetY * MATERIALS_MULTIPLIER);
|
||||||
|
material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD] = llround(mNormalRepeatX * MATERIALS_MULTIPLIER);
|
||||||
|
material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD] = llround(mNormalRepeatY * MATERIALS_MULTIPLIER);
|
||||||
|
material_data[MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD] = llround(mNormalRotation * MATERIALS_MULTIPLIER);
|
||||||
|
|
||||||
|
material_data[MATERIALS_CAP_SPECULAR_MAP_FIELD] = mSpecularID;
|
||||||
|
material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD] = llround(mSpecularOffsetX * MATERIALS_MULTIPLIER);
|
||||||
|
material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD] = llround(mSpecularOffsetY * MATERIALS_MULTIPLIER);
|
||||||
|
material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD] = llround(mSpecularRepeatX * MATERIALS_MULTIPLIER);
|
||||||
|
material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD] = llround(mSpecularRepeatY * MATERIALS_MULTIPLIER);
|
||||||
|
material_data[MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD] = llround(mSpecularRotation * MATERIALS_MULTIPLIER);
|
||||||
|
|
||||||
|
material_data[MATERIALS_CAP_SPECULAR_COLOR_FIELD] = mSpecularLightColor.getValue();
|
||||||
|
material_data[MATERIALS_CAP_SPECULAR_EXP_FIELD] = mSpecularLightExponent;
|
||||||
|
material_data[MATERIALS_CAP_ENV_INTENSITY_FIELD] = mEnvironmentIntensity;
|
||||||
|
material_data[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = mDiffuseAlphaMode;
|
||||||
|
material_data[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD] = mAlphaMaskCutoff;
|
||||||
|
|
||||||
|
return material_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterial::fromLLSD(const LLSD& material_data)
|
||||||
|
{
|
||||||
|
mNormalID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_NORMAL_MAP_FIELD, LLSD::TypeUUID);
|
||||||
|
mNormalOffsetX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
|
||||||
|
mNormalOffsetY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
|
||||||
|
mNormalRepeatX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
|
||||||
|
mNormalRepeatY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
|
||||||
|
mNormalRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
|
||||||
|
|
||||||
|
mSpecularID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_SPECULAR_MAP_FIELD, LLSD::TypeUUID);
|
||||||
|
mSpecularOffsetX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
|
||||||
|
mSpecularOffsetY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
|
||||||
|
mSpecularRepeatX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
|
||||||
|
mSpecularRepeatY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
|
||||||
|
mSpecularRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
|
||||||
|
|
||||||
|
mSpecularLightColor.setValue(getMaterialField<LLSD>(material_data, MATERIALS_CAP_SPECULAR_COLOR_FIELD, LLSD::TypeArray));
|
||||||
|
mSpecularLightExponent = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_EXP_FIELD, LLSD::TypeInteger);
|
||||||
|
mEnvironmentIntensity = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ENV_INTENSITY_FIELD, LLSD::TypeInteger);
|
||||||
|
mDiffuseAlphaMode = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger);
|
||||||
|
mAlphaMaskCutoff = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD, LLSD::TypeInteger);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterial::isNull() const
|
||||||
|
{
|
||||||
|
return (*this == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterial::operator == (const LLMaterial& rhs) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(mNormalID == rhs.mNormalID) && (mNormalOffsetX == rhs.mNormalOffsetX) && (mNormalOffsetY == rhs.mNormalOffsetY) &&
|
||||||
|
(mNormalRepeatX == rhs.mNormalRepeatX) && (mNormalRepeatY == rhs.mNormalRepeatY) && (mNormalRotation == rhs.mNormalRotation) &&
|
||||||
|
(mSpecularID == rhs.mSpecularID) && (mSpecularOffsetX == rhs.mSpecularOffsetX) && (mSpecularOffsetY == rhs.mSpecularOffsetY) &&
|
||||||
|
(mSpecularRepeatX == rhs.mSpecularRepeatX) && (mSpecularRepeatY == rhs.mSpecularRepeatY) && (mSpecularRotation == rhs.mSpecularRotation) &&
|
||||||
|
(mSpecularLightColor == rhs.mSpecularLightColor) && (mSpecularLightExponent == rhs.mSpecularLightExponent) &&
|
||||||
|
(mEnvironmentIntensity == rhs.mEnvironmentIntensity) && (mDiffuseAlphaMode == rhs.mDiffuseAlphaMode) && (mAlphaMaskCutoff == rhs.mAlphaMaskCutoff);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterial::operator != (const LLMaterial& rhs) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
U32 LLMaterial::getShaderMask(U32 alpha_mode)
|
||||||
|
{ //NEVER incorporate this value into the message system -- this function will vary depending on viewer implementation
|
||||||
|
U32 ret = 0;
|
||||||
|
|
||||||
|
//two least significant bits are "diffuse alpha mode"
|
||||||
|
if (alpha_mode != DIFFUSE_ALPHA_MODE_DEFAULT)
|
||||||
|
{
|
||||||
|
ret = alpha_mode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = getDiffuseAlphaMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
llassert(ret < SHADER_COUNT);
|
||||||
|
|
||||||
|
//next bit is whether or not specular map is present
|
||||||
|
const U32 SPEC_BIT = 0x4;
|
||||||
|
|
||||||
|
if (getSpecularID().notNull())
|
||||||
|
{
|
||||||
|
ret |= SPEC_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
llassert(ret < SHADER_COUNT);
|
||||||
|
|
||||||
|
//next bit is whether or not normal map is present
|
||||||
|
const U32 NORM_BIT = 0x8;
|
||||||
|
if (getNormalID().notNull())
|
||||||
|
{
|
||||||
|
ret |= NORM_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
llassert(ret < SHADER_COUNT);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
155
indra/llprimitive/llmaterial.h
Normal file
155
indra/llprimitive/llmaterial.h
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
/**
|
||||||
|
* @file llmaterial.h
|
||||||
|
* @brief Material definition
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LL_LLMATERIAL_H
|
||||||
|
#define LL_LLMATERIAL_H
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include "llmaterialid.h"
|
||||||
|
#include "llsd.h"
|
||||||
|
#include "v4coloru.h"
|
||||||
|
#include "llpointer.h"
|
||||||
|
#include "llrefcount.h"
|
||||||
|
|
||||||
|
class LLMaterial : public LLRefCount
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DIFFUSE_ALPHA_MODE_NONE = 0,
|
||||||
|
DIFFUSE_ALPHA_MODE_BLEND = 1,
|
||||||
|
DIFFUSE_ALPHA_MODE_MASK = 2,
|
||||||
|
DIFFUSE_ALPHA_MODE_EMISSIVE = 3,
|
||||||
|
DIFFUSE_ALPHA_MODE_DEFAULT = 4,
|
||||||
|
} eDiffuseAlphaMode;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SHADER_COUNT = 16,
|
||||||
|
ALPHA_SHADER_COUNT = 4
|
||||||
|
} eShaderCount;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const U8 DEFAULT_SPECULAR_LIGHT_EXPONENT = ((U8)(0.2f * 255));
|
||||||
|
static const LLColor4U DEFAULT_SPECULAR_LIGHT_COLOR;
|
||||||
|
static const U8 DEFAULT_ENV_INTENSITY = 0;
|
||||||
|
|
||||||
|
LLMaterial();
|
||||||
|
LLMaterial(const LLSD& material_data);
|
||||||
|
|
||||||
|
LLSD asLLSD() const;
|
||||||
|
void fromLLSD(const LLSD& material_data);
|
||||||
|
|
||||||
|
const LLUUID& getNormalID() const { return mNormalID; }
|
||||||
|
void setNormalID(const LLUUID& normal_id) { mNormalID = normal_id; }
|
||||||
|
void getNormalOffset(F32& offset_x, F32& offset_y) const { offset_x = mNormalOffsetX; offset_y = mNormalOffsetY; }
|
||||||
|
F32 getNormalOffsetX() const { return mNormalOffsetX; }
|
||||||
|
F32 getNormalOffsetY() const { return mNormalOffsetY; }
|
||||||
|
|
||||||
|
void setNormalOffset(F32 offset_x, F32 offset_y) { mNormalOffsetX = offset_x; mNormalOffsetY = offset_y; }
|
||||||
|
void setNormalOffsetX(F32 offset_x) { mNormalOffsetX = offset_x; }
|
||||||
|
void setNormalOffsetY(F32 offset_y) { mNormalOffsetY = offset_y; }
|
||||||
|
|
||||||
|
void getNormalRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mNormalRepeatX; repeat_y = mNormalRepeatY; }
|
||||||
|
F32 getNormalRepeatX() const { return mNormalRepeatX; }
|
||||||
|
F32 getNormalRepeatY() const { return mNormalRepeatY; }
|
||||||
|
|
||||||
|
void setNormalRepeat(F32 repeat_x, F32 repeat_y) { mNormalRepeatX = repeat_x; mNormalRepeatY = repeat_y; }
|
||||||
|
void setNormalRepeatX(F32 repeat_x) { mNormalRepeatX = repeat_x; }
|
||||||
|
void setNormalRepeatY(F32 repeat_y) { mNormalRepeatY = repeat_y; }
|
||||||
|
|
||||||
|
F32 getNormalRotation() const { return mNormalRotation; }
|
||||||
|
void setNormalRotation(F32 rot) { mNormalRotation = rot; }
|
||||||
|
|
||||||
|
const LLUUID& getSpecularID() const { return mSpecularID; }
|
||||||
|
void setSpecularID(const LLUUID& specular_id) { mSpecularID = specular_id; }
|
||||||
|
void getSpecularOffset(F32& offset_x, F32& offset_y) const { offset_x = mSpecularOffsetX; offset_y = mSpecularOffsetY; }
|
||||||
|
F32 getSpecularOffsetX() const { return mSpecularOffsetX; }
|
||||||
|
F32 getSpecularOffsetY() const { return mSpecularOffsetY; }
|
||||||
|
|
||||||
|
void setSpecularOffset(F32 offset_x, F32 offset_y) { mSpecularOffsetX = offset_x; mSpecularOffsetY = offset_y; }
|
||||||
|
void setSpecularOffsetX(F32 offset_x) { mSpecularOffsetX = offset_x; }
|
||||||
|
void setSpecularOffsetY(F32 offset_y) { mSpecularOffsetY = offset_y; }
|
||||||
|
|
||||||
|
void getSpecularRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mSpecularRepeatX; repeat_y = mSpecularRepeatY; }
|
||||||
|
F32 getSpecularRepeatX() const { return mSpecularRepeatX; }
|
||||||
|
F32 getSpecularRepeatY() const { return mSpecularRepeatY; }
|
||||||
|
|
||||||
|
void setSpecularRepeat(F32 repeat_x, F32 repeat_y) { mSpecularRepeatX = repeat_x; mSpecularRepeatY = repeat_y; }
|
||||||
|
void setSpecularRepeatX(F32 repeat_x) { mSpecularRepeatX = repeat_x; }
|
||||||
|
void setSpecularRepeatY(F32 repeat_y) { mSpecularRepeatY = repeat_y; }
|
||||||
|
|
||||||
|
F32 getSpecularRotation() const { return mSpecularRotation; }
|
||||||
|
void setSpecularRotation(F32 rot) { mSpecularRotation = rot; }
|
||||||
|
|
||||||
|
const LLColor4U getSpecularLightColor() const { return mSpecularLightColor; }
|
||||||
|
void setSpecularLightColor(const LLColor4U& color) { mSpecularLightColor = color; }
|
||||||
|
U8 getSpecularLightExponent() const { return mSpecularLightExponent; }
|
||||||
|
void setSpecularLightExponent(U8 exponent) { mSpecularLightExponent = exponent; }
|
||||||
|
U8 getEnvironmentIntensity() const { return mEnvironmentIntensity; }
|
||||||
|
void setEnvironmentIntensity(U8 intensity) { mEnvironmentIntensity = intensity; }
|
||||||
|
U8 getDiffuseAlphaMode() const { return mDiffuseAlphaMode; }
|
||||||
|
void setDiffuseAlphaMode(U8 alpha_mode) { mDiffuseAlphaMode = alpha_mode; }
|
||||||
|
U8 getAlphaMaskCutoff() const { return mAlphaMaskCutoff; }
|
||||||
|
void setAlphaMaskCutoff(U8 cutoff) { mAlphaMaskCutoff = cutoff; }
|
||||||
|
|
||||||
|
bool isNull() const;
|
||||||
|
static const LLMaterial null;
|
||||||
|
|
||||||
|
bool operator == (const LLMaterial& rhs) const;
|
||||||
|
bool operator != (const LLMaterial& rhs) const;
|
||||||
|
|
||||||
|
U32 getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LLUUID mNormalID;
|
||||||
|
F32 mNormalOffsetX;
|
||||||
|
F32 mNormalOffsetY;
|
||||||
|
F32 mNormalRepeatX;
|
||||||
|
F32 mNormalRepeatY;
|
||||||
|
F32 mNormalRotation;
|
||||||
|
|
||||||
|
LLUUID mSpecularID;
|
||||||
|
F32 mSpecularOffsetX;
|
||||||
|
F32 mSpecularOffsetY;
|
||||||
|
F32 mSpecularRepeatX;
|
||||||
|
F32 mSpecularRepeatY;
|
||||||
|
F32 mSpecularRotation;
|
||||||
|
|
||||||
|
LLColor4U mSpecularLightColor;
|
||||||
|
U8 mSpecularLightExponent;
|
||||||
|
U8 mEnvironmentIntensity;
|
||||||
|
U8 mDiffuseAlphaMode;
|
||||||
|
U8 mAlphaMaskCutoff;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef LLPointer<LLMaterial> LLMaterialPtr;
|
||||||
|
|
||||||
|
#endif // LL_LLMATERIAL_H
|
||||||
|
|
||||||
183
indra/llprimitive/llmaterialid.cpp
Normal file
183
indra/llprimitive/llmaterialid.cpp
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
/**
|
||||||
|
* @file llmaterialid.cpp
|
||||||
|
* @brief Implementation of llmaterialid
|
||||||
|
* @author Stinson@lindenlab.com
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2012, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "linden_common.h"
|
||||||
|
|
||||||
|
#include "llmaterialid.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "llformat.h"
|
||||||
|
|
||||||
|
const LLMaterialID LLMaterialID::null;
|
||||||
|
|
||||||
|
LLMaterialID::LLMaterialID()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMaterialID::LLMaterialID(const LLSD& pMaterialID)
|
||||||
|
{
|
||||||
|
llassert(pMaterialID.isBinary());
|
||||||
|
parseFromBinary(pMaterialID.asBinary());
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMaterialID::LLMaterialID(const LLSD::Binary& pMaterialID)
|
||||||
|
{
|
||||||
|
parseFromBinary(pMaterialID);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMaterialID::LLMaterialID(const void* pMemory)
|
||||||
|
{
|
||||||
|
set(pMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID)
|
||||||
|
{
|
||||||
|
copyFromOtherMaterialID(pOtherMaterialID);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMaterialID::~LLMaterialID()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterialID::operator == (const LLMaterialID& pOtherMaterialID) const
|
||||||
|
{
|
||||||
|
return (compareToOtherMaterialID(pOtherMaterialID) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterialID::operator != (const LLMaterialID& pOtherMaterialID) const
|
||||||
|
{
|
||||||
|
return (compareToOtherMaterialID(pOtherMaterialID) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterialID::operator < (const LLMaterialID& pOtherMaterialID) const
|
||||||
|
{
|
||||||
|
return (compareToOtherMaterialID(pOtherMaterialID) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterialID::operator <= (const LLMaterialID& pOtherMaterialID) const
|
||||||
|
{
|
||||||
|
return (compareToOtherMaterialID(pOtherMaterialID) <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterialID::operator > (const LLMaterialID& pOtherMaterialID) const
|
||||||
|
{
|
||||||
|
return (compareToOtherMaterialID(pOtherMaterialID) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterialID::operator >= (const LLMaterialID& pOtherMaterialID) const
|
||||||
|
{
|
||||||
|
return (compareToOtherMaterialID(pOtherMaterialID) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMaterialID& LLMaterialID::operator = (const LLMaterialID& pOtherMaterialID)
|
||||||
|
{
|
||||||
|
copyFromOtherMaterialID(pOtherMaterialID);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterialID::isNull() const
|
||||||
|
{
|
||||||
|
return (compareToOtherMaterialID(LLMaterialID::null) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const U8* LLMaterialID::get() const
|
||||||
|
{
|
||||||
|
return mID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialID::set(const void* pMemory)
|
||||||
|
{
|
||||||
|
llassert(pMemory != NULL);
|
||||||
|
|
||||||
|
// assumes that the required size of memory is available
|
||||||
|
memcpy(mID, pMemory, MATERIAL_ID_SIZE * sizeof(U8));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialID::clear()
|
||||||
|
{
|
||||||
|
memset(mID, 0, MATERIAL_ID_SIZE * sizeof(U8));
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSD LLMaterialID::asLLSD() const
|
||||||
|
{
|
||||||
|
LLSD::Binary materialIDBinary;
|
||||||
|
|
||||||
|
materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8));
|
||||||
|
memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8));
|
||||||
|
|
||||||
|
LLSD materialID = materialIDBinary;
|
||||||
|
return materialID;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LLMaterialID::asString() const
|
||||||
|
{
|
||||||
|
std::string materialIDString;
|
||||||
|
for (unsigned int i = 0U; i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32)); ++i)
|
||||||
|
{
|
||||||
|
if (i != 0U)
|
||||||
|
{
|
||||||
|
materialIDString += "-";
|
||||||
|
}
|
||||||
|
const U32 *value = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]);
|
||||||
|
materialIDString += llformat("%08x", *value);
|
||||||
|
}
|
||||||
|
return materialIDString;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id)
|
||||||
|
{
|
||||||
|
s << material_id.asString();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID)
|
||||||
|
{
|
||||||
|
llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8)));
|
||||||
|
memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialID::copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID)
|
||||||
|
{
|
||||||
|
memcpy(mID, pOtherMaterialID.get(), MATERIAL_ID_SIZE * sizeof(U8));
|
||||||
|
}
|
||||||
|
|
||||||
|
int LLMaterialID::compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const
|
||||||
|
{
|
||||||
|
int retVal = 0;
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; (retVal == 0) && (i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32))); ++i)
|
||||||
|
{
|
||||||
|
const U32 *thisValue = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]);
|
||||||
|
const U32 *otherValue = reinterpret_cast<const U32*>(&pOtherMaterialID.get()[i * sizeof(U32)]);
|
||||||
|
retVal = ((*thisValue < *otherValue) ? -1 : ((*thisValue > *otherValue) ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
76
indra/llprimitive/llmaterialid.h
Normal file
76
indra/llprimitive/llmaterialid.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* @file llmaterialid.h
|
||||||
|
* @brief Header file for llmaterialid
|
||||||
|
* @author Stinson@lindenlab.com
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2012, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
#ifndef LL_LLMATERIALID_H
|
||||||
|
#define LL_LLMATERIALID_H
|
||||||
|
|
||||||
|
#define MATERIAL_ID_SIZE 16
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class LLMaterialID
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LLMaterialID();
|
||||||
|
LLMaterialID(const LLSD& pMaterialID);
|
||||||
|
LLMaterialID(const LLSD::Binary& pMaterialID);
|
||||||
|
LLMaterialID(const void* pMemory);
|
||||||
|
LLMaterialID(const LLMaterialID& pOtherMaterialID);
|
||||||
|
~LLMaterialID();
|
||||||
|
|
||||||
|
bool operator == (const LLMaterialID& pOtherMaterialID) const;
|
||||||
|
bool operator != (const LLMaterialID& pOtherMaterialID) const;
|
||||||
|
|
||||||
|
bool operator < (const LLMaterialID& pOtherMaterialID) const;
|
||||||
|
bool operator <= (const LLMaterialID& pOtherMaterialID) const;
|
||||||
|
bool operator > (const LLMaterialID& pOtherMaterialID) const;
|
||||||
|
bool operator >= (const LLMaterialID& pOtherMaterialID) const;
|
||||||
|
|
||||||
|
LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID);
|
||||||
|
|
||||||
|
bool isNull() const;
|
||||||
|
|
||||||
|
const U8* get() const;
|
||||||
|
void set(const void* pMemory);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
LLSD asLLSD() const;
|
||||||
|
std::string asString() const;
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id);
|
||||||
|
|
||||||
|
static const LLMaterialID null;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void parseFromBinary(const LLSD::Binary& pMaterialID);
|
||||||
|
void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID);
|
||||||
|
int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const;
|
||||||
|
|
||||||
|
U8 mID[MATERIAL_ID_SIZE];
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#endif // LL_LLMATERIALID_H
|
||||||
|
|
||||||
@@ -309,6 +309,15 @@ S32 LLPrimitive::setTERotation(const U8 index, const F32 r)
|
|||||||
return mTextureList.setRotation(index, r);
|
return mTextureList.setRotation(index, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID)
|
||||||
|
{
|
||||||
|
return mTextureList.setMaterialID(index, pMaterialID);
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
|
||||||
|
{
|
||||||
|
return mTextureList.setMaterialParams(index, pMaterialParams);
|
||||||
|
}
|
||||||
|
|
||||||
//===============================================================
|
//===============================================================
|
||||||
S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)
|
S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)
|
||||||
@@ -356,6 +365,23 @@ S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow)
|
|||||||
return mTextureList.setGlow(index, glow);
|
return mTextureList.setGlow(index, glow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLPrimitive::setAllTESelected(bool sel)
|
||||||
|
{
|
||||||
|
for (int i = 0, cnt = getNumTEs(); i < cnt; i++)
|
||||||
|
{
|
||||||
|
setTESelected(i, sel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLPrimitive::setTESelected(const U8 te, bool sel)
|
||||||
|
{
|
||||||
|
LLTextureEntry* tep = getTE(te);
|
||||||
|
if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) )
|
||||||
|
{
|
||||||
|
LLMaterialID material_id = tep->getMaterialID();
|
||||||
|
setTEMaterialID(te, material_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
|
LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
|
||||||
{
|
{
|
||||||
@@ -1080,6 +1106,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
|
|||||||
U8 bump[MAX_TES];
|
U8 bump[MAX_TES];
|
||||||
U8 media_flags[MAX_TES];
|
U8 media_flags[MAX_TES];
|
||||||
U8 glow[MAX_TES];
|
U8 glow[MAX_TES];
|
||||||
|
U8 material_data[MAX_TES*16];
|
||||||
|
|
||||||
const U32 MAX_TE_BUFFER = 4096;
|
const U32 MAX_TE_BUFFER = 4096;
|
||||||
U8 packed_buffer[MAX_TE_BUFFER];
|
U8 packed_buffer[MAX_TE_BUFFER];
|
||||||
@@ -1117,6 +1144,9 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
|
|||||||
bump[face_index] = te->getBumpShinyFullbright();
|
bump[face_index] = te->getBumpShinyFullbright();
|
||||||
media_flags[face_index] = te->getMediaTexGen();
|
media_flags[face_index] = te->getMediaTexGen();
|
||||||
glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
|
glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
|
||||||
|
|
||||||
|
// Directly sending material_ids is not safe!
|
||||||
|
memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
|
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
|
||||||
@@ -1138,6 +1168,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
|
|||||||
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
|
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
|
||||||
*cur_ptr++ = 0;
|
*cur_ptr++ = 0;
|
||||||
cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
|
cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
|
||||||
|
*cur_ptr++ = 0;
|
||||||
|
cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
|
||||||
}
|
}
|
||||||
mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
|
mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
|
||||||
|
|
||||||
@@ -1159,6 +1191,7 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
|
|||||||
U8 bump[MAX_TES];
|
U8 bump[MAX_TES];
|
||||||
U8 media_flags[MAX_TES];
|
U8 media_flags[MAX_TES];
|
||||||
U8 glow[MAX_TES];
|
U8 glow[MAX_TES];
|
||||||
|
U8 material_data[MAX_TES*16];
|
||||||
|
|
||||||
const U32 MAX_TE_BUFFER = 4096;
|
const U32 MAX_TE_BUFFER = 4096;
|
||||||
U8 packed_buffer[MAX_TE_BUFFER];
|
U8 packed_buffer[MAX_TE_BUFFER];
|
||||||
@@ -1196,6 +1229,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
|
|||||||
bump[face_index] = te->getBumpShinyFullbright();
|
bump[face_index] = te->getBumpShinyFullbright();
|
||||||
media_flags[face_index] = te->getMediaTexGen();
|
media_flags[face_index] = te->getMediaTexGen();
|
||||||
glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
|
glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
|
||||||
|
|
||||||
|
// Directly sending material_ids is not safe!
|
||||||
|
memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
|
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
|
||||||
@@ -1217,6 +1253,8 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
|
|||||||
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
|
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
|
||||||
*cur_ptr++ = 0;
|
*cur_ptr++ = 0;
|
||||||
cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
|
cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
|
||||||
|
*cur_ptr++ = 0;
|
||||||
|
cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
|
dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
|
||||||
@@ -1226,6 +1264,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
|
|||||||
S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec)
|
S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec)
|
||||||
{
|
{
|
||||||
S32 retval = 0;
|
S32 retval = 0;
|
||||||
|
// temp buffer for material ID processing
|
||||||
|
// data will end up in tec.material_id[]
|
||||||
|
U8 material_data[LLTEContents::MAX_TES*16];
|
||||||
|
|
||||||
if (block_num < 0)
|
if (block_num < 0)
|
||||||
{
|
{
|
||||||
@@ -1251,7 +1292,7 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name
|
|||||||
mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER);
|
mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
tec.face_count = getNumTEs();
|
tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES);
|
||||||
|
|
||||||
U8 *cur_ptr = tec.packed_buffer;
|
U8 *cur_ptr = tec.packed_buffer;
|
||||||
cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID);
|
cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID);
|
||||||
@@ -1274,6 +1315,21 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name
|
|||||||
cur_ptr++;
|
cur_ptr++;
|
||||||
cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8);
|
cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8);
|
||||||
|
|
||||||
|
if (cur_ptr < tec.packed_buffer + tec.size)
|
||||||
|
{
|
||||||
|
cur_ptr++;
|
||||||
|
cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)material_data, 16, tec.face_count, MVT_LLUUID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(material_data, 0, sizeof(material_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (U32 i = 0; i < tec.face_count; i++)
|
||||||
|
{
|
||||||
|
tec.material_ids[i].set(&material_data[i * 16]);
|
||||||
|
}
|
||||||
|
|
||||||
retval = 1;
|
retval = 1;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -1294,6 +1350,9 @@ S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)
|
|||||||
retval |= setTEBumpShinyFullbright(i, tec.bump[i]);
|
retval |= setTEBumpShinyFullbright(i, tec.bump[i]);
|
||||||
retval |= setTEMediaTexGen(i, tec.media_flags[i]);
|
retval |= setTEMediaTexGen(i, tec.media_flags[i]);
|
||||||
retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);
|
retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);
|
||||||
|
|
||||||
|
retval |= setTEMaterialID(i, tec.material_ids[i]);
|
||||||
|
|
||||||
coloru = LLColor4U(tec.colors + 4*i);
|
coloru = LLColor4U(tec.colors + 4*i);
|
||||||
|
|
||||||
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
|
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
|
||||||
@@ -1328,6 +1387,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
|
|||||||
|
|
||||||
// Avoid construction of 32 UUIDs per call
|
// Avoid construction of 32 UUIDs per call
|
||||||
static LLUUID image_ids[MAX_TES];
|
static LLUUID image_ids[MAX_TES];
|
||||||
|
static LLMaterialID material_ids[MAX_TES];
|
||||||
|
|
||||||
U8 image_data[MAX_TES*16];
|
U8 image_data[MAX_TES*16];
|
||||||
U8 colors[MAX_TES*4];
|
U8 colors[MAX_TES*4];
|
||||||
@@ -1339,6 +1399,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
|
|||||||
U8 bump[MAX_TES];
|
U8 bump[MAX_TES];
|
||||||
U8 media_flags[MAX_TES];
|
U8 media_flags[MAX_TES];
|
||||||
U8 glow[MAX_TES];
|
U8 glow[MAX_TES];
|
||||||
|
U8 material_data[MAX_TES*16];
|
||||||
|
|
||||||
const U32 MAX_TE_BUFFER = 4096;
|
const U32 MAX_TE_BUFFER = 4096;
|
||||||
U8 packed_buffer[MAX_TE_BUFFER];
|
U8 packed_buffer[MAX_TE_BUFFER];
|
||||||
@@ -1381,10 +1442,20 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
|
|||||||
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
|
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
|
||||||
cur_ptr++;
|
cur_ptr++;
|
||||||
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
|
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
|
||||||
|
if (cur_ptr < packed_buffer + size)
|
||||||
|
{
|
||||||
|
cur_ptr++;
|
||||||
|
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)material_data, 16, face_count, MVT_LLUUID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(material_data, 0, sizeof(material_data));
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < face_count; i++)
|
for (i = 0; i < face_count; i++)
|
||||||
{
|
{
|
||||||
memcpy(image_ids[i].mData,&image_data[i*16],16); /* Flawfinder: ignore */
|
memcpy(image_ids[i].mData,&image_data[i*16],16); /* Flawfinder: ignore */
|
||||||
|
material_ids[i].set(&material_data[i * 16]);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLColor4 color;
|
LLColor4 color;
|
||||||
@@ -1398,6 +1469,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
|
|||||||
retval |= setTEBumpShinyFullbright(i, bump[i]);
|
retval |= setTEBumpShinyFullbright(i, bump[i]);
|
||||||
retval |= setTEMediaTexGen(i, media_flags[i]);
|
retval |= setTEMediaTexGen(i, media_flags[i]);
|
||||||
retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
|
retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
|
||||||
|
retval |= setTEMaterialID(i, material_ids[i]);
|
||||||
coloru = LLColor4U(colors + 4*i);
|
coloru = LLColor4U(colors + 4*i);
|
||||||
|
|
||||||
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
|
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class LLMessageSystem;
|
|||||||
class LLVolumeParams;
|
class LLVolumeParams;
|
||||||
class LLColor4;
|
class LLColor4;
|
||||||
class LLColor3;
|
class LLColor3;
|
||||||
|
class LLMaterialID;
|
||||||
class LLTextureEntry;
|
class LLTextureEntry;
|
||||||
class LLDataPacker;
|
class LLDataPacker;
|
||||||
class LLVolumeMgr;
|
class LLVolumeMgr;
|
||||||
@@ -309,6 +310,7 @@ struct LLTEContents
|
|||||||
U8 bump[MAX_TES];
|
U8 bump[MAX_TES];
|
||||||
U8 media_flags[MAX_TES];
|
U8 media_flags[MAX_TES];
|
||||||
U8 glow[MAX_TES];
|
U8 glow[MAX_TES];
|
||||||
|
LLMaterialID material_ids[MAX_TES];
|
||||||
|
|
||||||
static const U32 MAX_TE_BUFFER = 4096;
|
static const U32 MAX_TE_BUFFER = 4096;
|
||||||
U8 packed_buffer[MAX_TE_BUFFER];
|
U8 packed_buffer[MAX_TE_BUFFER];
|
||||||
@@ -359,6 +361,7 @@ public:
|
|||||||
LLTextureEntry* getTE(const U8 te_num) const;
|
LLTextureEntry* getTE(const U8 te_num) const;
|
||||||
|
|
||||||
virtual void setNumTEs(const U8 num_tes);
|
virtual void setNumTEs(const U8 num_tes);
|
||||||
|
virtual void setAllTESelected(bool sel);
|
||||||
virtual void setAllTETextures(const LLUUID &tex_id);
|
virtual void setAllTETextures(const LLUUID &tex_id);
|
||||||
virtual void setTE(const U8 index, const LLTextureEntry& te);
|
virtual void setTE(const U8 index, const LLTextureEntry& te);
|
||||||
virtual S32 setTEColor(const U8 te, const LLColor4 &color);
|
virtual S32 setTEColor(const U8 te, const LLColor4 &color);
|
||||||
@@ -381,7 +384,10 @@ public:
|
|||||||
virtual S32 setTEFullbright(const U8 te, const U8 fullbright);
|
virtual S32 setTEFullbright(const U8 te, const U8 fullbright);
|
||||||
virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
|
virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
|
||||||
virtual S32 setTEGlow(const U8 te, const F32 glow);
|
virtual S32 setTEGlow(const U8 te, const F32 glow);
|
||||||
|
virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
|
||||||
|
virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
|
||||||
virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
|
virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
|
||||||
|
virtual void setTESelected(const U8 te, bool sel);
|
||||||
|
|
||||||
void copyTEs(const LLPrimitive *primitive);
|
void copyTEs(const LLPrimitive *primitive);
|
||||||
S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;
|
S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
|
|
||||||
#include "llprimtexturelist.h"
|
#include "llprimtexturelist.h"
|
||||||
|
#include "llmaterialid.h"
|
||||||
#include "lltextureentry.h"
|
#include "lltextureentry.h"
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@@ -358,6 +359,24 @@ S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow)
|
|||||||
return TEM_CHANGE_NONE;
|
return TEM_CHANGE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID)
|
||||||
|
{
|
||||||
|
if (index < mEntryList.size())
|
||||||
|
{
|
||||||
|
return mEntryList[index]->setMaterialID(pMaterialID);
|
||||||
|
}
|
||||||
|
return TEM_CHANGE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
|
||||||
|
{
|
||||||
|
if (index < mEntryList.size())
|
||||||
|
{
|
||||||
|
return mEntryList[index]->setMaterialParams(pMaterialParams);
|
||||||
|
}
|
||||||
|
return TEM_CHANGE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
S32 LLPrimTextureList::size() const
|
S32 LLPrimTextureList::size() const
|
||||||
{
|
{
|
||||||
return mEntryList.size();
|
return mEntryList.size();
|
||||||
|
|||||||
@@ -39,9 +39,11 @@
|
|||||||
#include "lluuid.h"
|
#include "lluuid.h"
|
||||||
#include "v3color.h"
|
#include "v3color.h"
|
||||||
#include "v4color.h"
|
#include "v4color.h"
|
||||||
|
#include "llmaterial.h"
|
||||||
|
|
||||||
|
|
||||||
class LLTextureEntry;
|
class LLTextureEntry;
|
||||||
|
class LLMaterialID;
|
||||||
|
|
||||||
// this is a list of LLTextureEntry*'s because in practice the list's elements
|
// this is a list of LLTextureEntry*'s because in practice the list's elements
|
||||||
// are of some derived class: LLFooTextureEntry
|
// are of some derived class: LLFooTextureEntry
|
||||||
@@ -110,6 +112,8 @@ public:
|
|||||||
S32 setFullbright(const U8 index, const U8 t);
|
S32 setFullbright(const U8 index, const U8 t);
|
||||||
S32 setMediaFlags(const U8 index, const U8 media_flags);
|
S32 setMediaFlags(const U8 index, const U8 media_flags);
|
||||||
S32 setGlow(const U8 index, const F32 glow);
|
S32 setGlow(const U8 index, const F32 glow);
|
||||||
|
S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID);
|
||||||
|
S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
|
||||||
|
|
||||||
S32 size() const;
|
S32 size() const;
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "lluuid.h"
|
#include "lluuid.h"
|
||||||
#include "llmediaentry.h"
|
#include "llmediaentry.h"
|
||||||
#include "lltextureentry.h"
|
#include "lltextureentry.h"
|
||||||
|
#include "llmaterialid.h"
|
||||||
#include "llsdutil_math.h"
|
#include "llsdutil_math.h"
|
||||||
#include "v4color.h"
|
#include "v4color.h"
|
||||||
|
|
||||||
@@ -60,18 +61,24 @@ LLTextureEntry* LLTextureEntry::newTextureEntry()
|
|||||||
//===============================================================
|
//===============================================================
|
||||||
LLTextureEntry::LLTextureEntry()
|
LLTextureEntry::LLTextureEntry()
|
||||||
: mMediaEntry(NULL)
|
: mMediaEntry(NULL)
|
||||||
|
, mSelected(false)
|
||||||
|
, mMaterialUpdatePending(false)
|
||||||
{
|
{
|
||||||
init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
|
init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
|
LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
|
||||||
: mMediaEntry(NULL)
|
: mMediaEntry(NULL)
|
||||||
|
, mSelected(false)
|
||||||
|
, mMaterialUpdatePending(false)
|
||||||
{
|
{
|
||||||
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
|
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
|
LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
|
||||||
: mMediaEntry(NULL)
|
: mMediaEntry(NULL)
|
||||||
|
, mSelected(false)
|
||||||
|
, mMaterialUpdatePending(false)
|
||||||
{
|
{
|
||||||
mID = rhs.mID;
|
mID = rhs.mID;
|
||||||
mScaleS = rhs.mScaleS;
|
mScaleS = rhs.mScaleS;
|
||||||
@@ -83,6 +90,8 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
|
|||||||
mBump = rhs.mBump;
|
mBump = rhs.mBump;
|
||||||
mMediaFlags = rhs.mMediaFlags;
|
mMediaFlags = rhs.mMediaFlags;
|
||||||
mGlow = rhs.mGlow;
|
mGlow = rhs.mGlow;
|
||||||
|
mMaterialID = rhs.mMaterialID;
|
||||||
|
mMaterial = rhs.mMaterial;
|
||||||
if (rhs.mMediaEntry != NULL) {
|
if (rhs.mMediaEntry != NULL) {
|
||||||
// Make a copy
|
// Make a copy
|
||||||
mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
|
mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
|
||||||
@@ -103,6 +112,8 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
|
|||||||
mBump = rhs.mBump;
|
mBump = rhs.mBump;
|
||||||
mMediaFlags = rhs.mMediaFlags;
|
mMediaFlags = rhs.mMediaFlags;
|
||||||
mGlow = rhs.mGlow;
|
mGlow = rhs.mGlow;
|
||||||
|
mMaterialID = rhs.mMaterialID;
|
||||||
|
mMaterial = rhs.mMaterial;
|
||||||
if (mMediaEntry != NULL) {
|
if (mMediaEntry != NULL) {
|
||||||
delete mMediaEntry;
|
delete mMediaEntry;
|
||||||
}
|
}
|
||||||
@@ -130,6 +141,7 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
|
|||||||
mBump = bump;
|
mBump = bump;
|
||||||
mMediaFlags = 0x0;
|
mMediaFlags = 0x0;
|
||||||
mGlow = 0;
|
mGlow = 0;
|
||||||
|
mMaterialID.clear();
|
||||||
|
|
||||||
setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
|
setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
|
||||||
if (mMediaEntry != NULL) {
|
if (mMediaEntry != NULL) {
|
||||||
@@ -159,6 +171,7 @@ bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
|
|||||||
if (mBump != rhs.mBump) return (true);
|
if (mBump != rhs.mBump) return (true);
|
||||||
if (mMediaFlags != rhs.mMediaFlags) return (true);
|
if (mMediaFlags != rhs.mMediaFlags) return (true);
|
||||||
if (mGlow != rhs.mGlow) return (true);
|
if (mGlow != rhs.mGlow) return (true);
|
||||||
|
if (mMaterialID != rhs.mMaterialID) return (true);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +187,7 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const
|
|||||||
if (mBump != rhs.mBump) return (false);
|
if (mBump != rhs.mBump) return (false);
|
||||||
if (mMediaFlags != rhs.mMediaFlags) return false;
|
if (mMediaFlags != rhs.mMediaFlags) return false;
|
||||||
if (mGlow != rhs.mGlow) return false;
|
if (mGlow != rhs.mGlow) return false;
|
||||||
|
if (mMaterialID != rhs.mMaterialID) return (false);
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,6 +537,34 @@ S32 LLTextureEntry::setGlow(F32 glow)
|
|||||||
return TEM_CHANGE_NONE;
|
return TEM_CHANGE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
|
||||||
|
{
|
||||||
|
if ( (mMaterialID != pMaterialID) || (mMaterialUpdatePending && !mSelected) )
|
||||||
|
{
|
||||||
|
if (mSelected)
|
||||||
|
{
|
||||||
|
mMaterialUpdatePending = true;
|
||||||
|
mMaterialID = pMaterialID;
|
||||||
|
return TEM_CHANGE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mMaterialUpdatePending = false;
|
||||||
|
mMaterialID = pMaterialID;
|
||||||
|
return TEM_CHANGE_TEXTURE;
|
||||||
|
}
|
||||||
|
return TEM_CHANGE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams)
|
||||||
|
{
|
||||||
|
if (mSelected)
|
||||||
|
{
|
||||||
|
mMaterialUpdatePending = true;
|
||||||
|
}
|
||||||
|
mMaterial = pMaterialParams;
|
||||||
|
return TEM_CHANGE_TEXTURE;
|
||||||
|
}
|
||||||
|
|
||||||
void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
|
void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
|
||||||
{
|
{
|
||||||
mMediaFlags |= MF_HAS_MEDIA;
|
mMediaFlags |= MF_HAS_MEDIA;
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
#include "lluuid.h"
|
#include "lluuid.h"
|
||||||
#include "v4color.h"
|
#include "v4color.h"
|
||||||
#include "llsd.h"
|
#include "llsd.h"
|
||||||
|
#include "llmaterialid.h"
|
||||||
|
#include "llmaterial.h"
|
||||||
|
|
||||||
// These bits are used while unpacking TEM messages to tell which aspects of
|
// These bits are used while unpacking TEM messages to tell which aspects of
|
||||||
// the texture entry changed.
|
// the texture entry changed.
|
||||||
@@ -98,6 +100,10 @@ public:
|
|||||||
|
|
||||||
void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump);
|
void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump);
|
||||||
|
|
||||||
|
bool hasPendingMaterialUpdate() const { return mMaterialUpdatePending; }
|
||||||
|
bool isSelected() const { return mSelected; }
|
||||||
|
bool setSelected(bool sel) { bool prev_sel = mSelected; mSelected = sel; return prev_sel; }
|
||||||
|
|
||||||
// These return a TEM_ flag from above to indicate if something changed.
|
// These return a TEM_ flag from above to indicate if something changed.
|
||||||
S32 setID (const LLUUID &tex_id);
|
S32 setID (const LLUUID &tex_id);
|
||||||
S32 setColor(const LLColor4 &color);
|
S32 setColor(const LLColor4 &color);
|
||||||
@@ -121,6 +127,8 @@ public:
|
|||||||
S32 setTexGen(U8 texGen);
|
S32 setTexGen(U8 texGen);
|
||||||
S32 setMediaTexGen(U8 media);
|
S32 setMediaTexGen(U8 media);
|
||||||
S32 setGlow(F32 glow);
|
S32 setGlow(F32 glow);
|
||||||
|
S32 setMaterialID(const LLMaterialID& pMaterialID);
|
||||||
|
S32 setMaterialParams(const LLMaterialPtr pMaterialParams);
|
||||||
|
|
||||||
virtual const LLUUID &getID() const { return mID; }
|
virtual const LLUUID &getID() const { return mID; }
|
||||||
const LLColor4 &getColor() const { return mColor; }
|
const LLColor4 &getColor() const { return mColor; }
|
||||||
@@ -139,6 +147,8 @@ public:
|
|||||||
U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; }
|
U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; }
|
||||||
U8 getMediaTexGen() const { return mMediaFlags; }
|
U8 getMediaTexGen() const { return mMediaFlags; }
|
||||||
F32 getGlow() const { return mGlow; }
|
F32 getGlow() const { return mGlow; }
|
||||||
|
const LLMaterialID& getMaterialID() const { return mMaterialID; };
|
||||||
|
const LLMaterialPtr getMaterialParams() const { return mMaterial; };
|
||||||
|
|
||||||
// *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
|
// *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
|
||||||
// CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
|
// CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
|
||||||
@@ -188,11 +198,15 @@ public:
|
|||||||
static const char* TEXTURE_MEDIA_DATA_KEY;
|
static const char* TEXTURE_MEDIA_DATA_KEY;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool mSelected;
|
||||||
LLUUID mID; // Texture GUID
|
LLUUID mID; // Texture GUID
|
||||||
LLColor4 mColor;
|
LLColor4 mColor;
|
||||||
U8 mBump; // Bump map, shiny, and fullbright
|
U8 mBump; // Bump map, shiny, and fullbright
|
||||||
U8 mMediaFlags; // replace with web page, movie, etc.
|
U8 mMediaFlags; // replace with web page, movie, etc.
|
||||||
F32 mGlow;
|
F32 mGlow;
|
||||||
|
bool mMaterialUpdatePending;
|
||||||
|
LLMaterialID mMaterialID;
|
||||||
|
LLMaterialPtr mMaterial;
|
||||||
|
|
||||||
// Note the media data is not sent via the same message structure as the rest of the TE
|
// Note the media data is not sent via the same message structure as the rest of the TE
|
||||||
LLMediaEntry* mMediaEntry; // The media data for the face
|
LLMediaEntry* mMediaEntry; // The media data for the face
|
||||||
|
|||||||
@@ -318,6 +318,7 @@ set(viewer_SOURCE_FILES
|
|||||||
llmapresponders.cpp
|
llmapresponders.cpp
|
||||||
llmarketplacefunctions.cpp
|
llmarketplacefunctions.cpp
|
||||||
llmarketplacenotifications.cpp
|
llmarketplacenotifications.cpp
|
||||||
|
llmaterialmgr.cpp
|
||||||
llmediactrl.cpp
|
llmediactrl.cpp
|
||||||
llmediadataclient.cpp
|
llmediadataclient.cpp
|
||||||
llmediaremotectrl.cpp
|
llmediaremotectrl.cpp
|
||||||
@@ -830,6 +831,7 @@ set(viewer_HEADER_FILES
|
|||||||
llmapresponders.h
|
llmapresponders.h
|
||||||
llmarketplacefunctions.h
|
llmarketplacefunctions.h
|
||||||
llmarketplacenotifications.h
|
llmarketplacenotifications.h
|
||||||
|
llmaterialmgr.h
|
||||||
llmediactrl.h
|
llmediactrl.h
|
||||||
llmediadataclient.h
|
llmediadataclient.h
|
||||||
llmediaremotectrl.h
|
llmediaremotectrl.h
|
||||||
|
|||||||
793
indra/newview/llmaterialmgr.cpp
Normal file
793
indra/newview/llmaterialmgr.cpp
Normal file
@@ -0,0 +1,793 @@
|
|||||||
|
/**
|
||||||
|
* @file llmaterialmgr.cpp
|
||||||
|
* @brief Material manager
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2013, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "llviewerprecompiledheaders.h"
|
||||||
|
|
||||||
|
#include "llsdserialize.h"
|
||||||
|
#include "llsdutil.h"
|
||||||
|
|
||||||
|
#include "llagent.h"
|
||||||
|
#include "llcallbacklist.h"
|
||||||
|
#include "llmaterialmgr.h"
|
||||||
|
#include "llviewerobject.h"
|
||||||
|
#include "llviewerobjectlist.h"
|
||||||
|
#include "llviewerregion.h"
|
||||||
|
#include "llworld.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Materials cap parameters
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MATERIALS_CAPABILITY_NAME "RenderMaterials"
|
||||||
|
|
||||||
|
#define MATERIALS_CAP_ZIP_FIELD "Zipped"
|
||||||
|
|
||||||
|
#define MATERIALS_CAP_FULL_PER_FACE_FIELD "FullMaterialsPerFace"
|
||||||
|
#define MATERIALS_CAP_FACE_FIELD "Face"
|
||||||
|
#define MATERIALS_CAP_MATERIAL_FIELD "Material"
|
||||||
|
#define MATERIALS_CAP_OBJECT_ID_FIELD "ID"
|
||||||
|
#define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID"
|
||||||
|
|
||||||
|
#define MATERIALS_GET_MAX_ENTRIES 50
|
||||||
|
#define MATERIALS_GET_TIMEOUT (60.f * 20)
|
||||||
|
#define MATERIALS_POST_MAX_ENTRIES 50
|
||||||
|
#define MATERIALS_POST_TIMEOUT (60.f * 5)
|
||||||
|
#define MATERIALS_PUT_THROTTLE_SECS 1.f
|
||||||
|
#define MATERIALS_PUT_MAX_ENTRIES 50
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LLMaterialsResponder helper class
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern AIHTTPTimeoutPolicy materialsResponder_timeout;
|
||||||
|
|
||||||
|
class LLMaterialsResponder : public LLHTTPClient::ResponderWithResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::function<void (bool, const LLSD&)> CallbackFunction;
|
||||||
|
|
||||||
|
LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback);
|
||||||
|
virtual ~LLMaterialsResponder();
|
||||||
|
|
||||||
|
virtual void result(const LLSD& pContent);
|
||||||
|
virtual void error(U32 pStatus, const std::string& pReason);
|
||||||
|
|
||||||
|
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return materialsResponder_timeout; }
|
||||||
|
/*virtual*/ char const* getName(void) const { return "LLMaterialsResponder"; }
|
||||||
|
private:
|
||||||
|
std::string mMethod;
|
||||||
|
std::string mCapabilityURL;
|
||||||
|
CallbackFunction mCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
LLMaterialsResponder::LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback)
|
||||||
|
: LLHTTPClient::ResponderWithResult()
|
||||||
|
, mMethod(pMethod)
|
||||||
|
, mCapabilityURL(pCapabilityURL)
|
||||||
|
, mCallback(pCallback)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMaterialsResponder::~LLMaterialsResponder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialsResponder::result(const LLSD& pContent)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << LL_ENDL;
|
||||||
|
mCallback(true, pContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialsResponder::error(U32 pStatus, const std::string& pReason)
|
||||||
|
{
|
||||||
|
LL_WARNS("Materials")
|
||||||
|
<< "\n--------------------------------------------------------------------------\n"
|
||||||
|
<< mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
|
||||||
|
<< "'\n with url '" << mCapabilityURL << "' because " << pReason
|
||||||
|
<< "\n--------------------------------------------------------------------------"
|
||||||
|
<< LL_ENDL;
|
||||||
|
|
||||||
|
LLSD emptyResult;
|
||||||
|
mCallback(false, emptyResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LLMaterialMgr class
|
||||||
|
*/
|
||||||
|
|
||||||
|
LLMaterialMgr::LLMaterialMgr()
|
||||||
|
{
|
||||||
|
mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(LLMaterialID::null, LLMaterialPtr(NULL)));
|
||||||
|
gIdleCallbacks.addFunction(&LLMaterialMgr::onIdle, NULL);
|
||||||
|
LLWorld::instance().setRegionRemovedCallback(boost::bind(&LLMaterialMgr::onRegionRemoved, this, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMaterialMgr::~LLMaterialMgr()
|
||||||
|
{
|
||||||
|
gIdleCallbacks.deleteFunction(&LLMaterialMgr::onIdle, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterialMgr::isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const
|
||||||
|
{
|
||||||
|
get_pending_map_t::const_iterator itPending = mGetPending.find(pending_material_t(region_id, material_id));
|
||||||
|
return (mGetPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_POST_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::markGetPending(const LLUUID& region_id, const LLMaterialID& material_id)
|
||||||
|
{
|
||||||
|
get_pending_map_t::iterator itPending = mGetPending.find(pending_material_t(region_id, material_id));
|
||||||
|
if (mGetPending.end() == itPending)
|
||||||
|
{
|
||||||
|
mGetPending.insert(std::pair<pending_material_t, F64>(pending_material_t(region_id, material_id), LLFrameTimer::getTotalSeconds()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itPending->second = LLFrameTimer::getTotalSeconds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const LLMaterialPtr LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
|
||||||
|
LLMaterialPtr material;
|
||||||
|
material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
|
||||||
|
if (mMaterials.end() != itMaterial)
|
||||||
|
{
|
||||||
|
material = itMaterial->second;
|
||||||
|
LL_DEBUGS("Materials") << " found material " << LL_ENDL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!isGetPending(region_id, material_id))
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << " material pending " << material_id << LL_ENDL;
|
||||||
|
get_queue_t::iterator itQueue = mGetQueue.find(region_id);
|
||||||
|
if (mGetQueue.end() == itQueue)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "mGetQueue add region " << region_id << " pending " << material_id << LL_ENDL;
|
||||||
|
std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
|
||||||
|
itQueue = ret.first;
|
||||||
|
}
|
||||||
|
itQueue->second.insert(material_id);
|
||||||
|
markGetPending(region_id, material_id);
|
||||||
|
}
|
||||||
|
LL_DEBUGS("Materials") << " returning empty material " << LL_ENDL;
|
||||||
|
material = LLMaterialPtr();
|
||||||
|
}
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id, LLMaterialMgr::get_callback_t::slot_type cb)
|
||||||
|
{
|
||||||
|
boost::signals2::connection connection;
|
||||||
|
|
||||||
|
material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
|
||||||
|
if (itMaterial != mMaterials.end())
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL;
|
||||||
|
get_callback_t signal;
|
||||||
|
signal.connect(cb);
|
||||||
|
signal(material_id, itMaterial->second);
|
||||||
|
connection = boost::signals2::connection();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!isGetPending(region_id, material_id))
|
||||||
|
{
|
||||||
|
get_queue_t::iterator itQueue = mGetQueue.find(region_id);
|
||||||
|
if (mGetQueue.end() == itQueue)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL;
|
||||||
|
std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
|
||||||
|
itQueue = ret.first;
|
||||||
|
}
|
||||||
|
LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL;
|
||||||
|
itQueue->second.insert(material_id);
|
||||||
|
markGetPending(region_id, material_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
|
||||||
|
if (itCallback == mGetCallbacks.end())
|
||||||
|
{
|
||||||
|
std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.insert(std::pair<LLMaterialID, get_callback_t*>(material_id, new get_callback_t()));
|
||||||
|
itCallback = ret.first;
|
||||||
|
}
|
||||||
|
connection = itCallback->second->connect(cb);;
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::signals2::connection LLMaterialMgr::getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, LLMaterialMgr::get_callback_te_t::slot_type cb)
|
||||||
|
{
|
||||||
|
boost::signals2::connection connection;
|
||||||
|
|
||||||
|
material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
|
||||||
|
if (itMaterial != mMaterials.end())
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL;
|
||||||
|
get_callback_te_t signal;
|
||||||
|
signal.connect(cb);
|
||||||
|
signal(material_id, itMaterial->second, te);
|
||||||
|
connection = boost::signals2::connection();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!isGetPending(region_id, material_id))
|
||||||
|
{
|
||||||
|
get_queue_t::iterator itQueue = mGetQueue.find(region_id);
|
||||||
|
if (mGetQueue.end() == itQueue)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL;
|
||||||
|
std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
|
||||||
|
itQueue = ret.first;
|
||||||
|
}
|
||||||
|
LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL;
|
||||||
|
itQueue->second.insert(material_id);
|
||||||
|
markGetPending(region_id, material_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMaterialPair te_mat_pair;
|
||||||
|
te_mat_pair.te = te;
|
||||||
|
te_mat_pair.materialID = material_id;
|
||||||
|
|
||||||
|
get_callback_te_map_t::iterator itCallback = mGetTECallbacks.find(te_mat_pair);
|
||||||
|
if (itCallback == mGetTECallbacks.end())
|
||||||
|
{
|
||||||
|
std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.insert(std::pair<TEMaterialPair, get_callback_te_t*>(te_mat_pair, new get_callback_te_t()));
|
||||||
|
itCallback = ret.first;
|
||||||
|
}
|
||||||
|
connection = itCallback->second->connect(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLMaterialMgr::isGetAllPending(const LLUUID& region_id) const
|
||||||
|
{
|
||||||
|
getall_pending_map_t::const_iterator itPending = mGetAllPending.find(region_id);
|
||||||
|
return (mGetAllPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_GET_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::getAll(const LLUUID& region_id)
|
||||||
|
{
|
||||||
|
if (!isGetAllPending(region_id))
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "queuing for region " << region_id << LL_ENDL;
|
||||||
|
mGetAllQueue.insert(region_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "already pending for region " << region_id << LL_ENDL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMaterialMgr::getall_callback_t::slot_type cb)
|
||||||
|
{
|
||||||
|
if (!isGetAllPending(region_id))
|
||||||
|
{
|
||||||
|
mGetAllQueue.insert(region_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id);
|
||||||
|
if (mGetAllCallbacks.end() == itCallback)
|
||||||
|
{
|
||||||
|
std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.insert(std::pair<LLUUID, getall_callback_t*>(region_id, new getall_callback_t()));
|
||||||
|
itCallback = ret.first;
|
||||||
|
}
|
||||||
|
return itCallback->second->connect(cb);;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& material)
|
||||||
|
{
|
||||||
|
put_queue_t::iterator itQueue = mPutQueue.find(object_id);
|
||||||
|
if (mPutQueue.end() == itQueue)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "mPutQueue insert object " << object_id << LL_ENDL;
|
||||||
|
mPutQueue.insert(std::pair<LLUUID, facematerial_map_t>(object_id, facematerial_map_t()));
|
||||||
|
itQueue = mPutQueue.find(object_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
facematerial_map_t::iterator itFace = itQueue->second.find(te);
|
||||||
|
if (itQueue->second.end() == itFace)
|
||||||
|
{
|
||||||
|
itQueue->second.insert(std::pair<U8, LLMaterial>(te, material));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itFace->second = material;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::remove(const LLUUID& object_id, const U8 te)
|
||||||
|
{
|
||||||
|
put(object_id, te, LLMaterial::null);
|
||||||
|
}
|
||||||
|
|
||||||
|
const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
|
||||||
|
material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
|
||||||
|
if (mMaterials.end() == itMaterial)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "new material" << LL_ENDL;
|
||||||
|
LLMaterialPtr newMaterial(new LLMaterial(material_data));
|
||||||
|
std::pair<material_map_t::const_iterator, bool> ret = mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, newMaterial));
|
||||||
|
itMaterial = ret.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we may have cleared our queues on leaving a region before we recv'd our
|
||||||
|
// update for this material...too late now!
|
||||||
|
//
|
||||||
|
if (isGetPending(region_id, material_id))
|
||||||
|
{
|
||||||
|
|
||||||
|
TEMaterialPair te_mat_pair;
|
||||||
|
te_mat_pair.materialID = material_id;
|
||||||
|
|
||||||
|
U32 i = 0;
|
||||||
|
while (i < LLTEContents::MAX_TES)
|
||||||
|
{
|
||||||
|
te_mat_pair.te = i++;
|
||||||
|
get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair);
|
||||||
|
if (itCallbackTE != mGetTECallbacks.end())
|
||||||
|
{
|
||||||
|
(*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te);
|
||||||
|
delete itCallbackTE->second;
|
||||||
|
mGetTECallbacks.erase(itCallbackTE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
|
||||||
|
if (itCallback != mGetCallbacks.end())
|
||||||
|
{
|
||||||
|
(*itCallback->second)(material_id, itMaterial->second);
|
||||||
|
|
||||||
|
delete itCallback->second;
|
||||||
|
mGetCallbacks.erase(itCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mGetPending.erase(pending_material_t(region_id, material_id));
|
||||||
|
|
||||||
|
return itMaterial->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUID& region_id)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
// *TODO: is there any kind of error handling we can do here?
|
||||||
|
LL_WARNS("Materials")<< "failed"<<LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
llassert(content.isMap());
|
||||||
|
llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
|
||||||
|
llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
|
||||||
|
|
||||||
|
LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
|
||||||
|
std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
|
||||||
|
std::istringstream content_stream(content_string);
|
||||||
|
|
||||||
|
LLSD response_data;
|
||||||
|
if (!unzip_llsd(response_data, content_stream, content_binary.size()))
|
||||||
|
{
|
||||||
|
LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
llassert(response_data.isArray());
|
||||||
|
LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
|
||||||
|
for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial)
|
||||||
|
{
|
||||||
|
const LLSD& material_data = *itMaterial;
|
||||||
|
llassert(material_data.isMap());
|
||||||
|
|
||||||
|
llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
|
||||||
|
llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary());
|
||||||
|
LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary());
|
||||||
|
|
||||||
|
llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD));
|
||||||
|
llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap());
|
||||||
|
|
||||||
|
setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
// *TODO: is there any kind of error handling we can do here?
|
||||||
|
LL_WARNS("Materials")<< "failed"<<LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
llassert(content.isMap());
|
||||||
|
llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
|
||||||
|
llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
|
||||||
|
|
||||||
|
LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
|
||||||
|
std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
|
||||||
|
std::istringstream content_stream(content_string);
|
||||||
|
|
||||||
|
LLSD response_data;
|
||||||
|
if (!unzip_llsd(response_data, content_stream, content_binary.size()))
|
||||||
|
{
|
||||||
|
LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_queue_t::iterator itQueue = mGetQueue.find(region_id);
|
||||||
|
material_map_t materials;
|
||||||
|
|
||||||
|
llassert(response_data.isArray());
|
||||||
|
LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
|
||||||
|
for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial)
|
||||||
|
{
|
||||||
|
const LLSD& material_data = *itMaterial;
|
||||||
|
llassert(material_data.isMap());
|
||||||
|
|
||||||
|
llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
|
||||||
|
llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary());
|
||||||
|
LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary());
|
||||||
|
if (mGetQueue.end() != itQueue)
|
||||||
|
{
|
||||||
|
itQueue->second.erase(material_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD));
|
||||||
|
llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap());
|
||||||
|
LLMaterialPtr material = setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]);
|
||||||
|
|
||||||
|
materials[material_id] = material;
|
||||||
|
}
|
||||||
|
|
||||||
|
getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id);
|
||||||
|
if (itCallback != mGetAllCallbacks.end())
|
||||||
|
{
|
||||||
|
(*itCallback->second)(region_id, materials);
|
||||||
|
|
||||||
|
delete itCallback->second;
|
||||||
|
mGetAllCallbacks.erase(itCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (mGetQueue.end() != itQueue) && (itQueue->second.empty()) )
|
||||||
|
{
|
||||||
|
mGetQueue.erase(itQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
LL_DEBUGS("Materials")<< "recording that getAll has been done for region id " << region_id << LL_ENDL;
|
||||||
|
mGetAllRequested.insert(region_id); // prevents subsequent getAll requests for this region
|
||||||
|
mGetAllPending.erase(region_id); // Invalidates region_id
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
// *TODO: is there any kind of error handling we can do here?
|
||||||
|
LL_WARNS("Materials")<< "failed"<<LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
llassert(content.isMap());
|
||||||
|
llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
|
||||||
|
llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
|
||||||
|
|
||||||
|
LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
|
||||||
|
std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
|
||||||
|
std::istringstream content_stream(content_string);
|
||||||
|
|
||||||
|
LLSD response_data;
|
||||||
|
if (!unzip_llsd(response_data, content_stream, content_binary.size()))
|
||||||
|
{
|
||||||
|
LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
llassert(response_data.isArray());
|
||||||
|
LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
|
||||||
|
for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter)
|
||||||
|
{
|
||||||
|
# ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||||
|
const LLSD& face_data = *faceIter; // conditional to avoid unused variable warning
|
||||||
|
# endif
|
||||||
|
llassert(face_data.isMap());
|
||||||
|
|
||||||
|
llassert(face_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
|
||||||
|
llassert(face_data[MATERIALS_CAP_OBJECT_ID_FIELD].isInteger());
|
||||||
|
// U32 local_id = face_data[MATERIALS_CAP_OBJECT_ID_FIELD].asInteger();
|
||||||
|
|
||||||
|
llassert(face_data.has(MATERIALS_CAP_FACE_FIELD));
|
||||||
|
llassert(face_data[MATERIALS_CAP_FACE_FIELD].isInteger());
|
||||||
|
// S32 te = face_data[MATERIALS_CAP_FACE_FIELD].asInteger();
|
||||||
|
|
||||||
|
llassert(face_data.has(MATERIALS_CAP_MATERIAL_ID_FIELD));
|
||||||
|
llassert(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].isBinary());
|
||||||
|
// LLMaterialID material_id(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].asBinary());
|
||||||
|
|
||||||
|
// *TODO: do we really still need to process this?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LLFastTimer::DeclareTimer FTM_MATERIALS_IDLE("Materials");
|
||||||
|
|
||||||
|
void LLMaterialMgr::onIdle(void*)
|
||||||
|
{
|
||||||
|
LLFastTimer t(FTM_MATERIALS_IDLE);
|
||||||
|
|
||||||
|
LLMaterialMgr* instancep = LLMaterialMgr::getInstance();
|
||||||
|
|
||||||
|
if (!instancep->mGetQueue.empty())
|
||||||
|
{
|
||||||
|
instancep->processGetQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!instancep->mGetAllQueue.empty())
|
||||||
|
{
|
||||||
|
instancep->processGetAllQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
static LLFrameTimer mPutTimer;
|
||||||
|
if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) )
|
||||||
|
{
|
||||||
|
instancep->processPutQueue();
|
||||||
|
mPutTimer.reset(MATERIALS_PUT_THROTTLE_SECS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::processGetQueue()
|
||||||
|
{
|
||||||
|
get_queue_t::iterator loopRegionQueue = mGetQueue.begin();
|
||||||
|
while (mGetQueue.end() != loopRegionQueue)
|
||||||
|
{
|
||||||
|
get_queue_t::iterator itRegionQueue = loopRegionQueue++;
|
||||||
|
|
||||||
|
const LLUUID& region_id = itRegionQueue->first;
|
||||||
|
if (isGetAllPending(region_id))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
|
||||||
|
if (!regionp)
|
||||||
|
{
|
||||||
|
LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
|
||||||
|
mGetQueue.erase(itRegionQueue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!regionp->capabilitiesReceived())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (mGetAllRequested.end() == mGetAllRequested.find(region_id))
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL;
|
||||||
|
getAll(region_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
|
||||||
|
if (capURL.empty())
|
||||||
|
{
|
||||||
|
LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
|
||||||
|
<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
|
||||||
|
mGetQueue.erase(itRegionQueue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSD materialsData = LLSD::emptyArray();
|
||||||
|
|
||||||
|
material_queue_t& materials = itRegionQueue->second;
|
||||||
|
material_queue_t::iterator loopMaterial = materials.begin();
|
||||||
|
while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) )
|
||||||
|
{
|
||||||
|
material_queue_t::iterator itMaterial = loopMaterial++;
|
||||||
|
materialsData.append((*itMaterial).asLLSD());
|
||||||
|
materials.erase(itMaterial);
|
||||||
|
markGetPending(region_id, *itMaterial);
|
||||||
|
}
|
||||||
|
if (materials.empty())
|
||||||
|
{
|
||||||
|
mGetQueue.erase(itRegionQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string materialString = zip_llsd(materialsData);
|
||||||
|
|
||||||
|
S32 materialSize = materialString.size();
|
||||||
|
if (materialSize <= 0)
|
||||||
|
{
|
||||||
|
LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSD::Binary materialBinary;
|
||||||
|
materialBinary.resize(materialSize);
|
||||||
|
memcpy(materialBinary.data(), materialString.data(), materialSize);
|
||||||
|
|
||||||
|
LLSD postData = LLSD::emptyMap();
|
||||||
|
postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
|
||||||
|
|
||||||
|
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id));
|
||||||
|
LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials."
|
||||||
|
<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
|
||||||
|
LLHTTPClient::post(capURL, postData, materialsResponder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::processGetAllQueue()
|
||||||
|
{
|
||||||
|
getall_queue_t::iterator loopRegion = mGetAllQueue.begin();
|
||||||
|
while (mGetAllQueue.end() != loopRegion)
|
||||||
|
{
|
||||||
|
getall_queue_t::iterator itRegion = loopRegion++;
|
||||||
|
|
||||||
|
const LLUUID& region_id = *itRegion;
|
||||||
|
LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
|
||||||
|
if (regionp == NULL)
|
||||||
|
{
|
||||||
|
LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
|
||||||
|
clearGetQueues(region_id); // Invalidates region_id
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!regionp->capabilitiesReceived())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
|
||||||
|
if (capURL.empty())
|
||||||
|
{
|
||||||
|
LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
|
||||||
|
<< "' is not defined on the current region '" << regionp->getName() << "'" << LL_ENDL;
|
||||||
|
clearGetQueues(region_id); // Invalidates region_id
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL;
|
||||||
|
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion));
|
||||||
|
LLHTTPClient::get(capURL, materialsResponder);
|
||||||
|
mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
|
||||||
|
mGetAllQueue.erase(itRegion); // Invalidates region_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::processPutQueue()
|
||||||
|
{
|
||||||
|
typedef std::map<const LLViewerRegion*, LLSD> regionput_request_map;
|
||||||
|
regionput_request_map requests;
|
||||||
|
|
||||||
|
put_queue_t::iterator loopQueue = mPutQueue.begin();
|
||||||
|
while (mPutQueue.end() != loopQueue)
|
||||||
|
{
|
||||||
|
put_queue_t::iterator itQueue = loopQueue++;
|
||||||
|
|
||||||
|
const LLUUID& object_id = itQueue->first;
|
||||||
|
const LLViewerObject* objectp = gObjectList.findObject(object_id);
|
||||||
|
if ( (!objectp) || (!objectp->getRegion()) )
|
||||||
|
{
|
||||||
|
LL_WARNS("Materials") << "Object or object region is NULL" << LL_ENDL;
|
||||||
|
|
||||||
|
mPutQueue.erase(itQueue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LLViewerRegion* regionp = objectp->getRegion();
|
||||||
|
if (!regionp->capabilitiesReceived())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSD& facesData = requests[regionp];
|
||||||
|
|
||||||
|
facematerial_map_t& face_map = itQueue->second;
|
||||||
|
facematerial_map_t::iterator itFace = face_map.begin();
|
||||||
|
while ( (face_map.end() != itFace) && (facesData.size() < MATERIALS_GET_MAX_ENTRIES) )
|
||||||
|
{
|
||||||
|
LLSD faceData = LLSD::emptyMap();
|
||||||
|
faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
|
||||||
|
faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
|
||||||
|
if (!itFace->second.isNull())
|
||||||
|
{
|
||||||
|
faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
|
||||||
|
}
|
||||||
|
facesData.append(faceData);
|
||||||
|
face_map.erase(itFace++);
|
||||||
|
}
|
||||||
|
if (face_map.empty())
|
||||||
|
{
|
||||||
|
mPutQueue.erase(itQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest)
|
||||||
|
{
|
||||||
|
std::string capURL = itRequest->first->getCapability(MATERIALS_CAPABILITY_NAME);
|
||||||
|
if (capURL.empty())
|
||||||
|
{
|
||||||
|
LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
|
||||||
|
<< "' is not defined on region '" << itRequest->first->getName() << "'" << LL_ENDL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSD materialsData = LLSD::emptyMap();
|
||||||
|
materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = itRequest->second;
|
||||||
|
|
||||||
|
std::string materialString = zip_llsd(materialsData);
|
||||||
|
|
||||||
|
S32 materialSize = materialString.size();
|
||||||
|
|
||||||
|
if (materialSize > 0)
|
||||||
|
{
|
||||||
|
LLSD::Binary materialBinary;
|
||||||
|
materialBinary.resize(materialSize);
|
||||||
|
memcpy(materialBinary.data(), materialString.data(), materialSize);
|
||||||
|
|
||||||
|
LLSD putData = LLSD::emptyMap();
|
||||||
|
putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
|
||||||
|
|
||||||
|
LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
|
||||||
|
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
|
||||||
|
LLHTTPClient::put(capURL, putData, materialsResponder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::clearGetQueues(const LLUUID& region_id)
|
||||||
|
{
|
||||||
|
mGetQueue.erase(region_id);
|
||||||
|
for (get_pending_map_t::iterator itPending = mGetPending.begin(); itPending != mGetPending.end();)
|
||||||
|
{
|
||||||
|
if (region_id == itPending->first.first)
|
||||||
|
{
|
||||||
|
mGetPending.erase(itPending++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++itPending;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mGetAllQueue.erase(region_id);
|
||||||
|
mGetAllRequested.erase(region_id);
|
||||||
|
mGetAllPending.erase(region_id);
|
||||||
|
mGetAllCallbacks.erase(region_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLMaterialMgr::onRegionRemoved(LLViewerRegion* regionp)
|
||||||
|
{
|
||||||
|
clearGetQueues(regionp->getRegionID());
|
||||||
|
// Put doesn't need clearing: objects that can't be found will clean up in processPutQueue()
|
||||||
|
}
|
||||||
|
|
||||||
130
indra/newview/llmaterialmgr.h
Normal file
130
indra/newview/llmaterialmgr.h
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/**
|
||||||
|
* @file llmaterialmgr.h
|
||||||
|
* @brief Material manager
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LL_LLMATERIALMGR_H
|
||||||
|
#define LL_LLMATERIALMGR_H
|
||||||
|
|
||||||
|
#include "llmaterial.h"
|
||||||
|
#include "llmaterialid.h"
|
||||||
|
#include "llsingleton.h"
|
||||||
|
|
||||||
|
class LLViewerRegion;
|
||||||
|
|
||||||
|
class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
|
||||||
|
{
|
||||||
|
friend class LLSingleton<LLMaterialMgr>;
|
||||||
|
protected:
|
||||||
|
LLMaterialMgr();
|
||||||
|
virtual ~LLMaterialMgr();
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef std::map<LLMaterialID, LLMaterialPtr> material_map_t;
|
||||||
|
|
||||||
|
typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr)> get_callback_t;
|
||||||
|
const LLMaterialPtr get(const LLUUID& region_id, const LLMaterialID& material_id);
|
||||||
|
boost::signals2::connection get(const LLUUID& region_id, const LLMaterialID& material_id, get_callback_t::slot_type cb);
|
||||||
|
|
||||||
|
typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr, U32 te)> get_callback_te_t;
|
||||||
|
boost::signals2::connection getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, get_callback_te_t::slot_type cb);
|
||||||
|
|
||||||
|
typedef boost::signals2::signal<void (const LLUUID&, const material_map_t&)> getall_callback_t;
|
||||||
|
void getAll(const LLUUID& region_id);
|
||||||
|
boost::signals2::connection getAll(const LLUUID& region_id, getall_callback_t::slot_type cb);
|
||||||
|
void put(const LLUUID& object_id, const U8 te, const LLMaterial& material);
|
||||||
|
void remove(const LLUUID& object_id, const U8 te);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void clearGetQueues(const LLUUID& region_id);
|
||||||
|
bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const;
|
||||||
|
bool isGetAllPending(const LLUUID& region_id) const;
|
||||||
|
void markGetPending(const LLUUID& region_id, const LLMaterialID& material_id);
|
||||||
|
const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data);
|
||||||
|
|
||||||
|
static void onIdle(void*);
|
||||||
|
void processGetQueue();
|
||||||
|
void onGetResponse(bool success, const LLSD& content, const LLUUID& region_id);
|
||||||
|
void processGetAllQueue();
|
||||||
|
void onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id);
|
||||||
|
void processPutQueue();
|
||||||
|
void onPutResponse(bool success, const LLSD& content);
|
||||||
|
void onRegionRemoved(LLViewerRegion* regionp);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef std::set<LLMaterialID> material_queue_t;
|
||||||
|
typedef std::map<LLUUID, material_queue_t> get_queue_t;
|
||||||
|
get_queue_t mGetQueue;
|
||||||
|
typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
|
||||||
|
typedef std::map<const pending_material_t, F64> get_pending_map_t;
|
||||||
|
get_pending_map_t mGetPending;
|
||||||
|
typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
|
||||||
|
get_callback_map_t mGetCallbacks;
|
||||||
|
|
||||||
|
// struct for TE-specific material ID query
|
||||||
|
class TEMaterialPair
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
U32 te;
|
||||||
|
LLMaterialID materialID;
|
||||||
|
|
||||||
|
bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); }
|
||||||
|
};
|
||||||
|
|
||||||
|
friend inline bool operator<(
|
||||||
|
const LLMaterialMgr::TEMaterialPair& lhs,
|
||||||
|
const LLMaterialMgr::TEMaterialPair& rhs)
|
||||||
|
{
|
||||||
|
return (lhs.te < rhs.te) ? TRUE :
|
||||||
|
(lhs.materialID < rhs.materialID);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TEMaterialPairHasher
|
||||||
|
{
|
||||||
|
enum { bucket_size = 8 };
|
||||||
|
size_t operator()(const TEMaterialPair& key_value) const { return *((size_t*)key_value.materialID.get()); } // cheesy, but effective
|
||||||
|
bool operator()(const TEMaterialPair& left, const TEMaterialPair& right) const { return left < right; }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*, TEMaterialPairHasher> get_callback_te_map_t;
|
||||||
|
get_callback_te_map_t mGetTECallbacks;
|
||||||
|
|
||||||
|
typedef std::set<LLUUID> getall_queue_t;
|
||||||
|
getall_queue_t mGetAllQueue;
|
||||||
|
getall_queue_t mGetAllRequested;
|
||||||
|
typedef std::map<LLUUID, F64> getall_pending_map_t;
|
||||||
|
getall_pending_map_t mGetAllPending;
|
||||||
|
typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t;
|
||||||
|
getall_callback_map_t mGetAllCallbacks;
|
||||||
|
|
||||||
|
typedef std::map<U8, LLMaterial> facematerial_map_t;
|
||||||
|
typedef std::map<LLUUID, facematerial_map_t> put_queue_t;
|
||||||
|
put_queue_t mPutQueue;
|
||||||
|
|
||||||
|
material_map_t mMaterials;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LL_LLMATERIALMGR_H
|
||||||
|
|
||||||
@@ -840,6 +840,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to
|
|||||||
if (objectp->getNumTEs() > 0)
|
if (objectp->getNumTEs() > 0)
|
||||||
{
|
{
|
||||||
nodep->selectAllTEs(TRUE);
|
nodep->selectAllTEs(TRUE);
|
||||||
|
objectp->setAllTESelected(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -897,10 +898,12 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
|
|||||||
else if (face == SELECT_ALL_TES)
|
else if (face == SELECT_ALL_TES)
|
||||||
{
|
{
|
||||||
nodep->selectAllTEs(TRUE);
|
nodep->selectAllTEs(TRUE);
|
||||||
|
objectp->setAllTESelected(true);
|
||||||
}
|
}
|
||||||
else if (0 <= face && face < SELECT_MAX_TES)
|
else if (0 <= face && face < SELECT_MAX_TES)
|
||||||
{
|
{
|
||||||
nodep->selectTE(face, TRUE);
|
nodep->selectTE(face, TRUE);
|
||||||
|
objectp->setTESelected(face, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1124,6 +1127,7 @@ LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()
|
|||||||
|
|
||||||
// flag this object as selected
|
// flag this object as selected
|
||||||
objectp->setSelected(TRUE);
|
objectp->setSelected(TRUE);
|
||||||
|
objectp->setAllTESelected(true);
|
||||||
|
|
||||||
mSelectedObjects->mSelectType = getSelectTypeForObject(objectp);
|
mSelectedObjects->mSelectType = getSelectTypeForObject(objectp);
|
||||||
|
|
||||||
@@ -1351,6 +1355,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
|
|||||||
if (nodep->isTESelected(te))
|
if (nodep->isTESelected(te))
|
||||||
{
|
{
|
||||||
nodep->selectTE(te, FALSE);
|
nodep->selectTE(te, FALSE);
|
||||||
|
objectp->setTESelected(te, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1671,6 +1671,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
|||||||
capabilityNames.append("ProductInfoRequest");
|
capabilityNames.append("ProductInfoRequest");
|
||||||
capabilityNames.append("ProvisionVoiceAccountRequest");
|
capabilityNames.append("ProvisionVoiceAccountRequest");
|
||||||
capabilityNames.append("RemoteParcelRequest");
|
capabilityNames.append("RemoteParcelRequest");
|
||||||
|
capabilityNames.append("RenderMaterials");
|
||||||
capabilityNames.append("RequestTextureDownload");
|
capabilityNames.append("RequestTextureDownload");
|
||||||
//capabilityNames.append("ResourceCostSelected"); //Object weights (llfloaterobjectweights.cpp)
|
//capabilityNames.append("ResourceCostSelected"); //Object weights (llfloaterobjectweights.cpp)
|
||||||
capabilityNames.append("RetrieveNavMeshSrc");
|
capabilityNames.append("RetrieveNavMeshSrc");
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include "lldir.h"
|
#include "lldir.h"
|
||||||
#include "llflexibleobject.h"
|
#include "llflexibleobject.h"
|
||||||
#include "llfloatertools.h"
|
#include "llfloatertools.h"
|
||||||
|
#include "llmaterialid.h"
|
||||||
#include "llmaterialtable.h"
|
#include "llmaterialtable.h"
|
||||||
#include "llprimitive.h"
|
#include "llprimitive.h"
|
||||||
#include "llvolume.h"
|
#include "llvolume.h"
|
||||||
@@ -81,6 +82,7 @@
|
|||||||
#include "llviewershadermgr.h"
|
#include "llviewershadermgr.h"
|
||||||
#include "llvoavatar.h"
|
#include "llvoavatar.h"
|
||||||
#include "llvocache.h"
|
#include "llvocache.h"
|
||||||
|
#include "llmaterialmgr.h"
|
||||||
|
|
||||||
// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.0d)
|
// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.0d)
|
||||||
#include "rlvhandler.h"
|
#include "rlvhandler.h"
|
||||||
@@ -1942,6 +1944,48 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams, U32 te)
|
||||||
|
{
|
||||||
|
LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID);
|
||||||
|
if (pVol)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL;
|
||||||
|
if (te >= pVol->getNumTEs())
|
||||||
|
return;
|
||||||
|
|
||||||
|
LLTextureEntry* texture_entry = pVol->getTE(te);
|
||||||
|
if (texture_entry && (texture_entry->getMaterialID() == pMaterialID))
|
||||||
|
{
|
||||||
|
pVol->setTEMaterialParams(te, pMaterialParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
|
||||||
|
{
|
||||||
|
S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
|
||||||
|
LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res
|
||||||
|
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
|
||||||
|
<< LL_ENDL;
|
||||||
|
|
||||||
|
LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL;
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3));
|
||||||
|
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
|
||||||
|
{
|
||||||
|
S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
|
||||||
|
LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
|
||||||
|
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
|
||||||
|
<< LL_ENDL;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
|
S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
|
||||||
{
|
{
|
||||||
S32 res = LLViewerObject::setTEScale(te, s, t);
|
S32 res = LLViewerObject::setTEScale(te, s, t);
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
class LLViewerTextureAnim;
|
class LLViewerTextureAnim;
|
||||||
class LLDrawPool;
|
class LLDrawPool;
|
||||||
|
class LLMaterialID;
|
||||||
class LLSelectNode;
|
class LLSelectNode;
|
||||||
class LLObjectMediaDataClient;
|
class LLObjectMediaDataClient;
|
||||||
class LLObjectMediaNavigateClient;
|
class LLObjectMediaNavigateClient;
|
||||||
@@ -191,6 +192,11 @@ public:
|
|||||||
/*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump);
|
/*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump);
|
||||||
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags);
|
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags);
|
||||||
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
|
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
|
||||||
|
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
|
||||||
|
|
||||||
|
static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te);
|
||||||
|
|
||||||
|
/*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
|
||||||
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
|
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
|
||||||
/*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
|
/*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
|
||||||
/*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
|
/*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
|
||||||
|
|||||||
@@ -293,6 +293,7 @@ void LLWorld::removeRegion(const LLHost &host)
|
|||||||
mCulledRegionList.remove(regionp);
|
mCulledRegionList.remove(regionp);
|
||||||
mVisibleRegionList.remove(regionp);
|
mVisibleRegionList.remove(regionp);
|
||||||
|
|
||||||
|
mRegionRemovedSignal(regionp);
|
||||||
//double check all objects of this region are removed.
|
//double check all objects of this region are removed.
|
||||||
gObjectList.clearAllMapObjectsInRegion(regionp) ;
|
gObjectList.clearAllMapObjectsInRegion(regionp) ;
|
||||||
//llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ;
|
//llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ;
|
||||||
@@ -420,6 +421,19 @@ LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LLViewerRegion* LLWorld::getRegionFromID(const LLUUID& region_id)
|
||||||
|
{
|
||||||
|
for (region_list_t::iterator iter = mRegionList.begin();
|
||||||
|
iter != mRegionList.end(); ++iter)
|
||||||
|
{
|
||||||
|
LLViewerRegion* regionp = *iter;
|
||||||
|
if (regionp->getRegionID() == region_id)
|
||||||
|
{
|
||||||
|
return regionp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void LLWorld::updateAgentOffset(const LLVector3d &offset_global)
|
void LLWorld::updateAgentOffset(const LLVector3d &offset_global)
|
||||||
{
|
{
|
||||||
@@ -1506,6 +1520,11 @@ bool LLWorld::isRegionListed(const LLViewerRegion* region) const
|
|||||||
return it != mRegionList.end();
|
return it != mRegionList.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::signals2::connection LLWorld::setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb)
|
||||||
|
{
|
||||||
|
return mRegionRemovedSignal.connect(cb);
|
||||||
|
}
|
||||||
|
|
||||||
LLHTTPRegistration<LLEstablishAgentCommunication>
|
LLHTTPRegistration<LLEstablishAgentCommunication>
|
||||||
gHTTPRegistrationEstablishAgentCommunication(
|
gHTTPRegistrationEstablishAgentCommunication(
|
||||||
"/message/EstablishAgentCommunication");
|
"/message/EstablishAgentCommunication");
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ public:
|
|||||||
LLViewerRegion* getRegionFromPosGlobal(const LLVector3d &pos);
|
LLViewerRegion* getRegionFromPosGlobal(const LLVector3d &pos);
|
||||||
LLViewerRegion* getRegionFromPosAgent(const LLVector3 &pos);
|
LLViewerRegion* getRegionFromPosAgent(const LLVector3 &pos);
|
||||||
LLViewerRegion* getRegionFromHandle(const U64 &handle);
|
LLViewerRegion* getRegionFromHandle(const U64 &handle);
|
||||||
|
LLViewerRegion* getRegionFromID(const LLUUID& region_id);
|
||||||
BOOL positionRegionValidGlobal(const LLVector3d& pos); // true if position is in valid region
|
BOOL positionRegionValidGlobal(const LLVector3d& pos); // true if position is in valid region
|
||||||
LLVector3d clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos);
|
LLVector3d clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos);
|
||||||
|
|
||||||
@@ -157,6 +158,8 @@ public:
|
|||||||
typedef std::list<LLViewerRegion*> region_list_t;
|
typedef std::list<LLViewerRegion*> region_list_t;
|
||||||
const region_list_t& getRegionList() const { return mActiveRegionList; }
|
const region_list_t& getRegionList() const { return mActiveRegionList; }
|
||||||
|
|
||||||
|
typedef boost::signals2::signal<void(LLViewerRegion*)> region_remove_signal_t;
|
||||||
|
boost::signals2::connection setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb);
|
||||||
// Returns lists of avatar IDs and their world-space positions within a given distance of a point.
|
// Returns lists of avatar IDs and their world-space positions within a given distance of a point.
|
||||||
// All arguments are optional. Given containers will be emptied and then filled.
|
// All arguments are optional. Given containers will be emptied and then filled.
|
||||||
// Not supplying origin or radius input returns data on all avatars in the known regions.
|
// Not supplying origin or radius input returns data on all avatars in the known regions.
|
||||||
@@ -176,6 +179,8 @@ private:
|
|||||||
region_list_t mVisibleRegionList;
|
region_list_t mVisibleRegionList;
|
||||||
region_list_t mCulledRegionList;
|
region_list_t mCulledRegionList;
|
||||||
|
|
||||||
|
region_remove_signal_t mRegionRemovedSignal;
|
||||||
|
|
||||||
// Number of points on edge
|
// Number of points on edge
|
||||||
static const U32 mWidth;
|
static const U32 mWidth;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user