Hallo erneut - ich konnte das GFA-Repository nutzen um anhand dessen einen alleinstehenden funktionierenden Ansatz für RayCasts zu realisieren (der Code entstammt 1:1 mud-freaks GFA-Mod / Patch, weshalb allem Dank auch ihm gebührt ! ).
Mir ging es in erster Linie darum eine Möglichkeit zu finden einen RayCast durchzuführen um zu ermitteln "wohin der Spieler" blickt - ähnlich zu der Methode
https://docs.unity3d.com/ScriptRefer...s.Raycast.html aus Unity3D oder der Unreal Engine (https://docs.unrealengine.com/en-US/...nel/index.html)
Code:
// the last raytraced positions after calling doRayTrace()
var int currentPositionX;
var int currentPositionY;
var int currentPositionZ;
func void doRayTrace(){
// the max. distance of the ray
var int distance; distance = 10000;
// Get camera vob and player
var zCVob camVob; camVob = _^(MEM_Game._zCSession_camVob);
var zMAT4 camPos; camPos = _^(_@(camVob.trafoObjToWorld[0]));
var oCNpc her; her = getPlayerInstance();
var int herPtr; herPtr = _@(her);
// Shift the start point for the trace ray beyond the player model. This is necessary, because if zooming out
// (a) there might be something between camera and hero (unlikely) and
// (b) the maximum aiming distance is off and does not correspond to the parameter 'distance'
// To do so, the distance between camera and player is computed:
var int distCamToPlayer; distCamToPlayer = sqrtf(addf(addf( // Does not care about camera X shift, see below
sqrf(subf(her._zCVob_trafoObjToWorld[ 3], camPos.v0[zMAT4_position])),
sqrf(subf(her._zCVob_trafoObjToWorld[ 7], camPos.v1[zMAT4_position]))),
sqrf(subf(her._zCVob_trafoObjToWorld[11], camPos.v2[zMAT4_position]))));
// The distance is used to create the direction vector in which to cast the trace ray
distance = mkf(distance);
// This array holds the start vector (world coordinates) and the direction vector (local coordinates)
var int traceRayVec[6];
traceRayVec[0] = addf(camPos.v0[zMAT4_position], mulf(camPos.v0[zMAT4_outVec], distCamToPlayer));
traceRayVec[1] = addf(camPos.v1[zMAT4_position], mulf(camPos.v1[zMAT4_outVec], distCamToPlayer));
traceRayVec[2] = addf(camPos.v2[zMAT4_position], mulf(camPos.v2[zMAT4_outVec], distCamToPlayer));
traceRayVec[3] = mulf(camPos.v0[zMAT4_outVec], distance); // Direction-/to-vector of ray
traceRayVec[4] = mulf(camPos.v1[zMAT4_outVec], distance);
traceRayVec[5] = mulf(camPos.v2[zMAT4_outVec], distance);
// The trace ray uses certain flags. These are very important the way they are and have been carefully chosen
// and tested. Although the descriptions might be misleading, they should not be changed under any circumstances
// especially the flag to ignore alpha polygons is counter intuitive, since that means that gates and fences
// will be ignored although they have collision. However, this flag is buggy. It NEEDS to be present otherwise
// artifacts will arise, like pseudo-random ignoring of walls and objects.
var int flags; flags = zTRACERAY_vob_ignore_no_cd_dyn
| zTraceRay_poly_normal
| zTRACERAY_poly_ignore_transp // Do not change (will make trace ray unstable)
| zTRACERAY_poly_test_water
| zTRACERAY_vob_ignore_projectiles;
var int fromPosPtr; fromPosPtr = _@(traceRayVec);
var int dirPosPtr; dirPosPtr = _@(traceRayVec)+sizeof_zVEC3;
var int worldPtr; worldPtr = _@(MEM_World);
const int call = 0;
if (CALL_Begin(call)) {
CALL_IntParam(_@(flags)); // Trace ray flags
CALL_PtrParam(_@(herPtr)); // Ignore player model
CALL_PtrParam(_@(dirPosPtr)); // Trace ray direction
CALL_PutRetValTo(_@(hit)); // Did the trace ray hit
CALL__fastcall(_@(worldPtr), _@(fromPosPtr), zCWorld__TraceRayNearestHit_Vob);
call = CALL_End();
};
// Retrieve trace ray report
var int foundVob; foundVob = MEM_World.foundVob;
var int intersection[3];
MEM_CopyBytes(_@(MEM_World.foundIntersection), _@(intersection), sizeof_zVEC3);
// update the result of the intersection to some global values and use them as X,Y,Z-Coords.
currentPositionX = intersection[0];
currentPositionY = intersection[1];
currentPositionZ = intersection[2];
// needed for allocation
var int hit;
};