Exemple #1
0
void Bits::set_value(Spot p, int val) {
	numbers[idx_of_spot(p)] = val;
	int boxid = boxid_of_spot(p);
	for(int i=0; i < 9; i++) {
		remove_candidate(Spot(p.row, i), val);
		remove_candidate(Spot(i, p.col), val);
		remove_candidate(spot_of_boxid(boxid, i), val);
	}
	bits[idx_of_spot(p)] = (1 << (val - 1));
}
Exemple #2
0
// Create a cat, set its age, have it
// meow, tell us its age, then meow again.
int main()
{
    Cat Frisky(5);
    Frisky.Meow();
    std::cout << "Frisky is a cat who is " ;
    std::cout << Frisky.GetAge() << " years old.\n";
    Frisky.Meow();
    Frisky.SetAge(7);
    std::cout << "Now Frisky is " ;
    std::cout << Frisky.GetAge() << " years old.\n";
    //system("PAUSE");
   // return 0;
   
   Cat Spot(5);
   Spot.Meow();
   std::cout << "Spot is a cat who is ";
   std::cout << Spot.GetAge() << " years old.\n";
   Spot.Meow();
   Spot.SetAge(7);
   std::cout << "Now Spot is " ;
   std::cout << Spot.GetAge() << " years old.\n";
   system("PAUSE");
   return 0;
   
}
Exemple #3
0
int Bits::open_bit_of_col(int col) {
	int ret = 0;
	for(int i=0; i < 9; i++) {
		Spot p = Spot(i, col);
		if(has_value(p)) { continue; }
		ret |= bits[idx_of_spot(p)];
	}
	return ret;
}
Exemple #4
0
int Bits::open_bit_of_row(int row) {
	int ret = 0;
	for(int i=0; i < 9; i++) {
		Spot p = Spot(row, i);
		if(has_value(p)) { continue; }
		ret |= bits[idx_of_spot(p)];
	}
	return ret;
}
Exemple #5
0
std::vector<Spot> Bits::covers_of_spot(Spot p, int val) {
	std::vector<Spot> ret;
	int boxid = boxid_of_spot(p);
	for(int i=0; i < 9; i++) {
		Spot boxspot = spot_of_boxid(boxid, i);
		Spot rowspot = Spot(p.row, i);
		Spot colspot = Spot(i, p.col);
		// box
		if( get_value(boxspot) == val ) {
			ret.push_back(boxspot);
		}
		if( boxid_of_spot(rowspot) != boxid ) {
			if( get_value(rowspot) == val ) {
				ret.push_back(rowspot);
			}
		}
		if( boxid_of_spot(colspot) != boxid ) {
			if( get_value(colspot) == val ) {
				ret.push_back(colspot);
			}
		}
	}
	return ret;
}
std::ostream& operator << (std::ostream& os, Grid& grid) {
    for(int i=0; i < 9; i++) {
        for(int j=0; j < 9; j++) {
            int spot = grid.get(Spot(i,j));
            if(spot == 0) {
                os << ".";
            } else {
                os << spot;
            }
        }
        //os << std::endl;
    }
    os << std::endl;
    return os;
}
Exemple #7
0
std::ostream& operator << (std::ostream& os, Bits& bits) {
	for(int i=0; i < 9; i++) {
		for(int j=0; j < 9; j++) {
			int spot = bits.get_value(Spot(i,j));
			if(spot == 0) {
				os << ".";
			} else if(spot > 0 && spot <= 9) {
				os << spot;
			} else {
				os << "?";
			}
		}
	}
	os << std::endl;
	return os;
}
void ControllerManager::setup(Vec2f size, Vec2f single)
{
    int id = 0;
    for (int y = 0; y < size.y; y += size.y/4) {
        for (int x = 0; x < size.x; x += size.x/6) {
            mSpots.push_back(Spot(Vec2f(x,y),single,id));
            id++;
        }
    }
    
    mSpots.erase(mSpots.end()-1);
    mSpots.erase(mSpots.end()-1);
    console() << "Spots: " << mSpots.size() << endl;
    for(Spot s : mSpots){
        console() << s.getId() << endl;
        s.setup();
    }
}
Exemple #9
0
std::vector<YWing> find_ywings(Bits* bits) {
	std::vector<YWing> ret;

	std::vector<Spot> double_spots; // spots with only two candidates
	for(int i=0; i < 9; i++) {
		for(int j=0; j < 9; j++) {
			Spot p = Spot(i, j);
			if(bits->count_candidates(p) == 2) {
				double_spots.push_back(p);
			}
		}
	}

	for(int i=0; i < double_spots.size(); i++){
		ywing_process_hinge(bits, double_spots[i], &double_spots, &ret);
	}
	return ret;
}
Exemple #10
0
bool Bits::valid_now() {
	// rows
	for(int i=0; i < 9; i++) {
		std::vector<bool> exist;
		for(int j=0; j < 9; j++) {
			exist.push_back(false);
		}
		for(int j=0; j < 9; j++) {
			Spot p = Spot(i, j);
			if(has_value(p)) {
				int val = get_value(p);
				if(exist[val] == false) {
					exist[val] == true;
				} else {
					return false;
				}
			}
		}
	}
	
	// cols
	for(int i=0; i < 9; i++) {
		std::vector<bool> exist;
		for(int j=0; j < 9; j++) {
			exist.push_back(false);
		}
		for(int j=0; j < 9; j++) {
			Spot p = Spot(j, i);
			if(has_value(p)) {
				int val = get_value(p);
				if(exist[val] == false) {
					exist[val] == true;
				} else {
					return false;
				}
			}
		}
	}
	
	// boxes
	for(int i=0; i < 9; i++) {
		std::vector<bool> exist;
		for(int j=0; j < 9; j++) {
			exist.push_back(false);
		}
		for(int j=0; j < 9; j++) {
			Spot p = spot_of_boxid(i, j);
			if(has_value(p)) {
				int val = get_value(p);
				if(exist[val] == false) {
					exist[val] == true;
				} else {
					return false;
				}
			}
		}
	}
	
	
	return true;
}
Exemple #11
0
void LPOut::highlight_col(int col, float r, float g, float b) {
	highlighted_cols.push_back(Out_Highlight(Spot(0,0), col, r, g, b));
}
Exemple #12
0
void DigitChain::scan_false_color() {
	//rows
	for(int i=0; i < 9; i++) {
		int count_white = 0;
		int count_black = 0;
		for(int j=0; j < 9; j++) {
			int idx = idx_of_digit_vertex(verts, Spot(i, j));
			if(idx == -1) { continue; }
			if(verts[idx].color == DC_BLACK) {
				count_black++;
			} else if(verts[idx].color == DC_WHITE) {
				count_white++;
			}
		}
		if(count_black > 1) {
			black = false;
		}
		if(count_white > 1) {
			white = false;
		}
	}
	
	//cols
	for(int i=0; i < 9; i++) {
		int count_white = 0;
		int count_black = 0;
		for(int j=0; j < 9; j++) {
			int idx = idx_of_digit_vertex(verts, Spot(j, i));
			if(idx == -1) { continue; }
			if(verts[idx].color == DC_BLACK) {
				count_black++;
			} else if(verts[idx].color == DC_WHITE) {
				count_white++;
			}
		}
		if(count_black > 1) {
			black = false;
		}
		if(count_white > 1) {
			white = false;
		}
	}
	
	//boxes
	for(int i=0; i < 9; i++) {
		int count_white = 0;
		int count_black = 0;
		for(int j=0; j < 9; j++) {
			int idx = idx_of_digit_vertex(verts, spot_of_boxid(i, j));
			if(idx == -1) { continue; }
			if(verts[idx].color == DC_BLACK) {
				count_black++;
			} else if(verts[idx].color == DC_WHITE) {
				count_white++;
			}
		}
		if(count_black > 1) {
			black = false;
		}
		if(count_white > 1) {
			white = false;
		}
	}
}
Exemple #13
0
DigitVertex::DigitVertex() {
	spot = Spot();
	color = 0;
	peers = std::vector<int>();
	links = std::vector<StrongLink>();
}
Exemple #14
0
std::vector<BoxLine> find_boxlines(Bits* bits) {
	std::vector<BoxLine> ret;
	for(int i = 0; i < 9; i++) {
		// for box i
		std::vector<Spot> boxspots = spots_of_box(i);
		int boxrow = boxspots[0].row;
		int boxcol = boxspots[0].col;
		
		// check rows
		for(int j=0; j < 3; j++) {
			// row is absolute row
			int row = boxrow + j;
			std::vector<Spot> others;
			std::vector<Spot> spots;
			std::vector<Spot> empty_spots;
			std::vector<Spot> complements;
			
			// classify all necessary spots
			for(int k=0; k < 9; k++) {
				Spot boxspot = spot_of_boxid(i, k);
				Spot rowspot = Spot(row, k);
				if(boxid_of_spot(rowspot) != i) {
					others.push_back(rowspot);
				}
				if(boxspot.row == row) {
					spots.push_back(boxspot);
					if(!bits->has_value(boxspot)) {
						empty_spots.push_back(boxspot);
					}
				} else {
					if(!bits->has_value(boxspot)) {
						complements.push_back(boxspot);
					}
				}
			}
			
			int emptybits = bits->bit_of_spots(empty_spots);
			int otherbits = bits->bit_of_spots(others);
			int compbits = bits->bit_of_spots(complements);
			
			int boxedbits = bit_subtract_int(emptybits, otherbits);
			if(boxedbits == 0) { continue; }
			// we have aligned
			int targetbits = boxedbits & compbits;
			if(targetbits == 0) { continue; }
			// and will remove candidates
			
			std::vector<int> vals = vals_of_int(targetbits);
			
			// identify targets
			std::vector<Target> targets;
			for(int k=0; k < complements.size(); k++) {
				Spot comp = complements[k];
				std::vector<int> candidates;
				for(int m=0; m < vals.size(); m++) {
					int mbit = vals[m];
					if(bits->has_candidate(comp, mbit)) {
						candidates.push_back(mbit);
					}
				}
				if(candidates.size() > 0) {
					targets.push_back(Target(comp, candidates, 0));
				}
			}
			
			// identify subset
			std::vector<Spot> subset;
			for(int k=0; k < empty_spots.size(); k++) {
				bool part = false;
				for(int m=0; m < vals.size(); m++) {
					int mbit = vals[m];
					if(bits->has_candidate(empty_spots[k], mbit)) {
						part = true;
					}
				}
				if(part) {
					subset.push_back(empty_spots[k]);
				}
			}
			
			// identify keys
			// OLD NOTE: mostly copied from pointing.cpp
			
			KeyRank keyrank;
			for(int k=0; k < others.size(); k++) {
				Spot spot = others[k];
				for(int m=0; m < vals.size(); m++) {
					int mbit = vals[m];
					keyrank.add_possible_covers(bits, spot, mbit);
				}
			}
			ret.push_back(BoxLine(targets, keyrank.keys, subset, vals, BOXLINE_ROW));
		}
		
		// check cols
		for(int j=0; j < 3; j++) {
			// col is absolute col
			int col = boxcol + j;
			std::vector<Spot> others;
			std::vector<Spot> spots;
			std::vector<Spot> empty_spots;
			std::vector<Spot> complements;
			
			// classify all necessary spots
			for(int k=0; k < 9; k++) {
				Spot boxspot = spot_of_boxid(i, k);
				Spot rowspot = Spot(k, col);
				if(boxid_of_spot(rowspot) != i) {
					others.push_back(rowspot);
				}
				if(boxspot.col == col) {
					spots.push_back(boxspot);
					if(!bits->has_value(boxspot)) {
						empty_spots.push_back(boxspot);
					}
				} else {
					if(!bits->has_value(boxspot)) {
						complements.push_back(boxspot);
					}
				}
			}
			
			int emptybits = bits->bit_of_spots(empty_spots);
			int otherbits = bits->bit_of_spots(others);
			int compbits = bits->bit_of_spots(complements);
			
			int boxedbits = bit_subtract_int(emptybits, otherbits);
			if(boxedbits == 0) { continue; }
			// we have aligned
			int targetbits = boxedbits & compbits;
			if(targetbits == 0) { continue; }
			// and will remove candidates
			
			std::vector<int> vals = vals_of_int(targetbits);
			
			// identify targets
			std::vector<Target> targets;
			for(int k=0; k < complements.size(); k++) {
				Spot comp = complements[k];
				std::vector<int> candidates;
				for(int m=0; m < vals.size(); m++) {
					int mbit = vals[m];
					if(bits->has_candidate(comp, mbit)) {
						candidates.push_back(mbit);
					}
				}
				if(candidates.size() > 0) {
					targets.push_back(Target(comp, candidates, 0));
				}
			}
			
			// identify subset
			std::vector<Spot> subset;
			for(int k=0; k < empty_spots.size(); k++) {
				bool part = false;
				for(int m=0; m < vals.size(); m++) {
					int mbit = vals[m];
					if(bits->has_candidate(empty_spots[k], mbit)) {
						part = true;
					}
				}
				if(part) {
					subset.push_back(empty_spots[k]);
				}
			}
			
			// identify keys
			// OLD NOTE: mostly copied from pointing.cpp
			
			KeyRank keyrank;
			for(int k=0; k < others.size(); k++) {
				Spot spot = others[k];
				for(int m=0; m < vals.size(); m++) {
					int mbit = vals[m];
					keyrank.add_possible_covers(bits, spot, mbit);
				}
			}
			ret.push_back(BoxLine(targets, keyrank.keys, subset, vals, BOXLINE_COL));
		}
	}
	return ret;
}
Exemple #15
0
void ywing_process_hinge(Bits* bits, Spot hinge, std::vector<Spot>* double_spots, std::vector<YWing>* ret) {
	int hinge_bits = bits->bit_of_spot(hinge);

	for(int i=0; i < double_spots->size(); i++) {
		Spot wing1 = (*double_spots)[i];
		int wing1_bits = bits->bit_of_spot(wing1);

		// only consider wings that aren't the hinge, but are visible to the hinge, and have exactly 1 candidate in common with the hinge
		if(spot_equal(wing1,hinge) || !spot_visible(wing1,hinge) || count_bits(hinge_bits & wing1_bits) != 1 ) {
			continue;
		}

		for(int j=i+1; j < double_spots->size(); j++) {
			Spot wing2 = (*double_spots)[j];
			int wing2_bits = bits->bit_of_spot(wing2);

			// only consider wings that aren't the hinge, but are visible to the hinge, and have exactly 1 candidate in common with the hinge and the other wing
			if(spot_equal(wing2,hinge) || !spot_visible(wing2,hinge) || count_bits(hinge_bits & wing2_bits) != 1 || count_bits(wing1_bits & wing2_bits) != 1 || count_bits(hinge_bits & wing1_bits & wing2_bits) != 0) {
				continue;
			}

			// now we have two unique wings that can see the hinge, and each has only one candidate shared between each other

			// the candidate we can exclude is the shared candidate between the two wings
			int shared_candidate = first_bits(wing1_bits & wing2_bits);

			// determine all spots that are visible to both wing1 and wing2 (same row, column, or box)
			std::vector<Spot> shared_spots;
			for(int ia=0; ia < 9; ia++) {
				for(int ib=0; ib < 9; ib++) {
					Spot p = Spot(ia,ib);

					// exclude the hinge and wing spots
					if(spot_equal(p,hinge) || spot_equal(p,wing1) || spot_equal(p,wing2)) { continue; }

					if((p.row == wing1.row || p.col == wing1.col || boxid_of_spot(p) == boxid_of_spot(wing1)) && (p.row == wing2.row || p.col == wing2.col || boxid_of_spot(p) == boxid_of_spot(wing2))) {
						shared_spots.push_back(p);
					}
				}
			}

			// NOTE: potentially more-efficient version commented out, didn't figure out the best way to make this compile.
			// if(wing1.row == wing2.row) {
			// 	shared_spots = spots_union(shared_spots,spots_of_row(wing1.row));
			// }
			// if(wing1.col == wing2.col) {
			// 	shared_spots = spots_union(shared_spots,spots_of_col(wing1.col));
			// }
			// if(boxid_of_spot(wing1) == boxid_of_spot(wing2)) {
			// 	shared_spots = spots_union(shared_spots,spots_of_box(boxid_of_spot(wing1)));
			// }
			// remove any excluded spots (hinge,wings) from our list
			// std::vector<Spot> excluded_spots;
			// excluded_spots.push_back(hinge);
			// excluded_spots.push_back(wing1);
			// excluded_spots.push_back(wing2);
			// shared_spots = spots_subtract(shared_spots,excluded_spots);

			// candidate array (if necessary)
			std::vector<int> candidates;
			candidates.push_back(shared_candidate);

			std::vector<Target> targets;
			for(int k=0; k < shared_spots.size(); k++) {
				Spot target_spot = shared_spots[k];
				if(bits->has_candidate(target_spot,shared_candidate) && bits->count_candidates(target_spot) > 1) {
					targets.push_back(Target(target_spot, candidates, 0));
				}
			}
			if(targets.size() > 0) {
				KeyRank keyrank;
				std::vector<Spot> wings;
				wings.push_back(wing1);
				wings.push_back(wing2);
				ret->push_back(YWing(targets, keyrank.keys, hinge, wings));
			}
		}
	}
}
Exemple #16
0
void LPOut::highlight_row(int row, float r, float g, float b) {
	highlighted_rows.push_back(Out_Highlight(Spot(0,0), row, r, g, b));
}
Exemple #17
0
    bool TileBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion)
    {
        char mapFileName[255];
        sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX);

        FILE* mapFile = fopen(mapFileName, "rb");
        if(!mapFile)
            return true;

        GridMapFileHeader fheader;
        fread(&fheader, sizeof(GridMapFileHeader), 1, mapFile);

        if(fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC)))
        {
            fclose(mapFile);
            printf("%s is the wrong version, please extract new .map files\n", mapFileName);
            return false;
        }

        GridMapHeightHeader hheader;
        fseek(mapFile, fheader.heightMapOffset, SEEK_SET);
        fread(&hheader, sizeof(GridMapHeightHeader), 1, mapFile);

        bool haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT);
        bool haveLiquid = fheader.liquidMapOffset && !m_skipLiquid;

        // no data in this map file
        if(!haveTerrain && !haveLiquid)
        {
            fclose(mapFile);
            return true;
        }

        // data used later
        uint16 holes[16][16];
        uint8* liquid_type = 0;
        G3D::Array<int> ltriangles;
        G3D::Array<int> ttriangles;

        // terrain data
        if(haveTerrain)
        {
            int i;
            float heightMultiplier;
            float V9[V9_SIZE_SQ], V8[V8_SIZE_SQ];

            if(hheader.flags & MAP_HEIGHT_AS_INT8)
            {
                uint8 v9[V9_SIZE_SQ];
                uint8 v8[V8_SIZE_SQ];
                fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile);
                fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile);
                heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255;

                for(i = 0; i < V9_SIZE_SQ; ++i)
                    V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight;

                if(m_hiResHeightMaps)
                    for(i = 0; i < V8_SIZE_SQ; ++i)
                        V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight;
            }
            else if(hheader.flags & MAP_HEIGHT_AS_INT16)
            {
                uint16 v9[V9_SIZE_SQ];
                uint16 v8[V8_SIZE_SQ];
                fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile);
                fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile);
                heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535;

                for(i = 0; i < V9_SIZE_SQ; ++i)
                    V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight;

                if(m_hiResHeightMaps)
                    for(i = 0; i < V8_SIZE_SQ; ++i)
                        V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight;
            }
            else
            {
                fread(V9, sizeof(float), V9_SIZE_SQ, mapFile);
                if(m_hiResHeightMaps)
                    fread(V8, sizeof(float), V8_SIZE_SQ, mapFile);
            }

            // hole data
            memset(holes, 0, fheader.holesSize);
            fseek(mapFile, fheader.holesOffset, SEEK_SET);
            fread(holes, fheader.holesSize, 1, mapFile);

            int count = meshData.solidVerts.size() / 3;
            float xoffset = (float(tileX)-32)*GRID_SIZE;
            float yoffset = (float(tileY)-32)*GRID_SIZE;

            float coord[3];

            for(i = 0; i < V9_SIZE_SQ; ++i)
            {
                getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9);
                meshData.solidVerts.append(coord[0]);
                meshData.solidVerts.append(coord[2]);
                meshData.solidVerts.append(coord[1]);
            }

            if(m_hiResHeightMaps)
                for(i = 0; i < V8_SIZE_SQ; ++i)
                {
                    getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8);
                    meshData.solidVerts.append(coord[0]);
                    meshData.solidVerts.append(coord[2]);
                    meshData.solidVerts.append(coord[1]);
                }

            int triInc, j, indices[3], loopStart, loopEnd, loopInc;
            getLoopVars(portion, loopStart, loopEnd, loopInc);

            triInc = m_hiResHeightMaps ? 1 : BOTTOM-TOP;

            for(i = loopStart; i < loopEnd; i+=loopInc)
                    for(j = TOP; j <= BOTTOM; j+=triInc)
                    {
                        getHeightTriangle(i, Spot(j), indices);
                        ttriangles.append(indices[2] + count);
                        ttriangles.append(indices[1] + count);
                        ttriangles.append(indices[0] + count);
                    }
        }

        // liquid data
        if(haveLiquid)
        {
            do
            {
                GridMapLiquidHeader lheader;
                fseek(mapFile, fheader.liquidMapOffset, SEEK_SET);
                fread(&lheader, sizeof(GridMapLiquidHeader), 1, mapFile);

                float* liquid_map = 0;

                if (!(lheader.flags & MAP_LIQUID_NO_TYPE))
                {
                    liquid_type = new uint8 [16*16];
                    fread(liquid_type, sizeof(uint8), 16*16, mapFile);
                }
                if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT))
                {
                    liquid_map = new float [lheader.width*lheader.height];
                    fread(liquid_map, sizeof(float), lheader.width*lheader.height, mapFile);
                }

                if(!liquid_type && !liquid_map)
                    break;

                int count = meshData.liquidVerts.size() / 3;
                float xoffset = (float(tileX)-32)*GRID_SIZE;
                float yoffset = (float(tileY)-32)*GRID_SIZE;

                float coord[3];
                int row, col;

                // generate coordinates
                if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT))
                {
                    int j = 0;
                    for(int i = 0; i < V9_SIZE_SQ; ++i)
                    {
                        row = i / V9_SIZE;
                        col = i % V9_SIZE;
                        if((row < (lheader.offsetY) || row >= (lheader.offsetY + lheader.height)) ||
                           (col < (lheader.offsetX) || col >= (lheader.offsetX + lheader.width)))
                        {
                            // dummy vert using invalid height
                            meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, -500.f, (yoffset+row*GRID_PART_SIZE)*-1);
                            continue;
                        }

                        getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map);
                        meshData.liquidVerts.append(coord[0]);
                        meshData.liquidVerts.append(coord[2]);
                        meshData.liquidVerts.append(coord[1]);
                        j++;
                    }
                }
                else
                {
                    for(int i = 0; i < V9_SIZE_SQ; ++i)
                    {
                        row = i / V9_SIZE;
                        col = i % V9_SIZE;
                        meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1);
                    }
                }

                delete [] liquid_map;

                int indices[3], loopStart, loopEnd, loopInc, triInc;
                getLoopVars(portion, loopStart, loopEnd, loopInc);
                triInc = BOTTOM-TOP;

                // generate triangles
                for(int i = loopStart; i < loopEnd; i+=loopInc)
                    for(int j = TOP; j <= BOTTOM; j+= triInc)
                    {
                        getHeightTriangle(i, Spot(j), indices, true);
                        ltriangles.append(indices[2] + count);
                        ltriangles.append(indices[1] + count);
                        ltriangles.append(indices[0] + count);
                    }

            }while(0);
        }

        fclose(mapFile);

        // now that we have gathered the data, we can figure out which parts to keep:
        // liquid above ground
        // ground above any liquid type
        // ground below <1.5 yard of water

        int loopStart, loopEnd, loopInc, tTriCount;
        bool useTerrain, useLiquid;

        float* lverts = meshData.liquidVerts.getCArray();
        float* tverts = meshData.solidVerts.getCArray();
        int* ltris = ltriangles.getCArray();
        int* ttris = ttriangles.getCArray();

        getLoopVars(portion, loopStart, loopEnd, loopInc);
        tTriCount = m_hiResHeightMaps ? 4 : 2;

        if(ltriangles.size() || ttriangles.size())
        {
            for(int i = loopStart; i < loopEnd; i+=loopInc)
            {
                for(int j = 0; j < 2; ++j)
                {
                    // default is true, will change to false if needed
                    useTerrain = true;
                    useLiquid = true;
                    uint8 liquidType;

                    // if there is no liquid, don't use liquid
                    if(!liquid_type ||
                       !meshData.liquidVerts.size() ||
                       !ltriangles.size())
                        useLiquid = false;
                    else
                    {
                        liquidType = getLiquidType(i, (const uint8 (*)[16])liquid_type);
                        switch(liquidType)
                        {
                            case 0:
                                // unknown liquid gets no terrain type
                                liquidType = 0;
                                break;
                            case MAP_LIQUID_TYPE_WATER:
                            case MAP_LIQUID_TYPE_OCEAN:
                                // merge different types of water
                                liquidType = NAV_WATER;
                                break;
                            case MAP_LIQUID_TYPE_MAGMA:
                                liquidType = NAV_MAGMA;
                                break;
                            case MAP_LIQUID_TYPE_SLIME:
                                liquidType = NAV_SLIME;
                                break;
                            case MAP_LIQUID_TYPE_DARK_WATER:
                                // players should not be here, so logically neither should creatures
                                useTerrain = false;
                                useLiquid = false;
                                break;
                        }
                    }

                    // if there is no terrain, don't use terrain
                    if(!ttriangles.size())
                        useTerrain = false;

                    // liquid is rendered as quads.  If any triangle has invalid height,
                    // don't render any of the triangles in that quad
                    // contrib/extractor uses -500.0 for invalid height
                    if(useLiquid)
                        if((&lverts[ltris[0]*3])[1] == -500.f ||
                           (&lverts[ltris[1]*3])[1] == -500.f ||
                           (&lverts[ltris[2]*3])[1] == -500.f)
                        {
                            useLiquid = false;
                        }

                    // if there is a hole here, don't use the terrain
                    if(useTerrain)
                        useTerrain = !isHole(i, holes);

                    if(useTerrain && useLiquid)
                    {
                        // get the indexes of the corners of the quad
                        int idx1, idx2, idx3;
                        if(j == 0)
                        {
                            idx1 = 0;
                            idx2 = 1;
                            idx3 = tTriCount;   // accesses index from next triangle on low res
                        }
                        else
                        {
                            idx1 = 0;
                            idx2 = 3*tTriCount/2-2;
                            idx3 = 3*tTriCount/2-1;
                        }

                        if(useTerrain &&
                            (&lverts[ltris[0]*3])[1] - 1.5f > (&tverts[ttris[idx1]*3])[1] &&
                            (&lverts[ltris[1]*3])[1] - 1.5f > (&tverts[ttris[idx2]*3])[1] &&
                            (&lverts[ltris[2]*3])[1] - 1.5f > (&tverts[ttris[idx3]*3])[1])
                            useTerrain = false; // if the whole terrain triangle is 1.5yds under liquid, don't use it
                        else if(useLiquid &&
                                (&lverts[ltris[0]*3])[1] < (&tverts[ttris[idx1]*3])[1] &&
                                (&lverts[ltris[1]*3])[1] < (&tverts[ttris[idx2]*3])[1] &&
                                (&lverts[ltris[2]*3])[1] < (&tverts[ttris[idx3]*3])[1])
                            useLiquid = false;  // if the whole liquid triangle is under terrain, don't use it
                    }

                    if(useLiquid)
                    {
                        meshData.liquidType.append(liquidType);
                        for(int k = 0; k < 3; ++k)
                            meshData.liquidTris.append(ltris[k]);
                    }

                    if(useTerrain)
                        for(int k = 0; k < 3*tTriCount/2; ++k)
                            meshData.solidTris.append(ttris[k]);

                    // advance to next set of triangles
                    ltris += 3;
                    ttris += 3*tTriCount/2;
                }
            }
        }

        delete [] liquid_type;

        return true;
    }
Exemple #18
0
void LPOut::highlight_box(int boxid, float r, float g, float b) {
	highlighted_boxes.push_back(Out_Highlight(Spot(0,0), boxid, r, g, b));
}
Exemple #19
0
Key::Key() {
	spot = Spot();
	multiplicity = 1;
}