Panda3D: ruotare la telecamera col mouse

Come l’avevo fatto con Blender, ora lo faccio con Panda3D 😉

Dall’hello world della documentazione ufficiale, ho fatto questo script che muove la telecamera col mouse.

In pratica esegue un task - una funzione eseguita ad ogni frame - che controlla la posizione del mouse, la trasforma da radianti a gradi sessagesimali (usati da Panda) e alla rotazione che ha in quel momento la telecamera aggiunte quella ottenuta con la trasformazione. Infine centra il mouse.

Devo ancora capire perché trasformando le coordinate del mouse - il cui intervallo in panda è [-1; 1] - si riesca a ottenere una buona rotazione con Panda, però sembra funzionare bene!

Ecco lo script python:

#!/usr/bin/env python

from pandac.PandaModules import WindowProperties
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
import math

class MyApp(ShowBase):

	def __init__(self):
		ShowBase.__init__(self)

		# Load the environment model.
		self.environ = self.loader.loadModel("models/environment")
		# Reparent the model to render.
		self.environ.reparentTo(self.render)
		# Apply scale and position transforms on the model.
		self.environ.setScale(0.25, 0.25, 0.25)
		self.environ.setPos(-8, 42, 0)

		# Disable the default camera behavior
		base.disableMouse()
		# Add the mouseCameraTask procedure to the task manager.
		self.taskMgr.add(self.mouseCameraTask, "mouseCameraTask")

	# Define a procedure to move the camera.
	def mouseCameraTask(self, task):
		mw=base.mouseWatcherNode

		# Execute the Task only if the mouse is on the Panda window
		if mw.hasMouse():
			x=mw.getMouseX()
			y=mw.getMouseY()
			curr=self.camera.getHpr()
			self.camera.setHpr(curr.x-x*180/math.pi, curr.y+y*180/math.pi, 0)
			base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2)

		# Continue with the task
		return Task.cont

app = MyApp()
app.run()

Attenzione: vi consiglio di aggiungere un handler al tasto Esc per uscire, in quanto non riuscirete a raggiungere il tasto chiudi. Altrimenti dovete fare come me: usare le combinazioni di tasti Alt + Tab su GNOME per passare in un’altra finestra. In Windows dovrebbe essere sempre Alt + Tab o Super + Tab. In ogni caso lì c’è anche il Task Manager.

Socket e thread in Python

Chi è interessato a sviluppare un’applicazione che utilizzi in un modo anche semplice la rete deve spesso documentarsi sulle socket, in qualsiasi linguaggio di programmazione, anche per il python.

In questo campo ho lavorato più di una volta, però mi sono limitato alla creazione di socket con una sola connessione alla volta.

Tuttavia non è molto utile: penso che la maggior parte delle applicazioni pratiche richiedano più di un client connesso e “addirittura” la possibilità di dialogare tra di loro.

Quindi intervengono i thread.

Non so darvi la spiegazione tecnica di cosa siano, però so darvi una spiegazione pratica: i thread permettono di eseguire contemporaneamente più operazioni, senza però creare un altro processo. Il vantaggio è che si ottiene il famoso multi tasking.

Documentandomi ho trovato che uno degli svantaggi è che non avviene il controllo sull’uso contemporaneo di alcune risorse come file, tuttavia in questo caso usiamo solo la RAM e perciò non ci poniamo il problema.

In python usare i thread è abbastanza semplice: una volta importato il modulo threading o solamente la classe Thread da esso, bisogna estenderla e fare una funzione chiamata run in cui bisogna mettere il codice da eseguire. … [Leggi il resto]

Blender: ruotare la camera col mouse

Continuano i miei esperimenti con Blender.

Una delle mie più grandi domande riguardanti la game mode è: come fare per spostare la telecamera col movimento del mouse?

Beh, mi sono messo ad affrontare questo problema.

Il metodo che io utilizzerei è quello di analizzare il movimento del mouse e quindi di applicarlo alla rotazione.

Per fare ciò è mia intenzione associare uno script python al controller mousemove.

Ecco un prototipo di codice, con i commenti che spiegano cosa fa questo codice:

# Importa le librerie basi: la bge e classi utili da mathutils
import bge
from mathutils import *

