| 10-21-2003, 03:19 PM | #1 |
Here's the basic layout of the problem I'm having. I need a piece of code that will return two things, the first is whether or not a point on the map contains a cliff face, and what angle the cliff is facing. The inputs that I have are: -Height of any point on the map -Slope of any point on the map (slope of a cliff is 45 degrees) -Level of any point on the map For those that don't already know, a 32x32 map has a grid made just like a 3d model, basically it's a big box, divided into 32x32 smaller polygons, each one split diagonally into two triangles. Therefore the map has 33x33 points on it each of which is a corner of a triangle. Each of these points then has a level and a custom height, therefore the visual height of each point is (height = 128 x level + custom height change), each level is just 128 units high. Cliffs are in no way identified so I think war3 does it's own calculations to find out where they are using the difference in level between two points. The reason I need these two points of information is one, to limit a unit's movement (it is a flying unit that represents a ground unit) and two to properly calculate the angle of a projectile that would bounce off a cliff face (in this case the projectile being a vehicle). Suggestions of any kind are appreciated, if you're lazy code is unnecessary I can figure it out myself, a simple expression showing the general idea would be enough. Thank you all in advance. =) |
| 10-21-2003, 07:21 PM | #2 | |
I found a quote by Brett Wood: Quote:
Edit: I hope I understood your question correctly. emote_sweat |
| 10-21-2003, 09:07 PM | #3 |
It's possible to detect cliffs (I have developed this script) and probably, ground height. Myscript detects not only cliffs, but non-destructable doodads. There's no JASS function allows you to detect cliff or non-destructable doodad. Detection is posible but is really tricky. Also I have ideas about calculating ground height. I am member of Russian team - developers of map called 'Graveyard'. This is very interesting project I guess. But there's one rule - until this map is not completed none of team members allowed to publish scripts or triggers used in that map. So I can only attach screenshot where rocket impacts NON-destructable doodad and explodes. Rocket "detects" any unit / cliff / doodad. Map is near completed so wait few weeks - and I will publish map and scripts with comments. Ground-height algorythm is not included to 'Graveyard' so I can publish JASS script or idea... I'm not sure this algorythm will work but it seems no another way to calculate groung height. P.S. I have very detailed JASS faq with many examples every-string-commented. But it still not translated into English... Anybody there needs another FAQ? P.P.S. Sorry, but I think my English is not good enough so if you find mistakes in my posts please don't be so captious. |
| 10-22-2003, 05:09 AM | #4 |
I think alot of you misunderstand the problem, I have alreade Made my own JASS function that gets the terrain height (At the end of this post I'll explain) but I was giving those to everyone saying you "can" do this and knowing that you can how would you go about finding where a cliff was located. Cacodemon, could you please describe How you detected cliffs? And also if your detection meathod can in any way detect which way the cliffs are facing? Note, you're meathod wouldn't happen to place a ground unit at a location, and if the unit is not at that exact location when it spawns, the location it is at is a non-destructible doodad or cliff? (If you can't even answer that then nvm =D) Now for the description of how to get height: The basic idea I have to say is not mine, it was introduced to me by Ari when I was chatting to him about something or other and he told me he'd created a way to detect height for the FPSmod. Naturally I was interested and he told me that the way a map stores its height is in a file contained in the w3x called war3Map.w3e. This file is a binary data file which contains a short heading giving things like the tilesets, map size, etc etc. What's important though is what follows afterwards, in this case being a list of gridpoints (as described above, 32x32 map has 33x33 gridpoints) and alot of information attached to them (if you are interested read Zepir's (I think) tutorial on reading the files within a w3x. Two of the points of data included in this listing is the level and height of each gridpoint. I created a short and simple program to calculate the height of each gridpoint and print out a .txt file that looks like this: set HeightArray[0] = "00000023005701280128...." (Chunks of 4 digits each being the height of a gridpoint) set HeightArray[1] = "00000000000001280128...." . . . So now I have the height of every single grid point on the map, the rest is a just a little math work. What you do is when the function is called with a location, you find inside of which grid box the location is, then find out whether it is in the top right or bottom left triange of the grid box (I don't remeber which way it's split diagonally but that's easy to check if you just raise 2 grid points right next to each other). The terrain of a warcraft 3 map works Exactly like a 3d model, it's made out of triangles and so if you have the height of the 3 points of the triangle you have the height of any point within the triangle. The rest is a simple matter of calculating the xslope (bottom left and right or top left and right grid points) and yslope (bottom and top left or bottom and top right grid point) and then multiplying them by how far to the right and up the location is from the bottom left grid point of the grid box the location is in. In this way I am able to find at any location on the map, the height. Note, this does not work with doodad ramps, and terrain ramps longer than one grid box (I have been too lazy to implement it and it's not common enough for me to waste time on now). Similarly I used a function very close to that one to calculate the slope of any point on the map along a certain angle. With all this I hope someone will have some ideas as to detect whether a cliff exists at a point and which way it is angled. This shouldn't be too hard because cliffs can only be either horozontal vertical or diagonal, no weird angles. But I'm a little thought out to figure it out myself, and busy with alot of other work. Once again thank you, and all help is very appreciated. |
| 10-22-2003, 02:47 PM | #5 |
If I understood you correct, then you want to check if location X is located on the egde of a cliff (or very close to). If I'm right, then this should (untested). Code:
function IsLocationCliff takes location loc returns boolean
local real offset = 64.0 // The "size" of a cliff
local integer h = TerrainCliffHeight(loc)
local location l
set l = PointOffset(loc, offset, 0)
if (TerrainCliffHeight(l)!=h) then
return true
endif
set l = PointOffset(loc, -offset, 0)
if (TerrainCliffHeight(l)!=h) then
return true
endif
set l = PointOffset(loc, 0, offset)
if (TerrainCliffHeight(l)!=h) then
return true
endif
set l = PointOffset(loc, 0, -offset)
if (TerrainCliffHeight(l)!=h) then
return true
endif
return false
endfunction |
| 10-22-2003, 05:26 PM | #6 |
Ok, but I can't send you that script until Graveyard map is finished. Algorythm depends on way you want it to be used. There's two ways to detect cliffs and non-destructable doodads. Both algorythms use Warcraft core to detect objects. Idea - if you want to detect cliff/non-destructable doodad (NDD) in location at first you should set desired location to location-type variable. Then create dummy unit in that location or move existing unit there. Unit MUST have collision size MORE than 0 - collision size depends on precision. If doodad / another unit / cliff exists in desired location, Warcraft moves unit to nearest 'free' point, so distance between unit position and location, stored in variable (destination) will be MORE than 0. Else, that distance will be equal to 0. That's all. 1. Impact Cliff Detection - my 'rocket' algorythm utilizes this idea. It calculates trajectories for rockets and grenades every 0.05 seconds then writes calculated locations to location array. Note - you should use global declared array because local variables couldn't be used correctly with periodic events. On execution it calculates next location, stores it in array and moves rocket to that location. On next execution algorythm compares distance between current position of rocket and location stored in array (for example, array index = rocket number). If distance not equal to 0, this means collision so rocket explodes! If you want to detect cliffs you should move your unit to SMALL distances or you have chance to move your unit to cliff top / bottom and miss collision. 2. Distant cliff detection. You should create in desired locations custom units with transparent models (at first you should create your own mdls). Then analyze distances the same way. Idea about ground height calculation - I can guess only relative height calculation. Code:
B
/|
/ |
/ | Relative Height BC = SQRT(AB^2-AC^2)
/ |
A /____|C
This algorythm will works only for MOVING units! You should create periodic event with 0.2-1 sec. period. Longer period you select - more precisious result will be. But period shouldn't be too long or this algorytm will calculate wrong height! AC - "flat" distance. This is distance unit walks when moves on flat surface. This distance between 2 points, A and B, calculated by calling DistanceBetweenPoints(A,B) function. First Argument (A) is unit position on previous execution (should be stored it in global variable or array!). Second argument (B) is current position of unit. AB = Unit_Speed / TimePeriod_Of_Your_Periodic_Event. I can't guess how to detect slope direction (up / down). Anyone has ideas? |
| 10-22-2003, 05:42 PM | #7 |
Kattana...yeah thanks, that'll work but it's a bit ennoying =(. Also doesn't help with my problem of finding the angle of the cliff. Caco...That works very nicely too, but not in my case, my main unit is an air unit because I need to change it's fly height for jumping =). As for the height solution feel free to use mine. I'm guessing you didn't read through everything that I wrote but it is a very good and almost 100% perfect (other than ramps) too. Also for your solution, if distance between points really Does take into account height, what you can do is pick a constant point A that you know is at 0 height, and always use that as your A, then C will be your unit's position, and DistanceBetweenPoints(A,C) will be your BC. |
| 10-22-2003, 05:52 PM | #8 |
So use second algorythm! Create dummy ground unit (invisible unit with transparent model or something alike) and 'test' points in front of your flying unit! About ground height. Distance between points ignores height! So it returns 'flat' distance - AC. But when unit walks on slope, travelled distance can be calculated AB = SpeedOfUnit/TravellingPeriod. Distances AC and AB are different! P.S. Sorry, my English isn't so good so I can misunderstand you :( |
| 10-22-2003, 06:19 PM | #9 |
Oh alright, I esli ploho po angliski, govori po ruskii =). |
| 10-22-2003, 06:28 PM | #10 |
Vot ne jdal.. Davay stuchis v asu 84141061 - a to flud ustraivaem tut :) Horosho no ya tak luchshe budu pisat po angliyski :) P.S. What about second algorythm? Is it useful for your task? |
| 10-22-2003, 07:05 PM | #11 |
Epigoni, I like your hard-core method....But :/ it's not really useful but for certain people/projects .... cause...the way i see it...it requires a 3'rd party program to be on during game... and/or a giant array in-game that stores EVERY point and it's data...which needs to be pre-compiled from a finished w3e file... (and a good proggy too). I see it important feat to sense cliffs and heights, and we DaKaN could have used it for KDH to create totally random-battle-field area generator. But the fact that it either req's a third party program for player to use, and/or this giant pre-compiled array that needs to be rebuilt every time you do a single modification to the terrain...And also the general parsing of the w3e file, and all the different calculations needed at run-time. Makes this a pretty hard-to-use solution to the problem, But yeah. About Cacodemon, :) your methods is pretty interesting and logical, but it's still a little-bit non-acurate and rather heavy to use, atleast for checking big area/many points. But yeah, good idea none-the-less. Btw, do you use periodics, or a waiting loop? Cubasis |
| 10-22-2003, 07:15 PM | #12 |
Boths methods require only periodic event because delay caused by wait function depends on numbers of triggers in queue and causes another troubles. And if you want this algorythm to be more precisious, just decrease period or unit collision size. And I can't guess another algorythm to detect both cliffs and NDDs (and units, of course)... If you want to detect ONLY cliffs you shoud insert aditional conditions. When I finish Graveyard project, I'll send map illustrating this algorythm so you could see that it isn't so heavy as it seems to be. |
| 10-22-2003, 08:00 PM | #13 |
yes, But what i would need to do is "analize" area. F.ex. check the area and see if there is enough of free space on it without cliffs/doodads to create a battle-field there, and such. Also, most unit instant-interactions can cause lag if used very much, like move-instantly, and "remove" instantly and such. Cubasis |
| 10-22-2003, 09:19 PM | #14 |
Yes, of course. But there's no another way... As for your task, you may try to create battle-field in loop, checking was this creation succesfull or not... If it was succesfull then exit, else you may try another coordinates... |
| 10-23-2003, 12:00 AM | #15 |
Cubasis40: Please write datailed description what you need - may I can advise you required JASS script... |
