Collision Map Data

EQ2Emulator Development forum.

Moderator: Team Members

Andrew
Retired
Posts: 71
Joined: Fri Dec 14, 2007 8:33 am
Location: England
Contact:

Collision Map Data

Post by Andrew » Thu Jan 17, 2008 4:48 am

This used to be about drowning but since I have discovered that the hit files are just for collision data, I have renamed my thread.
As "backburner" thing I was wondering if anyone had figured out how drowning worked and could place information in here on the topic.
I didn't see the client communicating anything to the server about the fact they had gone underwater, etc.
So I am wondering how the server knows if you are underwater or not. I think this issue is important as it also effects how we keep underwater NPCs.. well, under the water! :)
Any ideas?
Last edited by Andrew on Sun Feb 17, 2008 1:47 pm, edited 1 time in total.

CrabClaw
Retired
Posts: 88
Joined: Wed Aug 01, 2007 10:49 am
Location: Seattle

Post by CrabClaw » Thu Jan 17, 2008 11:58 am

I do see the bar come up, so there must be something going on. Maybe they do it client side? It seems the state is reached after your go a set distance from the surface and you can hover just below the surface without drowning, then when you cross over into another zone then you are placed in the underwater state. Kinda like:
-----<water surface>------
normal swimming zone
-------<subsurface>-------
totally underwater zone

LethalEncounter
Team: Zombie
Posts: 2717
Joined: Wed Jul 25, 2007 10:10 pm

Post by LethalEncounter » Thu Jan 17, 2008 4:18 pm

If EQ2 works like the original EQ, then the server is expected to know where water boundaries are located. This was a major problem in EQEmu because obviously we had no easy way of determining if the client was in water.

Andrew
Retired
Posts: 71
Joined: Fri Dec 14, 2007 8:33 am
Location: England
Contact:

Post by Andrew » Thu Jan 17, 2008 8:41 pm

The way I am assuming it works is something along the lines of detecting if a player is within the bounds of a plane and then seeing if they are above or below it.
Image
Let the dot in the top left corner be point1 and the red dot in the bottom right be point2.

Code: Select all

if (player.x > point1.x && player.x < point2.x) {
   if (player.y > point1.y && player.y < point2.y) {
       if (player.z < point1.z && player.z > point2.z) {
           // insert drowning timer
       }
   }
}
That's kinda how a figured it would work? Means a lot of data entry though.

User avatar
alfa
Team Member
Posts: 550
Joined: Fri Jul 27, 2007 6:24 pm
Location: France
Contact:

Post by alfa » Fri Jan 18, 2008 5:44 am

Maybe on offi they just use geodata system no ?
Fight with me... Or die, like the rest.
J.A. say: "I think Xinux tried to tell me this, but I ignore most things he suggests."

CrabClaw
Retired
Posts: 88
Joined: Wed Aug 01, 2007 10:49 am
Location: Seattle

Post by CrabClaw » Fri Jan 18, 2008 11:11 am

Yes probably, because they do have entrances that are lower than global water table, like the gnoll caves under Antonica.

Andrew
Retired
Posts: 71
Joined: Fri Dec 14, 2007 8:33 am
Location: England
Contact:

Post by Andrew » Sat Jan 19, 2008 6:04 pm

I figure we can use the .hit files that are compressed in the .vpk files for collision data.
I used an extractor to take out the .hit files from a .vpk and then inspected the file format.

A perl version of the extracter is available from here
I've never done this before, but this is what I have come up with. I compared different .hit files and found the similarities in their structure.

Code: Select all

0F 56 65 43 6F 6C 69 73 69 6F 6E 4D 65 73 68 02 - Start of file, no idea
    HEX      ASCII  My best guess
48 49 54 20 - HIT  - Maybe an ID?
56 49 44 58 - VIDX - Vertex ID
22 00 23 00 - ".#. - ???  					
45 49 44 58 - EIDX - Edge ID
22 00 23 00 - ".#. - ???
46 49 44 58 - FIDX - Face ID		
22 00 23 00 - ".#. - ???	
56 45 52 54 - VERT - Vertex data			
45 44 47 45 - EDGE - Edge data
22 00 23 00 - ".#. - ???
46 41 43 45 - FACE - Polygon
4C 45 41 46 - LEAF - Leaf / Branches (used to connect different .hit files?)
42 52 41 4E - BRAN - Branch?
42 44 52 59 - BDRY - Boundry??
It looks like a 3D file format. If anyone could give me some help I would appreciate it. :)
Last edited by Andrew on Mon Jan 21, 2008 7:13 am, edited 2 times in total.

User avatar
alfa
Team Member
Posts: 550
Joined: Fri Jul 27, 2007 6:24 pm
Location: France
Contact:

Post by alfa » Sat Jan 19, 2008 6:12 pm

Andrew wrote:I figure we can use the .hit files that are compressed in the .vpk files for collision data.
So that mean we can extract collision file and make a geodata engine (like mangos and VMap) ?
Fight with me... Or die, like the rest.
J.A. say: "I think Xinux tried to tell me this, but I ignore most things he suggests."

Andrew
Retired
Posts: 71
Joined: Fri Dec 14, 2007 8:33 am
Location: England
Contact:

Post by Andrew » Sun Jan 20, 2008 9:19 am

alfa wrote:So that mean we can extract collision file and make a geodata engine (like mangos and VMap) ?
The client can already walk around and knows it is in water so there must be a files on the client that provides this.
If I am correct, the files already provide the data we need so we wouldn't need to generate data using the hit files, just load them up. :)

Riven
Retired
Posts: 113
Joined: Thu Aug 30, 2007 3:11 am
Location: Spain

Post by Riven » Tue Jan 22, 2008 12:56 am

I'm very sure that client knows every type of terrain. Server spawn certain harvestable nodes on certain terrain, mobs in water don't attack you if you go out of the water (not all as there are mobs that are amfibious), etc...

Andrew
Retired
Posts: 71
Joined: Fri Dec 14, 2007 8:33 am
Location: England
Contact:

Post by Andrew » Sat Feb 02, 2008 6:49 am

Thanks to LE we have been able to extract the data from the hit files.
Now I have been currently working on trying to figure out how the model can be converted into something we can use for physics.
I believe it to be some combination of the vertex data and edge data, although I don't quite understand the format and why they have included so much extra data such as the FACE values.
Someone I was talking to earlier about this format mentioned it could be a convex hull description, but I haven't had the time to research into it.
Here is an example below of the data extracted.

Code: Select all

BDRY Data: 
1406.45, -84.3873, -477.411, 1517.16, 95.6937, -21.015, 251.482
BRAN Data: 
-249.213 | 1 | -4 | 2, -363.312 | -2 | -3 | 2
EDGE Data: 
2 -> 0, 
0 -> 1, 
1 -> 2, 
1 -> 3, 
3 -> 2, 
4 -> 2, 
3 -> 4, 
5 -> 2, 
4 -> 5, 
4 -> 6, 
6 -> 5, 
7 -> 5, 
6 -> 7, 
6 -> 8, 
8 -> 7, 
9 -> 7, 
8 -> 9, 
8 -> 10, 
10 -> 9, 
11 -> 9, 
10 -> 11, 
10 -> 12, 
12 -> 11, 
13 -> 11, 
12 -> 13, 
12 -> 14, 
14 -> 13, 
15 -> 13, 
14 -> 15, 
14 -> 16, 
16 -> 15, 
14 -> 17, 
17 -> 16, 
18 -> 16, 
17 -> 18, 
19 -> 16, 
18 -> 19, 
22 -> 20, 
20 -> 21, 
21 -> 22, 
21 -> 23, 
23 -> 22, 
24 -> 22, 
23 -> 24, 
25 -> 22, 
24 -> 25, 
24 -> 26, 
26 -> 25, 
27 -> 25, 
26 -> 27, 
26 -> 28, 
28 -> 27, 
26 -> 29, 
29 -> 28, 
30 -> 28, 
29 -> 30, 
29 -> 31, 
31 -> 30, 
32 -> 30, 
31 -> 32, 
33 -> 30, 
32 -> 33, 
32 -> 34, 
34 -> 33, 
35 -> 33, 
34 -> 35, 
34 -> 36, 
36 -> 35, 
37 -> 35, 
36 -> 37, 
36 -> 0, 
0 -> 37, 
36 -> 1
EIDX Data: 
0 -> 1, 
2 -> 2, 
3 -> 4,
5 -> 4, 
6 -> 7, 
5 -> 8, 
8 -> 9, 
10 -> 11, 
10 -> 12, 
12 -> 13, 
14 -> 15, 
14 -> 16, 
16 -> 17, 
18 -> 19, 
18 -> 20, 
20 -> 21, 
22 -> 23, 
22 -> 24, 
24 -> 25, 
26 -> 27, 
26 -> 28, 
28 -> 29, 
30 -> 29, 
31 -> 32, 
33 -> 32, 
34 -> 35, 
33 -> 36, 
37 -> 38, 
39 -> 39,
40 -> 41, 
42 -> 41, 
43 -> 44, 
42 -> 45, 
45 -> 46, 
47 -> 48, 
47 -> 49, 
49 -> 50, 
51 -> 50, 
52 -> 53, 
54 -> 53, 
55 -> 55, 
56 -> 57, 
58 -> 57, 
59 -> 60, 
58 -> 61, 
61 -> 62, 
63 -> 64, 
63 -> 65, 
65 -> 66, 
67 -> 68, 
67 -> 69, 
70 -> 71, 
69 -> 1, 
70 -> 72
FACE Data: 
0 -> 0, 
768 -> 3, 
3 -> 768, 
6 -> 6, 
768 -> 9, 
9 -> 768, 
12 -> 12, 
768 -> 15, 
15 -> 768, 
18 -> 18, 
768 -> 21, 
21 -> 768, 
24 -> 24, 
768 -> 27, 
27 -> 768, 
30 -> 30, 
768 -> 33, 
33 -> 768, 
36 -> 36, 
768 -> 39, 
39 -> 768, 
42 -> 42, 
768 -> 45, 
45 -> 768, 
48 -> 48, 
768 -> 51, 
51 -> 768, 
54 -> 54, 
768 -> 57, 
57 -> 768, 
60 -> 60, 
768 -> 63, 
63 -> 768, 
66 -> 66, 
768 -> 69,
69 -> 768, 
72 -> 72, 
768 -> 75, 
75 -> 768, 
78 -> 78, 
768 -> 81, 
81 -> 768, 
84 -> 84, 
768 -> 87, 
87 -> 768, 
90 -> 90, 
768 -> 93, 
93 -> 768, 
96 -> 96, 
768 -> 99, 
99 -> 768, 
102 -> 102, 
768 -> 105, 
105 -> 768
FIDX Data: 
18 -> 19, 
20 -> 21, 
22 -> 23, 
24 -> 25, 
26 -> 27, 
0 -> 1, 
2 -> 3, 
26 -> 27, 
28 -> 29, 
30 -> 31, 
32 -> 33, 
34 -> 35, 
2 -> 3, 
4 -> 5, 
6 -> 7, 
8 -> 9, 
10 -> 11, 
12 -> 13, 
14 -> 15, 
16 -> 17
LEAF Data: 
0, 0, 10, 10, 0, 14, 24, 0, 16
VIDX Data: 
0 -> 1, 
2 -> 1, 
3 -> 2, 
2 -> 3, 
4 -> 2, 
4 -> 5, 
4 -> 6, 
5 -> 5, 
6 -> 7, 
6 -> 8, 
7 -> 7, 
8 -> 9, 
8 -> 10, 
9 -> 9, 
10 -> 11, 
10 -> 12, 
11 -> 11, 
12 -> 13, 
12 -> 14, 
13 -> 13, 
14 -> 15, 
14 -> 16, 
15 -> 14, 
17 -> 16, 
16 -> 17, 
18 -> 16, 
18 -> 19, 
20 -> 21, 
22 -> 21, 
23 -> 22, 
22 -> 23, 
24 -> 22, 
24 -> 25, 
24 -> 26, 
25 -> 25, 
26 -> 27, 
26 -> 28, 
27 -> 26, 
29 -> 28, 
28 -> 29, 
30 -> 29, 
31 -> 30, 
30 -> 31, 
32 -> 30, 
32 -> 33, 
32 -> 34, 
33 -> 33, 
34 -> 35, 
34 -> 36, 
35 -> 35, 
36 -> 37, 
0 -> 37, 
36 -> 0, 
36 -> 1
VERT Data: 
1465.29, 95.6771, -273.585, 
1465.29, -84.3873, -273.585, 
1466.07, 95.6747, -255.862, 
1466.07, -84.3873, -255.862, 
1457.78, -78.3065, -243.112, 
1457.78, 95.6768, -243.112, 
1459.17, -72.2256, -222.739, 
1459.17, 95.6788, -222.739, 
1462.64, -66.1448, -154.286, 
1462.64, 95.6808, -154.286, 
1458.37, -60.0639, -107.949, 
1458.37, 95.6829, -107.949, 
1439.65, -53.9831, -65.4345, 
1439.65, 95.6849, -65.4345, 
1412.54, -47.9022, -55.9909, 
1412.54, 95.6869, -55.9909, 
1406.45, 95.6889, -39.5724, 
1406.45, -47.9022, -39.5724, 
1411.2, -47.9022, -21.015, 
1411.2, 95.689, -21.015, 
1494.37, 95.6733, -477.411, 
1494.37, -84.3873, -477.411, 
1517.16, 95.6679, -432.342, 
1517.16, -84.3873, -432.342, 
1498.52, -84.3873, -418.828, 
1498.52, 95.6926, -418.828, 
1493.74, -84.3873, -397.718, 
1493.74, 95.6937, -397.718, 
1493.5, 95.6912, -368.558, 
1493.5, -84.3873, -368.558, 
1486.81, 95.6543, -341.136, 
1486.81, -84.3873, -341.136, 
1464.57, -84.3873, -330.983, 
1464.57, 95.6658, -330.983, 
1452.38, -84.3873, -319.967, 
1452.38, 95.6689, -319.967, 
1454.75, -84.3873, -294.927, 
1454.75, 95.6781, -294.927
and here is the source to extract data from the hit files.

