Skip to content

Commit 9b9a198

Browse files
committed
document coordinate system, fixes #1
1 parent b03d30d commit 9b9a198

2 files changed

Lines changed: 285 additions & 0 deletions

File tree

user-manual/en/book.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ include::chapter02_getting-started.adoc[]
6666

6767
include::chapter03_map-format-and-lighting.adoc[]
6868

69+
include::chapter04_coordinate-systems.adoc[]
70+
6971
:!sectnums:
7072

7173
//include::appendix.adoc[]
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
== Coordinate Systems
2+
3+
FIFE uses several different coordinate systems to handle positions across the game world, layers, and screen display.
4+
Understanding these coordinate systems is essential for positioning objects, handling input, and working with the camera.
5+
6+
This chapter explains each coordinate system, how they relate to each other, and provides examples for converting between them.
7+
8+
=== Overview
9+
10+
FIFE has four main coordinate systems:
11+
12+
[horizontal]
13+
*Model Coordinates*:: Integer-based 3D coordinates representing discrete grid positions (cells)
14+
*Exact Model Coordinates*:: Floating-point 3D coordinates for precise positioning
15+
*Layer Coordinates*:: Model coordinates mapped to a specific layer
16+
*Screen Coordinates*:: 2D pixel coordinates on the screen after camera transformation
17+
18+
The base types are defined in `model/metamodel/modelcoords.h`:
19+
20+
[source,cpp]
21+
----
22+
typedef DoublePoint3D ExactModelCoordinate; // Double precision (x, y, z)
23+
typedef Point3D ModelCoordinate; // Integer precision (x, y, z)
24+
typedef DoublePoint3D AudioSpaceCoordinate; // Audio positioning
25+
----
26+
27+
=== Model Coordinates
28+
29+
Model coordinates represent positions on the game grid using integers.
30+
They correspond to discrete cell positions and are useful when you need to reference specific tiles or cells on a layer.
31+
32+
==== Creating Model Coordinates
33+
34+
[source,python]
35+
----
36+
# Create a model coordinate at cell (5, 3, 0)
37+
coord = fife.ModelCoordinate(5, 3, 0)
38+
39+
# Access components
40+
print(coord.x) # 5
41+
print(coord.y) # 3
42+
print(coord.z) # 0
43+
----
44+
45+
==== Use Cases
46+
47+
* Referencing specific cells on a grid
48+
* Placing objects at exact tile boundaries
49+
* Grid-based pathfinding
50+
* Layer grid calculations
51+
52+
=== Exact Model Coordinates
53+
54+
Exact model coordinates use double-precision floating-point values for smooth, continuous positioning.
55+
They allow objects to be placed between grid cells, enabling smooth movement and animations.
56+
57+
==== Creating Exact Model Coordinates
58+
59+
[source,python]
60+
----
61+
# Create an exact coordinate at (5.5, 3.7, 0.0)
62+
coord = fife.ExactModelCoordinate(5.5, 3.7, 0.0)
63+
64+
# Access components
65+
print(coord.x) # 5.5
66+
print(coord.y) # 3.7
67+
print(coord.z) # 0.0
68+
----
69+
70+
==== Use Cases
71+
72+
* Smooth object movement between cells
73+
* Precise positioning for animations
74+
* Camera positioning
75+
* Map coordinate calculations
76+
77+
=== Layer Coordinates
78+
79+
Layer coordinates are model coordinates that are associated with a specific layer.
80+
The `Location` class ties coordinates to a layer, providing the bridge between coordinate systems.
81+
82+
==== The Location Class
83+
84+
The `Location` class represents a position on a specific layer:
85+
86+
[source,python]
87+
----
88+
# Create a location on a layer
89+
location = fife.Location(layer)
90+
91+
# Set position using layer coordinates (cell precision)
92+
location.setLayerCoordinates(fife.ModelCoordinate(5, 3, 0))
93+
94+
# Set position using exact layer coordinates (precise)
95+
location.setExactLayerCoordinates(fife.ExactModelCoordinate(5.5, 3.7, 0.0))
96+
----
97+
98+
==== Getting Coordinates from a Location
99+
100+
[source,python]
101+
----
102+
# Get the layer this location is on
103+
layer = location.getLayer()
104+
105+
# Get exact layer coordinates
106+
exact_coords = location.getExactLayerCoordinates()
107+
print(f"Exact: ({exact_coords.x}, {exact_coords.y}, {exact_coords.z})")
108+
109+
# Get cell precision coordinates
110+
cell_coords = location.getLayerCoordinates()
111+
print(f"Cell: ({cell_coords.x}, {cell_coords.y}, {cell_coords.z})")
112+
113+
# Get map coordinates
114+
map_coords = location.getMapCoordinates()
115+
print(f"Map: ({map_coords.x}, {map_coords.y}, {map_coords.z})")
116+
----
117+
118+
==== Checking Location Validity
119+
120+
A location is valid if:
121+
- A layer is set
122+
- The layer has a cell grid assigned
123+
124+
[source,python]
125+
----
126+
if location.isValid():
127+
# Location is ready to use
128+
pass
129+
----
130+
131+
==== Calculating Distances
132+
133+
The `Location` class provides methods for calculating distances:
134+
135+
[source,python]
136+
----
137+
# Distance in map coordinates
138+
map_distance = location.getMapDistanceTo(other_location)
139+
140+
# Distance in layer coordinates
141+
layer_distance = location.getLayerDistanceTo(other_location)
142+
----
143+
144+
=== Screen Coordinates
145+
146+
Screen coordinates represent positions on the game window in pixels.
147+
The camera transforms model coordinates to screen coordinates for rendering.
148+
149+
==== The Camera and ScreenPoint
150+
151+
The `Camera` class handles screen coordinate transformations.
152+
Screen coordinates use `ScreenPoint`, which is a `Point3D` where `z` represents depth.
153+
154+
==== Converting Between Map and Screen Coordinates
155+
156+
[source,python]
157+
----
158+
# Convert map coordinates to screen coordinates
159+
screen_point = camera.toScreenCoordinates(exact_map_coords)
160+
161+
# Convert screen coordinates back to map coordinates
162+
map_point = camera.toMapCoordinates(screen_point)
163+
164+
# Convert map to virtual screen coordinates (sub-pixel precision)
165+
virtual_screen = camera.toVirtualScreenCoordinates(exact_map_coords)
166+
----
167+
168+
==== Virtual Screen Coordinates
169+
170+
Virtual screen coordinates provide sub-pixel precision before final screen conversion:
171+
172+
[source,python]
173+
----
174+
# Map to virtual screen
175+
virtual = camera.toVirtualScreenCoordinates(map_coords)
176+
177+
# Virtual screen to screen
178+
screen = camera.virtualScreenToScreen(virtual)
179+
180+
# Screen to virtual screen
181+
virtual = camera.screenToVirtualScreen(screen)
182+
----
183+
184+
==== Mouse Click Example
185+
186+
When handling mouse clicks, you typically convert screen coordinates to map coordinates:
187+
188+
[source,python]
189+
----
190+
def onMousePress(self, event):
191+
# Get screen coordinates from mouse event
192+
screen_point = fife.ScreenPoint(event.getX(), event.getY(), 0)
193+
194+
# Convert to map coordinates
195+
map_point = camera.toMapCoordinates(screen_point)
196+
197+
# Convert to layer coordinates for a specific layer
198+
# (map coordinates are layer-independent)
199+
----
200+
201+
=== Coordinate Conversion Summary
202+
203+
This table shows how to convert between coordinate systems:
204+
205+
[horizontal]
206+
*Model to Exact*:: `ExactModelCoordinate(float(x), float(y), float(z))`
207+
*Exact to Model*:: `ModelCoordinate(int(x), int(y), int(z))` (truncates)
208+
*Layer to Screen*:: `camera.toScreenCoordinates(location.getExactLayerCoordinates())`
209+
*Screen to Map*:: `camera.toMapCoordinates(ScreenPoint(x, y, z))`
210+
*Map to Layer*:: Use cell grid's `getLayerCoordinates(map_coords)` method
211+
*Layer to Map*:: Use cell grid's `getExactLayerCoordinates(layer_coords)` method
212+
213+
=== Practical Examples
214+
215+
==== Moving an Instance
216+
217+
[source,python]
218+
----
219+
def move_instance(instance, target_x, target_y):
220+
# Get current location
221+
current = instance.getLocation()
222+
223+
# Create target coordinates
224+
target = fife.ExactModelCoordinate(target_x, target_y, 0)
225+
226+
# Create new location on same layer
227+
new_location = fife.Location(current.getLayer())
228+
new_location.setExactLayerCoordinates(target)
229+
230+
# Move the instance
231+
instance.setLocation(new_location)
232+
----
233+
234+
==== Finding Instance at Mouse Position
235+
236+
[source,python]
237+
----
238+
def get_instance_at(screen_x, screen_y, camera, layer):
239+
# Convert screen coordinates to screen point
240+
screen_point = fife.ScreenPoint(screen_x, screen_y, 0)
241+
242+
# Get matching instances
243+
instances = []
244+
camera.getMatchingInstances(screen_point, layer, instances)
245+
246+
return instances[0] if instances else None
247+
----
248+
249+
==== Placing an Object on a Grid
250+
251+
[source,python]
252+
----
253+
def place_object_at(object_id, layer, cell_x, cell_y):
254+
# Create location at specific cell
255+
location = fife.Location(layer)
256+
location.setLayerCoordinates(fife.ModelCoordinate(cell_x, cell_y, 0))
257+
258+
# Create instance
259+
instance = layer.createInstance(object_id, location)
260+
return instance
261+
----
262+
263+
=== Camera Properties Affecting Coordinate Transformations
264+
265+
The camera's properties affect how coordinates are transformed:
266+
267+
[horizontal]
268+
*Rotation*:: Rotates the view around the target point
269+
*Tilt*:: Adjusts the viewing angle (0 = top-down, 45 = isometric)
270+
*Zoom*:: Scales the view
271+
*zToY*:: Affects the z-axis to y-axis transformation ratio
272+
273+
These properties can be set via the camera:
274+
275+
[source,python]
276+
----
277+
camera.setRotation(45) # Rotate 45 degrees
278+
camera.setTilt(60) # 60 degree tilt angle
279+
camera.setZoom(1.5) # Zoom to 1.5x
280+
camera.setZToY(32) # 1 z-unit = 32 y-pixels
281+
----
282+
283+
Understanding these coordinate systems is key to working with FIFE's rendering and input systems effectively.

0 commit comments

Comments
 (0)