Relative position to global position.

Hello!
I’ve got a spot relative to one object. It is constant value. But the object can move. So I need to conver the relative value to global value. However, I am not quite sure how to do it. Can anybody help me out a bit?:slight_smile:

Point local to object

Local = target.worldPosition-base.worldPosition
Local = base.worldOrientation*Local

This gives you a vector you use to get get your relative point later

Point = base.worldPosition+(base.worldOrientation*Local)

I don’t understand.
I will try to explain again:
I have an object.
I have a constant vector value. This value is a relative position to an object.
I need to get a vector that is global position of the relative vector.

local = a point localized to another object

global = a point in space.

if you need a position relative to another object that moves, you want a local.

if you take a local position and then do this

Point = base.worldPosition+( base.worldOrientation*Local)

Point is a world coordinate, of the localized point.


import bge


from mathutils import Vector
def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner


    if 'Cube' not in own:
        own['Cube'] = bge.logic.getCurrentScene().objects['Cube.003']
        
    else:     
        Local = Vector([0,-5,5])
        own['Cube'].worldPosition = own.worldPosition+(own.worldOrientation*Local)


main()



OK! Thank you. And it works in rotation cases aswell, right?:slight_smile:

Yes, (that is what 'base.worldOrientation*Vector) does

So it should work like this:
I have a relative point where I should cast a ray from.
I have a vector like this:


vec = own.getAxisVect((0.0, 0.0, -1.0))

And I do this:


own.rayCast(relPosToWorldPos + vec, relPosToWorldPos, 1) # relPosToWorldPos is result that I get when I do calculation that you told me.

(this casts ray from the relative point downwards the local -Z axis of object)
This should work correctly, right?

end = own.worldPosition+(own.worldOrientation.col[2]*-1)

is what I use to cast along a axis (-z in this case)

or you can do

end = own.worldPosition+(own.worldOrientation.inverted()*Vector([0,0,-1]) )

Hm… This does the same as getAxisVect(), but both of them seams to result in ray being located around 0.5-1 BU on positive relative Y axis of master(it is hard to tell how far from their original positions). I don’t understand what’s wrong in this case.

lets see your script

also, I never use getAxisVect()**

it’s never been helpful.

3.14/360 = degrees rotation

with this .to_euler() and .col[0] etc, I have not needed it.

P.S. 22 / 7 is more accurate pi. And under math.pi there is even more accurate pi:D

I’m not sure that I understand what exactly you want.

Convert a vector given in parent space (localPosition) to scene space (worldPosition):

Lets demonstrate that with a the position of an child object:


child = ...
positionInParentSpace = child.localPosition
transformation = child.parent.worldTransform
positionInSceneSpace = transformation * positionInParentSpace

Convert a vector given in object space to scene space (worldPosition):

positionInParentSpace = mathutils.Vector([0,2,0])
transformation = baseObject.worldTransform
positionInSceneSpace = transformation * positionInParentSpace

as a function it would look like this:


def convertObjectToSceneSpace(positionInParentSpace, baseObject):
    transformation = baseObject.worldTransform
    return transformation * positionInParentSpace

you can call it with:



positionInSceneSpace = convertObjectToSceneSpace(mathutils.Vector([0,2,0]), owner)

#or 

positionInSceneSpace = convertObjectToSceneSpace(child.localPosition, child.parent)

OK! Thank you. I haven’t checked yet, but it seems to be really good thing. However, what is worldTransform?

it’s orientation and scale as 1 matrix

http://bgepython.tutorialsforblender3d.com/GameObject/worldTransform

OK! Thank you for information;)

worldTransform is a (not so good name) for:

The current transformation (incl. location, rotation, scaling) to place the object where it is (in scene space)"

I do not know why the developer wasn’t able to type the complete name “worldTransformation”. Maybe Python does not allow variables with more than 14 characters or the “devel” was hit by CAISY (Chronically Abbreviation Inventing SYndrome). It must be infectious.

  • btw. this is a joke

Warning: complicated things follow

Imagine your object is at the origin without any scale and rotation. Now you move it away (20,0,0), turn it (45°,0,0) and scale it a bit (3,3,3). These transformations (translation, rotation, scaling) concatenate each other in exactly that order to a final transformation:

translation () rotation () scaling = transformation (from origin to where it is now)

You could apply the final transformation to any object, to perform exactly the same operations without calculating it again.

sphere.worldTransform = cube.worldTransform.copy()

Scenegraph
The interesting thing is that you can easily use it to build hierarchies (parent child):

child.worldTransform = parent.worldTransform (*) localTransformation [e.g. a translation (0,1,0)]

The bge does not need to calculate the final transformation of the parent twice (one for parent and one for child) it can use the final transformation of the parent and concatenate the remaining transformation from parent to child. This saves a lot of processing power, especially on large scene graphs.

Mesh
The same happens on the mesh.
Each single vertex needs to be transformed into world space for rendering. The final object transformation needs to be calculated once and can be applied to each single vertex.

To complete the picture … vertices gets transformed to world space and from world space to camera space and from camera space to screen space. The necessary transformation from object to screen is a single transformation for a single object. If you have 1000 vertices, you calculate the final transformation from object to screen once but apply the vertex transformation 1000 times rather than calculating everything 1000 times.

(BGE) Implementation
A transformation is a Matrix (regardless if translation, rotation or scaling … even camera perspective is a matrix)
The concatenation is a matrix multiplication.

Multiplying a transformation matrix with a point (represented as vector) will apply all transformations of the matrix to that point.

Short cuts
Matrix multiplication is still a lot of calculation especially when used on a single point. In some special cases it can make sense to use short-cuts with the same result. That is why you sometimes see code like that from BluePrintRandom:


own.worldOrientation.col[2]

Typical special cases are:

  • move along a single axis
  • turn 90° around a single axis
  • single translation of a point/object

Efficiency
Special cases can be more efficient when used correctly. (Which does not mean that you always see a difference)


object.worldPosition.z = object.worldPosition.z + 1 #is more efficient than
object.worldPosition = object.worldPosition + mathutils.Vector((0.0, 0.0, 1.0)) # is more efficient than
object.worldTransform = object.worldTransform * mathutils.Matrix.Translation((0.0, 0.0, 1.0)) 

But the last one is more efficient on several transformations on several objects:


for object in objects:
   for transformation in transformations:
      object.worldTransform = object.worldTransform * transformation

#has worse performance than
finalTransformation = mathutils.Matrix.Identity(4)
for transformation in transformations:
    finalTransformation = finalTransformation * transformation

for object in objects:
    object.worldTransform = object.worldTransform * finalTransformation 

Now imagine you do that for meshes with 1000 vertices ;).

Thank you, Monster, for deep explanation. I actually read through it and understood it well, so I think that you indeed gave me good explanation :slight_smile:

Not really! :smiley:

I just reformatted it little bit :wink: