FPS-like navigation style

Have some feature requests, feedback, cool stuff to share, or want to know where FreeCAD is going? This is the place.
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
JMG
Posts: 288
Joined: Wed Dec 25, 2013 9:32 am
Location: Spain
Contact:

FPS-like navigation style

Post by JMG »

Hi!

I just read this sentence:
Another often wanted navigation style is fly mode (I would call it FPS navigation). Not done yet, too, but perfectly doable.
From this topic and started to think about how hard would it be to implement such functionality.

After an hour or so, I have the first working script:
How to use it:
-Create a new document
-Switch to perspective visualization
-Paste at Python console or run the code below as a macro
-Left click anywhere inside the 3D view window
-Use mouse to look around, WASD to move

Code: Select all

"""
FPS-like navigation
Javier Martinez Garcia 2015 GPL
"""
import FreeCAD
from pivy import coin
import Part
from math import sin, cos, pi

# create cube scenery and ground ###############################################
import random
cube_list = []
for i in range(200):
    b = Part.makeBox( 5, 5, 5, FreeCAD.Vector( random.uniform( -100, 100),
                                                  random.uniform( -100, 100),
                                                  random.uniform( -100, 100) ) )
    cube_list.append(b)


ground = Part.makePlane( 10000, 10000, FreeCAD.Vector( -5000, -5000, -150 ) )
g_o = FreeCAD.ActiveDocument.addObject( 'Part::Feature', 'Ground' )
g_o.Shape = ground
g_o.ViewObject.ShapeColor = (0.60,0.29,0.00)
g_o.ViewObject.Selectable = False
g_o.ViewObject.Transparency = 30
Part.show(Part.makeCompound( cube_list ) )                                                     
################################################################################

# FPS style camera -------------------------------------------------------------
class cameraUpdate:
    def __init__(self, view):
        self.view = view
        # retrieve camera
        self.cam = FreeCADGui.ActiveDocument.ActiveView.getCameraNode()
        # keyboard variables
        self.x = 0
        self.y = 0
        self.z = 0
        self.look_at_vector = (1,0,0)
        # mouse variables
        self.Alpha = 0.0 # azimut
        self.Beta = 0.0  # elevacion
        self.da_0 = 0.0
        self.db_0 = 0.0
        
    def mousePosition(self, info):
        pos = info["Position"]
        da = int( pos[0] )
        db = int( pos[1] )
        # azimut update
        self.Alpha = self.Alpha + ( self.da_0 - da )*0.008
        self.da_0 = da
        # elevation update
        self.Beta = self.Beta + ( self.db_0 - db )*0.008
        self.db_0 = db
        cam_pos = self.cam.position.getValue()
        self.look_at_vector = ( cam_pos[0] + cos( self.Alpha ),
                           cam_pos[1] + sin( self.Alpha ),
                           cam_pos[2] + sin( self.Beta ) )
        
        self.cam.pointAt( coin.SbVec3f( self.look_at_vector[0], 
                                        self.look_at_vector[1],
                                        self.look_at_vector[2] ),
                          coin.SbVec3f( 0, 0, 1 ) )
                                        
    def keyboardPosition( self, info ):
        key = info["Key"]
        down = (info["State"] == "DOWN" )
        # key logic
        if key == 'w':# and (down):
            self.x = self.x + cos( self.Alpha )
            self.y = self.y + sin( self.Alpha )
            self.z = self.z + sin( self.Beta )
            
        if key == 's':# and (down):
            self.x = self.x - cos( self.Alpha )
            self.y = self.y - sin( self.Alpha )
            self.z = self.z - sin( self.Beta )

        if key == 'a':# and (down):
            self.x = self.x + cos( self.Alpha + pi/2.0)
            self.y = self.y + sin( self.Alpha + pi/2.0)
        
        if key == 'd': #and (down):
            self.x = self.x - cos( self.Alpha + pi/2.0)
            self.y = self.y - sin( self.Alpha + pi/2.0)
        
        if key == 'r': #and (down):
            self.z = self.z + 1
        
        if key == 'f': #and (down):
            self.z = self.z - 1
        
        # compose vector
        self.cam.position.setValue( (self.x, self.y, self.z) )



v=Gui.activeDocument().activeView()
o = cameraUpdate(v)
c = v.addEventCallback("SoLocation2Event",o.mousePosition)
d = v.addEventCallback("SoKeyboardEvent", o.keyboardPosition)
The vídeo:
https://www.youtube.com/watch?v=mKy9Mb0tB_U


Javier.
Last edited by JMG on Fri Dec 18, 2015 11:43 pm, edited 3 times in total.
FreeCAD scripts, animations, experiments and more: http://linuxforanengineer.blogspot.com.es/
Open source CNC hot wire cutter project (NiCr): https://github.com/JMG1/NiCr
Exploded Assembly Workbench: https://github.com/JMG1/ExplodedAssembly
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: FPS-like navigation style

Post by microelly2 »

Very nice script. :)
I will reuse it to track the movements,
so the trip can be replayed later.
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: FPS-like navigation style

Post by DeepSOIC »

Interesting.
Pasted to py console. Mouse lookaround works, but keys WASD are ignored.

OS: Windows 8.1
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.16.6080 (Git)
Build type: Release
Branch: FreeCAD-DeepSOIC5
Hash: e150c5e9d80081fc1df7745b109483b7c6ca78d9
Python version: 2.7.8
Qt version: 4.8.6
Coin version: 4.0.0a
OCC version: 6.7.1
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: FPS-like navigation style

Post by microelly2 »

DeepSOIC wrote:Interesting.
Pasted to py console. Mouse lookaround works, but keys WASD are ignored.
Was my first impression too, but it works, its only hard to see.
You have first to click into the 3d window to bring the keyboard focus to the EventCallback, then the keys are recognized.
JMG
Posts: 288
Joined: Wed Dec 25, 2013 9:32 am
Location: Spain
Contact:

Re: FPS-like navigation style

Post by JMG »

I like the idea, microelly. It will be an easier way of generating the path for a tour camera :D

DeepSOIC, as microelly says, you need to click on the 3D view after you paste the code (maybe the python console has its own input events and they are in conflict with the inputs of the 3d view :? ). I've edited the instructions to include this ;)

Javier.
FreeCAD scripts, animations, experiments and more: http://linuxforanengineer.blogspot.com.es/
Open source CNC hot wire cutter project (NiCr): https://github.com/JMG1/NiCr
Exploded Assembly Workbench: https://github.com/JMG1/ExplodedAssembly
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: FPS-like navigation style

Post by DeepSOIC »

I have noticed from the very beginning, that my WASD ended up in py console, so I did click the 3d view. Characters are no longer being typed into py console, but still, I get no movement.
JMG
Posts: 288
Joined: Wed Dec 25, 2013 9:32 am
Location: Spain
Contact:

Re: FPS-like navigation style

Post by JMG »

I've added one extra line at the end of the script, is it working now?
FreeCAD scripts, animations, experiments and more: http://linuxforanengineer.blogspot.com.es/
Open source CNC hot wire cutter project (NiCr): https://github.com/JMG1/NiCr
Exploded Assembly Workbench: https://github.com/JMG1/ExplodedAssembly
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: FPS-like navigation style

Post by DeepSOIC »

YESS, now it works! Cool :D :mrgreen: 8-)

EDIT: so, it looks like I was dumb enough to not notice that the last line of code remained typed but not executed, so I just needed to press Enter? Oh, stupid me :x facepalm
User avatar
rockn
Veteran
Posts: 1791
Joined: Wed Sep 28, 2011 10:39 am
Location: Toulouse, France
Contact:

Re: FPS-like navigation style

Post by rockn »

Awesome JMG,

Can you tell me where I can change the speed of keyboard movement ? I work on Arch model at real size ;)
Formations - Assistance - Développement : https://freecad-france.com
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: FPS-like navigation style

Post by microelly2 »

I think this kind of navigation makes sense for "large" models.

To get more realistic pictures it should support perspective camera mode too.
So there is the need of a complete cockpit functionality:
joystick, thrust lever
and a head up display: horizon, hight, direction/compass , position in x/y

I have found this post:
viewtopic.php?t=5826

I think about the head up display. It makes sence to hold information on a fixed place inside 3D space when moving around.
Its an exciting story. 8-)
Post Reply