/**************************************************************************************/ /* */ /* Visualization Library */ /* http://visualizationlibrary.org */ /* */ /* Copyright (c) 2005-2020, Michele Bosi */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or without modification, */ /* are permitted provided that the following conditions are met: */ /* */ /* - Redistributions of source code must retain the above copyright notice, this */ /* list of conditions and the following disclaimer. */ /* */ /* - Redistributions in binary form must reproduce the above copyright notice, this */ /* list of conditions and the following disclaimer in the documentation and/or */ /* other materials provided with the distribution. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /**************************************************************************************/ #ifndef VLXWrapper_Graphics_INCLUDE_ONCE #define VLXWrapper_Graphics_INCLUDE_ONCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace vlX { /** VLX wrapper of vl::Array */ struct VLXClassWrapper_Array: public ClassWrapper { virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { if (!vlx->getValue("Value")) { vl::Log::error( vl::Say("Line %n : error. 'VLXValue' expected in object '%s'. \n") << vlx->lineNumber() << vlx->tag() ); return NULL; } const VLXValue& value = *vlx->getValue("Value"); vl::ref arr_abstract; if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value); const VLXArrayReal* vlx_arr_float = value.getArrayReal(); vl::ref arr_float1 = new vl::ArrayFloat1; arr_abstract = arr_float1; arr_float1->resize( vlx_arr_float->value().size() ); vlx_arr_float->copyTo((float*)arr_float1->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value); const VLXArrayReal* vlx_arr_float = value.getArrayReal(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_float->value().size() % 2 == 0, value) vl::ref arr_float2 = new vl::ArrayFloat2; arr_abstract = arr_float2; arr_float2->resize( vlx_arr_float->value().size() / 2 ); vlx_arr_float->copyTo((float*)arr_float2->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value); const VLXArrayReal* vlx_arr_float = value.getArrayReal(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_float->value().size() % 3 == 0, value) vl::ref arr_float3 = new vl::ArrayFloat3; arr_abstract = arr_float3; arr_float3->resize( vlx_arr_float->value().size() / 3 ); vlx_arr_float->copyTo((float*)arr_float3->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value); const VLXArrayReal* vlx_arr_float = value.getArrayReal(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_float->value().size() % 4 == 0, value) vl::ref arr_float4 = new vl::ArrayFloat4; arr_abstract = arr_float4; arr_float4->resize( vlx_arr_float->value().size() / 4 ); vlx_arr_float->copyTo((float*)arr_float4->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value); const VLXArrayReal* vlx_arr_floating = value.getArrayReal(); vl::ref arr_floating1 = new vl::ArrayDouble1; arr_abstract = arr_floating1; arr_floating1->resize( vlx_arr_floating->value().size() ); vlx_arr_floating->copyTo((double*)arr_floating1->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value); const VLXArrayReal* vlx_arr_floating = value.getArrayReal(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_floating->value().size() % 2 == 0, value) vl::ref arr_floating2 = new vl::ArrayDouble2; arr_abstract = arr_floating2; arr_floating2->resize( vlx_arr_floating->value().size() / 2 ); vlx_arr_floating->copyTo((double*)arr_floating2->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value); const VLXArrayReal* vlx_arr_floating = value.getArrayReal(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_floating->value().size() % 3 == 0, value) vl::ref arr_floating3 = new vl::ArrayDouble3; arr_abstract = arr_floating3; arr_floating3->resize( vlx_arr_floating->value().size() / 3 ); vlx_arr_floating->copyTo((double*)arr_floating3->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value); const VLXArrayReal* vlx_arr_floating = value.getArrayReal(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_floating->value().size() % 4 == 0, value) vl::ref arr_floating4 = new vl::ArrayDouble4; arr_abstract = arr_floating4; arr_floating4->resize( vlx_arr_floating->value().size() / 4 ); vlx_arr_floating->copyTo((double*)arr_floating4->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); vl::ref arr_int1 = new vl::ArrayInt1; arr_abstract = arr_int1; arr_int1->resize( vlx_arr_int->value().size() ); vlx_arr_int->copyTo((int*)arr_int1->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value) vl::ref arr_int2 = new vl::ArrayInt2; arr_abstract = arr_int2; arr_int2->resize( vlx_arr_int->value().size() / 2 ); vlx_arr_int->copyTo((int*)arr_int2->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value) vl::ref arr_int3 = new vl::ArrayInt3; arr_abstract = arr_int3; arr_int3->resize( vlx_arr_int->value().size() / 3 ); vlx_arr_int->copyTo((int*)arr_int3->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value) vl::ref arr_int4 = new vl::ArrayInt4; arr_abstract = arr_int4; arr_int4->resize( vlx_arr_int->value().size() / 4 ); vlx_arr_int->copyTo((int*)arr_int4->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); vl::ref arr_int1 = new vl::ArrayUInt1; arr_abstract = arr_int1; arr_int1->resize( vlx_arr_int->value().size() ); vlx_arr_int->copyTo((unsigned int*)arr_int1->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value) vl::ref arr_int2 = new vl::ArrayUInt2; arr_abstract = arr_int2; arr_int2->resize( vlx_arr_int->value().size() / 2 ); vlx_arr_int->copyTo((unsigned int*)arr_int2->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value) vl::ref arr_int3 = new vl::ArrayUInt3; arr_abstract = arr_int3; arr_int3->resize( vlx_arr_int->value().size() / 3 ); vlx_arr_int->copyTo((unsigned int*)arr_int3->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value) vl::ref arr_int4 = new vl::ArrayUInt4; arr_abstract = arr_int4; arr_int4->resize( vlx_arr_int->value().size() / 4 ); vlx_arr_int->copyTo((unsigned int*)arr_int4->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); vl::ref arr_short1 = new vl::ArrayShort1; arr_abstract = arr_short1; arr_short1->resize( vlx_arr_int->value().size() ); vlx_arr_int->copyTo((short*)arr_short1->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value) vl::ref arr_short2 = new vl::ArrayShort2; arr_abstract = arr_short2; arr_short2->resize( vlx_arr_int->value().size() / 2 ); vlx_arr_int->copyTo((short*)arr_short2->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value) vl::ref arr_short3 = new vl::ArrayShort3; arr_abstract = arr_short3; arr_short3->resize( vlx_arr_int->value().size() / 3 ); vlx_arr_int->copyTo((short*)arr_short3->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value) vl::ref arr_short4 = new vl::ArrayShort4; arr_abstract = arr_short4; arr_short4->resize( vlx_arr_int->value().size() / 4 ); vlx_arr_int->copyTo((short*)arr_short4->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); vl::ref arr_short1 = new vl::ArrayUShort1; arr_abstract = arr_short1; arr_short1->resize( vlx_arr_int->value().size() ); vlx_arr_int->copyTo((unsigned short*)arr_short1->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value) vl::ref arr_short2 = new vl::ArrayUShort2; arr_abstract = arr_short2; arr_short2->resize( vlx_arr_int->value().size() / 2 ); vlx_arr_int->copyTo((unsigned short*)arr_short2->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value) vl::ref arr_short3 = new vl::ArrayUShort3; arr_abstract = arr_short3; arr_short3->resize( vlx_arr_int->value().size() / 3 ); vlx_arr_int->copyTo((unsigned short*)arr_short3->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value) vl::ref arr_short4 = new vl::ArrayUShort4; arr_abstract = arr_short4; arr_short4->resize( vlx_arr_int->value().size() / 4 ); vlx_arr_int->copyTo((unsigned short*)arr_short4->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); vl::ref arr_byte1 = new vl::ArrayByte1; arr_abstract = arr_byte1; arr_byte1->resize( vlx_arr_int->value().size() ); vlx_arr_int->copyTo((char*)arr_byte1->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value) vl::ref arr_byte2 = new vl::ArrayByte2; arr_abstract = arr_byte2; arr_byte2->resize( vlx_arr_int->value().size() / 2 ); vlx_arr_int->copyTo((char*)arr_byte2->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value) vl::ref arr_byte3 = new vl::ArrayByte3; arr_abstract = arr_byte3; arr_byte3->resize( vlx_arr_int->value().size() / 3 ); vlx_arr_int->copyTo((char*)arr_byte3->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value) vl::ref arr_byte4 = new vl::ArrayByte4; arr_abstract = arr_byte4; arr_byte4->resize( vlx_arr_int->value().size() / 4 ); vlx_arr_int->copyTo((char*)arr_byte4->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); vl::ref arr_byte1 = new vl::ArrayUByte1; arr_abstract = arr_byte1; arr_byte1->resize( vlx_arr_int->value().size() ); vlx_arr_int->copyTo((unsigned char*)arr_byte1->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value) vl::ref arr_byte2 = new vl::ArrayUByte2; arr_abstract = arr_byte2; arr_byte2->resize( vlx_arr_int->value().size() / 2 ); vlx_arr_int->copyTo((unsigned char*)arr_byte2->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value) vl::ref arr_byte3 = new vl::ArrayUByte3; arr_abstract = arr_byte3; arr_byte3->resize( vlx_arr_int->value().size() / 3 ); vlx_arr_int->copyTo((unsigned char*)arr_byte3->ptr()); } else if (vlx->tag() == "") { VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value); const VLXArrayInteger* vlx_arr_int = value.getArrayInteger(); VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value) vl::ref arr_byte4 = new vl::ArrayUByte4; arr_abstract = arr_byte4; arr_byte4->resize( vlx_arr_int->value().size() / 4 ); vlx_arr_int->copyTo((unsigned char*)arr_byte4->ptr()); } else { s.signalImportError( vl::Say("Line %n : unknown array '%s'.\n") << vlx->lineNumber() << vlx->tag() ); } // register imported structure asap s.registerImportedStructure(vlx, arr_abstract.get()); return arr_abstract.get(); } template vl::ref export_ArrayT(VLXSerializer& s, const vl::Object* arr_abstract) { const T_Array* arr = arr_abstract->as(); vl::ref st =new VLXStructure(vlx_makeTag(arr_abstract).c_str(), s.generateID("array_")); vl::ref vlx_array = new T_VLXArray; if (arr->size()) { vlx_array->value().resize( arr->size() * arr->glSize() ); typename T_VLXArray::scalar_type* dst = &vlx_array->value()[0]; const typename T_Array::scalar_type* src = (const typename T_Array::scalar_type*)arr->begin(); const typename T_Array::scalar_type* end = (const typename T_Array::scalar_type*)arr->end(); for(; srcvalue().push_back( VLXStructure::KeyValue("Value", vlx_array.get() ) ); return st; } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { vl::ref vlx; if(obj->classType() == vl::ArrayUInt1::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUInt2::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUInt3::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUInt4::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayInt1::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayInt2::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayInt3::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayInt4::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUShort1::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUShort2::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUShort3::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUShort4::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUShort1::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUShort2::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUShort3::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUShort4::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayShort1::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayShort2::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayShort3::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayShort4::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUByte1::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUByte2::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUByte3::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayUByte4::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayByte1::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayByte2::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayByte3::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayByte4::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayFloat1::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayFloat2::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayFloat3::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayFloat4::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayDouble1::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayDouble2::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayDouble3::Type()) vlx = export_ArrayT(s, obj); else if(obj->classType() == vl::ArrayDouble4::Type()) vlx = export_ArrayT(s, obj); else { s.signalExportError("Array type not supported for export.\n"); } // register exported object asap s.registerExportedObject(obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Renderable */ struct VLXClassWrapper_Renderable: public ClassWrapper { virtual void exportRenderable(const vl::Renderable* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); *vlx << "BufferObjectEnabled" << obj->isBufferObjectEnabled(); *vlx << "DisplayListEnabled" << obj->isDisplayListEnabled(); if (!obj->boundsDirty()) { *vlx << "AABB" << export_AABB(obj->boundingBox()); *vlx << "Sphere" << export_Sphere(obj->boundingSphere()); } else vl::Log::debug("VLXClassWrapper_Renderable : skipping dirty bounds.\n"); } void importRenderable(const VLXStructure* vlx, vl::Renderable* ren) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) ren->setObjectName( name->getString() ); const std::vector& values = vlx->value(); for(size_t i=0; isetBufferObjectEnabled( values[i].value().getBool() ); } else if (key == "DisplayListEnabled") { ren->setDisplayListEnabled( values[i].value().getBool() ); } else if (key == "AABB") { ren->setBoundingBox( import_AABB(values[i].value().getStructure()) ); } else if (key == "Sphere") { ren->setBoundingSphere( import_Sphere(values[i].value().getStructure()) ); } } } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Geometry */ struct VLXClassWrapper_Geometry: public VLXClassWrapper_Renderable { void importGeometry(VLXSerializer& s, const VLXStructure* vlx, vl::Geometry* geom) { VLXClassWrapper_Renderable::importRenderable(vlx, geom); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if (key == "VertexArray") { VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as(); if (arr) geom->setVertexArray(arr); else s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); } else if (key == "NormalArray") { VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as(); if (arr) geom->setNormalArray(arr); else s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); } else if (key == "ColorArray") { VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as(); if (arr) geom->setColorArray(arr); else s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); } else if (key == "SecondaryColorArray") { VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as(); if (arr) geom->setSecondaryColorArray(arr); else s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); } else if (key == "FogCoordArray") { VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as(); if (arr) geom->setFogCoordArray(arr); else s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); } else if (strstr(key.c_str(), "TexCoordArray") == key.c_str()) { const char* ch = key.c_str() + 13/*strlen("TexCoordArray")*/; int tex_unit = 0; for(; *ch; ++ch) { if (*ch>='0' && *ch<='9') tex_unit = tex_unit*10 + (*ch - '0'); else { vl::Log::error( vl::Say("Line %n : error. ") << value.lineNumber() ); vl::Log::error( "TexCoordArray must end with a number!\n" ); s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); } } VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as(); if (arr) geom->setTexCoordArray(tex_unit, arr); else s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); } else if (strstr(key.c_str(), "VertexAttribArray") == key.c_str()) { // MIC FIXME //const char* ch = key.c_str() + 17/*strlen("VertexAttribArray")*/; //int attrib_location = 0; //for(; *ch; ++ch) //{ // if (*ch>='0' && *ch<='9') // attrib_location = attrib_location*10 + (*ch - '0'); // else // { // vl::Log::error( vl::Say("Line %n : error. ") << value.lineNumber() ); // vl::Log::error( "VertexAttribArray must end with a number!\n" ); // s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); // } //} //VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) //VertexAttribInfo* info_ptr = s.importVLX(value.getStructure())->as(); //if (info_ptr) //{ // VertexAttribInfo info = *info_ptr; // info.setAttribLocation(attrib_location); // geom->setVertexAttribArray(info); //} //else // s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); } else if (key == "DrawCall") { VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) vl::DrawCall* draw_call = s.importVLX(value.getStructure())->as(); if (draw_call) geom->drawCalls().push_back(draw_call); else s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref geom = new vl::Geometry; // registration must be done here to avoid loops s.registerImportedStructure(vlx, geom.get()); importGeometry(s, vlx, geom.get()); return geom; } void exportGeometry(VLXSerializer& s, const vl::Geometry* geom, VLXStructure* vlx) { // vl::Renderable VLXClassWrapper_Renderable::exportRenderable(geom, vlx); // vl::Geometry if (geom->vertexArray()) *vlx << "VertexArray" << s.exportVLX(geom->vertexArray()); if (geom->normalArray()) *vlx << "NormalArray" << s.exportVLX(geom->normalArray()); if (geom->colorArray()) *vlx << "ColorArray" << s.exportVLX(geom->colorArray()); if (geom->secondaryColorArray()) *vlx << "SecondaryColorArray" << s.exportVLX(geom->secondaryColorArray()); if (geom->fogCoordArray()) *vlx << "FogCoordArray" << s.exportVLX(geom->fogCoordArray()); for( int i=0; itexCoordArray(i)) { std::string tex_coord_array = vl::String::printf("TexCoordArray%d", i).toStdString(); *vlx << tex_coord_array.c_str() << s.exportVLX(geom->texCoordArray(i)); } } // MIC FIXME: unify with above //for(size_t i=0; ivertexAttribArray(i)) // { // std::string vertex_attrib_array = vl::String::printf("VertexAttribArray%d", i).toStdString(); // *vlx << vertex_attrib_array.c_str() << s.exportVLX(geom->vertexAttribArray(i)); // } //} for(int i=0; idrawCalls().size(); ++i) { *vlx << "DrawCall" << s.exportVLX(geom->drawCalls().at(i)); } } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Geometry* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("geometry_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportGeometry(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::DrawCall and subclasses. */ struct VLXClassWrapper_DrawCall: public ClassWrapper { void importDrawCall(VLXSerializer& s, const VLXStructure* vlx, vl::DrawCall* draw_call) { if(draw_call->isOfType(vl::DrawElementsBase::Type())) { vl::DrawElementsBase* de= draw_call->as(); const VLXValue* name = vlx->getValue("ObjectName"); if (name) de->setObjectName( name->getString() ); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if( key == "PrimitiveType" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier , value) de->setPrimitiveType( vlx_EPrimitiveType( value, s ) ); VLX_IMPORT_CHECK_RETURN( de->primitiveType() != vl::PT_UNKNOWN , value); } else if( key == "Enabled" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value) de->setEnabled( value.getBool() ); } else if( key == "Instances" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value) de->setInstances( (int)value.getInteger() ); } else if( key == "PrimitiveRestartEnabled" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value) de->setPrimitiveRestartEnabled( value.getBool() ); } else if( key == "BaseVertex" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value) de->setBaseVertex( (int)value.getInteger() ); } else if( key == "IndexBuffer" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure , value) vl::ArrayAbstract* arr_abstract = s.importVLX(value.getStructure())->as(); if(!arr_abstract) s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); if ( de->isOfType(vl::DrawElementsUInt::Type()) ) { VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUInt1::Type(), value); de->as()->setIndexBuffer( arr_abstract->as() ); } else if ( de->isOfType(vl::DrawElementsUShort::Type()) ) { VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUShort1::Type(), value); de->as()->setIndexBuffer( arr_abstract->as() ); } else if ( de->isOfType(vl::DrawElementsUByte::Type()) ) { VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUByte1::Type(), value); de->as()->setIndexBuffer( arr_abstract->as() ); } } } } else if(draw_call->isOfType(vl::MultiDrawElementsBase::Type())) { vl::MultiDrawElementsBase* de = draw_call->as(); VL_CHECK(de) VL_CHECK(draw_call) const VLXValue* name = vlx->getValue("ObjectName"); if (name) de->setObjectName( name->getString() ); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if( key == "PrimitiveType" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier , value) de->setPrimitiveType( vlx_EPrimitiveType( value, s ) ); VLX_IMPORT_CHECK_RETURN( de->primitiveType() != vl::PT_UNKNOWN , value); } else if( key == "Enabled" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value) de->setEnabled( value.getBool() ); } else if( key == "PrimitiveRestartEnabled" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value) de->setPrimitiveRestartEnabled( value.getBool() ); } else if( key == "BaseVertices" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger , value) de->baseVertices().resize( value.getArrayInteger()->value().size() ); if (de->baseVertices().size()) value.getArrayInteger()->copyTo( &de->baseVertices()[0] ); // de->setBaseVertices( value.getArrayInt32()->value() ); } else if( key == "CountVector" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger , value) de->countVector().resize( value.getArrayInteger()->value().size() ); if (de->countVector().size()) value.getArrayInteger()->copyTo( &de->countVector()[0] ); // de->countVector() = value.getArrayInt32()->value(); } else if( key == "IndexBuffer" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure , value) vl::ArrayAbstract* arr_abstract = s.importVLX(value.getStructure())->as(); if( !arr_abstract ) s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() ); if ( de->isOfType(vl::MultiDrawElementsUInt::Type()) ) { VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUInt1::Type(), value); de->as()->setIndexBuffer( arr_abstract->as() ); } else if ( de->isOfType(vl::MultiDrawElementsUShort::Type()) ) { VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUShort1::Type(), value); de->as()->setIndexBuffer( arr_abstract->as() ); } else if ( de->isOfType(vl::MultiDrawElementsUByte::Type()) ) { VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUByte1::Type(), value); de->as()->setIndexBuffer( arr_abstract->as() ); } } } // finalize setup de->computePointerVector(); de->computeBufferObjectPointerVector(); if ( de->baseVertices().size() != de->countVector().size() ) de->baseVertices().resize( de->countVector().size() ); } else if( draw_call->isOfType(vl::DrawArrays::Type()) ) { vl::ref da = draw_call->as(); const VLXValue* name = vlx->getValue("ObjectName"); if (name) da->setObjectName( name->getString() ); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if( key == "PrimitiveType" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier , value) da->setPrimitiveType( vlx_EPrimitiveType( value, s ) ); VLX_IMPORT_CHECK_RETURN( da->primitiveType() != vl::PT_UNKNOWN , value); } else if( key == "Enabled" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value) da->setEnabled( value.getBool() ); } else if( key == "Instances" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value) da->setInstances( (int)value.getInteger() ); } else if( key == "Start" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value) da->setStart( (int)value.getInteger() ); } else if( key == "Count" ) { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value) da->setCount( (int)value.getInteger() ); } } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref dc; if (vlx->tag() == "") dc = new vl::DrawElementsUInt; else if (vlx->tag() == "") dc = new vl::DrawElementsUShort; else if (vlx->tag() == "") dc = new vl::DrawElementsUByte; else if (vlx->tag() == "") dc = new vl::MultiDrawElementsUInt; else if (vlx->tag() == "") dc = new vl::MultiDrawElementsUShort; else if (vlx->tag() == "") dc = new vl::MultiDrawElementsUByte; else if (vlx->tag() == "") dc = new vl::DrawArrays; else s.signalImportError( vl::Say("Line %n : error. Unknown draw call.\n") << vlx->lineNumber() ); // register imported structure asap s.registerImportedStructure(vlx, dc.get()); importDrawCall(s, vlx, dc.get()); return dc; } void exportDrawCallBase(VLXSerializer& s, const vl::DrawCall* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); *vlx << "PrimitiveType" << vlx_Identifier(vlx_EPrimitiveType(obj->primitiveType())); *vlx << "Enabled" << obj->isEnabled(); if (obj->patchParameter()) *vlx << "PatchParameter" << s.exportVLX(obj->patchParameter()); } void exportDrawCall(VLXSerializer& s, const vl::DrawCall* dcall, VLXStructure* vlx) { exportDrawCallBase(s, dcall, vlx); if (dcall->isOfType(vl::DrawArrays::Type())) { const vl::DrawArrays* da = dcall->as(); *vlx << "Instances" << (long long)da->instances(); *vlx << "Start" << (long long)da->start(); *vlx << "Count" << (long long)da->count(); } else if (dcall->isOfType(vl::DrawElementsUInt::Type())) { const vl::DrawElementsUInt* de = dcall->as(); *vlx << "Instances" << (long long)de->instances(); *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled(); *vlx << "BaseVertex" << (long long)de->baseVertex(); *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer()); } else if (dcall->isOfType(vl::DrawElementsUShort::Type())) { const vl::DrawElementsUShort* de = dcall->as(); *vlx << "Instances" << (long long)de->instances(); *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled(); *vlx << "BaseVertex" << (long long)de->baseVertex(); *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer()); } else if (dcall->isOfType(vl::DrawElementsUByte::Type())) { const vl::DrawElementsUByte* de = dcall->as(); *vlx << "Instances" << (long long)de->instances(); *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled(); *vlx << "BaseVertex" << (long long)de->baseVertex(); *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer()); } else if (dcall->isOfType(vl::MultiDrawElementsUInt::Type())) { const vl::MultiDrawElementsUInt* de = dcall->as(); *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled(); *vlx << "BaseVertices" << vlx_toValue(de->baseVertices()); *vlx << "CountVector" << vlx_toValue(de->countVector()); *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer()); } else if (dcall->isOfType(vl::MultiDrawElementsUShort::Type())) { const vl::MultiDrawElementsUShort* de = dcall->as(); *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled(); *vlx << "BaseVertices" << vlx_toValue(de->baseVertices()); *vlx << "CountVector" << vlx_toValue(de->countVector()); *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer()); } else if (dcall->isOfType(vl::MultiDrawElementsUByte::Type())) { const vl::MultiDrawElementsUByte* de = dcall->as(); *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled(); *vlx << "BaseVertices" << vlx_toValue(de->baseVertices()); *vlx << "CountVector" << vlx_toValue(de->countVector()); *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer()); } else { vl::Log::error("vl::DrawCall type not supported for export.\n"); } } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::DrawCall* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("drawcall_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportDrawCall(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::PatchParameter */ struct VLXClassWrapper_PatchParameter: public ClassWrapper { void importPatchParameter(const VLXStructure* vlx, vl::PatchParameter* pp) { std::vector values = vlx->value(); for(size_t i=0; isetPatchVertices( (int)values[i].value().getInteger() ); } else if (key == "PatchDefaultOuterLevel") { pp->setPatchDefaultOuterLevel( (vl::fvec4)vlx_vec4(values[i].value().getArrayReal()) ); } else if (key == "PatchDefaultInnerLevel") { pp->setPatchDefaultInnerLevel( (vl::fvec2)vlx_vec2(values[i].value().getArrayReal()) ); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref pp = new vl::PatchParameter; // register imported structure asap s.registerImportedStructure(vlx, pp.get()); importPatchParameter(vlx, pp.get()); return pp; } void exportPatchParameter(const vl::PatchParameter* pp, VLXStructure* vlx) { *vlx << "PatchVertices" << (long long)pp->patchVertices(); *vlx << "PatchDefaultOuterLevel" << vlx_toValue((vl::vec4)pp->patchDefaultOuterLevel()); *vlx << "PatchDefaultInnerLevel" << vlx_toValue((vl::vec2)pp->patchDefaultInnerLevel()); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::PatchParameter* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("patchparam_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportPatchParameter(cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::ResourceDatabase */ struct VLXClassWrapper_ResourceDatabase: public ClassWrapper { void importResourceDatabase(VLXSerializer& s, const VLXStructure* vlx, vl::ResourceDatabase* resdb) { const VLXValue* vlx_obj_name = vlx->getValue("ObjectName"); if (vlx_obj_name) resdb->setObjectName( vlx_obj_name->getString() ); const VLXValue* vlx_res = vlx->getValue("Resources"); if (vlx_res) { VLX_IMPORT_CHECK_RETURN( vlx_res->type() == VLXValue::List, *vlx_res ); // get the list const VLXList* list = vlx_res->getList(); for(size_t i=0; ivalue().size(); ++i) { const VLXValue& value = list->value()[i]; // the member of this list must be all structures. if (value.type() != VLXValue::Structure) { s.signalImportError( vl::Say("Line %n : structure expected.\n") << value.lineNumber() ); return; } resdb->resources().push_back( s.importVLX(value.getStructure()) ); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref resdb = new vl::ResourceDatabase; // register imported structure asap s.registerImportedStructure(vlx, resdb.get()); importResourceDatabase(s, vlx, resdb.get()); return resdb; } void exportResourceDatabase(VLXSerializer& s, const vl::ResourceDatabase* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); vl::ref list = new VLXList; *vlx << "Resources" << list.get(); for(size_t i=0; iresources().size(); ++i) { if ( !s.canExport(obj->resources().at(i).get()) ) { vl::Log::debug( vl::Say("VLXClassWrapper_ResourceDatabase : skipping '%s'.\n") << obj->resources().at(i).get()->className() ); continue; } else { *list << s.exportVLX(obj->resources().at(i).get()); } } } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::ResourceDatabase* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("resdb_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportResourceDatabase(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Uniform */ struct VLXClassWrapper_Uniform: public ClassWrapper { void importUniform(VLXSerializer& s, const VLXStructure* vlx, vl::Uniform* uniform) { const VLXValue* val = vlx->getValue("Name"); if (val) { VL_CHECK( val->type() == VLXValue::Identifier ); uniform->setName( val->getIdentifier() ); } else { s.signalImportError( vl::Say("Line %d : uniform without 'Name'.\n") << vlx->lineNumber() ); return; } // 'Count' is optional int count = 1; val = vlx->getValue("Count"); if (val) { VL_CHECK( val->type() == VLXValue::Integer ); count = (int)val->getInteger(); } vl::EUniformType type = vl::UT_NONE; val = vlx->getValue("Type"); if (val) { VL_CHECK( val->type() == VLXValue::Identifier ); type = vlx_EUniformType( *val, s ); } else { s.signalImportError( vl::Say("Line %d : uniform without 'Type'.\n") << vlx->lineNumber() ); return; } val = vlx->getValue("Data"); const VLXArrayReal* arr_real = NULL; const VLXArrayInteger* arr_int = NULL; if (!val) { s.signalImportError( vl::Say("Line %d : uniform without 'Data'.\n") << vlx->lineNumber() ); return; } else { if (val->type() == VLXValue::ArrayReal) arr_real = val->getArrayReal(); else if (val->type() == VLXValue::ArrayInteger) arr_int = val->getArrayInteger(); } std::vector int_vec; std::vector uint_vec; std::vector float_vec; std::vector double_vec; switch(type) { case vl::UT_INT: int_vec.resize(count*1); if (arr_int) arr_int->copyTo(&int_vec[0]); else int_vec[0] = (int)val->getInteger(); uniform->setUniform1i(count, &int_vec[0]); break; case vl::UT_INT_VEC2: int_vec.resize(count*2); arr_int->copyTo(&int_vec[0]); VLX_IMPORT_CHECK_RETURN(int_vec.size() == arr_int->value().size(), *val); uniform->setUniform2i(count, &int_vec[0]); break; case vl::UT_INT_VEC3: int_vec.resize(count*3); arr_int->copyTo(&int_vec[0]); VLX_IMPORT_CHECK_RETURN(int_vec.size() == arr_int->value().size(), *val); uniform->setUniform3i(count, &int_vec[0]); break; case vl::UT_INT_VEC4: int_vec.resize(count*4); arr_int->copyTo(&int_vec[0]); VLX_IMPORT_CHECK_RETURN(int_vec.size() == arr_int->value().size(), *val); uniform->setUniform4i(count, &int_vec[0]); break; case vl::UT_UNSIGNED_INT: uint_vec.resize(count*1); if (arr_int) arr_int->copyTo(&uint_vec[0]); else uint_vec[0] = (unsigned int)val->getInteger(); uniform->setUniform1ui(count, &uint_vec[0]); break; case vl::UT_UNSIGNED_INT_VEC2: uint_vec.resize(count*2); arr_int->copyTo(&uint_vec[0]); VLX_IMPORT_CHECK_RETURN(uint_vec.size() == arr_int->value().size(), *val); uniform->setUniform2ui(count, &uint_vec[0]); break; case vl::UT_UNSIGNED_INT_VEC3: uint_vec.resize(count*3); arr_int->copyTo(&uint_vec[0]); VLX_IMPORT_CHECK_RETURN(uint_vec.size() == arr_int->value().size(), *val); uniform->setUniform3ui(count, &uint_vec[0]); break; case vl::UT_UNSIGNED_INT_VEC4: uint_vec.resize(count*4); arr_int->copyTo(&uint_vec[0]); VLX_IMPORT_CHECK_RETURN(uint_vec.size() == arr_int->value().size(), *val); uniform->setUniform4ui(count, &uint_vec[0]); break; case vl::UT_FLOAT: float_vec.resize(count*1); if (arr_real) arr_real->copyTo(&float_vec[0]); else float_vec[0] = (float)val->getReal(); uniform->setUniform1f(count, &float_vec[0]); break; case vl::UT_FLOAT_VEC2: float_vec.resize(count*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniform2f(count, &float_vec[0]); break; case vl::UT_FLOAT_VEC3: float_vec.resize(count*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniform3f(count, &float_vec[0]); break; case vl::UT_FLOAT_VEC4: float_vec.resize(count*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniform4f(count, &float_vec[0]); break; case vl::UT_FLOAT_MAT2: float_vec.resize(count*2*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix2f(count, &float_vec[0]); break; case vl::UT_FLOAT_MAT3: float_vec.resize(count*3*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix3f(count, &float_vec[0]); break; case vl::UT_FLOAT_MAT4: float_vec.resize(count*4*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix4f(count, &float_vec[0]); break; case vl::UT_FLOAT_MAT2x3: float_vec.resize(count*2*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix2x3f(count, &float_vec[0]); break; case vl::UT_FLOAT_MAT3x2: float_vec.resize(count*3*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix3x2f(count, &float_vec[0]); break; case vl::UT_FLOAT_MAT2x4: float_vec.resize(count*2*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix2x4f(count, &float_vec[0]); break; case vl::UT_FLOAT_MAT4x2: float_vec.resize(count*4*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix4x2f(count, &float_vec[0]); break; case vl::UT_FLOAT_MAT3x4: float_vec.resize(count*3*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix3x4f(count, &float_vec[0]); break; case vl::UT_FLOAT_MAT4x3: float_vec.resize(count*4*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix4x3f(count, &float_vec[0]); break; case vl::UT_DOUBLE: double_vec.resize(count*1); if (arr_real) arr_real->copyTo(&double_vec[0]); else double_vec[0] = (double)val->getReal(); uniform->setUniform1d(count, &double_vec[0]); break; case vl::UT_DOUBLE_VEC2: double_vec.resize(count*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniform2d(count, &double_vec[0]); break; case vl::UT_DOUBLE_VEC3: double_vec.resize(count*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniform3d(count, &double_vec[0]); break; case vl::UT_DOUBLE_VEC4: double_vec.resize(count*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniform4d(count, &double_vec[0]); break; case vl::UT_DOUBLE_MAT2: double_vec.resize(count*2*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix2d(count, &double_vec[0]); break; case vl::UT_DOUBLE_MAT3: double_vec.resize(count*3*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix3d(count, &double_vec[0]); break; case vl::UT_DOUBLE_MAT4: double_vec.resize(count*4*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix4d(count, &double_vec[0]); break; case vl::UT_DOUBLE_MAT2x3: double_vec.resize(count*2*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix2x3d(count, &double_vec[0]); break; case vl::UT_DOUBLE_MAT3x2: double_vec.resize(count*3*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix3x2d(count, &double_vec[0]); break; case vl::UT_DOUBLE_MAT2x4: double_vec.resize(count*2*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix2x4d(count, &double_vec[0]); break; case vl::UT_DOUBLE_MAT4x2: double_vec.resize(count*4*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix4x2d(count, &double_vec[0]); break; case vl::UT_DOUBLE_MAT3x4: double_vec.resize(count*3*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix3x4d(count, &double_vec[0]); break; case vl::UT_DOUBLE_MAT4x3: double_vec.resize(count*4*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); uniform->setUniformMatrix4x3d(count, &double_vec[0]); break; case vl::UT_NONE: vl::Log::error( vl::Say("Error importing uniform : uninitialized uniform (%s).\n") << uniform->name() ); break; default: vl::Log::error( vl::Say("Error importing uniform : illegal uniform type (%s).\n") << uniform->name() ); break; } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Uniform; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importUniform(s, vlx, obj.get()); return obj; } void exportUniform(const vl::Uniform* uniform, VLXStructure* vlx) { *vlx << "Name" << vlx_Identifier(uniform->name()); *vlx << "Type" << vlx_Identifier(vlx_EUniformType(uniform->type())); *vlx << "Count" << (long long)uniform->count(); const int count = uniform->count(); vl::ref arr_int = new VLXArrayInteger; vl::ref arr_real = new VLXArrayReal; switch(uniform->type()) { case vl::UT_INT: { if (count == 1) { int val = 0; uniform->getUniform(&val); *vlx << "Data" << (long long)val; break; } else { arr_int->value().resize(count*1); arr_int->copyFrom( (int*)uniform->rawData() ); break; } } case vl::UT_INT_VEC2: arr_int->value().resize(count*2); arr_int->copyFrom( (int*)uniform->rawData() ); break; case vl::UT_INT_VEC3: arr_int->value().resize(count*3); arr_int->copyFrom( (int*)uniform->rawData() ); break; case vl::UT_INT_VEC4: arr_int->value().resize(count*4); arr_int->copyFrom( (int*)uniform->rawData() ); break; case vl::UT_UNSIGNED_INT: { if (count == 1) { unsigned int val = 0; uniform->getUniform(&val); *vlx << "Data" << (long long)val; break; } else { arr_int->value().resize(count*1); arr_int->copyFrom( (int*)uniform->rawData() ); break; } } case vl::UT_UNSIGNED_INT_VEC2: arr_int->value().resize(count*2); arr_int->copyFrom( (int*)uniform->rawData() ); break; case vl::UT_UNSIGNED_INT_VEC3: arr_int->value().resize(count*3); arr_int->copyFrom( (int*)uniform->rawData() ); break; case vl::UT_UNSIGNED_INT_VEC4: arr_int->value().resize(count*4); arr_int->copyFrom( (int*)uniform->rawData() ); break; case vl::UT_FLOAT: { if (count == 1) { float val = 0; uniform->getUniform(&val); *vlx << "Data" << (double)val; break; } else { arr_real->value().resize(count*1); arr_real->copyFrom( (float*)uniform->rawData() ); break; } } case vl::UT_FLOAT_VEC2: arr_real->value().resize(count*2); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_VEC3: arr_real->value().resize(count*3); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_VEC4: arr_real->value().resize(count*4); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_MAT2: arr_real->value().resize(count*2*2); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_MAT3: arr_real->value().resize(count*3*3); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_MAT4: arr_real->value().resize(count*4*4); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_MAT2x3: arr_real->value().resize(count*2*3); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_MAT3x2: arr_real->value().resize(count*3*2); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_MAT2x4: arr_real->value().resize(count*2*4); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_MAT4x2: arr_real->value().resize(count*4*2); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_MAT3x4: arr_real->value().resize(count*3*4); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_FLOAT_MAT4x3: arr_real->value().resize(count*4*3); arr_real->copyFrom( (float*)uniform->rawData() ); break; case vl::UT_DOUBLE: { if (count == 1) { double val = 0; uniform->getUniform(&val); *vlx << "Data" << (double)val; break; } else { arr_real->value().resize(count*1); arr_real->copyFrom( (double*)uniform->rawData() ); break; } } case vl::UT_DOUBLE_VEC2: arr_real->value().resize(count*2); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_VEC3: arr_real->value().resize(count*3); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_VEC4: arr_real->value().resize(count*4); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_MAT2: arr_real->value().resize(count*2*2); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_MAT3: arr_real->value().resize(count*3*3); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_MAT4: arr_real->value().resize(count*4*4); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_MAT2x3: arr_real->value().resize(count*2*3); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_MAT3x2: arr_real->value().resize(count*3*2); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_MAT2x4: arr_real->value().resize(count*2*4); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_MAT4x2: arr_real->value().resize(count*4*2); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_MAT3x4: arr_real->value().resize(count*3*4); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_DOUBLE_MAT4x3: arr_real->value().resize(count*4*3); arr_real->copyFrom( (double*)uniform->rawData() ); break; case vl::UT_NONE: vl::Log::error( vl::Say("Error exporting uniform : uninitialized uniform (%s).\n") << uniform->name() ); break; default: vl::Log::error( vl::Say("Error exporting uniform : illegal uniform type (%s).\n") << uniform->name() ); break; } if (!arr_int->value().empty()) *vlx << "Data" << arr_int.get(); else if (!arr_real->value().empty()) *vlx << "Data" << arr_real.get(); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Uniform* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("uniform_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportUniform(cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Shader */ struct VLXClassWrapper_Shader: public ClassWrapper { void importShader(VLXSerializer& s, const VLXStructure* vlx, vl::Shader* sh) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) sh->setObjectName( name->getString() ); // enables const VLXValue* enables = vlx->getValue("Enables"); if (enables) { VLX_IMPORT_CHECK_RETURN( enables->type() == VLXValue::List, *enables ) const VLXList* list = enables->getList(); for(size_t i=0; ivalue().size(); ++i) { VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Identifier, list->value()[i] ); vl::EEnable en = vlx_EEnable( list->value()[i], s ); VLX_IMPORT_CHECK_RETURN( en != vl::EN_UnknownEnable, list->value()[i] ); sh->enable(en); } } // render states const VLXValue* renderstates = vlx->getValue("RenderStates"); if (renderstates) { VLX_IMPORT_CHECK_RETURN( renderstates->type() == VLXValue::List, *renderstates ) const VLXList* list = renderstates->getList(); int index = -1; for(size_t i=0; ivalue().size(); ++i) { VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure || list->value()[i].type() == VLXValue::Integer, list->value()[i] ); if (list->value()[i].type() == VLXValue::Integer) { VLX_IMPORT_CHECK_RETURN( index == -1, list->value()[i] ); index = (int)list->value()[i].getInteger(); } else { vl::RenderState* renderstate = s.importVLX( list->value()[i].getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( renderstate != NULL, list->value()[i] ) VLX_IMPORT_CHECK_RETURN( (index == -1 && !renderstate->isOfType(vl::RenderStateIndexed::Type())) || (index >= 0 && renderstate->isOfType(vl::RenderStateIndexed::Type())), list->value()[i] ) sh->setRenderState(renderstate, index); // consume index in any case index = -1; } } } // uniforms const VLXValue* uniforms = vlx->getValue("Uniforms"); if (uniforms) { VLX_IMPORT_CHECK_RETURN( uniforms->type() == VLXValue::List, *uniforms ) const VLXList* list = uniforms->getList(); for(size_t i=0; ivalue().size(); ++i) { VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure, list->value()[i] ); vl::Uniform* uniform = s.importVLX( list->value()[i].getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( uniform != NULL, list->value()[i] ) sh->setUniform(uniform); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Shader; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importShader(s, vlx, obj.get()); return obj; } void exportShader(VLXSerializer& s, const vl::Shader* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); // uniforms VLXValue uniforms; uniforms.setList( new VLXList ); if (obj->getUniformSet()) { for(size_t i=0; iuniforms().size(); ++i) *uniforms.getList() << s.exportVLX(obj->uniforms()[i].get()); } *vlx << "Uniforms" << uniforms; // enables vl::ref enables = new VLXList; if (obj->getEnableSet() ) { for(size_t i=0; igetEnableSet()->enables().size(); ++i) *enables << vlx_Identifier(vlx_EEnable(obj->getEnableSet()->enables()[i])); } *vlx << "Enables" << enables.get(); // renderstates VLXValue renderstates; renderstates.setList( new VLXList ); if (obj->getRenderStateSet()) { for(size_t i=0; igetRenderStateSet()->renderStatesCount(); ++i) { const vl::RenderState* rs = obj->getRenderStateSet()->renderStates()[i].mRS.get(); if ( !s.canExport(rs) ) { vl::Log::debug( vl::Say("VLXClassWrapper_Shader : skipping '%s'.\n") << rs->className() ); continue; } int index = obj->getRenderStateSet()->renderStates()[i].mIndex; if (index != -1) *renderstates.getList() << (long long)index; *renderstates.getList() << s.exportVLX(rs); } } *vlx << "RenderStates" << renderstates; } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Shader* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("shader_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportShader(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::DistanceLODEvaluator and vl::PixelLODEvaluator */ struct VLXClassWrapper_LODEvaluator: public ClassWrapper { void importLODEvaluator(VLXSerializer& s, const VLXStructure* vlx, vl::LODEvaluator* obj) { if (obj->isOfType(vl::DistanceLODEvaluator::Type())) { vl::DistanceLODEvaluator* lod = obj->as(); const VLXValue* vlx_distances = vlx->getValue("DistanceRageSet"); VLX_IMPORT_CHECK_RETURN( vlx_distances != NULL, *vlx ); VLX_IMPORT_CHECK_RETURN( vlx_distances->type() == VLXValue::ArrayReal, *vlx_distances ); const VLXArrayReal* arr = vlx_distances->getArrayReal(); if (arr->value().size()) { lod->distanceRangeSet().resize( arr->value().size() ); arr->copyTo( &lod->distanceRangeSet()[0] ); } } else if (obj->isOfType(vl::PixelLODEvaluator::Type())) { vl::PixelLODEvaluator* lod = obj->as(); const VLXValue* vlx_pixels = vlx->getValue("PixelRageSet"); VLX_IMPORT_CHECK_RETURN( vlx_pixels != NULL, *vlx ); VLX_IMPORT_CHECK_RETURN( vlx_pixels->type() == VLXValue::ArrayReal, *vlx_pixels ); const VLXArrayReal* arr = vlx_pixels->getArrayReal(); if (arr->value().size()) { lod->pixelRangeSet().resize( arr->value().size() ); arr->copyTo( &lod->pixelRangeSet()[0] ); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { if (vlx->tag() == "") { vl::ref obj = new vl::DistanceLODEvaluator; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importLODEvaluator(s, vlx, obj.get()); return obj; } else if (vlx->tag() == "") { vl::ref obj = new vl::PixelLODEvaluator; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importLODEvaluator(s, vlx, obj.get()); return obj; } else { return NULL; } } void exportLODEvaluator(VLXSerializer& s, const vl::LODEvaluator* obj, VLXStructure* vlx) { if (obj->classType() == vl::DistanceLODEvaluator::Type()) { const vl::DistanceLODEvaluator* lod = obj->as(); VLXValue distances( new VLXArrayReal ); distances.getArrayReal()->value().resize( lod->distanceRangeSet().size() ); if (lod->distanceRangeSet().size() != 0) distances.getArrayReal()->copyFrom( &lod->distanceRangeSet()[0] ); *vlx << "DistanceRageSet" << distances; } else if (obj->classType() == vl::PixelLODEvaluator::Type()) { const vl::PixelLODEvaluator* lod = obj->as(); VLXValue pixels( new VLXArrayReal ); pixels.getArrayReal()->value().resize( lod->pixelRangeSet().size() ); if (lod->pixelRangeSet().size() != 0) pixels.getArrayReal()->copyFrom( &lod->pixelRangeSet()[0] ); *vlx << "PixelRageSet" << pixels; } else { s.signalExportError("vl::LODEvaluator type not supported for export.\n"); } } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::LODEvaluator* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("lodeval_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportLODEvaluator(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Effect */ struct VLXClassWrapper_Effect: public ClassWrapper { void importEffect(VLXSerializer& s, const VLXStructure* vlx, vl::Effect* obj) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) obj->setObjectName( name->getString() ); const std::vector& values = vlx->value(); for(size_t i=0; isetRenderRank( (int)value.getInteger() ); } else if (key == "EnableMask") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ) obj->setEnableMask( (int)value.getInteger() ); } else if (key == "ActiveLod") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ) obj->setActiveLod( (int)value.getInteger() ); } else if (key == "LODEvaluator") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value ) vl::LODEvaluator* lod_eval = s.importVLX( value.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( lod_eval, value ) obj->setLODEvaluator(lod_eval); } else if (key == "Lods") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value ) const VLXList* lod_list = value.getList(); for(size_t ilod=0; ilod< lod_list->value().size(); ++ilod) { const VLXValue& lod_shaders = lod_list->value()[ilod]; VLX_IMPORT_CHECK_RETURN( lod_shaders.type() == VLXValue::List, lod_shaders ) obj->lod((int)ilod) = new vl::ShaderPasses; for( size_t ish=0; ishvalue().size(); ++ish) { const VLXValue& vlx_sh = lod_shaders.getList()->value()[ish]; VLX_IMPORT_CHECK_RETURN( vlx_sh.type() == VLXValue::Structure, vlx_sh ) vl::Shader* shader = s.importVLX( vlx_sh.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( shader, vlx_sh ) obj->lod((int)ilod)->push_back( shader ); } } } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Effect; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importEffect(s, vlx, obj.get()); return obj; } VLXValue export_ShaderPasses(VLXSerializer& s, const vl::ShaderPasses* sh_seq) { VLXValue value( new VLXList(vlx_makeTag(sh_seq).c_str()) ); for(int i=0; isize(); ++i) *value.getList() << s.exportVLX(sh_seq->at(i)); return value; } void exportEffect(VLXSerializer& s, const vl::Effect* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); *vlx << "RenderRank" << (long long)obj->renderRank(); *vlx << "EnableMask" << (long long)obj->enableMask(); *vlx << "ActiveLod" << (long long)obj->activeLod(); if (obj->lodEvaluator()) *vlx << "LODEvaluator" << s.exportVLX(obj->lodEvaluator()); // shaders vl::ref lod_list = new VLXList; for(int i=0; obj->lod(i) && ilod(i).get()); *vlx << "Lods" << lod_list.get(); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Effect* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("effect_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportEffect(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Actor */ struct VLXClassWrapper_Actor: public ClassWrapper { void importActor(VLXSerializer& s, const VLXStructure* vlx, vl::Actor* obj) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) obj->setObjectName( name->getString() ); const std::vector& values = vlx->value(); for(size_t i=0; isetRenderRank( (int)value.getInteger() ); } else if (key == "RenderBlock") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ) obj->setRenderBlock( (int)value.getInteger() ); } else if (key == "EnableMask") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ) obj->setEnableMask( (int)value.getInteger() ); } else if (key == "IsOccludee") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value ) obj->setOccludee( value.getBool() ); } else if (key == "Enabled") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value ) obj->setEnabled( value.getBool() ); } else if (key == "Lods") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value ) const VLXList* list = value.getList(); for(size_t i=0; ivalue().size(); ++i) { const VLXValue& lod = list->value()[i]; VLX_IMPORT_CHECK_RETURN( lod.type() == VLXValue::Structure, lod ) vl::Renderable* rend = s.importVLX( lod.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( rend != NULL, lod ) obj->setLod(i, rend); } } else if (key == "Effect") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value ) vl::Effect* fx = s.importVLX(value.getStructure())->as(); VLX_IMPORT_CHECK_RETURN( fx != NULL, value ) obj->setEffect(fx); } else if (key == "Transform") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value ) vl::Transform* tr = s.importVLX(value.getStructure())->as(); VLX_IMPORT_CHECK_RETURN( tr != NULL, value ) obj->setTransform(tr); } else if (key == "Uniforms") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value ) const VLXList* list = value.getList(); for(size_t i=0; ivalue().size(); ++i) { VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure, list->value()[i] ) vl::Uniform* uniform = s.importVLX( list->value()[i].getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( uniform != NULL, list->value()[i] ) obj->setUniform(uniform); } } // bounding volumes are not serialized, they are computed based on the geometry's bounds // else if (key == "AABB") {} // else if (key == "Sphere") {} else if (key == "LODEvaluator") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value ) if (s.canImport( value.getStructure() ) ) { vl::LODEvaluator* lod = s.importVLX( value.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( lod != NULL, value ) obj->setLODEvaluator(lod); } } else if (key == "ActorEventCallbacks") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value ) const VLXList* list = value.getList(); for(size_t i=0; ivalue().size(); ++i) { const VLXValue& elem = list->value()[i]; VLX_IMPORT_CHECK_RETURN( elem.type() == VLXValue::Structure, elem ) if (s.canImport(elem.getStructure())) { vl::ActorEventCallback* cb = s.importVLX( elem.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( cb != NULL, elem ) obj->actorEventCallbacks()->push_back(cb); } } } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Actor; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importActor(s, vlx, obj.get()); return obj; } void exportActor(VLXSerializer& s, const vl::Actor* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); *vlx << "EnableMask" << (long long)obj->enableMask(); *vlx << "RenderBlock" << (long long)obj->renderBlock(); *vlx << "RenderRank" << (long long)obj->renderRank(); *vlx << "IsOccludee" << obj->isOccludee(); *vlx << "Enabled" << obj->isEnabled(); VLXValue renderables; renderables.setList( new VLXList ); for(size_t i=0; ilod(i); ++i) *renderables.getList() << s.exportVLX(obj->lod(i)); *vlx << "Lods" << renderables; // bounding volumes are not serialized, they are computed based on the geometry's bounds // *vlx << "AABB" << export_AABB(obj->boundingBox()); // *vlx << "Sphere" << export_Sphere(obj->boundingSphere()); if (obj->effect()) *vlx << "Effect" << s.exportVLX(obj->effect()); if (obj->transform()) *vlx << "Transform" << s.exportVLX(obj->transform()); VLXValue uniforms; uniforms.setList( new VLXList ); for(size_t i=0; obj->getUniformSet() && iuniforms().size(); ++i) *uniforms.getList() << s.exportVLX(obj->uniforms()[i].get()); *vlx << "Uniforms" << uniforms; if (obj->lodEvaluator()) *vlx << "LODEvaluator" << s.exportVLX(obj->lodEvaluator()); // mic fixme: // Scissor: scissors might go away from the vl::Actor VLXValue callbacks; callbacks.setList( new VLXList ); for(int i=0; iactorEventCallbacks()->size(); ++i) *callbacks.getList() << s.exportVLX(obj->actorEventCallbacks()->at(i)); *vlx << "ActorEventCallbacks" << callbacks; } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Actor* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("actor_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportActor(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Camera */ struct VLXClassWrapper_Camera: public ClassWrapper { void importCamera(VLXSerializer& s, const VLXStructure* vlx, vl::Camera* obj) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) obj->setObjectName( name->getString() ); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if (key == "ViewMatrix") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value); obj->setViewMatrix( vlx_mat4(value.getList()) ); // VLX_IMPORT_CHECK_RETURN( !obj->viewMatrix().isNull(), value ) } else if (key == "ProjectionMatrix") { vl::EProjectionMatrixType ptype = vl::PMT_UserProjection; const VLXValue* pmtype = vlx->getValue("ProjectionMatrixType"); if ( pmtype ) { VLX_IMPORT_CHECK_RETURN( pmtype->type() == VLXValue::Identifier, *pmtype ); ptype = vlx_EProjectionMatrixType( *pmtype, s ); } VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value); obj->setProjectionMatrix( vlx_mat4(value.getList()), ptype ); // VLX_IMPORT_CHECK_RETURN( !obj->projectionMatrix().isNull(), value ) } else if (key == "Viewport") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value) vl::Viewport* viewp = s.importVLX( value.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( viewp != NULL, value ) obj->setViewport(viewp); } else if (key == "FOV") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setFOV( (float)value.getReal() ); } else if (key == "NearPlane") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setNearPlane( (float)value.getReal() ); } else if (key == "FarPlane") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setFarPlane( (float)value.getReal() ); } else if (key == "Left") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setLeft( (float)value.getReal() ); } else if (key == "Right") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setRight( (float)value.getReal() ); } else if (key == "Bottom") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setBottom( (float)value.getReal() ); } else if (key == "Top") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setTop( (float)value.getReal() ); } else if (key == "BoundTransform") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value) vl::Transform* tr= s.importVLX( value.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( tr != NULL, value ) obj->bindTransform(tr); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Camera; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importCamera(s, vlx, obj.get()); return obj; } void exportCamera(VLXSerializer& s, const vl::Camera* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); *vlx << "ViewMatrix" << vlx_toValue(obj->viewMatrix()); *vlx << "ProjectionMatrix" << vlx_toValue(obj->projectionMatrix()); *vlx << "ProjectionMatrixType" << vlx_Identifier(vlx_EProjectionMatrixType(obj->projectionMatrixType())); *vlx << "Viewport" << s.exportVLX(obj->viewport()); *vlx << "NearPlane" << (double)obj->nearPlane(); *vlx << "FarPlane" << (double)obj->farPlane(); *vlx << "FOV" << (double)obj->fov(); *vlx << "Left" << (double)obj->left(); *vlx << "Right" << (double)obj->right(); *vlx << "Bottom" << (double)obj->bottom(); *vlx << "Top" << (double)obj->top(); if (obj->boundTransform()) *vlx << "BoundTransfrm" << s.exportVLX(obj->boundTransform()); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Camera* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("camera_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportCamera(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Viewport */ struct VLXClassWrapper_Viewport: public ClassWrapper { void importViewport(VLXSerializer& s, const VLXStructure* vlx, vl::Viewport* obj) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) obj->setObjectName( name->getString() ); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if (key == "ClearColor") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ); obj->setClearColor( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "ClearColorInt") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger, value ); obj->setClearColorInt( vlx_ivec4( value.getArrayInteger() ) ); } else if (key == "ClearColorUInt") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger, value ); obj->setClearColorUInt( vlx_uivec4( value.getArrayInteger() ) ); } else if (key == "ClearDepth") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ); obj->setClearDepth( (float)value.getReal() ); } else if (key == "ClearStecil") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ); obj->setClearStencil( (int)value.getInteger() ); } else if (key == "ClearColorMode") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setClearColorMode( vlx_EClearColorMode( value, s) ); } else if (key == "ClearFlags") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setClearFlags( vlx_EClearFlags( value, s ) ); } else if (key == "X") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ); obj->setX( (int)value.getInteger() ); } else if (key == "Y") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ); obj->setY( (int)value.getInteger() ); } else if (key == "Width") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ); obj->setWidth( (int)value.getInteger() ); } else if (key == "Height") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ); obj->setHeight( (int)value.getInteger() ); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Viewport; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importViewport(s, vlx, obj.get()); return obj; } void exportViewport(const vl::Viewport* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); *vlx << "ClearColor" << vlx_toValue((vl::vec4)obj->clearColor()); *vlx << "ClearColorInt" << vlx_toValue(obj->clearColorInt()); *vlx << "ClearColorUInt" << vlx_toValue(obj->clearColorUInt()); *vlx << "ClearDepth" << (double)obj->clearDepth(); *vlx << "ClearStecil" << (long long)obj->clearStencil(); *vlx << "ClearColorMode" << vlx_Identifier(vlx_EClearColorMode(obj->clearColorMode())); *vlx << "ClearFlags" << vlx_Identifier(vlx_EClearFlags(obj->clearFlags())); *vlx << "X" << (long long)obj->x(); *vlx << "Y" << (long long)obj->y(); *vlx << "Width" << (long long)obj->width(); *vlx << "Height" << (long long)obj->height(); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Viewport* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("viewport_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportViewport(cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Transform */ struct VLXClassWrapper_Transform: public ClassWrapper { void importTransform(VLXSerializer& s, const VLXStructure* vlx, vl::Transform* obj) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) obj->setObjectName( name->getString() ); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if (key == "LocalMatrix") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value ) obj->setLocalAndWorldMatrix( vlx_mat4( value.getList() ) ); } else // let the "Children" property take care of children binding /* if (key == "Parent") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value ) vl::Transform* tr = s.importVLX( value.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( tr != NULL, value ) tr->addChild(obj); } else */ if (key == "Children") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value ) const VLXList* list = value.getList(); for(size_t ich=0; ichvalue().size(); ++ich) { VLX_IMPORT_CHECK_RETURN( list->value()[ich].type() == VLXValue::Structure, list->value()[ich] ) const VLXStructure* vlx_tr = list->value()[ich].getStructure(); vl::Transform* child = s.importVLX( vlx_tr )->as(); VLX_IMPORT_CHECK_RETURN( child != NULL, *vlx_tr ) obj->addChild(child); } } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Transform; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importTransform(s, vlx, obj.get()); return obj; } void exportTransform(VLXSerializer& s, const vl::Transform* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); *vlx << "LocalMatrix" << vlx_toValue(obj->localMatrix()); // not needed /*if (obj->parent()) *vlx << "Parent" << s.exportVLX(obj->parent());*/ VLXValue childs; childs.setList( new VLXList ); for(size_t i=0; ichildrenCount(); ++i) childs.getList()->value().push_back( s.exportVLX(obj->children()[i].get()) ); *vlx << "Children" << childs; } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Transform* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("transform_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportTransform(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Light */ struct VLXClassWrapper_Light: public ClassWrapper { void importLight(VLXSerializer& s, const VLXStructure* vlx, vl::Light* obj) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) obj->setObjectName( name->getString() ); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if (key == "Ambient") { // note: what if the user specifies ( 1 0 0 0 ) -> becomes a ArrayInteger and an error is issued. VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ) obj->setAmbient( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "Diffuse") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ) obj->setDiffuse( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "Specular") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ) obj->setSpecular( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "Position") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ) obj->setPosition( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "SpotDirection") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ) obj->setSpotDirection( (vl::fvec3)vlx_vec3( value.getArrayReal() ) ); } else if (key == "SpotExponent") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setSpotExponent( (float)value.getReal() ); } else if (key == "SpotCutoff") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setSpotCutoff( (float)value.getReal() ); } else if (key == "ConstantAttenuation") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setConstantAttenuation( (float)value.getReal() ); } else if (key == "LinearAttenuation") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setLinearAttenuation( (float)value.getReal() ); } else if (key == "QuadraticAttenuation") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->setQuadraticAttenuation( (float)value.getReal() ); } else if (key == "BoundTransform") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value) vl::Transform* tr= s.importVLX( value.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( tr != NULL, value ) obj->bindTransform(tr); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Light; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importLight(s, vlx, obj.get()); return obj; } void exportLight(VLXSerializer& s, const vl::Light* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); *vlx << "Ambient" << vlx_toValue((vl::vec4)obj->ambient()); *vlx << "Diffuse" << vlx_toValue((vl::vec4)obj->diffuse()); *vlx << "Specular" << vlx_toValue((vl::vec4)obj->specular()); *vlx << "Position" << vlx_toValue((vl::vec4)obj->position()); *vlx << "SpotDirection" << vlx_toValue((vl::vec3)obj->spotDirection()); *vlx << "SpotExponent" << obj->spotExponent(); *vlx << "SpotCutoff" << obj->spotCutoff(); *vlx << "ConstantAttenuation" << obj->constantAttenuation(); *vlx << "LinearAttenuation" << obj->linearAttenuation(); *vlx << "QuadraticAttenuation" << obj->quadraticAttenuation(); if (obj->boundTransform()) *vlx << "BoundTransform" << s.exportVLX(obj->boundTransform()); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Light* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("light_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportLight(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::ClipPlane*/ struct VLXClassWrapper_ClipPlane: public ClassWrapper { void importClipPlane(VLXSerializer& s, const VLXStructure* vlx, vl::ClipPlane* obj) { for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if (key == "PlaneNormal") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ) obj->plane().setNormal( vlx_vec3( value.getArrayReal() ) ); } else if (key == "PlaneOrigin") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ) obj->plane().setOrigin( (float)value.getReal() ); } else if (key == "BoundTransform") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value) vl::Transform* tr= s.importVLX( value.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( tr != NULL, value ) obj->bindTransform(tr); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::ClipPlane; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importClipPlane(s, vlx, obj.get()); return obj; } void exportClipPlane(VLXSerializer& s, const vl::ClipPlane* clip, VLXStructure* vlx) { *vlx << "PlaneNormal" << vlx_toValue(clip->plane().normal()); *vlx << "PlaneOrigin" << clip->plane().origin(); if (clip->boundTransform()) *vlx << "BoundTransform" << s.exportVLX(clip->boundTransform()); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::ClipPlane* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("clipplane_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportClipPlane(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::GLSLProgram */ struct VLXClassWrapper_GLSLProgram: public ClassWrapper { void importGLSLProgram(VLXSerializer& s, const VLXStructure* vlx, vl::GLSLProgram* obj) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) obj->setObjectName( name->getString() ); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if (key == "AttachShader") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value ) const VLXStructure* st = value.getStructure(); vl::GLSLShader* glsl_sh = s.importVLX(st)->as(); VLX_IMPORT_CHECK_RETURN( glsl_sh != NULL, *st ) obj->attachShader(glsl_sh); } else if (key == "FragDataLocation") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value ) const VLXList* list = value.getList(); VLX_IMPORT_CHECK_RETURN( list->value().size() == 2, *list ) VLX_IMPORT_CHECK_RETURN( list->value()[0].type() == VLXValue::Identifier, *list ) VLX_IMPORT_CHECK_RETURN( list->value()[1].type() == VLXValue::Integer, *list ) const char* name = list->value()[0].getIdentifier().c_str(); int index = (int)list->value()[1].getInteger(); obj->bindFragDataLocation(index, name); } // MIC FIXME //else //if (key == "AttribLocation") //{ // VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value ) // const VLXList* list = value.getList(); // VLX_IMPORT_CHECK_RETURN( list->value().size() == 2, *list ) // VLX_IMPORT_CHECK_RETURN( list->value()[0].type() == VLXValue::Identifier, *list ) // VLX_IMPORT_CHECK_RETURN( list->value()[1].type() == VLXValue::Integer, *list ) // const char* name = list->value()[0].getIdentifier().c_str(); // int index = (int)list->value()[1].getInteger(); // obj->addAutoAttribLocation(index, name); //} else if (key == "Uniforms") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value ) const VLXList* list = value.getList(); for(size_t i=0; ivalue().size(); ++i) { VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure, list->value()[i] ) vl::Uniform* uniform = s.importVLX( list->value()[i].getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( uniform != NULL, list->value()[i] ) obj->setUniform(uniform); } } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::GLSLProgram; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importGLSLProgram(s, vlx, obj.get()); return obj; } void exportGLSLProgram(VLXSerializer& s, const vl::GLSLProgram* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); // export obj shaders for(int i=0; ishaderCount(); ++i) *vlx << "AttachShader" << s.exportVLX(obj->shader(i)); // export uniforms VLXValue uniforms; uniforms.setList( new VLXList ); for(size_t i=0; obj->getUniformSet() && igetUniformSet()->uniforms().size(); ++i) *uniforms.getList() << s.exportVLX(obj->getUniformSet()->uniforms()[i].get()); *vlx << "Uniforms" << uniforms; // frag data location for(std::map::const_iterator it = obj->fragDataLocations().begin(); it != obj->fragDataLocations().end(); ++it) { VLXList* location = new VLXList; *location << vlx_Identifier(it->first); // Name *location << (long long)it->second; // Location *vlx << "FragDataLocation" << location; } //// auto attrib locations // MIC FIXME //for(std::map::const_iterator it = obj->autoAttribLocations().begin(); it != obj->autoAttribLocations().end(); ++it) //{ // VLXList* location = new VLXList; // *location << vlx_Identifier(it->first); // Name // *location << (long long)it->second; // Location // *vlx << "AttribLocation" << location; //} } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::GLSLProgram* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("glslprog_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportGLSLProgram(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::GLSLVertexShader, vl::GLSLFragmentShader, vl::GLSLGeometryShader, vl::GLSLTessControlShader, vl::GLSLTessEvaluationShader. */ struct VLXClassWrapper_GLSLShader: public ClassWrapper { void importGLSLShader(VLXSerializer& s, const VLXStructure* vlx, vl::GLSLShader* obj) { const VLXValue* path = vlx->getValue("Path"); const VLXValue* source = vlx->getValue("Source"); VLX_IMPORT_CHECK_RETURN( path != NULL || source != NULL, *vlx ) if (path) { VLX_IMPORT_CHECK_RETURN( path->type() == VLXValue::String, *path ) std::string resolved_path = path->getString(); s.resolvePath(resolved_path); obj->setSource(resolved_path.c_str()); // this automatically loads the source and sets the path } else if (source) { VLX_IMPORT_CHECK_RETURN( source->type() == VLXValue::RawtextBlock, *source ) obj->setSource(source->getRawtextBlock()->value().c_str()); } else { vl::Log::warning( vl::Say("Line %n : no source or path specified for glsl shader.\n") << vlx->lineNumber() ); } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = NULL; if (vlx->tag() == "") obj = new vl::GLSLVertexShader; else if (vlx->tag() == "") obj = new vl::GLSLFragmentShader; else if (vlx->tag() == "") obj = new vl::GLSLGeometryShader; else if (vlx->tag() == "") obj = new vl::GLSLTessControlShader; else if (vlx->tag() == "") obj = new vl::GLSLTessEvaluationShader; else { s.signalImportError( vl::Say("Line %n : shader type '%s' not supported.\n") << vlx->tag() ); return NULL; } // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importGLSLShader(s, vlx, obj.get()); return obj; } void exportGLSLShader(const vl::GLSLShader* glslsh, VLXStructure* vlx) { if (!glslsh->path().empty()) *vlx << "Path" << vlx_String(glslsh->path().toStdString()); else if (!glslsh->source().empty()) *vlx << "Source" << vlx_Rawtext(glslsh->source()); else if (glslsh->handle()) *vlx << "Source" << vlx_Rawtext(glslsh->getShaderSource()); else *vlx << "Source" << vlx_Identifier("NO_SOURCE_FOUND"); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::GLSLShader* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("glslsh_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportGLSLShader(cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::VertexAttrib */ struct VLXClassWrapper_VertexAttrib: public ClassWrapper { void importVertexAttrib(VLXSerializer& s, const VLXStructure* vlx, vl::VertexAttrib* obj) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) obj->setObjectName( name->getString() ); const VLXValue* value = vlx->getValue("Value"); VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value ) obj->setValue( (vl::fvec4)vlx_vec4( value->getArrayReal() ) ); } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::VertexAttrib; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importVertexAttrib(s, vlx, obj.get()); return obj; } void exportVertexAttrib(const vl::VertexAttrib* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); *vlx << "Value" << vlx_toValue((vl::vec4)obj->value()); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::VertexAttrib* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("vertexattrib_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportVertexAttrib(cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Color */ struct VLXClassWrapper_Color: public ClassWrapper { void importColor(VLXSerializer& s, const VLXStructure* vlx, vl::Color* obj) { const VLXValue* value = vlx->getValue("Value"); VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value ) obj->setValue( (vl::fvec4)vlx_vec4( value->getArrayReal() ) ); } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Color; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importColor(s, vlx, obj.get()); return obj; } void exportColor(const vl::Color* obj, VLXStructure* vlx) { *vlx << "Value" << vlx_toValue((vl::vec4)obj->value()); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Color* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("color_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportColor(cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::SecondaryColor */ struct VLXClassWrapper_SecondaryColor: public ClassWrapper { void importSecondaryColor(VLXSerializer& s, const VLXStructure* vlx, vl::SecondaryColor* obj) { const VLXValue* value = vlx->getValue("Value"); VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value ) obj->setValue( (vl::fvec3)vlx_vec3( value->getArrayReal() ) ); } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::SecondaryColor; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importSecondaryColor(s, vlx, obj.get()); return obj; } void exportSecondaryColor(const vl::SecondaryColor* obj, VLXStructure* vlx) { *vlx << "Value" << vlx_toValue((vl::vec3)obj->value()); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::SecondaryColor* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("seccolor_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportSecondaryColor(cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Normal */ struct VLXClassWrapper_Normal: public ClassWrapper { void importNormal(VLXSerializer& s, const VLXStructure* vlx, vl::Normal* obj) { const VLXValue* value = vlx->getValue("Value"); VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value ) obj->setValue( (vl::fvec3)vlx_vec3( value->getArrayReal() ) ); } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Normal; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importNormal(s, vlx, obj.get()); return obj; } void exportNormal(const vl::Normal* obj, VLXStructure* vlx) { *vlx << "Value" << vlx_toValue((vl::vec3)obj->value()); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Normal* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("normal_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportNormal(cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Material */ struct VLXClassWrapper_Material: public ClassWrapper { void importMaterial(VLXSerializer& s, const VLXStructure* vlx, vl::Material* obj) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) obj->setObjectName( name->getString() ); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if (key == "FrontAmbient") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ); obj->setFrontAmbient( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "FrontDiffuse") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ); obj->setFrontDiffuse( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "FrontEmission") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ); obj->setFrontEmission( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "FrontSpecular") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ); obj->setFrontSpecular( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "FrontShininess") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ); obj->setFrontShininess( (float)value.getReal() ); } else if (key == "BackAmbient") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ); obj->setBackAmbient( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "BackDiffuse") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ); obj->setBackDiffuse( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "BackEmission") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ); obj->setBackEmission( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "BackSpecular") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ); obj->setBackSpecular( (vl::fvec4)vlx_vec4( value.getArrayReal() ) ); } else if (key == "BackShininess") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ); obj->setBackShininess( (float)value.getReal() ); } else if (key == "ColorMaterialEnabled") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value ); obj->setColorMaterialEnabled( value.getBool() ); } } vl::EColorMaterial col_mat = vl::CM_AMBIENT_AND_DIFFUSE; const VLXValue* vlx_col_mat = vlx->getValue("ColorMaterial"); if (vlx_col_mat) { VLX_IMPORT_CHECK_RETURN( vlx_col_mat->type() == VLXValue::Identifier, *vlx_col_mat ); col_mat = vlx_EColorMaterial( *vlx_col_mat, s ); } vl::EPolygonFace poly_face = vl::PF_FRONT_AND_BACK; const VLXValue* vlx_poly_mat = vlx->getValue("ColorMaterialFace"); if (vlx_poly_mat) { VLX_IMPORT_CHECK_RETURN( vlx_poly_mat->type() == VLXValue::Identifier, *vlx_poly_mat ); poly_face = vlx_EPolygonFace( *vlx_poly_mat, s ); } obj->setColorMaterial( poly_face, col_mat ); } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Material; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importMaterial(s, vlx, obj.get()); return obj; } void exportMaterial(const vl::Material* obj, VLXStructure* vlx) { if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); *vlx << "FrontAmbient" << vlx_toValue((vl::vec4)obj->frontAmbient()); *vlx << "FrontDiffuse" << vlx_toValue((vl::vec4)obj->frontDiffuse()); *vlx << "FrontEmission" << vlx_toValue((vl::vec4)obj->frontEmission()); *vlx << "FrontSpecular" << vlx_toValue((vl::vec4)obj->frontSpecular()); *vlx << "FrontShininess" << (double)obj->frontShininess(); *vlx << "BackAmbient" << vlx_toValue((vl::vec4)obj->backAmbient()); *vlx << "BackDiffuse" << vlx_toValue((vl::vec4)obj->backDiffuse()); *vlx << "BackEmission" << vlx_toValue((vl::vec4)obj->backEmission()); *vlx << "BackSpecular" << vlx_toValue((vl::vec4)obj->backSpecular()); *vlx << "BackShininess" << (double)obj->backShininess(); *vlx << "ColorMaterial" << vlx_Identifier(vlx_EColorMaterial(obj->colorMaterial())); *vlx << "ColorMaterialFace" << vlx_Identifier(vlx_EPolygonFace(obj->colorMaterialFace())); *vlx << "ColorMaterialEnabled" << obj->colorMaterialEnabled(); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Material* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("material_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportMaterial(cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::DepthSortCallback */ struct VLXClassWrapper_ActorEventCallback: public ClassWrapper { void importActorEventCallback(VLXSerializer& s, const VLXStructure* vlx, vl::ActorEventCallback* obj) { if (obj->isOfType(vl::DepthSortCallback::Type())) { const VLXValue* vlx_sm = vlx->getValue("SortMode"); VLX_IMPORT_CHECK_RETURN( vlx_sm->type() == VLXValue::Identifier, *vlx_sm ) if (vlx_sm) { vl::ESortMode sm = vl::SM_SortBackToFront; if ( vlx_sm->getIdentifier() == "SM_SortBackToFront" ) sm = vl::SM_SortBackToFront; else if ( vlx_sm->getIdentifier() == "SM_SortFrontToBack" ) sm = vl::SM_SortFrontToBack; else s.signalImportError( vl::Say("Line %n : unknown sort mode '%s'.\n") << vlx_sm->lineNumber() << vlx_sm->getIdentifier() ); obj->as()->setSortMode(sm); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = NULL; if (vlx->tag() == "") obj = new vl::DepthSortCallback; else { s.signalImportError( vl::Say("Line %n : ActorEventCallback type not supported for import.\n") << vlx->lineNumber() ); return NULL; } // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importActorEventCallback(s, vlx, obj.get()); return obj; } void exportActorEventCallback(VLXSerializer& s, const vl::ActorEventCallback* cb, VLXStructure* vlx) { if (cb->classType() == vl::DepthSortCallback::Type()) { const vl::DepthSortCallback* dsc = cb->as(); if (dsc->sortMode() == vl::SM_SortBackToFront) *vlx << "SortMode" << vlx_Identifier("SM_SortBackToFront"); else *vlx << "SortMode" << vlx_Identifier("SM_SortFrontToBack"); } else { s.signalExportError("ActorEventCallback type not supported for export.\n"); } } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::ActorEventCallback* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("actorcallback_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportActorEventCallback(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::Texture */ struct VLXClassWrapper_Texture: public ClassWrapper { void importTexture(VLXSerializer& s, const VLXStructure* vlx, vl::Texture* obj) { const VLXValue* name = vlx->getValue("ObjectName"); if (name) obj->setObjectName( name->getString() ); obj->setSetupParams( new vl::Texture::SetupParams ); for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if (key == "Dimension") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setupParams()->setDimension( vlx_ETextureDimension( value, s ) ); } else if (key == "TexParameter") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value ); vl::TexParameter* tex_param = s.importVLX( value.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( tex_param != NULL, value ); // copy the content over *obj->getTexParameter() = *tex_param; } else if (key == "ImagePath") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::String, value ); std::string resolved_path = value.getString(); s.resolvePath( resolved_path ); obj->setupParams()->setImagePath( resolved_path.c_str() ); } else if (key == "Format") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setupParams()->setFormat( vlx_ETextureFormat( value, s ) ); } else if (key == "Width") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ); obj->setupParams()->setWidth( (int)value.getInteger() ); } else if (key == "Height") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ); obj->setupParams()->setHeight( (int)value.getInteger() ); } else if (key == "Depth") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ); obj->setupParams()->setDepth( (int)value.getInteger() ); } else if (key == "GenMipmaps") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value ); obj->setupParams()->setGenMipmaps( (int)value.getBool() ); } else if (key == "BufferObject") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value ); vl::BufferObject* buf_obj = s.importVLX( value.getStructure() )->as(); VLX_IMPORT_CHECK_RETURN( buf_obj, value ); obj->setupParams()->setBufferObject( buf_obj ); } else if (key == "Samples") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value ); obj->setupParams()->setSamples( (int)value.getInteger() ); } else if (key == "FixedSamplesLocations") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value ); obj->setupParams()->setFixedSamplesLocations( (int)value.getBool() ); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::Texture; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importTexture(s, vlx, obj.get()); return obj; } void exportTexture(VLXSerializer& s, const vl::Texture* obj, VLXStructure* vlx) { // mic fixme: // - we should allow patterns such as initializing a texture from an image filled by a shader or procedure. // - we should allow avoid loading twice the same image or shader source or any externa resource etc. time for a resource manager? if (!obj->objectName().empty() && obj->objectName() != obj->className()) *vlx << "ObjectName" << vlx_String(obj->objectName()); if (obj->getTexParameter()) *vlx << "TexParameter" << s.exportVLX(obj->getTexParameter()); if (obj->setupParams()) { const vl::Texture::SetupParams* par = obj->setupParams(); if (par) { *vlx << "Dimension" << vlx_Identifier(vlx_ETextureDimension(par->dimension())); *vlx << "Format" << vlx_Identifier(vlx_ETextureFormat(par->format())); if (!par->imagePath().empty()) *vlx << "ImagePath" << vlx_String(par->imagePath().toStdString()); else if (par->image()) *vlx << "ImagePath" << vlx_String(par->image()->filePath().toStdString()); if (par->width()) *vlx << "Width" << (long long)par->width(); if (par->height()) *vlx << "Height" << (long long)par->height(); if (par->depth()) *vlx << "Depth" << (long long)par->depth(); *vlx << "GenMipmaps" << par->genMipmaps(); // mic fixme: implement BufferObject importer/exporter #if 0 if (par->bufferObject()) { *vlx << "BufferObject" << s.exportVLX(par->bufferObject()); } #endif if(par->samples()) { *vlx << "Samples" << (long long)par->samples(); *vlx << "FixedSamplesLocations" << par->fixedSamplesLocations(); } } } } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::Texture* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("texture_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportTexture(s, cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::TexParameter */ struct VLXClassWrapper_TexParameter: public ClassWrapper { void importTexParameter(VLXSerializer& s, const VLXStructure* vlx, vl::TexParameter* obj) { for(size_t i=0; ivalue().size(); ++i) { const std::string& key = vlx->value()[i].key(); const VLXValue& value = vlx->value()[i].value(); if (key == "MinFilter") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setMinFilter( vlx_ETexParamFilter( value, s ) ); } else if (key == "MagFilter") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setMagFilter( vlx_ETexParamFilter( value, s ) ); } else if (key == "WrapS") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setWrapS( vlx_ETexParamWrap( value, s ) ); } else if (key == "WrapT") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setWrapT( vlx_ETexParamWrap( value, s ) ); } else if (key == "WrapR") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setWrapR( vlx_ETexParamWrap( value, s ) ); } else if (key == "CompareMode") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setCompareMode( vlx_ETexCompareMode( value, s ) ); } else if (key == "CompareFunc") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setCompareFunc( vlx_ETexCompareFunc( value, s ) ); } else if (key == "DepthTextureMode") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value ); obj->setDepthTextureMode( vlx_EDepthTextureMode( value, s ) ); } else if (key == "BorderColor") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value ); obj->setBorderColor( (vl::fvec4)vlx_vec4(value.getArrayReal()) ); } else if (key == "Anisotropy") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value ); obj->setAnisotropy( (float)value.getReal() ); } else if (key == "GenerateMipmap") { VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value ); obj->setGenerateMipmap( value.getBool() ); } } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::TexParameter; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importTexParameter(s, vlx, obj.get()); return obj; } void exportTexParameter(const vl::TexParameter* texparam, VLXStructure* vlx) { *vlx << "MinFilter" << vlx_Identifier(vlx_ETexParamFilter(texparam->minFilter())); *vlx << "MagFilter" << vlx_Identifier(vlx_ETexParamFilter(texparam->magFilter())); *vlx << "WrapS" << vlx_Identifier(vlx_ETexParamWrap(texparam->wrapS())); *vlx << "WrapT" << vlx_Identifier(vlx_ETexParamWrap(texparam->wrapT())); *vlx << "WrapR" << vlx_Identifier(vlx_ETexParamWrap(texparam->wrapR())); *vlx << "CompareMode" << vlx_Identifier(vlx_ETexCompareMode(texparam->compareMode())); *vlx << "CompareFunc" << vlx_Identifier(vlx_ETexCompareFunc(texparam->compareFunc())); *vlx << "DepthTextureMode" << vlx_Identifier(vlx_EDepthTextureMode(texparam->depthTextureMode())); *vlx << "BorderColor" << vlx_toValue((vl::vec4)texparam->borderColor()); *vlx << "Anisotropy" << texparam->anisotropy(); *vlx << "GenerateMipmap" << texparam->generateMipmap(); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::TexParameter* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("texparam_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportTexParameter(cast_obj, vlx.get()); return vlx; } }; //--------------------------------------------------------------------------- /** VLX wrapper of vl::TextureSampler */ struct VLXClassWrapper_TextureSampler: public ClassWrapper { void importTextureSampler(VLXSerializer& s, const VLXStructure* vlx, vl::TextureSampler* obj) { const VLXValue* vlx_texture = vlx->getValue("Texture"); if (vlx_texture) { VLX_IMPORT_CHECK_RETURN(vlx_texture->type() == VLXValue::Structure, *vlx_texture); vl::Texture* texture = s.importVLX(vlx_texture->getStructure())->as(); VLX_IMPORT_CHECK_RETURN( texture != NULL , *vlx_texture); obj->setTexture(texture); } } virtual vl::ref importVLX(VLXSerializer& s, const VLXStructure* vlx) { vl::ref obj = new vl::TextureSampler; // register imported structure asap s.registerImportedStructure(vlx, obj.get()); importTextureSampler(s, vlx, obj.get()); return obj; } void exportTextureSampler(VLXSerializer& s, const vl::TextureSampler* tex_sampler, VLXStructure* vlx) { if (tex_sampler->texture()) *vlx << "Texture" << s.exportVLX(tex_sampler->texture()); } virtual vl::ref exportVLX(VLXSerializer& s, const vl::Object* obj) { const vl::TextureSampler* cast_obj = obj->as(); VL_CHECK(cast_obj) vl::ref vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("texsampler_")); // register exported object asap s.registerExportedObject(obj, vlx.get()); exportTextureSampler(s, cast_obj, vlx.get()); return vlx; } }; } #endif