Merge remote-tracking branch 'upstream/development' into AssimpLoaader-Fix

This commit is contained in:
marauder2k7 2024-02-22 10:01:32 +00:00
commit 1ccf4cff85
42 changed files with 1294 additions and 84 deletions

View file

@ -79,7 +79,7 @@ if(TORQUE_SFX_OPENAL AND NOT TORQUE_DEDICATED)
endif()
endif()
# Handle GFX
torqueAddSourceDirectories("gfx" "gfx/Null" "gfx/test" "gfx/bitmap" "gfx/bitmap/loaders"
torqueAddSourceDirectories("gfx" "gfx/Null" "gfx/test" "gfx/bitmap" "gfx/bitmap/loaders" "gfx/bitmap/loaders/ies"
"gfx/util" "gfx/video" "gfx/sim" )
# add the stb headers

View file

@ -33,6 +33,8 @@
#include "core/resourceManager.h"
#include "scene/sceneManager.h"
#include "scene/sceneRenderState.h"
#include "renderInstance/renderProbeMgr.h"
#include "T3D/lighting/skylight.h"
// GuiMaterialPreview
GuiMaterialPreview::GuiMaterialPreview()
@ -372,6 +374,9 @@ void GuiMaterialPreview::renderWorld(const RectI &updateRect)
FogData savedFogData = gClientSceneGraph->getFogData();
gClientSceneGraph->setFogData( FogData() ); // no fog in preview window
if (Skylight::smSkylightProbe.isValid())
PROBEMGR->submitProbe(Skylight::smSkylightProbe->getProbeInfo());
RenderPassManager* renderPass = gClientSceneGraph->getDefaultRenderPass();
SceneRenderState state
(

View file

@ -31,6 +31,8 @@
#include "math/mathTypes.h"
#include "gfx/gfxTransformSaver.h"
#include "console/engineAPI.h"
#include "renderInstance/renderProbeMgr.h"
#include "T3D/lighting/skylight.h"
IMPLEMENT_CONOBJECT( GuiObjectView );
@ -541,6 +543,12 @@ void GuiObjectView::renderWorld( const RectI& updateRect )
// Render primary model.
if (Skylight::smSkylightProbe.isValid())
PROBEMGR->submitProbe(Skylight::smSkylightProbe->getProbeInfo());
FogData savedFogData = gClientSceneGraph->getFogData();
gClientSceneGraph->setFogData(FogData()); // no fog in preview window
if(mModelInstance)
{
if( mRunThread )
@ -567,6 +575,7 @@ void GuiObjectView::renderWorld( const RectI& updateRect )
renderPass->renderPass( &state );
gClientSceneGraph->setFogData(savedFogData); // restore fog setting
// Make sure to remove our fake sun.
LIGHTMGR->unregisterAllLights();
}

View file

@ -378,6 +378,7 @@ public:
/// Invokes a cubemap bake action for this probe
/// </summary>
void bake();
ProbeInfo* getProbeInfo() { return &mProbeInfo; }
};
typedef ReflectionProbe::ProbeInfo::ProbeShapeType ReflectProbeType;

View file

@ -59,6 +59,8 @@ extern bool gEditingMission;
extern ColorI gCanvasClearColor;
bool Skylight::smRenderSkylights = true;
SimObjectPtr<Skylight> Skylight::smSkylightProbe = nullptr;
IMPLEMENT_CO_NETOBJECT_V1(Skylight);
ConsoleDocClass(Skylight,
@ -117,6 +119,8 @@ bool Skylight::onAdd()
if (!Parent::onAdd())
return false;
if (isClientObject())
smSkylightProbe = this;
return true;
}

View file

@ -108,6 +108,7 @@ public:
void prepRenderImage(SceneRenderState *state);
void setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat);
static SimObjectPtr<Skylight> smSkylightProbe;
};
#endif // _Skylight_H_

View file

@ -65,6 +65,21 @@ struct CompoundKey3
bool operator==(const CompoundKey3 & compound) const { return key1==compound.key1 && key2==compound.key2 && key3==compound.key3; }
};
template<class A, class B, class C, class D>
struct CompoundKey4
{
A key1;
B key2;
C key3;
D key4;
CompoundKey4() {};
CompoundKey4(const A& a, const B& b, const C& c, const D& d) { key1 = a; key2 = b; key3 = c; key4 = d;};
bool operator==(const CompoundKey4& compound) const { return key1 == compound.key1 && key2 == compound.key2 && key3 == compound.key3 && key4 == compound.key4; }
};
namespace DictHash
{
@ -110,6 +125,11 @@ namespace DictHash
return hash(compound.key1) + hash(compound.key2) + hash(compound.key3);
}
template<class A, class B, class C, class D>
inline U32 hash(const CompoundKey4<A, B, C, D>& compound)
{
return hash(compound.key1) + hash(compound.key2) + hash(compound.key3) + hash(compound.key4);
}
U32 nextPrime(U32);
};

View file

@ -28,6 +28,7 @@
#include "core/strings/stringFunctions.h"
#include "gfx/bitmap/gBitmap.h"
#include "gfx/bitmap/imageUtils.h"
#include "gfx/bitmap/loaders/ies/ies_loader.h"
#ifdef __clang__
#define STBIWDEF static inline
@ -69,6 +70,7 @@ static struct _privateRegisterSTB
reg.extensions.push_back("psd");
reg.extensions.push_back("hdr");
reg.extensions.push_back("tga");
reg.extensions.push_back("ies");
reg.readFunc = sReadSTB;
reg.readStreamFunc = sReadStreamSTB;
@ -93,6 +95,103 @@ bool sReadSTB(const Torque::Path& path, GBitmap* bitmap)
U32 prevWaterMark = FrameAllocator::getWaterMark();
// if this is an ies profile we need to create a texture for it.
if (ext.equal("ies"))
{
String textureName = path.getFullPath();
textureName.replace(".ies", ".png");
x = 256;
y = 1;
n = 4;
channels = 4;
GFXFormat format = GFXFormatR8G8B8A8;
if (Torque::FS::IsFile(textureName.c_str()))
{
// if the txture already exist, load it.
unsigned char* data = stbi_load(textureName.c_str(), &x, &y, &n, channels);
// actually allocate the bitmap space...
bitmap->allocateBitmap(x, y,
false, // don't extrude miplevels...
format); // use determined format...
U8* pBase = (U8*)bitmap->getBits();
U32 rowBytes = bitmap->getByteSize();
dMemcpy(pBase, data, rowBytes);
stbi_image_free(data);
FrameAllocator::setWaterMark(prevWaterMark);
return true;
}
else
{
FileStream* readIes = new FileStream;
if (!readIes->open(path.getFullPath(), Torque::FS::File::Read))
{
Con::printf("Failed to open IES profile:%s", path.getFullFileName().c_str());
return false;
}
if (readIes->getStatus() != Stream::Ok)
{
Con::printf("Failed to open IES profile:%s", path.getFullFileName().c_str());
return false;
}
U32 buffSize = readIes->getStreamSize();
char* buffer = new char[buffSize];
readIes->read(buffSize, buffer);
IESFileInfo info;
IESLoadHelper IESLoader;
if (!IESLoader.load(buffer, buffSize, info))
{
Con::printf("Failed to load IES profile:%s \n LoaderError: %s", path.getFullFileName().c_str(), info.error().c_str());
return false;
}
float* data = new float[x*y*channels];
if (!IESLoader.saveAs1D(info, data, x, channels))
{
Con::printf("Failed to create 2d Texture for IES profile:%s", path.getFullFileName().c_str());
return false;
}
// use stb function to convert float data to uchar
unsigned char* dataChar = stbi__hdr_to_ldr(data, x, y, channels);
bitmap->deleteImage();
// actually allocate the bitmap space...
bitmap->allocateBitmap(x, y,
false,
format);
U8* pBase = (U8*)bitmap->getBits();
U32 rowBytes = x * y * channels;
dMemcpy(pBase, dataChar, rowBytes);
stbi_image_free(dataChar);
FrameAllocator::setWaterMark(prevWaterMark);
sWriteSTB(textureName, bitmap, 10);
return true;
}
}
if (!stbi_info(path.getFullPath().c_str(), &x, &y, &channels))
{
FrameAllocator::setWaterMark(prevWaterMark);
@ -142,21 +241,22 @@ bool sReadSTB(const Torque::Path& path, GBitmap* bitmap)
if (ext.equal("hdr"))
{
// force load to 4 channel.
float* data = stbi_loadf(path.getFullPath().c_str(), &x, &y, &n, 4);
float* data = stbi_loadf(path.getFullPath().c_str(), &x, &y, &n, 0);
unsigned char* dataChar = stbi__hdr_to_ldr(data, x, y, 4);
unsigned char* dataChar = stbi__hdr_to_ldr(data, x, y, n);
bitmap->deleteImage();
// actually allocate the bitmap space...
bitmap->allocateBitmap(x, y,
false,
GFXFormatR8G8B8A8);
GFXFormatR8G8B8);
U8* pBase = (U8*)bitmap->getBits();
U32 rowBytes = x * y * 4;
U32 rowBytes = x * y * n;
dMemcpy(pBase, dataChar, rowBytes);
//stbi_image_free(data);
stbi_image_free(dataChar);
FrameAllocator::setWaterMark(prevWaterMark);

View file

@ -0,0 +1,581 @@
// +----------------------------------------------------------------------
// | Project : ray.
// | All rights reserved.
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2017.
// +----------------------------------------------------------------------
// | * Redistribution and use of this software in source and binary forms,
// | with or without modification, are permitted provided that the following
// | conditions are met:
// |
// | * Redistributions of source code must retain the above
// | copyright notice, this list of conditions and the
// | following disclaimer.
// |
// | * Redistributions in binary form must reproduce the above
// | copyright notice, this list of conditions and the
// | following disclaimer in the documentation and/or other
// | materials provided with the distribution.
// |
// | * Neither the name of the ray team, nor the names of its
// | contributors may be used to endorse or promote products
// | derived from this software without specific prior
// | written permission of the ray team.
// |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// +----------------------------------------------------------------------
#include "ies_loader.h"
#include <assert.h>
#include <algorithm>
#include <functional>
#include "math/mMathFn.h"
IESFileInfo::IESFileInfo()
: _cachedIntegral(F32_MAX)
, _error("No data loaded")
{
}
bool
IESFileInfo::valid() const
{
return _error.empty();
}
const std::string&
IESFileInfo::error() const
{
return _error;
}
IESLoadHelper::IESLoadHelper()
{
}
IESLoadHelper::~IESLoadHelper()
{
}
bool
IESLoadHelper::load(const char* data, std::size_t dataLength, IESFileInfo& info)
{
assert(!info.valid());
return this->load(std::string(data, dataLength), info);
}
bool
IESLoadHelper::load(const std::string& data, IESFileInfo& info)
{
assert(!info.valid());
std::string dataPos;
std::string version;
this->getLineContent(data, dataPos, version, false, false);
if (version.empty())
{
info._error = "Unknown IES version";
return false;
}
else if (version == "IESNA:LM-63-1995")
info._version = "IESNA:LM-63-1995";
else if (version == "IESNA91")
info._version = "IESNA91";
else if (version == "IESNA:LM-63-2002")
info._version = "IESNA:LM-63-2002";
else
info._version = version;
while (!dataPos.empty())
{
std::string line;
this->getLineContent(dataPos, dataPos, line, false, false);
if (line.compare(0, 9, "TILT=NONE", 9) == 0 ||
line.compare(0, 10, "TILT= NONE", 10) == 0 ||
line.compare(0, 10, "TILT =NONE", 10) == 0 ||
line.compare(0, 11, "TILT = NONE", 11) == 0)
{
break;
}
else if (line.compare(0, 5, "TILT=", 5) == 0 ||
line.compare(0, 5, "TILT =", 5) == 0)
{
info._error = "Not supported yet.";
return false;
}
}
this->getFloat(dataPos, dataPos, info.totalLights);
if (info.totalLights < 0 || info.totalLights > F32_MAX)
{
info._error = "Light Count is not valid";
return false;
}
this->getFloat(dataPos, dataPos, info.totalLumens);
if (info.totalLumens < 0)
{
info._error = "TotalLumens is not positive number";
return false;
}
this->getFloat(dataPos, dataPos, info.candalaMult);
if (info.candalaMult < 0)
{
info._error = "CandalaMult is not positive number";
return false;
}
this->getInt(dataPos, dataPos, info.anglesNumV);
if (info.anglesNumV < 0 || info.anglesNumV > F32_MAX)
{
info._error = "VAnglesNum is not valid";
return false;
}
this->getInt(dataPos, dataPos, info.anglesNumH);
if (info.anglesNumH < 0 || info.anglesNumH > F32_MAX)
{
info._error = "HAnglesNum is not valid";
return false;
}
this->getInt(dataPos, dataPos, info.typeOfPhotometric);
this->getInt(dataPos, dataPos, info.typeOfUnit);
this->getFloat(dataPos, dataPos, info.width);
this->getFloat(dataPos, dataPos, info.length);
this->getFloat(dataPos, dataPos, info.height);
this->getFloat(dataPos, dataPos, info.ballastFactor);
this->getFloat(dataPos, dataPos, info.futureUse);
this->getFloat(dataPos, dataPos, info.inputWatts);
float minSoFarV = F32_MIN_EX;
float minSoFarH = F32_MIN_EX;
info._anglesV.reserve(info.anglesNumV);
info._anglesH.reserve(info.anglesNumH);
for (std::int32_t y = 0; y < info.anglesNumV; ++y)
{
float value;
this->getFloat(dataPos, dataPos, value, true, true);
if (value < minSoFarV)
{
info._error = "V Values is not valid";
return false;
}
minSoFarV = value;
info._anglesV.push_back(value);
}
for (std::int32_t x = 0; x < info.anglesNumH; ++x)
{
float value;
this->getFloat(dataPos, dataPos, value, true, true);
if (value < minSoFarH)
{
info._error = "H Values is not valid";
return false;
}
minSoFarH = value;
info._anglesH.push_back(value);
}
info._candalaValues.reserve(info.anglesNumH * info.anglesNumV);
for (std::int32_t y = 0; y < info.anglesNumH; ++y)
{
for (std::int32_t x = 0; x < info.anglesNumV; ++x)
{
float value;
this->getFloat(dataPos, dataPos, value, true, true);
info._candalaValues.push_back(value * info.candalaMult);
}
}
skipSpaceAndLineEnd(dataPos, dataPos);
if (!dataPos.empty())
{
std::string line;
this->getLineContent(dataPos, dataPos, line, true, false);
if (line == "END")
skipSpaceAndLineEnd(dataPos, dataPos);
if (!dataPos.empty())
{
info._error = "Unexpected content after END.";
return false;
}
}
info._error.clear();
return true;
}
bool
IESLoadHelper::saveAs1D(const IESFileInfo& info, float* data, std::uint32_t width, std::uint8_t channel) noexcept
{
assert(data);
assert(width > 0);
assert(channel == 1 || channel == 3 || channel == 4);
assert(info.valid());
float invW = 1.0f / width;
float invMaxValue = this->computeInvMax(info._candalaValues);
for (std::uint32_t x = 0; x < width; ++x)
{
float fraction = x * invW;
float value = invMaxValue * interpolate1D(info, fraction * 180.0f);
switch (channel)
{
case 1:
*data++ = value;
break;
case 3:
*data++ = value;
*data++ = value;
*data++ = value;
break;
case 4:
*data++ = value;
*data++ = value;
*data++ = value;
*data++ = 1.0f;
break;
default:
return false;
}
}
return true;
}
bool
IESLoadHelper::saveAs2D(const IESFileInfo& info, float* data, std::uint32_t width, std::uint32_t height, std::uint8_t channel) noexcept
{
assert(data);
assert(width > 0 && height > 0);
assert(channel == 1 || channel == 3 || channel == 4);
assert(info.valid());
float invW = 1.0f / width;
float invH = 1.0f / height;
float invMaxValue = this->computeInvMax(info._candalaValues);
for (std::uint32_t y = 0; y < height; ++y)
{
for (std::uint32_t x = 0; x < width; ++x)
{
float fractionV = x * invW * 180.0f;
float fractionH = y * invH * 180.0f;
float value = invMaxValue * interpolate2D(info, fractionV, fractionH);
switch (channel)
{
case 1:
*data++ = value;
break;
case 3:
*data++ = value;
*data++ = value;
*data++ = value;
break;
case 4:
*data++ = value;
*data++ = value;
*data++ = value;
*data++ = 1.0;
break;
default:
return false;
}
}
}
return true;
}
bool
IESLoadHelper::saveAsPreview(const IESFileInfo& info, std::uint8_t* data, std::uint32_t width, std::uint32_t height, std::uint8_t channel) noexcept
{
assert(data);
assert(width > 0 && height > 0);
assert(channel == 1 || channel == 3 || channel == 4);
assert(info.valid());
std::vector<float> ies(256);
if (!this->saveAs1D(info, ies.data(), ies.size(), 1))
return false;
float maxValue = this->computeInvMax(info._candalaValues);
auto TonemapHable = [](float x)
{
const float A = 0.22f;
const float B = 0.30f;
const float C = 0.10f;
const float D = 0.20f;
const float E = 0.01f;
const float F = 0.30f;
return ((x*(A*x + C*B) + D*E) / (x*(A*x + B) + D*F)) - E / F;
};
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
float u = ((float)x / width) * 2.0f - 1.0f;
float v = 1.0f - ((float)y / height) * 2.0f - 1.0f;
u *= 2.2f;
v *= 2.4f;
// float3(0.0f, 0.0f, -0.5f) - ray::float3(u, v, 0.0f)
float lx = +0.0f - u;
float ly = +0.0f - v;
float lz = -0.5f - 0.0f;
// normalize
float length = mSqrt(lx * lx + ly * ly + lz * lz);
lx /= length;
ly /= length;
lz /= length;
float angle = 1.0 - mAcos(lx * 0.0 + ly * -1.0 + lz * 0.0f) / 3.141592654;
float intensity = ies[angle * 255] * maxValue / length;
std::uint8_t value = std::min(std::max((int)mFloor(TonemapHable(intensity) / TonemapHable(maxValue) * 255.0f), 0), 255);
switch (channel)
{
case 1:
*data++ = value;
break;
case 3:
*data++ = value;
*data++ = value;
*data++ = value;
break;
case 4:
*data++ = value;
*data++ = value;
*data++ = value;
*data++ = 1.0;
break;
default:
return false;
}
}
}
return true;
}
float
IESLoadHelper::computeInvMax(const std::vector<float>& candalaValues) const
{
assert(candalaValues.size());
float candala = *std::max_element(candalaValues.begin(), candalaValues.end());
return 1.0f / candala;
}
float
IESLoadHelper::computeFilterPos(float value, const std::vector<float>& angles) const
{
assert(angles.size());
std::size_t start = 0;
std::size_t end = angles.size() - 1;
if (value < angles[start]) return 0.0f;
if (value > angles[end]) return (float)end;
while (start < end)
{
std::size_t index = (start + end + 1) / 2;
float angle = angles[index];
if (value >= angle)
{
assert(start != index);
start = index;
}
else
{
assert(end != index - 1);
end = index - 1;
}
}
float leftValue = angles[start];
float fraction = 0.0f;
if (start + 1 < (std::uint32_t)angles.size())
{
float rightValue = angles[start + 1];
float deltaValue = rightValue - leftValue;
if (deltaValue > 0.0001f)
{
fraction = (value - leftValue) / deltaValue;
}
}
return start + fraction;
}
float
IESLoadHelper::interpolate1D(const IESFileInfo& info, float angle) const
{
float angleV = this->computeFilterPos(angle, info._anglesV);
float anglesNum = (float)info._anglesH.size();
float angleTotal = 0.0f;
for (float x = 0; x < anglesNum; x++)
angleTotal += this->interpolateBilinear(info, x, angleV);
return angleTotal / anglesNum;
}
float
IESLoadHelper::interpolate2D(const IESFileInfo& info, float angleV, float angleH) const
{
float u = this->computeFilterPos(angleH, info._anglesH);
float v = this->computeFilterPos(angleV, info._anglesV);
return this->interpolateBilinear(info, u, v);
}
float
IESLoadHelper::interpolatePoint(const IESFileInfo& info, std::uint32_t x, std::uint32_t y) const
{
assert(x >= 0);
assert(y >= 0);
std::size_t anglesNumH = info._anglesH.size();
std::size_t anglesNumV = info._anglesV.size();
x %= anglesNumH;
y %= anglesNumV;
assert(x < anglesNumH);
assert(y < anglesNumV);
return info._candalaValues[y + anglesNumV * x];
}
float
IESLoadHelper::interpolateBilinear(const IESFileInfo& info, float x, float y) const
{
int ix = (int)mFloor(x);
int iy = (int)mFloor(y);
float fracX = x - ix;
float fracY = y - iy;
float p00 = this->interpolatePoint(info, ix + 0, iy + 0);
float p10 = this->interpolatePoint(info, ix + 1, iy + 0);
float p01 = this->interpolatePoint(info, ix + 0, iy + 1);
float p11 = this->interpolatePoint(info, ix + 1, iy + 1);
auto lerp = [](float t1, float t2, float t3) -> float { return t1 + (t2 - t1) * t3; };
float p0 = lerp(p00, p01, fracY);
float p1 = lerp(p10, p11, fracY);
return lerp(p0, p1, fracX);
}
void
IESLoadHelper::skipSpaceAndLineEnd(const std::string& data, std::string& out, bool stopOnComma)
{
std::size_t dataBegin = 0;
std::size_t dataEnd = data.size();
while (dataBegin < dataEnd)
{
if (data[dataBegin] != '\r' && data[dataBegin] != '\n' && data[dataBegin] > ' ')
break;
dataBegin++;
}
if (stopOnComma)
{
while (dataBegin < dataEnd)
{
if (data[dataBegin] != ',')
break;
dataBegin++;
}
}
out = data.substr(dataBegin, data.size() - dataBegin);
}
void
IESLoadHelper::getLineContent(const std::string& data, std::string& next, std::string& line, bool stopOnWhiteSpace, bool stopOnComma)
{
skipSpaceAndLineEnd(data, next);
auto it = data.begin();
auto end = data.end();
for (; it < end; ++it)
{
if ((*it == '\r') ||
(*it == '\n') ||
(*it <= ' ' && stopOnWhiteSpace) ||
(*it == ',' && stopOnComma))
{
break;
}
}
line.assign(data, 0, it - data.begin());
next.assign(data, it - data.begin(), end - it);
skipSpaceAndLineEnd(next, next, stopOnComma);
}
void
IESLoadHelper::getFloat(const std::string& data, std::string& next, float& ret, bool stopOnWhiteSpace, bool stopOnComma)
{
std::string line;
getLineContent(data, next, line, stopOnWhiteSpace, stopOnComma);
assert(!line.empty());
ret = (float)std::atof(line.c_str());
}
void
IESLoadHelper::getInt(const std::string& data, std::string& next, std::int32_t& ret, bool stopOnWhiteSpace, bool stopOnComma)
{
std::string line;
getLineContent(data, next, line, stopOnWhiteSpace, stopOnComma);
assert(!line.empty());
ret = std::atoi(line.c_str());
}

View file

@ -0,0 +1,116 @@
// +----------------------------------------------------------------------
// | Project : ray.
// | All rights reserved.
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2017.
// +----------------------------------------------------------------------
// | * Redistribution and use of this software in source and binary forms,
// | with or without modification, are permitted provided that the following
// | conditions are met:
// |
// | * Redistributions of source code must retain the above
// | copyright notice, this list of conditions and the
// | following disclaimer.
// |
// | * Redistributions in binary form must reproduce the above
// | copyright notice, this list of conditions and the
// | following disclaimer in the documentation and/or other
// | materials provided with the distribution.
// |
// | * Neither the name of the ray team, nor the names of its
// | contributors may be used to endorse or promote products
// | derived from this software without specific prior
// | written permission of the ray team.
// |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// +----------------------------------------------------------------------
#ifndef _H_IES_LOADER_H_
#define _H_IES_LOADER_H_
#include <vector>
#include <string>
// https://knowledge.autodesk.com/support/3ds-max/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/3DSMax/files/GUID-EA0E3DE0-275C-42F7-83EC-429A37B2D501-htm.html
class IESFileInfo
{
public:
IESFileInfo();
bool valid() const;
const std::string& error() const;
public:
float totalLights;
float totalLumens;
float candalaMult;
std::int32_t typeOfPhotometric;
std::int32_t typeOfUnit;
std::int32_t anglesNumH;
std::int32_t anglesNumV;
float width;
float length;
float height;
float ballastFactor;
float futureUse;
float inputWatts;
private:
friend class IESLoadHelper;
float _cachedIntegral;
std::string _error;
std::string _version;
std::vector<float> _anglesH;
std::vector<float> _anglesV;
std::vector<float> _candalaValues;
};
class IESLoadHelper final
{
public:
IESLoadHelper();
~IESLoadHelper();
bool load(const std::string& data, IESFileInfo& info);
bool load(const char* data, std::size_t dataLength, IESFileInfo& info);
bool saveAs1D(const IESFileInfo& info, float* data, std::uint32_t width = 256, std::uint8_t channel = 3) noexcept;
bool saveAs2D(const IESFileInfo& info, float* data, std::uint32_t width = 256, std::uint32_t height = 256, std::uint8_t channel = 3) noexcept;
bool saveAsPreview(const IESFileInfo& info, std::uint8_t* data, std::uint32_t width = 64, std::uint32_t height = 64, std::uint8_t channel = 3) noexcept;
private:
float computeInvMax(const std::vector<float>& candalaValues) const;
float computeFilterPos(float value, const std::vector<float>& angle) const;
float interpolate1D(const IESFileInfo& info, float angle) const;
float interpolate2D(const IESFileInfo& info, float angleV, float angleH) const;
float interpolatePoint(const IESFileInfo& info, std::uint32_t x, std::uint32_t y) const;
float interpolateBilinear(const IESFileInfo& info, float x, float y) const;
private:
static void skipSpaceAndLineEnd(const std::string& data, std::string& out, bool stopOnComma = false);
static void getLineContent(const std::string& data, std::string& next, std::string& line, bool stopOnWhiteSpace, bool stopOnComma);
static void getFloat(const std::string& data, std::string& next, float& ret, bool stopOnWhiteSpace = true, bool stopOnComma = false);
static void getInt(const std::string& data, std::string& next, std::int32_t& ret, bool stopOnWhiteSpace = true, bool stopOnComma = false);
};
#endif

