Dev:Py/Scripts/Game Engine/BRIK ragdolls

提供: wiki
移動先: 案内検索
on hold

 Major changes are necessary due to a major misunderstanding of Blender functionality.

Important notes

The biggest issue that I have with the addon in it's current form is a nasty workaround that was necessary.

At the time of releasing the current version of the addon, limits on rigid body joint constraints can not be set from the Blender ui. Rotation limits on the rigid body joints are an essential part of creating realistic ragdoll structures.

A patch was added that wrapped the rigid body joint constraint limits in RNA and allowed them to be set through Python, however the convertor that translates Blender data to Blender Game Engine data appears to not function where rigid body joint constraints are concerned.

This is not as serious as it might at first appear since the spawning of rigid body structures consisting of multiple rigid body objects joined with rigid body joints can only be done object-by-object (as far as I can tell). This means that when adding the rigid body objects to a game scene individually, the rigid body joints are lost. I surmise that this is due to the objects that the rigid body joints join together being added individually, rather than as a connected pair of objects.

Because the rigid body joints need to be recreated at runtime anyway, it is a minor issue that they are not converted from Blender to Blender Game Engine correctly. Should they be converted correctly they could provide a reference for the newly created joints but could not actually act as joints since they get lost as the rigid bodies are added to the scene.

My workaround is to store the information required to create the rigid body joints in the game file that is created by the "Write game file" operator. The disadvantage to this is a large file to write in Blender and a large file to be read into the game engine. However, once this information is in the game engine and stored on the relevant objects the performance should be fairly similar to what could be expected if the rigid body joints were correctly converted in the first place.

A further point to note is that the rigid body joints are currently all "Generic 6DoF" joints. This is probably inefficient since the joints only need rotational freedom and not translational freedom. In a future iteration of this addon, I believe that the relatively recent "Cone twist" joints would be preferable to "Generic 6DoF" joints. However, I could not find any documentation on their use, and the lack of the ability to set joint limits from the Blender ui makes experimentation with them difficult.


TODO

Rewrite script as an addon.

IN PROGRESS
It works, but...
How to get register() and unregister() working?

Make spawn points per-scene rather than per-file.

BRIK currently only creates a new spawn point if there is no spawn point in the *.blend at all.
It needs to create a new spawn point and then ensure that the spawn point has a unique name.
This will probably need some bug checking also since spawn points have unique names and cannot be referenced by name.

Add utility functions/operators:

Implement rigid body mass calculation.
A simple mass calculation could be done accurately if the objects are trapezoid and two of the opposite sides are parallel.
Keeping the ends of the boxes parallel (those with normals parallel to bone y axis) would be most sensible.
Implement individual rigid body box resizing.
Would probably be best to leave the user to do this manually.
Simple box shapes is highly recommended due to the large number of rigid body objects.
This might be best implemented as two operators, one to copy the meshes from hit boxes to rigid body objects and one to copy the meshes the other way. This would simplify the workflow for the user whilst allowing for maximum usability.
Reposition armature/mesh on own layer.
Should this be left to the user?
Reposition rigid body boxes on own layer.
This could also be left to the user.
If another layer is shift+selected after the layer that the armature is on is selected then the armature remains visible and the objects are all added to the shift+selected layer.
Add armature and mesh to group also to enable simpler linking to scenes.
This is not necessary for the script to function correctly.
This should probably be left to the user although it should be fairly simple to implement.
Objects can be grouped by the script and group selected, the armature and mesh are just two more objects. This should not be too much of an effort for the user to do themself.

Version history

Version 0.0.4

CURRENTLY WIP
Added BRIK_can_hit property to hit-boxes in the logic creation so they can register ray hits.
Added code to shut down all action actuators near the end of BRIK_use_doll.py
This probably needs moving to BRIK_spawn_boxes.py since it's a nasty loop to run every logic tick.
BRIK_spawn_boxes.py renamed BRIK_init_ragdoll.py
Made all game engine scripts module based for efficiency.
Updated logic creation to use game engine scripts as modules.
Load game scripts at start of create_logic operator if not present.
Implemented set physics type to 'No collision' for armature and mesh.
Changed rigid body spawn logic to be triggered by a property changed sensor. This is a more generic solution.
NO LONGER NECESSARY
Implement check for group membership before modifying RB objects.
If RB object is a member of an incorrect group already then the new RB object needs to be named differently in order to prevent naming conflicts.
No longer needed now the reliance on a naming convention has been removed. :The bone_hit_box and bone_box dictionaries should be sufficient to check the validity of operations.


Version 0.0.3

