LightsprintSDK 2021.08.08
rr::RRMeshArrays Class Reference

#include <RRMesh.h>

Inheritance diagram for rr::RRMeshArrays:
rr::RRMesh rr::RRUniformlyAllocatedNonCopyable rr::RRUniformlyAllocated

Public Member Functions

bool resizeMesh (unsigned numTriangles, unsigned numVertices, const RRVector< unsigned > *texcoords, bool tangents, bool preserveContents)
 
bool reload (const RRMesh *mesh, bool indexed, const RRVector< unsigned > &texcoords, bool tangents)
 
 RRMeshArrays ()
 
virtual ~RRMeshArrays ()
 
virtual unsigned getNumVertices () const override
 
virtual void getVertex (unsigned v, Vertex &out) const override
 
virtual unsigned getNumTriangles () const override
 
virtual void getTriangle (unsigned t, Triangle &out) const override
 
virtual void getTriangleBody (unsigned i, TriangleBody &out) const override
 
virtual void getTriangleNormals (unsigned t, TriangleNormals &out) const override
 
virtual bool getTriangleMapping (unsigned t, TriangleMapping &out, unsigned channel) const override
 
virtual void getUvChannels (RRVector< unsigned > &out) const override
 
virtual void getAABB (RRVec3 *mini, RRVec3 *maxi, RRVec3 *center) const override
 
unsigned flipFrontBack (unsigned numNormalsThatMustPointBack, bool negativeScale)
 
void buildNormals ()
 
void buildTangents (unsigned uvChannel)
 
unsigned manipulateMapping (unsigned sourceChannel, const float *matrix2x3, unsigned destinationChannel)
 
- Public Member Functions inherited from rr::RRMesh
 RRMesh ()
 
virtual ~RRMesh ()
 
virtual unsigned getNumVertices () const =0
 
virtual void getVertex (unsigned v, Vertex &out) const =0
 
virtual unsigned getNumTriangles () const =0
 
virtual void getTriangle (unsigned t, Triangle &out) const =0
 
virtual void getTriangleBody (unsigned t, TriangleBody &out) const
 
virtual bool getTrianglePlane (unsigned t, RRVec4 &out) const
 
virtual RRReal getTriangleArea (unsigned t) const
 
virtual void getTriangleNormals (unsigned t, TriangleNormals &out) const
 
virtual bool getTriangleMapping (unsigned t, TriangleMapping &out, unsigned channel) const
 
virtual PreImportNumber getPreImportVertex (unsigned postImportVertex, unsigned postImportTriangle) const
 
virtual unsigned getPostImportVertex (PreImportNumber preImportVertex, PreImportNumber preImportTriangle) const
 
virtual PreImportNumber getPreImportTriangle (unsigned postImportTriangle) const
 
virtual unsigned getPostImportTriangle (PreImportNumber preImportTriangle) const
 
unsigned getNumPreImportVertices () const
 
virtual void getUvChannels (RRVector< unsigned > &out) const
 
virtual void getAABB (RRVec3 *mini, RRVec3 *maxi, RRVec3 *center) const
 
virtual RRReal getAverageVertexDistance () const
 
virtual RRReal getMappingDensity (unsigned channel) const
 
virtual RRReal findGroundLevel () const
 
virtual RRHash getHash () const
 
TangentSpaceState checkNormals () const
 
TangentSpaceState checkTangents () const
 
virtual unsigned checkConsistency (unsigned lightmapTexcoord, const char *meshName, class NumReports *numReports=nullptr) const
 
RRMeshcreateTransformed (const RRMatrix3x4Ex *transform) const
 
const RRMeshcreateOptimizedVertices (float maxDistanceBetweenVerticesToMerge, float maxRadiansBetweenNormalsToMerge, float maxDistanceBetweenUvsToMerge, const RRVector< unsigned > *texcoords) const
 
const RRMeshcreateOptimizedTriangles () const
 
const RRMeshcreateAccelerated () const
 
RRMeshcreateVertexBufferRuler () const
 
class RRMeshArrayscreateArrays (bool indexed, const RRVector< unsigned > &texcoords, bool tangents) const
 
- Public Member Functions inherited from rr::RRUniformlyAllocated
void * operator new (std::size_t n)
 
void * operator new[] (std::size_t n)
 
void operator delete (void *p, std::size_t n)
 
void operator delete[] (void *p, std::size_t n)
 

Static Public Member Functions

static RRMeshArraysrectangle ()
 
static RRMeshArraysplane ()
 
static RRMeshArraysbox ()
 
static RRMeshArrayssphere ()
 
static RRMeshArrayscylinder ()
 
- Static Public Member Functions inherited from rr::RRMesh
static RRMeshcreate (unsigned flags, Format vertexFormat, void *vertexBuffer, unsigned vertexCount, unsigned vertexStride)
 
static RRMeshcreateIndexed (unsigned flags, Format vertexFormat, void *vertexBuffer, unsigned vertexCount, unsigned vertexStride, Format indexFormat, void *indexBuffer, unsigned indexCount, float vertexStitchMaxDistance=0)
 
static const RRMeshcreateMultiMesh (const RRMesh *const *meshes, unsigned numMeshes, bool fast)
 

Public Attributes

unsigned numTriangles
 
Triangletriangle
 
unsigned numVertices
 
RRVec3position
 
RRVec3normal
 
RRVec3tangent
 
RRVec3bitangent
 
RRVector< RRVec2 * > texcoord
 
unsigned version
 
unsigned unwrapChannel
 
unsigned unwrapWidth
 
unsigned unwrapHeight
 

Additional Inherited Members

- Public Types inherited from rr::RRMesh
enum  { UNDEFINED = UINT_MAX }
 
enum  TangentSpaceState {
  TSS_PERFECT ,
  TSS_NOT_ORTHOGONAL ,
  TSS_DENORMALIZED ,
  TSS_INVALID ,
  TSS_MISSING
}
 
enum  Format {
  UINT8 = 0 ,
  UINT16 = 1 ,
  UINT32 = 2 ,
  FLOAT32 = 4
}
 
enum  Flags {
  TRI_LIST = 0 ,
  TRI_STRIP = (1<<0) ,
  OPTIMIZED_VERTICES = (1<<1) ,
  OPTIMIZED_TRIANGLES = (1<<2)
}
 
typedef RRVec3 Vertex
 
- Protected Member Functions inherited from rr::RRUniformlyAllocatedNonCopyable
 RRUniformlyAllocatedNonCopyable ()
 
 ~RRUniformlyAllocatedNonCopyable ()
 
- Protected Attributes inherited from rr::RRMesh
struct AABBCache * aabbCache
 

Detailed Description

Mesh that exposes internal structures for direct read-write access.

You may freely edit data in arrays, however, resizing mesh (changing numVertices, numTriangles) is restricted, it is not allowed if other meshes were derived from this one. Derived meshes are e.g. multiobject or worldspace object, they may depend on original mesh size and crash if it changes.

When do we need it? Lightsprint has two major use cases:

  • Calculating GI for third party engine. In this case, we need only read-only access to individual triangles and vertices and RRMesh already provides it via getTriangle()/getVertex(). RRMesh implementations usually read vertices and triangles directly from third party engine structures in memory; duplicating data into RRMeshArrays would only waste memory.
  • Complete application development - render GI, build unwrap, manipulate meshes, vertices etc (without third party engine). In this case, we need also write access and RRMeshArrays provides it. There are no third party structures in memory, all data are stored in RRMeshArrays.

If you need direct read-write access to data in RRMesh, try dynamic_cast<RRMeshArrays*> first, your RRMesh might already be RRMeshArrays. If you don't have RRMeshArrays, create it via RRMesh::createArrays().

Constructor & Destructor Documentation

◆ RRMeshArrays()

rr::RRMeshArrays::RRMeshArrays ( )

◆ ~RRMeshArrays()

virtual rr::RRMeshArrays::~RRMeshArrays ( )
virtual

Member Function Documentation

◆ resizeMesh()

bool rr::RRMeshArrays::resizeMesh ( unsigned  numTriangles,
unsigned  numVertices,
const RRVector< unsigned > *  texcoords,
bool  tangents,
bool  preserveContents 
)

Memory management.

If you resize often, it's safe to resize once to max size and then change only numTriangles/numVertices.

Parameters
numTrianglesNumber of triangles you wish to have after resize.
numVerticesNumber of vertices you wish to have after resize.
texcoordsSet of uv channels you wish to have after resize.
tangentsWhether you wish to have tangents and bitangents after resize.
preserveContentsWhether you wish to preserve data stored in mesh through resizing process. False = triangle and vertex data are uninitialized after resize. True = all triangle and vertex data existing both before and after resize are preserved, while newly allocated data are left uninitialized.
Returns
If allocation fails, mesh is resized to 0 and false is returned.

◆ reload()

bool rr::RRMeshArrays::reload ( const RRMesh mesh,
bool  indexed,
const RRVector< unsigned > &  texcoords,
bool  tangents 
)

