2017-05-18 14 views
1

OpenGLで3DモデルにAABBを作成しようとしています。頂点がすべて1.0の3D box.objを使用すると、モデル間の衝突を検出する問題はありません。しかし、頂点に異なる値を持つより複雑な3Dモデルを使用すると、問題が発生します。複雑なモデルはbox.objよりも小さく、.18と.06のような頂点値を持つので、それらのバウンディングボックスは非常に大きいので、エンジンは接触していないときにオブジェクト間の衝突を検出します。この問題の解決策は、モデルをゲームに読み込むときにx軸、y軸、z軸のそれぞれの最大/最小値を記録することですが、問題があります。以下はOpenGLで3DモデルにAABBを作成する

モデルに読み込むための私のコードです:/ ** /コメントアウト

bool Model::buffer(string objFile) 
{ 
vector<vec3> locs; 
vector<vec2> uvs; 
vector<vec3> norms; 

vector<VertInd> vertInds; 

// Open file for reading 
ifstream inFile; 
inFile.open(objFile); 

string line; 

if (inFile.is_open()) 
{ 
    // Enter a loop that reads every line iteration from file until file is empty 
    while (getline(inFile, line)) 
    { 
     istringstream ss(line); 
     string lineLabel; 

     // Read a string (the line label) from the line 
     ss >> lineLabel; 

     if (lineLabel == "v") // Vertices 
     { 
      float a, b, c; 
      ss >> a >> b >> c; 
      locs.push_back(vec3(a, b, c)); 
     } 
     else if (lineLabel == "vt") // Texture Coordinates 
     { 
      float a, b; 
      ss >> a >> b; 
      uvs.push_back(vec2(a, b)); 
     } 
     else if (lineLabel == "vn") // Vertex Normals 
     { 
      float a, b, c; 
      ss >> a >> b >> c; 
      norms.push_back(vec3(a, b, c)); 
     } 
     // Get indices 
     else if (lineLabel == "f") 
     { 
      // do three times 
      for (int i = 0; i < 3; i++) 
      { 
       unsigned int a, b, c; 
       char s1, s2; 

       // Read int, then char slash 
       ss >> a >> s1 >> b >> s2 >> c; 

       // Decrement each of the ints by 1 
       vertInds.push_back(VertInd{ a - 1, b - 1, c - 1 }); 
      } 
     } 

     /* GLfloat min_x, max_x, min_y, max_y, min_z, max_z; 

     min_x = max_x = locs[0].x; 
     min_y = max_y = locs[0].y; 
     min_z = max_z = locs[0].z; 

     for (int i = 0; i < locs.size(); i++) 
     { 
      if (locs[i].x < min_x) min_x = locs[i].x; 
      if (locs[i].x > max_x) max_x = locs[i].x; 
      if (locs[i].y < min_y) min_y = locs[i].y; 
      if (locs[i].y > max_y) max_y = locs[i].y; 
      if (locs[i].z < min_z) min_z = locs[i].z; 
      if (locs[i].z > max_z) max_z = locs[i].z; 
     } 
     vec3 size = vec3(max_x - min_x, max_y - min_y, max_z - min_z); 
     vec3 center = vec3((min_x + max_x)/2, (min_y + max_y)/2, (min_z + max_z)/2); 
     mat4 transform = translate(mat4(1), center) * scale(mat4(1), size); 

     mat4 m = camera.camMat * transform; 
     glUniformMatrix4fv(2, 1, GL_FALSE, &m[0][0]); */ 
    } 
    // Close the file 
    inFile.close(); 
} 

vertCount = vertInds.size(); 

GLuint vertBuf; 

vector<Vertex> vertBufData(vertCount); 
for (unsigned int i = 0; i < vertCount; i++) 
    vertBufData[i] = { locs[vertInds[i].locInd], uvs[vertInds[i].uvInd], norms[vertInds[i].normInd] }; 

// Vertex array 
glGenVertexArrays(1, &vertArr); 
glGenBuffers(1, &vertBuf); 

// Buffer data 
glBindVertexArray(vertArr); 
glBindBuffer(GL_ARRAY_BUFFER, vertBuf); 
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) *vertCount, &vertBufData[0], GL_STATIC_DRAW); 

glEnableVertexAttribArray(0); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 
glEnableVertexAttribArray(1); 
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)sizeof(vec3)); // (void*)sizeof(VertInd)); 
glEnableVertexAttribArray(4); 
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(vec3) + sizeof(vec2))); 
glBindVertexArray(0); 

//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 

return true; 

}

セクションでは、私は最近、最小/最大を取得しようとする試みに追加した部分であります私のモデルを中心にしていますが、シーンはロードされません。どんな助けでも大歓迎です。ありがとうございました。

答えて

1

使用例here参照:

// return the min/max points of pts 
template< typename Vec > 
pair< Vec, Vec > GetExtents(const Vec* pts, size_t stride, size_t count) 
{ 
    unsigned char* base = (unsigned char*)pts; 
    Vec pmin(*(Vec*)base); 
    Vec pmax(*(Vec*)base); 
    for(size_t i = 0; i < count; ++i, base += stride) 
    { 
     const Vec& pt = *(Vec*)base; 
     pmin = glm::min(pmin, pt); 
     pmax = glm::max(pmax, pt); 
    } 

    return make_pair(pmin, pmax); 
} 

// centers geometry around the origin 
// and scales it to fit in a size^3 box 
template< typename Vec > 
void CenterAndScale(Vec* pts, size_t stride, size_t count, const typename Vec::value_type& size) 
{ 
    typedef typename Vec::value_type Scalar; 

    // get min/max extents 
    pair< Vec, Vec > exts = GetExtents(pts, stride, count); 

    // center and scale 
    const Vec center = (exts.first * Scalar(0.5)) + (exts.second * Scalar(0.5f)); 

    const Scalar factor = size/glm::compMax(exts.second - exts.first); 
    unsigned char* base = (unsigned char*)pts; 
    for(size_t i = 0; i < count; ++i, base += stride) 
    { 
     Vec& pt = *(Vec*)base; 
     pt = ((pt - center) * factor); 
    }  
} 
+1

うわー、ありがとうございました。これは非常に助けになりました。 – crin

関連する問題