Code: Select all

#include <iostream>
#include <fstream>
#include <map>
#include <vector>
using namespace std;
struct hit_data{
	short val1;
	short val2;
	float val3;
	short  val4;
};
int main(int argc, char** argv)
{
	map<string, vector<hit_data*> > data;
	char name[5] = {0};
	char buffer[4];
	unsigned long length = 0;
	int offset = 0;
	hit_data* hd = 0;
	fstream binary_file("test.hit",ios::binary|ios::in);
	binary_file.seekp(27);
	binary_file.read(name,4);
	do{
		binary_file.read(buffer, 4);
		memcpy(&length, buffer, 4);
		for(unsigned long i=0;i<length;i+=offset){
			hd = new hit_data;
			if(strcmp(name, "LEAF") != 0 && strcmp(name, "BRAN") != 0 && strcmp(name, "BDRY") != 0 && strcmp(name, "VERT") != 0){
				binary_file.read(buffer, 4);
				memcpy(&hd->val1, buffer, 2);
				memcpy(&hd->val2, buffer +2, 2);
				offset = 4;
			}
			else if(strcmp(name, "LEAF") == 0){
				binary_file.read(buffer, 2);
				memcpy(&hd->val1, buffer, 2);
				offset = 2;
			}
			else if(strcmp(name, "BDRY") == 0 || strcmp(name, "VERT") == 0){
				binary_file.read(buffer, 4);
				memcpy(&hd->val3, buffer, 4);
				offset = 4;
			}
			else{
				binary_file.read(buffer, 4);
				memcpy(&hd->val3, buffer, 4);
				binary_file.read(buffer, 4);
				memcpy(&hd->val1, buffer, 2);
				memcpy(&hd->val2, buffer +2, 2);
				binary_file.read(buffer, 1);
				memcpy(&hd->val4, buffer, 1);
				offset = 9;
			}
			data[string(name)].push_back(hd);
		}
		binary_file.read(name,4);
	} while(!binary_file.eof());
	binary_file.close();
	map<string, vector<hit_data*> >::iterator itr;
	for(itr = data.begin();itr != data.end(); itr++){
		cout << itr->first << " Data: " << endl;
		for(unsigned long i=0;i<itr->second.size();i++){
			if(i>0)
				cout << ", ";
			if(strcmp(itr->first.c_str(), "LEAF") != 0 && strcmp(itr->first.c_str(), "BRAN") != 0 && strcmp(itr->first.c_str(), "BDRY") != 0 && strcmp(itr->first.c_str(), "VERT") != 0){
				cout << itr->second[i]->val1 << " -> " << itr->second[i]->val2;
			}
			else if(strcmp(itr->first.c_str(), "LEAF") == 0)
				cout << itr->second[i]->val1;
			else if(strcmp(itr->first.c_str(), "BDRY") == 0 || strcmp(itr->first.c_str(), "VERT") == 0)
				cout << itr->second[i]->val3;
			else
				cout << itr->second[i]->val3 << " | " << itr->second[i]->val1 << " | " << itr->second[i]->val2 << " | " << itr->second[i]->val4;
		}
		cout << endl;
	}
	return 0;
}
After you have compiled the source, name your hit file "test.hit".

Andrew
Retired
Posts: 71
Joined: Fri Dec 14, 2007 8:33 am
Location: England
Contact:

Post by Andrew » Tue Feb 05, 2008 6:31 pm

Figured out the vertex format.
Image
There are a few problems. I didn't use all the data so it doesn't render correctly due to extra edges between two verts which are actually not suppose to have an edge but are suppose to begin a new piece of geometry.
This one looks good though. :D

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Post by John Adams » Wed Feb 06, 2008 4:01 pm

What happens when you run out of air in EQ2Emulator?
As LE said, in EQ(1)Emulator, it was built-in boundaries in the zone file itself (evidence of this in using OpenZone to create custom zone files). As for the burning/drowning, that is a good question. Perhaps the client knows when you are out of air (all sorted out locally) and sends a "drown this fooker" OpCode to the server, which then kills you.
But it's interesting indeed. I'd like to drown or fry a few players.
John Adams
EQ2Emulator - Project Ghost
"Everything should work now, except the stuff that doesn't" ~Xinux

User avatar
Arremis
Retired
Posts: 388
Joined: Sun Sep 02, 2007 10:11 am
Location: Memphis, TN

Post by Arremis » Thu Feb 07, 2008 6:03 am

John Adams wrote:I'd like to drown or fry a few players.
Two new GM commands:
/gmwrathwater playername (teleports the player to the middle of the nearest ocean and roots them to the bottom with a block of cement on their feet)
/gmwrathfire playername (hurls a chunk of Luclin at the player that explodes in a burst of fire and brimstone)
:D

User avatar
ZexisStryfe
Posts: 1026
Joined: Thu Jul 26, 2007 6:39 am
EQ2Emu Server: Sytherian Legends
Location: Connecticut
Contact:

Post by ZexisStryfe » Thu Feb 07, 2008 6:49 am

Arremis wrote: Two new GM commands:
/gmwrathwater playername (teleports the player to the middle of the nearest ocean and roots them to the bottom with a block of cement on their feet)
/gmwrathfire playername (hurls a chunk of Luclin at the player that explodes in a burst of fire and brimstone)
That is freakin hilarious! :twisted:

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests