mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Added: A3->Extension animation state sync framework done. Test cases for animations created.
This commit is contained in:
parent
1355662bfc
commit
eee18bcd64
BIN
ace_dynload.dll
BIN
ace_dynload.dll
Binary file not shown.
@ -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);
|
@ -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"];
|
||||
|
49
addons/vehicledamage/functions/fnc_getAnimationStates.sqf
Normal file
49
addons/vehicledamage/functions/fnc_getAnimationStates.sqf
Normal 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
|
@ -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
|
||||
|
@ -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);
|
||||
};
|
||||
};
|
@ -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];
|
@ -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];
|
||||
};
|
@ -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
|
@ -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") {
|
||||
|
@ -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
|
@ -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();
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() };
|
||||
|
Loading…
Reference in New Issue
Block a user