00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __GB_AttributeBuffer__
00019 #define __GB_AttributeBuffer__
00020
00021 #include "GB_API.h"
00022
00023 #include <SYS/SYS_Types.h>
00024
00025 #define GB_ATTRIBBUF_INITIAL_8B_SIZE 16
00026
00027 #define GB_ATTRIBBUF_INITIAL_SIZE_F64 (GB_ATTRIBBUF_INITIAL_8B_SIZE)
00028 #define GB_ATTRIBBUF_INITIAL_SIZE_F32 (GB_ATTRIBBUF_INITIAL_8B_SIZE * 2)
00029 #define GB_ATTRIBBUF_INITIAL_SIZE_I64 (GB_ATTRIBBUF_INITIAL_8B_SIZE)
00030 #define GB_ATTRIBBUF_INITIAL_SIZE_I32 (GB_ATTRIBBUF_INITIAL_8B_SIZE * 2)
00031 #define GB_ATTRIBBUF_INITIAL_SIZE_PTR (GB_ATTRIBBUF_INITIAL_8B_SIZE * 8 / sizeof(void *))
00032
00033 #include <UT/UT_VectorTypes.h>
00034
00035
00036
00037
00038
00039
00040 class GB_API GB_AttributeBuffer {
00041 public:
00042
00043 GB_AttributeBuffer() : myHeapBuffer(0), myHeapBufferSize(0) { }
00044
00045
00046 ~GB_AttributeBuffer() { if (myHeapBuffer) delete []myHeapBuffer; }
00047
00048 fpreal64 *asF64(int count)
00049 {
00050 if (count <= GB_ATTRIBBUF_INITIAL_SIZE_F64)
00051 return myStackBuffer.myF64;
00052 else
00053 return heapBufferAsPOD<fpreal64>(count);
00054 }
00055 fpreal32 *asF32(int count)
00056 {
00057 if (count <= GB_ATTRIBBUF_INITIAL_SIZE_F32)
00058 return myStackBuffer.myF32;
00059 else
00060 return heapBufferAsPOD<fpreal32>(count);
00061 }
00062
00063 int64 *asI64(int count)
00064 {
00065 if (count <= GB_ATTRIBBUF_INITIAL_SIZE_I64)
00066 return myStackBuffer.myI64;
00067 else
00068 return heapBufferAsPOD<int64>(count);
00069 }
00070 int32 *asI32(int count)
00071 {
00072 if (count <= GB_ATTRIBBUF_INITIAL_SIZE_I32)
00073 return myStackBuffer.myI32;
00074 else
00075 return heapBufferAsPOD<int32>(count);
00076 }
00077
00078 UT_Vector3 *asV3(int count)
00079 {
00080 if (count*3 <= GB_ATTRIBBUF_INITIAL_SIZE_F32)
00081 return (UT_Vector3 *)myStackBuffer.myF32;
00082 else
00083 return (UT_Vector3 *)
00084 heapBufferAsPOD<fpreal32>(count*3);
00085 }
00086 UT_Vector4 *asV4(int count)
00087 {
00088 if (count*4 <= GB_ATTRIBBUF_INITIAL_SIZE_F32)
00089 return (UT_Vector4 *)myStackBuffer.myF32;
00090 else
00091 return (UT_Vector4 *)
00092 heapBufferAsPOD<fpreal32>(count*4);
00093 }
00094 UT_Matrix3 *asM3(int count)
00095 {
00096 if (count*9 <= GB_ATTRIBBUF_INITIAL_SIZE_F32)
00097 return (UT_Matrix3 *)myStackBuffer.myF32;
00098 else
00099 return (UT_Matrix3 *)
00100 heapBufferAsPOD<fpreal32>(count*9);
00101 }
00102 UT_Matrix4 *asM4(int count)
00103 {
00104 if (count*16 <= GB_ATTRIBBUF_INITIAL_SIZE_F32)
00105 return (UT_Matrix4 *)myStackBuffer.myF32;
00106 else
00107 return (UT_Matrix4 *)
00108 heapBufferAsPOD<fpreal32>(count*16);
00109 }
00110
00111 private:
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 template <typename T, int FAKE> class TemplateAdapter
00123 {
00124 };
00125
00126
00127 #define GB_ATTRIBBUF_ADAPTER_SPECIALIZATION(TOKEN, T) \
00128 template <int FAKE> class TemplateAdapter<T, FAKE> \
00129 { \
00130 public: \
00131 static T *getRawBuffer(GB_AttributeBuffer &buffer, int count) \
00132 { return buffer.as##TOKEN(count); } \
00133 }
00134
00135
00136 GB_ATTRIBBUF_ADAPTER_SPECIALIZATION(F64, fpreal64);
00137 GB_ATTRIBBUF_ADAPTER_SPECIALIZATION(F32, fpreal32);
00138 GB_ATTRIBBUF_ADAPTER_SPECIALIZATION(I64, int64);
00139 GB_ATTRIBBUF_ADAPTER_SPECIALIZATION(I32, int32);
00140 GB_ATTRIBBUF_ADAPTER_SPECIALIZATION(V3, UT_Vector3);
00141 GB_ATTRIBBUF_ADAPTER_SPECIALIZATION(V4, UT_Vector4);
00142 GB_ATTRIBBUF_ADAPTER_SPECIALIZATION(M3, UT_Matrix3);
00143 GB_ATTRIBBUF_ADAPTER_SPECIALIZATION(M4, UT_Matrix4);
00144
00145 #undef GB_ATTRIBBUF_ADAPTER_SPECIALIZATION
00146
00147 public:
00148
00149
00150 template <typename T>
00151 T *asType(int count)
00152 {
00153 return TemplateAdapter<T,0>::getRawBuffer(*this, count);
00154 }
00155
00156 private:
00157
00158 GB_AttributeBuffer(const GB_AttributeBuffer &);
00159
00160
00161 GB_AttributeBuffer &operator=(const GB_AttributeBuffer &src);
00162
00163 static void compileTimeAssertions();
00164
00165
00166
00167 template<typename T>
00168 T *heapBufferAsPOD(int count)
00169 {
00170 const int size = count * sizeof(T);
00171 if (size > myHeapBufferSize)
00172 {
00173 if (myHeapBuffer)
00174 delete []myHeapBuffer;
00175
00176
00177 myHeapBuffer = new char[size];
00178 myHeapBufferSize = size;
00179 }
00180
00181 return (T *)myHeapBuffer;
00182 }
00183
00184 char *myHeapBuffer;
00185 int myHeapBufferSize;
00186
00187 union {
00188 fpreal64 myF64[GB_ATTRIBBUF_INITIAL_SIZE_F64];
00189 fpreal32 myF32[GB_ATTRIBBUF_INITIAL_SIZE_F32];
00190 int64 myI64[GB_ATTRIBBUF_INITIAL_SIZE_I64];
00191 int32 myI32[GB_ATTRIBBUF_INITIAL_SIZE_I32];
00192 void *myPtr[GB_ATTRIBBUF_INITIAL_SIZE_PTR];
00193 } myStackBuffer;
00194 };
00195
00196 #endif