Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# PrimitiveDrawRequestBuilder.cpp

Go to the documentation of this file.

    00001 //------------------------------------------------------------------------------
    00002 // Lamp : Open source game middleware
    00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
    00004 //
    00005 // This library is free software; you can redistribute it and/or
    00006 // modify it under the terms of the GNU Lesser General Public
    00007 // License as published by the Free Software Foundation; either
    00008 // version 2.1 of the License, or (at your option) any later version.
    00009 //
    00010 // This library is distributed in the hope that it will be useful,
    00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013 // Lesser General Public License for more details.
    00014 //
    00015 // You should have received a copy of the GNU Lesser General Public
    00016 // License along with this library; if not, write to the Free Software
    00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00018 //------------------------------------------------------------------------------
    00019
    00020 /** @file
    00021  * プリミティブ描画リクエストビルダ実装
    00022  * @author Junpee
    00023  */
    00024
    00025 #include "LampBasic.h"
    00026 #include "Graphics/PrimitiveRenderer/PrimitiveDrawRequestBuilder.h"
    00027 #include "Graphics/PrimitiveRenderer/PrimitiveDrawRequest.h"
    00028 #include "Graphics/Model/CharacterModel.h"
    00029
    00030 namespace Lamp{
    00031
    00032 //------------------------------------------------------------------------------
    00033 // ポイントの構築
    00034 void PrimitiveDrawRequestBuilder::buildPoint(PrimitiveDrawRequest* request){
    00035     request->setVertexCount(12);
    00036     request->enableColor(true);
    00037     // X軸
    00038     request->setPosition(0, Vector3::zero);
    00039     request->setColor(0, Color4c(255, 255, 255, 255));
    00040     request->setPosition(1, Vector3::unitX);
    00041     request->setColor(1, Color4c(255, 255, 255, 64));
    00042     request->setPosition(2, Vector3::zero);
    00043     request->setColor(2, Color4c(255, 255, 255, 255));
    00044     request->setPosition(3, -Vector3::unitX);
    00045     request->setColor(3, Color4c(255, 255, 255, 64));
    00046     // Y軸
    00047     request->setPosition(4, Vector3::zero);
    00048     request->setColor(4, Color4c(255, 255, 255, 255));
    00049     request->setPosition(5, Vector3::unitY);
    00050     request->setColor(5, Color4c(255, 255, 255, 64));
    00051     request->setPosition(6, Vector3::zero);
    00052     request->setColor(6, Color4c(255, 255, 255, 255));
    00053     request->setPosition(7, -Vector3::unitY);
    00054     request->setColor(7, Color4c(255, 255, 255, 64));
    00055     // Z軸
    00056     request->setPosition(8, Vector3::zero);
    00057     request->setColor(8, Color4c(255, 255, 255, 255));
    00058     request->setPosition(9, Vector3::unitZ);
    00059     request->setColor(9, Color4c(255, 255, 255, 64));
    00060     request->setPosition(10, Vector3::zero);
    00061     request->setColor(10, Color4c(255, 255, 255, 255));
    00062     request->setPosition(11, -Vector3::unitZ);
    00063     request->setColor(11, Color4c(255, 255, 255, 64));
    00064 }
    00065 //------------------------------------------------------------------------------
    00066 // 軸ポイントの構築
    00067 void PrimitiveDrawRequestBuilder::buildAxisPoint(PrimitiveDrawRequest* request){
    00068     request->setVertexCount(12);
    00069     request->enableColor(true);
    00070     // X軸
    00071     request->setPosition(0, Vector3::zero);
    00072     request->setColor(0, Color4c(255, 0, 0, 255));
    00073     request->setPosition(1, Vector3::unitX);
    00074     request->setColor(1, Color4c(255, 0, 0, 64));
    00075     request->setPosition(2, Vector3::zero);
    00076     request->setColor(2, Color4c(255, 0, 0, 255));
    00077     request->setPosition(3, -Vector3::unitX);
    00078     request->setColor(3, Color4c(255, 0, 0, 64));
    00079     // Y軸
    00080     request->setPosition(4, Vector3::zero);
    00081     request->setColor(4, Color4c(0, 255, 0, 255));
    00082     request->setPosition(5, Vector3::unitY);
    00083     request->setColor(5, Color4c(0, 255, 0, 64));
    00084     request->setPosition(6, Vector3::zero);
    00085     request->setColor(6, Color4c(0, 255, 0, 255));
    00086     request->setPosition(7, -Vector3::unitY);
    00087     request->setColor(7, Color4c(0, 255, 0, 64));
    00088     // Z軸
    00089     request->setPosition(8, Vector3::zero);
    00090     request->setColor(8, Color4c(0, 0, 255, 255));
    00091     request->setPosition(9, Vector3::unitZ);
    00092     request->setColor(9, Color4c(0, 0, 255, 64));
    00093     request->setPosition(10, Vector3::zero);
    00094     request->setColor(10, Color4c(0, 0, 255, 255));
    00095     request->setPosition(11, -Vector3::unitZ);
    00096     request->setColor(11, Color4c(0, 0, 255, 64));
    00097 }
    00098 //------------------------------------------------------------------------------
    00099 // 軸の構築
    00100 void PrimitiveDrawRequestBuilder::buildAxis(PrimitiveDrawRequest* request){
    00101     request->setVertexCount(6);
    00102     request->enableColor(true);
    00103     // X軸
    00104     request->setPosition(0, Vector3::zero);
    00105     request->setColor(0, Color4c(255, 0, 0, 255));
    00106     request->setPosition(1, Vector3::unitX);
    00107     request->setColor(1, Color4c(255, 0, 0, 64));
    00108     // Y軸
    00109     request->setPosition(2, Vector3::zero);
    00110     request->setColor(2, Color4c(0, 255, 0, 255));
    00111     request->setPosition(3, Vector3::unitY);
    00112     request->setColor(3, Color4c(0, 255, 0, 64));
    00113     // Z軸
    00114     request->setPosition(4, Vector3::zero);
    00115     request->setColor(4, Color4c(0, 0, 255, 255));
    00116     request->setPosition(5, Vector3::unitZ);
    00117     request->setColor(5, Color4c(0, 0, 255, 64));
    00118 }
    00119 //------------------------------------------------------------------------------
    00120 // 矢印の構築
    00121 void PrimitiveDrawRequestBuilder::buildArrow(PrimitiveDrawRequest* request){
    00122     request->setVertexCount(10);
    00123     request->enableColor(true);
    00124     request->setPosition(0, Vector3::zero);
    00125     request->setColor(0, Color4c(255, 255, 255, 255));
    00126     request->setPosition(1, Vector3::unitZ);
    00127     request->setColor(1, Color4c(255, 255, 255, 255));
    00128
    00129     float width = 0.25f;
    00130     request->setPosition(2, Vector3::unitZ);
    00131     request->setColor(2, Color4c(255, 255, 255, 255));
    00132     request->setPosition(3, Vector3(width, width, 0.5f));
    00133     request->setColor(3, Color4c(255, 255, 255, 64));
    00134
    00135     request->setPosition(4, Vector3::unitZ);
    00136     request->setColor(4, Color4c(255, 255, 255, 255));
    00137     request->setPosition(5, Vector3(width, -width, 0.5f));
    00138     request->setColor(5, Color4c(255, 255, 255, 64));
    00139
    00140     request->setPosition(6, Vector3::unitZ);
    00141     request->setColor(6, Color4c(255, 255, 255, 255));
    00142     request->setPosition(7, Vector3(-width, width, 0.5f));
    00143     request->setColor(7, Color4c(255, 255, 255, 64));
    00144
    00145     request->setPosition(8, Vector3::unitZ);
    00146     request->setColor(8, Color4c(255, 255, 255, 255));
    00147     request->setPosition(9, Vector3(-width, -width, 0.5f));
    00148     request->setColor(9, Color4c(255, 255, 255, 64));
    00149
    00150 }
    00151 //------------------------------------------------------------------------------
    00152 // グリッドの構築
    00153 void PrimitiveDrawRequestBuilder::buildGrid(
    00154     PrimitiveDrawRequest* request, int division, int subDivision){
    00155     int totalDivision = division * subDivision;
    00156     int lineCount = totalDivision + 1;
    00157     request->setVertexCount(lineCount * 4);
    00158     request->enableColor(true);
    00159     float scale = 1.f / totalDivision;
    00160     for(int i = 0; i < lineCount; i++){
    00161         int offset = i * 4;
    00162         float value = i * scale - 0.5f;
    00163         request->setPosition(offset + 0, Vector3(value, 0.f, -0.5f));
    00164         request->setPosition(offset + 1, Vector3(value, 0.f, 0.5f));
    00165         request->setPosition(offset + 2, Vector3(-0.5f, 0.f, value));
    00166         request->setPosition(offset + 3, Vector3(0.5f, 0.f, value));
    00167         Color4c color;
    00168         if((i % subDivision) == 0){ color.set(255, 255, 255, 255); }
    00169         else{ color.set(255, 255, 255, 64); }
    00170         for(int j = 0; j < 4; j++){ request->setColor(offset + j,color); }
    00171     }
    00172 }
    00173 //------------------------------------------------------------------------------
    00174 // 平面の構築
    00175 void PrimitiveDrawRequestBuilder::buildPlane(PrimitiveDrawRequest* request){
    00176     request->setVertexCount(10);
    00177     request->enableColor(true);
    00178     request->setPosition(0, Vector3(0.f, 0.f, 0.f));
    00179     request->setColor(0, Color4c(255, 255, 255, 255));
    00180     request->setPosition(1, Vector3(0.f, 0.f, 1.f));
    00181     request->setColor(1, Color4c(255, 255, 255, 192));
    00182
    00183     request->setPosition(2, Vector3(0.5f, 0.5f, 0.f));
    00184     request->setColor(2, Color4c(255, 255, 255, 192));
    00185     request->setPosition(3, Vector3(-0.5f, 0.5f, 0.f));
    00186     request->setColor(3, Color4c(255, 255, 255, 192));
    00187
    00188     request->setPosition(4, Vector3(-0.5f, 0.5f, 0.f));
    00189     request->setColor(4, Color4c(255, 255, 255, 192));
    00190     request->setPosition(5, Vector3(-0.5f, -0.5f, 0.f));
    00191     request->setColor(5, Color4c(255, 255, 255, 192));
    00192
    00193     request->setPosition(6, Vector3(-0.5f, -0.5f, 0.f));
    00194     request->setColor(6, Color4c(255, 255, 255, 192));
    00195     request->setPosition(7, Vector3(0.5f, -0.5f, 0.f));
    00196     request->setColor(7, Color4c(255, 255, 255, 192));
    00197
    00198     request->setPosition(8, Vector3(0.5f, -0.5f, 0.f));
    00199     request->setColor(8, Color4c(255, 255, 255, 192));
    00200     request->setPosition(9, Vector3(0.5f, 0.5f, 0.f));
    00201     request->setColor(9, Color4c(255, 255, 255, 192));
    00202 }
    00203 //------------------------------------------------------------------------------
    00204 // 球の構築
    00205 void PrimitiveDrawRequestBuilder::buildSphere(PrimitiveDrawRequest* request,
    00206     float radius, int horizontalDivision, int verticalDivision){
    00207     Assert(radius > 0.f);
    00208     Assert(horizontalDivision > 2);
    00209     Assert(verticalDivision > 2);
    00210     int offset;
    00211     // 頂点の構築
    00212     int vertexCount = (verticalDivision - 1) * horizontalDivision + 2;
    00213     request->setVertexCount(vertexCount);
    00214     offset = 0;
    00215     // 上
    00216     request->setPosition(offset, Vector3(0.f, radius, 0.f));
    00217     offset++;
    00218     // 下
    00219     request->setPosition(offset, Vector3(0.f, -radius, 0.f));
    00220     offset++;
    00221     // 中
    00222     for(int i = 1; i < verticalDivision; i++){
    00223         float yValue = Math::cos(Math::PI * i / verticalDivision) * radius;
    00224         float scale = Math::sin(Math::PI * i / verticalDivision) * radius;
    00225         for(int j = 0; j < horizontalDivision; j++){
    00226             float radian = Math::doublePI * j / horizontalDivision;
    00227             request->setPosition(offset, Vector3(
    00228                 Math::cos(radian) * scale, yValue, Math::sin(radian) * scale));
    00229             offset++;
    00230         }
    00231     }
    00232     Assert(offset == vertexCount);
    00233
    00234     // インデックスの構築
    00235     int indexCount = (verticalDivision - 2) * horizontalDivision * 4 +
    00236         horizontalDivision * 6;
    00237     request->setVertexIndexCount(indexCount);
    00238     offset = 0;
    00239     // ふた
    00240     for(int i = 0; i < horizontalDivision; i++){
    00241         request->setVertexIndex(offset, 0);
    00242         offset++;
    00243         request->setVertexIndex(offset, i + 2);
    00244         offset++;
    00245     }
    00246     // 中間
    00247     int verticalCount = verticalDivision - 1;
    00248     for(int i = 1; i < verticalCount; i++){
    00249         int upOffset = horizontalDivision * (i - 1) + 2;
    00250         int downOffset = upOffset + horizontalDivision;
    00251         for(int j = 0; j < horizontalDivision; j++){
    00252             int leftUp = upOffset + j;
    00253             request->setVertexIndex(offset, leftUp);
    00254             offset++;
    00255             int rightUp = leftUp + 1;
    00256             if(j == (horizontalDivision - 1)){ rightUp -= horizontalDivision; }
    00257             request->setVertexIndex(offset, rightUp);
    00258             offset++;
    00259             request->setVertexIndex(offset, leftUp);
    00260             offset++;
    00261             request->setVertexIndex(offset, downOffset + j);
    00262             offset++;
    00263         }
    00264     }
    00265     // 底
    00266     int bottomOffset = (verticalDivision - 2) * horizontalDivision + 2;
    00267     for(int i = 0; i < horizontalDivision; i++){
    00268         int leftUp = i + bottomOffset;
    00269         request->setVertexIndex(offset, leftUp);
    00270         offset++;
    00271         request->setVertexIndex(offset, 1);
    00272         offset++;
    00273         request->setVertexIndex(offset, leftUp);
    00274         offset++;
    00275         int rightUp = leftUp + 1;
    00276         if(i == (horizontalDivision - 1)){ rightUp -= horizontalDivision; }
    00277         request->setVertexIndex(offset, rightUp);
    00278         offset++;
    00279     }
    00280     Assert(offset == indexCount);
    00281 }
    00282 //------------------------------------------------------------------------------
    00283 // 箱の構築
    00284 void PrimitiveDrawRequestBuilder::buildBox(
    00285     PrimitiveDrawRequest* request, float width, float height, float depth){
    00286     Assert(width > 0.f);
    00287     Assert(height > 0.f);
    00288     Assert(depth > 0.f);
    00289     // 頂点の構築
    00290     float halfWidth = width * 0.5f;
    00291     float halfHeight = height * 0.5f;
    00292     float halfDepth = depth * 0.5f;
    00293     request->setVertexCount(8);
    00294     request->setPosition(0, Vector3(-halfWidth, -halfHeight, -halfDepth));
    00295     request->setPosition(1, Vector3(-halfWidth,  halfHeight, -halfDepth));
    00296     request->setPosition(2, Vector3( halfWidth,  halfHeight, -halfDepth));
    00297     request->setPosition(3, Vector3( halfWidth, -halfHeight, -halfDepth));
    00298     request->setPosition(4, Vector3( halfWidth,  halfHeight,  halfDepth));
    00299     request->setPosition(5, Vector3(-halfWidth,  halfHeight,  halfDepth));
    00300     request->setPosition(6, Vector3(-halfWidth, -halfHeight,  halfDepth));
    00301     request->setPosition(7, Vector3( halfWidth, -halfHeight,  halfDepth));
    00302
    00303     // インデックスの構築
    00304     const int indexCount = 24;
    00305     u_short indices[indexCount] = {
    00306         0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6,
    00307         6, 7, 7, 4, 0, 6, 1, 5, 2, 4, 3, 7 };
    00308     request->setVertexIndexCount(indexCount);
    00309     for(int i = 0; i < indexCount; i++){
    00310         request->setVertexIndex(i, indices[i]);
    00311     }
    00312 }
    00313 //------------------------------------------------------------------------------
    00314 // 円柱の構築
    00315 void PrimitiveDrawRequestBuilder::buildCylinder(
    00316     PrimitiveDrawRequest* request, float radius, float height, int division){
    00317     Assert(radius > 0.f);
    00318     Assert(height > 0.f);
    00319     Assert(division > 2);
    00320     // 頂点の構築
    00321     request->setVertexCount(division * 2);
    00322     for(int i = 0; i < division; i++){
    00323         float radian = Math::doublePI * i / division;
    00324         float xValue = Math::cos(radian) * radius;
    00325         float zValue = Math::sin(radian) * radius;
    00326         int offset = i * 2;
    00327         request->setPosition(offset + 0, Vector3(xValue, 0.f, zValue));
    00328         request->setPosition(offset + 1, Vector3(xValue, height, zValue));
    00329     }
    00330
    00331     // インデックスの構築
    00332     request->setVertexIndexCount(division * 6);
    00333     for(int i = 0; i < division; i++){
    00334         int offset = i * 6;
    00335         int leftUp = i * 2;
    00336         int leftDown = leftUp + 1;
    00337         request->setVertexIndex(offset + 0, leftUp);
    00338         request->setVertexIndex(offset + 1, leftDown);
    00339         request->setVertexIndex(offset + 2, leftUp);
    00340         request->setVertexIndex(offset + 4, leftDown);
    00341         if(i == (division - 1)){
    00342             request->setVertexIndex(offset + 3, 0);
    00343             request->setVertexIndex(offset + 5, 1);
    00344         }else{
    00345             request->setVertexIndex(offset + 3, leftUp + 2);
    00346             request->setVertexIndex(offset + 5, leftDown + 2);
    00347         }
    00348     }
    00349 }
    00350 //------------------------------------------------------------------------------
    00351 // コーンの構築
    00352 void PrimitiveDrawRequestBuilder::buildCone(
    00353     PrimitiveDrawRequest* request, float radius, float height, int division){
    00354     Assert(radius > 0.f);
    00355     Assert(height > 0.f);
    00356     Assert(division > 2);
    00357     // 頂点の構築
    00358     request->setVertexCount(division + 1);
    00359     request->setPosition(0, Vector3(0.f, height, 0.f));
    00360     for(int i = 0; i < division; i++){
    00361         float radian = Math::doublePI * i / division;
    00362         float xValue = Math::cos(radian) * radius;
    00363         float zValue = Math::sin(radian) * radius;
    00364         request->setPosition(i + 1, Vector3(xValue, 0.f, zValue));
    00365     }
    00366
    00367     // インデックスの構築
    00368     request->setVertexIndexCount(division * 4);
    00369     for(int i = 0; i < division; i++){
    00370         int offset = i * 4;
    00371         request->setVertexIndex(offset + 0, 0);
    00372         request->setVertexIndex(offset + 1, i + 1);
    00373         request->setVertexIndex(offset + 2, i + 1);
    00374         if(i == (division - 1)){ request->setVertexIndex(offset + 3, 1); }
    00375         else{ request->setVertexIndex(offset + 3, i + 2); }
    00376     }
    00377 }
    00378 //------------------------------------------------------------------------------
    00379 // ボーンの構築
    00380 void PrimitiveDrawRequestBuilder::buildBone(
    00381     PrimitiveDrawRequest* request, CharacterModel* model){
    00382     Assert(model != NULL);
    00383     int boneCount = model->getBoneCount();
    00384     Assert(boneCount != 0);
    00385     model->buildBoneMatrix();
    00386     // ルートボーン以外に対して一本の線が引かれる
    00387     int vertexCount = (boneCount - 1) * 2;
    00388     request->setVertexCount(vertexCount);
    00389     request->enableColor(true);
    00390     int offset = 0;
    00391     for(int i = 0; i < boneCount; i++){
    00392         Bone* bone = model->getBone(i);
    00393         // ボーン位置算出行列は deform * invertPose.invert()
    00394         Matrix34 matrix = bone->getInversePoseMatrix();
    00395         matrix.invertTransformation();
    00396         matrix = bone->getDeformMatrix() * matrix;
    00397         Vector3 position = matrix * Vector3::zero;
    00398         int childCount = bone->getBoneCount();
    00399         for(int j = 0; j < childCount; j++){
    00400             Bone* child = bone->getBone(j);
    00401             // ボーン位置算出行列は deform * invertPose.invert()
    00402             Matrix34 childMatrix = child->getInversePoseMatrix();
    00403             childMatrix.invertTransformation();
    00404             childMatrix = child->getDeformMatrix() * childMatrix;
    00405             Vector3 childPosition = childMatrix * Vector3::zero;
    00406             request->setPosition(offset, position);
    00407             request->setColor(offset, Color4c::white);
    00408             offset++;
    00409             request->setPosition(offset, childPosition);
    00410             request->setColor(offset, Color4c(255, 255, 255, 64));
    00411             offset++;
    00412         }
    00413     }
    00414     Assert(vertexCount == offset)
    00415 }
    00416 //------------------------------------------------------------------------------
    00417 } // End of namespace Lamp
    00418 //------------------------------------------------------------------------------