Community Forum Coding Script, addon e temi Script Ragdoll from Armature

Stai visualizzando 6 post - dal 1 a 6 (di 6 totali)
  • Autore
    Post
  • Anfeo
    Membro
    @anfeo
    #3109

    Da circa una decina di giorni sto colmando una delle mie più grandi lacune in Blender, ovvero lo scripting.

    Come primo esercizio ho deciso di creare uno script che da un Armature, crei una Ragdoll.

    Per chi non lo sapesse, ecco un esempio di ragdoll preso da Yotube:

    [youtube]Qn-jDcKkR0k[/youtube]

    In pratica si tratta di un fantoccio che reagisce alla fisica Rigid Body.

    La grande limitazione di questa pratica è che è molto difficile trasmettere il movimento dei Box su un persoanggio, a meno che non si utilizzi un Armature e si applichino delle contraint a ogni osso.

    Lo script qui sotto fa appunto questo, crea dei Box sull’Armature e ne setta fisica e constraint in automatico. Basta premere P e la Ragdoll fa il suo dovere.

    Siccome non ho scoperto l’acqua calda, Gillan mi ha segnalato che esisteva già  uno script simile per Blender 2.49:

    http://www.youtube.com/watch?v=MzNIRT-9cRo

    Allora mi sono studiato tale script e praticamente ne ho rifatto uno per la 2.5, mantenendo però lo stesso algoritmo dello script per la 2.5, soprattutto per la creazione dei Box.

    Ecco lo script:

    Code:

    # ##### BEGIN GPL LICENSE BLOCK #####
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software Foundation,
    # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ##### END GPL LICENSE BLOCK #####

    import bpy
    from mathutils import Vector

    def drawBox(ht,wdh, wdt, ofs):

    ht = ht-(ht*ofs); bs = ht*ofs
    verts = [[-wdh,bs,-wdh],[-wdh,bs,wdh],[wdh,bs,wdh],[wdh,bs,-wdh],[-wdt,ht,-wdt],[-wdt,ht,wdt],[wdt,ht,wdt],[wdt,ht,-wdt]]
    faces = [[3,2,1,0], [4,5,6,7],[7,6,2,3],[0,4,7,3],[0,1,5,4],[1,2,6,5]]
    edges = []## A ## ## B ## ## C ## ## D ## ## E ## ## F ##

    mesh = bpy.data.meshes.new(‘hitMesh’)
    mesh.from_pydata(verts, edges, faces)
    mesh.update()

    nob = bpy.data.objects.new(‘obj’,mesh)

    bpy.data.scenes[0].objects.link(nob)

    return nob

    def createRagObj (bone, offset, obj):

    obmat= obj.matrix_world
    #print (obmat)

    #this is the default choice for the ragdoll object radius
    #rag = drawBox(bone.length, bone.length/10,bone.length/10, offset)

    rag = drawBox(bone.length, bone.head_radius, bone.tail_radius, offset)
    rag.name = bone.name

    bonemat = bone.matrix_local
    #print (bonemat)

    rag.matrix_local = bonemat*obmat

    return rag

    def rigidBodySetup (rag, bone):

    rag_g = rag.game
    rag_g.physics_type = ‘RIGID_BODY’
    rag_g.use_collision_bounds = 1
    rag_g.damping = 0.4
    rag_g.collision_bounds_type = ‘BOX’
    rag_g.rotation_damping = 0.4

    volume = bone.length*((bone.tail_radius*bone.tail_radius)*3.14)
    rag_g.radius = bone.length/2
    rag_g.mass = volume
    print (‘Volume:’,volume)
    #print (rag)

    return

    def constraintJointSetup (rag, rag_target):
    #print (‘Ragdoll Target: ‘,rag_target.name)
    rag_j = rag.constraints.new(‘RIGID_BODY_JOINT’)

    rag_j.target = rag_target
    rag_j.use_linked_collision = True

    return

    def constraintCopyRotLoc (pose_bone, rag):

    rag_R = pose_bone.constraints.new(‘COPY_ROTATION’)
    rag_R.target = rag

    rag_L = pose_bone.constraints.new(‘COPY_LOCATION’)
    rag_L.target = rag

    return

    class Ragdoll(bpy.types.Operator):
    ”””
    bl_idname = “object.ragdoll”
    bl_label = “Ragdoll From Armature”
    bl_options = {‘REGISTER’, ‘UNDO’}

    @classmethod
    def poll(cls, context):
    return context.active_object != None

    def execute(self, context):
    obj = context.object
    Arm = obj.type

    # Control that the active object is ad Armature
    if Arm != ‘ARMATURE’:
    print (“You may select an Armature”)
    return {‘FINISHED’}

    # Processing each Bone in armature:
    bones = context.active_object.data.bones
    pose_bones = context.active_object.pose.bones

    for bone in bones:

    print (‘***********************’)
    print (‘Bone Name:’,bone.name)

    print (‘Radius:’, bone.tail_radius)

    # Control that the processed bone have a use Deform active.
    # This don’t make a Ragdoll object over controll bone, but only on Deform bone.
    if bone.use_deform:

    #Control that the parent bone use deform
    #This say at the script that there isn’t a ragdoll object to joint
    #if the parent are set with not-deform.
    if bone.parent and bone.parent.use_deform:

    RigidJoint = True
    print (‘Target Object:’,bone.parent.name)
    rag_target_name = bone.parent.name

    rag_target = bpy.data.objects[rag_target_name]
    else:

    RigidJoint = False
    print (‘Target Object: None’)
    rag_target = None

    print (‘Ragdoll Object Name :’ + bone.name)

    ########### create rag_object

    offset= 0.05 #variabile da ricavare dalla gui su scelta utente
    #con 0.05 le basi del Hitbox sono a filo dei tails e degli Heads delle ossa
    #con 0.01 le basi tagliano i tails e gli heads nel centro della sfera

    rag = createRagObj (bone, offset, obj)

    ############setup Rigid Body ong Ragobject

    rigidBodySetup (rag, bone)

    ##########setup Rigid Body Joint constraint
    if RigidJoint:

    constraintJointSetup (rag, rag_target)

    ##########Setup ChildOf constraint
    if rag:
    pose_bone = pose_bones[bone.name]
    constraintCopyRotLoc (pose_bone, rag)

    print (‘***********************’)
    print (‘You have %s bones’ % len(bones))

    return {‘FINISHED’}

    if __name__ == “__main__”:
    bpy.ops.object.ragdoll()

    Spiegazioni per l’utilizzo:

    – create un Armatura e annullate scala, rotazione e posizione con Alt+s, Alt+r e Alt+G

    – copiate lo script in una finestra Text e con l’armatura selezionata fate Run Script

    – premete P e la Ragdoll cade (dovete mettere un plane sotto se no cade nell’infinito).

    – per far muovere le ossa tramite i Box, dovete entrare in edit mode sull’armatura e cancellare tutti i parent con Alt+P

    – Lo script crea dei Box sulle ossa, ne setta la fisica e collega le pose delle ossa sui Box.

    – La dimensione delle basi dei box è data dal raggio degli Envelope (questa voglio renderla un opzione e lasciare di defult che il raggio sia 1/10 della lunghezza delle ossa)

    – Cambiando il valore di Oft, si cambia la lunghezza dei box (anche questo valore andrà  messo nella gui).

    Ora sto preparando la GUI (il pannello di controllo per settare alcuni parametri e lanciare lo script.

    In oltre volevo mettere in GUI anche tutti i parametri di rigid body, in questo modo si ha più libertà  di configurazione.

    Spero vi sia utile.

    ciao

    P.S. siccome è ancora in wip non sapevo se postarlo in risorse o meno… ditemi voi.. ➡

    Ego
    Membro
    @ego
    #71113

    Seguo e aspetto con ansia la gui

    Bernardo
    Membro
    @sdados
    #71114

    interessante!! seguo anche io!

    Anfeo
    Membro
    @anfeo
    #71115

    Ecco la seconda alpha (se la possiamo chiamare così) con GUI, questa volta l’ho trasformata in un Add-ons, per usarla basta copiare lo script nella cartella Add-ons di Blendere e attivare l’Add-on dalle user preferences.

    Ditemi se vi funziona, perché l’ho fatta con una delle ultime build di Blender 2.54.

    [attachment=3806:Ragdoll_02.py.zip]

    Utilizzo:

    – selezionate l’armatura e andata nel pannello object data dell’armatura

    – in fondo compare il menù Ragdoll from Armature

    – cambiando il valore di offset, modificate la lunghezza di Box.

    – Per modificarne la larghezza dovete agire sulla dimensione degli Envelope

    – Quando premete Make Ragdoll, vi crea la ragdoll, al momento crea una ragdoll sull’altra ogni volta che premete il tasto, ora sto lavorando per cercare di far sovrascrivere la ragdoll e cancellare quella vecchia ad ogni pressione del tasto. Basta fare ctrl+z per annullare la creazione di una ragdoll e cambiare il valore di offset. Se create più di una ragdoll quando premete P per il GE i box risulteranno disconnessi.

    – Crea Box su Bone settate su Deform (ma ci metto un opzione anche per quello)

    Se avete dei feedback ben vengano, soprattutto se volete che inserisca qualche opzione in più da settare oltre a quelle citate nel post precedente. https://community.blender.it/uploads/monthly_03_2011/post-118-1301573376,7092.ipb

    Anfeo
    Membro
    @anfeo
    #71116

    Fixati i problemi replace e inserite nuove opzioni dal pannello di controllo. https://community.blender.it/uploads/monthly_03_2011/post-118-1301573378,09.ipb

    Armageddon12
    Membro
    @armageddon12
    #71117

    Aspetta, quindi fammi capire bene….

    L'add-on che hai fatto mi permette di fare un armature a ragdoll diciamo con la fisica esempio Endorphin….

    Ma questa armatura dopo la posso collegare alla mesh e fare in modo che anche la mesh segui la ragdoll o avrò problemi?

    E ultima cosa…; se volessi fare in modo che l'armatura abbia animazioni varie come correre, colpire ecc (insomma le solite animazioni classiche degli open world) e che quando viene colpita segui la ragdoll come potrei fare dal punto di vista tecnico questo scambio?

Stai visualizzando 6 post - dal 1 a 6 (di 6 totali)
  • Devi essere connesso per rispondere a questo topic.