Skip to content

Commit

Permalink
First pass on #155
Browse files Browse the repository at this point in the history
added normal map import + shader generation support when combined with point lights.
Full supporting coming next.
  • Loading branch information
fabrobinet committed Jun 6, 2014
1 parent da85c74 commit 0686784
Show file tree
Hide file tree
Showing 13 changed files with 379 additions and 192 deletions.
2 changes: 2 additions & 0 deletions converter/COLLADA2GLTF/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ set(GLTF_SOURCES
GLTF/GLTFAccessor.cpp
GLTF/GLTFBuffer.cpp
GLTF/GLTFEffect.cpp
GLTF/GLTFExtras.cpp
GLTF/GLTFMesh.cpp
GLTF/GLTFPrimitive.cpp
GLTF/GLTFUtils.cpp
Expand All @@ -114,6 +115,7 @@ set(GLTF_SOURCES
GLTF/GLTFAccessor.h
GLTF/GLTFBuffer.h
GLTF/GLTFEffect.h
GLTF/GLTFExtras.h
GLTF/GLTFMesh.h
GLTF/GLTFPrimitive.h
GLTF/GLTFUtils.h
Expand Down
104 changes: 69 additions & 35 deletions converter/COLLADA2GLTF/COLLADA2GLTFWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,53 @@ namespace GLTF
return samplerUID;
}


void COLLADA2GLTFWriter::_installTextureSlot(Sampler* sampler,
const std::string& slotName,
const std::string& texcoord,
shared_ptr <GLTFAsset> asset,
shared_ptr<GLTFEffect> cvtEffect)
{
assert(sampler);
assert(asset);
assert(cvtEffect);
shared_ptr <JSONObject> values = cvtEffect->getValues();
std::string originalImageUID = asset->getOriginalId(sampler->getSourceImage().toAscii());
GLTFProfile* profile = asset->profile().get();

cvtEffect->addSemanticForTexcoordName(texcoord, slotName);
shared_ptr <JSONObject> slotObject(new JSONObject());

//do we need to export a new texture ? if yes compose a new unique ID
slotObject->setUnsignedInt32("type", profile->getGLenumForString("SAMPLER_2D"));

//do we need a new sampler ?
std::string samplerUID = this->getSamplerUIDForParameters(__GetGLWrapMode(sampler->getWrapS(), profile),
__GetGLWrapMode(sampler->getWrapT(), profile),
__GetFilterMode(sampler->getMinFilter(), profile),
__GetFilterMode(sampler->getMagFilter(), profile));

std::string textureUID = "texture_" + originalImageUID;
shared_ptr <GLTF::JSONObject> textures = asset->root()->createObjectIfNeeded("textures");
if (textures->contains(textureUID) == false) {
shared_ptr <JSONObject> textureObject(new JSONObject());
textureObject->setString(kSource, originalImageUID);
textureObject->setString("sampler", samplerUID);
textureObject->setUnsignedInt32("format", profile->getGLenumForString("RGBA"));

if (CONFIG_BOOL(asset, "exportDefaultValues")) {
textureObject->setUnsignedInt32("internalFormat", profile->getGLenumForString("RGBA"));
//UNSIGNED_BYTE is default https://github.com/KhronosGroup/glTF/issues/195
textureObject->setUnsignedInt32("type", profile->getGLenumForString("UNSIGNED_BYTE"));
}
textureObject->setUnsignedInt32(kTarget, profile->getGLenumForString("TEXTURE_2D"));
textures->setValue(textureUID, textureObject);
}

slotObject->setString("value", textureUID);
values->setValue(slotName, slotObject);
}

void COLLADA2GLTFWriter::handleEffectSlot(const COLLADAFW::EffectCommon* commonProfile,
std::string slotName,
shared_ptr <GLTFEffect> cvtEffect,
Expand Down Expand Up @@ -708,7 +755,26 @@ namespace GLTF
slot = commonProfile->getSpecular();
else if (slotName == "reflective")
slot = commonProfile->getReflective();
else
else if (slotName == "bump") {
//here we handle an extras slot
//for other extras, this will need refactoring
if (extras->contains("textures")) {
shared_ptr <JSONObject> textures = extras->getObject("textures");
if (textures->contains("bump")) {
shared_ptr <JSONObject> bump = textures->getObject("bump");

std::string texture = bump->getString("texture");
std::string texcoord = bump->getString("texcoord");
const SamplerPointerArray& samplers = commonProfile->getSamplerPointerArray();
for (size_t i = 0 ; i < samplers.getCount() ; i++) {
if (samplers[i]->getSid() == texture) {
Sampler* sampler = (Sampler*)samplers[i];
_installTextureSlot(sampler, slotName, texcoord, this->_asset, cvtEffect);
}
}
}
}
} else
return;

//retrieve the type, parameterName -> symbol -> type
Expand All @@ -730,41 +796,8 @@ namespace GLTF
const Texture& texture = slot.getTexture();
const SamplerPointerArray& samplers = commonProfile->getSamplerPointerArray();
Sampler* sampler = (Sampler*)samplers[texture.getSamplerId()];
std::string originalImageUID = this->_asset->getOriginalId(sampler->getSourceImage().toAscii());

std::string texcoord = texture.getTexcoord();

cvtEffect->addSemanticForTexcoordName(texcoord, slotName);
shared_ptr <JSONObject> slotObject(new JSONObject());

//do we need to export a new texture ? if yes compose a new unique ID
slotObject->setUnsignedInt32("type", profile->getGLenumForString("SAMPLER_2D"));

//do we need a new sampler ?
std::string samplerUID = this->getSamplerUIDForParameters(__GetGLWrapMode(sampler->getWrapS(), profile),
__GetGLWrapMode(sampler->getWrapT(), profile),
__GetFilterMode(sampler->getMinFilter(), profile),
__GetFilterMode(sampler->getMagFilter(), profile));

std::string textureUID = "texture_" + originalImageUID;
shared_ptr <GLTF::JSONObject> textures = asset->root()->createObjectIfNeeded("textures");
if (textures->contains(textureUID) == false) {
shared_ptr <JSONObject> textureObject(new JSONObject());
textureObject->setString(kSource, originalImageUID);
textureObject->setString("sampler", samplerUID);
textureObject->setUnsignedInt32("format", profile->getGLenumForString("RGBA"));

if (CONFIG_BOOL(asset, "exportDefaultValues")) {
textureObject->setUnsignedInt32("internalFormat", profile->getGLenumForString("RGBA"));
//UNSIGNED_BYTE is default https://github.com/KhronosGroup/glTF/issues/195
textureObject->setUnsignedInt32("type", profile->getGLenumForString("UNSIGNED_BYTE"));
}
textureObject->setUnsignedInt32(kTarget, profile->getGLenumForString("TEXTURE_2D"));
textures->setValue(textureUID, textureObject);
}

slotObject->setString("value", textureUID);
values->setValue(slotName, slotObject);
_installTextureSlot(sampler, slotName, texcoord, this->_asset, cvtEffect);
} else {
// nothing to do, no texture or color
}
Expand Down Expand Up @@ -815,6 +848,7 @@ namespace GLTF
handleEffectSlot(effectCommon,"emission" , cvtEffect, extras);
handleEffectSlot(effectCommon,"specular" , cvtEffect, extras);
handleEffectSlot(effectCommon,"reflective" , cvtEffect, extras);
handleEffectSlot(effectCommon,"bump" , cvtEffect, extras);

if (CONFIG_BOOL(asset, "alwaysExportFilterColor")) {
shared_ptr <JSONObject> slotObject(new JSONObject());
Expand Down
6 changes: 6 additions & 0 deletions converter/COLLADA2GLTF/COLLADA2GLTFWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ namespace GLTF
virtual bool writeKinematicsScene( const COLLADAFW::KinematicsScene* kinematicsScene ){return true;};

private:
void _installTextureSlot(COLLADAFW::Sampler* sampler,
const std::string& slotName,
const std::string& texcoord,
std::shared_ptr <GLTF::GLTFAsset> asset,
std::shared_ptr<GLTF::GLTFEffect> cvtEffect);

void _storeMaterialBindingArray(const std::string& prefix,
const std::string& nodeUID,
const std::string& meshUID,
Expand Down
1 change: 1 addition & 0 deletions converter/COLLADA2GLTF/GLTF/GLTF.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,6 @@
#include "GLTFOutputStream.h"
#include "GLTFConfig.h"
#include "GLTFAssetModifier.h"
#include "GLTFExtras.h"

#endif
4 changes: 1 addition & 3 deletions converter/COLLADA2GLTF/GLTF/GLTFAsset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,9 +463,7 @@ namespace GLTF
}

unsigned int indexOfSet = 0;
if (semantic == GLTF::TEXCOORD) {
indexOfSet = primitive->getIndexOfSetAtIndex((unsigned int)j);
}
indexOfSet = primitive->getIndexOfSetAtIndex((unsigned int)j);

sets->appendValue(shared_ptr<JSONNumber> (new JSONNumber(indexOfSet)));
}
Expand Down
90 changes: 50 additions & 40 deletions converter/COLLADA2GLTF/GLTF/GLTFExtraDataHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//#include "GeneratedSaxParserUtils.h"

#include <vector> //FIXME: this should be included by OpenCOLLADA.
#include "../GLTFOpenCOLLADA.h"
#include "GLTFExtraDataHandler.h"
#include "GLTF.h"

Expand Down Expand Up @@ -35,22 +36,63 @@ namespace GLTF
*/

//------------------------------
ExtraDataHandler::ExtraDataHandler()
ExtraDataHandler::ExtraDataHandler() : mExtraTagType(EXTRA_TAG_TYPE_UNKNOWN)
{
_allExtras = shared_ptr<JSONObject> (new JSONObject());
}

//------------------------------
ExtraDataHandler::~ExtraDataHandler()
{
}

void ExtraDataHandler::determineBumpTextureSamplerAndTexCoord( const GeneratedSaxParser::xmlChar** attributes )
{
COLLADAFW::TextureAttributes *textureAttributes = nullptr;

shared_ptr <JSONObject> bump = nullptr;
if(mCurrentObject) {
if( COLLADAFW::COLLADA_TYPE::EFFECT == mCurrentObject->getClassId()) {
shared_ptr <JSONObject> extras = this->getExtras(mCurrentElementUniqueId);
assert(extras);
shared_ptr <JSONObject> textures = extras->createObjectIfNeeded("textures");
bump = textures->createObjectIfNeeded("bump");

COLLADAFW::Effect* effect = (COLLADAFW::Effect*)mCurrentObject;
textureAttributes = effect->createExtraTextureAttributes();
}
}

if ((bump == nullptr) || (textureAttributes == nullptr))
return;

size_t index = 0;

const GeneratedSaxParser::xmlChar* attributeKey = attributes[index++];
const GeneratedSaxParser::xmlChar* attributeValue = 0;
while( attributeKey != 0 ) {
attributeValue = attributes[index++];
if( attributeValue != 0 ) {
bump->setString(attributeKey, attributeValue);
}

if (strcmp(attributeKey, "texture") == 0) {
textureAttributes->textureSampler = attributeValue;
} else if (strcmp(attributeKey, "texcoord")) {
textureAttributes->texCoord = attributeValue;
}
attributeKey = attributes[index++];
}
}

//------------------------------
bool ExtraDataHandler::elementBegin( const COLLADASaxFWL::ParserChar* elementName, const GeneratedSaxParser::xmlChar** attributes )
{
if (mExtraTagType == EXTRA_TAG_TYPE_BUMP) {
determineBumpTextureSamplerAndTexCoord(attributes);
}
mExtraTagType = EXTRA_TAG_TYPE_UNKNOWN;

if (strcmp(elementName, DOUBLE_SIDED) == 0) {
//Typically, may happen in EFFECT (MAX) or GEOMETRY (MAYA)
mExtraTagType = EXTRA_TAG_TYPE_DOUBLE_SIDED;
Expand All @@ -62,6 +104,12 @@ namespace GLTF
return true;
}


if (strcmp(elementName, "bump") == 0) {
mExtraTagType = EXTRA_TAG_TYPE_BUMP;
}


/*
switch ( mExtraTagType )
{
Expand Down Expand Up @@ -288,43 +336,5 @@ namespace GLTF
}
}

//------------------------------
void ExtraDataHandler::determineBumpTextureSamplerAndTexCoord( const GeneratedSaxParser::xmlChar** attributes )
{
mExtraParameters.bumpParameters.textureAttributes = 0;

if( mCurrentObject )
{
if( COLLADAFW::COLLADA_TYPE::EFFECT == mCurrentObject->getClassId() )
{
COLLADAFW::Effect* effect = (COLLADAFW::Effect*)mCurrentObject;
mExtraParameters.bumpParameters.textureAttributes = effect->createExtraTextureAttributes();
}
}

if( mExtraParameters.bumpParameters.textureAttributes == 0 )
return;

size_t index = 0;

const GeneratedSaxParser::xmlChar* attributeKey = attributes[index++];
const GeneratedSaxParser::xmlChar* attributeValue = 0;
while( attributeKey != 0 )
{
attributeValue = attributes[index++];
if( strcmp(attributeKey, "texture") == 0 && attributeValue != 0 )
{
if( mExtraParameters.bumpParameters.textureAttributes )
mExtraParameters.bumpParameters.textureAttributes->textureSampler = attributeValue;
}
else if( strcmp(attributeKey, "texcoord") == 0 && attributeValue != 0 )
{
if( mExtraParameters.bumpParameters.textureAttributes )
mExtraParameters.bumpParameters.textureAttributes->texCoord = attributeValue;
}

attributeKey = attributes[index++];
}
}
#endif
}
2 changes: 2 additions & 0 deletions converter/COLLADA2GLTF/GLTF/GLTFExtraDataHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ namespace GLTF
std::shared_ptr <JSONObject> getExtras(COLLADAFW::UniqueId uniqueId);
std::shared_ptr <JSONObject> allExtras() { return this->_allExtras; }

void determineBumpTextureSamplerAndTexCoord( const GeneratedSaxParser::xmlChar** attributes );

private:
std::shared_ptr <JSONObject> _allExtras;
};
Expand Down
4 changes: 1 addition & 3 deletions converter/COLLADA2GLTF/GLTF/GLTFMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,7 @@ namespace GLTF
GLTF::Semantic semantic = primitive->getSemanticAtIndex((unsigned int)j);
std::string semanticAndSet = GLTFUtils::getStringForSemantic(semantic);
unsigned int indexOfSet = 0;
if ((semantic != GLTF::POSITION) && (semantic != GLTF::NORMAL) &&
//FIXME: should not be required for JOINT and WEIGHT
(semantic != GLTF::JOINT) && (semantic != GLTF::WEIGHT)) {
if ((semantic == GLTF::TEXCOORD) || (semantic == GLTF::COLOR)) {
indexOfSet = primitive->getIndexOfSetAtIndex((unsigned int)j);
semanticAndSet += "_" + GLTFUtils::toString(indexOfSet);
}
Expand Down
4 changes: 3 additions & 1 deletion converter/COLLADA2GLTF/GLTF/GLTFTypesAndConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ namespace GLTF
TEXCOORD = 3,
COLOR = 4,
WEIGHT = 5,
JOINT = 6
JOINT = 6,
TEXTANGENT = 7,
TEXBINORMAL = 8
} Semantic;

typedef std::string JSONType;
Expand Down
4 changes: 4 additions & 0 deletions converter/COLLADA2GLTF/GLTF/GLTFUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ namespace GLTF
return "JOINT";
case GLTF::WEIGHT:
return "WEIGHT";
case GLTF::TEXBINORMAL:
return "TEXBINORMAL";
case GLTF::TEXTANGENT:
return "TEXTANGENT";

default:
return "UNKNOWN";
Expand Down
Loading

0 comments on commit 0686784

Please sign in to comment.