Hello everyone, as you may have read in the Clipping thread I posted earlier, I am working on re-implementing the ToEE engine. To do that, I have to re-implement the ToEE projection and view matrices (I am using Direct 3D too) so coordinates used in the MOB/Clipping/Whatever files map to the same screen location in my engine. Basically the complicated question first: Does anyone know how to map a ToEE X/Y coordinate onto the JPEG map chunks in a pixel-perfect way? Well what I've got so far is this: The basic coordinate system is based on the map width/height (15x15 sectors is standard) and 64x64 tiles per sector. This means a 960x960 coordinate system is used in MOB files. So far it seems the map is centered on 480,480 or 480.5,480.5. At least my experiments had some encouraging results in that direction. I get nearly pixel-perfect placement of objects near the 480,480 location, so small maps look quite good. On larger maps however, objects seem to "deviate" from the their correct location, so I must've made some form of mistake when I set up my matrices. Here is what I am using: Code: Matrix projection = Matrix.OrthoRH(w, h, 0, 3500); I got this from reverse engineering temple.dll. In temple.dll, it did a translation by 0.5 on the Z axis, but I removed this since I don't know why they've done that. To set up my view matrix, I use the following code: Code: Vector3 eye = new Vector3(0, 0, 2500); Matrix rotEye = Matrix.RotationAxis(new Vector3(1, -1, 0), Deg2Rad(-45)); eye = new Vector3(camPosition, 0) + Vector3.TransformCoordinate(eye, rotEye); Vector3 lookat = new Vector3(camPosition, 0); Matrix view = Matrix.LookAtRH(eye, lookat, new Vector3(-0.5f, -0.5f, 0)); What this basically means is, that I compute the eye and lookAt vectors by rotating the view by 45°. The original temple.dll used a conconation like this: Code: Matrix projection = Matrix.Translation(0.0f, 0.0f, 0.5f); projection = Matrix.OrthoLH(w, h, 0, 3628) * projection; projection = Matrix.RotationX(Deg2Rad(-45)) * projection; projection = Matrix.RotationY(Deg2Rad(135)) * projection; In the original disassembly, the radians value for 135 was more like 134.9997. But i *hope* this doesn't cause my problems. Basically the next issue is how to get the true coordinates out of a MOB coordinate like 480,480. Basically there seems to be a constant factor by which all coordinates are multiplied. This is likely the "side-length" of a tile in pixels. I am using 28, which seems to work out okay. But it's possible the ToEE developers used a different values and this causes issues for me. I am puzzled why 28 works so well, since each tile is divided into 3x3 tiles for sector visibility and 28 is not a multiple of 3 :/ I'll continue to experiment until I find a solution but this coordinate system thing really bugs me. My impression is that the troika team just jiggled their projection and view matrices until they fit... more or less... Cu, Storm
Some images to show what I am talking about: To the north-east of the map center: (Click for larger version) At the center: (Click for larger version) To the south-west of the map center: (Click for larger version) You can see in the images, that at the center of the map, the overlay and object placement is accurate in relation to the background-map. (Especially if you look at the tree-shadow, which is part of the background). To the north-east, the overlay is too far left and to the south-west it's too far east. So I am doing something wrong :/ Cu, Storm
I think the best person to talk to may be Agetian since he built the ToEE WorldBuilder tool for Co8 which can split and recombine maps. All I know is that if it pixel size is not perfect (compared to the dimensions the game thinks the map should be) when making a new map/zone, it either: 1) Causes a CTD 2) Causes the entire map to be black (more common) Not sure if it helps, but here are the instructions to make a new map. http://www.co8.org/forum/showthread.php?t=1323
This is not my area of expertise (not that I even have one), but I can tell you that 480,480 is indeed always the center of a map. [edit] Goofyness can also arise if the image isn't 96 dpi, though I don't believe that's at play here as far as DarkStorm's inquiry goes.
Thanks for your replies. The main problem is that the JPEG chunks use a normal 2d coordinate system and no isometric projection, while the game objects are placed in the isometric coordinate system. And if the projection from one coordinate system to the other isn't perfect, the object placement gets worse and worse the further away you get from the origin (480,480 in this case, since the 2d map is positioned in relation to that point). I am experimenting with it a bit. Interestingly enough, my positioning works best if I place the exact center of the map on 480.5, 481.5. That *may* be an arbitrary choice on Troika's part or I am doing something wrong elsewhere... *edit* followup question on the map size: I've used some guess-work to get the dimensions of the full JPEG map. Is width=66, height=70 correct for this? What i mean is: What is the highest x,y coordinate for a Map Chunk? (I mean the x and y encoded in the map chunk filename). Cu, Storm
I got it!!!! (I think) Basically I reverted back to the original matrix used by ToEE (almost at least): Code: Matrix projection = Matrix.Translation(0.0f, 0.0f, 0.5f); projection = Matrix.OrthoRH(w, h, 0, 3628) * projection; (This didn't change) Code: Matrix view = Matrix.RotationX(-0.77539754f); // Roughly -45° view = Matrix.RotationY(2.3561945f) * view; // Roughly 135° Matrix m = Matrix.Identity; m.M22 = 0; m.M23 = 1; m.M33 = 0; m.M32 = 1; view = m * view; // Switch Y and Z coordinates view = Matrix.Translation(-new Vector3(camPosition, 0)) * view; // Move the Cam I also discovered through some more reverse engineering what the side-length of a tile in ToEE is: 28.2842703 They multiply all over the place with that number. And always two times in short succession (Most likely x and y). To back up my theory, screenshots at the same locations as above: As you can see, the SVB overlay matches the background map. I also checked the clipping geometry and it fits almost perfectly everywhere on the homlett map (Jaroos house is off a little to the left, but that may be an error made by troika, not me). Other constants I assumed and have to verify for maps other than Homlett: MAX_JPEG_CHUNKS_X = 66 (Used to determine the center of the 2d background) MAX_JPEG_CHUNKS_Y = 71 (Used to determine the center of the 2d background) Map is centered on (480,481) Cu, Storm *edit*: You may notice I killed the models. But that should be comparably easy to fix, so don't worry about that.
I think you had a question about map limits. I believe the game gets those from a data/rules/MapLimits.mes A line such as: {5091}{1020,-12544,-780,-14084} {5091} refers to the map # (which corresponds to other files) {1020,-12544,-780,-14084} refers to the map size (I think) Whenever I make a new map I take the Verb map into Photoshop, put my map ontop of it (new layer) and then save the new JPG. This retains the Verb map dimensions perfectly and allows me me to use Verbs dimension data ({1020,-12544,-780,-14084} or whatever it would be) for my new map without any screw ups. Honestly, your over my head on a lot of this so I dont know if I am helping.
I still have to check all maps, but I think the main stuff is already done. I still have to check the MapLimits.mes, but personally I wouldn't implement scrolling that way. I would just allow scrolling until you hit an area where no JPEG chunks are defined. But for completenesses sake I'll see if I can make sense of MapLimits.mes. Cu, Storm