stuck on something..maybe simple matrix...

Edit: functional code


    point = own.worldPosition - player.worldPosition
    # calculate look vector and unrolled ground normal vector
    groundNormal = ray_down[2]
    horVec = own.worldOrientation.col[0].copy()
    horVec.z = 0
    horVec.normalize()
    unRolledNormal = groundNormal - groundNormal.project(horVec)

    # look towards player
    own.alignAxisToVect(-point,1,1)# look at player
    # align with ground without roll
    own.children[0].alignAxisToVect(unRolledNormal, 2)


I have been working on my wolves A.I. over the last few days in my spare time…

We all understand quadrupeds should align with the ground, but I am having trouble getting the wolves not to ‘roll’ rot on ‘y’ axis…

I have tried copying eulers converted to degrees etc etc…

I have tried copying the x orientation, to be reset after ground alignment etc…I am getting nowhere…

I need to stop the rolling on the y axis…here is what I have used for alignment.

point = own.worldPosition - player.worldPosition
    own.alignAxisToVect(-point,1,1)# look at player
    own.alignAxisToVect([0,0,1],2,1)#lock Z axis
    
    
    own.children[0].alignAxisToVect(ray_down[2],2,1)#align to ground

first part just tracks the player…
and ray_down is just a ray oriented on -z to get hit info…using normal…but anyone who can answer this should find this code rudimentary…
I’m also open to accepting a pre existing piece of code that would do this aligning to the ground as a simple function…
and if no one can help thanks anyway :slight_smile:

I think something like this is what you want.

# calculate look vector and unrolled ground normal vector
vec = point - own.worldPosition
horVec = own.worldOrientation.col[0].copy()
horVec.z = 0
horVec.normalize()
unRolledNormal = groundNormal - groundNormal.project(horVec)

# look towards player
own.alignAxisToVect(vec, 1)

# align with ground without roll
own.alignAxisToVect(unRolledNormal, 2)

The wolves should look towards the player (rotation around the z-axis) while aligning to the floor (rotation around local x-axis) without any rotation around the local y-axis.

i use this


import bge
from mathutils import Vector
cont = bge.logic.getCurrentController()
own = cont.owner
Ray = cont.sensors['Ray']

if Ray.positive: 
    own.alignAxisToVect(Vector(Ray.hitNormal)*1,2,.24)
else: 
    own.alignAxisToVect(Vector([0,0,1]),2,.25)

@Mobius: that is what I was trying to do initially copying the x orientation, then doing my alignment…and finally realign the x orientation…with your code I get the same issues I had when I tried it initially…and that is it no longer tracks the player…this is probably a simple logic issue…in where I place the code to face the player…I will give it a shot though…

groundNormal = hit[2] I assume

@edderkop: you get the gist of it, but this would basically realign the z axis(by 25%) this maybe doable if I do it on the x axis…as it would look less unusual.

I will copy this code from mobious and tinker with it…or just re-use the code I had doing the same thing…I’m guessing it will give me the same result. I’ll be back later to update this post.

EDIT: I went ahead and removed some code clutter.
ok, that was pretty quick…here is the un-refined code…now I need to clean it up and write it in a more proper manner :slight_smile: thanks for your help guys. Anyone who wants to copy this may do so(ofc) just remove all the commented lines.


    point = own.worldPosition - player.worldPosition
    # calculate look vector and unrolled ground normal vector
    groundNormal = ray_down[2]
    horVec = own.worldOrientation.col[0].copy()
    horVec.z = 0
    horVec.normalize()
    unRolledNormal = groundNormal - groundNormal.project(horVec)

    # look towards player
    own.alignAxisToVect(-point,1,1)# look at player
    # align with ground without roll
    own.children[0].alignAxisToVect(unRolledNormal, 2)