00001 #include <vector>
00002
00003 #include <vrs/bounds.h>
00004 #include <vrs/sg/scenething.h>
00005 #include <vrs/translation.h>
00006
00007 #include <vrsode/BoxShape.h>
00008 #include <vrsode/CollisionBody.h>
00009 #include <vrsode/TriangleData.h>
00010 #include <vrsode/TrimeshShape.h>
00011
00012 #include "ControlPointContainer.h"
00013 #include "TerrainGenerator.h"
00014 #include "VRSTerrainLoader.h"
00015
00016 #include "ODETerrainLoader.h"
00017 #include "ODETerrainLoader.tcc"
00018
00019 using namespace VRS;
00020 using namespace vrsode;
00021
00022
00023 namespace random_racer
00024 {
00025
00026 ODETerrainLoader::ODETerrainLoader(
00027 SO<SceneThing> p_thing,
00028 SO<VRSTerrainLoader> p_vrsLoader,
00029 double p_boxSize,
00030 double p_viewSize) : TerrainLoader(p_thing, p_boxSize, p_viewSize)
00031 {
00032 m_vrsLoader = p_vrsLoader;
00033
00034 const unsigned int lod = 9;
00035 const unsigned int multLod = (lod - 1)*2 + 1;
00036 const unsigned int multLod2 = (multLod - 1)*2 + 1;
00037 const unsigned int multLod3 = (multLod2 - 1)*2 + 1;
00038
00039
00040 m_triangleData = new TriangleData(
00041 multLod3*multLod3, (multLod3-1)*(multLod3-1)*2*3);
00042
00043
00044 fillIndexArray(multLod3, m_triangleData->uncommittedIndexArray());
00045
00046 std::vector<VRS::Vector> temp, temp2(multLod*multLod);
00047
00048 grabVertices(Vector(0.0, 0.0, 0.0), &temp);
00049
00050 doubleVertices(temp, temp2, lod, multLod);
00051
00052 temp.resize(multLod2*multLod2);
00053
00054 doubleVertices(temp2, temp, multLod, multLod2);
00055
00056 temp2.resize(multLod3*multLod3);
00057
00058 doubleVertices(temp, temp2, multLod2, multLod3);
00059
00060
00061 convertVertices(
00062 temp2.begin(), temp2.end(), m_triangleData->uncommittedVertexArray());
00063
00064 m_triangleData->setVertexArrayFill(multLod3*multLod3);
00065 m_triangleData->setIndexArrayFill((multLod3-1)*(multLod3-1)*2*3);
00066
00067 m_triangleData->commitDataUpdate();
00068
00069
00070
00071
00072
00073 m_trimeshBody = new CollisionBody(m_thing,new TrimeshShape(m_triangleData));
00074
00075 Vector translate = m_vrsLoader->m_translation->getTranslate();
00076 translate[1] = 0.1;
00077
00078 m_trimeshBody->setPosition(translate);
00079
00080 m_trimeshBody->surface()->setSlip1(0.01);
00081 m_trimeshBody->surface()->setSlip2(0.01);
00082 m_trimeshBody->surface()->setMu(9999);
00083 }
00084
00085 ODETerrainLoader::~ODETerrainLoader()
00086 {
00087 m_thing->clear();
00088 }
00089
00090 void
00091 ODETerrainLoader::grabVertices(
00092 const VRS::Vector& p_position, std::vector<VRS::Vector>* p_target)
00093 {
00094 m_vrsLoader->lock();
00095
00096
00097
00098 const double lodSpacing = 8.0;
00099 const unsigned int lod = 64;
00100
00101
00102
00103
00104 Vector odeLL = p_position;
00105
00106
00107
00108
00109 odeLL[1] = 0.0;
00110
00111 odeLL[0] -= (m_viewSize/2.0);
00112 odeLL[2] -= (m_viewSize/2.0);
00113
00114
00115
00116
00117 Vector vrsLL = m_vrsLoader->m_vertexIter->data[0] +
00118 m_vrsLoader->m_translation->getTranslate();
00119
00120 vrsLL[1] = 0.0;
00121
00122
00123 Vector diff = odeLL - vrsLL;
00124
00125 unsigned int offsetX, offsetY, numPts;
00126
00127
00128
00129
00130 offsetX = round(diff[0]/lodSpacing);
00131 offsetY = round(diff[2]/lodSpacing);
00132
00133 numPts = int(m_viewSize/lodSpacing) + 1;
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 unsigned int i, j;
00146
00147 for(i = offsetX; i < (numPts+offsetX); i++)
00148 for(j = offsetY; j < (numPts+offsetY); j++)
00149 p_target->push_back(m_vrsLoader->m_vertexIter->data[j*lod + i]);
00150
00151
00152 m_vrsLoader->unlock();
00153 }
00154
00155 VRS::Vector
00156 ODETerrainLoader::interpolate(
00157 const VRS::Vector& p_a,
00158 const VRS::Vector& p_b)
00159 {
00160 return (p_a + p_b)*0.5;
00161 }
00162
00163 unsigned int
00164 ODETerrainLoader::indexForTarget(
00165 unsigned int p_x,
00166 unsigned int p_y,
00167 unsigned int p_lod,
00168 unsigned int p_newLod,
00169 unsigned int p_offsetX,
00170 unsigned int p_offsetY)
00171 {
00172 unsigned int base, oldIndex;
00173
00174 oldIndex = (p_y*p_lod + p_x);
00175
00176 base = oldIndex*2 + (p_y*(p_newLod-1));
00177
00178 return (base+(p_offsetY*p_newLod) + p_offsetX);
00179 }
00180
00181 void
00182 ODETerrainLoader::doubleVertices(
00183 std::vector<VRS::Vector>& p_source,
00184 std::vector<VRS::Vector>& p_target,
00185 unsigned int p_lod,
00186 unsigned int p_newLod)
00187 {
00188 unsigned int i, j;
00189 VRS::Vector p00, p01, p10;
00190
00191
00192 for(i = 0; i < p_lod; i++)
00193 {
00194 for(j = 0; j < p_lod; j++)
00195 {
00196 p00 = p_source[ (i*p_lod + j) ];
00197
00198 if(i < (p_lod-1) && j < (p_lod-1))
00199 {
00200 p01 = p_source[ ((i+1)*p_lod + j) ];
00201 p10 = p_source[ (i*p_lod + j + 1) ];
00202
00203 p_target[indexForTarget(j, i, p_lod, p_newLod, 0, 0)] = p00;
00204
00205 p_target[indexForTarget(j, i, p_lod, p_newLod, 0, 1)] =
00206 interpolate(p00, p01);
00207
00208 p_target[indexForTarget(j, i, p_lod, p_newLod, 1, 0)] =
00209 interpolate(p00, p10);
00210
00211 p_target[indexForTarget(j, i, p_lod, p_newLod, 1, 1)] =
00212 interpolate(p01, p10);
00213 }
00214 else
00215 {
00216 p_target[indexForTarget(j, i, p_lod, p_newLod, 0, 0)] = p00;
00217
00218 if(i == p_lod-1)
00219 {
00220 p_target[indexForTarget(j, i, p_lod, p_newLod, 1, 0)] = p00;
00221 }
00222 else if(j == p_lod-1)
00223 {
00224 p_target[indexForTarget(j, i, p_lod, p_newLod, 0, 1)] = p00;
00225 }
00226 }
00227 }
00228 }
00229 }
00230
00231 void
00232 ODETerrainLoader::replaceTerrain(
00233 const VRS::Vector& p_position, const VRS::Vector& p_center)
00234 {
00235 m_triangleData->initDataUpdateKeepCurrent();
00236
00237 const unsigned int lod = 9;
00238 const unsigned int multLod = (lod - 1)*2 + 1;
00239 const unsigned int multLod2 = (multLod - 1)*2 + 1;
00240 const unsigned int multLod3 = (multLod2 - 1)*2 + 1;
00241
00242
00243 std::vector<VRS::Vector> temp, temp2(multLod*multLod);
00244
00245 grabVertices(p_center, &temp);
00246
00247 doubleVertices(temp, temp2, lod, multLod);
00248
00249 temp.resize(multLod2*multLod2);
00250
00251 doubleVertices(temp2, temp, multLod, multLod2);
00252
00253 temp2.resize(multLod3*multLod3);
00254
00255 doubleVertices(temp, temp2, multLod2, multLod3);
00256
00257 convertVertices(
00258 temp2.begin(), temp2.end(), m_triangleData->uncommittedVertexArray());
00259
00260
00261 m_vrsLoader->lock();
00262 Vector translate = m_vrsLoader->m_translation->getTranslate();
00263 m_vrsLoader->unlock();
00264
00265 translate[1] = 0.1;
00266
00267 m_trimeshBody->setPosition(translate);
00268
00269 m_triangleData->setVertexArrayFill(multLod3*multLod3);
00270 m_triangleData->setIndexArrayFill((multLod3-1)*(multLod3-1)*2*3);
00271 m_triangleData->commitDataUpdate();
00272 }
00273
00274 }