Added: A3->Extension animation state sync framework done. Test cases for animations created.

This commit is contained in:
jaynus 2015-05-11 11:01:53 -07:00
parent 1355662bfc
commit eee18bcd64
16 changed files with 160 additions and 18 deletions

Binary file not shown.

View File

@ -3,6 +3,8 @@
// Handle damage to local vehicles
[QGVAR(hp), FUNC(dispatchHitPart)] call EFUNC(common,addEventHandler);
// Extension dispatch commands
[QGVAR(setAnimationNames), FUNC(setAnimationNames)] call EFUNC(common,addEventHandler);
// Trigger and start fetching results
[FUNC(monitorResultsPFH), 0, []] call CBA_fnc_addPerFrameHandler;
[QGVAR(setAnimationNames), FUNC(setAnimationNames)] call EFUNC(common,addEventHandler);

View File

@ -13,6 +13,12 @@ GVAR(extensionLibrary) = "z\ace\extensions\build\vd\Debug\ace_vd.dll";
GVAR(async) = true;
GVAR(ready) = false;
// Extension dispatch events
PREP(setAnimationNames);
// To extension send events
PREP(getAnimationStates);
// Core functionality
PREP(registerVehicleDamageHandler);
PREP(registerVehicleWithExtension);
@ -23,6 +29,7 @@ PREP(dispatchDamage);
PREP(doHit);
GVAR(vehicle_id) = 0;
GVAR(vehicles) = HASH_CREATE;
FUNC(_textVector) = {
private["_str"];

View File

@ -0,0 +1,49 @@
#define DEBUG_MODE_FULL
#include "script_component.hpp"
private["_vehicleData", "_animationNames", "_animationResults", "_sendToExtension"];
PARAMS_1(_vehicle);
_sendToExtension = false;
if( (count _this) > 1) then {
_sendToExtension = true;
};
if((typeName _vehicle) != "OBJECT") then {
_vehicleData = HASH_GET(GVAR(vehicles),_vehicle);
TRACE_1("", _vehicleData);
if(isNil "_vehicleData") exitWith { nil };
_vehicle = _vehicleData select 0;
};
if(isNull _vehicle) exitWith {
diag_log text format["[ACE] - ERROR! Vehicle was null!!!"];
};
_animationNames = _vehicle getVariable[QGVAR(animationNames), nil];
if(isNil "_animationNames") exitWith {
diag_log text format["[ACE] - ERROR: Animations not loaded for vehicle [%1]", _vehicle];
};
_animationResults = [];
{
_animationResults pushBack [_x, (_vehicle animationPhase _x) ];
} forEach _animationNames;
TRACE_1("Returning", _animationResults);
if(_sendToExtension) then {
private["_cmd"];
_cmd = "set_animation_state:";
{
_cmd = _cmd + format["%1,%2,", (_x select 0), (_x select 1)];
} forEach _animationResults;
#ifdef DEBUG_MODE_FULL
TRACE_1("Updating Extension", _cmd);
copyToClipboard _cmd; // This was for debug saving animation states
#endif
_cmd call FUNC(callExtension);
};
_animationResults

View File

@ -6,7 +6,9 @@
GVAR(ready) = false;
#ifdef DEBUG_EXTENSION_DYNLOAD
#ifdef DEBUG_EXTENSION_DYNLOAD_RELOAD
"ace_dynload" callExtension format["unload:%1", GVAR(extensionLibrary)];
#endif
"ace_dynload" callExtension format["load:%1", GVAR(extensionLibrary)];
diag_log text format["[ACE] - DEBUG - Dynamic extension loaded for Vehicle Damage"];
#endif

View File

@ -1,21 +1,27 @@
//#define DEBUG_MODE_FULL
#include "script_component.hpp"
PARAMS_2(_args,_handle);
// params not used here to prevent debug spam
_args = _this select 0;
_handle = _this select 1;
private["_result"];
if(GVAR(ready)) then {
_result = "fetch_result:1" call FUNC(callExtension);;
while { _result != "" && {_result != "-1"} } do {
TRACE_1("", _result);
_result = "fetch_result:1" call FUNC(callExtension);;
_resultArgs = [_result] call FUNC(parseResult);
if(!isNil "_resultArgs") then {
if((_resultArgs select 0) == "exec") then {
TRACE_1("", "Dispatching exec");
[] call (_resultArgs select 1);
} else {
[format["ace_vehicledamage_%1", (_result select 0)], (_result select 1)] call EFUNC(common,localEvent);
_event = format["ace_vehicledamage_%1", (_resultArgs select 0)];
TRACE_3("Dispatch command", _event, (_resultArgs select 0), (_resultArgs select 1));
[_event, (_resultArgs select 1)] call EFUNC(common,localEvent);
};
};
// Pull next result
_result = "fetch_result:1" call FUNC(callExtension);
};
};

View File

@ -2,7 +2,7 @@
#include "script_component.hpp"
PARAMS_1(_vehicle);
private["_id", "_model"];
private["_id", "_model","_vehicleData"];
if(GVAR(Enabled) < 1) exitWith {};
@ -15,6 +15,8 @@ if(_model != "") then {
TRACE_1("", _value);
_result = _value call FUNC(callExtension);
_vehicle setVariable[QGVAR(id), _id, false];
_vehicleData = [_vehicle];
HASH_SET(GVAR(vehicles),_id,_vehicleData);
};
diag_log text format["[ACE] - Vehicle queued for extension loading %1 - %2=[%2]", _id, _vehicle, _model];

View File

@ -1,3 +1,16 @@
#define DEBUG_MODE_FULL
#include "script_component.hpp"
private["_id", "_vehicle", "_vehicleData"];
_id = parseNumber (_this select 0);
diag_log text format["ENTEERED!!!! %1", _this];
// The rest of the arguments in the array are just a stream of animation names
// remove the id
_this deleteAt 0;
_vehicleData = HASH_GET(GVAR(vehicles),_id);
TRACE_1("", _vehicleData);
if(!isNil "_vehicleData") then {
_vehicle = _vehicleData select 0;
_vehicle setVariable[QGVAR(animationNames), _this, false];
};

View File

@ -16,4 +16,5 @@
#define RELATIVE_VECTOR_TEXT(o,x) ([(o worldToModelVisual ((x) call EFUNC(common,ASLToPosition)))] call FUNC(_textVector))
#define DEBUG_EXTENSION_DYNLOAD
#define DEBUG_VEHICLEDAMAGE_RENDER
//#define DEBUG_EXTENSION_DYNLOAD_RELOAD
//#define DEBUG_VEHICLEDAMAGE_RENDER

View File

@ -124,10 +124,12 @@ namespace ace {
std::string function_str;
std::vector<std::string> temp = ace::split(args_.get(), ',');
function_str = temp[1] + ":";
for (int x = 2; x < temp.size(); x++)
function_str = function_str + temp[x] + ",";
if (temp.size() < 3) {
function_str = temp[1];
} else {
for (int x = 1; x < temp.size(); x++)
function_str = function_str + temp[x] + ",";
}
_modules[args_.as_string(0)].function((char *)result.c_str(), 4096, (const char *)function_str.c_str());
#ifdef _DEBUG
//if (args_.as_string(0) != "fetch_result" && args_.as_string(0) != "ready") {

View File

@ -4,4 +4,5 @@ debug_render:
register_vehicle:\A3\Armor_F_EPB\MBT_03\MBT_03_cannon_F.p3d,2,4050.18;3802.55;5.075
#hit:2,\A3\Armor_F_EPB\MBT_03\MBT_03_cannon_F.p3d,[],2,Sh_120mm_APFSDS,650,27,19100,50,10,708.602;235.609;-85.6468,-2.1748;0.139648;-1.35955,0.942743;0.31346;-0.113925,-1;6.1914e-007;0.000794772,-2.17383;0.139404;-1.32366,708.602;235.609;-85.6468
#register_vehicle:\a3\structures_f\mil\BagFence\BagFence_Long_F.p3d,0,4050.18;3802.55;5.075
#hit:0,A3\Structures_F\Mil\BagFence\BagFence_Long_F.p3d,[],0,B_65x39_Caseless,1295,264,11300,0,0,-16.5091;729.003;-177.406,0.2854;-0.239258;0.0619297,-0.0219989;0.971421;-0.236342,0.00232643;-0.999479;0.0321913
#hit:0,A3\Structures_F\Mil\BagFence\BagFence_Long_F.p3d,[],0,B_65x39_Caseless,1295,264,11300,0,0,-16.5091;729.003;-177.406,0.2854;-0.239258;0.0619297,-0.0219989;0.971421;-0.236342,0.00232643;-0.999479;0.0321913
fetch_result:1

View File

@ -8,7 +8,7 @@ using namespace ace::simulation;
namespace ace {
namespace vehicledamage {
base_vehicle::base_vehicle(uint32_t id, ace::simulation::object_p object_, ace::vector3<float> position_) : object(object_) {
base_vehicle::base_vehicle(uint32_t id, ace::simulation::object_p object_, ace::vector3<float> position_) : id(id), object(object_) {
bt_mesh = std::make_shared<btTriangleMesh>();
fire_lod = -1;
@ -54,6 +54,15 @@ namespace ace {
controller::get().bt_world->removeCollisionObject(bt_object.get());
}
bool base_vehicle::simulate() {
std::vector<uint32_t> lods;
lods.push_back(fire_lod);
object->animate(animation_state, lods);
return true;
}
void base_vehicle::transform() {
btTransform transform = bt_object->getWorldTransform();

View File

@ -23,17 +23,18 @@ namespace ace {
base_vehicle(uint32_t, ace::simulation::object_p, ace::vector3<float>);
~base_vehicle();
bool simulate();
void transform(void);
float surface_raycast(const ace::vector3<float> &, const ace::vector3<float> &, std::vector<ace::vector3<float>> &);
float thickness(const ace::vector3<float> &, const ace::vector3<float> &);
std::vector<ace::vector3<float>> selection_position(const uint32_t, const std::string &, const SELECTION_SEARCH_TYPE);
std::vector<ace::vector3<float>> selection_by_name_vertices(const uint32_t, const std::string &);
ace::simulation::named_selection_p selection_by_name(const uint32_t, const std::string &);
void transform(void);
// Bullet physx objects
uint32_t id;
int fire_lod;
ace::vector3<float> direction;
@ -44,6 +45,8 @@ namespace ace {
std::shared_ptr<btCollisionObject> bt_object;
std::shared_ptr<btRigidBody> bt_body;
std::map<std::string, float> animation_state;
ace::simulation::object_p object;
protected:

View File

@ -36,6 +36,7 @@ namespace ace {
add("delete_vehicle", std::bind(&ace::vehicledamage::controller::delete_vehicle, this, std::placeholders::_1, std::placeholders::_2));
add("set_vehicle_state", std::bind(&ace::vehicledamage::controller::set_vehicle_state, this, std::placeholders::_1, std::placeholders::_2));
add("set_animation_state", std::bind(&ace::vehicledamage::controller::set_animation_state, this, std::placeholders::_1, std::placeholders::_2));
add("hit", std::bind(&ace::vehicledamage::controller::handle_hit, this, std::placeholders::_1, std::placeholders::_2));
@ -113,9 +114,12 @@ namespace ace {
// For results on a valid vehicle registration, we return its animation names for that given vehicle
std::stringstream _animationNames;
_animationNames << _vehicle->id;
for (auto & anim : _vehicle->object->animations) {
_animationNames << anim->name << ",";
_animationNames << "," << anim->name;
_vehicle->animation_state[anim->name] = 0.0f;
}
this->push_result("setAnimationNames:"+_animationNames.str());
LOG(INFO) << "vehicle registered: [id=" << _args[1].as_uint32() << ", type=" << _args[0].as_string() << "]";
@ -139,6 +143,42 @@ namespace ace {
return true;
}
bool controller::set_animation_state(const arguments &_args, std::string & results) {
if (_args.size() < 3)
return false;
uint32_t id = _args[0];
// First value is id, following values are name,value,name,value,name,value
if (vehicles.find(id) == vehicles.end())
return false;
for (int x = 0, y = 0; x < vehicles[id]->animation_state.size() && x < _args.size() - 1; x++, y +=2) {
std::string animation_name = _args[y];
float state = _args[y + 1];
vehicles[id]->animation_state[animation_name] = state;
}
return false;
}
bool controller::get_animations(const arguments &_args, std::string & results) {
uint32_t id = static_cast<uint32_t>(_args[1]);
if (vehicles.find(id) == vehicles.end())
return false;
// For results on a valid vehicle registration, we return its animation names for that given vehicle
std::stringstream _animationNames;
_animationNames << vehicles[id]->id;
for (auto & anim : vehicles[id]->object->animations) {
_animationNames << "," << anim->name;
vehicles[id]->animation_state[anim->name] = 0.0f;
}
this->push_result("get_animations:" + _animationNames.str());
return false;
}
bool controller::set_vehicle_state(const arguments &_args, std::string & result) {
if (_args.size() < 3) return false;
@ -148,7 +188,7 @@ namespace ace {
vehicles[_args[0]]->direction = _args[1];
vehicles[_args[0]]->up = _args[2];
vehicles[_args[0]]->transform();
//vehicles[_args[0]]->transform();
return true;
}

View File

@ -29,9 +29,11 @@ namespace ace {
bool register_vehicle(const arguments &, std::string &);
bool delete_vehicle(const arguments &, std::string &);
bool set_animation_state(const arguments &, std::string &);
bool set_vehicle_state(const arguments &, std::string &);
bool handle_hit(const arguments & args, std::string &);
bool get_animations(const arguments &, std::string &);
bool get_thickness(const arguments &, std::string &);
bool selection_position(const arguments &, std::string &);
#ifdef _DEBUG

View File

@ -156,6 +156,9 @@ namespace ace {
batch.Begin();
// Debug animation the shit
_active_vehicle->simulate();
for (auto & face : obj.lods[lod]->faces) {
ace::vector3<float> vertices[3];
vertices[0] = { face->vertices[0]->x(), face->vertices[0]->y(), face->vertices[0]->z() };