Changed implementation of the file that is written for the game engine:
New format:
Armature name box['armature_name']
Base bone pivot offset x Vector from armature centre
Base bone pivot offset y to pivot of base bone
Base bone pivot offset z
Base bone pivot displacement x Vector from centre of base RB object
Base bone pivot displacement y to pivot of base bone
Base bone pivot displacement z
No line space here, but the following is given for each bone
Bone name box['bone_name']
RB object name box.name
Parent object name box['joint_target']
Hit box name
Bone rest world orientation w
Bone rest world orientation x
Bone rest world orientation y
Bone rest world orientation z
RB joint position x box['joint_position_x']
RB joint position y box['joint_position_y']
RB joint position z box['joint_position_z']
RB joint rotation limit max x box['rot_max_x']
RB joint rotation limit max y box['rot_max_y']
RB joint rotation limit max z box['rot_max_z']
RB joint rotation limit min x box['rot_min_x']
RB joint rotation limit min y box['rot_min_y']
RB joint rotation limit min z box['rot_min_z']
The new format should allow for faster parsing since only one iterator should be needed.
It should also allow for all the information needed to create the rigid body joints dynamically after the RB objects have been added to the scene using instantAddObject()
The order that the bones are in is the optimal order, as before.
The implementation of this can most likely be tidied up.
Implemented auto-setup of game logic on the armature.
NOT NEEDED
ragdoll_init boolean property to identify if ragdoll needs setting up.
BRIK_use_ragdoll boolean to determine if the BRIK_use_doll.py script should run.
Property sensor to run whenever ragdoll_use is True.
Connected to Python controller using BRIK_use_doll_0_3.py script.
NOT CURRENTLY IMPLEMENTED
Property sensor to run when ragdoll_use is False.
Might not be needed, just needs to enable action actuators.
Sensor to toggle ragdoll_use based on game conditions.
I have decided it is better to assign some data to the armature in it's ID properties.
Optimal ordering of RB objects.
The name of which RB object corresponds to which bone since the naming convention is to be relaxed.
The armature object now has the properties:
BRIK_optimal_order which is an ordered list of bone names in the most efficient order.
BRIK_bone_box_dict has bone names as keys and the corresponding box names as values.
Each box now has the properties:
bone_name stores the name of the bone corresponding to the box.
joint_target stores the name of the box to which a rigid body joint must be created.
There are also several properties to store the information needed to create the rigid body joint such as pivot location and rotation limits.
NOT CURRENTLY USED
bone_parent stores the name of the parent bone.
armature_name stores the name of the armature from which the rigid body structure is created.
hit_box stores the name of the hit box that the box will use to position and orient itself when rigid body dynamics is initiated.
Creation of hitboxes used to position and orient the RB objects after spawning has been implemented.
RIGID BODY OBJECTS NOW HAVE NO LOGIC. THE BELOW IS JUST FOR REFERENCE
Game logic for the RB objects is set up automatically.
dynamics_use boolean
dynamics_init boolean
Both of these might not be necessary.
A sensor to determine when to toggle dynamic or static. This will change the dynamics_use boolean. This is probably best set from the armature since all RB objects will need to be set simultaneously.
Property sensor with use_dynamics "changed" setting to trigger the script start_stop_dynamic.py. This script toggles whether the rigid body objects are static or driving the armature. When the objects transition to dynamic this script sets the position/orientation/LinV/AngV of the rigid bodies.
Implemented game engine script for loading data.
BRIK_load_0_1.py
Implemented game engine script for spawning mobs.
BRIK_spawn_mob_0_1.py
Implemented rigid body objects spawning when ragdoll is activated.
BRIK_spawn_boxes.py
Included setting of LinV and AngV from hit boxes to rigid bodies in BRIK_spawn_boxes.py
Updated the script for applying ragdoll motion to the armature.
BRIK_use_doll_0_3.py
Updated logic creation for BRIK_spawn_location to include BRIK_spawn_init.py
Updated logic creation for armature to include BRIK_spawn_boxes.py
NO LONGER REQUIRED
Removed logic creation on rigid body objects. BRIK_init_box.py is not required.
THIS IS COMMENTED OUT IN CASE IT NEEDS TO BE ADDED IN AGAIN
Implement game engine script for initialising rigid body objects.
BRIK_init_box_0_1.py
Restructured BRIK_alpha_0_0_3.py so operators are more sensibly separated.
Implemented parenting of hit boxes to bones.

Version 0.0.2

Rigid body driver objects are created from the bones in an armature. The armature can deform a mesh.
A custom prefix can be defined to append to the start of the rigid body driver object name.
Objects can be resized in a simple way.
Objects can be added to a group.
A text file can be generated to define the structure for use in the game engine.
Objects can be removed from the scene based on a prefix. Default prefix is that used to name the rigid body driver objects.
The generated text file can be automatically removed from the scene.
The generated ragdolls can be used in the game engine to drive a mesh bound to the armature.