Ticket #21: 21.2.patch
File 21.2.patch, 7.6 KB (added by , 12 years ago) |
---|
-
binaries/data/mods/public/simulation/components/Foundation.js
119 119 this.buildMultiplier = Math.pow(this.numRecentBuilders, 0.7) / this.numRecentBuilders; 120 120 } 121 121 122 Foundation.prototype.FlattenBuildingArea = function() 123 { 124 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 125 var pos = cmpPosition.GetPosition(); 126 var rot = cmpPosition.GetRotation(); 127 128 var cmpFootprint = Engine.QueryInterface(this.entity, IID_Footprint); 129 var shape = cmpFootprint.GetShape(); 130 var width, depth = 0; 131 132 if (shape.type == "square") 133 { 134 width = shape.width; 135 depth = shape.depth; 136 } 137 else if (shape.type == "circle") 138 { 139 width = depth = shape.radius * 2; 140 } 141 142 var xm = pos.x + width / 2 * Math.sin(rot.y); 143 var zm = pos.z + depth / 2 * Math.sin(rot.y); 144 145 var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain); 146 var height = cmpTerrain.GetGroundLevel(xm, zm); 147 148 cmpTerrain.SetGroundLevelRegion(height, pos.x, pos.z, width, depth, rot.y); 149 } 150 122 151 /** 123 152 * Perform some number of seconds of construction work. 124 153 * Returns true if the construction is completed. … … 177 206 } 178 207 179 208 this.committed = true; 209 210 // Now that we're committed, flatten ground under foundation 211 this.FlattenBuildingArea(); 180 212 } 181 213 182 214 // Calculate the amount of progress that will be added (where 1.0 = completion) -
source/graphics/Terrain.cpp
423 423 // in handling triangulation properly 424 424 } 425 425 426 void CTerrain::SetExactGroundLevelFixed(fixed new_y, fixed x, fixed z) 427 { 428 // Clamp to size-2 so we can use the tiles (xi,zi)-(xi+1,zi+1) 429 const ssize_t xi = clamp((ssize_t)(x / (int)TERRAIN_TILE_SIZE).ToInt_RoundToZero(), (ssize_t)0, m_MapSize-2); 430 const ssize_t zi = clamp((ssize_t)(z / (int)TERRAIN_TILE_SIZE).ToInt_RoundToZero(), (ssize_t)0, m_MapSize-2); 431 432 m_Heightmap[zi*m_MapSize + xi] = new_y.ToInt_RoundToZero() / HEIGHT_SCALE; 433 m_Heightmap[(zi+1)*m_MapSize + xi] = new_y.ToInt_RoundToZero() / HEIGHT_SCALE; 434 m_Heightmap[zi*m_MapSize + (xi+1)] = new_y.ToInt_RoundToZero() / HEIGHT_SCALE; 435 m_Heightmap[(zi+1)*m_MapSize + (xi+1)] = new_y.ToInt_RoundToZero() / HEIGHT_SCALE; 436 } 437 426 438 bool CTerrain::GetTriangulationDir(ssize_t i, ssize_t j) const 427 439 { 428 440 // Clamp to size-2 so we can use the tiles (i,j)-(i+1,j+1) -
source/graphics/Terrain.h
85 85 fixed GetVertexGroundLevelFixed(ssize_t i, ssize_t j) const; 86 86 float GetExactGroundLevel(float x, float z) const; 87 87 fixed GetExactGroundLevelFixed(fixed x, fixed z) const; 88 void SetExactGroundLevelFixed(fixed new_y, fixed x, fixed z); 88 89 float GetFilteredGroundLevel(float x, float z, float radius) const; 89 90 90 91 // get the approximate slope (0 = horizontal, 0.5 = 30 degrees, 1.0 = 45 degrees, etc) -
source/simulation2/components/CCmpTerrain.cpp
25 25 #include "simulation2/MessageTypes.h" 26 26 27 27 #include "graphics/Terrain.h" 28 #include "graphics/RenderableObject.h" 28 29 29 30 class CCmpTerrain : public ICmpTerrain 30 31 { … … 79 80 return m_Terrain->GetExactGroundLevelFixed(x, z); 80 81 } 81 82 83 virtual void SetGroundLevelRegion(entity_pos_t new_y, entity_pos_t x, entity_pos_t z, fixed width, fixed depth, fixed y_rot) 84 { 85 // Initialize dirty region to the center of the given region (coordinates in tile space) 86 ssize_t xi = x.ToInt_RoundToZero(); 87 ssize_t zi = z.ToInt_RoundToZero(); 88 89 ssize_t x_min = xi, z_min = zi, x_max = xi + 1, z_max = zi + 1; 90 91 // Loop through every integral point in the region 92 // This treats the region as a grid of points with a cell size of 1 93 for(fixed i = fixed::FromInt(-1); i < width + fixed::FromInt(1); i += fixed::FromInt(1)) 94 { 95 for(fixed j = fixed::FromInt(-1); j < width + fixed::FromInt(1); j += fixed::FromInt(1)) 96 { 97 // Create a vector corresponding to the top left corner of the region 98 CFixedVector2D v(width / -2 + i, depth / -2 + j); 99 // Rotate that vector by the rotation of the region 100 v = v.Rotate(y_rot); 101 102 fixed height = new_y; 103 104 // Smooth elevation on surrounding tiles by averaging 105 if(i < fixed::FromInt(0) || i > width || j < fixed::FromInt(0) || j > depth) 106 { 107 fixed current_height = m_Terrain->GetExactGroundLevelFixed(v.X + x, v.Y + z); 108 height = (current_height + new_y) / 2; 109 } 110 111 m_Terrain->SetExactGroundLevelFixed(height, v.X + x, v.Y + z); 112 113 // Calculate if the current point lies outside known dirty region, converting to tile space 114 ssize_t x_low = (v.X + x).ToInt_RoundToZero() / TERRAIN_TILE_SIZE; 115 ssize_t x_high = (v.X + x).ToInt_RoundToInfinity() / TERRAIN_TILE_SIZE; 116 ssize_t z_low = (v.Y + z).ToInt_RoundToZero() / TERRAIN_TILE_SIZE; 117 ssize_t z_high = (v.Y + z).ToInt_RoundToInfinity() / TERRAIN_TILE_SIZE; 118 119 if(x_low < x_min) 120 { 121 x_min = x_low; 122 } 123 else if(x_high > x_max) 124 { 125 x_max = x_high; 126 } 127 128 if(z_low < z_min) 129 { 130 z_min = z_low; 131 } 132 else if(z_high > z_max) 133 { 134 z_max = z_high; 135 } 136 } 137 } 138 139 // Allow changes to be displayed 140 // As noted in Terrain.h, this needs to include adjacent tiles that blend in to this one 141 m_Terrain->MakeDirty(x_min - 1, z_min - 1, x_max + 2, z_max + 2, RENDERDATA_UPDATE_VERTICES); 142 143 // Alert any components that are interested that the terrain changes 144 CmpPtr<ICmpTerrain> cmpTerrain(GetSimContext(), SYSTEM_ENTITY); 145 if (cmpTerrain) 146 cmpTerrain->MakeDirty(x_min, z_min, x_max, z_max); 147 148 } 149 82 150 virtual float GetExactGroundLevel(float x, float z) 83 151 { 84 152 return m_Terrain->GetExactGroundLevel(x, z); -
source/simulation2/components/ICmpTerrain.cpp
23 23 24 24 BEGIN_INTERFACE_WRAPPER(Terrain) 25 25 DEFINE_INTERFACE_METHOD_2("GetGroundLevel", entity_pos_t, ICmpTerrain, GetGroundLevel, entity_pos_t, entity_pos_t) 26 DEFINE_INTERFACE_METHOD_6("SetGroundLevelRegion", void, ICmpTerrain, SetGroundLevelRegion, entity_pos_t, entity_pos_t, entity_pos_t, fixed, fixed, fixed) 26 27 DEFINE_INTERFACE_METHOD_2("CalcNormal", CFixedVector3D, ICmpTerrain, CalcNormal, entity_pos_t, entity_pos_t) 27 28 END_INTERFACE_WRAPPER(Terrain) -
source/simulation2/components/ICmpTerrain.h
35 35 36 36 virtual entity_pos_t GetGroundLevel(entity_pos_t x, entity_pos_t z) = 0; 37 37 38 virtual void SetGroundLevelRegion(entity_pos_t new_y, entity_pos_t x, entity_pos_t z, fixed width, fixed depth, fixed y_rot) = 0; 39 38 40 virtual float GetExactGroundLevel(float x, float z) = 0; 39 41 40 42 /**