void World::growSpiralTree (v3di_t position) { position.y++; block_t *pBlock = mWorldMap->getBlock (position); if (pBlock != NULL && pBlock->type != BLOCK_TYPE_AIR) { return; } int blockType = BLOCK_TYPE_ALIEN_SKIN3; v3d_t top; top.x = position.x; top.z = position.z; double bottom = getTerrainHeight (static_cast<int>(floor (top.x)), static_cast<int>(floor (top.z))) - 4.0; v3d_t pos; double percent; double angle; int numSteps = 50; double sphereRadiusStart = 1.5; double sphereRadiusEnd = 1.0; double sphereRadius; double radius = r_num (1.0, 2.0); double totalRotation = r_num (2.0, 4.0) * 1.5; double height = r_num (10.0, 20.0); top.y = bottom + height; BYTE uniqueLighting = LIGHT_LEVEL_MIN; //static_cast<GLfloat>(r_num (-0.3, 0.0)); for (int step = 0; step < numSteps; step++) { percent = static_cast<double> (step) / static_cast<double>(numSteps - 1); angle = percent * totalRotation; pos.x = top.x + radius * cos (angle); pos.y = lerp (bottom, top.y, percent); pos.z = top.z + radius * sin (angle); sphereRadius = lerp (sphereRadiusStart, sphereRadiusEnd, percent); mWorldMap->fillSphere (pos, sphereRadius, blockType, uniqueLighting); } }
void TerrainManager::setTerrainDecal(Ogre::ManualObject* decal, Ogre::Real x, Ogre::Real z, Ogre::Real rad) { Ogre::Real x1 = x - rad; Ogre::Real z1 = z - rad; int x_size = 4; // number of polygons int z_size = 4; Ogre::Real x_step = rad * 2/ x_size; Ogre::Real z_step = rad * 2/ z_size; decal->beginUpdate(0); // redefine vertices for (int i=0; i<=x_size; i++) { for (int j=0; j<=z_size; j++) { decal->position(Ogre::Vector3(x1, getTerrainHeight(x1, z1) + 1, z1)); decal->textureCoord((float)i / (float)x_size, (float)j / (float)z_size); z1 += z_step; } x1 += x_step; z1 = z - rad; } // redefine quads for (int i=0; i<x_size; i++) { for (int j=0; j<z_size; j++) { decal->quad( i * (x_size+1) + j, i * (x_size+1) + j + 1, (i + 1) * (x_size+1) + j + 1, (i + 1) * (x_size+1) + j); } } decal->end(); }
v3d_t World::getStartPosition(void) { if (mIsPlayerStartPosSet) { return mPlayerStartPos; } bool foundAcceptableStartingLocation = false; int numAttempts = 0; double limit = 100.0; v2d_t searchPos; searchPos.x = mPeriodics.mPrng.getNextDouble(-10000.0, 10000.0); searchPos.y = mPeriodics.mPrng.getNextDouble(-10000.0, 10000.0); v3d_t pos; while (!foundAcceptableStartingLocation) { pos.x = mPeriodics.mPrng.getNextDouble(-limit, limit) + searchPos.x; pos.z = mPeriodics.mPrng.getNextDouble(-limit, limit) + searchPos.y; pos.y = getTerrainHeight (static_cast<int>(pos.x), static_cast<int>(pos.z)) + 2.0; if (pos.y > 1.0 && pos.y < 20.0) break; if (numAttempts++ > 10000) break; limit += 4.0; } pos.y += 30.0; v3d_print ("player start position", pos); printf ("numAttempts: %d\n", numAttempts); mPlayerStartPos = pos; mIsPlayerStartPosSet = true; return pos; }
BYTE Periodics::generateBlockAtWorldPosition(v3di_t worldPosition) { int terrainHeight = getTerrainHeight(worldPosition.x, worldPosition.z); return generateBlockAtWorldPosition(worldPosition, terrainHeight); }
void initScene() { // load map.bin away::ByteArray mapBytes; readFileToByteArray("map.bin", &mapBytes); // parse map.bin MapBinParser parser; parser.parse(&mapBytes); // load heightmap away::ByteArray heightBytes; readFileToByteArray("heightmap.dat", &heightBytes); // load blend texture away::ByteArray* blendBytes = new away::ByteArray(); readFileToByteArray("blendmask.atf", blendBytes); away::ATFTexture* blendMap = new away::ATFTexture(blendBytes); // load surface textures std::vector<away::ATFTexture*> surfaceMaps; std::vector<SurfaceData>& surfaces = parser.getSurfaceData(); for (SurfaceData& surface : surfaces) { away::ByteArray* surfaceBytes = new away::ByteArray(); std::string diffuseMapPath = surface.m_diffuseMap + ".atf"; readFileToByteArray(diffuseMapPath.c_str(), surfaceBytes); surfaceMaps.push_back(new away::ATFTexture(surfaceBytes)); } // load lightmap textures std::vector<away::ATFTexture*> lightMaps; std::vector<LightMapData>& terrainLightMaps = parser.getTerrainLightMapData(); for (unsigned int i = 0; i < terrainLightMaps.size(); i++) { char name[16]; sprintf_s(name, 16, "terrain%d.atf", i); away::ByteArray* lightMapBytes = new away::ByteArray(); readFileToByteArray(name, lightMapBytes); lightMaps.push_back(new away::ATFTexture(lightMapBytes)); } // triangle indices unsigned short idx0, idx1; int sectorGrid = parser.getSectorGrid(); int blockGrid = parser.getBlockGrid(); float vertexSpace = parser.getVertexSpace(); float sectorSize = sectorGrid * vertexSpace; int numVertexPerRow = blockGrid + 1; unsigned short* indices = new unsigned short[blockGrid * blockGrid * 6]; for (int row = 0, i = 0; row < blockGrid; row++) { for (int col = 0; col < blockGrid; col++) { idx0 = numVertexPerRow * row + col; idx1 = idx0 + numVertexPerRow; indices[i++] = idx0; indices[i++] = idx1; indices[i++] = idx0 + 1; indices[i++] = idx0 + 1; indices[i++] = idx1; indices[i++] = idx1 + 1; } } // read walkgrid.dat and draw walkgrid to bitmap away::ByteArray walkGridBytes; readFileToByteArray("walkgrid.dat", &walkGridBytes); int gridSize = parser.getWalkGridSize(); int bmdSize = away::TextureUtils::getBestPowerOf2(gridSize); away::BitmapData* walkGridBmd = new away::BitmapData(bmdSize, bmdSize, false); int margin = (bmdSize - gridSize) / 2; for (int y = 0; y < gridSize; y++) { for (int x = 0; x < gridSize; x++) { if (walkGridBytes.readUnsignedByte() & 0x80) walkGridBmd->setPixel(x + margin, y + margin, 0xFF0000); else walkGridBmd->setPixel(x + margin, y + margin, 0x00FF00); } } away::TextureProjector* projector = new away::TextureProjector(new away::BitmapTexture(walkGridBmd, false, false), false); static_cast<away::OrthographicLens*>(projector->getLens())->setProjectionHeight(sectorSize * bmdSize / gridSize); method = new away::ProjectiveTextureMethod(projector, away::ProjectiveMode::MULTIPLY, false); // read walkmesh.dat and build WireframeTriangles away::ByteArray walkMeshBytes; readFileToByteArray("walkmesh.dat", &walkMeshBytes); away::Vector3D point; walkableMesh = new away::WireframeTriangles(0x0000FF); unsigned int numMeshes = walkMeshBytes.readUnsignedInt(); for (unsigned int i = 0; i < numMeshes; i++) { unsigned int numPoints = walkMeshBytes.readUnsignedInt() * 3; walkMeshBytes.setPosition(walkMeshBytes.getPosition() + 24); for (unsigned int j = 0; j < numPoints; j++) { point.m_x = walkMeshBytes.readFloat(); point.m_y = walkMeshBytes.readFloat(); point.m_z = walkMeshBytes.readFloat(); walkableMesh->addPoint(point); } } // build blocks int blockId = 0; int numBlockPerRow = sectorGrid / blockGrid; for (BlockData& blockData : parser.getBlockData()) { // build terrain std::vector<away::ATFTexture*> layerMaps; std::vector<float> layerTilings, distMaskStrengths; for (int index : blockData.m_surfaceIndents) { layerMaps.push_back(surfaceMaps[index]); layerTilings.push_back(surfaces[index].m_textureTiling); distMaskStrengths.push_back(surfaces[index].m_distMaskStrength); } BeastData& beastData = blockData.m_terrainBeast; int frameIndex = beastData.m_frameIndex; TerrainMesh* terrainMesh = new TerrainMesh(blockGrid, vertexSpace); terrainMesh->buildGeometry(heightBytes, sectorGrid, parser.getMinHeight(), parser.getMaxHeight(), indices, blockId); terrainMesh->buildMaterial(blendMap, layerMaps, layerTilings, distMaskStrengths, lightMaps[frameIndex], beastData, terrainLightMaps[frameIndex], numBlockPerRow, blockId++); scene->addChild(terrainMesh); terrainMeshes.push_back(terrainMesh); } // build blockGrid segmentSet = new away::SegmentSet(); float x, z, blockSize = blockGrid * vertexSpace, halfSectorSize = sectorSize * 0.5f; for (int i = 1; i < numBlockPerRow; i++) { x = i * blockSize - halfSectorSize; for (int j = 0; j < sectorGrid; j++) { z = j * vertexSpace - halfSectorSize; away::Vector3D start(x, getTerrainHeight(i, j / blockGrid, numBlockPerRow, x, z), z); z += vertexSpace; away::Vector3D end(x, getTerrainHeight(i, (j + 1) / blockGrid, numBlockPerRow, x, z), z); segmentSet->addSegment(new away::Segment(start, end, 0xffffff, 0xffffff)); } } for (int i = 1; i < numBlockPerRow; i++) { z = i * blockSize - halfSectorSize; for (int j = 0; j < sectorGrid; j++) { x = j * vertexSpace - halfSectorSize; away::Vector3D start(x, getTerrainHeight(j / blockGrid, i, numBlockPerRow, x, z), z); x += vertexSpace; away::Vector3D end(x, getTerrainHeight((j + 1) / blockGrid, i, numBlockPerRow, x, z), z); segmentSet->addSegment(new away::Segment(start, end, 0xffffff, 0xffffff)); } } scene->addChild(segmentSet); }