From 657830291b893028a285767039736a482f2378e4 Mon Sep 17 00:00:00 2001 From: ebaydayz Date: Sat, 30 Jul 2016 10:34:25 -0400 Subject: [PATCH] Updated vanilla Collision system Vanilla development commit: https://github.com/DayZMod/DayZ/commit/0a1db17343f0eb828c60f08c28c06e571ee366cf --- SQF/dayz_code/actions/fn_collisions.sqf | 108 ++++++++++++++++++ SQF/dayz_code/actions/player_buildVanilla.sqf | 38 +++--- SQF/dayz_code/init/compiles.sqf | 3 + SQF/dayz_code/util/Vector.hpp | 2 +- 4 files changed, 131 insertions(+), 20 deletions(-) create mode 100644 SQF/dayz_code/actions/fn_collisions.sqf diff --git a/SQF/dayz_code/actions/fn_collisions.sqf b/SQF/dayz_code/actions/fn_collisions.sqf new file mode 100644 index 000000000..146139bcf --- /dev/null +++ b/SQF/dayz_code/actions/fn_collisions.sqf @@ -0,0 +1,108 @@ +#include "\z\addons\dayz_code\util\Vector.hpp" + +_project = +{ + private ["_verts","_axis","_min","_max"]; + local _verts = +(_this select 0); + local _axis = _this select 1; + + { _verts set [_foreachIndex, Vector_DotProduct_Fast(_axis, _x)] } foreach _verts; + + local _min = _verts select 0; + local _max = _min; + + { + if (_x < _min) then + { _min = _x }; + + if (_x > _max) then + { _max = _x }; + } + foreach _verts; + + [_min, _max] +}; + +_notOverlap = +{ + #define AMIN (_this select 0 select 0) + #define AMAX (_this select 0 select 1) + #define BMIN (_this select 1 select 0) + #define BMAX (_this select 1 select 1) + + AMAX < BMIN || AMIN > BMAX +}; + +_boundingBoxVertices = +{ + private ["_min","_max","_verts","_v"]; + local _min = _this select 0; + local _max = _this select 1; + local _verts = [_min, _max]; + _verts resize 8; + + local _v = +_min; + _v set [0, _max select 0]; + _verts set [2, +_v]; + _v set [1, _max select 1]; + _verts set [3, +_v]; + + _v = +_min; + _v set [1, _max select 1]; + _verts set [4, +_v]; + _v set [2, _max select 2]; + _verts set [5, +_v]; + + _v = +_min; + _v set [0, _max select 0]; + _verts set [6, +_v]; + _v set [2, _max select 2]; + _verts set [7, _v]; + + _verts +}; + +_modelToWorld = +{ + private ["_object","_verts"]; + local _object = _this select 0; + local _verts = _this select 1; + + { _verts set [_foreachIndex, _object modelToWorld _x] } foreach _verts; + + _verts +}; + +_getAxes = +{ + private ["_dir","_up","_side"]; + local _dir = vectorDir _this; + local _up = vectorUp _this; + + local _side = Vector_Rotate3D_Fast(_dir, _up, 90); + + [_dir, _side, _up] +}; + +_collision = +{ + private ["_abb","_bbb","_averts","_bverts","_axes","_result"]; + local _abb = boundingBox (_this select 0); + local _bbb = boundingBox (_this select 1); + local _averts = [_this select 0, _abb call _boundingBoxVertices] call _modelToWorld; + local _bverts = [_this select 1, _bbb call _boundingBoxVertices] call _modelToWorld; + + local _axes = (_this select 0 call _getAxes) + (_this select 1 call _getAxes); + + local _result = true; + + { + if ([[_averts, _x] call _project, [_bverts, _x] call _project] call _notOverlap) exitWith + { _result = false }; + } + foreach _axes; + + _result +}; + +_this call _collision; diff --git a/SQF/dayz_code/actions/player_buildVanilla.sqf b/SQF/dayz_code/actions/player_buildVanilla.sqf index 565e35f10..a2c302a81 100644 --- a/SQF/dayz_code/actions/player_buildVanilla.sqf +++ b/SQF/dayz_code/actions/player_buildVanilla.sqf @@ -163,19 +163,18 @@ _insideCheck = { _building = _this select 0; _unit = _this select 1; - if ((typeOf _building != "") and {( - (sizeOf (typeOf _building) < 8) or {(_unit distance _building > (sizeOf (typeOf _building) + sizeOf (typeOf _unit))/2)} - )}) exitwith {false}; - + + if ((typeOf _building != "") and {((sizeOf (typeOf _building) < 8) or {(_unit distance _building > (sizeOf (typeOf _building) + sizeOf (typeOf _unit))/2)})}) exitwith {false}; + _bbb = boundingBox _building; _ubb = boundingBox _unit; - + _check = { _min = _bbb select 0; _max = _bbb select 1; _myX = _p select 0; _myY = _p select 1; - + (((_myX > (_min select 0)) and {(_myX < (_max select 0))}) and {((_myY > (_min select 1)) and {(_myY < (_max select 1))})}) }; @@ -198,28 +197,29 @@ _checkBuildingCollision = { { _inside = false; _ownerID = _x getVariable ["ownerArray",[]]; - - if (count _ownerID > 0) then { _ownerID = _ownerID select 0; } else { _ownerID = (getPlayerUID player); }; - //and (!(_x isKindOf "DZ_buildables")) Not used - + if (count _ownerID > 0) then { _ownerID = _ownerID select 0; } else { _ownerID = (getPlayerUID player); }; + + if (_object in ["WoodenFence_ghost","MetalFence_ghost","WoodenGate_ghost","MetalGate_ghost"]) then {}; + if(_ownerID != (getPlayerUID player)) then { - if ((!isNull _x) and (!(_x == player)) and (!(_x == _object)) and (!(_x IN DayZ_SafeObjects)) - and (!((typeOf _x == "CamoNet_DZ") or {(_x isKindOf "Land_CamoNet_EAST")}))) then { + if ((!isNull _x) and (!(_x == player)) and (!(_x == _object)) ) then { if ((_x isKindOf "Building") or (_x isKindOf "AllVehicles")) then { - _inside = [_x, _object] call _insideCheck; - - /* + //_inside = [_object, _x] call _insideCheck; + _inside = [_object, _x] call fn_collisions; + if (!_inside) then { - _inside = [_object, _x] call _insideCheck; + //_inside = [_x, _object] call _insideCheck; + _inside = [_x, _object] call fn_collisions; }; - */ }; }; }; + if (_inside) exitWith { _objColliding = _x; }; } forEach (nearestObjects [_object, ["Building", "Air", "LandVehicle", "Ship", "DZ_buildables"], 35]); - (!isNull _objColliding) + + (!isNull _objColliding) // _objColliding contains the building that collides with the ghost object }; @@ -385,7 +385,7 @@ while {r_action_count != 0 and Dayz_constructionContext select 4} do { }; }; }; - uiSleep 0.03; + uiSleep 0.01; }; if (!_actionBuildHidden) then { // player can't build until all is fine diff --git a/SQF/dayz_code/init/compiles.sqf b/SQF/dayz_code/init/compiles.sqf index 85c8b43e7..1d6af9f57 100644 --- a/SQF/dayz_code/init/compiles.sqf +++ b/SQF/dayz_code/init/compiles.sqf @@ -63,6 +63,9 @@ if (!isDedicated) then { object_setpitchbank = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\fn_setpitchbank.sqf"; object_monitorGear = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\object_monitorGear.sqf"; object_dismantle = compile preprocessFileLineNumbers "\z\addons\dayz_code\actions\object_dismantle.sqf"; + + //Collisions + fn_collisions = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\fn_collisions.sqf"; //Zombies zombie_findTargetAgent = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\zombie_findTargetAgent.sqf"; diff --git a/SQF/dayz_code/util/Vector.hpp b/SQF/dayz_code/util/Vector.hpp index 93af4bd51..515da0286 100644 --- a/SQF/dayz_code/util/Vector.hpp +++ b/SQF/dayz_code/util/Vector.hpp @@ -82,6 +82,6 @@ Author: Foxy //Rotates the vector around the specified axis by the specified angle in degrees, in three dimensions. #define Vector_Rotate3D(v, u, deg) ([v, u, deg] call dz_fn_vector_rotate3d) -#define Vector_Rotate3D_Fast(v, u, deg) [((v)select0)*(((u)select0)^2*(1-cos(deg))+cos(deg))+((v)select1)*(((u)select0)*((u)select1)*(1-cos(deg))-((u)select2)*sin(deg))+((v)select2)*(((u)select0)*((u)select2)*(1-cos(deg))+((u)select1)*sin(deg)),((v)select0)*(((u)select1)*((u)select0)*(1-cos(deg))+((u)select2)*sin(deg))+((v)select1)*(((u)select1)^2*(1-cos(deg))+cos(deg))+((v)select2)*(((u)select1)*((u)select2)*(1-cos(deg))-((u)select0)*sin(deg)),((v)select0)*(((u)select2)*((u)select0)*(1-cos(deg))-((u)select1)*sin(deg))+((v)select1)*(((u)select2)*((u)select1)*(1-cos(deg))+((u)select0)*sin(deg))+((v)select2)*(((u)select2)^2*(1-cos(deg))+cos(deg))] +#define Vector_Rotate3D_Fast(v, u, deg) [Vector_X(v) * (Vector_X(u)^2 * (1 - cos(deg)) + cos(deg)) + Vector_Y(v) * (Vector_X(u) * Vector_Y(u) * (1 - cos(deg)) - Vector_Z(u) * sin(deg)) + Vector_Z(v) * (Vector_X(u) * Vector_Z(u) * (1 - cos(deg)) + Vector_Y(u) * sin(deg)), Vector_X(v) * (Vector_Y(u) * Vector_X(u) * (1 - cos(deg)) + Vector_Z(u) * sin(deg)) + Vector_Y(v) * (Vector_Y(u)^2 * (1 - cos(deg)) + cos(deg)) + Vector_Z(v) * (Vector_Y(u) * Vector_Z(u) * (1 - cos(deg)) - Vector_X(u) * sin(deg)), Vector_X(v) * (Vector_Z(u) * Vector_X(u) * (1 - cos(deg)) - Vector_Y(u) * sin(deg)) + Vector_Y(v) * (Vector_Z(u) * Vector_Y(u) * (1 - cos(deg)) + Vector_X(u) * sin(deg)) + Vector_Z(v) * (Vector_Z(u)^2 * (1 - cos(deg)) + cos(deg))] #endif \ No newline at end of file