LightsprintSDK 2021.08.08
|
#include <RRObject.h>
Public Member Functions | |
void | makeNamesUnique () const |
virtual unsigned | loadLayer (int layerNumber, const RRString &path, const RRString &ext) const |
virtual unsigned | saveLayer (int layerNumber, const RRString &path, const RRString &ext) const |
virtual unsigned | layerExistsInMemory (int layerNumber) const |
virtual unsigned | layerDeleteFromMemory (int layerNumber) const |
virtual unsigned | layerDeleteFromDisk (const RRString &path, const RRString &ext) const |
virtual unsigned | allocateBuffersForRealtimeGI (int layerLightmap, int layerEnvironment, unsigned diffuseEnvMapSize, unsigned specularEnvMapSize, unsigned refractEnvMapSize, bool allocateNewBuffers, bool changeExistingBuffers, float specularThreshold, float depthThreshold) const |
unsigned | checkConsistency (const char *objectType) const |
virtual unsigned | buildUnwrap (unsigned resolution, unsigned minimalUvChannel, unsigned minTrianglesForFastUnwrap, bool &aborting) const |
void | getAllMaterials (RRMaterials &materials) const |
void | updateColorLinear (const RRColorSpace *colorSpace) const |
virtual unsigned | flipFrontBack (unsigned numNormalsThatMustPointBack, bool report) const |
virtual unsigned | buildTangents (RRMesh::TangentSpaceState stateThatWarrantsRebuild) const |
virtual unsigned | optimizeFaceGroups (RRObject *object=nullptr) const |
RRObjects | mergeObjects (bool splitByMaterial) const |
RRObject * | createMultiObject (RRCollider::IntersectTechnique intersectTechnique, bool &aborting, float maxDistanceBetweenVerticesToStitch, float maxRadiansBetweenNormalsToStitch, bool optimizeTriangles, unsigned speed, const char *cacheLocation) const |
virtual void | smoothAndStitch (bool splitVertices, bool mergeVertices, bool removeUnusedVertices, bool removeDegeneratedTriangles, bool stitchPositions, bool stitchNormals, bool generateNormals, float maxDistanceBetweenVerticesToStitch, float maxRadiansBetweenNormalsToStitch, float maxDistanceBetweenUvsToStitch, bool report) const |
virtual void | multiplyEmittance (float emissiveMultiplier) const |
void | deleteComponents (bool deleteTangents, bool deleteUnwrap, bool deleteUnusedUvChannels, bool deleteEmptyFacegroups) const |
void | removeEmptyObjects () |
virtual | ~RRObjects () |
Public Member Functions inherited from rr::RRVector< RRObject * > | |
RRVector () | |
RRVector (const RRVector &a) | |
RRVector & | operator= (const RRVector &a) |
void | resize (unsigned newSize, RRObject * initial=RRObject *()) |
void | push_back (RRObject * a) |
void | pop_back () |
void | erase (RRObject * *e) |
size_t | size () const |
RRObject * & | operator[] (unsigned i) |
const RRObject * & | operator[] (unsigned i) const |
void | clear () |
RRObject * * | begin () |
const RRObject * * | begin () const |
RRObject * * | end () |
const RRObject * * | end () const |
void | insert (RRObject * *_where, const RRObject * *_first, const RRObject * *_last) |
bool | operator== (const RRVector< RRObject * > &a) const |
bool | operator!= (const RRVector< RRObject * > &a) const |
~RRVector () | |
Additional Inherited Members | |
Protected Attributes inherited from rr::RRVector< RRObject * > | |
RRObject * * | c |
unsigned | numAllocated |
unsigned | numUsed |
Set of objects with interface similar to std::vector.
GI solver uses this class to set all static or dynamic objects at once. You can adapt content from memory or load content from files to RRObjects, see scene adapters in LightsprintIO library; or you can fill RRObjects instance manually, using push_back(object).
|
inlinevirtual |
Destructor does not delete objects in collection (but individual adapters may do).
void rr::RRObjects::makeNamesUnique | ( | ) | const |
Modifies non-unique object names to make them unique.
When multiple objects with the same name "name" are found, they are renamed to "name", "name.2", "name.3" etc. Function ensures that filenames derived from object names are also unique (when comparing names, function thinks of all non-filename characters as '_'). Such extended uniqueness is necessary when loading/saving layers, because e.g. default lightmap filenames are constructed from object names. If you don't ensure uniqueness, multiple lightmaps may end up with the same filename and with incorrect illumination.
|
virtual |
Loads illumination layer from disk.
It is shortcut for calling illumination->getLayer() = RRBuffer::load() on all elements in this container.
layerNumber | Layer to load, nothing is done for negative number. |
path | Where to read files, should have trailing slash. |
ext | File format of maps to load, e.g. "png". Vertex buffers are always loaded from .rrbuffer, without regard to ext. |
|
virtual |
Saves illumination layer to disk.
It is shortcut for calling illumination->getLayer()->save() on all elements in this container.
layerNumber | Layer to save, nothing is done for negative number. |
path | Where to store files, should have trailing slash. Subdirectories are not created. |
ext | File format of maps to save, e.g. "png". Vertex buffers are always saved to .rrbuffer, without regard to ext. |
|
virtual |
Returns number of buffers in memory.
|
virtual |
Deletes buffers from memory.
|
virtual |
Deletes buffers from disk.
|
virtual |
Allocates buffers for realtime GI illumination.
Before rendering realtime GI, you need buffers for illumination to be calculated into.
For the best control, you can allocate these buffers manually, using code like for (all static objects) illumination.getLayer(layerLightmap) = RRBuffer::create(BT_VERTEX_BUFFER,getNumVertices(),1,1,BF_RGBF,false,nullptr); for (all objects that need environment map) illumination.getLayer(layerEnvironment) = RRBuffer::create(BT_CUBE_TEXTURE,16,16,6,BF_RGBA,true,nullptr);
However, you can save time by calling this helper function, once for solver's static objects, once for dynamic ones.
Well, you can save even more by calling RRSolver::allocateBuffersForRealtimeGI(), it handles both static ond dynamic objects at once.
layerLightmap | Arbitrary layer number for storing realtime calculated per-vertex indirect illumination. If >=0, vertex buffers in illumination->getLayer(layerLightmap) are allocated, resized or deleted according to other parameters. You should pass the same layer number to renderer, so it can use buffers you just allocated. Pass <0 if you don't want to touch vertex buffers. Vertex buffers are suitable (=we can realtime update them) only for static objects. |
layerEnvironment | Arbitrary layer number for storing realtime calculated environment maps. If >=0, cubemaps in illumination->getLayer(layerEnvironment) are allocated, resized or deleted according to other parameters. You should pass the same layer number to renderer, so it can use buffers you just allocated. Pass <0 if you don't want to touch environment maps. Environment maps are suitable (=we can realtime update them) for both static and dynamic objects. |
diffuseEnvMapSize | If materials have diffuse reflection, reflection map of at least this size will be allocated in illumination. Size 4 is usually good enough. |
specularEnvMapSize | If materials have specular reflection, reflection map of at least this size will be allocated in illumination. Size 16 is usually sufficient, not very sharp, but makes GI calculation fast. |
refractEnvMapSize | If materials refract light using cubemap, cubemap of at least this size will be allocated in illumination. Size 16 is very lowres, but it makes GI calculation fast. |
allocateNewBuffers | If buffer does not exist yet, true = it will be allocated, false = no action. |
changeExistingBuffers | If buffer already exists, true = it will be resized or deleted accordingly, false = no action. |
specularThreshold | Only objects with specular color above threshold apply for specular cube reflection, -1=all objects apply, 0=all objects with specular apply, 0.2=only objects with spec color above 0.2 apply. |
depthThreshold | Only objects with depth above threshold apply for specular cube reflection, 0=all objects apply, 0.1=all but near planar objects apply, 1=none apply. Depth is number between 0 and 1, calculated as ratio between min and mid size of axis aligned bounding box. Purpose of depthThreshold is to exclude very flat objects from processing, environment reflections produce visible inaccuracies on such objects. For absolutely flat objects, see rr_gl::UberProgramSetup::LIGHT_INDIRECT_MIRROR_SPECULAR, it produces reflections of high quality and accuracy. |
unsigned rr::RRObjects::checkConsistency | ( | const char * | objectType | ) | const |
Reports inconsistencies found in objects.
objectType | Optional identifier of collection, e.g "static", "dynamic". May be nullptr. |
|
virtual |
Rebuilds unwrap in all meshes of RRMeshArrays type.
New unwrap is created into the lowest unused uv channel, the same channel in all meshes. All materials are updated to use new unwrap. All successfully unwrapped meshes have RRMeshArrays::unwrapChannel/unwrapWidth/unwrapHeight set, failed and aborted meshes stay completely unchanged.
Unwrapper doesn't modify pointers to objects, colliders, materials or meshes, but it can add new vertices in mesh, if unwrap contains seams. Therefore structures that depend on exact number of vertices may need update after unwrapping. This is case of solver; if you build unwrap in solver solver->getStaticObjects().buildUnwrap(...)
, you have to resend modified objects to solver solver->setStaticObjects(solver->getStaticObjects(),...)
.
Currently it is implemented only for Windows platform.
resolution | Expected lightmap resolution, e.g. 1024 for 1024x1024. |
minimalUvChannel | New unwrap is created into the lowest unused uv channel, but at least minimalUvChannel. So if minimalUvChannel=2, unwrap is never created to channel 0 or 1. |
minTrianglesForFastUnwrap | Higher quality but slower technique is used for meshes with lower number of triangles. It is too slow for large meshes, so reasonable threshold could be 25000. |
aborting | May be set asynchronously, aborts build. |
void rr::RRObjects::getAllMaterials | ( | RRMaterials & | materials | ) | const |
Inserts all materials found in objects into collection.
May shuffle elements that were already present in collection. Removes duplicates, the same material is never listed twice.
void rr::RRObjects::updateColorLinear | ( | const RRColorSpace * | colorSpace | ) | const |
Converts color to colorLinear in all materials.
Solver calls it automatically from RRSolver::setStaticObjects() and setDynamicObjects().
|
virtual |
Flips front/back if at least this number of normals in triangle points to back side.
So all triangles are flipped if numNormalsThatMustPointBack==0.
|
virtual |
Builds tangents in selected meshes. Returns number of meshes modified.
stateThatWarrantsRebuild | Pass TSS_MISSING to build only missing tangents, TSS_INVALID to rebuild also invalid ones etc. TSS_PERFECT rebuilds all tangents, even perfect ones. |
|
virtual |
Merges facegroups with the same material. Reorders triangles in mesh if necessary.
Object is silently skipped in two special cases: if either its mesh is not of RRMeshArrays type or the mesh appears multiple times in this collection.
Note that objects alone don't have a way to find out what other objects use the same mesh, therefore you should call this function on collection of all objects (or at least all potential instances of the same mesh). Collection is scanned for instances of the same mesh, and if found, optimization is skipped to avoid breaking materials in other object. If you know that no other instance with the same mesh exists, you can safely use any collection, even empty.
object | Object to be optimized. If it is nullptr, all objects in this collection are optimized. |
RRObjects rr::RRObjects::mergeObjects | ( | bool | splitByMaterial | ) | const |
Merges objects from collection, and optionally splits them by materials.
Returns newly created object or collection of objects that doesn't depend on old objects, colliders and meshes. New structures contain copy of all triangle and vertex data in RRMeshArrays format. Only materials are shared between old and new objects.
RRObject * rr::RRObjects::createMultiObject | ( | RRCollider::IntersectTechnique | intersectTechnique, |
bool & | aborting, | ||
float | maxDistanceBetweenVerticesToStitch, | ||
float | maxRadiansBetweenNormalsToStitch, | ||
bool | optimizeTriangles, | ||
unsigned | speed, | ||
const char * | cacheLocation | ||
) | const |
Creates and returns union of multiple objects (contains geometry and materials from all objects), in world space.
In contrast to mergeObjects(), createMultiObject() doesn't allocate additional memory, but it depends on original objects, they must stay alive for whole life of MultiObject.
Merging can be used to accelerate calculations, as one big object is nearly always faster than multiple small objects.
Merging can be used to simplify calculations, as processing one object may be simpler than processing array of objects.
For description how to access original triangles and vertices in MultiObject, see RRMesh::createMultiMesh().
intersectTechnique | Technique used for collider construction. |
aborting | May be set asynchronously, aborts creation. |
maxDistanceBetweenVerticesToStitch | Distance in world units. Vertices with lower or equal distance may be stitched into one vertex (if they satisfy also maxRadiansBetweenNormalsToStitch). Zero may stitch only identical vertices, negative value means no action. Vertices are stitched even if uv coordinates differ. Therefore stitchig is safe for offline calculation, but it could break mapping in relatime renderer. |
maxRadiansBetweenNormalsToStitch | Vertices with lower or equal angle between normals may be stitched into one vertex (if they satisfy also maxDistanceBetweenVerticesToStitch). Zero may stitch only identical normals, negative value means no action. |
optimizeTriangles | True removes degenerated triangles. It is always good to get rid of degenerated triangles (true), but sometimes you know there are no degenerated triangles at all and you can save few cycles by setting false. |
speed | Could make object faster, but needs additional memory. 0 = normal speed, 0bytes/triangle overhead 1 = +speed, 12bytes/triangle overhead 2 = ++speed, 156bytes/triangle overhead |
cacheLocation | Directory for caching intermediate files used by RRCollider. It is passed to RRCollider::create(), so default nullptr caches in temp, "*" or any other invalid path disables caching, any valid is path where to cache colliders. |
|
virtual |
Rebuilds objects to make them smooth (possibly changing numbers of triangles, vertices, facegroups).
If there are multiple objects sharing one mesh, all objects must be smoothed at once (because smoothing can remove triangles and object facegroups must reflect that).
Smoothing doesn't modify pointers to objects, colliders, materials or meshes, but it can add/remove triangles/vertices in mesh, depending on parameters. Therefore structures that depend on exact number of triangles/vertices may need update after smoothing. This is case of solver; if you smooth in solver solver->getStaticObjects().smoothAndStitch(...)
, you have to resend modified objects to solver solver->setStaticObjects(solver->getStaticObjects(),...)
.
splitVertices | Allows splitting vertices shared by multiple triangles (increases number of vertices), can make mesh less smooth. |
mergeVertices | Allows merging similar vertices (reduces number of vertices), can make mesh smoother. |
removeUnusedVertices | Removes unused vertices (reduces number of vertices). |
removeDegeneratedTriangles | Removes degenerated triangles possibly created by merging/stitching (reduces number of triangles). There might be unused vertices after removal of degenerated triangles, use removeUnusedVertices to remove them. Note that number of triangles may drop to zero, you can use removeEmptyObjects() to remove such objects. |
stitchPositions | Allows stitching positions of nearby vertices (doesn't change number of vertices). |
stitchNormals | Allows stitching normals of nearby vertices (doesn't change number of vertices). |
generateNormals | True = generates new normals from mesh geometry, completely ignoring old normals (but keeps existing tangents). False = keeps existing normals (and tangents). |
maxDistanceBetweenVerticesToStitch | When merging and/or stitching, controls maximal distance between vertices to merge and/or stitch. |
maxRadiansBetweenNormalsToStitch | When merging and/or stitching, controls maximal angle between face normals to stitch and smooth. |
maxDistanceBetweenUvsToStitch | When merging, controls maximal distance between uvs to merge. |
report | Allows reporting warnings. |
|
virtual |
Multiplies emittance in all materials, both colors and textures.
void rr::RRObjects::deleteComponents | ( | bool | deleteTangents, |
bool | deleteUnwrap, | ||
bool | deleteUnusedUvChannels, | ||
bool | deleteEmptyFacegroups | ||
) | const |
Deletes selected object components: tangents, unwrap, uv channels not referenced by materials.
void rr::RRObjects::removeEmptyObjects | ( | ) |
Removes objects with zero triangles or vertices. Does not delete them.