View file

@ -54,6 +54,7 @@ GuiInspector::GuiInspector()
mForcedArrayIndex(-1)
{
mPadding = 1;
mSearchText = StringTable->EmptyString();
}
//-----------------------------------------------------------------------------
@ -79,7 +80,8 @@ void GuiInspector::initPersistFields()
"If false the custom fields Name, Id, and Source Class will not be shown." );
addField("forcedArrayIndex", TypeS32, Offset(mForcedArrayIndex, GuiInspector));
addField("searchText", TypeString, Offset(mSearchText, GuiInspector), "A string that, if not blank, is used to filter shown fields");
endGroup( "Inspector" );
Parent::initPersistFields();
@ -829,6 +831,12 @@ void GuiInspector::setForcedArrayIndex(S32 arrayIndex)
refresh();
}
void GuiInspector::setSearchText(StringTableEntry searchText)
{
mSearchText = searchText;
refresh();
}
//=============================================================================
// Console Methods.
//=============================================================================
@ -1000,3 +1008,10 @@ DefineEngineMethod(GuiInspector, setForcedArrayIndex, void, (S32 arrayIndex), (-
{
object->setForcedArrayIndex(arrayIndex);
}
DefineEngineMethod(GuiInspector, setSearchText, void, (const char* searchText), (""),
"Sets the searched text used to filter out displayed fields in the inspector."
"@param searchText The text to be used as a filter for field names. Leave as blank to clear search")
{
object->setSearchText(searchText);
}

View file

@ -171,6 +171,10 @@ public:
void setForcedArrayIndex(S32 arrayIndex);
StringTableEntry getSearchText() { return mSearchText; }
void setSearchText(StringTableEntry searchText);
protected:
typedef Vector< SimObjectPtr< SimObject > > TargetVector;
@ -190,6 +194,8 @@ protected:
String mGroupFilters;
bool mShowCustomFields;
S32 mForcedArrayIndex;
StringTableEntry mSearchText;
};
#endif

View file

@ -37,6 +37,8 @@
#include "T3D/assets/ShapeAsset.h"
#include "T3D/assets/ShapeAnimationAsset.h"
#include "renderInstance/renderProbeMgr.h"
#include "T3D/lighting/skylight.h"
#ifdef TORQUE_COLLADA
#include "collision/optimizedPolyList.h"
@ -1409,6 +1411,8 @@ void GuiShapeEdPreview::renderWorld(const RectI &updateRect)
FogData savedFogData = gClientSceneGraph->getFogData();
gClientSceneGraph->setFogData( FogData() ); // no fog in preview window
if (Skylight::smSkylightProbe.isValid())
PROBEMGR->submitProbe(Skylight::smSkylightProbe->getProbeInfo());
SceneRenderState state
(
gClientSceneGraph,

View file

@ -175,6 +175,9 @@ GuiControl* GuiInspectorDatablockField::constructEditControl()
//Add add button
mAddButton = new GuiBitmapButtonCtrl();
if(mDesiredClass == NULL)
return retCtrl;
dSprintf(szBuffer, sizeof(szBuffer), "DatablockEditorPlugin.createNewDatablockOfType(%s, %d.getText());", mDesiredClass->getClassName(), retCtrl->getId());
mAddButton->setField("Command", szBuffer);

View file

@ -123,6 +123,12 @@ bool GuiInspectorDynamicGroup::inspectGroup()
SimFieldDictionary * fieldDictionary = target->getFieldDictionary();
for(SimFieldDictionaryIterator ditr(fieldDictionary); *ditr; ++ditr)
{
String searchText = mParent->getSearchText();
if (searchText != String::EmptyString) {
if (String((*ditr)->slotName).find(searchText, 0, String::NoCase | String::Left) == String::NPos)
continue;
}
if( i == 0 )
{
flist.increment();

View file

@ -288,6 +288,12 @@ bool GuiInspectorGroup::inspectGroup()
if (field->flag.test(AbstractClassRep::FIELD_HideInInspectors))
continue;
String searchText = mParent->getSearchText();
if (searchText != String::EmptyString) {
if (String(field->pFieldname).find(searchText, 0, String::NoCase | String::Left) == String::NPos)
continue;
}
if ((bGrabItems == true || (bNoGroup == true && bGrabItems == false)) && itr->type != AbstractClassRep::DeprecatedFieldType)
{
if (bNoGroup == true && bGrabItems == true)

View file

@ -253,7 +253,7 @@ void AdvancedLightBinManager::addLight( LightInfo *light )
LightBinEntry lEntry;
lEntry.lightInfo = light;
lEntry.shadowMap = lsm;
lEntry.lightMaterial = _getLightMaterial( lightType, shadowType, lsp->hasCookieTex() );
lEntry.lightMaterial = _getLightMaterial( lightType, shadowType, lsp->hasCookieTex(), lsp->hasIesProfile() );
if( lightType == LightInfo::Spot )
lEntry.vertBuffer = mLightManager->getConeMesh( lEntry.numPrims, lEntry.primBuffer );
@ -399,9 +399,9 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
sunLight->getCastShadows() &&
!disableShadows &&
sunLight->getExtended<ShadowMapParams>() )
vectorMatInfo = _getLightMaterial( LightInfo::Vector, ShadowType_PSSM, false );
vectorMatInfo = _getLightMaterial( LightInfo::Vector, ShadowType_PSSM );
else
vectorMatInfo = _getLightMaterial( LightInfo::Vector, ShadowType_None, false );
vectorMatInfo = _getLightMaterial( LightInfo::Vector, ShadowType_None );
// Initialize and set the per-frame parameters after getting
// the vector light material as we use lazy creation.
@ -513,12 +513,13 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
AdvancedLightBinManager::LightMaterialInfo* AdvancedLightBinManager::_getLightMaterial( LightInfo::Type lightType,
ShadowType shadowType,
bool useCookieTex )
bool useCookieTex,
bool isPhotometric)
{
PROFILE_SCOPE( AdvancedLightBinManager_GetLightMaterial );
// Build the key.
const LightMatKey key( lightType, shadowType, useCookieTex );
const LightMatKey key( lightType, shadowType, useCookieTex, isPhotometric );
// See if we've already built this one.
LightMatTable::Iterator iter = mLightMaterials.find( key );
@ -558,6 +559,9 @@ AdvancedLightBinManager::LightMaterialInfo* AdvancedLightBinManager::_getLightMa
if ( useCookieTex )
shadowMacros.push_back( GFXShaderMacro( "USE_COOKIE_TEX" ) );
if(isPhotometric)
shadowMacros.push_back(GFXShaderMacro("UES_PHOTOMETRIC_MASK"));
// Its safe to add the PSSM debug macro to all the materials.
if ( smPSSMDebugRender )
shadowMacros.push_back( GFXShaderMacro( "PSSM_DEBUG_RENDER" ) );
@ -830,6 +834,7 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
const F32 radius = lightInfo->getRange().x;
const F32 invSqrRadius = 1.0f / (radius * radius);
matParams->setSafe( lightRange, radius);
matParams->setSafe( lightDirection, -lightInfo->getTransform().getUpVector());
matParams->setSafe( lightInvSqrRange, invSqrRadius);
luxTargMultiplier =radius;
}

View file

@ -233,14 +233,14 @@ protected:
static const GFXVertexFormat* smLightMatVertex[LightInfo::Count];
typedef CompoundKey3<LightInfo::Type,ShadowType,bool> LightMatKey;
typedef CompoundKey4<LightInfo::Type,ShadowType,bool, bool> LightMatKey;
typedef HashTable<LightMatKey,LightMaterialInfo*> LightMatTable;
/// The fixed table of light material info.
LightMatTable mLightMaterials;
LightMaterialInfo* _getLightMaterial( LightInfo::Type lightType, ShadowType shadowType, bool useCookieTex );
LightMaterialInfo* _getLightMaterial( LightInfo::Type lightType, ShadowType shadowType, bool useCookieTex = false, bool isPhotometric = false );
///
void _onShadowFilterChanged();

View file

@ -277,6 +277,7 @@ void AdvancedLightManager::_initLightFields()
DEFINE_LIGHT_FIELD( attenuationRatio, TypePoint3F, NULL );
DEFINE_LIGHT_FIELD( shadowType, TYPEID< ShadowType >(), ConsoleBaseType::getType( TYPEID< ShadowType >() )->getEnumTable() );
DEFINE_LIGHT_FIELD( texSize, TypeS32, NULL );
DEFINE_LIGHT_FIELD( iesProfile, TypeStringFilename, NULL );
DEFINE_LIGHT_FIELD( cookie, TypeStringFilename, NULL );
DEFINE_LIGHT_FIELD( numSplits, TypeS32, NULL );
DEFINE_LIGHT_FIELD( logWeight, TypeF32, NULL );
@ -300,6 +301,9 @@ void AdvancedLightManager::_initLightFields()
ADD_LIGHT_FIELD( "shadowType", TYPEID< ShadowType >(), shadowType,
"The type of shadow to use on this light." );
ADD_LIGHT_FIELD("iesProfile", TypeStringFilename, iesProfile,
"A photometric profile for the light.");
ADD_LIGHT_FIELD( "cookie", TypeStringFilename, cookie,
"A custom pattern texture which is projected from the light." );
@ -496,6 +500,17 @@ bool AdvancedLightManager::setTextureStage( const SceneData &sgData,
return true;
}
else if (currTexFlag == Material::PhotometricMask)
{
S32 reg = lsc->mIesProfileSC->getSamplerRegister();
if (reg != -1 && sgData.lights[0])
{
ShadowMapParams* p = sgData.lights[0]->getExtended<ShadowMapParams>();
GFX->setTexture(reg, p->getIesProfileTex());
}
return true;
}
return false;
}

View file

@ -269,7 +269,8 @@ bool LightShadowMap::setTextureStage( U32 currTexFlag, LightingShaderConstants*
GFX->setTexture( reg, mShadowMapTex);
return true;
} else if ( currTexFlag == Material::DynamicLightMask )
}
else if ( currTexFlag == Material::DynamicLightMask )
{
S32 reg = lsc->mCookieMapSC->getSamplerRegister();
if ( reg != -1 )
@ -284,6 +285,17 @@ bool LightShadowMap::setTextureStage( U32 currTexFlag, LightingShaderConstants*
return true;
}
else if (currTexFlag == Material::PhotometricMask)
{
S32 reg = lsc->mIesProfileSC->getSamplerRegister();
if (reg != -1)
{
ShadowMapParams* p = mLight->getExtended<ShadowMapParams>();
GFX->setTexture(reg, p->getIesProfileTex());
}
return true;
}
return false;
}
@ -430,6 +442,7 @@ LightingShaderConstants::LightingShaderConstants()
mShadowMapSC(NULL),
mShadowMapSizeSC(NULL),
mCookieMapSC(NULL),
mIesProfileSC(NULL),
mRandomDirsConst(NULL),
mShadowSoftnessConst(NULL),
mAtlasXOffsetSC(NULL),
@ -490,6 +503,7 @@ void LightingShaderConstants::init(GFXShader* shader)
mShadowMapSizeSC = shader->getShaderConstHandle("$shadowMapSize");
mCookieMapSC = shader->getShaderConstHandle("$cookieMap");
mIesProfileSC = shader->getShaderConstHandle("$iesProfile");
mShadowSoftnessConst = shader->getShaderConstHandle("$shadowSoftness");
mAtlasXOffsetSC = shader->getShaderConstHandle("$atlasXOffset");
@ -542,7 +556,8 @@ ShadowMapParams::ShadowMapParams( LightInfo *light )
fadeStartDist = 75.0f;
lastSplitTerrainOnly = false;
mQuery = GFX->createOcclusionQuery();
cookie = StringTable->EmptyString();;
cookie = StringTable->EmptyString();
iesProfile = StringTable->EmptyString();
_validate();
}
@ -662,6 +677,22 @@ GFXTextureObject* ShadowMapParams::getCookieTex()
return mCookieTex.getPointer();
}
GFXTextureObject* ShadowMapParams::getIesProfileTex()
{
if (hasIesProfile() &&
(mIesTex.isNull() ||
iesProfile != StringTable->insert(mIesTex->getPath().c_str())))
{
mIesTex.set(iesProfile,
&GFXStaticTextureSRGBProfile,
"ShadowMapParams::getIesProfileTex()");
}
else if (!hasIesProfile())
mIesTex = NULL;
return mIesTex.getPointer();
}
GFXCubemap* ShadowMapParams::getCookieCubeTex()
{
if ( hasCookieTex() &&
@ -695,6 +726,7 @@ void ShadowMapParams::packUpdate( BitStream *stream ) const
stream->write( texSize );
stream->writeString( cookie );
stream->writeString( iesProfile );
stream->write( numSplits );
stream->write( logWeight );
@ -725,6 +757,7 @@ void ShadowMapParams::unpackUpdate( BitStream *stream )
stream->read( &texSize );
cookie = stream->readSTString();
iesProfile = stream->readSTString();
stream->read( &numSplits );
stream->read( &logWeight );

View file

@ -99,6 +99,7 @@ struct LightingShaderConstants
GFXShaderConstHandle* mShadowMapSizeSC;
GFXShaderConstHandle* mCookieMapSC;
GFXShaderConstHandle* mIesProfileSC;
GFXShaderConstHandle* mRandomDirsConst;
GFXShaderConstHandle* mShadowSoftnessConst;
@ -289,11 +290,14 @@ public:
LightShadowMap* getOrCreateShadowMap();
bool hasCookieTex() const { return cookie != StringTable->EmptyString(); }
bool hasIesProfile() const { return iesProfile != StringTable->EmptyString(); }
GFXOcclusionQuery* getOcclusionQuery() const { return mQuery; }
GFXTextureObject* getCookieTex();
GFXTextureObject* getIesProfileTex();
GFXCubemap* getCookieCubeTex();
// Validates the parameters after a field is changed.
@ -313,6 +317,8 @@ protected:
GFXCubemapHandle mCookieCubeTex;
GFXTexHandle mIesTex;
public:
// We're leaving these public for easy access
@ -326,6 +332,7 @@ public:
///
StringTableEntry cookie;
StringTableEntry iesProfile;
/// @}

View file

@ -94,6 +94,7 @@ public:
Misc,
DynamicLight,
DynamicLightMask,
PhotometricMask,
NormalizeCube,
TexTarget,
AccuMap,

View file

@ -94,6 +94,14 @@ void ProcessedCustomMaterial::_setStageData()
continue;
}
if (filename.equal(String("$photometricmask"), String::NoCase))
{
rpd->mTexType[i] = Material::PhotometricMask;
rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
mMaxTex = i + 1;
continue;
}
if(filename.equal(String("$lightmap"), String::NoCase))
{
rpd->mTexType[i] = Material::Lightmap;

View file

@ -100,6 +100,7 @@ static const S32 S32_MIN = S32(-2147483647 - 1); ///< Constant
static const S32 S32_MAX = S32(2147483647); ///< Constant Max Limit S32
static const U32 U32_MAX = U32(0xffffffff); ///< Constant Max Limit U32
static const F32 F32_MIN_EX = F32(-3.40282347e+38); ///< Constant Min Limit F32
static const F32 F32_MIN = F32(1.175494351e-38F); ///< Constant Min Limit F32
static const F32 F32_MAX = F32(3.402823466e+38F); ///< Constant Max Limit F32

View file

@ -73,6 +73,7 @@ static const S32 S32_MIN = S32(-2147483647 - 1);
static const S32 S32_MAX = S32(2147483647);
static const U32 U32_MAX = U32(0xffffffff);
static const F32 F32_MIN_EX = F32(-3.40282347e+38);
static const F32 F32_MAX = F32(3.402823466e+38F);
static const F32 F32_MIN = F32(1.175494351e-38F);

View file

@ -116,6 +116,7 @@ static const S32 S32_MIN = S32(-2147483647 - 1); ///< Constant
static const S32 S32_MAX = S32(2147483647); ///< Constant Max Limit S32
static const U32 U32_MAX = U32(0xffffffff); ///< Constant Max Limit U32
static const F32 F32_MIN_EX = F32(-3.40282347e+38); ///< Constant Min Limit F32
static const F32 F32_MIN = F32(1.175494351e-38F); ///< Constant Min Limit F32
static const F32 F32_MAX = F32(3.402823466e+38F); ///< Constant Max Limit F32

View file

@ -73,6 +73,7 @@ static const S32 S32_MIN = S32(-2147483647 - 1);
static const S32 S32_MAX = S32(2147483647);
static const U32 U32_MAX = U32(0xffffffff);
static const F32 F32_MIN_EX = F32(-3.40282347e+38);
static const F32 F32_MAX = F32(3.402823466e+38F);
static const F32 F32_MIN = F32(1.175494351e-38F);

View file

@ -19,3 +19,43 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
IES Profile Generator tool: https://github.com/nickmcdonald/ies-generator
// +----------------------------------------------------------------------
// | Project : ray.
// | All rights reserved.
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2017.
// +----------------------------------------------------------------------
// | * Redistribution and use of this software in source and binary forms,
// | with or without modification, are permitted provided that the following
// | conditions are met:
// |
// | * Redistributions of source code must retain the above
// | copyright notice, this list of conditions and the
// | following disclaimer.
// |
// | * Redistributions in binary form must reproduce the above
// | copyright notice, this list of conditions and the
// | following disclaimer in the documentation and/or other
// | materials provided with the distribution.
// |
// | * Neither the name of the ray team, nor the names of its
// | contributors may be used to endorse or promote products
// | derived from this software without specific prior
// | written permission of the ray team.
// |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// +----------------------------------------------------------------------

View file

@ -108,11 +108,15 @@ uniform sampler2D deferredBuffer;
#include "softShadow.glsl"
uniform sampler2D colorBuffer;
uniform sampler2D matInfoBuffer;
#ifdef USE_COOKIE_TEX
#ifdef SHADOW_CUBE
/// The texture for cookie rendering.
uniform samplerCube cookieMap;
#else
uniform sampler2D cookieMap;
#endif
uniform sampler2D iesProfile;
uniform vec4 rtParams0;
uniform vec3 lightPosition;
@ -181,7 +185,12 @@ void main()
#ifdef USE_COOKIE_TEX
// Lookup the cookie sample.
#ifdef SHADOW_CUBE
vec4 cookie = texture(cookieMap, tMul(worldToLightProj, -surfaceToLight.L));
#else
vec2 cookieCoord = decodeShadowCoord( tMul( worldToLightProj, -surfaceToLight.L ) ).xy;
vec4 cookie = texture(cookieMap, cookieCoord);
#endif
// Multiply the light with the cookie tex.
lightCol *= cookie.rgb;
// Use a maximum channel luminance to attenuate
@ -224,6 +233,15 @@ void main()
//get punctual light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadow);
#ifdef UES_PHOTOMETRIC_MASK
// Lookup the cookie sample.d
float cosTheta = dot(-surfaceToLight.L, lightDirection);
float angle = acos(cosTheta) * ( M_1OVER_PI_F);
float iesMask = texture(iesProfile, vec2(angle, 0.0)).r;
// Multiply the light with the iesMask tex.
lighting *= iesMask;
#endif
}
OUT_col = vec4(lighting, 0);

View file

@ -38,11 +38,8 @@ uniform sampler2D shadowMap;
#include "softShadow.glsl"
uniform sampler2D colorBuffer;
uniform sampler2D matInfoBuffer;
#ifdef USE_COOKIE_TEX
/// The texture for cookie rendering.
uniform sampler2D cookieMap;
#endif
uniform sampler2D iesProfile;
uniform vec4 rtParams0;
uniform float lightBrightness;
@ -91,7 +88,7 @@ void main()
if(dist < lightRange)
{
SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L);
vec3 lightCol = lightColor.rgb;
float shadow = 1.0;
#ifndef NO_SHADOW
@ -105,19 +102,22 @@ void main()
//distance to light in shadow map space
float distToLight = pxlPosLightProj.z / lightRange;
shadow = softShadow_filter(shadowMap, ssPos.xy/ssPos.w, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y);
#ifdef USE_COOKIE_TEX
// Lookup the cookie sample.
vec4 cookie = texture(cookieMap, shadowCoord);
// Multiply the light with the cookie tex.
lightCol *= cookie.rgb;
// Use a maximum channel luminance to attenuate
// the lighting else we get specular in the dark
// regions of the cookie texture.
lightCol *= max(cookie.r, max(cookie.g, cookie.b));
#endif
}
#endif
#endif
vec3 lightCol = lightColor.rgb;
#ifdef USE_COOKIE_TEX
// Lookup the cookie sample.
vec4 cookie = texture(cookieMap, shadowCoord);
// Multiply the light with the cookie tex.
lightCol *= cookie.rgb;
// Use a maximum channel luminance to attenuate
// the lighting else we get specular in the dark
// regions of the cookie texture.
lightCol *= max(cookie.r, max(cookie.g, cookie.b));
#endif
#ifdef DIFFUSE_LIGHT_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
@ -156,6 +156,14 @@ void main()
//get spot light contribution
lighting = getSpotlight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, lightDirection, lightSpotParams, shadow);
#ifdef UES_PHOTOMETRIC_MASK
// Lookup the cookie sample.d
float cosTheta = dot(-surfaceToLight.L, lightDirection);
float angle = acos(cosTheta) * ( M_1OVER_PI_F);
float iesMask = texture(iesProfile, vec2(angle, 0.0)).r;
// Multiply the light with the iesMask tex.
lighting *= iesMask;
#endif
}
OUT_col = vec4(lighting, 0);

View file

@ -107,16 +107,20 @@ TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1);
#include "softShadow.hlsl"
TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 3);
TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 4);
#ifdef USE_COOKIE_TEX
/// The texture for cookie rendering.
#ifdef SHADOW_CUBE
TORQUE_UNIFORM_SAMPLERCUBE(cookieMap, 5);
#else
TORQUE_UNIFORM_SAMPLER2D(cookieMap, 5);
#endif
TORQUE_UNIFORM_SAMPLER2D(iesProfile, 6);
uniform float4 rtParams0;
uniform float4 lightColor;
uniform float lightBrightness;
uniform float3 lightPosition;
uniform float3 lightDirection;
uniform float4 lightMapParams;
uniform float4 vsFarPlane;
@ -158,28 +162,31 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
{
float distToLight = dist / lightRange;
SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L);
float shadow = 1.0;
float3 lightCol = lightColor.rgb;
float shadow = 1.0;
#ifndef NO_SHADOW
if (getFlag(surface.matFlag, 0)) //also skip if we don't recieve shadows
{
#ifdef SHADOW_CUBE
#ifdef SHADOW_CUBE
// TODO: We need to fix shadow cube to handle soft shadows!
float occ = TORQUE_TEXCUBE( shadowMap, mul( worldToLightProj, -surfaceToLight.L ) ).r;
shadow = saturate( exp( lightParams.y * ( occ - distToLight ) ) );
// TODO: We need to fix shadow cube to handle soft shadows!
float occ = TORQUE_TEXCUBE( shadowMap, mul( worldToLightProj, -surfaceToLight.L ) ).r;
shadow = saturate( exp( lightParams.y * ( occ - distToLight ) ) );
#else
float2 shadowCoord = decodeShadowCoord( mul( worldToLightProj, -surfaceToLight.L ) ).xy;
shadow = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap), ssPos.xy, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y);
#endif
#else
float2 shadowCoord = decodeShadowCoord( mul( worldToLightProj, -surfaceToLight.L ) ).xy;
shadow = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap), ssPos.xy, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y);
#endif
}
#endif // !NO_SHADOW
float3 lightCol = lightColor.rgb;
#ifdef USE_COOKIE_TEX
// Lookup the cookie sample.
#ifdef SHADOW_CUBE
float4 cookie = TORQUE_TEXCUBE(cookieMap, mul(worldToLightProj, -surfaceToLight.L));
#else
float2 cookieCoord = decodeShadowCoord( mul( worldToLightProj, -surfaceToLight.L ) ).xy;
float4 cookie = TORQUE_TEX2D(cookieMap, cookieCoord);
#endif
// Multiply the light with the cookie tex.
lightCol *= cookie.rgb;
// Use a maximum channel luminance to attenuate
@ -187,7 +194,6 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
// regions of the cookie texture.
lightCol *= max(cookie.r, max(cookie.g, cookie.b));
#endif
#ifdef DIFFUSE_LIGHT_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
@ -198,7 +204,7 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
#endif
#ifdef SPECULAR_LIGHT_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
float3 diffuse = BRDF_GetDebugSpecular(surface,surfaceToLight) * factor;
@ -219,7 +225,17 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
//get punctual light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadow);
#ifdef UES_PHOTOMETRIC_MASK
// Lookup the cookie sample.d
float cosTheta = dot(-surfaceToLight.L, lightDirection);
float angle = acos(cosTheta) * ( M_1OVER_PI_F);
float iesMask = TORQUE_TEX2D(iesProfile, float2(angle, 0.0)).r;
// Multiply the light with the iesMask tex.
lighting *= iesMask;
#endif
}
return float4(lighting, 0);
}

