Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/VLXWrappers.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #ifndef VLXWrapper_Graphics_INCLUDE_ONCE
00033 #define VLXWrapper_Graphics_INCLUDE_ONCE
00034 
00035 #include <vlCore/VLXWrappers.hpp>
00036 #include <vlCore/LoadWriterManager.hpp>
00037 #include <vlGraphics/Actor.hpp>
00038 #include <vlGraphics/Effect.hpp>
00039 #include <vlGraphics/Shader.hpp>
00040 #include <vlGraphics/Geometry.hpp>
00041 #include <vlGraphics/Light.hpp>
00042 #include <vlGraphics/ClipPlane.hpp>
00043 #include <vlGraphics/Camera.hpp>
00044 #include <vlGraphics/DrawElements.hpp>
00045 #include <vlGraphics/MultiDrawElements.hpp>
00046 #include <vlGraphics/DrawArrays.hpp>
00047 #include <vlGraphics/SceneManagerActorTree.hpp>
00048 #include <vlGraphics/DistanceLODEvaluator.hpp>
00049 #include <vlGraphics/PixelLODEvaluator.hpp>
00050 #include <vlGraphics/DepthSortCallback.hpp>
00051 #include <vlGraphics/GLSL.hpp>
00052 #include <vlCore/ResourceDatabase.hpp>
00053 #include <vlCore/DiskFile.hpp>
00054 
00055 namespace vl
00056 {
00058   struct VLXClassWrapper_Array: public VLXClassWrapper
00059   {
00060     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
00061     {
00062       if (!vlx->getValue("Value"))
00063       {
00064         Log::error( Say("Line %n : error. 'Value' expected in object '%s'. \n") << vlx->lineNumber() << vlx->tag() );
00065         return NULL;
00066       }
00067 
00068       const VLXValue& value = *vlx->getValue("Value");
00069 
00070       ref<ArrayAbstract> arr_abstract;
00071 
00072       if (vlx->tag() == "<vl::ArrayFloat1>")
00073       {
00074         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
00075         const VLXArrayReal* vlx_arr_float = value.getArrayReal();
00076         ref<ArrayFloat1> arr_float1 = new ArrayFloat1; arr_abstract = arr_float1;
00077         arr_float1->resize( vlx_arr_float->value().size() );
00078         vlx_arr_float->copyTo((float*)arr_float1->ptr());
00079       }
00080       else
00081       if (vlx->tag() == "<vl::ArrayFloat2>")
00082       {
00083         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
00084         const VLXArrayReal* vlx_arr_float = value.getArrayReal();
00085         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_float->value().size() % 2 == 0, value)
00086         ref<ArrayFloat2> arr_float2 = new ArrayFloat2; arr_abstract = arr_float2;
00087         arr_float2->resize( vlx_arr_float->value().size() / 2 );
00088         vlx_arr_float->copyTo((float*)arr_float2->ptr());
00089       }
00090       else
00091       if (vlx->tag() == "<vl::ArrayFloat3>")
00092       {
00093         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
00094         const VLXArrayReal* vlx_arr_float = value.getArrayReal();
00095         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_float->value().size() % 3 == 0, value)
00096         ref<ArrayFloat3> arr_float3 = new ArrayFloat3; arr_abstract = arr_float3;
00097         arr_float3->resize( vlx_arr_float->value().size() / 3 );
00098         vlx_arr_float->copyTo((float*)arr_float3->ptr());
00099       }
00100       else
00101       if (vlx->tag() == "<vl::ArrayFloat4>")
00102       {
00103         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
00104         const VLXArrayReal* vlx_arr_float = value.getArrayReal();
00105         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_float->value().size() % 4 == 0, value)
00106         ref<ArrayFloat4> arr_float4 = new ArrayFloat4; arr_abstract = arr_float4;
00107         arr_float4->resize( vlx_arr_float->value().size() / 4 );
00108         vlx_arr_float->copyTo((float*)arr_float4->ptr());
00109       }
00110       else
00111       if (vlx->tag() == "<vl::ArrayDouble1>")
00112       {
00113         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
00114         const VLXArrayReal* vlx_arr_floating = value.getArrayReal();
00115         ref<ArrayDouble1> arr_floating1 = new ArrayDouble1; arr_abstract = arr_floating1;
00116         arr_floating1->resize( vlx_arr_floating->value().size() );
00117         vlx_arr_floating->copyTo((double*)arr_floating1->ptr());
00118       }
00119       else
00120       if (vlx->tag() == "<vl::ArrayDouble2>")
00121       {
00122         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
00123         const VLXArrayReal* vlx_arr_floating = value.getArrayReal();
00124         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_floating->value().size() % 2 == 0, value)
00125         ref<ArrayDouble2> arr_floating2 = new ArrayDouble2; arr_abstract = arr_floating2;
00126         arr_floating2->resize( vlx_arr_floating->value().size() / 2 );
00127         vlx_arr_floating->copyTo((double*)arr_floating2->ptr());
00128       }
00129       else
00130       if (vlx->tag() == "<vl::ArrayDouble3>")
00131       {
00132         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
00133         const VLXArrayReal* vlx_arr_floating = value.getArrayReal();
00134         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_floating->value().size() % 3 == 0, value)
00135         ref<ArrayDouble3> arr_floating3 = new ArrayDouble3; arr_abstract = arr_floating3;
00136         arr_floating3->resize( vlx_arr_floating->value().size() / 3 );
00137         vlx_arr_floating->copyTo((double*)arr_floating3->ptr());
00138       }
00139       else
00140       if (vlx->tag() == "<vl::ArrayDouble4>")
00141       {
00142         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
00143         const VLXArrayReal* vlx_arr_floating = value.getArrayReal();
00144         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_floating->value().size() % 4 == 0, value)
00145         ref<ArrayDouble4> arr_floating4 = new ArrayDouble4; arr_abstract = arr_floating4;
00146         arr_floating4->resize( vlx_arr_floating->value().size() / 4 );
00147         vlx_arr_floating->copyTo((double*)arr_floating4->ptr());
00148       }
00149       else
00150       if (vlx->tag() == "<vl::ArrayInt1>")
00151       {
00152         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00153         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00154         ref<ArrayInt1> arr_int1 = new ArrayInt1; arr_abstract = arr_int1;
00155         arr_int1->resize( vlx_arr_int->value().size() );
00156         vlx_arr_int->copyTo((int*)arr_int1->ptr());
00157       }
00158       else
00159       if (vlx->tag() == "<vl::ArrayInt2>")
00160       {
00161         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00162         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00163         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
00164         ref<ArrayInt2> arr_int2 = new ArrayInt2; arr_abstract = arr_int2;
00165         arr_int2->resize( vlx_arr_int->value().size() / 2 );
00166         vlx_arr_int->copyTo((int*)arr_int2->ptr());
00167       }
00168       else
00169       if (vlx->tag() == "<vl::ArrayInt3>")
00170       {
00171         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00172         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00173         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
00174         ref<ArrayInt3> arr_int3 = new ArrayInt3; arr_abstract = arr_int3;
00175         arr_int3->resize( vlx_arr_int->value().size() / 3 );
00176         vlx_arr_int->copyTo((int*)arr_int3->ptr());
00177       }
00178       else
00179       if (vlx->tag() == "<vl::ArrayInt4>")
00180       {
00181         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00182         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00183         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
00184         ref<ArrayInt4> arr_int4 = new ArrayInt4; arr_abstract = arr_int4;
00185         arr_int4->resize( vlx_arr_int->value().size() / 4 );
00186         vlx_arr_int->copyTo((int*)arr_int4->ptr());
00187       }
00188       else
00189       if (vlx->tag() == "<vl::ArrayUInt1>")
00190       {
00191         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00192         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00193         ref<ArrayUInt1> arr_int1 = new ArrayUInt1; arr_abstract = arr_int1;
00194         arr_int1->resize( vlx_arr_int->value().size() );
00195         vlx_arr_int->copyTo((unsigned int*)arr_int1->ptr());
00196       }
00197       else
00198       if (vlx->tag() == "<vl::ArrayUInt2>")
00199       {
00200         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00201         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00202         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
00203         ref<ArrayUInt2> arr_int2 = new ArrayUInt2; arr_abstract = arr_int2;
00204         arr_int2->resize( vlx_arr_int->value().size() / 2 );
00205         vlx_arr_int->copyTo((unsigned int*)arr_int2->ptr());
00206       }
00207       else
00208       if (vlx->tag() == "<vl::ArrayUInt3>")
00209       {
00210         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00211         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00212         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
00213         ref<ArrayUInt3> arr_int3 = new ArrayUInt3; arr_abstract = arr_int3;
00214         arr_int3->resize( vlx_arr_int->value().size() / 3 );
00215         vlx_arr_int->copyTo((unsigned int*)arr_int3->ptr());
00216       }
00217       else
00218       if (vlx->tag() == "<vl::ArrayUInt4>")
00219       {
00220         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00221         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00222         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
00223         ref<ArrayUInt4> arr_int4 = new ArrayUInt4; arr_abstract = arr_int4;
00224         arr_int4->resize( vlx_arr_int->value().size() / 4 );
00225         vlx_arr_int->copyTo((unsigned int*)arr_int4->ptr());
00226       }
00227       else
00228       if (vlx->tag() == "<vl::ArrayShort1>")
00229       {
00230         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00231         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00232         ref<ArrayShort1> arr_short1 = new ArrayShort1; arr_abstract = arr_short1;
00233         arr_short1->resize( vlx_arr_int->value().size() );
00234         vlx_arr_int->copyTo((short*)arr_short1->ptr());
00235       }
00236       else
00237       if (vlx->tag() == "<vl::ArrayShort2>")
00238       {
00239         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00240         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00241         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
00242         ref<ArrayShort2> arr_short2 = new ArrayShort2; arr_abstract = arr_short2;
00243         arr_short2->resize( vlx_arr_int->value().size() / 2 );
00244         vlx_arr_int->copyTo((short*)arr_short2->ptr());
00245       }
00246       else
00247       if (vlx->tag() == "<vl::ArrayShort3>")
00248       {
00249         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00250         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00251         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
00252         ref<ArrayShort3> arr_short3 = new ArrayShort3; arr_abstract = arr_short3;
00253         arr_short3->resize( vlx_arr_int->value().size() / 3 );
00254         vlx_arr_int->copyTo((short*)arr_short3->ptr());
00255       }
00256       else
00257       if (vlx->tag() == "<vl::ArrayShort4>")
00258       {
00259         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00260         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00261         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
00262         ref<ArrayShort4> arr_short4 = new ArrayShort4; arr_abstract = arr_short4;
00263         arr_short4->resize( vlx_arr_int->value().size() / 4 );
00264         vlx_arr_int->copyTo((short*)arr_short4->ptr());
00265       }
00266       else
00267       if (vlx->tag() == "<vl::ArrayUShort1>")
00268       {
00269         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00270         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00271         ref<ArrayUShort1> arr_short1 = new ArrayUShort1; arr_abstract = arr_short1;
00272         arr_short1->resize( vlx_arr_int->value().size() );
00273         vlx_arr_int->copyTo((unsigned short*)arr_short1->ptr());
00274       }
00275       else
00276       if (vlx->tag() == "<vl::ArrayUShort2>")
00277       {
00278         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00279         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00280         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
00281         ref<ArrayUShort2> arr_short2 = new ArrayUShort2; arr_abstract = arr_short2;
00282         arr_short2->resize( vlx_arr_int->value().size() / 2 );
00283         vlx_arr_int->copyTo((unsigned short*)arr_short2->ptr());
00284       }
00285       else
00286       if (vlx->tag() == "<vl::ArrayUShort3>")
00287       {
00288         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00289         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00290         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
00291         ref<ArrayUShort3> arr_short3 = new ArrayUShort3; arr_abstract = arr_short3;
00292         arr_short3->resize( vlx_arr_int->value().size() / 3 );
00293         vlx_arr_int->copyTo((unsigned short*)arr_short3->ptr());
00294       }
00295       else
00296       if (vlx->tag() == "<vl::ArrayUShort4>")
00297       {
00298         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00299         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00300         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
00301         ref<ArrayUShort4> arr_short4 = new ArrayUShort4; arr_abstract = arr_short4;
00302         arr_short4->resize( vlx_arr_int->value().size() / 4 );
00303         vlx_arr_int->copyTo((unsigned short*)arr_short4->ptr());
00304       }
00305       else
00306       if (vlx->tag() == "<vl::ArrayByte1>")
00307       {
00308         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00309         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00310         ref<ArrayByte1> arr_byte1 = new ArrayByte1; arr_abstract = arr_byte1;
00311         arr_byte1->resize( vlx_arr_int->value().size() );
00312         vlx_arr_int->copyTo((char*)arr_byte1->ptr());
00313       }
00314       else
00315       if (vlx->tag() == "<vl::ArrayByte2>")
00316       {
00317         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00318         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00319         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
00320         ref<ArrayByte2> arr_byte2 = new ArrayByte2; arr_abstract = arr_byte2;
00321         arr_byte2->resize( vlx_arr_int->value().size() / 2 );
00322         vlx_arr_int->copyTo((char*)arr_byte2->ptr());
00323       }
00324       else
00325       if (vlx->tag() == "<vl::ArrayByte3>")
00326       {
00327         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00328         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00329         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
00330         ref<ArrayByte3> arr_byte3 = new ArrayByte3; arr_abstract = arr_byte3;
00331         arr_byte3->resize( vlx_arr_int->value().size() / 3 );
00332         vlx_arr_int->copyTo((char*)arr_byte3->ptr());
00333       }
00334       else
00335       if (vlx->tag() == "<vl::ArrayByte4>")
00336       {
00337         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00338         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00339         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
00340         ref<ArrayByte4> arr_byte4 = new ArrayByte4; arr_abstract = arr_byte4;
00341         arr_byte4->resize( vlx_arr_int->value().size() / 4 );
00342         vlx_arr_int->copyTo((char*)arr_byte4->ptr());
00343       }
00344       else
00345       if (vlx->tag() == "<vl::ArrayUByte1>")
00346       {
00347         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00348         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00349         ref<ArrayUByte1> arr_byte1 = new ArrayUByte1; arr_abstract = arr_byte1;
00350         arr_byte1->resize( vlx_arr_int->value().size() );
00351         vlx_arr_int->copyTo((unsigned char*)arr_byte1->ptr());
00352       }
00353       else
00354       if (vlx->tag() == "<vl::ArrayUByte2>")
00355       {
00356         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00357         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00358         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
00359         ref<ArrayUByte2> arr_byte2 = new ArrayUByte2; arr_abstract = arr_byte2;
00360         arr_byte2->resize( vlx_arr_int->value().size() / 2 );
00361         vlx_arr_int->copyTo((unsigned char*)arr_byte2->ptr());
00362       }
00363       else
00364       if (vlx->tag() == "<vl::ArrayUByte3>")
00365       {
00366         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00367         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00368         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
00369         ref<ArrayUByte3> arr_byte3 = new ArrayUByte3; arr_abstract = arr_byte3;
00370         arr_byte3->resize( vlx_arr_int->value().size() / 3 );
00371         vlx_arr_int->copyTo((unsigned char*)arr_byte3->ptr());
00372       }
00373       else
00374       if (vlx->tag() == "<vl::ArrayUByte4>")
00375       {
00376         VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
00377         const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
00378         VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
00379         ref<ArrayUByte4> arr_byte4 = new ArrayUByte4; arr_abstract = arr_byte4;
00380         arr_byte4->resize( vlx_arr_int->value().size() / 4 );
00381         vlx_arr_int->copyTo((unsigned char*)arr_byte4->ptr());
00382       }
00383       else
00384       {
00385         s.signalImportError(Say("Line %n : unknown array '%s'.\n") << vlx->lineNumber() << vlx->tag() );
00386       }
00387 
00388       // register imported structure asap
00389       s.registerImportedStructure(vlx, arr_abstract.get());
00390       return arr_abstract.get();
00391     }
00392 
00393     template<typename T_Array, typename T_VLXArray>
00394     ref<VLXStructure> export_ArrayT(VLXSerializer& s, const Object* arr_abstract)
00395     {
00396       const T_Array* arr = arr_abstract->as<T_Array>();
00397       ref<VLXStructure> st =new VLXStructure(vlx_makeTag(arr_abstract).c_str(), s.generateID("array_"));
00398       ref<T_VLXArray> vlx_array = new T_VLXArray;
00399       if (arr->size())
00400       {
00401         vlx_array->value().resize( arr->size() * arr->glSize() );
00402         typename T_VLXArray::scalar_type* dst = &vlx_array->value()[0];
00403         const typename T_Array::scalar_type* src = (const typename T_Array::scalar_type*)arr->begin();
00404         const typename T_Array::scalar_type* end = (const typename T_Array::scalar_type*)arr->end();
00405         for(; src<end; ++src, ++dst)
00406           *dst = (typename T_VLXArray::scalar_type)*src;
00407       }
00408       st->value().push_back( VLXStructure::Value("Value", vlx_array.get() ) );
00409       return st;
00410     }
00411 
00412     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
00413     {
00414       ref<VLXStructure> vlx;
00415       if(obj->classType() == ArrayUInt1::Type())
00416         vlx = export_ArrayT<ArrayUInt1, VLXArrayInteger>(s, obj);
00417       else
00418       if(obj->classType() == ArrayUInt2::Type())
00419         vlx = export_ArrayT<ArrayUInt2, VLXArrayInteger>(s, obj);
00420       else
00421       if(obj->classType() == ArrayUInt3::Type())
00422         vlx = export_ArrayT<ArrayUInt3, VLXArrayInteger>(s, obj);
00423       else
00424       if(obj->classType() == ArrayUInt4::Type())
00425         vlx = export_ArrayT<ArrayUInt4, VLXArrayInteger>(s, obj);
00426       else
00427 
00428       if(obj->classType() == ArrayInt1::Type())
00429         vlx = export_ArrayT<ArrayInt1, VLXArrayInteger>(s, obj);
00430       else
00431       if(obj->classType() == ArrayInt2::Type())
00432         vlx = export_ArrayT<ArrayInt2, VLXArrayInteger>(s, obj);
00433       else
00434       if(obj->classType() == ArrayInt3::Type())
00435         vlx = export_ArrayT<ArrayInt3, VLXArrayInteger>(s, obj);
00436       else
00437       if(obj->classType() == ArrayInt4::Type())
00438         vlx = export_ArrayT<ArrayInt4, VLXArrayInteger>(s, obj);
00439       else
00440 
00441       if(obj->classType() == ArrayUShort1::Type())
00442         vlx = export_ArrayT<ArrayUShort1, VLXArrayInteger>(s, obj);
00443       else
00444       if(obj->classType() == ArrayUShort2::Type())
00445         vlx = export_ArrayT<ArrayUShort2, VLXArrayInteger>(s, obj);
00446       else
00447       if(obj->classType() == ArrayUShort3::Type())
00448         vlx = export_ArrayT<ArrayUShort3, VLXArrayInteger>(s, obj);
00449       else
00450       if(obj->classType() == ArrayUShort4::Type())
00451         vlx = export_ArrayT<ArrayUShort4, VLXArrayInteger>(s, obj);
00452       else
00453 
00454       if(obj->classType() == ArrayUShort1::Type())
00455         vlx = export_ArrayT<ArrayUShort1, VLXArrayInteger>(s, obj);
00456       else
00457       if(obj->classType() == ArrayUShort2::Type())
00458         vlx = export_ArrayT<ArrayUShort2, VLXArrayInteger>(s, obj);
00459       else
00460       if(obj->classType() == ArrayUShort3::Type())
00461         vlx = export_ArrayT<ArrayUShort3, VLXArrayInteger>(s, obj);
00462       else
00463       if(obj->classType() == ArrayUShort4::Type())
00464         vlx = export_ArrayT<ArrayUShort4, VLXArrayInteger>(s, obj);
00465       else
00466 
00467       if(obj->classType() == ArrayShort1::Type())
00468         vlx = export_ArrayT<ArrayShort1, VLXArrayInteger>(s, obj);
00469       else
00470       if(obj->classType() == ArrayShort2::Type())
00471         vlx = export_ArrayT<ArrayShort2, VLXArrayInteger>(s, obj);
00472       else
00473       if(obj->classType() == ArrayShort3::Type())
00474         vlx = export_ArrayT<ArrayShort3, VLXArrayInteger>(s, obj);
00475       else
00476       if(obj->classType() == ArrayShort4::Type())
00477         vlx = export_ArrayT<ArrayShort4, VLXArrayInteger>(s, obj);
00478       else
00479 
00480       if(obj->classType() == ArrayUByte1::Type())
00481         vlx = export_ArrayT<ArrayUByte1, VLXArrayInteger>(s, obj);
00482       else
00483       if(obj->classType() == ArrayUByte2::Type())
00484         vlx = export_ArrayT<ArrayUByte2, VLXArrayInteger>(s, obj);
00485       else
00486       if(obj->classType() == ArrayUByte3::Type())
00487         vlx = export_ArrayT<ArrayUByte3, VLXArrayInteger>(s, obj);
00488       else
00489       if(obj->classType() == ArrayUByte4::Type())
00490         vlx = export_ArrayT<ArrayUByte4, VLXArrayInteger>(s, obj);
00491       else
00492 
00493       if(obj->classType() == ArrayByte1::Type())
00494         vlx = export_ArrayT<ArrayByte1, VLXArrayInteger>(s, obj);
00495       else
00496       if(obj->classType() == ArrayByte2::Type())
00497         vlx = export_ArrayT<ArrayByte2, VLXArrayInteger>(s, obj);
00498       else
00499       if(obj->classType() == ArrayByte3::Type())
00500         vlx = export_ArrayT<ArrayByte3, VLXArrayInteger>(s, obj);
00501       else
00502       if(obj->classType() == ArrayByte4::Type())
00503         vlx = export_ArrayT<ArrayByte4, VLXArrayInteger>(s, obj);
00504       else
00505 
00506       if(obj->classType() == ArrayFloat1::Type())
00507         vlx = export_ArrayT<ArrayFloat1, VLXArrayReal>(s, obj);
00508       else
00509       if(obj->classType() == ArrayFloat2::Type())
00510         vlx = export_ArrayT<ArrayFloat2, VLXArrayReal>(s, obj);
00511       else
00512       if(obj->classType() == ArrayFloat3::Type())
00513         vlx = export_ArrayT<ArrayFloat3, VLXArrayReal>(s, obj);
00514       else
00515       if(obj->classType() == ArrayFloat4::Type())
00516         vlx = export_ArrayT<ArrayFloat4, VLXArrayReal>(s, obj);
00517       else
00518 
00519       if(obj->classType() == ArrayDouble1::Type())
00520         vlx = export_ArrayT<ArrayDouble1, VLXArrayReal>(s, obj);
00521       else
00522       if(obj->classType() == ArrayDouble2::Type())
00523         vlx = export_ArrayT<ArrayDouble2, VLXArrayReal>(s, obj);
00524       else
00525       if(obj->classType() == ArrayDouble3::Type())
00526         vlx = export_ArrayT<ArrayDouble3, VLXArrayReal>(s, obj);
00527       else
00528       if(obj->classType() == ArrayDouble4::Type())
00529         vlx = export_ArrayT<ArrayDouble4, VLXArrayReal>(s, obj);
00530       else
00531       {
00532         s.signalExportError("Array type not supported for export.\n");
00533       }
00534 
00535       // register exported object asap
00536       s.registerExportedObject(obj, vlx.get());
00537       return vlx;
00538     }
00539   };
00540 
00541   //---------------------------------------------------------------------------
00542 
00544   struct VLXClassWrapper_Renderable: public VLXClassWrapper
00545   {
00546     virtual void exportRenderable(const Renderable* obj, VLXStructure* vlx)
00547     {
00548       if (!obj->objectName().empty() && obj->objectName() != obj->className())
00549         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
00550       *vlx << "BufferObjectEnabled" << obj->isBufferObjectEnabled();
00551       *vlx << "DisplayListEnabled" << obj->isDisplayListEnabled();
00552       if (!obj->boundsDirty())
00553       {
00554         *vlx << "AABB" << export_AABB(obj->boundingBox());
00555         *vlx << "Sphere" << export_Sphere(obj->boundingSphere());
00556       }
00557       else
00558         Log::debug("VLXClassWrapper_Renderable : skipping dirty bounds.\n");
00559     }
00560 
00561     void importRenderable(const VLXStructure* vlx, Renderable* ren)
00562     {
00563       const VLXValue* name = vlx->getValue("ObjectName");
00564       if (name)
00565         ren->setObjectName( name->getString().c_str() );
00566 
00567       const std::vector<VLXStructure::Value>& values = vlx->value();
00568       for(size_t i=0; i<values.size(); ++i)
00569       {
00570         const std::string& key = values[i].key();
00571         if (key == "BufferObjectEnabled")
00572         {
00573           ren->setBufferObjectEnabled( values[i].value().getBool() );
00574         }
00575         else
00576         if (key == "DisplayListEnabled")
00577         {
00578           ren->setDisplayListEnabled( values[i].value().getBool() );
00579         }
00580         else
00581         if (key == "AABB")
00582         {
00583           ren->setBoundingBox( import_AABB(values[i].value().getStructure()) );
00584         }
00585         else
00586         if (key == "Sphere")
00587         {
00588           ren->setBoundingSphere( import_Sphere(values[i].value().getStructure()) );
00589         }
00590       }
00591     }
00592   };
00593 
00594   //---------------------------------------------------------------------------
00595 
00597   struct VLXClassWrapper_Geometry: public VLXClassWrapper_Renderable
00598   {
00599     void importGeometry(VLXSerializer& s, const VLXStructure* vlx, Geometry* geom)
00600     {
00601       VLXClassWrapper_Renderable::importRenderable(vlx, geom);
00602 
00603       for(size_t i=0; i<vlx->value().size(); ++i)
00604       {
00605         const std::string& key = vlx->value()[i].key();
00606         const VLXValue& value = vlx->value()[i].value();
00607 
00608         if (key == "VertexArray")
00609         {
00610           VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) 
00611           ArrayAbstract* arr = s.importVLX(value.getStructure())->as<ArrayAbstract>();
00612           if (arr)
00613             geom->setVertexArray(arr);
00614           else
00615             s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00616         }
00617         else
00618         if (key == "NormalArray")
00619         {
00620           VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) 
00621           ArrayAbstract* arr = s.importVLX(value.getStructure())->as<ArrayAbstract>();
00622           if (arr)
00623             geom->setNormalArray(arr);
00624           else
00625             s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00626         }
00627         else
00628         if (key == "ColorArray")
00629         {
00630           VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) 
00631           ArrayAbstract* arr = s.importVLX(value.getStructure())->as<ArrayAbstract>();
00632           if (arr)
00633             geom->setColorArray(arr);
00634           else
00635             s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00636         }
00637         else
00638         if (key == "SecondaryColorArray")
00639         {
00640           VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) 
00641           ArrayAbstract* arr = s.importVLX(value.getStructure())->as<ArrayAbstract>();
00642           if (arr)
00643             geom->setSecondaryColorArray(arr);
00644           else
00645             s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00646         }
00647         else
00648         if (key == "FogCoordArray")
00649         {
00650           VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) 
00651           ArrayAbstract* arr = s.importVLX(value.getStructure())->as<ArrayAbstract>();
00652           if (arr)
00653             geom->setFogCoordArray(arr);
00654           else
00655             s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00656         }
00657         else
00658         if (strstr(key.c_str(), "TexCoordArray") == key.c_str())
00659         {
00660           const char* ch = key.c_str() + 13/*strlen("TexCoordArray")*/;
00661           int tex_unit = 0;
00662           for(; *ch; ++ch)
00663           {
00664             if (*ch>='0' && *ch<='9')
00665               tex_unit = tex_unit*10 + (*ch - '0');
00666             else
00667             {
00668               Log::error( Say("Line %n : error. ") << value.lineNumber() );
00669               Log::error( "TexCoordArray must end with a number!\n" );
00670               s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00671             }
00672           }
00673 
00674           VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) 
00675           ArrayAbstract* arr = s.importVLX(value.getStructure())->as<ArrayAbstract>();
00676           if (arr)
00677             geom->setTexCoordArray(tex_unit, arr);
00678           else
00679             s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00680         }
00681         else
00682         if (strstr(key.c_str(), "VertexAttribArray") == key.c_str())
00683         {
00684           const char* ch = key.c_str() + 17/*strlen("VertexAttribArray")*/;
00685           int attrib_location = 0;
00686           for(; *ch; ++ch)
00687           {
00688             if (*ch>='0' && *ch<='9')
00689               attrib_location = attrib_location*10 + (*ch - '0');
00690             else
00691             {
00692               Log::error( Say("Line %n : error. ") << value.lineNumber() );
00693               Log::error( "VertexAttribArray must end with a number!\n" );
00694               s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00695             }
00696           }
00697         
00698           VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value)
00699           VertexAttribInfo* info_ptr = s.importVLX(value.getStructure())->as<VertexAttribInfo>();
00700           if (info_ptr)
00701           {
00702             VertexAttribInfo info = *info_ptr;
00703             info.setAttribLocation(attrib_location);
00704             geom->setVertexAttribArray(info);
00705           }
00706           else
00707             s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00708         }
00709         else
00710         if (key == "DrawCall")
00711         {
00712           VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value) 
00713           DrawCall* draw_call = s.importVLX(value.getStructure())->as<DrawCall>();
00714           if (draw_call)
00715             geom->drawCalls()->push_back(draw_call);
00716           else
00717             s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00718         }
00719       }
00720     }
00721 
00722     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
00723     {
00724       ref<Geometry> geom = new Geometry;
00725       // registration must be done here to avoid loops
00726       s.registerImportedStructure(vlx, geom.get());
00727       importGeometry(s, vlx, geom.get());
00728       return geom;
00729     }
00730 
00731     void exportGeometry(VLXSerializer& s, const Geometry* geom, VLXStructure* vlx)
00732     {
00733       // Renderable
00734       VLXClassWrapper_Renderable::exportRenderable(geom, vlx);
00735 
00736       // Geometry
00737       if (geom->vertexArray()) 
00738         *vlx << "VertexArray" << s.exportVLX(geom->vertexArray());
00739     
00740       if (geom->normalArray()) 
00741         *vlx << "NormalArray" << s.exportVLX(geom->normalArray());
00742     
00743       if (geom->colorArray()) 
00744         *vlx << "ColorArray" << s.exportVLX(geom->colorArray());
00745     
00746       if (geom->secondaryColorArray()) 
00747         *vlx << "SecondaryColorArray" << s.exportVLX(geom->secondaryColorArray());
00748     
00749       if (geom->fogCoordArray()) 
00750         *vlx << "FogCoordArray" << s.exportVLX(geom->fogCoordArray());
00751 
00752       for( int i=0; i<VL_MAX_TEXTURE_UNITS; ++i)
00753       {
00754         if (geom->texCoordArray(i)) 
00755         {
00756           std::string tex_coord_array = String::printf("TexCoordArray%d", i).toStdString();
00757           *vlx << tex_coord_array.c_str() << s.exportVLX(geom->texCoordArray(i)); 
00758         }
00759       }
00760 
00761       for(size_t i=0; i<VL_MAX_GENERIC_VERTEX_ATTRIB; ++i)
00762       {
00763         if (geom->vertexAttribArray(i))
00764         {
00765           std::string vertex_attrib_array = String::printf("VertexAttribArray%d", i).toStdString();
00766           *vlx << vertex_attrib_array.c_str() << s.exportVLX(geom->vertexAttribArray(i));
00767         }
00768       }
00769 
00770       for(int i=0; i<geom->drawCalls()->size(); ++i)
00771         *vlx << "DrawCall" << s.exportVLX(geom->drawCalls()->at(i));
00772     }
00773 
00774     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
00775     {
00776       const Geometry* cast_obj = obj->as<Geometry>(); VL_CHECK(cast_obj)
00777       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("geometry_"));
00778       // register exported object asap
00779       s.registerExportedObject(obj, vlx.get());
00780       exportGeometry(s, cast_obj, vlx.get());
00781       return vlx;
00782     }
00783   };
00784 
00785   //---------------------------------------------------------------------------
00786 
00788   struct VLXClassWrapper_VertexAttribInfo: public VLXClassWrapper
00789   {
00790     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
00791     {
00792       if (vlx->tag() != "<vl::VertexAttribInfo>")
00793       {
00794         Log::error( Say("Line %n : <vl::VertexAttribInfo> expected.\n") << vlx->lineNumber() );
00795         return NULL;
00796       }
00797 
00798       // link the VLX to the VL object
00799       ref<VertexAttribInfo> info = new VertexAttribInfo;
00800       // register imported structure asap
00801       s.registerImportedStructure(vlx, info.get());
00802 
00803       for(size_t i=0; i<vlx->value().size(); ++i)
00804       {
00805         const std::string& key = vlx->value()[i].key();
00806         const VLXValue& value = vlx->value()[i].value();
00807 
00808         if (key == "Data")
00809         {
00810           VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::Structure, value) 
00811           ArrayAbstract* arr = s.importVLX( value.getStructure() )->as<ArrayAbstract>();
00812           if(arr)
00813             info->setData(arr);
00814           else
00815             s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00816         }
00817         else
00818         if (key == "Normalize")
00819         {
00820           VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::Bool, value) 
00821           info->setNormalize( value.getBool() );
00822         }
00823         else
00824         if (key == "Interpretation")
00825         {
00826           VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::Identifier, value) 
00827           info->setInterpretation( vlx_EVertexAttribInterpretation(value, s) );
00828         }
00829       }
00830     
00831       return info.get();
00832     }
00833 
00834     void exportVertexAttribInfo(VLXSerializer& s, const VertexAttribInfo* info, VLXStructure* vlx)
00835     {
00836       *vlx << "Data" << s.exportVLX(info->data());
00837       *vlx << "Normalize" << info->normalize();
00838       *vlx << "Interpretation" << vlx_Identifier(vlx_EVertexAttribInterpretation(info->interpretation()));
00839     }
00840 
00841     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
00842     {
00843       const VertexAttribInfo* cast_obj = obj->as<VertexAttribInfo>(); VL_CHECK(cast_obj)
00844       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("vertattrinfo_"));
00845       // register exported object asap
00846       s.registerExportedObject(obj, vlx.get());
00847       exportVertexAttribInfo(s, cast_obj, vlx.get());
00848       return vlx;
00849     }
00850   };
00851 
00852   //---------------------------------------------------------------------------
00853 
00855   struct VLXClassWrapper_DrawCall: public VLXClassWrapper
00856   {
00857     void importDrawCall(VLXSerializer& s, const VLXStructure* vlx, DrawCall* draw_call)
00858     {
00859       if(draw_call->isOfType(DrawElementsBase::Type()))
00860       {
00861         DrawElementsBase* de= draw_call->as<DrawElementsBase>();
00862 
00863         const VLXValue* name = vlx->getValue("ObjectName");
00864         if (name)
00865           de->setObjectName( name->getString().c_str() );
00866 
00867         for(size_t i=0; i<vlx->value().size(); ++i)
00868         {
00869           const std::string& key = vlx->value()[i].key();
00870           const VLXValue& value = vlx->value()[i].value();
00871           if( key == "PrimitiveType" )
00872           {
00873             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier , value)
00874             de->setPrimitiveType( vlx_EPrimitiveType( value, s ) );
00875             VLX_IMPORT_CHECK_RETURN( de->primitiveType() != PT_UNKNOWN , value);
00876           }
00877           else
00878           if( key == "Enabled" )
00879           {
00880             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value)
00881             de->setEnabled( value.getBool() );
00882           }
00883           else
00884           if( key == "Instances" )
00885           {
00886             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value)
00887             de->setInstances( (int)value.getInteger() );
00888           }
00889           else
00890           if( key == "PrimitiveRestartEnabled" )
00891           {
00892             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value)
00893             de->setPrimitiveRestartEnabled( value.getBool() );
00894           }
00895           else
00896           if( key == "BaseVertex" )
00897           {
00898             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value)
00899             de->setBaseVertex( (int)value.getInteger() );
00900           }
00901           else
00902           if( key == "IndexBuffer" )
00903           {
00904             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure , value)
00905             ArrayAbstract* arr_abstract = s.importVLX(value.getStructure())->as<ArrayAbstract>();
00906             if(!arr_abstract)
00907               s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00908 
00909             if ( de->isOfType(DrawElementsUInt::Type()) )
00910             {
00911               VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == ArrayUInt1::Type(), value);
00912               de->as<DrawElementsUInt>()->setIndexBuffer( arr_abstract->as<ArrayUInt1>() );
00913             }
00914             else
00915             if ( de->isOfType(DrawElementsUShort::Type()) )
00916             {
00917               VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == ArrayUShort1::Type(), value);
00918               de->as<DrawElementsUShort>()->setIndexBuffer( arr_abstract->as<ArrayUShort1>() );
00919             }
00920             else
00921             if ( de->isOfType(DrawElementsUByte::Type()) )
00922             {
00923               VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == ArrayUByte1::Type(), value);
00924               de->as<DrawElementsUByte>()->setIndexBuffer( arr_abstract->as<ArrayUByte1>() );
00925             }
00926           }
00927         }
00928       }
00929       else
00930       if(draw_call->isOfType( MultiDrawElementsBase::Type() ))
00931       {
00932         MultiDrawElementsBase* de = draw_call->as<MultiDrawElementsBase>();
00933 
00934         VL_CHECK(de)
00935         VL_CHECK(draw_call)
00936 
00937         const VLXValue* name = vlx->getValue("ObjectName");
00938         if (name)
00939           de->setObjectName( name->getString().c_str() );
00940 
00941         for(size_t i=0; i<vlx->value().size(); ++i)
00942         {
00943           const std::string& key = vlx->value()[i].key();
00944           const VLXValue& value = vlx->value()[i].value();
00945           if( key == "PrimitiveType" )
00946           {
00947             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier , value)
00948             de->setPrimitiveType( vlx_EPrimitiveType( value, s ) );
00949             VLX_IMPORT_CHECK_RETURN( de->primitiveType() != PT_UNKNOWN , value);
00950           }
00951           else
00952           if( key == "Enabled" )
00953           {
00954             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value)
00955             de->setEnabled( value.getBool() );
00956           }
00957           else
00958           if( key == "PrimitiveRestartEnabled" )
00959           {
00960             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value)
00961             de->setPrimitiveRestartEnabled( value.getBool() );
00962           }
00963           else
00964           if( key == "BaseVertices" )
00965           {
00966             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger , value)
00967             de->baseVertices().resize( value.getArrayInteger()->value().size() );
00968             if (de->baseVertices().size())
00969               value.getArrayInteger()->copyTo( &de->baseVertices()[0] );
00970             // de->setBaseVertices( value.getArrayInt32()->value() );
00971           }
00972           else
00973           if( key == "CountVector" )
00974           {
00975             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger , value)
00976             de->countVector().resize( value.getArrayInteger()->value().size() );
00977             if (de->countVector().size())
00978               value.getArrayInteger()->copyTo( &de->countVector()[0] );
00979             // de->countVector() = value.getArrayInt32()->value();
00980           }
00981           else
00982           if( key == "IndexBuffer" )
00983           {
00984             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure , value)
00985             ArrayAbstract* arr_abstract = s.importVLX(value.getStructure())->as<ArrayAbstract>();
00986             if( !arr_abstract )
00987               s.signalImportError( Say("Line %n : import error.\n") << value.lineNumber() );
00988 
00989             if ( de->isOfType(MultiDrawElementsUInt::Type()) )
00990             {
00991               VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == ArrayUInt1::Type(), value);
00992               de->as<MultiDrawElementsUInt>()->setIndexBuffer( arr_abstract->as<ArrayUInt1>() );
00993             }
00994             else
00995             if ( de->isOfType(MultiDrawElementsUShort::Type()) )
00996             {
00997               VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == ArrayUShort1::Type(), value);
00998               de->as<MultiDrawElementsUShort>()->setIndexBuffer( arr_abstract->as<ArrayUShort1>() );
00999             }
01000             else
01001             if ( de->isOfType(MultiDrawElementsUByte::Type()) )
01002             {
01003               VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == ArrayUByte1::Type(), value);
01004               de->as<MultiDrawElementsUByte>()->setIndexBuffer( arr_abstract->as<ArrayUByte1>() );
01005             }
01006           }
01007         }
01008 
01009         // finalize setup
01010         de->computePointerVector();
01011         de->computeBufferObjectPointerVector();
01012         if ( de->baseVertices().size() != de->countVector().size() )
01013           de->baseVertices().resize( de->countVector().size() );
01014       }
01015       else
01016       if( draw_call->isOfType( DrawArrays::Type() ) )
01017       {
01018         ref<DrawArrays> da = draw_call->as<DrawArrays>();
01019 
01020         const VLXValue* name = vlx->getValue("ObjectName");
01021         if (name)
01022           da->setObjectName( name->getString().c_str() );
01023 
01024         for(size_t i=0; i<vlx->value().size(); ++i)
01025         {
01026           const std::string& key = vlx->value()[i].key();
01027           const VLXValue& value = vlx->value()[i].value();
01028 
01029           if( key == "PrimitiveType" )
01030           {
01031             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier , value)
01032             da->setPrimitiveType( vlx_EPrimitiveType( value, s ) );
01033             VLX_IMPORT_CHECK_RETURN( da->primitiveType() != PT_UNKNOWN , value);
01034           }
01035           else
01036           if( key == "Enabled" )
01037           {
01038             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value)
01039             da->setEnabled( value.getBool() );
01040           }
01041           else
01042           if( key == "Instances" )
01043           {
01044             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value)
01045             da->setInstances( (int)value.getInteger() );
01046           }
01047           else
01048           if( key == "Start" )
01049           {
01050             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value)
01051             da->setStart( (int)value.getInteger() );
01052           }
01053           else
01054           if( key == "Count" )
01055           {
01056             VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value)
01057             da->setCount( (int)value.getInteger() );
01058           }
01059         }
01060       }
01061     }
01062 
01063     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
01064     {
01065       ref<DrawCall> dc;
01066       if (vlx->tag() == "<vl::DrawElementsUInt>")
01067         dc = new DrawElementsUInt;
01068       else
01069       if (vlx->tag() == "<vl::DrawElementsUShort>")
01070         dc = new DrawElementsUShort;
01071       else
01072       if (vlx->tag() == "<vl::DrawElementsUByte>")
01073         dc = new DrawElementsUByte;
01074       else
01075       if (vlx->tag() == "<vl::MultiDrawElementsUInt>")
01076         dc = new MultiDrawElementsUInt;
01077       else
01078       if (vlx->tag() == "<vl::MultiDrawElementsUShort>")
01079         dc = new MultiDrawElementsUShort;
01080       else
01081       if (vlx->tag() == "<vl::MultiDrawElementsUByte>")
01082         dc = new MultiDrawElementsUByte;
01083       else
01084       if (vlx->tag() == "<vl::DrawArrays>")
01085         dc = new DrawArrays;
01086       else
01087         s.signalImportError( Say("Line %n : error. Unknown draw call.\n") << vlx->lineNumber() );
01088       // register imported structure asap
01089       s.registerImportedStructure(vlx, dc.get());
01090       importDrawCall(s, vlx, dc.get());
01091       return dc;
01092     }
01093 
01094     void exportDrawCallBase(VLXSerializer& s, const DrawCall* obj, VLXStructure* vlx)
01095     {
01096       if (!obj->objectName().empty() && obj->objectName() != obj->className())
01097         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
01098       *vlx << "PrimitiveType" << vlx_Identifier(vlx_EPrimitiveType(obj->primitiveType()));
01099       *vlx << "Enabled" << obj->isEnabled();
01100       if (obj->patchParameter())
01101         *vlx << "PatchParameter" << s.exportVLX(obj->patchParameter());
01102     }
01103 
01104     void exportDrawCall(VLXSerializer& s, const DrawCall* dcall, VLXStructure* vlx)
01105     {
01106       exportDrawCallBase(s, dcall, vlx);
01107 
01108       if (dcall->isOfType(DrawArrays::Type()))
01109       {
01110         const DrawArrays* da = dcall->as<DrawArrays>();
01111         *vlx << "Instances" << (long long)da->instances();
01112         *vlx << "Start" << (long long)da->start();
01113         *vlx << "Count" << (long long)da->count();
01114       }
01115       else
01116       if (dcall->isOfType(DrawElementsUInt::Type()))
01117       {
01118         const DrawElementsUInt* de = dcall->as<DrawElementsUInt>();
01119         *vlx << "Instances" << (long long)de->instances();
01120         *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
01121         *vlx << "BaseVertex" << (long long)de->baseVertex();
01122         *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
01123       }
01124       else
01125       if (dcall->isOfType(DrawElementsUShort::Type()))
01126       {
01127         const DrawElementsUShort* de = dcall->as<DrawElementsUShort>();
01128         *vlx << "Instances" << (long long)de->instances();
01129         *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
01130         *vlx << "BaseVertex" << (long long)de->baseVertex();
01131         *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
01132       }
01133       else
01134       if (dcall->isOfType(DrawElementsUByte::Type()))
01135       {
01136         const DrawElementsUByte* de = dcall->as<DrawElementsUByte>();
01137         *vlx << "Instances" << (long long)de->instances();
01138         *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
01139         *vlx << "BaseVertex" << (long long)de->baseVertex();
01140         *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
01141       }
01142       else
01143       if (dcall->isOfType(MultiDrawElementsUInt::Type()))
01144       {
01145         const MultiDrawElementsUInt* de = dcall->as<MultiDrawElementsUInt>();
01146         *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
01147         *vlx << "BaseVertices" << vlx_toValue(de->baseVertices());
01148         *vlx << "CountVector" << vlx_toValue(de->countVector());
01149         *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
01150       }
01151       else
01152       if (dcall->isOfType(MultiDrawElementsUShort::Type()))
01153       {
01154         const MultiDrawElementsUShort* de = dcall->as<MultiDrawElementsUShort>();
01155         *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
01156         *vlx << "BaseVertices" << vlx_toValue(de->baseVertices());
01157         *vlx << "CountVector" << vlx_toValue(de->countVector());
01158         *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
01159       }
01160       else
01161       if (dcall->isOfType(MultiDrawElementsUByte::Type()))
01162       {
01163         const MultiDrawElementsUByte* de = dcall->as<MultiDrawElementsUByte>();
01164         *vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
01165         *vlx << "BaseVertices" << vlx_toValue(de->baseVertices());
01166         *vlx << "CountVector" << vlx_toValue(de->countVector());
01167         *vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
01168       }
01169       else
01170       {
01171         Log::error("DrawCall type not supported for export.\n");
01172       }
01173     }
01174 
01175     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
01176     {
01177       const DrawCall* cast_obj = obj->as<DrawCall>(); VL_CHECK(cast_obj)
01178       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("drawcall_"));
01179       // register exported object asap
01180       s.registerExportedObject(obj, vlx.get());
01181       exportDrawCall(s, cast_obj, vlx.get());
01182       return vlx;
01183     }
01184   };
01185 
01186   //---------------------------------------------------------------------------
01187 
01189   struct VLXClassWrapper_PatchParameter: public VLXClassWrapper
01190   {
01191     void importPatchParameter(const VLXStructure* vlx, PatchParameter* pp)
01192     {
01193       std::vector<VLXStructure::Value> values = vlx->value();
01194       for(size_t i=0; i<values.size(); ++i)
01195       {
01196         const std::string& key = values[i].key();
01197         if (key == "PatchVertices")
01198         {
01199           pp->setPatchVertices( (int)values[i].value().getInteger() );
01200         }
01201         else
01202         if (key == "PatchDefaultOuterLevel")
01203         {
01204           pp->setPatchDefaultOuterLevel( (fvec4)vlx_vec4(values[i].value().getArrayReal()) );
01205         }
01206         else
01207         if (key == "PatchDefaultInnerLevel")
01208         {
01209           pp->setPatchDefaultInnerLevel( (fvec2)vlx_vec2(values[i].value().getArrayReal()) );
01210         }
01211       }
01212     }
01213 
01214     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
01215     {
01216       ref<PatchParameter> pp = new PatchParameter;
01217       // register imported structure asap
01218       s.registerImportedStructure(vlx, pp.get());
01219       importPatchParameter(vlx, pp.get());
01220       return pp;
01221     }
01222 
01223     void exportPatchParameter(const PatchParameter* pp, VLXStructure* vlx)
01224     {
01225       *vlx << "PatchVertices" << (long long)pp->patchVertices();
01226       *vlx << "PatchDefaultOuterLevel" << vlx_toValue((vec4)pp->patchDefaultOuterLevel());
01227       *vlx << "PatchDefaultInnerLevel" << vlx_toValue((vec2)pp->patchDefaultInnerLevel());
01228     }
01229 
01230     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
01231     {
01232       const PatchParameter* cast_obj = obj->as<PatchParameter>(); VL_CHECK(cast_obj)
01233       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("patchparam_"));
01234       // register exported object asap
01235       s.registerExportedObject(obj, vlx.get());
01236       exportPatchParameter(cast_obj, vlx.get());
01237       return vlx;
01238     }
01239   };
01240 
01241   //---------------------------------------------------------------------------
01242 
01244   struct VLXClassWrapper_ResourceDatabase: public VLXClassWrapper
01245   {
01246     void importResourceDatabase(VLXSerializer& s, const VLXStructure* vlx, ResourceDatabase* resdb)
01247     {
01248       const VLXValue* vlx_obj_name = vlx->getValue("ObjectName");
01249       if (vlx_obj_name)
01250         resdb->setObjectName( vlx_obj_name->getString().c_str() );
01251 
01252       const VLXValue* vlx_res = vlx->getValue("Resources");
01253       if (vlx_res)
01254       {
01255         VLX_IMPORT_CHECK_RETURN( vlx_res->type() == VLXValue::List, *vlx_res );
01256         // get the list
01257         const VLXList* list = vlx_res->getList();
01258         for(size_t i=0; i<list->value().size(); ++i)
01259         {
01260           const VLXValue& value = list->value()[i];
01261 
01262           // the member of this list must be all structures.
01263 
01264           if (value.type() != VLXValue::Structure)
01265           {
01266             s.signalImportError( Say("Line %n : structure expected.\n") << value.lineNumber() );
01267             return;
01268           }
01269 
01270           resdb->resources().push_back( s.importVLX(value.getStructure()) );
01271         }
01272       }
01273     }
01274 
01275     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
01276     {
01277       ref<ResourceDatabase> resdb = new ResourceDatabase;
01278       // register imported structure asap
01279       s.registerImportedStructure(vlx, resdb.get());
01280       importResourceDatabase(s, vlx, resdb.get());
01281       return resdb;
01282     }
01283 
01284     void exportResourceDatabase(VLXSerializer& s, const ResourceDatabase* obj, VLXStructure* vlx)
01285     {
01286       if (!obj->objectName().empty() && obj->objectName() != obj->className())
01287         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
01288       ref<VLXList> list = new VLXList;
01289       *vlx << "Resources" << list.get();
01290 
01291       for(size_t i=0; i<obj->resources().size(); ++i)
01292       {
01293         if ( !s.canExport(obj->resources().at(i).get()) )
01294         {
01295           Log::debug( Say("VLXClassWrapper_ResourceDatabase : skipping '%s'.\n") << obj->resources().at(i).get()->className() );
01296           continue;
01297         }
01298         else
01299         {
01300           *list << s.exportVLX(obj->resources().at(i).get());
01301         }
01302       }
01303     }
01304 
01305     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
01306     {
01307       const ResourceDatabase* cast_obj = obj->as<ResourceDatabase>(); VL_CHECK(cast_obj)
01308       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("resdb_"));
01309       // register exported object asap
01310       s.registerExportedObject(obj, vlx.get());
01311       exportResourceDatabase(s, cast_obj, vlx.get());
01312       return vlx;
01313     }
01314   };
01315 
01316   //---------------------------------------------------------------------------
01317 
01319   struct VLXClassWrapper_Uniform: public VLXClassWrapper
01320   {
01321     void importUniform(VLXSerializer& s, const VLXStructure* vlx, Uniform* uniform)
01322     {
01323       const VLXValue* val = vlx->getValue("Name");
01324       if (val)
01325       {
01326         VL_CHECK( val->type() == VLXValue::Identifier );
01327         uniform->setName( val->getIdentifier().c_str() );
01328       }
01329       else
01330       {
01331         s.signalImportError( Say("Line %d : uniform without 'Name'.\n") << vlx->lineNumber() );
01332         return;
01333       }
01334 
01335       // 'Count' is optional
01336       int count = 1;
01337       val = vlx->getValue("Count");
01338       if (val)
01339       {
01340         VL_CHECK( val->type() == VLXValue::Integer );
01341         count = (int)val->getInteger();
01342       }
01343 
01344       EUniformType type = UT_NONE;
01345       val = vlx->getValue("Type");
01346       if (val)
01347       {
01348         VL_CHECK( val->type() == VLXValue::Identifier );
01349         type = vlx_EUniformType( *val, s );
01350       }
01351       else
01352       {
01353         s.signalImportError( Say("Line %d : uniform without 'Type'.\n") << vlx->lineNumber() );
01354         return;
01355       }
01356 
01357       val = vlx->getValue("Data");
01358       const VLXArrayReal* arr_real = NULL;
01359       const VLXArrayInteger* arr_int = NULL;
01360       if (!val)
01361       {
01362         s.signalImportError( Say("Line %d : uniform without 'Data'.\n") << vlx->lineNumber() );
01363         return;
01364       }
01365       else
01366       {
01367         if (val->type() == VLXValue::ArrayReal)
01368           arr_real = val->getArrayReal();
01369         else
01370         if (val->type() == VLXValue::ArrayInteger)
01371           arr_int = val->getArrayInteger();
01372       }
01373 
01374       std::vector<int> int_vec;
01375       std::vector<unsigned int> uint_vec;
01376       std::vector<float> float_vec;
01377       std::vector<double> double_vec;
01378 
01379       switch(type)
01380       {
01381       case UT_INT:
01382         int_vec.resize(count*1); if (arr_int) arr_int->copyTo(&int_vec[0]); else int_vec[0] = (int)val->getInteger();
01383         uniform->setUniform1i(count, &int_vec[0]);
01384         break;
01385       case UT_INT_VEC2: 
01386         int_vec.resize(count*2); arr_int->copyTo(&int_vec[0]); VLX_IMPORT_CHECK_RETURN(int_vec.size() == arr_int->value().size(), *val); 
01387         uniform->setUniform2i(count, &int_vec[0]);
01388         break;
01389       case UT_INT_VEC3: 
01390         int_vec.resize(count*3); arr_int->copyTo(&int_vec[0]); VLX_IMPORT_CHECK_RETURN(int_vec.size() == arr_int->value().size(), *val); 
01391         uniform->setUniform3i(count, &int_vec[0]);
01392         break;
01393       case UT_INT_VEC4: 
01394         int_vec.resize(count*4); arr_int->copyTo(&int_vec[0]); VLX_IMPORT_CHECK_RETURN(int_vec.size() == arr_int->value().size(), *val); 
01395         uniform->setUniform4i(count, &int_vec[0]);
01396         break;
01397 
01398       case UT_UNSIGNED_INT:
01399         uint_vec.resize(count*1); if (arr_int) arr_int->copyTo(&uint_vec[0]); else uint_vec[0] = (unsigned int)val->getInteger(); 
01400         uniform->setUniform1ui(count, &uint_vec[0]);
01401         break;
01402       case UT_UNSIGNED_INT_VEC2: 
01403         uint_vec.resize(count*2); arr_int->copyTo(&uint_vec[0]); VLX_IMPORT_CHECK_RETURN(uint_vec.size() == arr_int->value().size(), *val); 
01404         uniform->setUniform2ui(count, &uint_vec[0]);
01405         break;
01406       case UT_UNSIGNED_INT_VEC3: 
01407         uint_vec.resize(count*3); arr_int->copyTo(&uint_vec[0]); VLX_IMPORT_CHECK_RETURN(uint_vec.size() == arr_int->value().size(), *val); 
01408         uniform->setUniform3ui(count, &uint_vec[0]);
01409         break;
01410       case UT_UNSIGNED_INT_VEC4: 
01411         uint_vec.resize(count*4); arr_int->copyTo(&uint_vec[0]); VLX_IMPORT_CHECK_RETURN(uint_vec.size() == arr_int->value().size(), *val); 
01412         uniform->setUniform4ui(count, &uint_vec[0]);
01413         break;
01414 
01415       case UT_FLOAT: 
01416         float_vec.resize(count*1); if (arr_real) arr_real->copyTo(&float_vec[0]); else float_vec[0] = (float)val->getReal(); 
01417         uniform->setUniform1f(count, &float_vec[0]);
01418         break;
01419       case UT_FLOAT_VEC2: 
01420         float_vec.resize(count*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); 
01421         uniform->setUniform2f(count, &float_vec[0]);
01422         break;
01423       case UT_FLOAT_VEC3: 
01424         float_vec.resize(count*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); 
01425         uniform->setUniform3f(count, &float_vec[0]);
01426         break;
01427       case UT_FLOAT_VEC4: 
01428         float_vec.resize(count*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); 
01429         uniform->setUniform4f(count, &float_vec[0]);
01430         break;
01431 
01432       case UT_FLOAT_MAT2: 
01433         float_vec.resize(count*2*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
01434         uniform->setUniformMatrix2f(count, &float_vec[0]);
01435         break;
01436       case UT_FLOAT_MAT3: 
01437         float_vec.resize(count*3*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
01438         uniform->setUniformMatrix3f(count, &float_vec[0]);
01439         break;
01440       case UT_FLOAT_MAT4: 
01441         float_vec.resize(count*4*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
01442         uniform->setUniformMatrix4f(count, &float_vec[0]);
01443         break;
01444 
01445       case UT_FLOAT_MAT2x3: 
01446         float_vec.resize(count*2*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); 
01447         uniform->setUniformMatrix2x3f(count, &float_vec[0]);
01448         break;
01449       case UT_FLOAT_MAT3x2: 
01450         float_vec.resize(count*3*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); 
01451         uniform->setUniformMatrix3x2f(count, &float_vec[0]);
01452         break;
01453       case UT_FLOAT_MAT2x4: 
01454         float_vec.resize(count*2*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); 
01455         uniform->setUniformMatrix2x4f(count, &float_vec[0]);
01456         break;
01457       case UT_FLOAT_MAT4x2: 
01458         float_vec.resize(count*4*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); 
01459         uniform->setUniformMatrix4x2f(count, &float_vec[0]);
01460         break;
01461       case UT_FLOAT_MAT3x4: 
01462         float_vec.resize(count*3*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); 
01463         uniform->setUniformMatrix3x4f(count, &float_vec[0]);
01464         break;
01465       case UT_FLOAT_MAT4x3: 
01466         float_vec.resize(count*4*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val); 
01467         uniform->setUniformMatrix4x3f(count, &float_vec[0]);
01468         break;
01469 
01470       case UT_DOUBLE: 
01471         double_vec.resize(count*1); if (arr_real) arr_real->copyTo(&double_vec[0]); else double_vec[0] = (double)val->getReal(); 
01472         uniform->setUniform1d(count, &double_vec[0]);
01473         break;
01474       case UT_DOUBLE_VEC2: 
01475         double_vec.resize(count*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); 
01476         uniform->setUniform2d(count, &double_vec[0]);
01477         break;
01478       case UT_DOUBLE_VEC3: 
01479         double_vec.resize(count*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); 
01480         uniform->setUniform3d(count, &double_vec[0]);
01481         break;
01482       case UT_DOUBLE_VEC4:
01483         double_vec.resize(count*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); 
01484         uniform->setUniform4d(count, &double_vec[0]);
01485         break;
01486 
01487       case UT_DOUBLE_MAT2: 
01488         double_vec.resize(count*2*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
01489         uniform->setUniformMatrix2d(count, &double_vec[0]);
01490         break;
01491       case UT_DOUBLE_MAT3: 
01492         double_vec.resize(count*3*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
01493         uniform->setUniformMatrix3d(count, &double_vec[0]);
01494         break;
01495       case UT_DOUBLE_MAT4: 
01496         double_vec.resize(count*4*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
01497         uniform->setUniformMatrix4d(count, &double_vec[0]);
01498         break;
01499 
01500       case UT_DOUBLE_MAT2x3:
01501         double_vec.resize(count*2*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); 
01502         uniform->setUniformMatrix2x3d(count, &double_vec[0]);
01503         break;
01504       case UT_DOUBLE_MAT3x2:
01505         double_vec.resize(count*3*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); 
01506         uniform->setUniformMatrix3x2d(count, &double_vec[0]);
01507         break;
01508       case UT_DOUBLE_MAT2x4:
01509         double_vec.resize(count*2*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); 
01510         uniform->setUniformMatrix2x4d(count, &double_vec[0]);
01511         break;
01512       case UT_DOUBLE_MAT4x2:
01513         double_vec.resize(count*4*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); 
01514         uniform->setUniformMatrix4x2d(count, &double_vec[0]);
01515         break;
01516       case UT_DOUBLE_MAT3x4:
01517         double_vec.resize(count*3*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); 
01518         uniform->setUniformMatrix3x4d(count, &double_vec[0]);
01519         break;
01520       case UT_DOUBLE_MAT4x3:
01521         double_vec.resize(count*4*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val); 
01522         uniform->setUniformMatrix4x3d(count, &double_vec[0]);
01523         break;
01524 
01525       case UT_NONE:
01526         Log::error( Say("Error importing uniform : uninitialized uniform (%s).\n") << uniform->name() );
01527         break;
01528 
01529       default:
01530         Log::error( Say("Error importing uniform : illegal uniform type (%s).\n") << uniform->name() );
01531         break;
01532       }
01533 
01534     }
01535 
01536     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
01537     {
01538       ref<Uniform> obj = new Uniform;
01539       // register imported structure asap
01540       s.registerImportedStructure(vlx, obj.get());
01541       importUniform(s, vlx, obj.get());
01542       return obj;
01543     }
01544 
01545     void exportUniform(const Uniform* uniform, VLXStructure* vlx)
01546     {
01547       *vlx << "Name" << vlx_Identifier(uniform->name());
01548       *vlx << "Type" << vlx_Identifier(vlx_EUniformType(uniform->type()));
01549       *vlx << "Count" << (long long)uniform->count();
01550 
01551       const int count = uniform->count();
01552       ref<VLXArrayInteger> arr_int = new VLXArrayInteger;
01553       ref<VLXArrayReal> arr_real = new VLXArrayReal;
01554 
01555       switch(uniform->type())
01556       {
01557       case UT_INT:
01558         {
01559           if (count == 1)
01560             { int val = 0; uniform->getUniform(&val); *vlx << "Data" << (long long)val; break; }
01561           else
01562             { arr_int->value().resize(count*1); arr_int->copyFrom( (int*)uniform->rawData() ); break; }
01563         }
01564       case UT_INT_VEC2: arr_int->value().resize(count*2); arr_int->copyFrom( (int*)uniform->rawData() ); break;
01565       case UT_INT_VEC3: arr_int->value().resize(count*3); arr_int->copyFrom( (int*)uniform->rawData() ); break;
01566       case UT_INT_VEC4: arr_int->value().resize(count*4); arr_int->copyFrom( (int*)uniform->rawData() ); break;
01567 
01568       case UT_UNSIGNED_INT:
01569         {
01570           if (count == 1)
01571             { unsigned int val = 0; uniform->getUniform(&val); *vlx << "Data" << (long long)val; break; }
01572           else
01573             { arr_int->value().resize(count*1); arr_int->copyFrom( (int*)uniform->rawData() ); break; }
01574         }
01575       case UT_UNSIGNED_INT_VEC2: arr_int->value().resize(count*2); arr_int->copyFrom( (int*)uniform->rawData() ); break;
01576       case UT_UNSIGNED_INT_VEC3: arr_int->value().resize(count*3); arr_int->copyFrom( (int*)uniform->rawData() ); break;
01577       case UT_UNSIGNED_INT_VEC4: arr_int->value().resize(count*4); arr_int->copyFrom( (int*)uniform->rawData() ); break;
01578 
01579       case UT_FLOAT:
01580         {
01581           if (count == 1)
01582             { float val = 0; uniform->getUniform(&val); *vlx << "Data" << (double)val; break; }
01583           else
01584             { arr_real->value().resize(count*1); arr_real->copyFrom( (float*)uniform->rawData() ); break; }
01585         }
01586       case UT_FLOAT_VEC2: arr_real->value().resize(count*2); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01587       case UT_FLOAT_VEC3: arr_real->value().resize(count*3); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01588       case UT_FLOAT_VEC4: arr_real->value().resize(count*4); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01589 
01590       case UT_FLOAT_MAT2: arr_real->value().resize(count*2*2); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01591       case UT_FLOAT_MAT3: arr_real->value().resize(count*3*3); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01592       case UT_FLOAT_MAT4: arr_real->value().resize(count*4*4); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01593 
01594       case UT_FLOAT_MAT2x3: arr_real->value().resize(count*2*3); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01595       case UT_FLOAT_MAT3x2: arr_real->value().resize(count*3*2); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01596       case UT_FLOAT_MAT2x4: arr_real->value().resize(count*2*4); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01597       case UT_FLOAT_MAT4x2: arr_real->value().resize(count*4*2); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01598       case UT_FLOAT_MAT3x4: arr_real->value().resize(count*3*4); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01599       case UT_FLOAT_MAT4x3: arr_real->value().resize(count*4*3); arr_real->copyFrom( (float*)uniform->rawData() ); break;
01600 
01601       case UT_DOUBLE:
01602         {
01603           if (count == 1)
01604             { double val = 0; uniform->getUniform(&val); *vlx << "Data" << (double)val; break; }
01605           else
01606             { arr_real->value().resize(count*1); arr_real->copyFrom( (double*)uniform->rawData() ); break; }
01607         }
01608       case UT_DOUBLE_VEC2: arr_real->value().resize(count*2); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01609       case UT_DOUBLE_VEC3: arr_real->value().resize(count*3); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01610       case UT_DOUBLE_VEC4: arr_real->value().resize(count*4); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01611 
01612       case UT_DOUBLE_MAT2: arr_real->value().resize(count*2*2); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01613       case UT_DOUBLE_MAT3: arr_real->value().resize(count*3*3); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01614       case UT_DOUBLE_MAT4: arr_real->value().resize(count*4*4); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01615 
01616       case UT_DOUBLE_MAT2x3: arr_real->value().resize(count*2*3); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01617       case UT_DOUBLE_MAT3x2: arr_real->value().resize(count*3*2); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01618       case UT_DOUBLE_MAT2x4: arr_real->value().resize(count*2*4); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01619       case UT_DOUBLE_MAT4x2: arr_real->value().resize(count*4*2); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01620       case UT_DOUBLE_MAT3x4: arr_real->value().resize(count*3*4); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01621       case UT_DOUBLE_MAT4x3: arr_real->value().resize(count*4*3); arr_real->copyFrom( (double*)uniform->rawData() ); break;
01622 
01623       case UT_NONE:
01624         Log::error( Say("Error exporting uniform : uninitialized uniform (%s).\n") << uniform->name() );
01625         break;
01626 
01627       default:
01628         Log::error( Say("Error exporting uniform : illegal uniform type (%s).\n") << uniform->name() );
01629         break;
01630       }
01631 
01632       if (!arr_int->value().empty())
01633         *vlx << "Data" << arr_int.get();
01634       else
01635       if (!arr_real->value().empty())
01636         *vlx << "Data" << arr_real.get();
01637     }
01638 
01639     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
01640     {
01641       const Uniform* cast_obj = obj->as<Uniform>(); VL_CHECK(cast_obj)
01642       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("uniform_"));
01643       // register exported object asap
01644       s.registerExportedObject(obj, vlx.get());
01645       exportUniform(cast_obj, vlx.get());
01646       return vlx;
01647     }
01648   };
01649 
01650   //---------------------------------------------------------------------------
01651 
01653   struct VLXClassWrapper_Shader: public VLXClassWrapper
01654   {
01655     void importShader(VLXSerializer& s, const VLXStructure* vlx, Shader* sh)
01656     {
01657       const VLXValue* name = vlx->getValue("ObjectName");
01658       if (name)
01659         sh->setObjectName( name->getString().c_str() );
01660 
01661       // enables
01662       const VLXValue* enables = vlx->getValue("Enables");
01663       if (enables)
01664       {
01665         VLX_IMPORT_CHECK_RETURN( enables->type() == VLXValue::List, *enables )
01666         const VLXList* list = enables->getList();
01667         for(size_t i=0; i<list->value().size(); ++i)
01668         {
01669           VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Identifier, list->value()[i] );
01670           EEnable en = vlx_EEnable( list->value()[i], s );
01671           VLX_IMPORT_CHECK_RETURN( en != EN_UnknownEnable, list->value()[i] );
01672           sh->enable(en);
01673         }
01674       }
01675 
01676       // render states
01677       const VLXValue* renderstates = vlx->getValue("RenderStates");
01678       if (renderstates)
01679       {
01680         VLX_IMPORT_CHECK_RETURN( renderstates->type() == VLXValue::List, *renderstates )
01681         const VLXList* list = renderstates->getList();
01682         int index = -1;
01683         for(size_t i=0; i<list->value().size(); ++i)
01684         {
01685           VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure || list->value()[i].type() == VLXValue::Integer, list->value()[i] );
01686           if (list->value()[i].type() == VLXValue::Integer)
01687           {
01688             VLX_IMPORT_CHECK_RETURN( index == -1, list->value()[i] );
01689             index = (int)list->value()[i].getInteger();
01690           }
01691           else
01692           {
01693             RenderState* renderstate = s.importVLX( list->value()[i].getStructure() )->as<RenderState>();
01694             VLX_IMPORT_CHECK_RETURN( renderstate != NULL, list->value()[i] )
01695             VLX_IMPORT_CHECK_RETURN( (index == -1 && !renderstate->isOfType(RenderStateIndexed::Type())) || (index >= 0 && renderstate->isOfType(RenderStateIndexed::Type())), list->value()[i] )
01696             sh->setRenderState(renderstate, index);
01697             // consume index in any case
01698             index = -1;
01699           }
01700         }
01701       }
01702       
01703       // uniforms
01704       const VLXValue* uniforms = vlx->getValue("Uniforms");
01705       if (uniforms)
01706       {
01707         VLX_IMPORT_CHECK_RETURN( uniforms->type() == VLXValue::List, *uniforms )
01708         const VLXList* list = uniforms->getList();
01709         for(size_t i=0; i<list->value().size(); ++i)
01710         {
01711           VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure, list->value()[i] );
01712           Uniform* uniform = s.importVLX( list->value()[i].getStructure() )->as<Uniform>();
01713           VLX_IMPORT_CHECK_RETURN( uniform != NULL, list->value()[i] )
01714           sh->setUniform(uniform);
01715         }
01716       }
01717     }
01718 
01719     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
01720     {
01721       ref<Shader> obj = new Shader;
01722       // register imported structure asap
01723       s.registerImportedStructure(vlx, obj.get());
01724       importShader(s, vlx, obj.get());
01725       return obj;
01726     }
01727 
01728     void exportShader(VLXSerializer& s, const Shader* obj, VLXStructure* vlx)
01729     {
01730       if (!obj->objectName().empty() && obj->objectName() != obj->className())
01731         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
01732 
01733       // uniforms
01734       VLXValue uniforms;
01735       uniforms.setList( new VLXList );
01736       if (obj->getUniformSet())
01737       {
01738         for(size_t i=0; i<obj->uniforms().size(); ++i)
01739           *uniforms.getList() << s.exportVLX(obj->uniforms()[i].get());
01740       }
01741       *vlx << "Uniforms" << uniforms;
01742 
01743       // enables
01744       ref<VLXList> enables = new VLXList;
01745       if (obj->getEnableSet() )
01746       {
01747         for(size_t i=0; i<obj->getEnableSet()->enables().size(); ++i)
01748           *enables << vlx_Identifier(vlx_EEnable(obj->getEnableSet()->enables()[i]));
01749       }
01750       *vlx << "Enables" << enables.get();
01751 
01752       // renderstates
01753       VLXValue renderstates;
01754       renderstates.setList( new VLXList );
01755       if (obj->getRenderStateSet())
01756       {
01757         for(size_t i=0; i<obj->getRenderStateSet()->renderStatesCount(); ++i)
01758         {
01759           const RenderState* rs = obj->getRenderStateSet()->renderStates()[i].mRS.get();
01760           if ( !s.canExport(rs) )
01761           {
01762             Log::debug( Say("VLXClassWrapper_Shader : skipping '%s'.\n") << rs->className() );
01763             continue;
01764           }
01765           int index = obj->getRenderStateSet()->renderStates()[i].mIndex;
01766           if (index != -1)
01767             *renderstates.getList() << (long long)index;
01768           *renderstates.getList() << s.exportVLX(rs);
01769         }
01770       }
01771       *vlx << "RenderStates" << renderstates;
01772     }
01773 
01774     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
01775     {
01776       const Shader* cast_obj = obj->as<Shader>(); VL_CHECK(cast_obj)
01777       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("shader_"));
01778       // register exported object asap
01779       s.registerExportedObject(obj, vlx.get());
01780       exportShader(s, cast_obj, vlx.get());
01781       return vlx;
01782     }
01783   };
01784 
01785   //---------------------------------------------------------------------------
01786 
01788   struct VLXClassWrapper_LODEvaluator: public VLXClassWrapper
01789   {
01790     void importLODEvaluator(VLXSerializer& s, const VLXStructure* vlx, LODEvaluator* obj)
01791     {
01792       if (obj->isOfType(DistanceLODEvaluator::Type()))
01793       {
01794         DistanceLODEvaluator* lod = obj->as<DistanceLODEvaluator>();
01795         const VLXValue* vlx_distances = vlx->getValue("DistanceRageSet");
01796         VLX_IMPORT_CHECK_RETURN( vlx_distances != NULL, *vlx );
01797         VLX_IMPORT_CHECK_RETURN( vlx_distances->type() == VLXValue::ArrayReal, *vlx_distances );
01798         const VLXArrayReal* arr = vlx_distances->getArrayReal();
01799         if (arr->value().size())
01800         {
01801           lod->distanceRangeSet().resize( arr->value().size() );
01802           arr->copyTo( &lod->distanceRangeSet()[0] );
01803         }
01804       }
01805       else
01806       if (obj->isOfType(PixelLODEvaluator::Type()))
01807       {
01808         PixelLODEvaluator* lod = obj->as<PixelLODEvaluator>();
01809         const VLXValue* vlx_pixels = vlx->getValue("PixelRageSet");
01810         VLX_IMPORT_CHECK_RETURN( vlx_pixels != NULL, *vlx );
01811         VLX_IMPORT_CHECK_RETURN( vlx_pixels->type() == VLXValue::ArrayReal, *vlx_pixels );
01812         const VLXArrayReal* arr = vlx_pixels->getArrayReal();
01813         if (arr->value().size())
01814         {
01815           lod->pixelRangeSet().resize( arr->value().size() );
01816           arr->copyTo( &lod->pixelRangeSet()[0] );
01817         }
01818       }
01819     }
01820 
01821     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
01822     {
01823       if (vlx->tag() == "<vl::DistanceLODEvaluator>")
01824       {
01825         ref<LODEvaluator> obj = new DistanceLODEvaluator;
01826         // register imported structure asap
01827         s.registerImportedStructure(vlx, obj.get());
01828         importLODEvaluator(s, vlx, obj.get());
01829         return obj;
01830       }
01831       else
01832       if (vlx->tag() == "<vl::PixelLODEvaluator>")
01833       {
01834         ref<LODEvaluator> obj = new PixelLODEvaluator;
01835         // register imported structure asap
01836         s.registerImportedStructure(vlx, obj.get());
01837         importLODEvaluator(s, vlx, obj.get());
01838         return obj;
01839       }
01840       else
01841       {
01842         return NULL;
01843       }
01844     }
01845 
01846     void exportLODEvaluator(VLXSerializer& s, const LODEvaluator* obj, VLXStructure* vlx)
01847     {
01848       if (obj->classType() == DistanceLODEvaluator::Type())
01849       {
01850         const DistanceLODEvaluator* lod = obj->as<DistanceLODEvaluator>();
01851         VLXValue distances( new VLXArrayReal );
01852         distances.getArrayReal()->value().resize( lod->distanceRangeSet().size() );
01853         if (lod->distanceRangeSet().size() != 0)
01854           distances.getArrayReal()->copyFrom( &lod->distanceRangeSet()[0] );
01855         *vlx << "DistanceRageSet" << distances;
01856       }
01857       else
01858       if (obj->classType() == PixelLODEvaluator::Type())
01859       {
01860         const PixelLODEvaluator* lod = obj->as<PixelLODEvaluator>();
01861         VLXValue pixels( new VLXArrayReal );
01862         pixels.getArrayReal()->value().resize( lod->pixelRangeSet().size() );
01863         if (lod->pixelRangeSet().size() != 0)
01864           pixels.getArrayReal()->copyFrom( &lod->pixelRangeSet()[0] );
01865         *vlx << "PixelRageSet" << pixels;
01866       }
01867       else
01868       {
01869         s.signalExportError("LODEvaluator type not supported for export.\n");
01870       }
01871     }
01872 
01873     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
01874     {
01875       const LODEvaluator* cast_obj = obj->as<LODEvaluator>(); VL_CHECK(cast_obj)
01876       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("lodeval_"));
01877       // register exported object asap
01878       s.registerExportedObject(obj, vlx.get());
01879       exportLODEvaluator(s, cast_obj, vlx.get());
01880       return vlx;
01881     }
01882   };
01883 
01884   //---------------------------------------------------------------------------
01885 
01887   struct VLXClassWrapper_Effect: public VLXClassWrapper
01888   {
01889     void importEffect(VLXSerializer& s, const VLXStructure* vlx, Effect* obj)
01890     {
01891       const VLXValue* name = vlx->getValue("ObjectName");
01892       if (name)
01893         obj->setObjectName( name->getString().c_str() );
01894 
01895       const std::vector<VLXStructure::Value>& values = vlx->value();
01896       for(size_t i=0; i<values.size(); ++i)
01897       {
01898         const std::string& key = values[i].key();
01899         const VLXValue& value = values[i].value();
01900         if (key == "RenderRank")
01901         {
01902           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
01903           obj->setRenderRank( (int)value.getInteger() );
01904         }
01905         else
01906         if (key == "EnableMask")
01907         {
01908           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
01909           obj->setEnableMask( (int)value.getInteger() );
01910         }
01911         else
01912         if (key == "ActiveLod")
01913         {
01914           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
01915           obj->setActiveLod( (int)value.getInteger() );
01916         }
01917         else
01918         if (key == "LODEvaluator")
01919         {
01920           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
01921           LODEvaluator* lod_eval = s.importVLX( value.getStructure() )->as<LODEvaluator>();
01922           VLX_IMPORT_CHECK_RETURN( lod_eval, value )
01923           obj->setLODEvaluator(lod_eval);
01924         }
01925         else
01926         if (key == "Lods")
01927         {
01928           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
01929           const VLXList* lod_list = value.getList();
01930           for(size_t ilod=0; ilod< lod_list->value().size(); ++ilod)
01931           {
01932             const VLXValue& lod_shaders = lod_list->value()[ilod];
01933             VLX_IMPORT_CHECK_RETURN( lod_shaders.type() == VLXValue::List, lod_shaders )
01934             obj->lod(ilod) = new ShaderPasses;
01935             for( size_t ish=0; ish<lod_shaders.getList()->value().size(); ++ish)
01936             {
01937               const VLXValue& vlx_sh = lod_shaders.getList()->value()[ish];
01938               VLX_IMPORT_CHECK_RETURN( vlx_sh.type() == VLXValue::Structure, vlx_sh )
01939               Shader* shader = s.importVLX( vlx_sh.getStructure() )->as<Shader>();
01940               VLX_IMPORT_CHECK_RETURN( shader, vlx_sh )
01941               obj->lod(ilod)->push_back( shader );
01942             }
01943           }
01944         }
01945       }
01946     }
01947 
01948     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
01949     {
01950       ref<Effect> obj = new Effect;
01951       // register imported structure asap
01952       s.registerImportedStructure(vlx, obj.get());
01953       importEffect(s, vlx, obj.get());
01954       return obj;
01955     }
01956 
01957     VLXValue export_ShaderPasses(VLXSerializer& s, const ShaderPasses* sh_seq)
01958     {
01959       VLXValue value( new VLXList(vlx_makeTag(sh_seq).c_str()) );
01960       for(int i=0; i<sh_seq->size(); ++i)
01961         *value.getList() << s.exportVLX(sh_seq->at(i));
01962       return value;
01963     }
01964 
01965     void exportEffect(VLXSerializer& s, const Effect* obj, VLXStructure* vlx)
01966     {
01967       if (!obj->objectName().empty() && obj->objectName() != obj->className())
01968         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
01969       *vlx << "RenderRank" << (long long)obj->renderRank();
01970       *vlx << "EnableMask" << (long long)obj->enableMask();
01971       *vlx << "ActiveLod" << (long long)obj->activeLod();
01972 
01973       if (obj->lodEvaluator())
01974         *vlx << "LODEvaluator" << s.exportVLX(obj->lodEvaluator());
01975 
01976       // shaders
01977       ref<VLXList> lod_list = new VLXList;
01978       for(int i=0; obj->lod(i) && i<VL_MAX_EFFECT_LOD; ++i)
01979         *lod_list << export_ShaderPasses(s, obj->lod(i).get());
01980       *vlx << "Lods" << lod_list.get();
01981     }
01982 
01983     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
01984     {
01985       const Effect* cast_obj = obj->as<Effect>(); VL_CHECK(cast_obj)
01986       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("effect_"));
01987       // register exported object asap
01988       s.registerExportedObject(obj, vlx.get());
01989       exportEffect(s, cast_obj, vlx.get());
01990       return vlx;
01991     }
01992   };
01993 
01994   //---------------------------------------------------------------------------
01995 
01997   struct VLXClassWrapper_Actor: public VLXClassWrapper
01998   {
01999     void importActor(VLXSerializer& s, const VLXStructure* vlx, Actor* obj)
02000     {
02001       const VLXValue* name = vlx->getValue("ObjectName");
02002       if (name)
02003         obj->setObjectName( name->getString().c_str() );
02004 
02005       const std::vector<VLXStructure::Value>& values = vlx->value();
02006       for(size_t i=0; i<values.size(); ++i)
02007       {
02008         const std::string& key = values[i].key();
02009         const VLXValue& value = values[i].value();
02010         if (key == "RenderRank")
02011         {
02012           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
02013           obj->setRenderRank( (int)value.getInteger() );
02014         }
02015         else
02016         if (key == "RenderBlock")
02017         {
02018           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
02019           obj->setRenderBlock( (int)value.getInteger() );
02020         }
02021         else
02022         if (key == "EnableMask")
02023         {
02024           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
02025           obj->setEnableMask( (int)value.getInteger() );
02026         }
02027         else
02028         if (key == "IsOccludee")
02029         {
02030           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value )
02031           obj->setOccludee( value.getBool() );
02032         }
02033         else
02034         if (key == "Lods")
02035         {
02036           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
02037           const VLXList* list = value.getList();
02038           for(size_t i=0; i<list->value().size(); ++i)
02039           {
02040             const VLXValue& lod = list->value()[i];
02041             VLX_IMPORT_CHECK_RETURN( lod.type() == VLXValue::Structure, lod )
02042             Renderable* rend = s.importVLX( lod.getStructure() )->as<Renderable>();
02043             VLX_IMPORT_CHECK_RETURN( rend != NULL, lod )
02044             obj->setLod(i, rend);
02045           }
02046         }
02047         else
02048         if (key == "Effect")
02049         {
02050           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
02051           Effect* fx = s.importVLX(value.getStructure())->as<Effect>();
02052           VLX_IMPORT_CHECK_RETURN( fx != NULL, value )
02053           obj->setEffect(fx);
02054         }
02055         else
02056         if (key == "Transform")
02057         {
02058           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
02059           Transform* tr = s.importVLX(value.getStructure())->as<Transform>();
02060           VLX_IMPORT_CHECK_RETURN( tr != NULL, value )
02061           obj->setTransform(tr);
02062         }
02063         else
02064         if (key == "Uniforms")
02065         {
02066           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
02067           const VLXList* list = value.getList();
02068           for(size_t i=0; i<list->value().size(); ++i)
02069           {
02070             VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure, list->value()[i] )
02071             Uniform* uniform = s.importVLX( list->value()[i].getStructure() )->as<Uniform>();
02072             VLX_IMPORT_CHECK_RETURN( uniform != NULL, list->value()[i] )
02073             obj->setUniform(uniform);
02074           }
02075         }
02076         // bounding volumes are not serialized, they are computed based on the geometry's bounds
02077         // else if (key == "AABB") {}
02078         // else if (key == "Sphere") {}
02079         else
02080         if (key == "LODEvaluator")
02081         {
02082           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
02083           if (s.canImport( value.getStructure() ) )
02084           {
02085             LODEvaluator* lod = s.importVLX( value.getStructure() )->as<LODEvaluator>();
02086             VLX_IMPORT_CHECK_RETURN( lod != NULL, value )
02087             obj->setLODEvaluator(lod);
02088           }
02089         }
02090         else
02091         if (key == "ActorEventCallbacks")
02092         {
02093           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
02094           const VLXList* list = value.getList();
02095           for(size_t i=0; i<list->value().size(); ++i)
02096           {
02097             const VLXValue& elem = list->value()[i];
02098             VLX_IMPORT_CHECK_RETURN( elem.type() == VLXValue::Structure, elem )
02099             if (s.canImport(elem.getStructure()))
02100             {
02101               ActorEventCallback* cb = s.importVLX( elem.getStructure() )->as<ActorEventCallback>();
02102               VLX_IMPORT_CHECK_RETURN( cb != NULL, elem )
02103               obj->actorEventCallbacks()->push_back(cb);
02104             }
02105           }
02106         }
02107       }
02108     }
02109 
02110     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02111     {
02112       ref<Actor> obj = new Actor;
02113       // register imported structure asap
02114       s.registerImportedStructure(vlx, obj.get());
02115       importActor(s, vlx, obj.get());
02116       return obj;
02117     }
02118 
02119     void exportActor(VLXSerializer& s, const Actor* obj, VLXStructure* vlx)
02120     {
02121       if (!obj->objectName().empty() && obj->objectName() != obj->className())
02122         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
02123       *vlx << "EnableMask" << (long long)obj->enableMask();
02124       *vlx << "RenderBlock" << (long long)obj->renderBlock();
02125       *vlx << "RenderRank" << (long long)obj->renderRank();
02126       *vlx << "IsOccludee" << obj->isOccludee();
02127 
02128       VLXValue renderables;
02129       renderables.setList( new VLXList );
02130       for(size_t i=0; i<VL_MAX_ACTOR_LOD && obj->lod(i); ++i)
02131         *renderables.getList() << s.exportVLX(obj->lod(i));
02132       *vlx << "Lods" << renderables;
02133 
02134       // bounding volumes are not serialized, they are computed based on the geometry's bounds
02135       // *vlx << "AABB" << export_AABB(obj->boundingBox());
02136       // *vlx << "Sphere" << export_Sphere(obj->boundingSphere());
02137 
02138       if (obj->effect())
02139         *vlx << "Effect" << s.exportVLX(obj->effect());
02140       if (obj->transform())
02141         *vlx << "Transform" << s.exportVLX(obj->transform());
02142 
02143       VLXValue uniforms;
02144       uniforms.setList( new VLXList );
02145       for(size_t i=0; obj->getUniformSet() && i<obj->uniforms().size(); ++i)
02146         *uniforms.getList() << s.exportVLX(obj->uniforms()[i].get());
02147       *vlx << "Uniforms" << uniforms;
02148 
02149       if (obj->lodEvaluator())
02150         *vlx << "LODEvaluator" << s.exportVLX(obj->lodEvaluator());
02151 
02152       // mic fixme:
02153       // Scissor: scissors might go away from the Actor
02154 
02155       VLXValue callbacks;
02156       callbacks.setList( new VLXList );
02157       for(int i=0; i<obj->actorEventCallbacks()->size(); ++i)
02158         *callbacks.getList() << s.exportVLX(obj->actorEventCallbacks()->at(i));
02159       *vlx << "ActorEventCallbacks" << callbacks;
02160     }
02161 
02162     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
02163     {
02164       const Actor* cast_obj = obj->as<Actor>(); VL_CHECK(cast_obj)
02165       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("actor_"));
02166       // register exported object asap
02167       s.registerExportedObject(obj, vlx.get());
02168       exportActor(s, cast_obj, vlx.get());
02169       return vlx;
02170     }
02171   };
02172 
02173   //---------------------------------------------------------------------------
02174 
02176   struct VLXClassWrapper_Camera: public VLXClassWrapper
02177   {
02178     void importCamera(VLXSerializer& s, const VLXStructure* vlx, Camera* obj)
02179     {
02180       const VLXValue* name = vlx->getValue("ObjectName");
02181       if (name)
02182         obj->setObjectName( name->getString().c_str() );
02183 
02184       for(size_t i=0; i<vlx->value().size(); ++i)
02185       {
02186         const std::string& key = vlx->value()[i].key();
02187         const VLXValue& value = vlx->value()[i].value();
02188         if (key == "ViewMatrix")
02189         {
02190           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value);
02191           obj->setViewMatrix( vlx_mat4(value.getList()) );
02192           // VLX_IMPORT_CHECK_RETURN( !obj->viewMatrix().isNull(), value )
02193         }
02194         else
02195         if (key == "ProjectionMatrix")
02196         {
02197           EProjectionMatrixType ptype = PMT_UserProjection;
02198           const VLXValue* pmtype = vlx->getValue("ProjectionMatrixType");
02199           if ( pmtype )
02200           {
02201             VLX_IMPORT_CHECK_RETURN( pmtype->type() == VLXValue::Identifier, *pmtype );
02202             ptype = vlx_EProjectionMatrixType( *pmtype, s );
02203           }
02204 
02205           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value);
02206           obj->setProjectionMatrix( vlx_mat4(value.getList()), ptype );
02207           // VLX_IMPORT_CHECK_RETURN( !obj->projectionMatrix().isNull(), value )
02208         }
02209         else
02210         if (key == "Viewport")
02211         {
02212           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value)
02213           Viewport* viewp = s.importVLX( value.getStructure() )->as<Viewport>();
02214           VLX_IMPORT_CHECK_RETURN( viewp != NULL, value )
02215           obj->setViewport(viewp);
02216         }
02217         else
02218         if (key == "FOV")
02219         {
02220           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02221           obj->setFOV( (float)value.getReal() );
02222         }
02223         else
02224         if (key == "NearPlane")
02225         {
02226           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02227           obj->setNearPlane( (float)value.getReal() );
02228         }
02229         else
02230         if (key == "FarPlane")
02231         {
02232           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02233           obj->setFarPlane( (float)value.getReal() );
02234         }
02235         else
02236         if (key == "Left")
02237         {
02238           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02239           obj->setLeft( (float)value.getReal() );
02240         }
02241         else
02242         if (key == "Right")
02243         {
02244           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02245           obj->setRight( (float)value.getReal() );
02246         }
02247         else
02248         if (key == "Bottom")
02249         {
02250           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02251           obj->setBottom( (float)value.getReal() );
02252         }
02253         else
02254         if (key == "Top")
02255         {
02256           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02257           obj->setTop( (float)value.getReal() );
02258         }
02259         else
02260         if (key == "BoundTransform")
02261         {
02262           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value)
02263           Transform* tr= s.importVLX( value.getStructure() )->as<Transform>();
02264           VLX_IMPORT_CHECK_RETURN( tr != NULL, value )
02265           obj->bindTransform(tr);
02266         }
02267       }
02268     }
02269 
02270     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02271     {
02272       ref<Camera> obj = new Camera;
02273       // register imported structure asap
02274       s.registerImportedStructure(vlx, obj.get());
02275       importCamera(s, vlx, obj.get());
02276       return obj;
02277     }
02278 
02279     void exportCamera(VLXSerializer& s, const Camera* obj, VLXStructure* vlx)
02280     {
02281       if (!obj->objectName().empty() && obj->objectName() != obj->className())
02282         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
02283       *vlx << "ViewMatrix" << vlx_toValue(obj->viewMatrix());
02284       *vlx << "ProjectionMatrix" << vlx_toValue(obj->projectionMatrix());
02285       *vlx << "ProjectionMatrixType" << vlx_Identifier(vlx_EProjectionMatrixType(obj->projectionMatrixType()));
02286       *vlx << "Viewport" << s.exportVLX(obj->viewport());
02287       *vlx << "NearPlane" << (double)obj->nearPlane();
02288       *vlx << "FarPlane" << (double)obj->farPlane();
02289       *vlx << "FOV" << (double)obj->fov();
02290       *vlx << "Left" << (double)obj->left();
02291       *vlx << "Right" << (double)obj->right();
02292       *vlx << "Bottom" << (double)obj->bottom();
02293       *vlx << "Top" << (double)obj->top();
02294       if (obj->boundTransform())
02295         *vlx << "BoundTransfrm" << s.exportVLX(obj->boundTransform());
02296     }
02297 
02298     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
02299     {
02300       const Camera* cast_obj = obj->as<Camera>(); VL_CHECK(cast_obj)
02301       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("camera_"));
02302       // register exported object asap
02303       s.registerExportedObject(obj, vlx.get());
02304       exportCamera(s, cast_obj, vlx.get());
02305       return vlx;
02306     }
02307   };
02308 
02309 
02310   //---------------------------------------------------------------------------
02311 
02313   struct VLXClassWrapper_Viewport: public VLXClassWrapper
02314   {
02315     void importViewport(VLXSerializer& s, const VLXStructure* vlx, Viewport* obj)
02316     {
02317       const VLXValue* name = vlx->getValue("ObjectName");
02318       if (name)
02319         obj->setObjectName( name->getString().c_str() );
02320 
02321       for(size_t i=0; i<vlx->value().size(); ++i)
02322       {
02323         const std::string& key = vlx->value()[i].key();
02324         const VLXValue& value = vlx->value()[i].value();
02325         if (key == "ClearColor")
02326         {
02327           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
02328           obj->setClearColor( (fvec4)vlx_vec4( value.getArrayReal() ) );
02329         }
02330         else
02331         if (key == "ClearColorInt")
02332         {
02333           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger, value );
02334           obj->setClearColorInt( vlx_ivec4( value.getArrayInteger() ) );
02335         }
02336         else
02337         if (key == "ClearColorUInt")
02338         {
02339           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger, value );
02340           obj->setClearColorUInt( vlx_uivec4( value.getArrayInteger() ) );
02341         }
02342         else
02343         if (key == "ClearDepth")
02344         {
02345           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value );
02346           obj->setClearDepth( (float)value.getReal() );
02347         }
02348         else
02349         if (key == "ClearStecil")
02350         {
02351           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
02352           obj->setClearStencil( (int)value.getInteger() );
02353         }
02354         else
02355         if (key == "ClearColorMode")
02356         {
02357           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
02358           obj->setClearColorMode( vlx_EClearColorMode( value, s) );
02359         }
02360         else
02361         if (key == "ClearFlags")
02362         {
02363           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
02364           obj->setClearFlags( vlx_EClearFlags( value, s ) );
02365         }
02366         else
02367         if (key == "X")
02368         {
02369           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
02370           obj->setX( (int)value.getInteger()  );
02371         }
02372         else
02373         if (key == "Y")
02374         {
02375           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
02376           obj->setY( (int)value.getInteger()  );
02377         }
02378         else
02379         if (key == "Width")
02380         {
02381           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
02382           obj->setWidth( (int)value.getInteger()  );
02383         }
02384         else
02385         if (key == "Height")
02386         {
02387           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
02388           obj->setHeight( (int)value.getInteger()  );
02389         }
02390       }
02391     }
02392 
02393     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02394     {
02395       ref<Viewport> obj = new Viewport;
02396       // register imported structure asap
02397       s.registerImportedStructure(vlx, obj.get());
02398       importViewport(s, vlx, obj.get());
02399       return obj;
02400     }
02401 
02402     void exportViewport(const Viewport* obj, VLXStructure* vlx)
02403     {
02404       if (!obj->objectName().empty() && obj->objectName() != obj->className())
02405         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
02406       *vlx << "ClearColor" << vlx_toValue((vec4)obj->clearColor());
02407       *vlx << "ClearColorInt" << vlx_toValue(obj->clearColorInt());
02408       *vlx << "ClearColorUInt" << vlx_toValue(obj->clearColorUInt());
02409       *vlx << "ClearDepth" << (double)obj->clearDepth();
02410       *vlx << "ClearStecil" << (long long)obj->clearStencil();
02411       *vlx << "ClearColorMode" << vlx_Identifier(vlx_EClearColorMode(obj->clearColorMode()));
02412       *vlx << "ClearFlags" << vlx_Identifier(vlx_EClearFlags(obj->clearFlags()));
02413       *vlx << "X" << (long long)obj->x();
02414       *vlx << "Y" << (long long)obj->y();
02415       *vlx << "Width" << (long long)obj->width();
02416       *vlx << "Height" << (long long)obj->height();
02417     }
02418 
02419     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
02420     {
02421       const Viewport* cast_obj = obj->as<Viewport>(); VL_CHECK(cast_obj)
02422       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("viewport_"));
02423       // register exported object asap
02424       s.registerExportedObject(obj, vlx.get());
02425       exportViewport(cast_obj, vlx.get());
02426       return vlx;
02427     }
02428   };
02429 
02430   //---------------------------------------------------------------------------
02431 
02433   struct VLXClassWrapper_Transform: public VLXClassWrapper
02434   {
02435     void importTransform(VLXSerializer& s, const VLXStructure* vlx, Transform* obj)
02436     {
02437       const VLXValue* name = vlx->getValue("ObjectName");
02438       if (name)
02439         obj->setObjectName( name->getString().c_str() );
02440 
02441       for(size_t i=0; i<vlx->value().size(); ++i)
02442       {
02443         const std::string& key = vlx->value()[i].key();
02444         const VLXValue& value = vlx->value()[i].value();
02445         if (key == "LocalMatrix")
02446         {
02447           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
02448           obj->setLocalAndWorldMatrix( vlx_mat4( value.getList() ) );
02449         }
02450         else
02451         // let the "Children" property take care of children binding
02452         /*
02453         if (key == "Parent")
02454         {
02455           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
02456           Transform* tr = s.importVLX( value.getStructure() )->as<Transform>();
02457           VLX_IMPORT_CHECK_RETURN( tr != NULL, value )
02458           tr->addChild(obj);
02459         }
02460         else
02461         */
02462         if (key == "Children")
02463         {
02464           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
02465           const VLXList* list = value.getList();
02466           for(size_t ich=0; ich<list->value().size(); ++ich)
02467           {
02468             VLX_IMPORT_CHECK_RETURN( list->value()[ich].type() == VLXValue::Structure, list->value()[ich] )
02469             const VLXStructure* vlx_tr = list->value()[ich].getStructure();
02470             Transform* child = s.importVLX( vlx_tr )->as<Transform>();
02471             VLX_IMPORT_CHECK_RETURN( child != NULL, *vlx_tr )
02472             obj->addChild(child);
02473           }
02474         }
02475       }
02476     }
02477 
02478     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02479     {
02480       ref<Transform> obj = new Transform;
02481       // register imported structure asap
02482       s.registerImportedStructure(vlx, obj.get());
02483       importTransform(s, vlx, obj.get());
02484       return obj;
02485     }
02486 
02487     void exportTransform(VLXSerializer& s, const Transform* obj, VLXStructure* vlx)
02488     {
02489       if (!obj->objectName().empty() && obj->objectName() != obj->className())
02490         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
02491       *vlx << "LocalMatrix" << vlx_toValue(obj->localMatrix());
02492 
02493       // not needed
02494       /*if (obj->parent())
02495         *vlx << "Parent" << s.exportVLX(obj->parent());*/
02496 
02497       VLXValue childs;
02498       childs.setList( new VLXList );
02499       for(size_t i=0; i<obj->childrenCount(); ++i)
02500         childs.getList()->value().push_back( s.exportVLX(obj->children()[i].get()) );
02501       *vlx << "Children" << childs;
02502     }
02503 
02504     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
02505     {
02506       const Transform* cast_obj = obj->as<Transform>(); VL_CHECK(cast_obj)
02507       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("transform_"));
02508       // register exported object asap
02509       s.registerExportedObject(obj, vlx.get());
02510       exportTransform(s, cast_obj, vlx.get());
02511       return vlx;
02512     }
02513   };
02514 
02515   //---------------------------------------------------------------------------
02516 
02518   struct VLXClassWrapper_Light: public VLXClassWrapper
02519   {
02520     void importLight(VLXSerializer& s, const VLXStructure* vlx, Light* obj)
02521     {
02522       const VLXValue* name = vlx->getValue("ObjectName");
02523       if (name)
02524         obj->setObjectName( name->getString().c_str() );
02525 
02526       for(size_t i=0; i<vlx->value().size(); ++i)
02527       {
02528         const std::string& key = vlx->value()[i].key();
02529         const VLXValue& value = vlx->value()[i].value();
02530         if (key == "Ambient")
02531         {
02532           // note: what if the user specifies ( 1 0 0 0 ) -> becomes a ArrayInteger and an error is issued.
02533           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
02534           obj->setAmbient( (fvec4)vlx_vec4( value.getArrayReal() ) );
02535         }
02536         else
02537         if (key == "Diffuse")
02538         {
02539           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
02540           obj->setDiffuse( (fvec4)vlx_vec4( value.getArrayReal() ) );
02541         }
02542         else
02543         if (key == "Specular")
02544         {
02545           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
02546           obj->setSpecular( (fvec4)vlx_vec4( value.getArrayReal() ) );
02547         }
02548         else
02549         if (key == "Position")
02550         {
02551           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
02552           obj->setPosition( (fvec4)vlx_vec4( value.getArrayReal() ) );
02553         }
02554         else
02555         if (key == "SpotDirection")
02556         {
02557           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
02558           obj->setSpotDirection( (fvec3)vlx_vec3( value.getArrayReal() ) );
02559         }
02560         else
02561         if (key == "SpotExponent")
02562         {
02563           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02564           obj->setSpotExponent( (float)value.getReal() );
02565         }
02566         else
02567         if (key == "SpotCutoff")
02568         {
02569           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02570           obj->setSpotCutoff( (float)value.getReal() );
02571         }
02572         else
02573         if (key == "ConstantAttenuation")
02574         {
02575           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02576           obj->setConstantAttenuation( (float)value.getReal() );
02577         }
02578         else
02579         if (key == "LinearAttenuation")
02580         {
02581           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02582           obj->setLinearAttenuation( (float)value.getReal() );
02583         }
02584         else
02585         if (key == "QuadraticAttenuation")
02586         {
02587           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02588           obj->setQuadraticAttenuation( (float)value.getReal() );
02589         }
02590         else
02591         if (key == "BoundTransform")
02592         {
02593           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value)
02594           Transform* tr= s.importVLX( value.getStructure() )->as<Transform>();
02595           VLX_IMPORT_CHECK_RETURN( tr != NULL, value )
02596           obj->bindTransform(tr);
02597         }
02598       }
02599     }
02600 
02601     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02602     {
02603       ref<Light> obj = new Light;
02604       // register imported structure asap
02605       s.registerImportedStructure(vlx, obj.get());
02606       importLight(s, vlx, obj.get());
02607       return obj;
02608     }
02609 
02610     void exportLight(VLXSerializer& s, const Light* obj, VLXStructure* vlx)
02611     {
02612       if (!obj->objectName().empty() && obj->objectName() != obj->className())
02613         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
02614       *vlx << "Ambient" << vlx_toValue((vec4)obj->ambient());
02615       *vlx << "Diffuse" << vlx_toValue((vec4)obj->diffuse());
02616       *vlx << "Specular" << vlx_toValue((vec4)obj->specular());
02617       *vlx << "Position" << vlx_toValue((vec4)obj->position());
02618       *vlx << "SpotDirection" << vlx_toValue((vec3)obj->spotDirection());
02619       *vlx << "SpotExponent" << obj->spotExponent();
02620       *vlx << "SpotCutoff" << obj->spotCutoff();
02621       *vlx << "ConstantAttenuation" << obj->constantAttenuation();
02622       *vlx << "LinearAttenuation" << obj->linearAttenuation();
02623       *vlx << "QuadraticAttenuation" << obj->quadraticAttenuation();
02624       if (obj->boundTransform())
02625         *vlx << "BoundTransform" << s.exportVLX(obj->boundTransform());
02626     }
02627 
02628     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
02629     {
02630       const Light* cast_obj = obj->as<Light>(); VL_CHECK(cast_obj)
02631       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("light_"));
02632       // register exported object asap
02633       s.registerExportedObject(obj, vlx.get());
02634       exportLight(s, cast_obj, vlx.get());
02635       return vlx;
02636     }
02637   };
02638 
02639   //---------------------------------------------------------------------------
02640 
02642   struct VLXClassWrapper_ClipPlane: public VLXClassWrapper
02643   {
02644     void importClipPlane(VLXSerializer& s, const VLXStructure* vlx, ClipPlane* obj)
02645     {
02646       for(size_t i=0; i<vlx->value().size(); ++i)
02647       {
02648         const std::string& key = vlx->value()[i].key();
02649         const VLXValue& value = vlx->value()[i].value();
02650         if (key == "PlaneNormal")
02651         {
02652           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
02653           obj->plane().setNormal( vlx_vec3( value.getArrayReal() ) );
02654         }
02655         else
02656         if (key == "PlaneOrigin")
02657         {
02658           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
02659           obj->plane().setOrigin( (float)value.getReal() );
02660         }
02661         else
02662         if (key == "BoundTransform")
02663         {
02664           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value)
02665           Transform* tr= s.importVLX( value.getStructure() )->as<Transform>();
02666           VLX_IMPORT_CHECK_RETURN( tr != NULL, value )
02667           obj->bindTransform(tr);
02668         }
02669       }
02670     }
02671 
02672     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02673     {
02674       ref<ClipPlane> obj = new ClipPlane;
02675       // register imported structure asap
02676       s.registerImportedStructure(vlx, obj.get());
02677       importClipPlane(s, vlx, obj.get());
02678       return obj;
02679     }
02680 
02681     void exportClipPlane(VLXSerializer& s, const ClipPlane* clip, VLXStructure* vlx)
02682     {
02683       *vlx << "PlaneNormal" << vlx_toValue(clip->plane().normal());
02684       *vlx << "PlaneOrigin" << clip->plane().origin();
02685       if (clip->boundTransform())
02686         *vlx << "BoundTransform" << s.exportVLX(clip->boundTransform());
02687     }
02688 
02689     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
02690     {
02691       const ClipPlane* cast_obj = obj->as<ClipPlane>(); VL_CHECK(cast_obj)
02692       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("clipplane_"));
02693       // register exported object asap
02694       s.registerExportedObject(obj, vlx.get());
02695       exportClipPlane(s, cast_obj, vlx.get());
02696       return vlx;
02697     }
02698   };
02699 
02700   //---------------------------------------------------------------------------
02701 
02703   struct VLXClassWrapper_GLSLProgram: public VLXClassWrapper
02704   {
02705     void importGLSLProgram(VLXSerializer& s, const VLXStructure* vlx, GLSLProgram* obj)
02706     {
02707       const VLXValue* name = vlx->getValue("ObjectName");
02708       if (name)
02709         obj->setObjectName( name->getString().c_str() );
02710 
02711       for(size_t i=0; i<vlx->value().size(); ++i)
02712       {
02713         const std::string& key = vlx->value()[i].key();
02714         const VLXValue& value = vlx->value()[i].value();
02715         if (key == "AttachShader")
02716         {
02717           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
02718           const VLXStructure* st = value.getStructure();
02719           GLSLShader* glsl_sh = s.importVLX(st)->as<GLSLShader>();
02720           VLX_IMPORT_CHECK_RETURN( glsl_sh != NULL, *st )
02721           obj->attachShader(glsl_sh);
02722         }
02723         else
02724         if (key == "FragDataLocation")
02725         {
02726           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
02727           const VLXList* list = value.getList();
02728           VLX_IMPORT_CHECK_RETURN( list->value().size() == 2, *list )
02729           VLX_IMPORT_CHECK_RETURN( list->value()[0].type() == VLXValue::Identifier, *list )
02730           VLX_IMPORT_CHECK_RETURN( list->value()[1].type() == VLXValue::Integer, *list )
02731           const char* name = list->value()[0].getIdentifier().c_str();
02732           int index = (int)list->value()[1].getInteger();
02733           obj->bindFragDataLocation(index, name);
02734         }
02735         else
02736         if (key == "AttribLocation")
02737         {
02738           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
02739           const VLXList* list = value.getList();
02740           VLX_IMPORT_CHECK_RETURN( list->value().size() == 2, *list )
02741           VLX_IMPORT_CHECK_RETURN( list->value()[0].type() == VLXValue::Identifier, *list )
02742           VLX_IMPORT_CHECK_RETURN( list->value()[1].type() == VLXValue::Integer, *list )
02743           const char* name = list->value()[0].getIdentifier().c_str();
02744           int index = (int)list->value()[1].getInteger();
02745           obj->addAutoAttribLocation(index, name);
02746         }
02747         else
02748         if (key == "Uniforms")
02749         {
02750           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
02751           const VLXList* list = value.getList();
02752           for(size_t i=0; i<list->value().size(); ++i)
02753           {
02754             VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure, list->value()[i] )
02755             Uniform* uniform = s.importVLX( list->value()[i].getStructure() )->as<Uniform>();
02756             VLX_IMPORT_CHECK_RETURN( uniform != NULL, list->value()[i] )
02757             obj->setUniform(uniform);
02758           }
02759         }
02760       }
02761     }
02762 
02763     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02764     {
02765       ref<GLSLProgram> obj = new GLSLProgram;
02766       // register imported structure asap
02767       s.registerImportedStructure(vlx, obj.get());
02768       importGLSLProgram(s, vlx, obj.get());
02769       return obj;
02770     }
02771 
02772     void exportGLSLProgram(VLXSerializer& s, const GLSLProgram* obj, VLXStructure* vlx)
02773     {
02774       if (!obj->objectName().empty() && obj->objectName() != obj->className())
02775         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
02776 
02777       // export obj shaders
02778       for(int i=0; i<obj->shaderCount(); ++i)
02779         *vlx << "AttachShader" << s.exportVLX(obj->shader(i));
02780 
02781       // export uniforms
02782       VLXValue uniforms;
02783       uniforms.setList( new VLXList );
02784       for(size_t i=0; obj->getUniformSet() && i<obj->getUniformSet()->uniforms().size(); ++i)
02785         *uniforms.getList() << s.exportVLX(obj->getUniformSet()->uniforms()[i].get());
02786       *vlx << "Uniforms" << uniforms;
02787 
02788       // frag data location
02789       for(std::map<std::string, int>::const_iterator it = obj->fragDataLocations().begin(); it != obj->fragDataLocations().end(); ++it)
02790       {
02791         VLXList* location = new VLXList;
02792         *location << vlx_Identifier(it->first); // Name
02793         *location << (long long)it->second;   // Location
02794         *vlx << "FragDataLocation" << location;
02795       }
02796 
02797       // auto attrib locations
02798       for(std::map<std::string, int>::const_iterator it = obj->autoAttribLocations().begin(); it != obj->autoAttribLocations().end(); ++it)
02799       {
02800         VLXList* location = new VLXList;
02801         *location << vlx_Identifier(it->first); // Name
02802         *location << (long long)it->second;   // Location
02803         *vlx << "AttribLocation" << location;
02804       }
02805     }
02806 
02807     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
02808     {
02809       const GLSLProgram* cast_obj = obj->as<GLSLProgram>(); VL_CHECK(cast_obj)
02810       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("glslprog_"));
02811       // register exported object asap
02812       s.registerExportedObject(obj, vlx.get());
02813       exportGLSLProgram(s, cast_obj, vlx.get());
02814       return vlx;
02815     }
02816   };
02817 
02818   //---------------------------------------------------------------------------
02819 
02821   struct VLXClassWrapper_GLSLShader: public VLXClassWrapper
02822   {
02823     void importGLSLShader(VLXSerializer& s, const VLXStructure* vlx, GLSLShader* obj)
02824     {
02825       const VLXValue* path   = vlx->getValue("Path");
02826       const VLXValue* source = vlx->getValue("Source");
02827       VLX_IMPORT_CHECK_RETURN( path != NULL || source != NULL, *vlx )
02828       if (path)
02829       {
02830         VLX_IMPORT_CHECK_RETURN( path->type() == VLXValue::String, *path )
02831         std::string resolved_path = path->getString();
02832         s.resolvePath(resolved_path);
02833         obj->setSource(resolved_path.c_str()); // this automatically loads the source and sets the path
02834       }
02835       else
02836       if (source)
02837       {
02838         VLX_IMPORT_CHECK_RETURN( source->type() == VLXValue::RawtextBlock, *source )
02839         obj->setSource(source->getRawtextBlock()->value().c_str());
02840       }
02841       else
02842       {
02843         Log::warning( Say("Line %n : no source or path specified for glsl shader.\n") << vlx->lineNumber() );
02844       }
02845     }
02846 
02847     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02848     {
02849       ref<GLSLShader> obj = NULL;
02850       if (vlx->tag() == "<vl::GLSLVertexShader>")
02851         obj = new GLSLVertexShader;
02852       else
02853       if (vlx->tag() == "<vl::GLSLFragmentShader>")
02854         obj = new GLSLFragmentShader;
02855       else
02856       if (vlx->tag() == "<vl::GLSLGeometryShader>")
02857         obj = new GLSLGeometryShader;
02858       else
02859       if (vlx->tag() == "<vl::GLSLTessControlShader>")
02860         obj = new GLSLTessControlShader;
02861       else
02862       if (vlx->tag() == "<vl::GLSLTessEvaluationShader>")
02863         obj = new GLSLTessEvaluationShader;
02864       else
02865       {
02866         s.signalImportError( Say("Line %n : shader type '%s' not supported.\n") << vlx->tag() );
02867         return NULL;
02868       }
02869 
02870       // register imported structure asap
02871       s.registerImportedStructure(vlx, obj.get());
02872       importGLSLShader(s, vlx, obj.get());
02873       return obj;
02874     }
02875 
02876     void exportGLSLShader(const GLSLShader* glslsh, VLXStructure* vlx)
02877     {
02878       if (!glslsh->path().empty())
02879         *vlx << "Path" << vlx_String(glslsh->path());
02880       else
02881       if (!glslsh->source().empty())
02882         *vlx << "Source" << vlx_Rawtext(glslsh->source());
02883       else
02884       if (glslsh->handle())
02885         *vlx << "Source" << vlx_Rawtext(glslsh->getShaderSource());
02886       else
02887         *vlx << "Source" << vlx_Identifier("NO_SOURCE_FOUND");
02888     }
02889 
02890     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
02891     {
02892       const GLSLShader* cast_obj = obj->as<GLSLShader>(); VL_CHECK(cast_obj)
02893       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("glslsh_"));
02894       // register exported object asap
02895       s.registerExportedObject(obj, vlx.get());
02896       exportGLSLShader(cast_obj, vlx.get());
02897       return vlx;
02898     }
02899   };
02900 
02901   //---------------------------------------------------------------------------
02902 
02904   struct VLXClassWrapper_VertexAttrib: public VLXClassWrapper
02905   {
02906     void importVertexAttrib(VLXSerializer& s, const VLXStructure* vlx, VertexAttrib* obj)
02907     {
02908       const VLXValue* name = vlx->getValue("ObjectName");
02909       if (name)
02910         obj->setObjectName( name->getString().c_str() );
02911 
02912       const VLXValue* value = vlx->getValue("Value");
02913       VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value )
02914       obj->setValue( (fvec4)vlx_vec4( value->getArrayReal() ) );
02915     }
02916 
02917     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02918     {
02919       ref<VertexAttrib> obj = new VertexAttrib;
02920       // register imported structure asap
02921       s.registerImportedStructure(vlx, obj.get());
02922       importVertexAttrib(s, vlx, obj.get());
02923       return obj;
02924     }
02925 
02926     void exportVertexAttrib(const VertexAttrib* obj, VLXStructure* vlx)
02927     {
02928       if (!obj->objectName().empty() && obj->objectName() != obj->className())
02929         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
02930       *vlx << "Value" << vlx_toValue((vec4)obj->value());
02931     }
02932 
02933     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
02934     {
02935       const VertexAttrib* cast_obj = obj->as<VertexAttrib>(); VL_CHECK(cast_obj)
02936       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("vertexattrib_"));
02937       // register exported object asap
02938       s.registerExportedObject(obj, vlx.get());
02939       exportVertexAttrib(cast_obj, vlx.get());
02940       return vlx;
02941     }
02942   };
02943 
02944   //---------------------------------------------------------------------------
02945 
02947   struct VLXClassWrapper_Color: public VLXClassWrapper
02948   {
02949     void importColor(VLXSerializer& s, const VLXStructure* vlx, Color* obj)
02950     {
02951       const VLXValue* value = vlx->getValue("Value");
02952       VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value )
02953       obj->setValue( (fvec4)vlx_vec4( value->getArrayReal() ) );
02954     }
02955 
02956     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02957     {
02958       ref<Color> obj = new Color;
02959       // register imported structure asap
02960       s.registerImportedStructure(vlx, obj.get());
02961       importColor(s, vlx, obj.get());
02962       return obj;
02963     }
02964 
02965     void exportColor(const Color* obj, VLXStructure* vlx)
02966     {
02967       *vlx << "Value" << vlx_toValue((vec4)obj->value());
02968     }
02969 
02970     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
02971     {
02972       const Color* cast_obj = obj->as<Color>(); VL_CHECK(cast_obj)
02973       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("color_"));
02974       // register exported object asap
02975       s.registerExportedObject(obj, vlx.get());
02976       exportColor(cast_obj, vlx.get());
02977       return vlx;
02978     }
02979   };
02980 
02981   //---------------------------------------------------------------------------
02982 
02984   struct VLXClassWrapper_SecondaryColor: public VLXClassWrapper
02985   {
02986     void importSecondaryColor(VLXSerializer& s, const VLXStructure* vlx, SecondaryColor* obj)
02987     {
02988       const VLXValue* value = vlx->getValue("Value");
02989       VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value )
02990       obj->setValue( (fvec3)vlx_vec3( value->getArrayReal() ) );
02991     }
02992 
02993     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
02994     {
02995       ref<SecondaryColor> obj = new SecondaryColor;
02996       // register imported structure asap
02997       s.registerImportedStructure(vlx, obj.get());
02998       importSecondaryColor(s, vlx, obj.get());
02999       return obj;
03000     }
03001 
03002     void exportSecondaryColor(const SecondaryColor* obj, VLXStructure* vlx)
03003     {
03004       *vlx << "Value" << vlx_toValue((vec3)obj->value());
03005     }
03006 
03007     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
03008     {
03009       const SecondaryColor* cast_obj = obj->as<SecondaryColor>(); VL_CHECK(cast_obj)
03010       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("seccolor_"));
03011       // register exported object asap
03012       s.registerExportedObject(obj, vlx.get());
03013       exportSecondaryColor(cast_obj, vlx.get());
03014       return vlx;
03015     }
03016   };
03017 
03018   //---------------------------------------------------------------------------
03019 
03021   struct VLXClassWrapper_Normal: public VLXClassWrapper
03022   {
03023     void importNormal(VLXSerializer& s, const VLXStructure* vlx, Normal* obj)
03024     {
03025       const VLXValue* value = vlx->getValue("Value");
03026       VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value )
03027       obj->setValue( (fvec3)vlx_vec3( value->getArrayReal() ) );
03028     }
03029 
03030     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
03031     {
03032       ref<Normal> obj = new Normal;
03033       // register imported structure asap
03034       s.registerImportedStructure(vlx, obj.get());
03035       importNormal(s, vlx, obj.get());
03036       return obj;
03037     }
03038 
03039     void exportNormal(const Normal* obj, VLXStructure* vlx)
03040     {
03041       *vlx << "Value" << vlx_toValue((vec3)obj->value());
03042     }
03043 
03044     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
03045     {
03046       const Normal* cast_obj = obj->as<Normal>(); VL_CHECK(cast_obj)
03047       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("normal_"));
03048       // register exported object asap
03049       s.registerExportedObject(obj, vlx.get());
03050       exportNormal(cast_obj, vlx.get());
03051       return vlx;
03052     }
03053   };
03054 
03055   //---------------------------------------------------------------------------
03056 
03058   struct VLXClassWrapper_Material: public VLXClassWrapper
03059   {
03060     void importMaterial(VLXSerializer& s, const VLXStructure* vlx, Material* obj)
03061     {
03062       const VLXValue* name = vlx->getValue("ObjectName");
03063       if (name)
03064         obj->setObjectName( name->getString().c_str() );
03065 
03066       for(size_t i=0; i<vlx->value().size(); ++i)
03067       {
03068         const std::string& key = vlx->value()[i].key();
03069         const VLXValue& value = vlx->value()[i].value();
03070         if (key == "FrontAmbient")
03071         {
03072           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
03073           obj->setFrontAmbient( (fvec4)vlx_vec4( value.getArrayReal() ) );
03074         }
03075         else
03076         if (key == "FrontDiffuse")
03077         {
03078           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
03079           obj->setFrontDiffuse( (fvec4)vlx_vec4( value.getArrayReal() ) );
03080         }
03081         else
03082         if (key == "FrontEmission")
03083         {
03084           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
03085           obj->setFrontEmission( (fvec4)vlx_vec4( value.getArrayReal() ) );
03086         }
03087         else
03088         if (key == "FrontSpecular")
03089         {
03090           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
03091           obj->setFrontSpecular( (fvec4)vlx_vec4( value.getArrayReal() ) );
03092         }
03093         else
03094         if (key == "FrontShininess")
03095         {
03096           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value );
03097           obj->setFrontShininess( (float)value.getReal() ); 
03098         }
03099         else
03100         if (key == "BackAmbient")
03101         {
03102           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
03103           obj->setBackAmbient( (fvec4)vlx_vec4( value.getArrayReal() ) );
03104         }
03105         else
03106         if (key == "BackDiffuse")
03107         {
03108           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
03109           obj->setBackDiffuse( (fvec4)vlx_vec4( value.getArrayReal() ) );
03110         }
03111         else
03112         if (key == "BackEmission")
03113         {
03114           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
03115           obj->setBackEmission( (fvec4)vlx_vec4( value.getArrayReal() ) );
03116         }
03117         else
03118         if (key == "BackSpecular")
03119         {
03120           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
03121           obj->setBackSpecular( (fvec4)vlx_vec4( value.getArrayReal() ) );
03122         }
03123         else
03124         if (key == "BackShininess")
03125         {
03126           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value );
03127           obj->setBackShininess( (float)value.getReal() ); 
03128         }
03129         else
03130         if (key == "ColorMaterialEnabled")
03131         {
03132           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value );
03133           obj->setColorMaterialEnabled( value.getBool() ); 
03134         }
03135       }
03136 
03137       EColorMaterial col_mat = CM_AMBIENT_AND_DIFFUSE;
03138       const VLXValue* vlx_col_mat = vlx->getValue("ColorMaterial");
03139       if (vlx_col_mat)
03140       {
03141         VLX_IMPORT_CHECK_RETURN( vlx_col_mat->type() == VLXValue::Identifier, *vlx_col_mat );
03142         col_mat = vlx_EColorMaterial( *vlx_col_mat, s );
03143       }
03144 
03145       EPolygonFace poly_face = PF_FRONT_AND_BACK;
03146       const VLXValue* vlx_poly_mat = vlx->getValue("ColorMaterialFace");
03147       if (vlx_poly_mat)
03148       {
03149         VLX_IMPORT_CHECK_RETURN( vlx_poly_mat->type() == VLXValue::Identifier, *vlx_poly_mat );
03150         poly_face = vlx_EPolygonFace( *vlx_poly_mat, s );
03151       }
03152 
03153       obj->setColorMaterial( poly_face, col_mat );
03154     }
03155 
03156     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
03157     {
03158       ref<Material> obj = new Material;
03159       // register imported structure asap
03160       s.registerImportedStructure(vlx, obj.get());
03161       importMaterial(s, vlx, obj.get());
03162       return obj;
03163     }
03164 
03165     void exportMaterial(const Material* obj, VLXStructure* vlx)
03166     {
03167       if (!obj->objectName().empty() && obj->objectName() != obj->className())
03168         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
03169 
03170       *vlx << "FrontAmbient" << vlx_toValue((vec4)obj->frontAmbient());
03171       *vlx << "FrontDiffuse" << vlx_toValue((vec4)obj->frontDiffuse());
03172       *vlx << "FrontEmission" << vlx_toValue((vec4)obj->frontEmission());
03173       *vlx << "FrontSpecular" << vlx_toValue((vec4)obj->frontSpecular());
03174       *vlx << "FrontShininess" << (double)obj->frontShininess();
03175 
03176       *vlx << "BackAmbient" << vlx_toValue((vec4)obj->backAmbient());
03177       *vlx << "BackDiffuse" << vlx_toValue((vec4)obj->backDiffuse());
03178       *vlx << "BackEmission" << vlx_toValue((vec4)obj->backEmission());
03179       *vlx << "BackSpecular" << vlx_toValue((vec4)obj->backSpecular());
03180       *vlx << "BackShininess" << (double)obj->backShininess();
03181 
03182       *vlx << "ColorMaterial" << vlx_Identifier(vlx_EColorMaterial(obj->colorMaterial()));
03183       *vlx << "ColorMaterialFace" << vlx_Identifier(vlx_EPolygonFace(obj->colorMaterialFace()));
03184 
03185       *vlx << "ColorMaterialEnabled" << obj->colorMaterialEnabled();
03186     }
03187 
03188     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
03189     {
03190       const Material* cast_obj = obj->as<Material>(); VL_CHECK(cast_obj)
03191       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("material_"));
03192       // register exported object asap
03193       s.registerExportedObject(obj, vlx.get());
03194       exportMaterial(cast_obj, vlx.get());
03195       return vlx;
03196     }
03197   };
03198 
03199   //---------------------------------------------------------------------------
03200 
03202   struct VLXClassWrapper_ActorEventCallback: public VLXClassWrapper
03203   {
03204     void importActorEventCallback(VLXSerializer& s, const VLXStructure* vlx, ActorEventCallback* obj)
03205     {
03206       if (obj->isOfType(DepthSortCallback::Type()))
03207       {
03208         const VLXValue* vlx_sm = vlx->getValue("SortMode");
03209         VLX_IMPORT_CHECK_RETURN( vlx_sm->type() == VLXValue::Identifier, *vlx_sm )
03210         if (vlx_sm)
03211         {
03212           ESortMode sm = SM_SortBackToFront;
03213           if ( vlx_sm->getIdentifier() == "SM_SortBackToFront" )
03214             sm = SM_SortBackToFront;
03215           else
03216           if ( vlx_sm->getIdentifier() == "SM_SortFrontToBack" )
03217             sm = SM_SortFrontToBack;
03218           else
03219             s.signalImportError( Say("Line %n : unknown sort mode '%s'.\n") << vlx_sm->lineNumber() << vlx_sm->getIdentifier() );
03220           obj->as<DepthSortCallback>()->setSortMode(sm);
03221         }
03222       }
03223     }
03224 
03225     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
03226     {
03227       ref<ActorEventCallback> obj = NULL;
03228 
03229       if (vlx->tag() == "<vl::DepthSortCallback>")
03230         obj = new DepthSortCallback;
03231       else
03232       {
03233         s.signalImportError( Say("Line %n : ActorEventCallback type not supported for import.\n") << vlx->lineNumber() );
03234         return NULL;
03235       }
03236 
03237       // register imported structure asap
03238       s.registerImportedStructure(vlx, obj.get());
03239       importActorEventCallback(s, vlx, obj.get());
03240       return obj;
03241     }
03242 
03243     void exportActorEventCallback(VLXSerializer& s, const ActorEventCallback* cb, VLXStructure* vlx)
03244     {
03245       if (cb->classType() == DepthSortCallback::Type())
03246       {
03247         const DepthSortCallback* dsc = cb->as<DepthSortCallback>();
03248 
03249         if (dsc->sortMode() == SM_SortBackToFront)
03250           *vlx << "SortMode" << vlx_Identifier("SM_SortBackToFront");
03251         else
03252           *vlx << "SortMode" << vlx_Identifier("SM_SortFrontToBack");
03253       }
03254       else
03255       {
03256         s.signalExportError("ActorEventCallback type not supported for export.\n");
03257       }
03258     }
03259 
03260     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
03261     {
03262       const ActorEventCallback* cast_obj = obj->as<ActorEventCallback>(); VL_CHECK(cast_obj)
03263       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("actorcallback_"));
03264       // register exported object asap
03265       s.registerExportedObject(obj, vlx.get());
03266       exportActorEventCallback(s, cast_obj, vlx.get());
03267       return vlx;
03268     }
03269   };
03270 
03271   //---------------------------------------------------------------------------
03272 
03274   struct VLXClassWrapper_Texture: public VLXClassWrapper
03275   {
03276     void importTexture(VLXSerializer& s, const VLXStructure* vlx, Texture* obj)
03277     {
03278       const VLXValue* name = vlx->getValue("ObjectName");
03279       if (name)
03280         obj->setObjectName( name->getString().c_str() );
03281 
03282       obj->setSetupParams( new Texture::SetupParams );
03283 
03284       for(size_t i=0; i<vlx->value().size(); ++i)
03285       {
03286         const std::string& key = vlx->value()[i].key();
03287         const VLXValue& value = vlx->value()[i].value();
03288 
03289         if (key == "Dimension")
03290         {
03291           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
03292           obj->setupParams()->setDimension( vlx_ETextureDimension( value, s ) );
03293         }
03294         else
03295         if (key == "TexParameter")
03296         {
03297           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value );
03298           TexParameter* tex_param = s.importVLX( value.getStructure() )->as<TexParameter>();
03299           VLX_IMPORT_CHECK_RETURN( tex_param != NULL, value );
03300           // copy the content over
03301           *obj->getTexParameter() = *tex_param;
03302         }
03303         else
03304         if (key == "ImagePath")
03305         {
03306           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::String, value );
03307           std::string resolved_path = value.getString();
03308           s.resolvePath( resolved_path );
03309           obj->setupParams()->setImagePath( resolved_path.c_str() );
03310         }
03311         else
03312         if (key == "Format")
03313         {
03314           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
03315           obj->setupParams()->setFormat( vlx_ETextureFormat( value, s ) );
03316         }
03317         else
03318         if (key == "Width")
03319         {
03320           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
03321           obj->setupParams()->setWidth( (int)value.getInteger() );
03322         }
03323         else
03324         if (key == "Height")
03325         {
03326           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
03327           obj->setupParams()->setHeight( (int)value.getInteger() );
03328         }
03329         else
03330         if (key == "Depth")
03331         {
03332           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
03333           obj->setupParams()->setDepth( (int)value.getInteger() );
03334         }
03335         else
03336         if (key == "GenMipmaps")
03337         {
03338           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value );
03339           obj->setupParams()->setGenMipmaps( (int)value.getBool() );
03340         }
03341         else
03342         if (key == "BufferObject")
03343         {
03344           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value );
03345           BufferObject* buf_obj = s.importVLX( value.getStructure() )->as<BufferObject>();
03346           VLX_IMPORT_CHECK_RETURN( buf_obj, value );
03347           obj->setupParams()->setBufferObject( buf_obj );
03348         }
03349         else
03350         if (key == "Samples")
03351         {
03352           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
03353           obj->setupParams()->setSamples( (int)value.getInteger() );
03354         }
03355         else
03356         if (key == "FixedSamplesLocations")
03357         {
03358           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value );
03359           obj->setupParams()->setFixedSamplesLocations( (int)value.getBool() );
03360         }
03361       }
03362     }
03363 
03364     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
03365     {
03366       ref<Texture> obj = new Texture;
03367       // register imported structure asap
03368       s.registerImportedStructure(vlx, obj.get());
03369       importTexture(s, vlx, obj.get());
03370       return obj;
03371     }
03372 
03373     void exportTexture(VLXSerializer& s, const Texture* obj, VLXStructure* vlx)
03374     {
03375       // mic fixme:
03376       // - we should allow patterns such as initializing a texture from an image filled by a shader or procedure.
03377       // - we should allow avoid loading twice the same image or shader source or any externa resource etc. time for a resource manager?
03378 
03379       if (!obj->objectName().empty() && obj->objectName() != obj->className())
03380         *vlx << "ObjectName" << vlx_String(obj->objectName().c_str());
03381 
03382       if (obj->getTexParameter())
03383         *vlx << "TexParameter" << s.exportVLX(obj->getTexParameter());
03384 
03385       if (obj->setupParams())
03386       {
03387         const Texture::SetupParams* par = obj->setupParams();
03388 
03389         if (par)
03390         {
03391           *vlx << "Dimension" << vlx_Identifier(vlx_ETextureDimension(par->dimension()));
03392 
03393           *vlx << "Format" << vlx_Identifier(vlx_ETextureFormat(par->format()));
03394 
03395           if (!par->imagePath().empty())
03396             *vlx << "ImagePath" << vlx_String(par->imagePath().toStdString());
03397           else
03398           if (par->image())
03399             *vlx << "ImagePath" << vlx_String(par->image()->filePath().toStdString());
03400 
03401           if (par->width())
03402             *vlx << "Width" << (long long)par->width();
03403 
03404           if (par->height())
03405             *vlx << "Height" << (long long)par->height();
03406 
03407           if (par->depth())
03408             *vlx << "Depth" << (long long)par->depth();
03409 
03410           *vlx << "GenMipmaps" << par->genMipmaps();
03411           
03412           // mic fixme: implement BufferObject importer/exporter
03413 #if 0
03414           if (par->bufferObject())
03415           {
03416             *vlx << "BufferObject" << s.exportVLX(par->bufferObject());
03417           }
03418 #endif
03419 
03420           if(par->samples())
03421           {
03422             *vlx << "Samples" << (long long)par->samples();
03423             *vlx << "FixedSamplesLocations" << par->fixedSamplesLocations();
03424           }
03425         }
03426       }
03427     }
03428 
03429     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
03430     {
03431       const Texture* cast_obj = obj->as<Texture>(); VL_CHECK(cast_obj)
03432       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("texture_"));
03433       // register exported object asap
03434       s.registerExportedObject(obj, vlx.get());
03435       exportTexture(s, cast_obj, vlx.get());
03436       return vlx;
03437     }
03438   };
03439 
03440   //---------------------------------------------------------------------------
03441 
03443   struct VLXClassWrapper_TexParameter: public VLXClassWrapper
03444   {
03445     void importTexParameter(VLXSerializer& s, const VLXStructure* vlx, TexParameter* obj)
03446     {
03447       for(size_t i=0; i<vlx->value().size(); ++i)
03448       {
03449         const std::string& key = vlx->value()[i].key();
03450         const VLXValue& value = vlx->value()[i].value();
03451 
03452         if (key == "MinFilter")
03453         {
03454           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
03455           obj->setMinFilter( vlx_ETexParamFilter( value, s ) );
03456         }
03457         else
03458         if (key == "MagFilter")
03459         {
03460           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
03461           obj->setMagFilter( vlx_ETexParamFilter( value, s ) );
03462         }
03463         else
03464         if (key == "WrapS")
03465         {
03466           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
03467           obj->setWrapS( vlx_ETexParamWrap( value, s ) );
03468         }
03469         else
03470         if (key == "WrapT")
03471         {
03472           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
03473           obj->setWrapT( vlx_ETexParamWrap( value, s ) );
03474         }
03475         else
03476         if (key == "WrapR")
03477         {
03478           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
03479           obj->setWrapR( vlx_ETexParamWrap( value, s ) );
03480         }
03481         else
03482         if (key == "CompareMode")
03483         {
03484           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
03485           obj->setCompareMode( vlx_ETexCompareMode( value, s ) );
03486         }
03487         else
03488         if (key == "CompareFunc")
03489         {
03490           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
03491           obj->setCompareFunc( vlx_ETexCompareFunc( value, s ) );
03492         }
03493         else
03494         if (key == "DepthTextureMode")
03495         {
03496           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
03497           obj->setDepthTextureMode( vlx_EDepthTextureMode( value, s ) );
03498         }
03499         else
03500         if (key == "BorderColor")
03501         {
03502           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
03503           obj->setBorderColor( (fvec4)vlx_vec4(value.getArrayReal()) );
03504         }
03505         else
03506         if (key == "Anisotropy")
03507         {
03508           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value );
03509           obj->setAnisotropy( (float)value.getReal() );
03510         }
03511         else
03512         if (key == "GenerateMipmap")
03513         {
03514           VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value );
03515           obj->setGenerateMipmap( value.getBool() );
03516         }
03517       }
03518     }
03519 
03520     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
03521     {
03522       ref<TexParameter> obj = new TexParameter;
03523       // register imported structure asap
03524       s.registerImportedStructure(vlx, obj.get());
03525       importTexParameter(s, vlx, obj.get());
03526       return obj;
03527     }
03528 
03529     void exportTexParameter(const TexParameter* texparam, VLXStructure* vlx)
03530     {
03531       *vlx << "MinFilter" << vlx_Identifier(vlx_ETexParamFilter(texparam->minFilter()));
03532       *vlx << "MagFilter" << vlx_Identifier(vlx_ETexParamFilter(texparam->magFilter()));
03533       *vlx << "WrapS" << vlx_Identifier(vlx_ETexParamWrap(texparam->wrapS()));
03534       *vlx << "WrapT" << vlx_Identifier(vlx_ETexParamWrap(texparam->wrapT()));
03535       *vlx << "WrapR" << vlx_Identifier(vlx_ETexParamWrap(texparam->wrapR()));
03536       *vlx << "CompareMode" << vlx_Identifier(vlx_ETexCompareMode(texparam->compareMode()));
03537       *vlx << "CompareFunc" << vlx_Identifier(vlx_ETexCompareFunc(texparam->compareFunc()));
03538       *vlx << "DepthTextureMode" << vlx_Identifier(vlx_EDepthTextureMode(texparam->depthTextureMode()));
03539       *vlx << "BorderColor" << vlx_toValue((vec4)texparam->borderColor());
03540       *vlx << "Anisotropy" << texparam->anisotropy();
03541       *vlx << "GenerateMipmap" << texparam->generateMipmap();
03542     }
03543 
03544     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
03545     {
03546       const TexParameter* cast_obj = obj->as<TexParameter>(); VL_CHECK(cast_obj)
03547       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("texparam_"));
03548       // register exported object asap
03549       s.registerExportedObject(obj, vlx.get());
03550       exportTexParameter(cast_obj, vlx.get());
03551       return vlx;
03552     }
03553   };
03554 
03555   //---------------------------------------------------------------------------
03556 
03558   struct VLXClassWrapper_TextureSampler: public VLXClassWrapper
03559   {
03560     void importTextureSampler(VLXSerializer& s, const VLXStructure* vlx, TextureSampler* obj)
03561     {
03562       const VLXValue* vlx_texture = vlx->getValue("Texture");
03563       if (vlx_texture)
03564       {
03565         VLX_IMPORT_CHECK_RETURN(vlx_texture->type() == VLXValue::Structure, *vlx_texture);
03566         Texture* texture = s.importVLX(vlx_texture->getStructure())->as<Texture>();
03567         VLX_IMPORT_CHECK_RETURN( texture != NULL , *vlx_texture);
03568         obj->setTexture(texture);
03569       }
03570 
03571       const VLXValue* vlx_texp = vlx->getValue("TexParameter");
03572       if (vlx_texp)
03573       {
03574         VLX_IMPORT_CHECK_RETURN(vlx_texp->type() == VLXValue::Structure, *vlx_texp);
03575         TexParameter* texp = s.importVLX(vlx_texp->getStructure())->as<TexParameter>();
03576         VLX_IMPORT_CHECK_RETURN( texp != NULL , *vlx_texp);
03577         obj->setTexParameter(texp);
03578       }
03579     }
03580 
03581     virtual ref<Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
03582     {
03583       ref<TextureSampler> obj = new TextureSampler;
03584       // register imported structure asap
03585       s.registerImportedStructure(vlx, obj.get());
03586       importTextureSampler(s, vlx, obj.get());
03587       return obj;
03588     }
03589 
03590     void exportTextureSampler(VLXSerializer& s, const TextureSampler* tex_sampler, VLXStructure* vlx)
03591     {
03592       if (tex_sampler->texture())
03593         *vlx << "Texture" << s.exportVLX(tex_sampler->texture());
03594       if (tex_sampler->getTexParameter())
03595         *vlx << "TexParameter" << s.exportVLX(tex_sampler->getTexParameter());
03596     }
03597 
03598     virtual ref<VLXStructure> exportVLX(VLXSerializer& s, const Object* obj)
03599     {
03600       const TextureSampler* cast_obj = obj->as<TextureSampler>(); VL_CHECK(cast_obj)
03601       ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("texsampler_"));
03602       // register exported object asap
03603       s.registerExportedObject(obj, vlx.get());
03604       exportTextureSampler(s, cast_obj, vlx.get());
03605       return vlx;
03606     }
03607   };
03608 }
03609 
03610 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:33.
Permission is granted to use this page to write and publish articles regarding Visualization Library.