# HG changeset patch # User Ritor1 # Date 1395315509 -21600 # Node ID 133882370e837186b71fb6901b7673aabd983cd2 # Parent 345b1ff000bbe74bf00886a44f43f715594ece5c far_clip and near_clip for draw terrain diff -r 345b1ff000bb -r 133882370e83 Indoor.cpp --- a/Indoor.cpp Thu Mar 20 09:13:42 2014 +0600 +++ b/Indoor.cpp Thu Mar 20 17:38:29 2014 +0600 @@ -5507,16 +5507,16 @@ for ( uint i = 1; i <= pFace->uNumVertices; ++i) { next_vertices_flag = PortalFace._view_transformed_z[i + 3] >= 0x80000; //524288;// 8.0 - if ( current_vertices_flag ^ next_vertices_flag )//или текущая или следующая вершина за ближней границей + if ( current_vertices_flag ^ next_vertices_flag )//или текущая или следующая вершина за ближней границей - v5 { if ( next_vertices_flag )//следующая вершина за ближней границей { - //t = near_clip - v0.z / v1.z - v0.z + //t = near_clip - v4.z / v5.z - v4.z t = fixpoint_div(0x80000 - PortalFace._view_transformed_z[i + 2], PortalFace._view_transformed_z[i + 3] - PortalFace._view_transformed_z[i + 2]); - //New_x = (v1.x - v0.x)*t + v0.x + //New_x = (v5.x - v4.x)*t + v4.x PortalFace._view_transformed_x[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_x[i + 3] - PortalFace._view_transformed_x[i + 2]), t) + PortalFace._view_transformed_x[i + 2]; - //New_y = (v1.y - v0.y)*t + v0.y + //New_y = (v5.y - v4.y)*t + v4.y PortalFace._view_transformed_y[depth_num_vertices] = fixpoint_mul((PortalFace._view_transformed_y[i + 3] - PortalFace._view_transformed_y[i + 2]), t) + PortalFace._view_transformed_y[i + 2]; //New_z = 8.0(0x80000) diff -r 345b1ff000bb -r 133882370e83 Render.cpp --- a/Render.cpp Thu Mar 20 09:13:42 2014 +0600 +++ b/Render.cpp Thu Mar 20 17:38:29 2014 +0600 @@ -263,8 +263,8 @@ pGame->pIndoorCameraD3D->Project(&pTerrainVertices[z * 128 + x], 1, 0); } } -//-------------------------------------------------------------------------------------------------------------------- - int direction = pGame->pIndoorCameraD3D->sRotationY / 256;//direction of the camera(напрвление камеры), не могу округлить :( +//-------(Отсечение невидимой части карты)------------------------------------------------------------------------------------------ + float direction = pGame->pIndoorCameraD3D->sRotationY / 256;//direction of the camera(напрвление камеры) //0-East(B) //1-NorthEast(CB) //2-North(C) @@ -274,42 +274,30 @@ //6-South(Ю) //7-SouthEast(ЮВ) int Start_X, End_X, Start_Z, End_Z; - switch ( direction ) - { - case 0://East(B) - Start_X = pODMRenderParams->uMapGridCellX, End_X = 127; - Start_Z = 0, End_Z = 127; - break; - case 1://NorthEast(CB) - Start_X = 0,/*pODMRenderParams->uMapGridCellX - 1,*/ End_X = 127; - Start_Z = 0, End_Z = pODMRenderParams->uMapGridCellZ; - break; - case 2://North(C) + if ( direction >= 0 && direction < 1.0 )//East(B) - NorthEast(CB) + { + Start_X = pODMRenderParams->uMapGridCellX, End_X = 127; + Start_Z = 0, End_Z = 127; + } + else if (direction >= 1.0 && direction < 3.0)//NorthEast(CB) - WestNorth(CЗ) + { Start_X = 0, End_X = 127; Start_Z = 0, End_Z = pODMRenderParams->uMapGridCellZ; - break; - case 3://WestNorth(CЗ) - Start_X = 0, End_X = pODMRenderParams->uMapGridCellX + 1; - Start_Z = 0, End_Z = 127;//pODMRenderParams->uMapGridCellZ + 2; - break; - case 4://West(З) - Start_X = 0, End_X = pODMRenderParams->uMapGridCellX + 1; - Start_Z = 0, End_Z = 127; - break; - case 5://SouthWest(ЮЗ) - Start_X = 0, End_X = 127;//pODMRenderParams->uMapGridCellX + 2; - Start_Z = pODMRenderParams->uMapGridCellZ - 1, End_Z = 127; - break; - case 6://South(Ю) - Start_X = 0, End_X = 127; - Start_Z = pODMRenderParams->uMapGridCellZ - 1, End_Z = 127; - break; - case 7://SouthEast(ЮВ) - Start_X = pODMRenderParams->uMapGridCellX, End_X = 127; - Start_Z = 0,/*pODMRenderParams->uMapGridCellZ,*/ End_Z = 127; - break; - default: - __debugbreak();//Ritor1: error + } + else if (direction >= 3.0 && direction < 5.0)//WestNorth(CЗ) - SouthWest(ЮЗ) + { + Start_X = 0, End_X = pODMRenderParams->uMapGridCellX + 1; + Start_Z = 0, End_Z = 127; + } + else if ( direction >= 5.0 && direction < 7.0 )//SouthWest(ЮЗ) - //SouthEast(ЮВ) + { + Start_X = 0, End_X = 127; + Start_Z = pODMRenderParams->uMapGridCellZ - 1, End_Z = 127; + } + else//SouthEast(ЮВ) - East(B) + { + Start_X = pODMRenderParams->uMapGridCellX, End_X = 127; + Start_Z = 0, End_Z = 127; } for (unsigned int z = Start_Z; z < End_Z; ++z) { @@ -371,8 +359,8 @@ norm = 0; else norm = &pTerrainNormals[norm_idx]; - //pGame->pLightmapBuilder->StackLights_TerrainFace(norm, &a3a, array_50AC10, 4, 1);//Ritor1: slows - //pDecalBuilder->_49BE8A(pTilePolygon, norm, &a3a, array_50AC10, 4, 1); + pGame->pLightmapBuilder->StackLights_TerrainFace(norm, &a3a, array_50AC10, 4, 1);//Ritor1: slows + pDecalBuilder->_49BE8A(pTilePolygon, norm, &a3a, array_50AC10, 4, 1); //----------------------------------------------------------------------------------------------- ++pODMRenderParams->uNumPolygons; @@ -387,6 +375,31 @@ memcpy(&array_50AC10[k], &array_73D150[k], sizeof(struct RenderVertexSoft)); array_50AC10[k]._rhw = 1.0 / (array_73D150[k].vWorldViewPosition.x + 0.0000001000000011686097); } +//---------Draw distance(Дальность отрисовки)------------------------------- + pODMRenderParams->shading_dist_mist = 0x5000; + bool neer_clip = array_73D150[0].vWorldViewPosition.x < 8.0 + || array_73D150[1].vWorldViewPosition.x < 8.0 + || array_73D150[2].vWorldViewPosition.x < 8.0 + || array_73D150[3].vWorldViewPosition.x < 8.0; + bool far_clip = (double)pODMRenderParams->shading_dist_mist < array_73D150[0].vWorldViewPosition.x + || (double)pODMRenderParams->shading_dist_mist < array_73D150[1].vWorldViewPosition.x + || (double)pODMRenderParams->shading_dist_mist < array_73D150[2].vWorldViewPosition.x + || (double)pODMRenderParams->shading_dist_mist < array_73D150[3].vWorldViewPosition.x; + if ( !byte_4D864C || ~pGame->uFlags & 0x80 ) + { + if ( neer_clip ) + { + pTilePolygon->uNumVertices = ODM_NearClip(pTilePolygon->uNumVertices); + //ODM_Project(pTilePolygon->uNumVertices); + } + if ( far_clip ) + { + + pTilePolygon->uNumVertices = ODM_FarClip(pTilePolygon->uNumVertices); + //ODM_Project(pTilePolygon->uNumVertices); + } + } + pODMRenderParams->shading_dist_mist = 0x2000; // check the transparency and texture (tiles) mapping (проверка прозрачности и наложение текстур (тайлов))---------------------- bool transparent = false; @@ -8511,48 +8524,51 @@ bool current_vertices_flag; // edi@1 bool next_vertices_flag; // [sp+Ch] [bp-24h]@6 double t; // st6@10 - int pNextVertices; + //int pNextVertices; if (!num_vertices) return 0; - memcpy(&array_50AC10[num_vertices], array_50AC10, sizeof(array_50AC10[0])); - current_vertices_flag = 0; - if ( array_50AC10[0].vWorldViewPosition.x >= 8.0 ) - current_vertices_flag = 1; + memcpy(&array_50AC10[num_vertices], &array_50AC10[0], sizeof(array_50AC10[0])); + current_vertices_flag = false; + next_vertices_flag = false; + if ( array_50AC10[0].vWorldViewPosition.x <= 8.0 ) + current_vertices_flag = true; int out_num_vertices = 0; for (int i = 0; i < num_vertices; ++i) { - next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x >= 8.0; - if ( current_vertices_flag != next_vertices_flag ) - { - if ( next_vertices_flag ) + next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x <= 8.0;// + if ( current_vertices_flag ^ next_vertices_flag ) + { + if ( next_vertices_flag )//следующая вершина за ближней границей { //t = near_clip - v0.x / v1.x - v0.x (формула получения точки пересечения отрезка с плоскостью) t = (8.0 - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x); - array_507D30[out_num_vertices].vWorldViewPosition.y = (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t + array_50AC10[i].vWorldViewPosition.y; - array_507D30[out_num_vertices].vWorldViewPosition.z = (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t + array_50AC10[i].vWorldViewPosition.z; - array_507D30[out_num_vertices].u = (array_50AC10[i + 1].u - array_50AC10[i].u) * t + array_50AC10[i].u; - array_507D30[out_num_vertices].v = (array_50AC10[i + 1].v - array_50AC10[i].v) * t + array_50AC10[i].v; - } - else - { - t = (8.0 - array_50AC10[i + 1].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x); - array_507D30[out_num_vertices].vWorldViewPosition.y = (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t + array_50AC10[i + 1].vWorldViewPosition.y; - array_507D30[out_num_vertices].vWorldViewPosition.z = (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t + array_50AC10[i + 1].vWorldViewPosition.z; - array_507D30[out_num_vertices].u = (array_50AC10[i].u - array_50AC10[i + 1].u) * t + array_50AC10[i + 1].u; - array_507D30[out_num_vertices].v = (array_50AC10[i].v - array_50AC10[i + 1].v) * t + array_50AC10[i + 1].v; - } - array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0; - array_507D30[out_num_vertices]._rhw = 1.0 / 8.0; + array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0; + array_507D30[out_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t; + array_507D30[out_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t; + array_507D30[out_num_vertices].u = array_50AC10[i].u + (array_50AC10[i + 1].u - array_50AC10[i].u) * t; + array_507D30[out_num_vertices].v = array_50AC10[i].v + (array_50AC10[i + 1].v - array_50AC10[i].v) * t; + array_507D30[out_num_vertices]._rhw = 1.0 / 8.0; + } + else// текущая вершина за ближней границей + { + t = (8.0 - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x); + array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0; + array_507D30[out_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t; + array_507D30[out_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t; + array_507D30[out_num_vertices].u = array_50AC10[i].u + (array_50AC10[i].u - array_50AC10[i + 1].u) * t; + array_507D30[out_num_vertices].v = array_50AC10[i].v + (array_50AC10[i].v - array_50AC10[i + 1].v) * t; + array_507D30[out_num_vertices]._rhw = 1.0 / 8.0; + } //array_507D30[out_num_vertices]._rhw = 0x3E000000u; ++out_num_vertices; } - if ( next_vertices_flag ) - { - pNextVertices = out_num_vertices++; - memcpy(&array_507D30[pNextVertices], &array_50AC10[i + 1], 0x30); + if ( !next_vertices_flag ) + { + memcpy(&array_507D30[out_num_vertices], &array_50AC10[i + 1], sizeof(array_50AC10[i + 1])); + out_num_vertices++; } current_vertices_flag = next_vertices_flag; } @@ -8561,59 +8577,92 @@ //----- (00424EE0) -------------------------------------------------------- int ODM_FarClip(unsigned int uNumVertices) { - signed int previous_vertices_flag; // edi@1 + bool current_vertices_flag; // [sp+Ch] [bp-28h]@6 + bool next_vertices_flag; // edi@1 double t; // st6@10 - bool current_vertices_flag; // [sp+Ch] [bp-28h]@6 signed int depth_num_vertices; // [sp+18h] [bp-1Ch]@1 - int pNextVertices; + //int pNextVertices; + bool bFound; //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910 - memcpy(&array_50AC10[uNumVertices], array_50AC10, sizeof(array_50AC10[uNumVertices])); + bFound = false; + + memcpy(&array_50AC10[uNumVertices], &array_50AC10[0], sizeof(array_50AC10[uNumVertices])); depth_num_vertices = 0; - previous_vertices_flag = 0; - if ( array_50AC10[0].vWorldViewPosition.x <= pODMRenderParams->shading_dist_mist ) - previous_vertices_flag = 1;//предыдущая грань меньше границы видимости + current_vertices_flag = false; + if ( array_50AC10[0].vWorldViewPosition.x >= pODMRenderParams->shading_dist_mist ) + current_vertices_flag = true;//настоящая вершина больше границы видимости if ( (signed int)uNumVertices <= 0 ) return 0; - for ( uint i = 1; i <= uNumVertices; ++i ) - { - current_vertices_flag = pODMRenderParams->shading_dist_mist >= array_50AC10[i].vWorldViewPosition.x; - if ( previous_vertices_flag != current_vertices_flag )//одна из граней за границей видимости - { - if ( current_vertices_flag )//текущая грань меньше границы видимости(предыдущая грань за пределами видимости) - { - //t = far_clip - v0.x / v1.x - v0.x (формула получения точки пересечения отрезка с плоскостью) - t = (pODMRenderParams->shading_dist_mist - array_50AC10[i - 1].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i - 1].vWorldViewPosition.x); - array_507D30[depth_num_vertices].vWorldViewPosition.y = (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i - 1].vWorldViewPosition.y) * t + array_50AC10[i - 1].vWorldViewPosition.y; - array_507D30[depth_num_vertices].vWorldViewPosition.z = (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i - 1].vWorldViewPosition.z) * t + array_50AC10[i - 1].vWorldViewPosition.z; - array_507D30[depth_num_vertices].u = (array_50AC10[i].u - array_50AC10[i - 1].u) * t + array_50AC10[i - 1].u; - array_507D30[depth_num_vertices].v = (array_50AC10[i].v - array_50AC10[i - 1].v) * t + array_50AC10[i - 1].v; - } - else//предыдущая грань меньше границы видимости(текущая грань вышла за пределы видимости) + for (uint i = 0; i < uNumVertices; ++i)// есть ли пограничные вершины + { + if ( array_50AC10[i].vWorldViewPosition.x < pODMRenderParams->shading_dist_mist ) + { + bFound = true; + break; + } + } + if ( !bFound ) + return 0; + //check for far clip plane(проверка по дальней границе) + // + // v3.__________________. v0 + // | | + // | | + // | | + // ----------------------- 8192.0(far_clip - 0x2000) + // | | + // .__________________. + // v2 v1 + + for ( uint i = 0; i < uNumVertices; ++i ) + { + next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x >= pODMRenderParams->shading_dist_mist; + if ( current_vertices_flag ^ next_vertices_flag )//одна из граней за границей видимости + { + if ( next_vertices_flag )//следующая вершина больше границы видимости(настоящая вершина меньше границы видимости) - v3 + { + //t = far_clip - v2.x / v3.x - v2.x (формула получения точки пересечения отрезка с плоскостью) + t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x); + array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist; + //New_y = v2.y + (v3.y - v2.y)*t + array_507D30[depth_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t; + //New_z = v2.z + (v3.z - v2.z)*t + array_507D30[depth_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t; + array_507D30[depth_num_vertices].u = array_50AC10[i].u + (array_50AC10[i + 1].u - array_50AC10[i].u) * t; + array_507D30[depth_num_vertices].v = array_50AC10[i].v + (array_50AC10[i + 1].v - array_50AC10[i].v) * t; + array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist; + } + else//настоящая вершина больше границы видимости(следующая вершина меньше границы видимости) - v0 { //t = far_clip - v1.x / v0.x - v1.x - t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i - 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x); - array_507D30[depth_num_vertices].vWorldViewPosition.y = (array_50AC10[i - 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t + array_50AC10[i].vWorldViewPosition.y; - array_507D30[depth_num_vertices].vWorldViewPosition.z = (array_50AC10[i - 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t + array_50AC10[i].vWorldViewPosition.z; - array_507D30[depth_num_vertices].u = (array_50AC10[i - 1].u - array_50AC10[i].u) * t + array_50AC10[i].u; - array_507D30[depth_num_vertices].v = (array_50AC10[i - 1].v - array_50AC10[i].v) * t + array_50AC10[i].v; - } - array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist; - array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist; + t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x); + array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist; + //New_y = (v0.y - v1.y)*t + v1.y + array_507D30[depth_num_vertices].vWorldViewPosition.y = array_50AC10[i + 1].vWorldViewPosition.y + (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t; + //New_z = (v0.z - v1.z)*t + v1.z + array_507D30[depth_num_vertices].vWorldViewPosition.z = array_50AC10[i + 1].vWorldViewPosition.z + (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t; + array_507D30[depth_num_vertices].u = array_50AC10[i + 1].u + (array_50AC10[i].u - array_50AC10[i + 1].u) * t; + array_507D30[depth_num_vertices].v = array_50AC10[i + 1].v + (array_50AC10[i].v - array_50AC10[i + 1].v) * t; + array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist; + } ++depth_num_vertices; } - if ( current_vertices_flag )//оба в границе видимости - { - pNextVertices = depth_num_vertices++; - memcpy(&array_507D30[pNextVertices], &array_50AC10[i], 0x30); - //array_507D30[pNextVertices]._rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); - //array_507D30[pNextVertices].flt_2C = array_50AC10[i].flt_2C; - } - previous_vertices_flag = current_vertices_flag; - } - if ( depth_num_vertices < 3 ) - return 0; - return depth_num_vertices; + if ( !next_vertices_flag )//оба в границе видимости + { + memcpy(&array_507D30[depth_num_vertices], &array_50AC10[i + 1], sizeof(array_507D30[depth_num_vertices])); + depth_num_vertices++; + } + current_vertices_flag = next_vertices_flag; + } + for (uint i = 0; i < depth_num_vertices; ++i)// есть ли пограничные вершины + { + if ( array_507D30[i].vWorldViewPosition.x > pODMRenderParams->shading_dist_mist ) + { + __debugbreak(); + } + } + return depth_num_vertices >= 3 ? depth_num_vertices : 0; } //----- (0047840D) --------------------------------------------------------