View file

@ -42,11 +42,10 @@ TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1);
#include "softShadow.hlsl"
TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 3);
TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 4);
#ifdef USE_COOKIE_TEX
/// The texture for cookie rendering.
TORQUE_UNIFORM_SAMPLER2D(cookieMap, 5);
TORQUE_UNIFORM_SAMPLER2D(iesProfile, 6);
#endif
uniform float4 rtParams0;
uniform float lightBrightness;
@ -96,8 +95,7 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
if(dist < lightRange)
{
SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L);
float3 lightCol = lightColor.rgb;
float shadow = 1.0;
#ifndef NO_SHADOW
if (getFlag(surface.matFlag, 0)) //also skip if we don't recieve shadows
@ -109,19 +107,23 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
//distance to light in shadow map space
float distToLight = pxlPosLightProj.z / lightRange;
shadow = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap), ssPos.xy, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y);
#ifdef USE_COOKIE_TEX
// Lookup the cookie sample.
float4 cookie = TORQUE_TEX2D(cookieMap, shadowCoord);
// Multiply the light with the cookie tex.
lightCol *= cookie.rgb;
// Use a maximum channel luminance to attenuate
// the lighting else we get specular in the dark
// regions of the cookie texture.
lightCol *= max(cookie.r, max(cookie.g, cookie.b));
#endif
}
#endif
float3 lightCol = lightColor.rgb;
#ifdef USE_COOKIE_TEX
float4 pxlPosLightProj = mul( worldToLightProj, float4( surface.P, 1 ) );
float2 cookieCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
// Lookup the cookie sample.
float4 cookie = TORQUE_TEX2D(cookieMap, cookieCoord);
// Multiply the light with the cookie tex.
lightCol *= cookie.rgb;
// Use a maximum channel luminance to attenuate
// the lighting else we get specular in the dark
// regions of the cookie texture.
lightCol *= max(cookie.r, max(cookie.g, cookie.b));
#endif
#ifdef DIFFUSE_LIGHT_VIZ
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
@ -153,6 +155,14 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
//get spot light contribution
lighting = getSpotlight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, lightDirection, lightSpotParams, shadow);
#ifdef UES_PHOTOMETRIC_MASK
// Lookup the cookie sample.d
float cosTheta = dot(-surfaceToLight.L, lightDirection);
float angle = acos(cosTheta) * ( M_1OVER_PI_F);
float iesMask = TORQUE_TEX2D(iesProfile, float2(angle, 0.0)).r;
// Multiply the light with the iesMask tex.
lighting *= iesMask;
#endif
}
return float4(lighting, 0);

