/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "obj-loader.h"
// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
#include <string>
#include <sstream>
#include <string.h>
namespace Internal
{
+namespace
+{
+ const int MAX_POINT_INDICES = 4;
+}
using namespace Dali;
ObjLoader::ObjLoader()
{
mSceneLoaded = false;
mMaterialLoaded = false;
+ mHasTexturePoints = false;
+ mHasDiffuseMap = false;
+ mHasNormalMap = false;
+ mHasSpecularMap = false;
mSceneAABB.Init();
}
return mMaterialLoaded;
}
-//TODO: Use a function that can generate more than one normal/tangent per vertex (using angle)
-void ObjLoader::CalculateTangentArray(const Dali::Vector<Vector3>& vertex,
- const Dali::Vector<Vector2>& texcoord,
- Dali::Vector<TriIndex>& triangle,
- Dali::Vector<Vector3>& normal,
- Dali::Vector<Vector3>& tangent)
+void ObjLoader::CalculateHardFaceNormals( const Dali::Vector<Vector3>& vertices, Dali::Vector<TriIndex>& triangles,
+ Dali::Vector<Vector3>& normals )
{
- normal.Clear();
- normal.Resize(vertex.Size());
-
- Vector3 *tan1 = new Vector3[vertex.Size() * 2];
+ int numFaceVertices = 3 * triangles.Size(); //Vertex per face, as each point has different normals for each face.
+ int normalIndex = 0; //Tracks progress through the array of normals.
- memset(tan1, 0, normal.Size() * sizeof(Vector3) * 2);
- memset(&normal[0], 0, normal.Size() * sizeof(Vector3) * 2);
+ normals.Clear();
+ normals.Resize( numFaceVertices );
- for (unsigned long a = 0; a < triangle.Size(); a++)
+ //For each triangle, calculate the normal by crossing two vectors on the triangle's plane.
+ for( unsigned long i = 0; i < triangles.Size(); i++ )
{
- Vector3 Tangent, Bitangent, Normal;
+ //Triangle vertices.
+ const Vector3& v0 = vertices[triangles[i].pointIndex[0]];
+ const Vector3& v1 = vertices[triangles[i].pointIndex[1]];
+ const Vector3& v2 = vertices[triangles[i].pointIndex[2]];
- const Vector3& v0 = vertex[triangle[a].pntIndex[0]];
- const Vector3& v1 = vertex[triangle[a].pntIndex[1]];
- const Vector3& v2 = vertex[triangle[a].pntIndex[2]];
+ //Triangle edges.
+ Vector3 edge1 = v1 - v0;
+ Vector3 edge2 = v2 - v0;
- Vector3 Edge1 = v1 - v0;
- Vector3 Edge2 = v2 - v0;
+ //Using edges as vectors on the plane, cross to get the normal.
+ Vector3 normalVector = edge1.Cross(edge2);
+ normalVector.Normalize();
- Normal = Edge1.Cross(Edge2);
+ //Assign normals to points.
+ for( unsigned long j = 0; j < 3; j++, normalIndex++ )
+ {
+ triangles[i].normalIndex[j] = normalIndex;
+ normals[normalIndex] = normalVector;
+ }
+ }
+}
- const Vector2& w0 = texcoord[triangle[a].texIndex[0]];
- const Vector2& w1 = texcoord[triangle[a].texIndex[1]];
- const Vector2& w2 = texcoord[triangle[a].texIndex[2]];
+void ObjLoader::CalculateSoftFaceNormals( const Dali::Vector<Vector3>& vertices, Dali::Vector<TriIndex>& triangles,
+ Dali::Vector<Vector3>& normals )
+{
+ int normalIndex = 0; //Tracks progress through the array of normals.
- float DeltaU1 = w1.x - w0.x;
- float DeltaV1 = w1.y - w0.y;
- float DeltaU2 = w2.x - w0.x;
- float DeltaV2 = w2.y - w0.y;
+ normals.Clear();
+ normals.Resize( vertices.Size() ); //One (averaged) normal per point.
- float f = 1.0f / (DeltaU1 * DeltaV2 - DeltaU2 * DeltaV1);
+ //For each triangle, calculate the normal by crossing two vectors on the triangle's plane
+ //We then add the triangle's normal to the cumulative normals at each point of it
+ for( unsigned long i = 0; i < triangles.Size(); i++ )
+ {
+ //Triangle vertices.
+ const Vector3& v0 = vertices[triangles[i].pointIndex[0]];
+ const Vector3& v1 = vertices[triangles[i].pointIndex[1]];
+ const Vector3& v2 = vertices[triangles[i].pointIndex[2]];
- Tangent.x = f * (DeltaV2 * Edge1.x - DeltaV1 * Edge2.x);
- Tangent.y = f * (DeltaV2 * Edge1.y - DeltaV1 * Edge2.y);
- Tangent.z = f * (DeltaV2 * Edge1.z - DeltaV1 * Edge2.z);
+ //Triangle edges.
+ Vector3 edge1 = v1 - v0;
+ Vector3 edge2 = v2 - v0;
- tan1[triangle[a].pntIndex[0]] += Tangent;
- tan1[triangle[a].pntIndex[1]] += Tangent;
- tan1[triangle[a].pntIndex[2]] += Tangent;
+ //Using edges as vectors on the plane, cross to get the normal.
+ Vector3 normalVector = edge1.Cross(edge2);
- normal[triangle[a].pntIndex[0]] += Normal;
- normal[triangle[a].pntIndex[1]] += Normal;
- normal[triangle[a].pntIndex[2]] += Normal;
+ //Add this triangle's normal to the cumulative normal of each constituent point and set the index of the normal accordingly.
+ for( unsigned long j = 0; j < 3; j++, normalIndex++ )
+ {
+ triangles[i].normalIndex[j] = triangles[i].pointIndex[j]; //Normal index matches up to vertex index, as one normal per vertex.
+ normals[triangles[i].normalIndex[j]] += normalVector;
+ }
}
- for (unsigned long a = 0; a < triangle.Size(); a++)
+ //Normalise the normals.
+ for( unsigned long i = 0; i < normals.Size(); i++ )
{
- for (unsigned long j = 0; j < 3; j++)
- {
- triangle[a].nrmIndex[j] = triangle[a].pntIndex[j];
- }
+ normals[i].Normalize();
}
+}
+
+//TODO: Use a function that can generate more than one normal/tangent per vertex (using angle)
+void ObjLoader::CalculateTangentFrame()
+{
+ //Reset tangent and bitangent vectors to hold new values.
+ mTangents.Clear();
+ mBiTangents.Clear();
+ mTangents.Resize( mPoints.Size() );
+ mBiTangents.Resize( mPoints.Size() );
- for (unsigned long a = 0; a < normal.Size(); a++)
+ //For each triangle, calculate the tangent vector and then add it to the total tangent vector of each point.
+ for ( unsigned long a = 0; a < mTriangles.Size(); a++ )
{
- normal[a].Normalize();
+ Vector3 tangentVector;
- const Vector3& n = normal[a];
- const Vector3& t = tan1[a];
+ const Vector3& v0 = mPoints[mTriangles[a].pointIndex[0]];
+ const Vector3& v1 = mPoints[mTriangles[a].pointIndex[1]];
+ const Vector3& v2 = mPoints[mTriangles[a].pointIndex[2]];
- // Gram-Schmidt orthogonalize
- Vector3 calc = t - n * n.Dot(t);
- calc.Normalize();
- tangent[a] = Vector3(calc.x,calc.y,calc.z);
+ Vector3 edge1 = v1 - v0;
+ Vector3 edge2 = v2 - v0;
+
+ const Vector2& w0 = mTextures[mTriangles[a].textureIndex[0]];
+ const Vector2& w1 = mTextures[mTriangles[a].textureIndex[1]];
+ const Vector2& w2 = mTextures[mTriangles[a].textureIndex[2]];
+
+ float deltaU1 = w1.x - w0.x;
+ float deltaV1 = w1.y - w0.y;
+ float deltaU2 = w2.x - w0.x;
+ float deltaV2 = w2.y - w0.y;
+
+ float f = 1.0f / (deltaU1 * deltaV2 - deltaU2 * deltaV1);
+
+ tangentVector.x = f * ( deltaV2 * edge1.x - deltaV1 * edge2.x );
+ tangentVector.y = f * ( deltaV2 * edge1.y - deltaV1 * edge2.y );
+ tangentVector.z = f * ( deltaV2 * edge1.z - deltaV1 * edge2.z );
+
+ mTangents[mTriangles[a].pointIndex[0]] += tangentVector;
+ mTangents[mTriangles[a].pointIndex[1]] += tangentVector;
+ mTangents[mTriangles[a].pointIndex[2]] += tangentVector;
}
- delete[] tan1;
-}
+ //Orthogonalize tangents and set binormals.
+ for ( unsigned long a = 0; a < mTangents.Size(); a++ )
+ {
+ const Vector3& n = mNormals[a];
+ const Vector3& t = mTangents[a];
+ // Gram-Schmidt orthogonalize
+ mTangents[a] = t - n * n.Dot(t);
+ mTangents[a].Normalize();
+
+ mBiTangents[a] = mNormals[a].Cross( mTangents[a] );
+ }
+}
-void ObjLoader::CenterAndScale(bool center, Dali::Vector<Vector3>& points)
+void ObjLoader::CenterAndScale( bool center, Dali::Vector<Vector3>& points )
{
BoundingVolume newAABB;
biggestDimension = sceneSize.z;
}
-
newAABB.Init();
- for( unsigned int ui = 0; ui < points.Size(); ++ui)
+ for( unsigned int ui = 0; ui < points.Size(); ++ui )
{
points[ui] = points[ui] - GetCenter();
points[ui] = points[ui] / biggestDimension;
mSceneAABB = newAABB;
}
-void ObjLoader::CreateGeometryArray(Dali::Vector<Vertex> & vertices,
- Dali::Vector<Vector2> & textures,
- Dali::Vector<VertexExt> & verticesExt,
- Dali::Vector<int> & indices)
+void ObjLoader::CreateGeometryArray( Dali::Vector<Vertex> & vertices,
+ Dali::Vector<Vector2> & textures,
+ Dali::Vector<VertexExt> & verticesExt,
+ Dali::Vector<unsigned short> & indices,
+ bool useSoftNormals )
{
- //If we don't have tangents, calculate them
- //we need to recalculate the normals too, because we need just one normal,tangent, bitangent per vertex
- //TODO: Use a better function to calculate tangents
- if( mTangents.Size() == 0 )
+ //We must calculate the tangents and bitangents if they weren't supplied, or if they don't match up.
+ bool mustCalculateTangents = mTangents.Size() == 0 || mBiTangents.Size() == 0 ||
+ mTangents.Size() != mBiTangents.Size() || mTangents.Size() != mNormals.Size() ||
+ mBiTangents.Size() != mNormals.Size();
+
+ //However, we don't need to do this if the object doesn't use textures to begin with.
+ mustCalculateTangents &= mHasTexturePoints;
+
+ //We also have to recalculate the normals if we need to calculate tangents,
+ // as we need just one normal, tangent and bitangent per vertex, rather than the supplied per-face vertices.
+ //Alternatively, we need to calculate the normals if there weren't any to begin with.
+ if( mNormals.Size() == 0 || mustCalculateTangents )
{
- mTangents.Resize(mNormals.Size());
- mBiTangents.Resize(mNormals.Size());
- CalculateTangentArray(mPoints, mTextures, mTriangles, mNormals, mTangents);
- for (unsigned int ui = 0 ; ui < mNormals.Size() ; ++ui )
+ if( useSoftNormals || mustCalculateTangents )
+ {
+ CalculateSoftFaceNormals( mPoints, mTriangles, mNormals );
+ }
+ else
{
- mBiTangents[ui] = mNormals[ui].Cross(mTangents[ui]);
+ CalculateHardFaceNormals( mPoints, mTriangles, mNormals );
}
}
+ //TODO: Use a better function to calculate tangents
+ if( mHasTexturePoints && mustCalculateTangents )
+ {
+ CalculateTangentFrame();
+ }
+
+ bool mapsCorrespond; //True if the sizes of the arrays necessary for the object agree.
+
+ if ( mHasTexturePoints )
+ {
+ mapsCorrespond = ( mPoints.Size() == mTextures.Size() ) && ( mTextures.Size() == mNormals.Size() );
+ }
+ else
+ {
+ mapsCorrespond = ( mPoints.Size() == mNormals.Size() );
+ }
+
//Check the number of points textures and normals
- if ((mPoints.Size() == mTextures.Size()) && (mTextures.Size() == mNormals.Size()))
+ if ( mapsCorrespond )
{
+ int numPoints = mPoints.Size();
+ int numIndices = 3 * mTriangles.Size();
+ vertices.Resize( numPoints );
+ textures.Resize( numPoints );
+ verticesExt.Resize( numPoints );
+ indices.Resize( numIndices );
+
//We create the vertices array. For now we just copy points info
for (unsigned int ui = 0 ; ui < mPoints.Size() ; ++ui )
{
Vertex vertex;
vertex.position = mPoints[ui];
- vertices.PushBack(vertex);
+ vertices[ui] = vertex;
- textures.PushBack(Vector2());
- verticesExt.PushBack(VertexExt());
+ if ( mHasTexturePoints )
+ {
+ textures[ui] = Vector2();
+ verticesExt[ui] = VertexExt();
+ }
}
+ int indiceIndex = 0;
+
//We copy the indices
- for (unsigned int ui = 0 ; ui < mTriangles.Size() ; ++ui )
+ for ( unsigned int ui = 0 ; ui < mTriangles.Size() ; ++ui )
{
- for (int j = 0 ; j < 3 ; ++j)
+ for ( int j = 0 ; j < 3 ; ++j )
{
- indices.PushBack(mTriangles[ui].pntIndex[j]);
+ indices[indiceIndex] = mTriangles[ui].pointIndex[j];
+ indiceIndex++;
- vertices[mTriangles[ui].pntIndex[j]].normal = mNormals[mTriangles[ui].nrmIndex[j]];
+ vertices[mTriangles[ui].pointIndex[j]].normal = mNormals[mTriangles[ui].normalIndex[j]];
- textures[mTriangles[ui].pntIndex[j]] = mTextures[mTriangles[ui].texIndex[j]];
-
- verticesExt[mTriangles[ui].pntIndex[j]].tangent = mTangents[mTriangles[ui].nrmIndex[j]];
- verticesExt[mTriangles[ui].pntIndex[j]].bitangent = mBiTangents[mTriangles[ui].nrmIndex[j]];
+ if ( mHasTexturePoints )
+ {
+ textures[mTriangles[ui].pointIndex[j]] = mTextures[mTriangles[ui].textureIndex[j]];
+ verticesExt[mTriangles[ui].pointIndex[j]].tangent = mTangents[mTriangles[ui].normalIndex[j]];
+ verticesExt[mTriangles[ui].pointIndex[j]].bitangent = mBiTangents[mTriangles[ui].normalIndex[j]];
+ }
}
}
}
else
{
+ int numVertices = 3 * mTriangles.Size();
+ vertices.Resize( numVertices );
+ textures.Resize( numVertices );
+ verticesExt.Resize( numVertices );
+
+ int index = 0;
+
//We have to normalize the arrays so we can draw we just one index array
- for (unsigned int ui = 0 ; ui < mTriangles.Size() ; ++ui )
+ for ( unsigned int ui = 0 ; ui < mTriangles.Size() ; ++ui )
{
- for (int j = 0 ; j < 3 ; ++j)
+ for ( int j = 0 ; j < 3 ; ++j )
{
Vertex vertex;
- vertex.position = mPoints[mTriangles[ui].pntIndex[j]];
- vertex.normal = mNormals[mTriangles[ui].nrmIndex[j]];
- vertices.PushBack(vertex);
+ vertex.position = mPoints[mTriangles[ui].pointIndex[j]];
+ vertex.normal = mNormals[mTriangles[ui].normalIndex[j]];
+ vertices[index] = vertex;
- textures.PushBack(mTextures[mTriangles[ui].texIndex[j]]);
+ if ( mHasTexturePoints )
+ {
+ textures[index] = mTextures[mTriangles[ui].textureIndex[j]];
+ VertexExt vertexExt;
+ vertexExt.tangent = mTangents[mTriangles[ui].normalIndex[j]];
+ vertexExt.bitangent = mBiTangents[mTriangles[ui].normalIndex[j]];
+ verticesExt[index] = vertexExt;
+ }
- VertexExt vertexExt;
- vertexExt.tangent = mTangents[mTriangles[ui].nrmIndex[j]];
- vertexExt.bitangent = mBiTangents[mTriangles[ui].nrmIndex[j]];
- verticesExt.PushBack(vertexExt);
+ index++;
}
}
}
}
-bool ObjLoader::Load(char* objBuffer, std::streampos fileSize, std::string& materialFile)
+bool ObjLoader::LoadObject( char* objBuffer, std::streampos fileSize )
{
Vector3 point;
Vector2 texture;
- std::string vet[4], name;
- int ptIdx[4];
- int nrmIdx[4];
- int texIdx[4];
+ std::string vet[MAX_POINT_INDICES], name;
+ int ptIdx[MAX_POINT_INDICES];
+ int nrmIdx[MAX_POINT_INDICES];
+ int texIdx[MAX_POINT_INDICES];
TriIndex triangle,triangle2;
int pntAcum = 0, texAcum = 0, nrmAcum = 0;
bool iniObj = false;
+ bool hasTexture = false;
int face = 0;
//Init AABB for the file
std::string strMatActual;
- std::string input = objBuffer;
+ std::string input( objBuffer, fileSize );
std::istringstream ss(input);
- ss.imbue(std::locale("C"));
+ ss.imbue( std::locale( "C" ) );
std::string line;
- std::getline(ss, line);
+ std::getline( ss, line );
- while (std::getline(ss, line))
+ while ( std::getline( ss, line ) )
{
- std::istringstream isline(line, std::istringstream::in);
+ std::istringstream isline( line, std::istringstream::in );
std::string tag;
isline >> tag;
- if (tag == "v")
+ if ( tag == "v" )
{
//Two different objects in the same file
isline >> point.x;
isline >> point.y;
isline >> point.z;
- mPoints.PushBack(point);
+ mPoints.PushBack( point );
- mSceneAABB.ConsiderNewPointInVolume(point);
+ mSceneAABB.ConsiderNewPointInVolume( point );
}
- else if (tag == "vn")
+ else if ( tag == "vn" )
{
isline >> point.x;
isline >> point.y;
isline >> point.z;
- mNormals.PushBack(point);
+ mNormals.PushBack( point );
}
- else if (tag == "#_#tangent")
+ else if ( tag == "#_#tangent" )
{
isline >> point.x;
isline >> point.y;
isline >> point.z;
- mTangents.PushBack(point);
+ mTangents.PushBack( point );
}
- else if (tag == "#_#binormal")
+ else if ( tag == "#_#binormal" )
{
isline >> point.x;
isline >> point.y;
isline >> point.z;
- mBiTangents.PushBack(point);
+ mBiTangents.PushBack( point );
}
- else if (tag == "vt")
+ else if ( tag == "vt" )
{
isline >> texture.x;
isline >> texture.y;
texture.y = 1.0-texture.y;
- mTextures.PushBack(texture);
+ mTextures.PushBack( texture );
}
- else if (tag == "#_#vt1")
+ else if ( tag == "#_#vt1" )
{
isline >> texture.x;
isline >> texture.y;
texture.y = 1.0-texture.y;
- mTextures2.PushBack(texture);
+ mTextures2.PushBack( texture );
}
- else if (tag == "s")
+ else if ( tag == "s" )
{
}
- else if (tag == "f")
+ else if ( tag == "f" )
{
- if (!iniObj)
+ if ( !iniObj )
{
//name assign
}
int numIndices = 0;
- while( isline >> vet[numIndices] )
+ while( ( numIndices < MAX_POINT_INDICES ) && ( isline >> vet[numIndices] ) )
{
numIndices++;
}
+ //Hold slashes that separate attributes of the same point.
char separator;
char separator2;
- //File could not have texture Coordinates
- if (strstr(vet[0].c_str(),"//"))
+
+ const char * subString; //A pointer to the position in the string as we move through it.
+
+ subString = strstr( vet[0].c_str(),"/" ); //Search for the first '/'
+
+ if( subString )
{
- for( int i = 0 ; i < numIndices; i++)
+ if( subString[1] == '/' ) // Of the form A//C, so has points and normals but no texture coordinates.
{
- std::istringstream isindex(vet[i]);
- isindex >> ptIdx[i] >> separator >> nrmIdx[i];
- texIdx[i] = 0;
+ for( int i = 0 ; i < numIndices; i++)
+ {
+ std::istringstream isindex( vet[i] );
+ isindex >> ptIdx[i] >> separator >> separator2 >> nrmIdx[i];
+ texIdx[i] = 0;
+ }
}
- }
- else if (strstr(vet[0].c_str(),"/"))
- {
- for( int i = 0 ; i < numIndices; i++)
+ else if( strstr( subString, "/" ) ) // Of the form A/B/C, so has points, textures and normals.
+ {
+ for( int i = 0 ; i < numIndices; i++ )
+ {
+ std::istringstream isindex( vet[i] );
+ isindex >> ptIdx[i] >> separator >> texIdx[i] >> separator2 >> nrmIdx[i];
+ }
+
+ hasTexture = true;
+ }
+ else // Of the form A/B, so has points and textures but no normals.
{
- std::istringstream isindex(vet[i]);
- isindex >> ptIdx[i] >> separator >> texIdx[i] >> separator2 >> nrmIdx[i];
+ for( int i = 0 ; i < numIndices; i++ )
+ {
+ std::istringstream isindex( vet[i] );
+ isindex >> ptIdx[i] >> separator >> texIdx[i];
+ nrmIdx[i] = 0;
+ }
+
+ hasTexture = true;
}
}
- else
+ else // Simply of the form A, as in, point indices only.
{
- for( int i = 0 ; i < numIndices; i++)
+ for( int i = 0 ; i < numIndices; i++ )
{
- std::istringstream isindex(vet[i]);
+ std::istringstream isindex( vet[i] );
isindex >> ptIdx[i];
texIdx[i] = 0;
nrmIdx[i] = 0;
//If it is a triangle
if( numIndices == 3 )
{
- for( int i = 0 ; i < 3; i++)
+ for( int i = 0 ; i < 3; i++ )
{
- triangle.pntIndex[i] = ptIdx[i] - 1 - pntAcum;
- triangle.nrmIndex[i] = nrmIdx[i] - 1 - nrmAcum;
- triangle.texIndex[i] = texIdx[i] - 1 - texAcum;
+ triangle.pointIndex[i] = ptIdx[i] - 1 - pntAcum;
+ triangle.normalIndex[i] = nrmIdx[i] - 1 - nrmAcum;
+ triangle.textureIndex[i] = texIdx[i] - 1 - texAcum;
}
- mTriangles.PushBack(triangle);
+ mTriangles.PushBack( triangle );
face++;
}
//If on the other hand it is a quad, we will create two triangles
else if( numIndices == 4 )
{
- for( int i = 0 ; i < 3; i++)
+ for( int i = 0 ; i < 3; i++ )
{
- triangle.pntIndex[i] = ptIdx[i] - 1 - pntAcum;
- triangle.nrmIndex[i] = nrmIdx[i] - 1 - nrmAcum;
- triangle.texIndex[i] = texIdx[i] - 1 - texAcum;
+ triangle.pointIndex[i] = ptIdx[i] - 1 - pntAcum;
+ triangle.normalIndex[i] = nrmIdx[i] - 1 - nrmAcum;
+ triangle.textureIndex[i] = texIdx[i] - 1 - texAcum;
}
- mTriangles.PushBack(triangle);
+ mTriangles.PushBack( triangle );
face++;
- for( int i = 0 ; i < 3; i++)
+ for( int i = 0 ; i < 3; i++ )
{
- int idx = (i+2) % numIndices;
- triangle2.pntIndex[i] = ptIdx[idx] - 1 - pntAcum;
- triangle2.nrmIndex[i] = nrmIdx[idx] - 1 - nrmAcum;
- triangle2.texIndex[i] = texIdx[idx] - 1 - texAcum;
+ int idx = ( i + 2 ) % numIndices;
+ triangle2.pointIndex[i] = ptIdx[idx] - 1 - pntAcum;
+ triangle2.normalIndex[i] = nrmIdx[idx] - 1 - nrmAcum;
+ triangle2.textureIndex[i] = texIdx[idx] - 1 - texAcum;
}
- mTriangles.PushBack(triangle2);
+ mTriangles.PushBack( triangle2 );
face++;
}
}
- else if (tag == "usemtl")
+ else if ( tag == "usemtl" )
{
isline >> strMatActual;
}
- else if (tag == "mtllib")
+ else if ( tag == "mtllib" )
{
isline >> strMatActual;
}
- else if (tag == "g")
+ else if ( tag == "g" )
{
isline >> name;
}
- else
- {
- }
}
- if (iniObj)
+ if ( iniObj )
{
- pntAcum += (int)mPoints.Size();
- texAcum += (int)mTextures.Size();
- nrmAcum += (int)mNormals.Size();
-
- CenterAndScale(true, mPoints);
-
- face = 0;
-
+ CenterAndScale( true, mPoints );
mSceneLoaded = true;
-
+ mHasTexturePoints = hasTexture;
return true;
}
return false;
-
}
-void ObjLoader::LoadMaterial(char* objBuffer, std::streampos fileSize, std::string& texture0Url, std::string& texture1Url, std::string& texture2Url)
+void ObjLoader::LoadMaterial( char* objBuffer, std::streampos fileSize, std::string& diffuseTextureUrl,
+ std::string& normalTextureUrl, std::string& glossTextureUrl )
{
float fR,fG,fB;
std::string info;
- std::string input = objBuffer;
+ std::string input( objBuffer, fileSize );
std::istringstream ss(input);
ss.imbue(std::locale("C"));
std::string line;
- std::getline(ss, line);
+ std::getline( ss, line );
- while (std::getline(ss, line))
+ while ( std::getline( ss, line ) )
{
- std::istringstream isline(line, std::istringstream::in);
+ std::istringstream isline( line, std::istringstream::in );
std::string tag;
isline >> tag;
- if (tag == "newmtl") //name of the material
+ if ( tag == "newmtl" ) //name of the material
{
isline >> info;
}
- else if (tag == "Kd") //diffuse color
+ else if ( tag == "Ka" ) //ambient color
+ {
+ isline >> fR >> fG >> fB;
+ }
+ else if ( tag == "Kd" ) //diffuse color
{
isline >> fR >> fG >> fB;
}
- else if (tag == "Kd") //Ambient color
+ else if ( tag == "Ks" ) //specular color
{
isline >> fR >> fG >> fB;
}
- else if (tag == "Tf") //color
+ else if ( tag == "Tf" ) //color
{
}
- else if (tag == "Ni")
+ else if ( tag == "Ni" )
{
}
- else if (tag == "map_Kd")
+ else if ( tag == "map_Kd" )
{
isline >> info;
- texture0Url = info;
+ diffuseTextureUrl = info;
+ mHasDiffuseMap = true;
}
- else if (tag == "bump")
+ else if ( tag == "bump" )
{
isline >> info;
- texture1Url = info;
+ normalTextureUrl = info;
+ mHasNormalMap = true;
}
- else if (tag == "map_Ks")
+ else if ( tag == "map_Ks" )
{
isline >> info;
- texture2Url = info;
+ glossTextureUrl = info;
+ mHasSpecularMap = true;
}
}
mMaterialLoaded = true;
}
-Geometry ObjLoader::CreateGeometry(Toolkit::Model3dView::IlluminationType illuminationType)
+Geometry ObjLoader::CreateGeometry( int objectProperties, bool useSoftNormals )
{
+ Geometry surface = Geometry::New();
+
Dali::Vector<Vertex> vertices;
Dali::Vector<Vector2> textures;
Dali::Vector<VertexExt> verticesExt;
- Dali::Vector<int> indices;
+ Dali::Vector<unsigned short> indices;
- CreateGeometryArray(vertices, textures, verticesExt, indices);
+ CreateGeometryArray( vertices, textures, verticesExt, indices, useSoftNormals );
//All vertices need at least Position and Normal
Property::Map vertexFormat;
vertexFormat["aPosition"] = Property::VECTOR3;
vertexFormat["aNormal"] = Property::VECTOR3;
- PropertyBuffer surfaceVertices = PropertyBuffer::New( vertexFormat, vertices.Size() );
- surfaceVertices.SetData( &vertices[0] );
-
- Geometry surface = Geometry::New();
+ VertexBuffer surfaceVertices = VertexBuffer::New( vertexFormat );
+ surfaceVertices.SetData( &vertices[0], vertices.Size() );
surface.AddVertexBuffer( surfaceVertices );
//Some need texture coordinates
- if( (illuminationType == Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP ) || (illuminationType == Toolkit::Model3dView::DIFFUSE_WITH_TEXTURE ) )
+ if( ( objectProperties & TEXTURE_COORDINATES ) && mHasTexturePoints && mHasDiffuseMap )
{
Property::Map textureFormat;
textureFormat["aTexCoord"] = Property::VECTOR2;
- PropertyBuffer extraVertices = PropertyBuffer::New( textureFormat, textures.Size() );
- extraVertices.SetData( &textures[0] );
+ VertexBuffer extraVertices = VertexBuffer::New( textureFormat );
+ extraVertices.SetData( &textures[0], textures.Size() );
surface.AddVertexBuffer( extraVertices );
}
//Some need tangent and bitangent
- if( illuminationType == Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP )
+ if( ( objectProperties & TANGENTS ) && ( objectProperties & BINORMALS ) && mHasTexturePoints )
{
Property::Map vertexExtFormat;
vertexExtFormat["aTangent"] = Property::VECTOR3;
vertexExtFormat["aBiNormal"] = Property::VECTOR3;
- PropertyBuffer extraVertices = PropertyBuffer::New( vertexExtFormat, verticesExt.Size() );
- extraVertices.SetData( &verticesExt[0] );
+ VertexBuffer extraVertices = VertexBuffer::New( vertexExtFormat );
+ extraVertices.SetData( &verticesExt[0], verticesExt.Size() );
surface.AddVertexBuffer( extraVertices );
}
- if (indices.Size())
+ //If indices are required, we set them.
+ if ( indices.Size() )
{
- //Indices
- Property::Map indicesVertexFormat;
- indicesVertexFormat["aIndices"] = Property::INTEGER;
- PropertyBuffer indicesToVertices = PropertyBuffer::New( indicesVertexFormat, indices.Size() );
- indicesToVertices.SetData(&indices[0]);
-
- surface.SetIndexBuffer ( indicesToVertices );
+ surface.SetIndexBuffer ( &indices[0], indices.Size() );
}
- surface.SetRequiresDepthTesting(true);
-
- vertices.Clear();
- verticesExt.Clear();
- indices.Clear();
-
return surface;
}
mSceneLoaded = false;
}
+bool ObjLoader::IsTexturePresent()
+{
+ return mHasTexturePoints;
+}
+
+bool ObjLoader::IsDiffuseMapPresent()
+{
+ return mHasDiffuseMap;
+}
+
+bool ObjLoader::IsNormalMapPresent()
+{
+ return mHasNormalMap;
+}
+
+bool ObjLoader::IsSpecularMapPresent()
+{
+ return mHasSpecularMap;
+}
+
} // namespace Internal
} // namespace Toolkit
} // namespace Dali