mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 03:33:48 +00:00
Updates the handling of the baking of shape asset previews to generate them with support for view angle control to improve visibility, as well as supporting overriding of a material in the preview bake
Also utilizes the updated bake handling to have material asset previews render as a sphere shape asset, overriding with the material asset's material, improving distinction of what is a material asset vs image asset Also updates the sphere preview mesh to be more generic and not only for reflection probes
This commit is contained in:
parent
d9bedbe31c
commit
b70faae38f
10 changed files with 206 additions and 172 deletions
|
|
@ -51,6 +51,9 @@
|
|||
#endif
|
||||
#include "util/imposterCapture.h"
|
||||
|
||||
#include "ts/tsShapeInstance.h"
|
||||
#include "gfx/bitmap/imageUtils.h"
|
||||
|
||||
StringTableEntry ShapeAsset::smNoShapeAssetFallback = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -560,25 +563,94 @@ ShapeAnimationAsset* ShapeAsset::getAnimation(S32 index)
|
|||
}
|
||||
|
||||
#ifdef TORQUE_TOOLS
|
||||
const char* ShapeAsset::generateCachedPreviewImage(S32 resolution)
|
||||
const char* ShapeAsset::generateCachedPreviewImage(S32 resolution, String overrideMaterial)
|
||||
{
|
||||
if (!mShape)
|
||||
return "";
|
||||
|
||||
TSLastDetail* dt = new TSLastDetail(mShape,
|
||||
mFilePath,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
resolution);
|
||||
// We're gonna render... make sure we can.
|
||||
bool sceneBegun = GFX->canCurrentlyRender();
|
||||
if (!sceneBegun)
|
||||
GFX->beginScene();
|
||||
|
||||
dt->update();
|
||||
// We need to create our own instance to render with.
|
||||
TSShapeInstance* shape = new TSShapeInstance(mShape, true);
|
||||
|
||||
delete dt;
|
||||
if(overrideMaterial.isNotEmpty())
|
||||
shape->reSkin(overrideMaterial, mShape->materialList->getMaterialName(0));
|
||||
|
||||
return mFilePath;
|
||||
// Animate the shape once.
|
||||
shape->animate(0);
|
||||
|
||||
// So we don't have to change it everywhere.
|
||||
const GFXFormat format = GFXFormatR8G8B8A8;
|
||||
|
||||
GBitmap* imposter = NULL;
|
||||
GBitmap* imposterNrml = NULL;
|
||||
|
||||
ImposterCapture* imposterCap = new ImposterCapture();
|
||||
|
||||
static const MatrixF topXfm(EulerF(-M_PI_F / 2.0f, 0, 0));
|
||||
static const MatrixF bottomXfm(EulerF(M_PI_F / 2.0f, 0, 0));
|
||||
|
||||
MatrixF angMat;
|
||||
|
||||
S32 mip = 0;
|
||||
|
||||
PROFILE_START(ShapeAsset_generateCachedPreviewImage);
|
||||
|
||||
//dMemset(destBmp.getWritableBits(mip), 0, destBmp.getWidth(mip) * destBmp.getHeight(mip) * GFXFormat_getByteSize(format));
|
||||
|
||||
F32 rotX = -(mDegToRad(60.0) - 0.5f * M_PI_F);
|
||||
F32 rotZ = -(mDegToRad(45.0) - 0.5f * M_PI_F);
|
||||
|
||||
// We capture the images in a particular order which must
|
||||
// match the order expected by the imposter renderer.
|
||||
|
||||
imposterCap->begin(shape, 0, resolution, mShape->mRadius, mShape->center);
|
||||
|
||||
angMat.mul(MatrixF(EulerF(rotX, 0, 0)),
|
||||
MatrixF(EulerF(0, 0, rotZ)));
|
||||
|
||||
imposterCap->capture(angMat, &imposter, &imposterNrml);
|
||||
|
||||
imposterCap->end();
|
||||
|
||||
PROFILE_END(); // ShapeAsset_generateCachedPreviewImage
|
||||
|
||||
delete imposterCap;
|
||||
delete shape;
|
||||
|
||||
String dumpPath = String(mFilePath) + "_Preview.dds";
|
||||
|
||||
char* returnBuffer = Con::getReturnBuffer(dumpPath.length());
|
||||
dSprintf(returnBuffer, dumpPath.length(), "%s", dumpPath.c_str());
|
||||
|
||||
/*FileStream stream;
|
||||
if (stream.open(dumpPath, Torque::FS::File::Write))
|
||||
destBmp.writeBitmap("png", stream);
|
||||
stream.close();*/
|
||||
|
||||
DDSFile* ddsDest = DDSFile::createDDSFileFromGBitmap(imposter);
|
||||
ImageUtil::ddsCompress(ddsDest, GFXFormatBC2);
|
||||
|
||||
// Finally save the imposters to disk.
|
||||
FileStream fs;
|
||||
if (fs.open(returnBuffer, Torque::FS::File::Write))
|
||||
{
|
||||
ddsDest->write(fs);
|
||||
fs.close();
|
||||
}
|
||||
|
||||
delete ddsDest;
|
||||
delete imposter;
|
||||
delete imposterNrml;
|
||||
|
||||
// If we did a begin then end it now.
|
||||
if (!sceneBegun)
|
||||
GFX->endScene();
|
||||
|
||||
return returnBuffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -625,9 +697,12 @@ DefineEngineMethod(ShapeAsset, getStatusString, String, (), , "get status string
|
|||
|
||||
|
||||
#ifdef TORQUE_TOOLS
|
||||
DefineEngineMethod(ShapeAsset, generateCachedPreviewImage, const char*, (S32 resolution), (256), "")
|
||||
DefineEngineMethod(ShapeAsset, generateCachedPreviewImage, const char*, (S32 resolution, const char* overrideMaterialName), (256, ""),
|
||||
"Generates a baked preview image of the given shapeAsset. Only really used for generating Asset Browser icons.\n"
|
||||
"@param resolution Optional field for what resolution to bake the preview image at. Must be pow2\n"
|
||||
"@param overrideMaterialName Optional field for overriding the material used when rendering the shape for the bake.")
|
||||
{
|
||||
return object->generateCachedPreviewImage(resolution);
|
||||
return object->generateCachedPreviewImage(resolution, overrideMaterialName);
|
||||
}
|
||||
|
||||
DefineEngineStaticMethod(ShapeAsset, getAssetIdByFilename, const char*, (const char* filePath), (""),
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ public:
|
|||
static U32 getAssetById(StringTableEntry assetId, AssetPtr<ShapeAsset>* shapeAsset);
|
||||
|
||||
#ifdef TORQUE_TOOLS
|
||||
const char* generateCachedPreviewImage(S32 resolution);
|
||||
const char* generateCachedPreviewImage(S32 resolution, String overrideMaterial = "");
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -798,7 +798,7 @@ void ReflectionProbe::createEditorResources()
|
|||
|
||||
mEditorShape = NULL;
|
||||
|
||||
String shapeFile = "tools/resources/ReflectProbeSphere.dae";
|
||||
String shapeFile = "tools/resources/previewSphereShape.dae";
|
||||
|
||||
// Attempt to get the resource from the ResourceManager
|
||||
mEditorShape = ResourceManager::get().load(shapeFile);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue