WMO/Rendering: Difference between revisions

From wowdev
Jump to navigation Jump to search
(→‎CMapObjGroup::QueryLighting: Some code clean up)
Line 90: Line 90:


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
bool CMapObjGroup::QueryLighting(CMapObjGroup *this, const C3Vector *point, unsigned __int16 polyIdx, CImVector *color, bool *a5) {
bool CMapObjGroup::QueryLighting(CMapObjGroup *this, const C3Vector *point, uint16_t polyIdx, CImVector *color, bool *a5) {


   // Out of bounds
   // Out of bounds
Line 115: Line 115:
   }
   }


   indices = &this->indexList[3 * polyIdx];
   uint16_t* indices = &this->indexList[3 * polyIdx];
  vertices = this->vertexList;


   vert1 = &vertices[*indices];
   C3Vector* vertices = this->vertexList;
  vert2 = &vertices[indices[1]];
  vert3 = &vertices[indices[2]];


   v11 = vert3->x - vert1->x;
   C3Vector* vert1 = &vertices[indices[0]];
  v12 = vert3->y - vert1->y;
   C3Vector* vert2 = &vertices[indices[1]];
   v13 = vert3->z - vert1->z;
   C3Vector* vert3 = &vertices[indices[2]];
  v14 = vert2->x - vert1->x;
  v15 = vert2->y - vert1->y;
   v16 = vert2->z - vert1->z;


   v53.x = v15 * v13 - v16 * v12;
   C4Plane plane;
   v53.y = v16 * v11 - v13 * v14;
   C4Plane::From3Pos(&plane, vert1, vert2, vert3);
  v53.z = v12 * v14 - v11 * v15;


   v17 = C3Vector::MajorAxis(&v53);
   int axis = C3Vector::MajorAxis(&plane.normal);
 
  v19 = 4 * xyAxisTable[axis].x;
  v20 = 4 * xyAxisTable[axis].y;


  v18 = 8 * v17 + 0xD2DC00;
  v19 = 4 * xyAxisTable[v17].x;
  v20 = 4 * *(_DWORD *)(v18 + 4);
   v21 = *(float *)((char *)&vert1->x + v19);
   v21 = *(float *)((char *)&vert1->x + v19);
   v22 = *(float *)((char *)&vert1->x + v20);
   v22 = *(float *)((char *)&vert1->x + v20);
Line 156: Line 149:
   v33 = (signed int)v32;
   v33 = (signed int)v32;
   v34 = 256 - (signed int)v32 - v31;
   v34 = 256 - (signed int)v32 - v31;
   pointa = (signed int)v32;
   v58 = (signed int)v32;
   if ( v31 < 0 )
 
  {
   if (v31 < 0) {
 
     v35 = v31 * v33 / (v33 + v34);
     v35 = v31 * v33 / (v33 + v34);
     v33 = (int)vert3 + v35;
     v33 = (int)vert3 + v35;
     v34 += v31 - v35;
     v34 += v31 - v35;
     pointa = (int)vert3 + v35;
     v58 = (int)vert3 + v35;
     v31 = 0;
     v31 = 0;
   }
   }
   if ( v33 < 0 )
 
  {
   if (v33 < 0) {
 
     v36 = v31 * v33 / (v34 + v31);
     v36 = v31 * v33 / (v34 + v31);
     v31 += v36;
     v31 += v36;
     v34 += pointa - v36;
     v34 += v58 - v36;
     v33 = 0;
     v33 = 0;
     pointa = 0;
     v58 = 0;
 
   }
   }
   if ( v34 < 0 )
 
  {
   if (v34 < 0) {
 
     v37 = v31 * v34 / (v33 + v31);
     v37 = v31 * v34 / (v33 + v31);
     pointa += v34 - v37;
     v58 += v34 - v37;
     v31 += v37;
     v31 += v37;
     v34 = 0;
     v34 = 0;
   }
   }
  color->a = (unsigned __int16)(pointa * v56->colorVertexList[indices[2]].a
                              + v34 * v56->colorVertexList[*indices].a
                              + v31 * v56->colorVertexList[indices[1]].a) >> 8;
  color->r = (unsigned __int16)(pointa * v56->colorVertexList[indices[2]].r
                              + v34 * v56->colorVertexList[*indices].r
                              + v31 * v56->colorVertexList[indices[1]].r) >> 8;
  v38 = v56;
  color->g = (unsigned __int16)(pointa * v56->colorVertexList[indices[2]].g
                              + v34 * v56->colorVertexList[*indices].g
                              + v31 * v56->colorVertexList[indices[1]].g) >> 8;
  v39 = v38->colorVertexList;
  v40 = v31 * v39[indices[1]].b;
  v41 = v34 * v39[*indices].b;
  v42 = pointa * v39[indices[2]].b;
  v43 = color->g;
  v44 = v41 + v40;
  v45 = v56;
  v46 = v42 + v44;
  v47 = color->r;
  v46 >>= 8;
  color->b = v46;
  v48 = v45->parent;
  v49 = 2 * v47;
  v50 = 2 * v43;
  v51 = 2 * (unsigned __int8)v46;


   if (v48->header->flags & 2) {
  color->a = (unsigned __int16)(v58 * this->colorVertexList[indices[2]].a
                              + v34 * this->colorVertexList[indices[0]].a
                              + v31 * this->colorVertexList[indices[1]].a) >> 8;
 
  color->r = (unsigned __int16)(v58 * this->colorVertexList[indices[2]].r
                              + v34 * this->colorVertexList[indices[0]].r
                              + v31 * this->colorVertexList[indices[1]].r) >> 8;
 
  color->g = (unsigned __int16)(v58 * this->colorVertexList[indices[2]].g
                              + v34 * this->colorVertexList[indices[0]].g
                              + v31 * this->colorVertexList[indices[1]].g) >> 8;
 
  color->b = (unsigned __int16)(v58 * this->colorVertexList[indices[2]].b
                              + v34 * this->colorVertexList[indices[0]].b
                              + v31 * this->colorVertexList[indices[1]].b) >> 8;
 
  uint32_t v49 = 2 * color->r;
  uint32_t v50 = 2 * color->g;
  uint32_t v51 = 2 * color->b;
 
   if (this->parent->header->flags & 0x2) {


     v49 += v48->ambColor.r;
     v49 += this->parent->ambColor.r;
     v50 += v48->ambColor.g;
     v50 += this->parent->ambColor.g;
     v51 += v48->ambColor.b;
     v51 += this->parent->ambColor.b;


   }
   }
Line 218: Line 212:
   color->b = v51 >= 0xFF ? 0xFF : v51;
   color->b = v51 >= 0xFF ? 0xFF : v51;


   *a5 = v56->polyList[polyIdx].flags & 1;
   *a5 = this->polyList[polyIdx].flags & 0x1;


   return 1;
   return 1;

Revision as of 14:44, 5 October 2017

Lighting

Lighting for interior WMO groups is prebaked into vertex colors.

CMapObj::QueryLighting

In order to light entities like units, game objects, etc that exist within interior WMO groups, the game does the following:

  1. Query for the closest MOPY.
  2. Obtain the 3 relevant MOCV values for the MOPY.
  3. Create a CImVector color by interpolating the values based on the position of the entity relative to the MOPY (ie barycentric interpolation).

This queried color value is then fed in to the standard lighting logic.

Query with C3Segment

The following function is used to query lighting when the exact poly is not yet known. It uses a C3Segment to perform a ranged query against the BSP tree for relevant tris.

bool CMapObj::QueryLighting(CMapObj *this, uint32_t groupIndex, const C3Segment *seg, CImVector *color, bool *a5) {

  CMapObjGroup group = this->groupList[groupIndex];

  if (!this->unk6[16] || !(group->unk14 & 1) || group->flags & (SMOGroup::EXTERIOR | SMOGroup::EXTERIOR_LIT)) {

    return 0;

  }

  World::TriData::resultFlags = 0;
  World::TriData::nBatches = 0;
  World::TriData::nTriIndices = 0;
  World::TriData::nVertexIndices = 0;
  World::TriData::nMatrices = 0;

  float hitT = 1.0;

  // Query the BSP tree for the group to find appropriate tris

  bool triRes = CMapObjGroup::GetTris(group, seg, &hitT, 0, 0x8, (int)&a2 + 3, 0);

  if (!triRes) {

    return 0;

  }

  // Obtain point matching intersection between segment and tri

  C3Vector point;

  point.x = seg->start.x + hitT * (seg->end.x - seg->start.x);
  point.y = seg->start.y + hitT * (seg->end.y - seg->start.y);
  point.z = seg->start.z + hitT * (seg->end.z - seg->start.z);

  unsigned __int16 hitPoly = word_CD8094;

  bool lightRes = CMapObjGroup::QueryLighting(group, &point, hitPoly, color, a5);

  return lightRes;

}

Query with C3Vector and poly index

The following function is used to query lighting when the relevant poly is already known.

bool CMapObj::QueryLighting(CMapObj *this, uint32_t groupIndex, const C3Vector *point, uint16_t polyIdx, CImVector *color, bool *a5) {

  CMapObjGroup group = this->groupList[groupIndex];

  if (!this->unk6[16] || !(group->unk14 & 1) || group->flags & (SMOGroup::EXTERIOR | SMOGroup::EXTERIOR_LIT)) {

    return 0;

  }

  // Since the point and poly are already known, there's no need to query the BSP tree

  bool lightRes = CMapObjGroup::QueryLighting(group, point, polyIdx, color, a5);

  return lightRes;

}

