1 /* 2 Copyright (c) 2008-2009 NetAllied Systems GmbH 3 4 This file is part of COLLADASaxFrameworkLoader. 5 6 Licensed under the MIT Open Source License, 7 for details please see LICENSE file or the website 8 http://www.opensource.org/licenses/mit-license.php 9 */ 10 11 #include "COLLADASaxFWLStableHeaders.h" 12 #include "COLLADASaxFWLSourceArrayLoader.h" 13 #include "COLLADAFWTypes.h" 14 15 namespace COLLADASaxFWL 16 { 17 18 #ifdef COLLADASAXFWL_REAL_IS_FLOAT 19 const COLLADAFW::FloatOrDoubleArray::DataType SourceArrayLoader::DATA_TYPE_REAL = COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT; 20 #else 21 const COLLADAFW::FloatOrDoubleArray::DataType SourceArrayLoader::DATA_TYPE_REAL = COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE; 22 #endif 23 24 25 //------------------------------ SourceArrayLoader(IFilePartLoader * callingFilePartLoader)26 SourceArrayLoader::SourceArrayLoader(IFilePartLoader* callingFilePartLoader) 27 :FilePartLoader(callingFilePartLoader), 28 mSourceArray( SourceArray::OWNER ), 29 mCurrentSoure(0) 30 { 31 } 32 33 //------------------------------ ~SourceArrayLoader()34 SourceArrayLoader::~SourceArrayLoader() 35 { 36 clearSources(); 37 } 38 39 /** Copies the values contained in @a realSource into @a realsArray .*/ 40 //------------------------------ setRealValues(COLLADAFW::FloatOrDoubleArray & realsArray,const RealSource * realSource)41 void SourceArrayLoader::setRealValues( COLLADAFW::FloatOrDoubleArray& realsArray, const RealSource* realSource ) 42 { 43 if ( !realsArray.empty() ) 44 { 45 // There already must have been an input with semantic INPUT. We ignore all following. 46 return; 47 } 48 realsArray.setType( SourceArrayLoader::DATA_TYPE_REAL ); 49 const RealArrayElement& realArrayElement = realSource->getArrayElement(); 50 realsArray.appendValues(realArrayElement.getValues()); 51 } 52 53 54 //------------------------------ clearSources()55 void SourceArrayLoader::clearSources() 56 { 57 for ( size_t i = 0, count = mSourceArray.getCount(); i < count; ++i) 58 delete mSourceArray[i]; 59 mSourceArray.setCount(0); 60 } 61 62 //------------------------------ assignSourceValuesToFloatOrDoubleArray(SourceBase * sourceBase,COLLADAFW::FloatOrDoubleArray & floatOrDoubleArray)63 bool SourceArrayLoader::assignSourceValuesToFloatOrDoubleArray( SourceBase* sourceBase, COLLADAFW::FloatOrDoubleArray& floatOrDoubleArray ) 64 { 65 if (sourceBase->getDataType() == SourceBase::DATA_TYPE_FLOAT) 66 { 67 floatOrDoubleArray.setType( COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT); 68 COLLADAFW::FloatArray* values = floatOrDoubleArray.getFloatValues(); 69 FloatSource* source = ( FloatSource* ) sourceBase; 70 FloatArrayElement& arrayElement = source->getArrayElement(); 71 COLLADAFW::FloatArray& valuesArray = arrayElement.getValues(); 72 values->setData ( valuesArray.getData (), valuesArray.getCount () ); 73 valuesArray.yieldOwnerShip(); 74 return true; 75 } 76 else if (sourceBase->getDataType() == SourceBase::DATA_TYPE_DOUBLE) 77 { 78 floatOrDoubleArray.setType( COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE); 79 COLLADAFW::DoubleArray* values = floatOrDoubleArray.getDoubleValues(); 80 DoubleSource* source = ( DoubleSource* ) sourceBase; 81 DoubleArrayElement& arrayElement = source->getArrayElement(); 82 COLLADAFW::DoubleArray& valuesArray = arrayElement.getValues(); 83 values->setData ( valuesArray.getData (), valuesArray.getCount () ); 84 valuesArray.yieldOwnerShip(); 85 return true; 86 } 87 else 88 { 89 return false; 90 } 91 } 92 93 //------------------------------ getIdFromURIFragmentType(const char * uriFragment)94 COLLADAFW::String SourceArrayLoader::getIdFromURIFragmentType( const char* uriFragment ) 95 { 96 if ( !uriFragment ) 97 return ""; 98 99 const char* startPos = uriFragment; 100 while ( *startPos && GeneratedSaxParser::Utils::isWhiteSpace(*startPos)) 101 startPos++; 102 103 // skip leading '#' if present. (the uriFragment would be invalid if there is no '#', but we are tolerant) 104 if ( *startPos == '#' ) 105 startPos++; 106 107 const char* endPos = startPos; 108 while ( *endPos && !GeneratedSaxParser::Utils::isWhiteSpace(*endPos) ) 109 endPos++; 110 111 return String(startPos, endPos - startPos); 112 } 113 114 //------------------------------ getSourceArray() const115 const SourceArray& SourceArrayLoader::getSourceArray () const 116 { 117 return mSourceArray; 118 } 119 120 //------------------------------ setSourceArray(const SourceArray & sourceArray)121 void SourceArrayLoader::setSourceArray ( const SourceArray& sourceArray ) 122 { 123 mSourceArray = sourceArray; 124 } 125 126 //------------------------------ getSourceById(const String & sourceId) const127 const SourceBase* SourceArrayLoader::getSourceById ( const String& sourceId ) const 128 { 129 for ( size_t i=0; i<mSourceArray.getCount (); ++i ) 130 { 131 const SourceBase* source = mSourceArray [ i ]; 132 if ( COLLADABU::Utils::equals ( source->getId (), sourceId ) ) 133 return source; 134 } 135 return 0; 136 } 137 138 //------------------------------ getSourceById(const String & sourceId)139 SourceBase* SourceArrayLoader::getSourceById ( const String& sourceId ) 140 { 141 for ( size_t i=0; i<mSourceArray.getCount (); ++i ) 142 { 143 SourceBase* source = mSourceArray [ i ]; 144 if ( COLLADABU::Utils::equals ( source->getId (), sourceId ) ) 145 return source; 146 } 147 return 0; 148 } 149 150 //------------------------------ beginSource(const source__AttributeData & attributes)151 bool SourceArrayLoader::beginSource( const source__AttributeData& attributes ) 152 { 153 if ( attributes.id ) 154 mCurrentSourceId = attributes.id; 155 return true; 156 } 157 158 159 //------------------------------ endSource()160 bool SourceArrayLoader::endSource( ) 161 { 162 if ( mCurrentSoure ) 163 { 164 mSourceArray.append(mCurrentSoure); 165 } 166 mCurrentSoure = 0; 167 mCurrentSourceId.clear(); 168 mCurrentArrayId.clear(); 169 return true; 170 } 171 172 //------------------------------ begin__float_array(const float_array__AttributeData & attributeData)173 bool SourceArrayLoader::begin__float_array( const float_array__AttributeData& attributeData ) 174 { 175 return beginArray<FloatSource>( attributeData.count, attributeData.id ) != 0; 176 } 177 178 //------------------------------ end__float_array()179 bool SourceArrayLoader::end__float_array() 180 { 181 // we don't need to do anything here 182 return true; 183 } 184 185 //------------------------------ data__float_array(const float * data,size_t length)186 bool SourceArrayLoader::data__float_array( const float* data, size_t length ) 187 { 188 FloatSource* source = (FloatSource*)mCurrentSoure; 189 COLLADAFW::FloatArray& array = source->getArrayElement().getValues(); 190 array.appendValues(data, length); 191 return true; 192 } 193 194 //------------------------------ begin__animation__source__technique_common()195 bool SourceArrayLoader::begin__animation__source__technique_common() 196 { 197 //we don't need to do anything here 198 return true; 199 } 200 201 //------------------------------ end__animation__source__technique_common()202 bool SourceArrayLoader::end__animation__source__technique_common() 203 { 204 //we don't need to do anything here 205 return true; 206 } 207 208 //------------------------------ begin__accessor(const accessor__AttributeData & attributeData)209 bool SourceArrayLoader::begin__accessor( const accessor__AttributeData& attributeData ) 210 { 211 // As soon as we support all array types, remove this check 212 if ( mCurrentSoure ) 213 mCurrentSoure->setStride((int)attributeData.stride); 214 return true; 215 } 216 217 //------------------------------ end__accessor()218 bool SourceArrayLoader::end__accessor() 219 { 220 //we don't need to do anything here 221 return true; 222 } 223 224 //------------------------------ begin__param(const param__AttributeData & attributeData)225 bool SourceArrayLoader::begin__param( const param__AttributeData& attributeData ) 226 { 227 if ( mCurrentSoure ) 228 { 229 SourceBase::AccessorParameter accessorParameter; 230 if ( attributeData.name && *attributeData.name ) 231 { 232 accessorParameter.name = attributeData.name; 233 } 234 235 // the type is required. We don't need to check 236 accessorParameter.type = attributeData.type; 237 mCurrentSoure->appendAccessorParameter( accessorParameter ); 238 } 239 return true; 240 } 241 242 243 } // namespace COLLADAFW 244