View file

@ -0,0 +1,80 @@
IESNA:LM-63-1995
[TEST]BALLABS TEST NO. 12788.0
[MANUFAC] LeoMoon Studios
[LUMINAIRE] 1/100W ICETRON INDUCTION 20x15"DIRECT AREALIGHT LUMINAIRE
[LUMINAIRE] MIRO4 SPEC ALUM TYPE II OPTICS & CLEAR FLAT GLASS LENS
[LUMINAIRE] BLACK PANEL STREET SIDE SYLVANIA # QT 1x150 ICE/UNV-T
[LUMCAT] ICEAL2-150S-TYPE2/CG1-277
[LAMPCAT] ICE100/QT150 2PIN
TILT=NONE
1 11000. 1.000000 25 21 1 1 .938 1.266 .000
1.0000 1.0000 140.0000
.0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0
50.0 55.0 60.0 62.5 65.0 67.5 70.0 72.5 75.0 77.5
80.0 82.5 85.0 87.5 90.0
.0 5.0 15.0 25.0 35.0 45.0 55.0 65.0 75.0 85.0
90.0 95.0 105.0 115.0 125.0 135.0 145.0 155.0 165.0 175.0
180.0
1789. 1841. 1911. 1979. 2023. 2025. 1994. 1867. 1718. 1551.
1374. 1208. 990. 808. 637. 469. 347. 202. 89. 18.
9. 7. 7. 6. 0.
1789. 1831. 1908. 1969. 2013. 2018. 1983. 1865. 1701. 1548.
1353. 1193. 981. 842. 661. 503. 352. 172. 68. 19.
8. 6. 6. 5. 0.
1789. 1828. 1891. 1939. 1958. 1939. 1908. 1808. 1668. 1559.
1428. 1300. 1222. 1161. 999. 778. 580. 318. 129. 39.
10. 7. 7. 4. 0.
1789. 1818. 1865. 1891. 1942. 1959. 1927. 1843. 1761. 1714.
1673. 1599. 1445. 1325. 1165. 948. 668. 400. 186. 75.
30. 9. 7. 2. 0.
1789. 1811. 1821. 1891. 1941. 1974. 1980. 1943. 1993. 2082.
1963. 1808. 1621. 1601. 1424. 1166. 829. 487. 279. 152.
65. 15. 8. 2. 0.
1789. 1794. 1804. 1893. 1935. 1995. 2020. 2145. 2342. 2221.
2063. 2135. 2157. 1694. 948. 340. 101. 8. 0. 185.
94. 32. 9. 0. 0.
1789. 1775. 1803. 1868. 1931. 1992. 2076. 2357. 2333. 2285.
2254. 2608. 2375. 2010. 1722. 1448. 981. 661. 376. 244.
122. 38. 8. 0. 0.
1789. 1763. 1798. 1839. 1918. 1961. 2151. 2291. 2310. 2263.
2575. 2700. 2380. 2075. 1792. 1483. 1102. 702. 430. 298.
192. 67. 11. 2. 0.
1789. 1746. 1801. 1827. 1871. 1923. 2176. 2119. 2124. 2062.
2553. 2596. 2201. 1907. 1678. 1368. 1015. 673. 440. 303.
178. 63. 10. 1. 0.
1789. 1738. 1788. 1808. 1830. 1895. 2081. 2024. 1953. 1883.
2313. 2285. 1854. 1661. 1400. 1139. 833. 577. 404. 267.
157. 54. 12. 1. 0.
1789. 1735. 1783. 1797. 1812. 1868. 2046. 1983. 1911. 1805.
2191. 2151. 1759. 1513. 1288. 1033. 802. 568. 386. 243.
134. 56. 10. 3. 0.
1789. 1734. 1778. 1786. 1797. 1838. 2016. 1951. 1871. 1766.
2128. 2078. 1681. 1474. 1248. 1009. 739. 523. 349. 228.
144. 52. 13. 2. 0.
1789. 1733. 1774. 1773. 1771. 1777. 1959. 1895. 1811. 1647.
2034. 1957. 1595. 1293. 1118. 925. 717. 481. 319. 208.
125. 51. 7. 1. 0.
1789. 1738. 1763. 1755. 1744. 1704. 1880. 1794. 1752. 1541.
1772. 1720. 1427. 1191. 1003. 795. 588. 427. 274. 166.
98. 39. 8. 3. 0.
1789. 1734. 1744. 1732. 1708. 1647. 1674. 1703. 1620. 1413.
1325. 1423. 1205. 983. 808. 642. 464. 312. 192. 107.
57. 18. 8. 3. 0.
1789. 1735. 1714. 1725. 1673. 1590. 1481. 1511. 1373. 1230.
982. 993. 902. 771. 626. 456. 300. 187. 112. 60.
31. 14. 8. 4. 0.
1789. 1736. 1681. 1700. 1617. 1511. 1381. 1252. 1210. 1043.
875. 657. 554. 487. 398. 294. 195. 122. 70. 40.
19. 11. 8. 3. 0.
1789. 1737. 1666. 1641. 1577. 1471. 1333. 1172. 1015. 890.
728. 574. 409. 326. 243. 181. 114. 72. 40. 24.
14. 9. 7. 4. 0.
1789. 1740. 1679. 1601. 1493. 1388. 1268. 1114. 956. 769.
624. 481. 347. 267. 201. 141. 85. 41. 25. 16.
10. 7. 6. 3. 0.
1789. 1737. 1693. 1616. 1479. 1340. 1187. 1041. 896. 724.
572. 431. 303. 233. 167. 117. 62. 29. 18. 12.
9. 6. 6. 4. 1.
1789. 1742. 1698. 1623. 1491. 1354. 1196. 1040. 894. 722.
565. 421. 302. 227. 159. 108. 57. 20. 14. 10.
8. 6. 6. 5. 0.

View file

