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 "Graphics/MeshData/MeshData.h"
00027 #include "Graphics/MeshData/MeshDataManager.h"
00028 #include "Graphics/Renderer/RenderingDevice.h"
00029
00030 namespace Lamp{
00031
00032
00033
00034 MeshData::MeshData(const String& name, Scene* scene) :
00035 SceneObject(name, scene), boundingSphere_(Sphere::zero),
00036 boundingBox_(AxisAlignedBox::zero), indexBuffer_(NULL),
00037 vertexDeclaration_(NULL), vertexSize_(0), vertexBuffer_(NULL),
00038 primitiveType_(Mesh::triangleList),
00039 vertexIndexCount_(0), vertexIndexArray_(NULL), vertexCount_(0),
00040 positions_(NULL), normals_(NULL), colors_(NULL),
00041 texCoordSetCount_(0), normalFlag_(false), colorFlag_(false),
00042 bonesPerVertex_(0), boneIndices_(NULL), weightsPerVertex_(0),
00043 weights_(NULL), vertexBufferChanged_(true), indexBufferChanged_(true),
00044 boundingChanged_(true){
00045 for(int i = 0; i < TexCoord::maxSetCount; i++){
00046 texCoordTypes_[i] = TexCoord::type2;
00047 texCoords_[i] = NULL;
00048 }
00049 }
00050
00051
00052 MeshData::~MeshData(){
00053 SafeArrayDelete(weights_);
00054 SafeArrayDelete(boneIndices_);
00055 for(int i = 0; i < texCoordSetCount_; i++){
00056 SafeArrayDelete(texCoords_[i]);
00057 }
00058 SafeArrayDelete(colors_);
00059 SafeArrayDelete(normals_);
00060 SafeArrayDelete(positions_);
00061 SafeArrayDelete(vertexIndexArray_);
00062 SafeRelease(vertexBuffer_);
00063 SafeRelease(vertexDeclaration_);
00064 SafeRelease(indexBuffer_);
00065 }
00066
00067
00068 MeshData* MeshData::copy() const{
00069 MeshDataManager* manager = scene_->getMeshDataManager();
00070 MeshData* copyMeshData = manager->createMeshData(manager->rename(name_));
00071
00072 copyMeshDataValue(copyMeshData);
00073 return copyMeshData;
00074 }
00075
00076
00077 int MeshData::destroy(MeshData* meshData){
00078 Assert(meshData != NULL);
00079
00080 MeshDataManager* manager = meshData->getScene()->getMeshDataManager();
00081 if(manager->destroy(meshData) == 0){ return 1; }
00082 return 0;
00083 }
00084
00085
00086 void MeshData::copyMeshDataValue(MeshData* destination) const{
00087 destination->setBoundingBox(getBoundingBox());
00088 destination->setBoundingSphere(getBoundingSphere());
00089
00090 destination->setPrimitiveType(primitiveType_);
00091
00092 if(hasVertexIndices()){
00093 destination->setVertexIndexCount(vertexIndexCount_);
00094 std::memcpy(destination->vertexIndexArray_,
00095 vertexIndexArray_, sizeof(u_short) * vertexIndexCount_);
00096 }
00097
00098 destination->setVertexCount(vertexCount_);
00099 std::memcpy(destination->positions_,
00100 positions_, sizeof(Vector3) * vertexCount_);
00101
00102 destination->enableNormal(normalFlag_);
00103 if(normalFlag_){
00104 std::memcpy(destination->normals_,
00105 normals_, sizeof(Vector3) * vertexCount_);
00106 }
00107
00108 destination->enableColor(colorFlag_);
00109 if(colorFlag_){
00110 std::memcpy(destination->colors_,
00111 colors_, sizeof(Color4c) * vertexCount_);
00112 }
00113
00114 destination->setTexCoordSetCount(texCoordSetCount_);
00115 for(int i = 0; i < texCoordSetCount_; i++){
00116 destination->setTexCoordType(i, texCoordTypes_[i]);
00117 std::memcpy(destination->texCoords_[i], texCoords_[i],
00118 sizeof(float) * texCoordTypes_[i] * vertexCount_);
00119 }
00120
00121 if(hasBoneIndex()){
00122 std::memcpy(destination->boneIndices_,
00123 boneIndices_, sizeof(u_char) * vertexCount_ * bonesPerVertex_);
00124 }
00125
00126 if(hasWeight()){
00127 std::memcpy(destination->weights_,
00128 weights_, sizeof(float) * vertexCount_ * weightsPerVertex_);
00129 }
00130 }
00131
00132
00133
00134
00135 void MeshData::setPrimitiveType(Mesh::PrimitiveType primitiveType){
00136 primitiveType_ = primitiveType;
00137
00138 vertexIndexCount_ = 0;
00139 SafeArrayDelete(vertexIndexArray_);
00140
00141 SafeRelease(indexBuffer_);
00142 }
00143
00144
00145 int MeshData::getPrimitiveCount() const{
00146 if(primitiveType_ == Mesh::triangleList){
00147 Assert((getVertexCount() % 3) == 0);
00148 return (getVertexCount() / 3);
00149 }else if(primitiveType_ == Mesh::indexedTriangleList){
00150 Assert((getVertexIndexCount() % 3) == 0);
00151 return (getVertexIndexCount() / 3);
00152 }
00153 ErrorOut("MeshData::getPrimitiveCount() "
00154 "サポートされていないプリミティブタイプです");
00155 return 0;
00156 }
00157
00158
00159 Triangle MeshData::getTriangle(int index) const{
00160 Triangle triangle;
00161 int offset = index * 3;
00162 if(primitiveType_ == Mesh::triangleList){
00163 triangle.setVertex(0, getPosition(offset + 0));
00164 triangle.setVertex(1, getPosition(offset + 1));
00165 triangle.setVertex(2, getPosition(offset + 2));
00166 }else if(primitiveType_ == Mesh::indexedTriangleList){
00167 triangle.setVertex(0, getPosition(getVertexIndex(offset + 0)));
00168 triangle.setVertex(1, getPosition(getVertexIndex(offset + 1)));
00169 triangle.setVertex(2, getPosition(getVertexIndex(offset + 2)));
00170 }else{
00171 ErrorOut("MeshData::getTriangle() "
00172 "サポートされていないプリミティブタイプです");
00173 }
00174 return triangle;
00175 }
00176
00177
00178
00179
00180 void MeshData::setVertexIndexCount(int vertexIndexCount){
00181 Assert(hasVertexIndices());
00182 if(vertexIndexCount_ == vertexIndexCount){ return; }
00183 vertexIndexCount_ = vertexIndexCount;
00184 SafeArrayDelete(vertexIndexArray_);
00185 if(vertexIndexCount_ == 0){ return; }
00186 vertexIndexArray_ = new u_short[vertexIndexCount_];
00187
00188 SafeRelease(indexBuffer_);
00189 }
00190
00191
00192
00193
00194 void MeshData::setVertexCount(int vertexCount){
00195 Assert(vertexCount >= 0);
00196 if(vertexCount_ == vertexCount){ return; }
00197 vertexCount_ = vertexCount;
00198 SafeArrayDelete(boneIndices_);
00199 SafeArrayDelete(weights_);
00200 for(int i = 0; i < texCoordSetCount_; i++){
00201 SafeArrayDelete(texCoords_[i]);
00202 }
00203 SafeArrayDelete(colors_);
00204 SafeArrayDelete(normals_);
00205 SafeArrayDelete(positions_);
00206 if(vertexCount_ == 0){ return; }
00207 positions_ = new Vector3[vertexCount_];
00208 if(normalFlag_){ normals_ = new Vector3[vertexCount_]; }
00209 if(colorFlag_){ colors_ = new Color4c[vertexCount_]; }
00210 for(int i = 0; i < texCoordSetCount_; i++){
00211 texCoords_[i] = new float[vertexCount_ * texCoordTypes_[i]];
00212 }
00213 if(hasBoneIndex()){
00214 boneIndices_ = new u_char[vertexCount_ * bonesPerVertex_];
00215 }
00216 if(hasWeight()){ weights_ = new float[vertexCount_ * weightsPerVertex_]; }
00217
00218 SafeRelease(vertexBuffer_);
00219 }
00220
00221
00222 void MeshData::enableNormal(bool normalFlag){
00223 if(normalFlag_ == normalFlag){ return; }
00224 normalFlag_ = normalFlag;
00225 SafeArrayDelete(normals_);
00226 if(normalFlag_ && (vertexCount_ != 0)){
00227 normals_ = new Vector3[vertexCount_];
00228 }
00229
00230 SafeRelease(vertexBuffer_);
00231
00232 vertexSize_ = 0;
00233 SafeRelease(vertexDeclaration_);
00234 }
00235
00236
00237 void MeshData::enableColor(bool colorFlag){
00238 if(colorFlag_ == colorFlag){ return; }
00239 colorFlag_ = colorFlag;
00240 SafeArrayDelete(colors_);
00241 if(colorFlag_ && (vertexCount_ != 0)){
00242 colors_ = new Color4c[vertexCount_];
00243 }
00244
00245 SafeRelease(vertexBuffer_);
00246
00247 vertexSize_ = 0;
00248 SafeRelease(vertexDeclaration_);
00249 }
00250
00251
00252 void MeshData::setTexCoordSetCount(int texCoordSetCount){
00253 if(texCoordSetCount_ == texCoordSetCount){ return; }
00254 for(int i = 0; i < texCoordSetCount; i++){ SafeArrayDelete(texCoords_[i]); }
00255 texCoordSetCount_ = texCoordSetCount;
00256 if(vertexCount_ == 0){ return; }
00257 for(int i = 0; i < texCoordSetCount_; i++){
00258 texCoords_[i] = new float[vertexCount_ * texCoordTypes_[i]];
00259 }
00260
00261 SafeRelease(vertexBuffer_);
00262
00263 vertexSize_ = 0;
00264 SafeRelease(vertexDeclaration_);
00265 }
00266
00267
00268 void MeshData::setTexCoordType(int texCoordSet, TexCoord::Type texCoordType){
00269 Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
00270 if(texCoordTypes_[texCoordSet] == texCoordType){ return; }
00271 texCoordTypes_[texCoordSet] = texCoordType;
00272 SafeArrayDelete(texCoords_[texCoordSet]);
00273 if(vertexCount_ == 0){ return; }
00274 texCoords_[texCoordSet] =
00275 new float[vertexCount_ * texCoordTypes_[texCoordSet]];
00276
00277 SafeRelease(vertexBuffer_);
00278
00279 vertexSize_ = 0;
00280 SafeRelease(vertexDeclaration_);
00281 }
00282
00283
00284 void MeshData::setBonesPerVertex(int bonesPerVertex){
00285 Assert(bonesPerVertex >= 0);
00286 Assert(bonesPerVertex <= 4);
00287 if(bonesPerVertex_ == bonesPerVertex){ return; }
00288 bonesPerVertex_ = bonesPerVertex;
00289 weightsPerVertex_ = (bonesPerVertex_ - 1);
00290 if(weightsPerVertex_ < 0){ weightsPerVertex_ = 0; }
00291
00292 SafeArrayDelete(weights_);
00293 SafeArrayDelete(boneIndices_);
00294 if(vertexCount_ == 0){ return; }
00295 if(hasBoneIndex()){
00296 boneIndices_ = new u_char[vertexCount_ * bonesPerVertex_];
00297 }
00298 if(hasWeight()){
00299 weights_ = new float[vertexCount_ * weightsPerVertex_];
00300 }
00301
00302 SafeRelease(vertexBuffer_);
00303
00304 vertexSize_ = 0;
00305 SafeRelease(vertexDeclaration_);
00306 }
00307
00308
00309
00310
00311 Direct3DIndexBuffer* MeshData::getIndexBuffer(){
00312
00313 if(indexBuffer_ == NULL){
00314 Assert(hasVertexIndices());
00315 Assert(getVertexIndexCount() != 0);
00316 RenderingDevice* device = RenderingDevice::getInstance();
00317 int bufferSize = getVertexIndexCount() * sizeof(u_short);
00318 indexBuffer_ = device->createDynamicIndexBuffer(bufferSize);
00319 indexBufferChanged_ = true;
00320 }
00321
00322 if(indexBufferChanged_){
00323 RenderingDevice* device = RenderingDevice::getInstance();
00324 int bufferSize = getVertexIndexCount() * sizeof(u_short);
00325 device->writeDynamicIndexBuffer(
00326 indexBuffer_, getVertexIndexArray(), bufferSize);
00327 indexBufferChanged_ = false;
00328 }
00329 return indexBuffer_;
00330 }
00331
00332
00333 Direct3DVertexDeclaration* MeshData::getVertexDeclaration(){
00334
00335 if(vertexDeclaration_ == NULL){
00336 Assert(vertexSize_ == 0);
00337 vertexSize_ = RenderingDevice::getInstance()->createVertexDeclaration(
00338 &vertexDeclaration_, true, getWeightsPerVertex(),
00339 getBonesPerVertex(), hasNormal(), hasColor(), getTexCoordSetCount(),
00340 getTexCoordTypeArray());
00341 }
00342 return vertexDeclaration_;
00343 }
00344
00345
00346 int MeshData::getVertexSize(){
00347 getVertexDeclaration();
00348 return vertexSize_;
00349 }
00350
00351
00352 Direct3DVertexBuffer* MeshData::getVertexBuffer(){
00353 RenderingDevice* device = RenderingDevice::getInstance();
00354 int vertexCount = getVertexCount();
00355 int bufferSize = getVertexSize() * vertexCount;
00356
00357 if(vertexBuffer_ == NULL){
00358 vertexBuffer_ = device->createDynamicVertexBuffer(bufferSize);
00359 vertexBufferChanged_ = true;
00360 }
00361
00362 if(vertexBufferChanged_){
00363 device->writeDynamicVertexBuffer(vertexBuffer_, bufferSize, vertexCount,
00364 getPositionArray(), getWeightsPerVertex(), getWeightArray(),
00365 getBonesPerVertex(), getBoneIndexArray(), getNormalArray(),
00366 getColorArray(), getTexCoordSetCount(), getTexCoordTypeArray(),
00367 getTexCoordArray());
00368 vertexBufferChanged_ = false;
00369 }
00370 return vertexBuffer_;
00371 }
00372
00373 }
00374