Code :

// First I get the difference between the current mouse coords and the last. The html lock cursor api returns it and I store it in Game.Input.
this.yaw += Game.Input.x * this.sensitivity;
this.pitch += Game.Input.y * this.sensitivity;
// I cap the pitch and yaw
if (this.yaw < 0.0) this.yaw += 360.0;
if (this.pitch > 89.0) {
this.pitch = 89.0;
}
if (this.pitch < -89.0) {
this.pitch = -89.0;
}

Code :

// This is where I calculate the view matrix and use the pitch and yaw (by the way these are all matrices, JS doesn't really help specifying that)
var view = Mathf.Mat4();
var rotX = Mathf.rotateX(cam.pitch),
rotY = Mathf.rotateY(-cam.yaw),
rot = Mathf.mul(rotX, rotY),
pos = Mathf.translate(cam.x, cam.y, cam.z),
cam = Mathf.Mat4();
cam = Mathf.mul(rot, pos);
view = Mathf.inverse(cam);
return view;

Code :

// ... and in my game object draw function, I use the view matrix
model = Mathf.mul(model, scale);
normMat = Mathf.transpose(Mathf.inverse(model));
modelView = Mathf.mul(model, view);
mvp = Mathf.mul(modelView, projection);

Everything works fine, I see the world, I could translate left, right, forward and back if I coded those instructions. But I can't seem to get the mouse look working, I clearly don't understand the fps camera concept properly. I also understand that in order to walk towards the correct direction I'm looking at, I need a few more steps using the cross product, but at the moment I just want to look around and can't seem to get it.

Hope this all makes sense :S Thanks!

Oh by the way, I wrote my own Math lib, I'm aware that I could have used any popular one out there, but I wanted to learn. If you want to take a look at it (just in case I did something, wrong) it's here: https://gist.github.com/hashbrownjs/...e3cdb60f3d8371

I'll go ahead and copy the rotateX and rotateY functions for your convenience since those are crucial in making the cam rotate.

Code :

Mathf.rotateX = function (degree) {
var r = Mathf.Mat4(),
angle = Mathf.degToRad(degree),
cos = Math.cos(angle),
sin = Math.sin(angle);
r[5] = cos; r[6] = -sin;
r[9] = sin; r[10] = cos;
return r;
};
Mathf.rotateY = function (degree) {
var r = Mathf.identity(r),
angle = Mathf.degToRad(degree),
cos = Math.cos(angle),
sin = Math.sin(angle);
r[0] = cos; r[2] = -sin;
r[8] = sin; r[10] = cos;
return r;
};

I have an idea how I could solve the problem in the title but I want to know your oppinion about that before I waste time In programming something not working.

Basicly the idea is to have a grid of boxes with height = width, all of these boxes are the same size and they don't have a gap between each other, I also have a function to calculate the box index which belongs to a point.

Now I calculate a box around the grid and calculate the hit points of a ray with it.

So I know the intersection points and of course the rays direction, now I take the direction, normalize it and devide it by 2. ( Im not realy sure if I need /2 but I feel better with it)

The resulting vector is now my "step size". (I call this vector v)

So if I take now my first intersection point add v, calculate the box which belongs to the resulting point and do this again and again until I reach my second intersection point I shouldn't miss any box. (rigth ?)

But Im not sure about that so I ask for your oppinion.

Thanks. ]]>

I'm experimenting with skinning and trying to do the calculation directly with the quaternion, but I'm stuck getting the translation to be the same as with the matrix. I

In the code-block below I know that the matrix is correct (mesh is displayed correctly). Now instead of using the matrix, I'm trying to do the same but directly using the quaternion. For verifying, I create a matrix out of the Quaternion + vector. The problem is that the 3x3 rotation-part of that matrix is correct but the translation isn't.

Question: How do I calculate the worldspace-translation using the current localspace-quaternion/translation + parent-worldspace-quaternion/translation ?

Code :

void _computeWorldPose(const Model& model, const Animation& anim, size_t frame, KeyFrame& keyframe)
{
// reserve space for the output
keyframe.pose.resize(model.rig.size());
keyframe.poseQ.resize(model.rig.size());
keyframe.poseT.resize(model.rig.size());
for (int b=0; b<model.rig.size(); b++)
{
// anim-bone-index may have different index as model-bone-index, lookup by name
int abid = anim.getIndexByName(model.rig[b].name);
if(abid!=-1)
{
Quaternion qq;
vector3 pos;
float scale;
unsigned int parentid = model.rig[b].ParentID;
anim.GetDataForKeyframe(abid, frame, qq, pos, scale);
// prepare the matrix
Quaternion q = qq.Inverse(); // (not entirely sure why, but with this the mesh is rendered correctly... )
matrix4 m4 = q.ToMatrix4();
m4.set_translation(pos);
// do calculation as Matrix and as Quaternion
keyframe.pose[b] = keyframe.pose[parentid] * m4;
keyframe.poseQ[b] = q * keyframe.poseQ[parentid];
keyframe.poseT[b] = q.transform(pos) + keyframe.poseT[parentid]; // ? what needs to be done here ?
// verify that we get the same result
matrix4 m(keyframe.poseQ[b], keyframe.poseT[b]);
if (keyframe.pose[b] != m) {
assert(0); // this fires, with the 3x3-rotation being identical, but translation is different
}
}
else
{
// "Root"
keyframe.pose[b].identity();
keyframe.poseQ[b] = Quaternion();
keyframe.poseT[b] = VECTOR3_ZERO;
}
}
}

lets say we have 3 arbitrary points A, B and C in 3D space, we dont know if and which are laying in a line or even if all of those are (0|0|0). the coords of these points are described in float (or double)

whats the approch to calculate the point in 3D space that is the center if a circle which lays on these 3 points, the "circumscribed circle" center ?

in pure math (that is without bothering about floating-point precision etc), i'd:

middleAB = A + AB / 2

normal = cross(AB, AC)

tocenterAB = cross(normal, AB)

first line:

X = middleAB + n * tocenterAB

the same then for AC:

X = middleAC + n * tocenterAC

then intersect both lines. the problem is that the slightest precision loss will make these 2 lines not intersect. how to do it "

lets say we have a bunch of points, we want to calculate the center M + radius R of the smallest sphere that contains all of these points:

case 1: 1 point --> R = 0, M = point

case 2: 2 points --> R = AB / 2, M = (A+B) / 2

case 3: 3 points --> ??? see question 1

case 4: 4 points --> ??? :doh:

case N: N points --> reduce to 4 points that are furthest away

the reason for that is that i want to calculate bounding spheres:

Code :

struct BoundingSphere {
vec3 Center; /* offset from "local space" */
float Radius = 0.0f;
};

3. question:

would you do that using a (vertex or compute) shader to do that for complex models ?

4. question:

having a model with bones, would you do this calculation at runtime (on the fly instead of once at initialization) ? each frame (possibly not) ? each few (500) milliseconds ? or just precalculate for each "pose" another bounding sphere and interpolate between those ?

i'm looking for a method to check for collision for arbitrary object, these models shouldnt have a "scaling" component so the they only have different translation / rotation component at each bone (if any available). lets say its for a flight simulator kind of game ...

last but not least: can i use glm to do anything of this ?

thanks for your suggestions ! ]]>

i'm trying to put all images i need into array textures, for example:

Array texture 1:

-- rgba8, 1024 x 1024

-- for diffuse and specular textures

Array texture 2:

-- r8, 1024 x 1024

-- for alpha / height / other things that only need 1 channel

etc ...

there is a problem however: memory waste.

what if i have a diffuse texture that is only 512 x 512 ? that will fit into a layer, but only 25% are acually needed. a solution would be a class that manages texture layers efficiently. is there a lib or example where something like this is implemented ? i mean that would be very useful .. with that, i bind the array texture once and let them bound for the time the app runs, so that i can access them with a layer index (part of material) + texcoord (part of mesh)

i'm trying to write such a manager but i dont know how to do it (yet) :dejection: (i'm trying it too general in applicability)

example interface:

Code :

manager.append("image1.dds", width, height);
manager.append("image2.png", width, height);
...
int layers = manager.getLayers();
glTexStorage3D(... layers, ...)
for each layer
-- manager.getLocationOf("tex1");
-- glTexSubImage3D(....)

Looking here

http://www.lighthouse3d.com/tutorial.../point-lights/

I can see that to get the light direction you need to use the formula

"light direction = light position – vertex position"

The text following this says

"Before we can compute this vector we must apply the View Model matrix (m_viewModel in the shader) to the vertex position."

The vertex position would not be calculated from the viewModel matrix it would be calculated from the model matrix only.

This tutorial uses the model matrix as I would expect but then has other logic to work out the spec light

https://learnopengl.com/#!Lighting/Basic-Lighting

Can someone say if there is a typo in the first formula or if there is something basic that I haven;t understood which would explain it and also what the difference is between the two tutorials? ]]>

However, the more the model is rotated, the farther away from the vertices the labels are placed.

??

Code :

// labels.c
// This program writes a cube, which can be spun with a mouse drag, and then labels the corners.
// compile as gcc labels.c -lm -lglut -lGLEW -lGL
#include <stdio.h>
#include<math.h>
#include<time.h>
#include <GL/glew.h>
#include <GL/glext.h>
#include <GL/glut.h>
float roll0 = 0.0, pitch0 = 0.0, roll = 0.0, pitch = 0.0, zoom = 1.0;
int xdown, ydown, WindowWidth = 720, WindowHeight = 540, mainWindow;
void init(){
roll = pitch = 0.0; zoom = 1.0;
glMatrixMode(GL_MODELVIEW);
}
// multiply 4X4 matrix A by matrix B; answer is copied into matrix A
void mult4matrix(float A[4][4], float B[4][4]){
int i, j, k;
float C[4][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};
for(i=0; i<4; i++) for(j=0; j<4; j++) for(k=0; k<4; k++){
C[i][j] += A[i][k] *B[k][j];
}
for(i=0; i<4; i++) for(j=0; j<4; j++) A[i][j] = C[i][j];
}
void transform(float *in, float *t){
// build(?) a transformation matrix, multiply in[] by that matrix, put answers in in[]
// roll is rotation about X axis; pitch = rotation about Y axis
const double PI = 3.14159265358979323846;
float ix, iy, iz, rad, ox, oy, oz;
int i, j;
double iroll, ipitch, ialpha, igamma, oroll, opitch;
static float lroll=NAN, lpitch, lzoom=1.0, xmatrix[4][4]; // values from previous
const float imatrix[4][4] = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; //identity
float mmatrix[4][4], vout[3] = {0, 0, 0};
if((lroll != roll) || (lpitch != pitch) || (lzoom != zoom)){
// compute transformation matrix based on updated values
lroll = roll; lpitch = pitch; lzoom = zoom;
// roll & pitch are in degrees; iroll & ipitch are in radians
iroll = roll *PI/180.0;
ipitch = pitch *PI/180.0;
// set xmatrix, mmatrix = identity matrix
for(i=0; i<4; i++) for(j=0; j<4; j++) xmatrix[i][j] = mmatrix[i][j] = imatrix[i][j];
xmatrix[0][0] = cos(iroll);
xmatrix[0][2] = sin(iroll);
xmatrix[2][0] = -sin(iroll);
xmatrix[2][2] = cos(iroll);
mmatrix[1][1] = cos(ipitch);
mmatrix[1][2] = -sin(ipitch);
mmatrix[2][1] = sin(ipitch);
mmatrix[2][2] = cos(ipitch);
mult4matrix(xmatrix, mmatrix);
for(i=0; i<4; i++) for(j=0; j<4; j++) mmatrix[i][j] = imatrix[i][j]; lzoom = 1.0;
mmatrix[0][0] = lzoom;
mmatrix[1][1] = lzoom;
mmatrix[2][2] = lzoom;
mult4matrix(xmatrix, mmatrix);
}
for(i=0; i<4; i++) for(j=0; j<4; j++)vout[i] += xmatrix[i][j] *in[j];
t[0] = vout[0]; t[1] = vout[1]; t[2] = vout[2]; t[3] = 0;
}
void printtext(int x, int y, char String[]) // labels etc for model
{
int i, stringsize;
//(x,y) is from the bottom left of the window
glPushMatrix();
glPushAttrib(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
glRasterPos2i(x,y);
for(i=0; String[i] != 0 && i<10; i++){
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, String[i]);
}
glPopAttrib();
glPopMatrix();
}
void display(){
float g[8][3] = {{-10.0, -10.0, -10.0},{10.0, -10.0, -10.0}, {10.0, 10.0, -10.0}, {-10.0, 10.0, -10.0},
{-10.0, -10.0, 10.0},{10.0, -10.0, 10.0}, {10.0, 10.0, 10.0}, {-10.0, 10.0, 10.0}};
float t[3];
int i;
char label[10];
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glLoadIdentity();
glOrtho(-20.0, 20.0, -20.0, 20.0, -20.0, 20.0);
glScalef(zoom, zoom, zoom);
glRotatef(roll, 0.0, 1.0, 0.0);
glRotatef(pitch, 1.0, 0.0, 0.0);
glPointSize(2.5);
glColor3f(0.0, 1.0, 1.0);
glBegin(GL_POINTS);
for(i=0; i<8; i++) glVertex3fv(g[i]);
glEnd();
// print grid identification numbers to screen
glColor3f(0.0, 0.3, 1.0);
for(i=0; i<8; i++){
transform(g[i], t);
sprintf(label, "%d", i);
printtext((int)(t[0]), (int)(t[1] ), label);
// offset the labels from the grid points
// printtext((int)(t[0]+2), (int)(t[1] +2), label);
}
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
for(i=0; i<4; i++) glVertex3fv(g[i]);
glVertex3fv(g[0]);
for(i=4; i<8; i++) glVertex3fv(g[i]);
glVertex3fv(g[4]);
glEnd();
glBegin(GL_LINES);
for(i=1; i<4; i++){
glVertex3fv(g[i]);
glVertex3fv(g[i+4]);
}
glEnd();
glutSwapBuffers();
}
void move(int x, int y){
roll = roll0 + 90*(xdown -x)/WindowWidth;
pitch = pitch0 + 90*(ydown -y)/WindowHeight;
display();
}
void mouse(int btn, int state, int x, int y){
static int gup = 1;
if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
xdown = x;
ydown = y;
gup = 0;
return;
}
else if(btn == 3){ // mouse wheel
zoom *= 1.1;
display();
}
else if(btn == 4){
zoom /= 1.1;
display();
}
else if (state = GLUT_UP){
if(gup == 1)return;
roll0 += pitch;
pitch0 += roll;
}
gup = 1;
display();
}
int main(int argc, char* argv[]){
int WindowWidth = 720, WindowHeigyt=540;
glutInit(&argc,argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(WindowWidth, WindowHeight);
glutInitWindowPosition(100, 100);
mainWindow = glutCreateWindow("Print Labels");
init();
glutDisplayFunc(display);
glutMouseFunc (mouse);
glutMotionFunc(move);
glutMainLoop();
return 0;
}