@ -0,0 +1,16 @@
IESNA:LM-63-2002
[TEST]BALLABS TEST NO. 14501.0
[TESTLAB] BUILDING ACOUSTICS & LIGHTING LABORATORIES, INC
[ISSUEDATE] 04-MAR-2009
[MANUFAC] LeoMoon Studios
[LUMINAIRE] 1/100W CLEAR ED17PS MH HORIZ LAMP LS SERIES POST LUMINAIRE
[MORE] WHITE TOP REFLECTOR w/FROSTED GLASS CHIMNEY
[MORE] CLEAR ACRYLIC PANELS
[LUMCAT] HLSC15-100PSMH120-BLK
[LAMPCAT] M90
TILT=NONE
1 9000 1 35 1 1 1 0.885 0.885 0.781
1 1 100
0 5 10 15 20 25 30 35 40 45 50 55 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 95 105 115 125 135 145 155 165 175 180
0
67.00 113.00 238.00 460.00 973.00 1277.00 1388.00 1425.00 1408.00 1338.00 1199.00 1018.00 700.00 430.00 320.00 335.00 227.00 209.00 154.00 137.00 125.00 109.00 91.00 65.00 46.00 38.00 25.00 18.00 10.00 5.00 3.00 3.00 0.00 0.00 0.00

View file

@ -0,0 +1,13 @@
IESNA:LM-63-1995
[TEST] BE1680
[DATE] 12-FEB-96
[MANUFAC] LeoMoon Studios
[LUMCAT] 6340
[LUMINAIRE] SURFACE MOUNTED WALL LUMINAIRE
[LAMP] (1) 100W A-19 INC
TILT=NONE
1 1750 1.75 73 1 1 2 -.1 0 .05
1 1 100
0 2.5 5 7.5 10 12.5 15 17.5 20 22.5 25 27.5 30 32.5 35 37.5 40 42.5 45 47.5 50 52.5 55 57.5 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 92.5 95 97.5 100 102.5 105 107.5 110 112.5 115 117.5 120 122.5 125 127.5 130 132.5 135 137.5 140 142.5 145 147.5 150 152.5 155 157.5 160 162.5 165 167.5 170 172.5 175 177.5 180
0
167.3 168.9 173 179.9 179.2 151.2 119.4 95.63 81.03 71.95 66.46 62.67 60.25 57.67 52.18 46.62 48.91 63.15 83.15 95.41 97.4 87.75 62.6 43.08 39.26 47.36 52.89 45.74 31.45 18.17 10.5 7.888 8.112 7.592 3.665 .6467 .498 .4252 .3735 .3185 .2765 .2279 .2199 .2021 .1746 .1407 .1358 .1277 .1326 .1342 .1406 .1374 .1358 .1375 .1488 .1488 .1536 .1925 .2183 .2328 .2345 .249 .2765 .3023 .3266 .3476 .3557 .3638 .3541 .3573 .3638 .3719 .3816

View file

@ -967,6 +967,36 @@ $guiContent = new GuiControl(GuiEditorGui, EditorGuiGroup) {
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
new GuiTextEditCtrl( GuiEditorInspectorFilter ) {
position = "5 0";
extent = "222 20";
profile = "ToolsGuiTextEditProfile";
horizSizing = "width";
vertSizing = "bottom";
placeholderText = "Filter...";
validate = "GuiEditorInspectFields.setSearchText($ThisControl.getText());";
};
new GuiBitmapButtonCtrl() {
bitmapAsset = "ToolsModule:clear_icon_n_image";
groupNum = "-1";
buttonType = "PushButton";
useMouseEvents = "0";
isContainer = "0";
Profile = "ToolsGuiDefaultProfile";
HorizSizing = "left";
VertSizing = "bottom";
position = "205 2";
Extent = "17 17";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
command = "GuiEditorInspectorFilter.setText(\"\");GuiEditorInspectFields.setSearchText(\"\");";
};
new GuiScrollCtrl() {
willFirstRespond = "1";
@ -979,7 +1009,7 @@ $guiContent = new GuiControl(GuiEditorGui, EditorGuiGroup) {
mouseWheelScrollSpeed = "-1";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorTop = "0";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
@ -987,8 +1017,8 @@ $guiContent = new GuiControl(GuiEditorGui, EditorGuiGroup) {
Profile = "GuiEditorScrollProfile";
HorizSizing = "width";
VertSizing = "height";
position = "0 2";
Extent = "223 341";
position = "0 20";
Extent = "223 321";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
@ -1011,7 +1041,7 @@ $guiContent = new GuiControl(GuiEditorGui, EditorGuiGroup) {
HorizSizing = "width";
VertSizing = "bottom";
position = "1 1";
Extent = "221 24";
Extent = "221 321";
MinExtent = "8 24";
canSave = "1";
Visible = "1";

View file

@ -745,8 +745,9 @@ function MaterialEditorGui::setActiveMaterial( %this, %material )
MaterialEditorGui.lastMaterial = %material;
// we create or recreate a material to hold in a pristine state
if(isObject(notDirtyMaterial))
notDirtyMaterial.delete();
// or, this crashes the ap. fix properly - BJR
// if(isObject(notDirtyMaterial))
// notDirtyMaterial.delete();
singleton Material(notDirtyMaterial)
{

View file

@ -41,7 +41,7 @@
<Setting
name="doubleClickAction">Edit Asset</Setting>
<Setting
name="LastPosExt">0 976 2200 360</Setting>
name="LastPosExt">0 634 1560 360</Setting>
<Setting
name="previewTileSize">1</Setting>
<Setting
@ -245,7 +245,7 @@
<Setting
name="AdvancedWndVisible">1</Setting>
<Setting
name="backgroundColor">0 0 0 100</Setting>
name="backgroundColor">128 128 128 100</Setting>
<Setting
name="gridDimension">40 40</Setting>
<Setting
@ -367,12 +367,10 @@
name="dropType">screenCenter</Setting>
<Setting
name="EditorLayoutMode">Modern</Setting>
<Setting
name="forceLoadDAE">0</Setting>
<Setting
name="forceSidebarToSide">1</Setting>
<Setting
name="orthoFOV">4.60158014</Setting>
name="orthoFOV">1.21430779</Setting>
<Setting
name="orthoShowGrid">1</Setting>
<Setting

View file

@ -41,7 +41,7 @@ $guiContent = new GuiControl() {
canSave = "1";
Visible = "1";
hovertime = "1000";
color = "0 0 0 .39";
color = "0.5 0.5 0.5 .39";
};
new GuiShapeEdPreview(ShapeEdShapeView) {
canSaveDynamicFields = "0";

View file

@ -354,7 +354,7 @@ function ShapeEditorPlugin::initSettings( %this )
EditorSettings.beginGroup( "ShapeEditor", true );
// Display options
EditorSettings.setDefaultValue( "BackgroundColor", "0 0 0 100" );
EditorSettings.setDefaultValue( "BackgroundColor", "128 128 128 100" );
EditorSettings.setDefaultValue( "HighlightMaterial", 1 );
EditorSettings.setDefaultValue( "ShowNodes", 1 );
EditorSettings.setDefaultValue( "ShowBounds", 0 );

View file

@ -1585,7 +1585,7 @@ function ShapeEdSeqFromMenu::onBrowseSelect( %this, %assetId )
function ShapeEdAnimWIndow::onWake(%this)
{
%animWindow = ShapeEdAnimWIndow;
%position = "1" SPC Canvas.extent.y - 112;
%position = "1" SPC Canvas.extent.y - 132;
if(isObject(ShapeEdPropWindow))
{

View file

@ -67,6 +67,36 @@ $guiContent = new GuiControl() {
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
new GuiTextEditCtrl( EditorInspectorFilter ) {
position = "5 -4";
extent = "341 20";
profile = "ToolsGuiTextEditProfile";
horizSizing = "width";
vertSizing = "bottom";
placeholderText = "Filter...";
validate = "Inspector.setSearchText($ThisControl.getText());";
};
new GuiBitmapButtonCtrl() {
bitmapAsset = "ToolsModule:clear_icon_n_image";
groupNum = "-1";
buttonType = "PushButton";
useMouseEvents = "0";
isContainer = "0";
Profile = "ToolsGuiDefaultProfile";
HorizSizing = "left";
VertSizing = "bottom";
position = "325 -2";
Extent = "17 17";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
command = "EditorInspectorFilter.setText(\"\");Inspector.setSearchText(\"\");";
};
new GuiScrollCtrl() {
canSaveDynamicFields = "0";
@ -74,20 +104,20 @@ $guiContent = new GuiControl() {
isContainer = "1";
Profile = "GuiEditorScrollProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "5 5";
Extent = "187 238";
VertSizing = "bottom";
Position = "5 20";
Extent = "343 941";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Docking = "Client";
Docking = "None";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorTop = "0";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorLeft = "0";
AnchorRight = "0";
willFirstRespond = "1";
hScrollBar = "alwaysOff";
@ -109,7 +139,7 @@ $guiContent = new GuiControl() {
HorizSizing = "width";
VertSizing = "bottom";
Position = "0 0";
Extent = "202 309";
Extent = "343 941";
MinExtent = "8 8";
canSave = "1";
Visible = "1";