CMapObjGroup::QueryLighting

bool CMapObjGroup::QueryLighting(CMapObjGroup *this, const C3Vector *point, uint16_t polyIdx, CImVector *color, bool *a5) {

  // Out of bounds

  if (polyIdx >= this->polyCount) {

    *color = this->parent->ambColor;
    *a5 = 0;

    return 1;

  }

  // Load xyAxisTable

  if (!(dword_D2DC18 & 1)) {

    dword_D2DC18 |= 1u;

    xyAxisTable[0] = { 1, 2 };
    xyAxisTable[1] = { 2, 0 };
    xyAxisTable[2] = { 0, 1 };

  }

  uint16_t* indices = &this->indexList[3 * polyIdx];

  C3Vector* vertices = this->vertexList;

  C3Vector* vert1 = &vertices[indices[0]];
  C3Vector* vert2 = &vertices[indices[1]];
  C3Vector* vert3 = &vertices[indices[2]];

  C4Plane plane;
  C4Plane::From3Pos(&plane, vert1, vert2, vert3);

  int axis = C3Vector::MajorAxis(&plane.normal);

  v19 = 4 * xyAxisTable[axis].x;
  v20 = 4 * xyAxisTable[axis].y;

  v21 = *(float *)((char *)&vert1->x + v19);
  v22 = *(float *)((char *)&vert1->x + v20);
  v23 = *(float *)((char *)&vert2->x + v19) - v21;
  v24 = *(float *)((char *)&vert3->x + v19) - v21;
  v25 = *(float *)((char *)&vert3->x + v20) - v22;
  v26 = *(float *)((char *)&point->x + v19) - v21;
  v27 = *(float *)((char *)&vert2->x + v20) - v22;
  v28 = v25;
  v29 = 1.0 / (v25 * v23 - v27 * v24);
  v30 = *(float *)((char *)&point->x + v20) - v22;
  v54 = v29 * (v23 * v30 - v26 * v27);
  *(float *)&vert3 = (v28 * v26 - v24 * v30) * v29 * 256.0;
  v31 = (signed int)(*(float *)&vert3 - flt_AEEE50);
  *(float *)&pointb = v54 * 256.0;
  v32 = *(float *)&pointb - flt_AEEE50;
  vert3 = (C3Vector *)(signed int)v32;
  v33 = (signed int)v32;
  v34 = 256 - (signed int)v32 - v31;
  v58 = (signed int)v32;

  if (v31 < 0) {

    v35 = v31 * v33 / (v33 + v34);
    v33 = (int)vert3 + v35;
    v34 += v31 - v35;
    v58 = (int)vert3 + v35;
    v31 = 0;

  }

  if (v33 < 0) {

    v36 = v31 * v33 / (v34 + v31);
    v31 += v36;
    v34 += v58 - v36;
    v33 = 0;
    v58 = 0;

  }

  if (v34 < 0) {

    v37 = v31 * v34 / (v33 + v31);
    v58 += v34 - v37;
    v31 += v37;
    v34 = 0;

  }

  color->a = (unsigned __int16)(v58 * this->colorVertexList[indices[2]].a
                              + v34 * this->colorVertexList[indices[0]].a
                              + v31 * this->colorVertexList[indices[1]].a) >> 8;

  color->r = (unsigned __int16)(v58 * this->colorVertexList[indices[2]].r
                              + v34 * this->colorVertexList[indices[0]].r
                              + v31 * this->colorVertexList[indices[1]].r) >> 8;

  color->g = (unsigned __int16)(v58 * this->colorVertexList[indices[2]].g
                              + v34 * this->colorVertexList[indices[0]].g
                              + v31 * this->colorVertexList[indices[1]].g) >> 8;

  color->b = (unsigned __int16)(v58 * this->colorVertexList[indices[2]].b
                              + v34 * this->colorVertexList[indices[0]].b
                              + v31 * this->colorVertexList[indices[1]].b) >> 8;

  uint32_t v49 = 2 * color->r;
  uint32_t v50 = 2 * color->g;
  uint32_t v51 = 2 * color->b;

  if (this->parent->header->flags & 0x2) {

    v49 += this->parent->ambColor.r;
    v50 += this->parent->ambColor.g;
    v51 += this->parent->ambColor.b;

  }

  color->r = v49 >= 0xFF ? 0xFF : v49;
  color->g = v50 >= 0xFF ? 0xFF : v50;
  color->b = v51 >= 0xFF ? 0xFF : v51;

  *a5 = this->polyList[polyIdx].flags & 0x1;

  return 1;

}