#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(). |
1.3.6