Neverwinter Nights/Research

From xoreos Wiki
Jump to navigation Jump to search

Lighting

original NWN for linux uses:

glLightModelfv(pname = GL_LIGHT_MODEL_AMBIENT, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT1, pname = GL_AMBIENT, params = {0.160784, 0.160784, 0.160784, 1})
glLightfv(light = GL_LIGHT1, pname = GL_DIFFUSE, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT1, pname = GL_SPECULAR, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT1, pname = GL_POSITION, params = {4000, 4500, 7000, 1})
glLightfv(light = GL_LIGHT1, pname = GL_QUADRATIC_ATTENUATION, params = &4.5e-10)
glLightfv(light = GL_LIGHT2, pname = GL_AMBIENT, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT2, pname = GL_DIFFUSE, params = {1.75, 1.5, 1, 1})
glLightfv(light = GL_LIGHT2, pname = GL_SPECULAR, params = {1.75, 1.5, 1, 1})
glLightfv(light = GL_LIGHT2, pname = GL_POSITION, params = {16.43526, 8.189793, 2.922178, 1})
glLightfv(light = GL_LIGHT2, pname = GL_QUADRATIC_ATTENUATION, params = &0.02543954)

or

glLightfv(light = GL_LIGHT1, pname = GL_AMBIENT, params = {0.160784, 0.160784, 0.160784, 1})
glLightfv(light = GL_LIGHT1, pname = GL_DIFFUSE, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT1, pname = GL_SPECULAR, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT1, pname = GL_POSITION, params = {4000, 4500, 7000, 1})
glLightfv(light = GL_LIGHT1, pname = GL_QUADRATIC_ATTENUATION, params = &4.5e-10)
glLightfv(light = GL_LIGHT2, pname = GL_AMBIENT, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT2, pname = GL_DIFFUSE, params = {1.75, 1.5, 1, 1})
glLightfv(light = GL_LIGHT2, pname = GL_SPECULAR, params = {1.75, 1.5, 1, 1})
glLightfv(light = GL_LIGHT2, pname = GL_POSITION, params = {16.43526, 8.189793, 2.922178, 1})
glLightfv(light = GL_LIGHT2, pname = GL_QUADRATIC_ATTENUATION, params = &0.02543954)
glLightfv(light = GL_LIGHT3, pname = GL_AMBIENT, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT3, pname = GL_DIFFUSE, params = {1.3, 1.92, 1.82, 1})
glLightfv(light = GL_LIGHT3, pname = GL_SPECULAR, params = {1.3, 1.92, 1.82, 1})
glLightfv(light = GL_LIGHT3, pname = GL_POSITION, params = {14.99999, 4.999998, 5, 1})
glLightfv(light = GL_LIGHT3, pname = GL_QUADRATIC_ATTENUATION, params = &0.045)
glLightfv(light = GL_LIGHT4, pname = GL_AMBIENT, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT4, pname = GL_DIFFUSE, params = {2, 0.5, 0.2, 1})
glLightfv(light = GL_LIGHT4, pname = GL_SPECULAR, params = {2, 0.5, 0.2, 1})
glLightfv(light = GL_LIGHT4, pname = GL_POSITION, params = {14.02705, 2.55035, 4, 1})
glLightfv(light = GL_LIGHT4, pname = GL_QUADRATIC_ATTENUATION, params = &0.18)
glLightfv(light = GL_LIGHT5, pname = GL_AMBIENT, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT5, pname = GL_DIFFUSE, params = {0.1847787, 0.1847787, 0.09828652, 1})
glLightfv(light = GL_LIGHT5, pname = GL_SPECULAR, params = {0.1847787, 0.1847787, 0.09828652, 1})
glLightfv(light = GL_LIGHT5, pname = GL_POSITION, params = {14.9855, 1.83074, 1.62787, 1})
glLightfv(light = GL_LIGHT5, pname = GL_QUADRATIC_ATTENUATION, params = &0.09183674)
glLightfv(light = GL_LIGHT6, pname = GL_AMBIENT, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT6, pname = GL_DIFFUSE, params = {0.1847787, 0.1847787, 0.09828652, 1})
glLightfv(light = GL_LIGHT6, pname = GL_SPECULAR, params = {0.1847787, 0.1847787, 0.09828652, 1})
glLightfv(light = GL_LIGHT6, pname = GL_POSITION, params = {5, 15, 5, 1})
glLightfv(light = GL_LIGHT6, pname = GL_QUADRATIC_ATTENUATION, params = &0.045)
glLightfv(light = GL_LIGHT7, pname = GL_AMBIENT, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT7, pname = GL_DIFFUSE, params = {0.196573, 0.1474298, 0.05897192, 1})
glLightfv(light = GL_LIGHT7, pname = GL_SPECULAR, params = {0.196573, 0.1474298, 0.05897192, 1})
glLightfv(light = GL_LIGHT7, pname = GL_POSITION, params = {5, 5, 5, 1})
glLightfv(light = GL_LIGHT7, pname = GL_QUADRATIC_ATTENUATION, params = &0.045)

for light0 the following is used:

glLightModelfv(pname = GL_LIGHT_MODEL_AMBIENT, params = {1, 1, 1, 1})
glLightfv(light = GL_LIGHT0, pname = GL_AMBIENT, params = {0, 0, 0, 1})
glLightfv(light = GL_LIGHT0, pname = GL_DIFFUSE, params = {1, 1, 1, 1})
glLightfv(light = GL_LIGHT0, pname = GL_POSITION, params = {0, 0, 742.4, 1})

Walkmesh

The way nwn determines where a character/creature can or cannot walk seems to involve two different parts: a mesh and AABB[1] for collision detection. Those two parts can be found in a tile model ".mdl" and is associated ".wok" file (an ASCII file). The data in the model and in the wok seems to be almost redundant: slightly different at the mesh level.

Mesh

The mesh can be found in both the mdl and the wok. In the mdl, it can be found as a normal mesh in the node that contains both AABB and mesh flags. Each face of the mesh have a smooth property that can be related to a specific material. The material properties is in the "surfacemat.2da" file where the index is the smooth value. The 2da file contains two columns with boolean values, "Walk" and "WalkCheck", that should surely indicates where one can walk or not.

AABB

Similarly to the mesh, AABBs can be found in the model in the same node and directly in the wok file. AABBs come as a binary tree, each leaf from that tree is related to a specific face from the walkmesh and surrounds it. It is the part_number_leaf_face[2] property that relates to the face.

Difference between mdl and wok

The shape of the mesh in the mdl and the wok are the same though the number of vertices differs. In deed, in the mdl one can find more or less three times the number of vertices regarding the wok. In fact, almost each face in the mdl has its own vertices, only a few share some vertices.

About AABB, it seems they are the same in both files.

How it could work

There are two cases. First, when the user want to know where he can/cannot go by moving the cursor. In this case, the intersection between the ray coming from the camera and the AABB tree will give a AABB leaf node, its related face and thus if it is walkable or not. Second, when a creature want to move, it needs to know if it can, what sound should be played and the vertical position of the creature. The intersection in the XY plan of the creature's bounding box and the AABB tree should give similarly as the former case if the creature can be moved. For the vertical position, one hypothesis would be that it is given from the intersection between the XY position of the creature and the related face from the AABB leaf node.