#include <zone_symmetrisation.h>
This class build symmetry specific informations needed to know how transform tiles when a zone is symmetrise.
There is two states for a tile : Regular or Goofy. If the tile is regular, it doesn't need specific transformation when the zone is symmetrise. If the tile is goofy, the tile must be rotate by 180deg more to be correct.
Nevrax France
Definition at line 54 of file zone_symmetrisation.h.
Public Types | |
enum | TState { Nothing = 0, Regular = 1, Goofy = 2 } |
Symmetrie state. More... | |
Public Member Functions | |
bool | build (const std::vector< CPatchInfo > &patchInfo, float snapCell, float weldThreshold, const CTileBank &bank, CError &errorDesc, const NLMISC::CMatrix &toOriginalSpace) |
CZoneSymmetrisation () | |
Constructor. | |
TState | getOrientedTileBorderState (uint patch, uint tile) const |
bool | getOrientedTileCorner (uint patch, uint tile) |
TState | getTileBorderState (uint patch, uint tile) const |
TState | getTileState (uint patch, uint tile, uint layer) const |
Private Member Functions | |
bool | propagateTileState (uint i, uint s, uint t, const std::vector< CPatchInfo > &patchInfo, const CTileBank &bank, bool forceRegular) |
void | setOrientedTileBorderState (uint patch, uint tile, TState state) |
void | setOrientedTileCorner (uint patch, uint tile, bool corner) |
bool | setOrientedTileState (const NL3D::CPatchInfo &patch, uint patchId, float snapCell, float weldThreshold, TState &state, const NLMISC::CMatrix &toOriginalSpace, const CTileBank &bank) |
void | setTileBorderState (uint patch, uint tile, TState state) |
bool | setTileState (const NL3D::CPatchInfo &patch, uint patchId, float snapCell, float weldThreshold, TState &state, const NLMISC::CMatrix &toOriginalSpace, const CTileBank &bank) |
void | setTileState (uint patch, uint tile, uint layer, TState state) |
Static Private Member Functions | |
bool | snapOnGrid (float &value, float resolution, float snap) |
Private Attributes | |
std::vector< std::vector< uint16 > > | _TilesLayerStates |
|
Symmetrie state.
Definition at line 59 of file zone_symmetrisation.h.
|
|
Constructor.
Definition at line 39 of file zone_symmetrisation.cpp.
00040 { 00041 } |
|
Build symmetry informations
Definition at line 186 of file zone_symmetrisation.cpp. References _TilesLayerStates, NL3D::CZoneSymmetrisation::CError::Errors, NL3D::CPatchInfo::OrderS, NL3D::CPatchInfo::OrderT, propagateTileState(), s, setOrientedTileState(), setTileState(), t, NLMISC::toString(), and uint. Referenced by NL3D::CPatchInfo::transform().
00187 { 00188 // * Clear errors 00189 errorDesc.Errors.clear (); 00190 00191 // * Build the patches state 00192 00193 // A) Resize arrays 00194 _TilesLayerStates.resize (patchInfo.size ()); 00195 00196 // D) Resize the tile array 00197 uint i; 00198 for (i=0; i<patchInfo.size (); i++) 00199 { 00200 // Ref on the patch 00201 const CPatchInfo &patch = patchInfo[i]; 00202 _TilesLayerStates[i].resize (0); 00203 _TilesLayerStates[i].resize (patch.OrderS * patch.OrderT, 0); 00204 } 00205 00206 // B), C) and E) We need to select patches having an open edge on the zone border. To do so, we use the snapCell and weldThreshold parameters 00207 for (i=0; i<patchInfo.size (); i++) 00208 { 00209 // Ref on the patch 00210 const CPatchInfo &patch = patchInfo[i]; 00211 00212 // Does this patch is over a border ? 00213 TState patchState; 00214 if (!setTileState (patch, i, snapCell, weldThreshold, patchState, toOriginalSpace, bank)) 00215 { 00216 // Push an error 00217 errorDesc.Errors.push_back ("Patch nb "+toString (i)+" is invalid"); 00218 } 00219 00220 // Set the oriented patch state 00221 if (!setOrientedTileState (patch, i, snapCell, weldThreshold, patchState, toOriginalSpace, bank)) 00222 { 00223 // Push an error 00224 errorDesc.Errors.push_back ("Patch nb "+toString (i)+" is invalid"); 00225 } 00226 } 00227 00228 // F) We flag each tile on an opened edge using this formula 00229 // - If the patch is not Nothing do 00230 // - tileIsGoofy = (patchIsGoofy) XOR ((tileRotation&1) != 0) 00231 for (i=0; i<patchInfo.size (); i++) 00232 { 00233 // Ref on the patch 00234 const CPatchInfo &patch = patchInfo[i]; 00235 00236 // For each tile 00237 uint s,t; 00238 for (t=0; t<patch.OrderT; t++) 00239 { 00240 for (s=0; s<patch.OrderS; s++) 00241 { 00242 if (!propagateTileState (i, s, t, patchInfo, bank, false)) 00243 { 00244 // Push an error 00245 errorDesc.Errors.push_back ("Error during propagation. Topology invalid."); 00246 return false; 00247 } 00248 } 00249 } 00250 } 00251 00252 // G) Force all remaining Nothing tiles to Regular 00253 for (i=0; i<patchInfo.size (); i++) 00254 { 00255 // Ref on the patch 00256 const CPatchInfo &patch = patchInfo[i]; 00257 00258 // For each tile 00259 uint s,t; 00260 for (t=0; t<patch.OrderT; t++) 00261 { 00262 for (s=0; s<patch.OrderS; s++) 00263 { 00264 if (!propagateTileState (i, s, t, patchInfo, bank, true)) 00265 { 00266 // Push an error 00267 errorDesc.Errors.push_back ("Error during propagation. Topology invalid."); 00268 return false; 00269 } 00270 } 00271 } 00272 } 00273 00274 // Returns true if no error 00275 return true; // errorDesc.Errors.size () == 0; 00276 } |
|
Get tile symmetry state for oriented tiles Can return Regular, Goofy or Nothing. Definition at line 72 of file zone_symmetrisation.cpp. References getTileState(), and uint.
00073 { 00074 return getTileState (patch, tile, 4); 00075 } |
|
Set oriented tile corner state Definition at line 79 of file zone_symmetrisation.cpp. References _TilesLayerStates, and uint. Referenced by propagateTileState().
00080 { 00081 return ( ( _TilesLayerStates[patch][tile] >> 10 ) & 1 ) != 0; 00082 } |
|
Get tile symmetry state Can return Regular, Goofy or Nothing. Definition at line 65 of file zone_symmetrisation.cpp. References getTileState(), and uint.
00066 { 00067 return getTileState (patch, tile, 3); 00068 } |
|
Get tile symmetry state Can return Regular, Goofy or Nothing. Definition at line 57 of file zone_symmetrisation.cpp. References _TilesLayerStates, nlassert, and uint. Referenced by getOrientedTileBorderState(), getTileBorderState(), propagateTileState(), and NL3D::CPatchInfo::transform().
00058 { 00059 nlassert (layer<5); 00060 return (TState)((_TilesLayerStates[patch][tile]>>(layer*2))&0x3); 00061 } |
|
Propagate tile state information for a given tile.
Definition at line 670 of file zone_symmetrisation.cpp. References NL3D::CPatchInfo::CBindInfo::Edge, NL3D::CFillStackNode::Edge, NL3D::CTileSet::getOriented(), getOrientedTileCorner(), NL3D::CTileBank::getTileCount(), NL3D::CTileBank::getTileSet(), NL3D::CTileBank::getTileSetCount(), getTileState(), NL3D::CTileBank::getTileXRef(), Goofy, NL3D::CPatchInfo::CBindInfo::Next, NL_TILE_ELM_LAYER_EMPTY, nlassert, nlwarning, Nothing, NL3D::CPatchInfo::CBindInfo::NPatchs, NL3D::CPatchInfo::OrderS, NL3D::CFillStackNode::Patch, Regular, NL3D::CFillStackNode::Rotate, NL3D::CFillStackNode::S, s, setTileState(), sint, NL3D::CFillStackNode::State, NL3D::CFillStackNode::T, t, NL3D::CPatchInfo::Tiles, type, and uint. Referenced by build().
00671 { 00672 // For each layer 00673 uint layer; 00674 for (layer=0; layer<3; layer++) 00675 { 00676 // Get the patch ptr 00677 const CPatchInfo *currentPatchPtr = &(patchInfo[patch]); 00678 00679 // Get the tile index 00680 uint tile = s+t*currentPatchPtr->OrderS; 00681 00682 // Get the tiles set used here 00683 uint tileIndex = currentPatchPtr->Tiles[tile].Tile[layer]; 00684 if (tileIndex != NL_TILE_ELM_LAYER_EMPTY) 00685 { 00686 // Valid tile number ? 00687 if (tileIndex >= (uint)bank.getTileCount ()) 00688 { 00689 nlwarning ("CZoneSymmetrisation::propagateTileState: Invalid tile index"); 00690 return false; 00691 } 00692 00693 // Get the tile set used by this layer 00694 int tileSetToPropagate; 00695 int number; 00696 CTileBank::TTileType type; 00697 bank.getTileXRef (tileIndex, tileSetToPropagate, number, type); 00698 00699 if ((tileSetToPropagate < 0) || (tileSetToPropagate >= bank.getTileSetCount())) 00700 { 00701 nlwarning("CZoneSymmetrisation::propagateTileState: tile %d has an unknown tileSet (%d)", tileIndex, tileSetToPropagate); 00702 } 00703 else 00704 { 00705 // Oriented ? 00706 bool oriented = bank.getTileSet (tileSetToPropagate)->getOriented (); 00707 00708 // If oriented, must not be a corner 00709 if (!(oriented && getOrientedTileCorner (patch, tile))) 00710 { 00711 // Current node 00712 CFillStackNode currentNode (patch, s, t, currentPatchPtr->Tiles[tile].getTileOrient(layer), getTileState (patch, tile, layer)); 00713 00714 // Propagate non-Nothing tiles 00715 if ( (!forceRegular && (currentNode.State != Nothing)) || (forceRegular && (currentNode.State == Nothing)) ) 00716 { 00717 // Force to Regular ? 00718 if (forceRegular) 00719 { 00720 setTileState (patch, tile, layer, Regular); 00721 currentNode.State = Regular; 00722 } 00723 00724 // Fill stack 00725 vector<CFillStackNode> stack; 00726 stack.push_back (currentNode); 00727 00728 // While people in the stack 00729 while (!stack.empty ()) 00730 { 00731 // Pop last element 00732 currentNode = stack.back (); 00733 stack.pop_back (); 00734 00735 do 00736 { 00737 // Set current patch pointer 00738 currentPatchPtr = &(patchInfo[currentNode.Patch]); 00739 00740 // Get neighbor 00741 CFillStackNode neighborNode (currentNode.Patch, currentNode.S, currentNode.T, currentNode.Rotate, currentNode.State); 00742 switch (currentNode.Edge) 00743 { 00744 case 0: 00745 neighborNode.S--; 00746 break; 00747 case 1: 00748 neighborNode.T++; 00749 break; 00750 case 2: 00751 neighborNode.S++; 00752 break; 00753 case 3: 00754 neighborNode.T--; 00755 break; 00756 } 00757 00758 // Is still in patch ? 00759 if ( (neighborNode.S>=patchInfo[currentNode.Patch].OrderS) || (neighborNode.T>=patchInfo[currentNode.Patch].OrderT) ) 00760 { 00761 // No, found new patch 00762 uint position; 00763 switch (currentNode.Edge) 00764 { 00765 case 0: 00766 position = neighborNode.T; 00767 break; 00768 case 1: 00769 position = neighborNode.S; 00770 break; 00771 case 2: 00772 position = patchInfo[currentNode.Patch].OrderT - neighborNode.T - 1; 00773 break; 00774 case 3: 00775 position = patchInfo[currentNode.Patch].OrderS - neighborNode.S - 1; 00776 break; 00777 } 00778 00779 // Get next patch 00780 uint patchOut; 00781 sint sOut; 00782 sint tOut; 00783 if (patchInfo[currentNode.Patch].getNeighborTile (currentNode.Patch, currentNode.Edge, position, 00784 patchOut, sOut, tOut, patchInfo)) 00785 { 00786 // Should be another patch 00787 nlassert (patchOut != currentNode.Patch); 00788 00789 // Get patch id 00790 neighborNode.Patch = patchOut; 00791 00792 // Coordinate must be IN the patch 00793 nlassert (sOut >= 0); 00794 nlassert (tOut >= 0); 00795 nlassert (sOut < patchInfo[neighborNode.Patch].OrderS); 00796 nlassert (tOut < patchInfo[neighborNode.Patch].OrderT); 00797 00798 // Copy it 00799 neighborNode.S = sOut; 00800 neighborNode.T = tOut; 00801 00802 // Find neighbor 00803 const CPatchInfo::CBindInfo &neighborBindInfo = patchInfo[currentNode.Patch].BindEdges[currentNode.Edge]; 00804 uint edgePatch; 00805 for (edgePatch=0; edgePatch<(uint)neighborBindInfo.NPatchs; edgePatch++) 00806 { 00807 if (neighborBindInfo.Next[edgePatch] == neighborNode.Patch) 00808 break; 00809 } 00810 00811 // Must find one patch 00812 nlassert (edgePatch<(uint)neighborBindInfo.NPatchs); 00813 00814 // Rotation 00815 neighborNode.Rotate = (currentNode.Rotate + 2 + neighborBindInfo.Edge[edgePatch] - currentNode.Edge) & 3; 00816 00817 // Toggle the state ? 00818 if ((neighborNode.Rotate ^ currentNode.Rotate) & 1) 00819 { 00820 // Yes 00821 neighborNode.State = (neighborNode.State == Regular) ? Goofy : Regular; 00822 } 00823 } 00824 else 00825 { 00826 // No propagation, continue 00827 currentNode.Edge++; 00828 continue; 00829 } 00830 } 00831 00832 // Neighbor patch 00833 const CPatchInfo *neighborPatchPtr = &(patchInfo[neighborNode.Patch]); 00834 00835 // Get the tile index 00836 uint neighborTile = neighborNode.S+neighborNode.T*neighborPatchPtr->OrderS; 00837 00838 // Look for the same tile set in the new tile 00839 uint neighborLayer; 00840 for (neighborLayer=0; neighborLayer<3; neighborLayer++) 00841 { 00842 // Get the tile index 00843 uint neighborTileIndex = neighborPatchPtr->Tiles[neighborTile].Tile[neighborLayer]; 00844 00845 if (neighborTileIndex != NL_TILE_ELM_LAYER_EMPTY) 00846 { 00847 // Valid tile number ? 00848 if (neighborTileIndex >= (uint)bank.getTileCount ()) 00849 { 00850 nlwarning ("CZoneSymmetrisation::propagateTileState: Invalid tile index"); 00851 return false; 00852 } 00853 00854 // Get tileset 00855 int neighborTileSet; 00856 int neighborNumber; 00857 CTileBank::TTileType neighborType; 00858 bank.getTileXRef (neighborTileIndex, neighborTileSet, neighborNumber, neighborType); 00859 00860 // Same tileset ? Stop! 00861 if ( (neighborTileSet == tileSetToPropagate) && 00862 (neighborNode.Rotate == neighborPatchPtr->Tiles[neighborTile].getTileOrient(neighborLayer)) ) 00863 break; 00864 } 00865 } 00866 00867 // Found ? 00868 if (neighborLayer<3) 00869 { 00870 // If oriented, must not be a corner 00871 if (!(oriented && getOrientedTileCorner (neighborNode.Patch, neighborTile))) 00872 { 00873 // Propagate in the new node ? 00874 TState neighborState = getTileState (neighborNode.Patch, neighborTile, neighborLayer); 00875 if (neighborState == Nothing) 00876 { 00877 // Set the state 00878 setTileState (neighborNode.Patch, neighborTile, neighborLayer, neighborNode.State); 00879 00880 // Stack current node if some neighbor left to visit 00881 if (currentNode.Edge < 3) 00882 { 00883 currentNode.Edge++; 00884 stack.push_back (currentNode); 00885 } 00886 00887 // Continue with the new node 00888 currentNode = neighborNode; 00889 } 00890 else if (neighborState != neighborNode.State) 00891 { 00892 // Error, same tile but not same state 00893 // nlwarning ("CZoneSymmetrisation::propagateTileState: error, find same iso surfaces with different state."); 00894 00895 // No propagation, continue 00896 currentNode.Edge++; 00897 } 00898 else 00899 { 00900 // No propagation, continue 00901 currentNode.Edge++; 00902 } 00903 } 00904 else 00905 { 00906 // No propagation, continue 00907 currentNode.Edge++; 00908 } 00909 } 00910 else 00911 // No propagation, continue 00912 currentNode.Edge++; 00913 } 00914 while (currentNode.Edge<4); 00915 } 00916 } 00917 } 00918 } 00919 } 00920 } 00921 00922 return true; 00923 } |
|
Set border oriented tile symmetry state Definition at line 102 of file zone_symmetrisation.cpp. References setTileState(), and uint. Referenced by setOrientedTileState().
00103 { 00104 setTileState (patch, tile, 4, state); 00105 } |
|
Set oriented tile corner state Definition at line 109 of file zone_symmetrisation.cpp. References _TilesLayerStates, uint, and uint16. Referenced by setOrientedTileState().
00110 { 00111 uint16 &ref = _TilesLayerStates[patch][tile]; 00112 ref &= ~(1<<10); 00113 ref |= ((uint16)corner)<<(10); 00114 } |
|
Definition at line 472 of file zone_symmetrisation.cpp. References NL3D::CTileSet::getOriented(), NL3D::CTileBank::getTileSet(), NL3D::CTileBank::getTileSetCount(), NL3D::CTileBank::getTileXRef(), Goofy, NL_TILE_ELM_LAYER_EMPTY, nlwarning, Nothing, NL3D::CPatchInfo::OrderS, NL3D::CPatchInfo::OrderT, NL3D::CPatchInfo::Patch, Regular, setOrientedTileBorderState(), setOrientedTileCorner(), setTileState(), sint, sint32, snapOnGrid(), NL3D::CPatchInfo::Tiles, type, uint, NL3D::CBezierPatch::Vertices, NLMISC::CVector::x, and NLMISC::CVector::y. Referenced by build().
00473 { 00474 // Edges state 00475 TState edgesState[4] = { Nothing, Nothing, Nothing, Nothing }; 00476 00477 // Vertices position 00478 sint32 vertPosU[4]; 00479 sint32 vertPosV[4]; 00480 00481 // For each vertices 00482 uint i; 00483 for (i=0; i<4; i++) 00484 { 00485 // Snap the vertex 00486 CVector original = toOriginalSpace * patch.Patch.Vertices[i]; 00487 float valueU = original.x; 00488 float valueV = original.y; 00489 00490 // Snap on U 00491 if (snapOnGrid (valueU, snapCell, weldThreshold)) 00492 vertPosU[i] = (sint32)((valueU+0.5f) / snapCell); 00493 else 00494 vertPosU[i] = 0x80000000; 00495 00496 // Snap on V 00497 if (snapOnGrid (valueV, snapCell, weldThreshold)) 00498 vertPosV[i] = (sint32)((valueV+0.5f) / snapCell); 00499 else 00500 vertPosV[i] = 0x80000000; 00501 } 00502 00503 // Patch flags 00504 bool regular = false; 00505 bool goofy = false; 00506 bool EdgeSnaped[4] = { false, false, false, false }; 00507 00508 // For each edges 00509 for (i=0; i<4; i++) 00510 { 00511 // Vertex snapped and align on a common axis ? 00512 if ( (vertPosU[i] != 0x80000000) || (vertPosV[i] != 0x80000000) ) 00513 { 00514 // Snapped on U or V ? 00515 bool snapU = (vertPosU[i] == vertPosU[(i+1)&3]) && (vertPosU[i] != 0x80000000); 00516 bool snapV = (vertPosV[i] == vertPosV[(i+1)&3]) && (vertPosV[i] != 0x80000000); 00517 00518 // If snapped on one, continue 00519 if (snapU || snapV) 00520 { 00521 // If snap on the both, error 00522 if (snapU && snapV) 00523 return false; 00524 00525 // Is this edge Regular or Goofy ? 00526 edgesState[i] = (i&1)?Goofy:Regular; 00527 00528 // Flag the patch 00529 if (edgesState[i] == Regular) 00530 regular = true; 00531 else 00532 goofy = true; 00533 00534 // Edge snaped 00535 EdgeSnaped[i] = true; 00536 } 00537 } 00538 } 00539 00540 // * Set the tiles 00541 00542 // For each edges 00543 for (i=0; i<4; i++) 00544 { 00545 // Edge snapped ? 00546 if (EdgeSnaped[i]) 00547 { 00548 // For each tiles 00549 uint tileCount = ((i&1)!=0)?patch.OrderS:patch.OrderT; 00550 sint currentTile; 00551 sint delta; 00552 switch (i) 00553 { 00554 case 0: 00555 currentTile = 0; 00556 delta = patch.OrderS; 00557 break; 00558 case 1: 00559 currentTile = patch.OrderS*(patch.OrderT-1); 00560 delta = 1; 00561 break; 00562 case 2: 00563 currentTile = patch.OrderS-1; 00564 delta = patch.OrderS; 00565 break; 00566 case 3: 00567 currentTile = 0; 00568 delta = 1; 00569 break; 00570 } 00571 uint j; 00572 for (j=0; j<tileCount; j++) 00573 { 00574 // Set the border state 00575 setOrientedTileBorderState (patchId, currentTile, edgesState[i]); 00576 00577 // For each layer 00578 uint layer; 00579 for (layer=0; layer<3; layer++) 00580 { 00581 // Get the tiles set used here 00582 uint tile = patch.Tiles[currentTile].Tile[layer]; 00583 if (tile != NL_TILE_ELM_LAYER_EMPTY) 00584 { 00585 int tileSet; 00586 int number; 00587 CTileBank::TTileType type; 00588 00589 bank.getTileXRef (tile, tileSet, number, type); 00590 if ((tileSet < 0) || (tileSet >= bank.getTileSetCount())) 00591 { 00592 nlwarning("CZoneSymmetrisation::setOrientedTileState : tile %d has an unknown tileSet (%d)", tile, tileSet); 00593 return false; 00594 } 00595 00596 // Set it only if oriented 00597 if (bank.getTileSet (tileSet)->getOriented ()) 00598 { 00599 setTileState (patchId, currentTile, layer, edgesState[i]); 00600 } 00601 } 00602 } 00603 00604 // Next tile 00605 currentTile += delta; 00606 } 00607 } 00608 } 00609 00610 // For each corners 00611 for (i=0; i<4; i++) 00612 { 00613 // Corner snapped ? 00614 uint next = (i+1)&3; 00615 if (EdgeSnaped[i] && EdgeSnaped[next]) 00616 { 00617 // Flag tile as corner 00618 switch (i) 00619 { 00620 case 0: 00621 setOrientedTileCorner (patchId, patch.OrderS*(patch.OrderT-1), true); 00622 break; 00623 case 1: 00624 setOrientedTileCorner (patchId, patch.OrderS*patch.OrderT-1, true); 00625 break; 00626 case 2: 00627 setOrientedTileCorner (patchId, patch.OrderS-1, true); 00628 break; 00629 case 3: 00630 setOrientedTileCorner (patchId, 0, true); 00631 break; 00632 } 00633 } 00634 } 00635 00636 return true; 00637 } |
|
Set border tile symmetry state Definition at line 95 of file zone_symmetrisation.cpp. References setTileState(), and uint. Referenced by setTileState().
00096 { 00097 setTileState (patch, tile, 3, state); 00098 } |
|
Set tile state of a patch Definition at line 312 of file zone_symmetrisation.cpp. References NL3D::CTileSet::getOriented(), NL3D::CTileBank::getTileSet(), NL3D::CTileBank::getTileSetCount(), NL3D::CTileBank::getTileXRef(), Goofy, NL_TILE_ELM_LAYER_EMPTY, nlwarning, Nothing, NL3D::CPatchInfo::OrderS, NL3D::CPatchInfo::OrderT, NL3D::CPatchInfo::Patch, Regular, setTileBorderState(), setTileState(), sint, sint32, snapOnGrid(), NL3D::CPatchInfo::Tiles, type, uint, NL3D::CBezierPatch::Vertices, NLMISC::CVector::x, and NLMISC::CVector::y.
00313 { 00314 // Edges state 00315 TState edgesState[4] = { Nothing, Nothing, Nothing, Nothing }; 00316 00317 // Vertices position 00318 sint32 vertPosU[4]; 00319 sint32 vertPosV[4]; 00320 00321 // For each vertices 00322 uint i; 00323 for (i=0; i<4; i++) 00324 { 00325 // Snap the vertex 00326 CVector original = toOriginalSpace * patch.Patch.Vertices[i]; 00327 float valueU = original.x; 00328 float valueV = original.y; 00329 00330 // Snap on U 00331 if (snapOnGrid (valueU, snapCell, weldThreshold)) 00332 vertPosU[i] = (sint32)((valueU+0.5f) / snapCell); 00333 else 00334 vertPosU[i] = 0x80000000; 00335 00336 // Snap on V 00337 if (snapOnGrid (valueV, snapCell, weldThreshold)) 00338 vertPosV[i] = (sint32)((valueV+0.5f) / snapCell); 00339 else 00340 vertPosV[i] = 0x80000000; 00341 } 00342 00343 // Patch flags 00344 bool regular = false; 00345 bool goofy = false; 00346 bool EdgeSnaped[4] = { false, false, false, false }; 00347 00348 // For each edges 00349 for (i=0; i<4; i++) 00350 { 00351 // Vertex snapped and align on a common axis ? 00352 if ( (vertPosU[i] != 0x80000000) || (vertPosV[i] != 0x80000000) ) 00353 { 00354 // Snapped on U or V ? 00355 bool snapU = (vertPosU[i] == vertPosU[(i+1)&3]) && (vertPosU[i] != 0x80000000); 00356 bool snapV = (vertPosV[i] == vertPosV[(i+1)&3]) && (vertPosV[i] != 0x80000000); 00357 00358 // If snapped on one, continue 00359 if (snapU || snapV) 00360 { 00361 // If snap on the both, error 00362 if (snapU && snapV) 00363 return false; 00364 00365 // Is this edge Regular or Goofy ? 00366 if (snapU) 00367 edgesState[i] = (i&1)?Goofy:Regular; 00368 else // (snapV) 00369 edgesState[i] = (i&1)?Regular:Goofy; 00370 00371 // Flag the patch 00372 if (edgesState[i] == Regular) 00373 regular = true; 00374 else 00375 goofy = true; 00376 00377 // Edge snaped 00378 EdgeSnaped[i] = true; 00379 } 00380 } 00381 } 00382 00383 // Goofy and regular ? Error 00384 if (goofy && regular) 00385 return false; 00386 00387 // Nothing ? 00388 if ((!goofy) && (!regular)) 00389 state = Nothing; 00390 else 00391 { 00392 // Not nothing ? 00393 state = regular?Regular:Goofy; 00394 00395 // * Set the tiles 00396 00397 // For each edges 00398 for (i=0; i<4; i++) 00399 { 00400 // Edge snapped ? 00401 if (EdgeSnaped[i]) 00402 { 00403 // For each tiles 00404 uint tileCount = ((i&1)!=0)?patch.OrderS:patch.OrderT; 00405 sint currentTile; 00406 sint delta; 00407 switch (i) 00408 { 00409 case 0: 00410 currentTile = 0; 00411 delta = patch.OrderS; 00412 break; 00413 case 1: 00414 currentTile = patch.OrderS*(patch.OrderT-1); 00415 delta = 1; 00416 break; 00417 case 2: 00418 currentTile = patch.OrderS-1; 00419 delta = patch.OrderS; 00420 break; 00421 case 3: 00422 currentTile = 0; 00423 delta = 1; 00424 break; 00425 } 00426 uint j; 00427 for (j=0; j<tileCount; j++) 00428 { 00429 // Set the border state 00430 setTileBorderState (patchId, currentTile, state); 00431 00432 // For each layer 00433 uint layer; 00434 for (layer=0; layer<3; layer++) 00435 { 00436 // Get the tiles set used here 00437 uint tile = patch.Tiles[currentTile].Tile[layer]; 00438 if (tile != NL_TILE_ELM_LAYER_EMPTY) 00439 { 00440 int tileSet; 00441 int number; 00442 CTileBank::TTileType type; 00443 bank.getTileXRef (tile, tileSet, number, type); 00444 00445 if ((tileSet < 0) || (tileSet >= bank.getTileSetCount())) 00446 { 00447 nlwarning("CZoneSymmetrisation::setTileState : tile %d has an unknown tileSet (%d)", tile, tileSet); 00448 return false; 00449 } 00450 00451 // Set it only if not oriented 00452 if (!bank.getTileSet (tileSet)->getOriented ()) 00453 { 00454 // Set the tile state 00455 setTileState (patchId, currentTile, layer, state); 00456 } 00457 } 00458 } 00459 00460 // Next tile 00461 currentTile += delta; 00462 } 00463 } 00464 } 00465 } 00466 00467 return true; 00468 } |
|
Set orientedtile symmetry state Definition at line 86 of file zone_symmetrisation.cpp. References _TilesLayerStates, uint, and uint16. Referenced by build(), propagateTileState(), setOrientedTileBorderState(), setOrientedTileState(), setTileBorderState(), and setTileState().
00087 { 00088 uint16 &ref = _TilesLayerStates[patch][tile]; 00089 ref &= ~(3<<(layer*2)); 00090 ref |= ((uint16)state)<<(layer*2); 00091 } |
|
Definition at line 280 of file zone_symmetrisation.cpp. References nlassert, and value. Referenced by setOrientedTileState(), and setTileState().
00281 { 00282 // Calc the floor 00283 float _floor = (float) ( resolution * floor (value / resolution) ); 00284 nlassert (_floor<=value); 00285 00286 // Calc the remainder 00287 float remainder = value - _floor; 00288 //nlassert ( (remainder>=0) && (remainder<resolution) ); 00289 00290 // Check the snape 00291 if ( remainder <= snap ) 00292 { 00293 // Flag it 00294 value = _floor; 00295 00296 // Floor is good 00297 return true; 00298 } 00299 else if ( (resolution - remainder) <= snap ) 00300 { 00301 // Flag it 00302 value = _floor + resolution; 00303 00304 // Floor + resolution is good 00305 return true; 00306 } 00307 return false; 00308 } |
|
Definition at line 158 of file zone_symmetrisation.h. Referenced by build(), getOrientedTileCorner(), getTileState(), setOrientedTileCorner(), and setTileState(). |