Tell me if I'm wrong...


(kEinStein) #1

Hiho! Me again with my annoying questions… :wink:

It’s python again. So, I want to calculate a relative position of a mouse pointer to the camera. For this first I need is the orientation of the camera and the orientation of a ray (for the getting the hit position in 3d space). Well, I fetch the orientation of both with getOrientation and this should return me a 3x3 rotation matrix, right? So, if no rotation is applied to the objects then the directional vector should be (0,1,0) which means that this would be my basic vector. If now I change the orientation of the cam or the ray I should get the new directional vector if I apply the matrix getOrientation returned on that vector.

Would be something like that:


import GameLogic

def mult(mat, vec):

        nx = mat[0][0] * vec[0] + mat[0][1] * vec[0] + mat[0][2] * vec[0]
        ny = mat[1][0] * vec[1] + mat[1][1] * vec[1] + mat[1][2] * vec[1]
        nz = mat[2][0] * vec[2] + mat[2][1] * vec[2] + mat[2][2] * vec[2]

        return [nx,ny,nz]

def orient2vec(mat):

        return mult(mat, [0,1,0])

cont  = GameLogic.getCurrentController()
owner = cont.getOwner()

orient = owner.getOrientation()

GameLogic.orient_cam = orient2vec(orient)
GameLogic.cam_pos    = owner.getPosition()


Or am I wrong?

Then I calculate the position of the pointer (on a (imaginary) plane at a certain distance to the camera - here 3 units).

For that purpose I did the following:


#
# Maus-Skript / Pointer setzen
#

import GameLogic
import Rasterizer
from math import *

cont    = GameLogic.getCurrentController()
sensor  = cont.getSensor("always")
owner   = cont.getOwner()

cam_pos    = GameLogic.cam_pos
posx,posy,posz = cam_pos

orient_cam = GameLogic.orient_cam
cx,cy,cz = orient_cam

orient_ray = GameLogic.orient_ray
rx,ry,rz = orient_ray

r_vector_len = sqrt(rx*rx + ry*ry + rz*rz) / cx*rx*3 + cy*ry*3 + cz*rz*3

rx = r_vector_len * rx
ry = r_vector_len * ry
rz = r_vector_len * rz

# |r| = sqrt( bx² + by² +bz² ) / ax * bx + ay * by + az * bz

#
# Pointerposition setzen
#

owner.setPosition([posx + rx, posy + ry, posz + rz])


I can’t say for sure if the math in here is fully correct. It should be a triangulation of the desired point. But I think that it should work.

Yes, the globals are defined as emtpy arrays at startup…
Anyone an idea what’s wrong?


(kEinStein) #2

What I forgot: It doesn’t work! :wink: I get a division by zero error at the following point:


r_vector_len = sqrt(rx*rx + ry*ry + rz*rz) / cx*rx*3 + cy*ry*3 + cz*rz*3 

But the amount of both vectors should be always 1. So I don’t know why it fails. It must be either a problem with the globals or with the first part of the code.


(Ben) #3

-This script written by Iconjunky(I’m not sure)finds the mouse position in 3D.

from math import sqrt
cont = GameLogic.getCurrentController()
owner = cont.getOwner()

def normalize(x):
	length = sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2])
	return [x[0]/length,x[1]/length,x[2]/length]

def cross(x,y):
	return [x[1]*y[2] - x[2]*y[1],
			x[2]*y[0] - x[0]*y[2],
			x[0]*y[1] - x[1]*y[0]]

def dot(x,y):
	return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]

def mul(s,x):
	return [s*x[0],s*x[1],s*x[2]]

def vecToMat3(vec,track):
	z = normalize(vec)
	dotprod = dot(z, normalize(track))
	if abs(dotprod) == 1:
		track.append(track[0])
		del track[0]
	x = normalize(cross(track, vec))
	y = cross(z,x)
	return [[x[0],y[0],z[0]],
			[x[1],y[1],z[1]],
			[x[2],y[2],z[2]]]

if cont.getSensor("ObjLocate").isPositive()==1:
	leftbut = cont.getSensor("LeftBut")
	if leftbut.isPositive()==1:
		HP = cont.getSensor("GetOwner").getOwner()
		BHPosi = cont.getSensor("ObjLocate").getHitPosition()
		BHNorm = cont.getSensor("ObjLocate").getHitNormal()
		AFWD = owner.getOrientation()
		FWD = AFWD[0]
		BHOri = vecToMat3(BHNorm,FWD)
		HP.setPosition(BHPosi)
		HP.setOrientation(BHOri)
		GameLogic.addActiveActuator(cont.getActuator("AddHole"),1)

-Hope it helps.
Ben


(kEinStein) #4

Found one error by myself…


r_vector_len = sqrt(rx*rx + ry*ry + rz*rz) / cx*rx*3 + cy*ry*3 + cz*rz*3 

This should be:


r_vector_len = sqrt(rx*rx + ry*ry + rz*rz) / (cx*rx*3 + cy*ry*3 + cz*rz*3) 

To Ben: Thanks, I’ll take a look at it.


(kEinStein) #5

That’s not really what I’m looking for…
But I found out that the error must be in the first part of the code:


import GameLogic 

def mult(mat, vec): 

        nx = mat[0][0] * vec[0] + mat[0][1] * vec[0] + mat[0][2] * vec[0] 
        ny = mat[1][0] * vec[1] + mat[1][1] * vec[1] + mat[1][2] * vec[1] 
        nz = mat[2][0] * vec[2] + mat[2][1] * vec[2] + mat[2][2] * vec[2] 

        return [nx,ny,nz] 

def orient2vec(mat): 

        return mult(mat, [0,1,0]) 

cont  = GameLogic.getCurrentController() 
owner = cont.getOwner() 

orient = owner.getOrientation() 

GameLogic.orient_cam = orient2vec(orient) 
GameLogic.cam_pos    = owner.getPosition() 

nx, ny, nz are 0… :frowning:
Can anybody tell me what getOrientation returns? I believed that it was the rotation matrix of the object… Does not dot-multiplying this matrix with a vector apply the rotation to a vector? Oh man…


(eeshlo) #6

getOrientation does return the rotation, but you didn’t implement the matrix multiply right, it should be something like this:


def mult(mat, vec): 
	nx = vec[0]*mat[0][0] + vec[1]*mat[1][0] + vec[2]*mat[2][0]
	ny = vec[0]*mat[0][1] + vec[1]*mat[1][1] + vec[2]*mat[2][1]
	nz = vec[0]*mat[0][2] + vec[1]*mat[1][2] + vec[2]*mat[2][2]
	return [nx,ny,nz] 

In your case, as you seem to be always multiplying it with [0,1,0], this simplifies to:


GameLogic.orient_cam = mat[1]

In other words, you don’t need these functions if you are not going to use it for anything else.


(kEinStein) #7

Ok. Works. I still have screwed axes, seems that I have to do a cross multiply somewhere, but it works. Thanks eeshlo! I had nothing to do with math for more than 4 years… I should take a look at that again! :smiley: