5 #include <unordered_map>
32 using std::unordered_map;
55 ObjectNodeMesh::ObjectNodeMesh(
ObjectNodeRenderer* objectNodeRenderer,
Engine::AnimationProcessingTarget animationProcessingTarget,
Node* node,
const vector<unordered_map<string, Matrix4x4*>*>& transformMatrices,
const vector<unordered_map<string, Matrix4x4*>*>& skinningMatrices,
int instances)
78 for (
const auto& joint:
skinning->getJoints()) {
92 for (
auto j = 0; j < nodeVertices.size(); j++) {
102 for (
auto j = 0; j < nodeNormals.size(); j++) {
113 for (
auto j = 0; j < nodeTextureCoordinates.size(); j++) {
121 if (nodeTangents.size() > 0) {
127 for (
auto j = 0; j < nodeTangents.size(); j++) {
133 if (nodeBitangents.size() > 0) {
139 for (
auto j = 0; j < nodeBitangents.size(); j++) {
149 if (nodeTangents.size() > 0) {
152 if (nodeBitangents.size() > 0) {
158 auto indicesCount = 0;
160 indicesCount += 3 * facesEntity.getFaces().size();
167 for (
const auto& face: facesEntity.getFaces())
168 for (
auto vertexIndex: face.getVertexIndices()) {
169 indices[j++] = nodeVertices.size() * i + vertexIndex;
191 const auto& joints =
skinning->getJoints();
192 const auto& weights =
skinning->getWeights();
193 const auto& jointsWeights =
skinning->getVerticesJointsWeights();
194 for (
auto vertexIndex = 0; vertexIndex < nodeVertices.size(); vertexIndex++) {
195 auto vertexJointWeights = jointsWeights[vertexIndex].size();
200 auto jointWeightIdx = 0;
201 for (
const auto& jointWeight : jointsWeights[vertexIndex]) {
202 const auto& joint = joints[jointWeight.getJointIndex()];
209 auto jointWeightIdx = 0;
210 for (
const auto& jointWeight : jointsWeights[vertexIndex]) {
211 auto& joint = joints[jointWeight.getJointIndex()];
237 const auto& jointsWeights =
skinning->getVerticesJointsWeights();
247 float weightNormalized;
254 for (
auto vertexIndex = 0; vertexIndex < nodeVertices.size(); vertexIndex++) {
256 vertex = &nodeVertices[vertexIndex];
257 transformedVertex = &
transformedVertices[nodeVertices.size() * j + vertexIndex].set(0.0f, 0.0f, 0.0f);
258 normal = &nodeNormals[vertexIndex];
259 transformedNormal = &
transformedNormals[nodeVertices.size() * j + vertexIndex].set(0.0f, 0.0f, 0.0f);
260 tangent =
tangents !=
nullptr?&nodeTangent[vertexIndex]:
nullptr;
261 transformedTangent =
tangents !=
nullptr?&
transformedTangents[nodeVertices.size() * j + vertexIndex].set(0.0f, 0.0f, 0.0f):
nullptr;
262 bitangent =
bitangents !=
nullptr?&nodeBitangent[vertexIndex]:
nullptr;
266 for (
auto vertexJointWeightIdx = 0; vertexJointWeightIdx < jointsWeights[vertexIndex].size(); vertexJointWeightIdx++) {
269 if (skinningJointTransformMatrix ==
nullptr)
continue;
279 if (tangent !=
nullptr && transformedTangent !=
nullptr) {
283 if (bitangent !=
nullptr && transformedBitangent !=
nullptr) {
287 totalWeights += weight;
290 if (Math::abs(totalWeights - 1.0f) > Math::EPSILON) {
291 weightNormalized = 1.0f / totalWeights;
293 transformedVertex->
scale(weightNormalized);
295 transformedNormal->
scale(weightNormalized);
297 if (transformedTangent !=
nullptr) {
298 transformedTangent->
scale(weightNormalized);
301 if (transformedBitangent !=
nullptr) {
302 transformedBitangent->
scale(weightNormalized);
320 for (
auto vertexIndex = 0; vertexIndex < nodeVertices.size(); vertexIndex++) {
324 for (
auto normalIndex = 0; normalIndex < nodeNormals.size(); normalIndex++) {
353 "ObjectNodeMesh::setupVertexIndicesBuffer(): " +
356 "more than 2^16-1 indices: " +
364 sbIndices.
put(index);
373 ibIndices.
put(index);
388 fbTextureCoordinates.
put(textureCoordinate.getArray());
391 renderer->
uploadBufferObject(contextIdx, vboId, fbTextureCoordinates.getPosition() *
sizeof(
float), &fbTextureCoordinates);
398 for (
const auto& vertex: *
vertices) {
399 fbVertices.
put(vertex.getArray());
402 renderer->
uploadBufferObject(contextIdx, vboId, fbVertices.getPosition() *
sizeof(
float), &fbVertices);
409 for (
const auto& normal: *
normals) {
410 fbNormals.
put(normal.getArray());
413 renderer->
uploadBufferObject(contextIdx, vboId, fbNormals.getPosition() *
sizeof(
float), &fbNormals);
422 for (
const auto& tangent: *
tangents) {
423 fbTangents.
put(tangent.getArray());
426 renderer->
uploadBufferObject(contextIdx, vboId, fbTangents.getPosition() *
sizeof(
float), &fbTangents);
436 fbBitangents.
put(bitangent.getArray());
439 renderer->
uploadBufferObject(contextIdx, vboId, fbBitangents.getPosition() *
sizeof(
float), &fbBitangents);
445 if (origins.size() == 0)
return;
449 for (
const auto& origin: origins) {
450 fbOrigins.
put(origin.getArray());
453 renderer->
uploadBufferObject(contextIdx, vboId, fbOrigins.getPosition() *
sizeof(
float), &fbOrigins);
458 const vector<int32_t>*
indices {
nullptr };
465 "ObjectNodeMesh::setupLodBuffer(): " +
468 "no valid lod level: " + to_string(lodLevel)
472 if (
indices->empty() ==
true) {
474 "ObjectNodeMesh::setupLodBuffer(): " +
484 "ObjectNodeMesh::setupLodBuffer(): " +
487 "more than 2^16-1 indices: " +
494 for (
const auto index: *
indices) {
495 sbIndices.
put(index);
502 for (
const auto index: *
indices) {
503 ibIndices.
put(index);
AnimationProcessingTarget
static SkinningShader * getSkinningShader()
Represents a model face, consisting of vertex, normal, tangent and bitangent vectors,...
Node faces entity A node can have multiple entities containing faces and a applied material.
const vector< Vector3 > & getBitangents() const
int32_t getFaceCount() const
const vector< Vector3 > & getTangents() const
const vector< Vector3 > & getOrigins() const
const vector< Vector3 > & getVertices() const
const vector< Vector3 > & getNormals() const
const vector< Vector2 > & getTextureCoordinates() const
const string & getId()
Returns id.
const vector< FacesEntity > & getFacesEntities() const
Skinning definition for nodes.
virtual void uploadIndicesBufferObject(int contextIdx, int32_t bufferObjectId, int32_t size, ShortBuffer *data)=0
Uploads buffer data to buffer object.
virtual bool isUsingShortIndices()=0
virtual void uploadBufferObject(int contextIdx, int32_t bufferObjectId, int32_t size, FloatBuffer *data)=0
Uploads buffer data to buffer object.
vector< bool > instanceEnabled
void setCurrentInstance(int currentInstance)
Set current instance.
const Matrix4x4 & getTransformMatrix() const
Buffers used to transfer data between main memory to graphics board memory.
static ByteBuffer * getByteBuffer(int contextIdx, int32_t bytes)
Get byte buffer for given context.
Object node mesh specifically for rendering.
const vector< Vector2 > * textureCoordinates
void setupOriginsBuffer(Renderer *renderer, int contextIdx, int32_t vboId)
Set up render node object origins data buffer.
void setupNormalsBuffer(Renderer *renderer, int contextIdx, int32_t vboId)
Set up normals buffer.
vector< int32_t > indices
void setupVertexIndicesBuffer(Renderer *renderer, int contextIdx, int32_t vboId)
Set up vertex indices buffer.
const vector< Vector3 > * vertices
vector< Vector3 > transformedTangents
Engine::AnimationProcessingTarget animationProcessingTarget
void computeSkinning(int contextIdx, ObjectBase *objectBase)
Computes skinning.
vector< Vector3 > transformedVertices
void setupLodBuffer(Renderer *renderer, int contextIdx, int32_t vboId, int lodLevel)
Set up render node object lod data buffer.
void setupTextureCoordinatesBuffer(Renderer *renderer, int contextIdx, int32_t vboId)
Set up texture coordinates buffer.
const vector< Vector3 > * tangents
const vector< Vector3 > * normals
vector< vector< vector< Matrix4x4 * > > > skinningJointTransformMatrices
int skinningMaxVertexWeights
void recreateBuffers()
Recreates node float buffers.
void setupTangentsBuffer(Renderer *renderer, int contextIdx, int32_t vboId)
Set up tangents buffer.
Matrix4x4 * nodeTransformMatrix
vector< vector< float > > skinningJointWeight
bool getRecreatedBuffers()
void setupVerticesBuffer(Renderer *renderer, int contextIdx, int32_t vboId)
Set up vertices buffer.
vector< vector< Matrix4x4 * > > jointsSkinningMatrices
void setupBitangentsBuffer(Renderer *renderer, int contextIdx, int32_t vboId)
Set up bitangents buffer.
ObjectNodeRenderer * objectNodeRenderer
const vector< Vector3 > * bitangents
vector< Vector3 > transformedBitangents
vector< unordered_map< string, Matrix4x4 * > * > skinningMatrices
vector< Vector2 > transformedTextureCoordinates
vector< Vector3 > transformedNormals
Object node VBO renderer.
Interface to compute shader skinning shader program.
void computeSkinning(int contextIdx, ObjectBase *objectBase, ObjectNodeMesh *objectNodeMesh)
Compute skinning.
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Vector3 multiply(const Vector3 &vector3) const
Multiplies this matrix with vector3.
Matrix4x4 & set(float r0c0, float r0c1, float r0c2, float r0c3, float r1c0, float r1c1, float r1c2, float r1c3, float r2c0, float r2c1, float r2c2, float r2c3, float r3c0, float r3c1, float r3c2, float r3c3)
Sets this matrix by its components.
Vector3 multiplyNoTranslation(const Vector3 &vector3) const
Multiplies this matrix with vector3 while ignoring translation.
Vector2 class representing vector2 mathematical structure and operations with x, y components.
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Vector3 & add(float scalar)
Adds a scalar.
Vector3 & scale(float scalar)
Scales by scalar.
Vector3 & normalize()
Normalizes this vector3.
ShortBuffer asShortBuffer()
FloatBuffer asFloatBuffer()
FloatBuffer * put(float value)
Put a float value into float buffer.
IntBuffer * put(uint32_t value)
Puts a value into buffer at its current position.
ShortBuffer * put(uint16_t value)
Put a value into current position.