diff options
Diffstat (limited to 'indra/llprimitive')
-rw-r--r-- | indra/llprimitive/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/llprimitive/llmaterial.cpp | 166 | ||||
-rw-r--r-- | indra/llprimitive/llmaterial.h | 101 |
3 files changed, 269 insertions, 0 deletions
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 82d0f892f2..4eef1673f4 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -21,6 +21,7 @@ include_directories( set(llprimitive_SOURCE_FILES llmaterialid.cpp + llmaterial.cpp llmaterialtable.cpp llmediaentry.cpp llmodel.cpp @@ -38,6 +39,7 @@ set(llprimitive_HEADER_FILES CMakeLists.txt legacy_object_types.h + llmaterial.h llmaterialid.h llmaterialtable.h llmediaentry.h diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp new file mode 100644 index 0000000000..645fcf7b46 --- /dev/null +++ b/indra/llprimitive/llmaterial.cpp @@ -0,0 +1,166 @@ +/** + * @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" + +/** + * Materials constants + */ + +const LLColor4U MATERIALS_DEFAULT_SPECULAR_COLOR = LLColor4U(255, 255, 255, 255); +const U8 MATERIALS_DEFAULT_SPECULAR_EXP = 128; +const U8 MATERIALS_DEFAULT_ENV_INTENSITY = 128; +const U8 MATERIALS_DEFAULT_DIFFUSE_ALPHA_MODE = 0; +const U8 MATERIALS_DEFAULT_ALPHA_MASK_CUTOFF = 128; +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() + : mSpecularLightColor(MATERIALS_DEFAULT_SPECULAR_COLOR) + , mSpecularLightExponent(MATERIALS_DEFAULT_SPECULAR_EXP) + , mEnvironmentIntensity(MATERIALS_DEFAULT_ENV_INTENSITY) + , mDiffuseAlphaMode(MATERIALS_DEFAULT_DIFFUSE_ALPHA_MODE) + , mAlphaMaskCutoff(MATERIALS_DEFAULT_ALPHA_MASK_CUTOFF) +{ +} + +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 +{ + // *TODO: find a better way of defining a 'null' material? + return + (mNormalID.isNull()) && (.0f == mNormalOffsetX) && (.0f == mNormalOffsetY) && (.0f == mNormalRepeatX) && (.0f == mNormalRepeatY) && + (mSpecularID.isNull()) && (.0f == mSpecularOffsetX) && (.0f == mSpecularOffsetY) && (.0f == mSpecularRepeatX) && (.0f == mSpecularRepeatY); +} diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h new file mode 100644 index 0000000000..da364e548c --- /dev/null +++ b/indra/llprimitive/llmaterial.h @@ -0,0 +1,101 @@ +/** + * @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" + +class LLMaterial +{ +public: + 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; } + void setNormalOffset(F32 offset_x, F32 offset_y) { mNormalOffsetX = offset_x; mNormalOffsetY = offset_y; } + void getNormalRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mNormalRepeatX; repeat_y = mNormalRepeatY; } + void setNormalRepeat(F32 repeat_x, F32 repeat_y) { mNormalRepeatX = repeat_x; 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; } + void setSpecularOffset(F32 offset_x, F32 offset_y) { mSpecularOffsetX = offset_x; mSpecularOffsetY = offset_y; } + void getSpecularRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mSpecularRepeatX; repeat_y = mSpecularRepeatY; } + void setSpecularRepeat(F32 repeat_x, F32 repeat_y) { mSpecularRepeatX = repeat_x; 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; + +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 boost::shared_ptr<LLMaterial> LLMaterialPtr; + +#endif // LL_LLMATERIAL_H |