Advertisement
Guest User

MapAndreas.cpp - therainycat edit.

a guest
May 3rd, 2014
389
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.38 KB | None | 0 0
  1. //----------------------------------------------------------
  2. //
  3. //   SA-MP Multiplayer Modification For GTA:SA
  4. //   Copyright 2004-2010 SA-MP Team
  5. //
  6. //   Author: Kye 10 Jan 2010
  7. //
  8. //----------------------------------------------------------
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13.  
  14. #include "MapAndreas.h"
  15.  
  16. //----------------------------------------------------------
  17.  
  18. CMapAndreas::CMapAndreas()
  19. {
  20.     m_iOperatingMode = MAP_ANDREAS_MODE_NONE;
  21.     m_pPointData = NULL;
  22. }
  23.  
  24. //----------------------------------------------------------
  25.  
  26. CMapAndreas::~CMapAndreas()
  27. {
  28.     m_iOperatingMode = MAP_ANDREAS_MODE_NONE;
  29.     if(m_pPointData) free(m_pPointData);
  30.     m_pPointData = NULL;
  31. }
  32.  
  33. //----------------------------------------------------------
  34.  
  35. int CMapAndreas::Init(int iMode)
  36. {
  37.     // check if already inited
  38.     if(m_iOperatingMode != MAP_ANDREAS_MODE_NONE)
  39.         return MAP_ANDREAS_ERROR_SUCCESS;
  40.  
  41.     if(iMode == MAP_ANDREAS_MODE_FULL)
  42.     {
  43.         // allocate the memory we need
  44.         m_pPointData = (unsigned short *)calloc(MAP_ANDREAS_POINTS_FULL,sizeof(unsigned short));
  45.         if(NULL == m_pPointData) return MAP_ANDREAS_ERROR_MEMORY;
  46.  
  47.         // load the file contents in to our point data buffer
  48.         FILE *fileInput = fopen(MAP_ANDREAS_HMAP_FILE_FULL,"rb");
  49.         if(NULL == fileInput) return MAP_ANDREAS_ERROR_DATA_FILES;
  50.        
  51.         /**
  52.         *   Старая версия (грузит пару секунд
  53.         *
  54.  
  55.         for(int x=0;x<MAP_ANDREAS_POINTS_FULL;x++) {
  56.             fread(&m_pPointData[x],1,sizeof(unsigned short),fileInput);
  57.         }
  58.         */
  59.         // Новая версия - грузит меньше чем за секунду
  60.         unsigned short points_line[6000];
  61.         for(int x=0;x<MAP_ANDREAS_POINTS_FULL/6000;x++) {
  62.             fread(&points_line,6000,sizeof(unsigned short),fileInput);
  63.             for(int k=0; k<6000; k++){
  64.                 m_pPointData[x*6000+k] = points_line[k];
  65.             }
  66.         }
  67.         fclose(fileInput);
  68.  
  69.         m_iOperatingMode = MAP_ANDREAS_MODE_FULL;
  70.         m_gridSize = MAP_ANDREAS_GRID_FULL;
  71.         return MAP_ANDREAS_ERROR_SUCCESS;
  72.     } else
  73.  
  74.     if(iMode == MAP_ANDREAS_MODE_MINIMAL)
  75.     {
  76.         m_pPointData = (unsigned short *)calloc(MAP_ANDREAS_POINTS_MINIMAL,sizeof(unsigned short));
  77.         if(NULL == m_pPointData) return MAP_ANDREAS_ERROR_MEMORY;
  78.    
  79.         FILE *fileInput = fopen(MAP_ANDREAS_HMAP_FILE_MINIMAL,"rb");
  80.         if(NULL == fileInput) return MAP_ANDREAS_ERROR_DATA_FILES;
  81.        
  82.         for(int x=0;x<MAP_ANDREAS_POINTS_MINIMAL;x++) {
  83.             fread(&m_pPointData[x],1,sizeof(unsigned short),fileInput);
  84.         }
  85.  
  86.         fclose(fileInput);
  87.  
  88.         m_iOperatingMode = MAP_ANDREAS_MODE_MINIMAL;
  89.         m_gridSize = MAP_ANDREAS_GRID_MINIMAL;
  90.         return MAP_ANDREAS_ERROR_SUCCESS;
  91.     } else
  92.  
  93.     if(iMode == MAP_ANDREAS_MODE_NOBUFFER)
  94.     {
  95.         m_iOperatingMode = MAP_ANDREAS_MODE_NOBUFFER;
  96.         m_gridSize = MAP_ANDREAS_GRID_FULL;
  97.         m_pPointData = (unsigned short *)calloc(1,sizeof(unsigned short));
  98.         mapFile = fopen(MAP_ANDREAS_HMAP_FILE_FULL,"rb");
  99.         if(NULL == mapFile) return MAP_ANDREAS_ERROR_DATA_FILES;
  100.         return MAP_ANDREAS_ERROR_SUCCESS;
  101.     }
  102.    
  103.     return MAP_ANDREAS_ERROR_FAILURE;
  104. }
  105.  
  106. //----------------------------------------------------------
  107.  
  108. float CMapAndreas::FindZ_For2DCoord(float X, float Y)
  109. {
  110.     // check for a co-ord outside the map
  111.     if(X < -2999.0f || X > 2999.0f || Y > 2999.0f || Y < -2999.0f) return 0.0f;
  112.  
  113.     // get row/col on 6000x6000 grid
  114.     int iGridX = ((int)X) + 3000;
  115.     int iGridY = (((int)Y) - 3000) * -1;
  116.     int iDataPos;
  117.    
  118.     if(m_iOperatingMode == MAP_ANDREAS_MODE_FULL)
  119.     {
  120.         iDataPos = (iGridY * 6000) + iGridX; // for every Y, increment by the number of cols, add the col index.
  121.         return (float)m_pPointData[iDataPos] / 100.0f; // the data is a float stored as ushort * 100
  122.     } else
  123.  
  124.     if(m_iOperatingMode == MAP_ANDREAS_MODE_MINIMAL)
  125.     {      
  126.         iDataPos = ((iGridY / 3) * 2000) + iGridX / 3;  // skip every 2nd and 3rd line
  127.         return (float)m_pPointData[iDataPos] / 100.0f;
  128.     } else
  129.  
  130.     if(m_iOperatingMode == MAP_ANDREAS_MODE_NOBUFFER)
  131.     {      
  132.         iDataPos = (iGridY * 6000) + iGridX;           
  133.        
  134.         // Jump to the position in the file and read it
  135.         fseek(mapFile, iDataPos * sizeof(unsigned short), SEEK_SET);
  136.         fread(&m_pPointData[0], 1, sizeof(unsigned short), mapFile);
  137.  
  138.         return (float)m_pPointData[0] / 100.0f;
  139.     }
  140.  
  141.     return 0.0f;
  142. }
  143.  
  144. float CMapAndreas::GetAverageZ(float x, float y)
  145. {
  146.     int whole[2];
  147.     whole[0] = (int)floor(x);
  148.     whole[1] = (int)floor(y);
  149.    
  150.     bool triangle;
  151.     if((x - (float)whole[0]) + (y - (float)whole[1]) < 1.0){
  152.         triangle = false;
  153.     }else{
  154.         triangle = true;
  155.     }
  156.    
  157.     float floor_x = (float)whole[0];
  158.     float floor_y = (float)whole[1];
  159.     float ceil_x = floor_x + 1.0f;
  160.     float ceil_y = floor_y + 1.0f;
  161.     float height[3];
  162.        
  163.     float _x1, _y1, _z1, _x2, _y2, _z2, _x3, _y3, _z3;
  164.        
  165.     if(triangle == false){
  166.     // 0
  167.     // 1 2
  168.         //FCNPC_GetZGround(floor_x, ceil_y, height[0]);
  169.         height[0] = FindZ_For2DCoord(floor_x, ceil_y);
  170.         //FCNPC_GetZGround(floor_x, floor_y, height[1]);
  171.         height[1] = FindZ_For2DCoord(floor_x, floor_y);
  172.         //FCNPC_GetZGround(ceil_x, floor_y, height[2]);
  173.         height[2] = FindZ_For2DCoord(ceil_x, floor_y);
  174.  
  175.         _x1 = floor_x;
  176.         _y1 = ceil_y;
  177.         _z1 = height[0];
  178.        
  179.         _x2 = floor_x;
  180.         _y2 = floor_y;
  181.         _z2 = height[1];
  182.        
  183.         _x3 = ceil_x;
  184.         _y3 = floor_y;
  185.         _z3 = height[2];
  186.     }else{
  187.     // 0 1
  188.     //   2
  189.         //FCNPC_GetZGround(floor_x, ceil_y, height[0]);
  190.         height[0] = FindZ_For2DCoord((float)floor_x, (float)ceil_y);
  191.         //FCNPC_GetZGround(ceil_x, ceil_y, height[1]);
  192.         height[1] = FindZ_For2DCoord((float)ceil_x, (float)ceil_y);
  193.         //FCNPC_GetZGround(ceil_x, floor_y, height[2]);
  194.         height[2] = FindZ_For2DCoord((float)ceil_x, (float)floor_y);
  195.  
  196.         _x1 = floor_x;
  197.         _y1 = ceil_y;
  198.         _z1 = height[0];
  199.        
  200.         _x2 = ceil_x;
  201.         _y2 = ceil_y;
  202.         _z2 = height[1];
  203.        
  204.         _x3 = ceil_x;
  205.         _y3 = floor_y;
  206.         _z3 = height[2];
  207.     }
  208.     //вершины полигона:
  209.     //_x1=argument0 _y1=argument1 _z1=argument2
  210.     //_x2=argument3 _y2=argument4 _z2=argument5
  211.     //_x3=argument6 _y3=argument7 _z3=argument8
  212.     //x и y точки, для которой нужно найти z:
  213.  
  214.     //Уравнение плоскости - A*x+B*y+C*z+D=0
  215.     //где A, B, C - нормаль к поверхности.
  216.     //у меня вместо переменных A, B и C будут nx, ny и nz
  217.     //D - положение плосктости относительно начала координат.
  218.     //Из этой формулы выражаем z,
  219.     //получается: z=-(A*x+B*Y+D)/C
  220.  
  221.     //Вычисляем нормаль к плоскости полигона  
  222.     //и записываем координаты этого вектора в переменные nx, ny, nz.
  223.     float nx = (_z1-_z2)*(_y3-_y2)-(_y1-_y2)*(_z3-_z2);
  224.     float ny = (_x1-_x2)*(_z3-_z2)-(_z1-_z2)*(_x3-_x2);
  225.     float nz = (_y1-_y2)*(_x3-_x2)-(_x1-_x2)*(_y3-_y2);
  226.     float normlength = sqrt((nx * nx)+(ny * ny)+(nz * nz));
  227.     nx /= normlength;
  228.     ny /= normlength;
  229.     nz /= normlength;
  230.  
  231.     float D = -(_x1*nx+_y1*ny+_z1*nz); //Находим положение плосктости относительно начала координат по этой формуле.
  232.     return -(nx*x+ny*y+D)/nz; //вычисляем z по формуле
  233. }
  234.  
  235. bool CMapAndreas::Unload()
  236. {
  237.     // Close the file if neccessary
  238.     if (mapFile != NULL)
  239.     {
  240.         fclose(mapFile);
  241.     }
  242.     // Free the used memory
  243.     free(m_pPointData);
  244.     //m_pPointData = NULL;
  245.     m_iOperatingMode = MAP_ANDREAS_MODE_NONE;
  246.     return true;
  247. }
  248.  
  249. //----------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement