00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Collision/InputOutput/TextCollisionLoader.h"
00027 #include "Core/InputOutput/TextFileReader.h"
00028 #include "Core/InputOutput/StreamTokenizer.h"
00029 #include "Core/InputOutput/FilePath.h"
00030 #include "Collision/System/CollisionScene.h"
00031 #include "Collision/System/CollisionNode.h"
00032 #include "Collision/Leaf/StaticSphereCollision.h"
00033 #include "Collision/Leaf/StaticDeformedMeshCollision.h"
00034
00035 namespace Lamp{
00036
00037
00038
00039 TextCollisionLoader::TextCollisionLoader(){
00040 }
00041
00042
00043 TextCollisionLoader::~TextCollisionLoader(){
00044 }
00045
00046
00047 void TextCollisionLoader::load(const String& filePath, CollisionScene* scene){
00048 load(filePath, scene, scene->getRootNode());
00049 }
00050
00051
00052 void TextCollisionLoader::load(const String& filePath, CollisionScene* scene,
00053 CollisionNode* node){
00054 FilePath path(filePath);
00055 if(!path.existFile()){
00056 ErrorOut("TextCollisionLoader::load() ファイルが見つかりませんでした %s",
00057 filePath.getBytes());
00058 return;
00059 }
00060 TextFileReader* textFileReader = new TextFileReader(filePath);
00061 load(textFileReader, scene, node);
00062 delete textFileReader;
00063 }
00064
00065
00066 void TextCollisionLoader::load(TextReader* textReader, CollisionScene* scene){
00067 load(textReader, scene, scene->getRootNode());
00068 }
00069
00070
00071 void TextCollisionLoader::load(TextReader* textReader, CollisionScene* scene,
00072 CollisionNode* node){
00073
00074 tokenizer_ = new StreamTokenizer(textReader);
00075 scene_ = scene;
00076 rootNode_ = node;
00077
00078
00079 bool rootNodeEnabled = rootNode_->isEnabled();
00080 rootNode_->setEnabled(false);
00081
00082
00083 readHeader();
00084
00085 while(true){
00086
00087 if(!tokenizer_->nextToken()){ break; }
00088 String chunkName = tokenizer_->getToken();
00089 if(chunkName == "CollisionNode"){
00090 readCollisionNodeList();
00091 }else if(chunkName == "CollisionLeaf"){
00092 readCollisionLeafList();
00093 }else if(chunkName == "CollisionNodeLink"){
00094 readCollisionLinkList();
00095 }else{
00096 ErrorOut("TextCollisionLoader::load() "
00097 "invalid chunk %s (line %d)",
00098 chunkName.getBytes(), tokenizer_->getLineNumber());
00099 }
00100 }
00101 delete tokenizer_;
00102
00103 rootNode_->setEnabled(rootNodeEnabled);
00104 }
00105
00106
00107 void TextCollisionLoader::readHeader(){
00108 skipWord("Header");
00109 openChunk();
00110 skipWord("type");
00111 skipWord("LampTextCollisionFormat");
00112 skipWord("version");
00113 skipWord("0_1_0");
00114 closeChunk();
00115 }
00116
00117
00118
00119
00120 void TextCollisionLoader::readCollisionNodeList(){
00121 openChunk();
00122 while(true){
00123 String token = readToken("readCollisionNodeList()");
00124 if(token == "}"){ break; }
00125 readCollisionNode(token);
00126 }
00127 }
00128
00129
00130 void TextCollisionLoader::readCollisionNode(const String& name){
00131 CollisionNode* node = scene_->createCollisionNode(name);
00132 openChunk();
00133
00134 skipWord("scale");
00135 node->setScale(readVector3());
00136
00137 skipWord("rotation");
00138 node->setRotationXYZ(readVector3());
00139
00140 skipWord("translation");
00141 node->setTranslation(readVector3());
00142
00143 skipWord("enabled");
00144 node->setEnabled(readBool());
00145 closeChunk();
00146 }
00147
00148
00149
00150
00151 void TextCollisionLoader::readCollisionLeafList(){
00152 openChunk();
00153 while(true){
00154 String token = readToken("readCollisionLeafList()");
00155 if(token == "}"){ break; }
00156 openChunk();
00157 skipWord("type");
00158 String type = readToken("readCollisionLeafList()");
00159 if(type == "StaticSphere"){
00160 readStaticSphere(token);
00161 }else if(type == "StaticDeformedMesh"){
00162 readStaticDeformedMesh(token);
00163 }else{
00164 ErrorOut("TextCollisionLoader::readCollisionLeafList() "
00165 "不正なタイプです %s (line %d)",
00166 type.getBytes(), tokenizer_->getLineNumber());
00167 }
00168 closeChunk();
00169 }
00170 }
00171
00172
00173 void TextCollisionLoader::readStaticSphere(const String& name){
00174 StaticSphereCollision* sphere = scene_->createStaticSphereCollision(name);
00175
00176 skipWord("collisionMask");
00177 sphere->setCollisionMask(readUInt());
00178
00179 skipWord("enabled");
00180 sphere->setEnabled(readBool());
00181
00182 skipWord("sphere");
00183 sphere->setSphere(readSphere());
00184 }
00185
00186
00187 void TextCollisionLoader::readStaticDeformedMesh(const String& name){
00188 StaticDeformedMeshCollision* mesh =
00189 scene_->createStaticDeformedMeshCollision(name);
00190
00191 skipWord("collisionMask");
00192 mesh->setCollisionMask(readUInt());
00193
00194 skipWord("enabled");
00195 mesh->setEnabled(readBool());
00196
00197 skipWord("boundingBox");
00198 mesh->setBoundingBox(readAxisAlignedBox());
00199
00200 skipWord("boundingSphere");
00201 mesh->setBoundingSphere(readSphere());
00202
00203 skipWord("triangleCount");
00204 int triangleCount = readInt();
00205 mesh->setTriangleCount(triangleCount);
00206 openChunk();
00207 for(int i = 0; i < triangleCount; i++){
00208 mesh->setTriangle(i, readTriangle());
00209 }
00210 closeChunk();
00211 }
00212
00213
00214
00215
00216 void TextCollisionLoader::readCollisionLinkList(){
00217 openChunk();
00218 while(true){
00219 String token = readToken("readCollisionLinkList()");
00220 if(token == "}"){ break; }
00221 readCollisionLink(token);
00222 }
00223 }
00224
00225
00226 void TextCollisionLoader::readCollisionLink(const String& name){
00227 CollisionNode* node;
00228 if(name.equals("RootNode")){
00229 node = rootNode_;
00230 }else{
00231 node = scene_->searchNode(name);
00232 if(node == NULL){
00233 ErrorOut("TextCollisionLoader::readCollisionLink() "
00234 "親ノードが見つかりません %s (line %d)",
00235 name.getBytes(), tokenizer_->getLineNumber());
00236 }
00237 }
00238
00239 openChunk();
00240 while(true){
00241 String token = readToken("readCollisionLink()");
00242 if(token == "}"){ break; }
00243 if(token == "node"){
00244 String childName = readToken("readCollisionLink()");
00245 CollisionNode* child = scene_->searchNode(childName);
00246 if(child == NULL){
00247 ErrorOut("TextCollisionLoader::readCollisionLink() "
00248 "子ノードが見つかりません %s (line %d)",
00249 childName.getBytes(), tokenizer_->getLineNumber());
00250 }
00251 node->addChild(child);
00252 }else if(token == "leaf"){
00253 String childName = readToken("readCollisionLink()");
00254 CollisionLeaf* child = scene_->searchLeaf(childName);
00255 if(child == NULL){
00256 ErrorOut("TextCollisionLoader::readCollisionLink() "
00257 "子リーフが見つかりません %s (line %d)",
00258 childName.getBytes(), tokenizer_->getLineNumber());
00259 }
00260 node->addChild(child);
00261 }else{
00262 ErrorOut("TextCollisionLoader::readCollisionLink() "
00263 "不正なトークンです %s (line %d)",
00264 token.getBytes(), tokenizer_->getLineNumber());
00265 }
00266 }
00267 }
00268
00269
00270
00271
00272 bool TextCollisionLoader::readBool(){
00273 String token = readToken("readBool()");
00274 if(token == "true"){ return true; }
00275 else if(token == "false"){ return false; }
00276 ErrorOut("TextCollisionLoader::readBool() 不正なトークンです %s (line %d)",
00277 token.getBytes(), tokenizer_->getLineNumber());
00278 return false;
00279 }
00280
00281
00282 int TextCollisionLoader::readInt(){
00283 String token = readToken("readInt()");
00284 int value = 0;
00285 bool result = token.parseInt(&value);
00286 if(!result){
00287 ErrorOut("TextCollisionLoader::readInt() "
00288 "不正なトークンです %s (line %d)",
00289 token.getBytes(), tokenizer_->getLineNumber());
00290 }
00291 return value;
00292 }
00293
00294
00295 u_int TextCollisionLoader::readUInt(){
00296 String token = readToken("readInt()");
00297 u_int value = 0;
00298 bool result = token.parseUInt(&value);
00299 if(!result){
00300 ErrorOut("TextCollisionLoader::readUInt() "
00301 "不正なトークンです %s (line %d)",
00302 token.getBytes(), tokenizer_->getLineNumber());
00303 }
00304 return value;
00305 }
00306
00307
00308 float TextCollisionLoader::readFloat(){
00309 String token = readToken("readFloat()");
00310 float value = 0.f;
00311 bool result = token.parseFloat(&value);
00312 if(!result){
00313 ErrorOut("TextCollisionLoader::readFloat() "
00314 "不正なトークンです %s (line %d)",
00315 token.getBytes(), tokenizer_->getLineNumber());
00316 }
00317 return value;
00318 }
00319
00320
00321 Vector3 TextCollisionLoader::readVector3(){
00322 Vector3 result;
00323 openChunk();
00324 result.x = readFloat();
00325 result.y = readFloat();
00326 result.z = readFloat();
00327 closeChunk();
00328 return result;
00329 }
00330
00331
00332 AxisAlignedBox TextCollisionLoader::readAxisAlignedBox(){
00333 AxisAlignedBox result;
00334 Vector3 minimum, maximum;
00335 openChunk();
00336 minimum.x = readFloat();
00337 minimum.y = readFloat();
00338 minimum.z = readFloat();
00339 closeChunk();
00340 openChunk();
00341 maximum.x = readFloat();
00342 maximum.y = readFloat();
00343 maximum.z = readFloat();
00344 closeChunk();
00345 result.set(minimum, maximum);
00346 return result;
00347 }
00348
00349
00350 Sphere TextCollisionLoader::readSphere(){
00351 Sphere result;
00352 Vector3 vector;
00353 openChunk();
00354 vector.x = readFloat();
00355 vector.y = readFloat();
00356 vector.z = readFloat();
00357 result.setCenter(vector);
00358 result.setRadius(readFloat());
00359 closeChunk();
00360 return result;
00361 }
00362
00363
00364 Triangle TextCollisionLoader::readTriangle(){
00365 Triangle result;
00366 Vector3 vector;
00367 for(int i = 0; i < 3; i++){
00368 openChunk();
00369 vector.x = readFloat();
00370 vector.y = readFloat();
00371 vector.z = readFloat();
00372 result.setVertex(i, vector);
00373 closeChunk();
00374 }
00375 return result;
00376 }
00377
00378
00379
00380
00381 String TextCollisionLoader::readToken(const String& caller){
00382 bool hasNext = tokenizer_->nextToken();
00383 if(!hasNext){
00384 ErrorOut("TextCollisionLoader::%s トークンがありません (line %d)",
00385 caller.getBytes(), tokenizer_->getLineNumber());
00386 }
00387 return tokenizer_->getToken();
00388 }
00389
00390
00391 void TextCollisionLoader::skipWord(const String& word){
00392 String token = readToken("skipWord()");
00393 if(token != word){
00394 ErrorOut("TextCollisionLoader::skipWord(%s) "
00395 "不正なトークンです %s (line %d)",
00396 word.getBytes(), token.getBytes(), tokenizer_->getLineNumber());
00397 }
00398 }
00399
00400
00401 void TextCollisionLoader::skipChunk(){
00402 int chunkLine = tokenizer_->getLineNumber();
00403 int chunkCounter = 0;
00404 while(true){
00405 bool hasNext = tokenizer_->nextToken();
00406 if(!hasNext){
00407 ErrorOut("TextCollisionLoader::skipChunk(%d) "
00408 "トークンがありません (line %d)",
00409 chunkLine, tokenizer_->getLineNumber());
00410 }
00411 String token = tokenizer_->getToken();
00412 if(token == "{"){
00413 chunkCounter++;
00414 }else if(token == "}"){
00415 chunkCounter--;
00416
00417 if(chunkCounter == 0){ break; }
00418 if(chunkCounter < 0){
00419 ErrorOut("TextCollisionLoader::skipChunk(%d) "
00420 "不正なチャンクです (line %d)",
00421 chunkLine, tokenizer_->getLineNumber());
00422 }
00423 }
00424 }
00425 }
00426
00427 }
00428