Neverwinter Nights/Research
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.