Ich weiß nicht, ob es Absicht ist, aber der Algorithmus im Manual unter physX_open ist ein anderer als der, der tatsächlich implementiert ist.
Manual:
function physX_level_load()
{
if (level_ent)
pXent_settype(level_ent,PH_STATIC,PH_POLY);
for (you = ent_next(NULL); you; you = ent_next(you))
{
if (you.emask&DYNAMIC) continue; // only register static ents
if (you.flags&PASSABLE) continue; var type = ent_type(you);
if (type >= 2 && type <= 5) // blocks, models, or terrain
pXent_settype(you,PH_STATIC,PH_POLY);
}
}
function physX_ent_remove(ENTITY* ent)
{
if (ent.body) // unregister entity before removal
pXent_settype(ent,0,0);
}
function physX_open()
{
physX_load();
pX_setsteprate(60,8,0);
pX_setunit(1/40);
on_exit = physX_destroy;
on_level_load = physX_level_load;
on_ent_remove = physX_ent_remove;
while(1) {
physX_run(time_step/16);
wait(1);
}
}
In ackphysX.h:
function physX_level_load()
{
if (!NxPhysicsSDK) return;
if (level_ent)
pXent_settype(level_ent,PH_STATIC,PH_POLY);
for (you = ent_next(NULL); you; you = ent_next(you))
{
if (you.flags & PASSABLE) continue;
var type = ent_type(you);
if (type == 5 && (you.emask & DYNAMIC)) continue; // only register static models
if (type < 2 && type > 5) continue; // blocks, models, or terrain only
pXent_settype(you,PH_STATIC,PH_POLY);
}
on_level_load_px();
}
function physX_ent_remove(ENTITY* ent)
{
if (!NxPhysicsSDK) return;
if (ent.body)
pXent_settype(ent,0,0);
on_ent_remove_px(ent);
}
function physX_open()
{
if (NxPhysicsSDK) return; // already initialized
if (version < 8) {
error("PhysX only supported in A8!");
return;
}
if (level_ent) // level already loaded?
error("Open PhysX before loading level!");
NxPhysicsSDK = physX_load();
NxScene = physX_run(0);
pX_setsteprate(60,8,0);
pX_setunit(1/40);
on_exit_px = on_exit; // store previous on_exit function
on_exit = physX_close;
on_level_load_px = on_level_load;
on_level_load = physX_level_load;
on_ent_remove_px = on_ent_remove;
on_ent_remove = physX_ent_remove;
while(NxPhysicsSDK) {
#ifdef FIXED_TIME
//This for-loop fixes the physX framerate to 60 when the frame rate is below 60 fps
int loc_n = integer(time_step * 60 / 16) + 1;
int loc_i = 0;
if (freeze_mode <= 0)
for (; loc_i < loc_n; loc_i++)
physX_run(0);
#else
if (freeze_mode <= 0)
physX_run(time_step/16);
#endif
wait(1);
}
}
Was das ausmacht? Ich habe, da ich meine physX_level_load-Funktion anpassen musste, natürlich das Code-Beispiel aus dem Manual genommen und mich gewundert, warum das Spiel bei manchen Level-Wechseln abstürzte.
EDIT: Wenn ich in meinem Level PH_CHAR-Entities (BOX oder CAPSULE) registriere, erhalte ich einen invalid pointer/ handle im eigentlichen physX_open (oder meiner eigenen Funktion), wenn ich sie wieder aus der Physik-Registrierung löschen möchte (ganz mit settype(0,0) oder temporär mit enable(0)).
PH_CAR-Entities bekommen keinen entity.body-Physik-Pointer zugewiesen, korrekt?