Overwrites content of this RRMeshArrays, copies data from given RRMesh.

Parameters
meshData source, mesh data are copied to this.
indexedFalse splits vertices, makes numVertices=3*numTriangles.
texcoordsLets you specify what texcoord channels to copy from original mesh.
tangentsTrue = tangents will be stored in this mesh. False = tangents will be calculated on the fly in getTriangleNormals().

◆ getNumVertices()

virtual unsigned rr::RRMeshArrays::getNumVertices ( ) const
overridevirtual

Returns number of vertices in mesh.

Implements rr::RRMesh.

◆ getVertex()

virtual void rr::RRMeshArrays::getVertex ( unsigned  v,
Vertex out 
) const
overridevirtual

Writes position of v-th vertex in mesh to out.

Make sure you provide valid v is in range <0..getNumVertices()-1>. Implementations are allowed to expect valid v, result is undefined for invalid v (possible assert in debug, crash in release).

What exactly is vertex, do boxes have 8 or 24 vertices?
RRMesh, RRCollider and RRObject create no constraints, you are free to use your favorite approach - create box with 8 or 24 or any other number of vertices greater than 8, collisions and illumination will be computed correctly. (24 because each one of 8 vertices is used by 3 sides with different normal)
RRSolver depends on vertex list defined here. If you request vertex buffer with per-vertex illumination, vertex buffer will have getNumVertices() items. So when writing new RRMesh implementations, create vertex list so that vertex buffers with the same size and vertex order are compatible with your renderer.

Implements rr::RRMesh.

◆ getNumTriangles()

virtual unsigned rr::RRMeshArrays::getNumTriangles ( ) const
overridevirtual

Returns number of triangles in mesh.

Implements rr::RRMesh.

◆ getTriangle()

virtual void rr::RRMeshArrays::getTriangle ( unsigned  t,
Triangle out 
) const
overridevirtual

Writes t-th triangle in mesh to out.

Make sure you provide valid t in range <0..getNumTriangles()-1>. Implementators are allowed to expect valid t (performance reasons, may be called very often), so result is completely undefined for invalid t (possible crash).

Order of vertices in triangle has influence on what side of triangle is front, which is important for lighting. See more details in Front/back side.

Implements rr::RRMesh.

◆ getTriangleBody()

virtual void rr::RRMeshArrays::getTriangleBody ( unsigned  t,
TriangleBody out 
) const
overridevirtual

Writes t-th triangle in mesh to out.

Make sure you provide valid t in range <0..getNumTriangles()-1>. Implementators are allowed to expect valid t, so result is completely undefined for invalid t (possible crash).
There is default implementation, but if you know format of your data well, you may provide faster one.
Speed of this function is important for intersection tests performance.

Reimplemented from rr::RRMesh.

◆ getTriangleNormals()

virtual void rr::RRMeshArrays::getTriangleNormals ( unsigned  t,
TriangleNormals out 
) const
overridevirtual

Writes tangent bases in triangle vertices to out. Normals are part of bases.

Tangent bases are used by global illumination solver and renderer. Normals should point to front side hemisphere, see Front/back side.
Default implementation writes all vertex normals equal to triangle plane normal and constructs appropriate tangent space.

Parameters
tIndex of triangle. Valid t is in range <0..getNumTriangles()-1>.
outCaller provided storage for result. For valid t, requested normals are written to out. For invalid t, out stays unmodified.

Reimplemented from rr::RRMesh.

◆ getTriangleMapping()

virtual bool rr::RRMeshArrays::getTriangleMapping ( unsigned  t,
TriangleMapping out,
unsigned  channel 
) const
overridevirtual

Writes t-th triangle's uv mapping to out.

Parameters
tIndex of triangle. Valid t is in range <0..getNumTriangles()-1>.
outCaller provided storage for result. For valid t, requested mapping is written to out. For invalid t, out stays unmodified.
channelTexcoord channel to use, RRMaterial::diffuseReflectance.texcoord for diffuse texture mapping, RRMaterial::lightmap.texcoord for unwrap used by lightmaps etc.
Note that for proper lighting, unwrap must have all coordinates in <0..1> range and triangles must not overlap. Unwrap may be imported or automatically generated by RRObjects::buildUnwrap().
Returns
True for valid t and supported channel, result was written to out. False for invalid t or unsupported channel, out stays unmodified.

Reimplemented from rr::RRMesh.

◆ getUvChannels()

virtual void rr::RRMeshArrays::getUvChannels ( RRVector< unsigned > &  out) const
overridevirtual

Fills out with uv channels provided by mesh, in ascending order. Default implementation queries presence of channels 0 to 100, ignores higher channels.

Reimplemented from rr::RRMesh.

◆ getAABB()

virtual void rr::RRMeshArrays::getAABB ( RRVec3 mini,
RRVec3 maxi,
RRVec3 center 
) const
overridevirtual

Returns axis aligned bounding box and center of mesh. Fast (cached).

Parameters
mininullptr or pointer to vec3 to be filled with minimum of computed AABB.
maxinullptr or pointer to vec3 to be filled with maximum of computed AABB.
centernullptr or pointer to vec3 to be filled with average vertex position.

Reimplemented from rr::RRMesh.

◆ flipFrontBack()

unsigned rr::RRMeshArrays::flipFrontBack ( unsigned  numNormalsThatMustPointBack,
bool  negativeScale 
)

Flips front/back if at least this number of normals in triangle points to back side. So all triangles are flipped if numNormalsThatMustPointBack==0. Meaning of front and back is inverted when negativeScale.

Returns
Number of triangles flipped.

◆ buildNormals()

void rr::RRMeshArrays::buildNormals ( )

Builds new smooth vertex normals from angles between faces.

◆ buildTangents()

void rr::RRMeshArrays::buildTangents ( unsigned  uvChannel)

Builds new tangents and bitangents from normals.

Parameters
uvChannelIf such channel exists, tangents will point in u+ direction, bitangents in v+ direction. When building tangentspace for normal maps, pass uv channel used for mapping normal map.

◆ manipulateMapping()

unsigned rr::RRMeshArrays::manipulateMapping ( unsigned  sourceChannel,
const float *  matrix2x3,
unsigned  destinationChannel 
)

Manipulates mapping by 2x3 matrix.

Parameters
sourceChannelChannel data are taken from. If there is no such channel, function fails.
matrix2x3Matrix to transform data with. As this is the only function working with 2x3 matrix, we pass just pointer to 6 floats instead of creating new class. Uvs are transformed as in uv=RRVec2(u*matrix[0]+v*matrix[1]+matrix[2],u*matrix[3]+v*matrix[4]+matrix[5]); nullptr works as identity, i.e. no transformation.
destinationChannelChannel results are saved to. If there is no such channel, it is created.
Returns
Returns 1 on success, 0 on failure (mesh was not modified).

◆ rectangle()

static RRMeshArrays * rr::RRMeshArrays::rectangle ( )
static

◆ plane()

static RRMeshArrays * rr::RRMeshArrays::plane ( )
static

◆ box()

static RRMeshArrays * rr::RRMeshArrays::box ( )
static

◆ sphere()

static RRMeshArrays * rr::RRMeshArrays::sphere ( )
static

◆ cylinder()

static RRMeshArrays * rr::RRMeshArrays::cylinder ( )
static

Member Data Documentation

◆ numTriangles

unsigned rr::RRMeshArrays::numTriangles

◆ triangle

Triangle* rr::RRMeshArrays::triangle

32bit triangle list, may be nullptr only in completely empty mesh.

◆ numVertices

unsigned rr::RRMeshArrays::numVertices

◆ position

RRVec3* rr::RRMeshArrays::position

May be nullptr only in completely empty mesh.

◆ normal

RRVec3* rr::RRMeshArrays::normal

May be nullptr only in completely empty mesh.

◆ tangent

RRVec3* rr::RRMeshArrays::tangent

May be nullptr.

◆ bitangent

RRVec3* rr::RRMeshArrays::bitangent

May be nullptr.

◆ texcoord

RRVector<RRVec2*> rr::RRMeshArrays::texcoord

May contain mix of nullptr and non-nullptr channels, e.g. texcoord[5] array is missing but texcoord[6] array is present.

◆ version

unsigned rr::RRMeshArrays::version

Increase version each time you modify arrays, to let renderer know that data in GPU are outdated.

◆ unwrapChannel

unsigned rr::RRMeshArrays::unwrapChannel

Uv channel with unwrap, UINT_MAX=unknown or none. It is filled by buildUnwrap(), but it is currently not used, renderer and solver use RRMaterial::lightmap.texcoord instead.

◆ unwrapWidth

unsigned rr::RRMeshArrays::unwrapWidth

Optimal texture width when using unwrap from unwrapChannel, 0=unknown or none. It is filled by buildUnwrap().

◆ unwrapHeight

unsigned rr::RRMeshArrays::unwrapHeight

Optimal texture height when using unwrap from unwrapChannel, 0=unknown or none. It is filled by buildUnwrap().