# Comincia la funzione main
def main():

    # Prende l'oggetto del controller
    cont = bge.logic.getCurrentController()
    # Prende l'oggetto a cui il controller è applicato
    own = cont.owner
    # Per comodità ci salviamo i globalDict come obj
    obj = bge.logic.globalDict

    # Prendiamo il movimento del mouse
    mousemove=cont.sensors['Mousemove']
    pos=mousemove.position

    # Se è il primo movimento dobbiamo inizializzare i salvataggi dei movimenti
    if not 'mousepos' in obj:
        obj['mousepos']=pos

    # Salviamo il movimento
    obj['oldmousepos']=obj['mousepos']
    obj['mousepos']=pos

    # Troviamo le variazioni
    deltax=obj['mousepos']<sup><a id="entry111224-221225-rel-0" href="#entry111224-221225-fn-0" title="Note 0">0</a></sup>-obj['oldmousepos']<sup><a id="entry111224-221225-rel-0" href="#entry111224-221225-fn-0" title="Note 0">0</a></sup>
    deltay=obj['mousepos']<sup><a id="entry111224-221225-rel-1" href="#entry111224-221225-fn-1" title="Note 1">1</a></sup>-obj['oldmousepos']<sup><a id="entry111224-221225-rel-1" href="#entry111224-221225-fn-1" title="Note 1">1</a></sup>

    # Creiamo il vettore ed eseguiamo la rotazione lungo l'asse delle z (globale)
    rot=Vector((deltay*0.005, 0.0, -deltax*0.005))
    own.applyRotation(rot, False)

    # Creiamo il vettore ed eseguiamo la rotazione lungo l'asse delle y (locale della camera)
    rot=Vector((-deltay*0.005, 0.0, 0.0))
    own.applyRotation(rot, True)

# Esegue main, ogni volta che il mouse viene mosso
main()

Il risultato è ancora molto primitivo, ma sempre meglio che nulla 😉[Leggi il resto]

pyLoad

Qualche giorno fa avevo detto che mi serviva un downloader in stile jDownloader.

Quest’ultimo è ottimo, però ha due grossi problemi: è pesante e necessita di X.Org o un altro server X su Linux.

Così mi serviva un’alternativa le cui caratteristiche dovevano essere queste:

  1. Ovviamente funzionare su Linux (il muletto ha Debian 😉 )
  2. Essere più leggero di jDownloader
  3. Possibilmente essere software libero
  4. Non aver bisogno di un server X attivo
  5. Possibilmente non essere scritto in Java

Inizialmente stavo pensando di scrivermene uno io, però sarebbe stato difficile. Per la parte dell’interfaccia mi sarei accontentato, però mi sarebbe stata sicuramente utile la funzione di decodifica captcha automatica, troppo difficile per me.

Google mi ha aiutato: immediatamente mi ha dato ciò che cercavo: pyLoad.

Mi è subito parso buono: è multipiattaforma, è così leggero da funzionare anche sui router, è rilasciato sotto la GPL. È multi interfaccia: ha sia l’interfaccia a linea di comando, sia una grafica sia un’interfaccia web che volendo si può dotare di SSL. In più, si capisce subito dal nome, è scritto in python. … [Leggi il resto]

Plugin Local Cover Art [Picard]

È da quasi due anni che uso Music Brainz Picard, il programma di cui avevo già parlato che serve per taggare in automatico e con precisione la musica.

Già allora mi ero lamentato della mancanza del supporto delle copertine, cosa che, per chi ha un iPod Touch, è insopportabile.

All’inizio ho usato il plugin Cover Art Downloader, solo che il risultato non era del tutto soddisfacente: infatti il plugin non poteva distinguere le copertine belle da quelle meno.

La mia soluzione al problema allora è stata scaricare le copertine da Google immagini e inserirle con un altro programma: EasyTag. Come software quest’ultimo non è affatto male, però io continuavo a usare comunque Picard, perché più veloce, immediato e preciso e dover usare due programmi mi risultava scomodo.

Così oggi ho cambiato ancora le mie abitudini: per Picard è possibile scrivere plugin in python, linguaggio che mi piaciucchia, così ho scritto un plugin per fare da solo ciò che prima dovevo fare io, cioè cercare un’immagine chiamata Front.png o Front.jpg nella cartella dell’album e poi aggiungerla.

Non è stato proprio immediato da fare perché non conoscevo bene le API di MusicBrainz e il plugin da cui sono partito (Cover Art Downloader, di Oliver Charles e Philipp Wolfer) non andava più bene con la versione di Picard/Python della mia Debian Unstable.

Se avete voglia di provarlo, il file è localcoverart.py.

Va installato come tutti gli altri plugin del programma.

Per la licenza, fin quando non scoprirò quella del plugin originale è Creative Commons 3.0 con obbligo di Attribuzione: potete farne quel che volete, fino a quando io, Oliver Charles e Philipp Wolfer (gli autori del plugin da cui ho preso spunto) saremo riconosciuti come gli autori originali del plugin.