архитектура и цели для агентов
This commit is contained in:
@@ -365,10 +365,11 @@ void ADTLoader::_parse_adt(const uint8_t *raw, size_t len, Dictionary &result) {
|
||||
adt_placement_rot_to_godot(dd[i].rot[0], dd[i].rot[1], dd[i].rot[2], rx, ry, rz);
|
||||
|
||||
Dictionary p;
|
||||
p["name_id"] = (int)dd[i].nameId;
|
||||
p["pos"] = Vector3(gx, gy, gz);
|
||||
p["rot"] = Vector3(rx, ry, rz);
|
||||
p["scale"] = dd[i].scale / 1024.f;
|
||||
p["name_id"] = (int)dd[i].nameId;
|
||||
p["unique_id"] = (int)dd[i].uniqueId;
|
||||
p["pos"] = Vector3(gx, gy, gz);
|
||||
p["rot"] = Vector3(rx, ry, rz);
|
||||
p["scale"] = dd[i].scale / 1024.f;
|
||||
m2_placements.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// ADTLoader
|
||||
//
|
||||
// Loads WoW 3.3.5a ADT terrain tiles.
|
||||
@@ -32,13 +31,13 @@ namespace godot {
|
||||
// "wmo_names": PackedStringArray, # WMO filenames
|
||||
// "m2_placements": Array[Dictionary],
|
||||
// "wmo_placements": Array[Dictionary],
|
||||
// "chunks": Array[Dictionary], # 16×16 = 256 entries, row-major
|
||||
// "chunks": Array[Dictionary], # 16x16 = 256 entries, row-major
|
||||
// }
|
||||
//
|
||||
// Placement Dictionary (both M2 and WMO):
|
||||
// {
|
||||
// "name_id": int, # index into m2_names / wmo_names
|
||||
// "unique_id": int, # WMO only — MODF uniqueId (dedupe key across tiles)
|
||||
// "unique_id": int, # MDDF/MODF uniqueId (dedupe key across tiles)
|
||||
// "pos": Vector3, # Godot world coords
|
||||
// "rot": Vector3, # Euler angles (radians)
|
||||
// "scale": float, # M2 only (WMO always 1.0)
|
||||
@@ -52,7 +51,7 @@ namespace godot {
|
||||
// "index_x": int, # 0-15
|
||||
// "index_y": int, # 0-15
|
||||
// "origin": Vector3, # Godot world position of chunk origin
|
||||
// "heights": PackedFloat32Array, # 145 values (9×9 outer + 8×8 inner grid)
|
||||
// "heights": PackedFloat32Array, # 145 values (9x9 outer + 8x8 inner grid)
|
||||
// "normals": PackedVector3Array, # 145 normals
|
||||
// "holes": int, # hole bit mask (low 16 bits)
|
||||
// "layers": Array[Dictionary], # texture layer definitions
|
||||
@@ -66,7 +65,6 @@ namespace godot {
|
||||
// "effect_id": int,
|
||||
// "alpha_offset": int,
|
||||
// }
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
class ADTLoader : public RefCounted {
|
||||
GDCLASS(ADTLoader, RefCounted)
|
||||
|
||||
|
||||
@@ -389,6 +389,34 @@ static Vector4 decode_comp_quat(const uint16_t q[4]) {
|
||||
return wow_quat_to_godot(x, y, z, w);
|
||||
}
|
||||
|
||||
static Vector4 decode_comp_quat_raw(const uint16_t q[4]) {
|
||||
float x = ((float)q[0] - 32768.0f) / 32767.0f;
|
||||
float y = ((float)q[1] - 32768.0f) / 32767.0f;
|
||||
float z = ((float)q[2] - 32768.0f) / 32767.0f;
|
||||
float w = ((float)q[3] - 32768.0f) / 32767.0f;
|
||||
return normalize_quat(x, y, z, w);
|
||||
}
|
||||
|
||||
static Vector4 texture_quat_to_uv_rotation(const Vector4 &q) {
|
||||
float x = q.x;
|
||||
float y = q.y;
|
||||
float z = q.z;
|
||||
float w = q.w;
|
||||
return Vector4(
|
||||
1.0f - 2.0f * (y * y + z * z),
|
||||
2.0f * (x * y - z * w),
|
||||
2.0f * (x * y + z * w),
|
||||
1.0f - 2.0f * (x * x + z * z));
|
||||
}
|
||||
|
||||
static float texture_quat_z_angle(const Vector4 &q) {
|
||||
float x = q.x;
|
||||
float y = q.y;
|
||||
float z = q.z;
|
||||
float w = q.w;
|
||||
return std::atan2(2.0f * (w * z + x * y), 1.0f - 2.0f * (y * y + z * z));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static const T *track_sequence_array(const std::vector<uint8_t> &buf, const M2ArrayRef &outer, uint32_t sequence_index, uint32_t &count_out) {
|
||||
count_out = 0;
|
||||
@@ -448,6 +476,37 @@ static Vector2 first_vec3_track_xy_speed(const std::vector<uint8_t> &buf, const
|
||||
return Vector2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
static float angle_delta(float from, float to) {
|
||||
float delta = to - from;
|
||||
const float pi = 3.14159265358979323846f;
|
||||
while (delta > pi) delta -= pi * 2.0f;
|
||||
while (delta < -pi) delta += pi * 2.0f;
|
||||
return delta;
|
||||
}
|
||||
|
||||
static float first_quat_track_z_rotation_speed(const std::vector<uint8_t> &buf, const M2Track &track) {
|
||||
for (uint32_t i = 0; i < track.values.count && i < track.timestamps.count; ++i) {
|
||||
uint32_t time_count = 0;
|
||||
uint32_t value_count = 0;
|
||||
const uint32_t *times = track_sequence_array<uint32_t>(buf, track.timestamps, i, time_count);
|
||||
const M2CompQuat *values = track_sequence_array<M2CompQuat>(buf, track.values, i, value_count);
|
||||
uint32_t key_count = std::min(time_count, value_count);
|
||||
if (!times || !values || key_count < 2) {
|
||||
continue;
|
||||
}
|
||||
uint32_t first = 0;
|
||||
uint32_t last = key_count - 1;
|
||||
float duration = (float)(times[last] - times[first]) / 1000.0f;
|
||||
if (duration <= 0.0001f) {
|
||||
continue;
|
||||
}
|
||||
float first_angle = texture_quat_z_angle(decode_comp_quat_raw(values[first].v));
|
||||
float last_angle = texture_quat_z_angle(decode_comp_quat_raw(values[last].v));
|
||||
return angle_delta(first_angle, last_angle) / duration;
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
static uint32_t sequence_activity_score(const std::vector<uint8_t> &buf, const M2CompBone *bones, uint32_t bone_count, uint32_t sequence_index) {
|
||||
if (!bones) return 0;
|
||||
uint32_t score = 0;
|
||||
@@ -704,18 +763,25 @@ Dictionary M2Loader::parse_m2(const std::vector<uint8_t> &buf, const std::string
|
||||
for (uint32_t i = 0; i < hdr.nTexTransforms; ++i) {
|
||||
Vector2 translation(0.0f, 0.0f);
|
||||
Vector2 scale(1.0f, 1.0f);
|
||||
Vector4 rotation(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
const M2Float3 *trans = first_track_value<M2Float3>(buf, transform_arr[i].translationTrack);
|
||||
if (trans) {
|
||||
translation = Vector2(trans->v[0], trans->v[1]);
|
||||
}
|
||||
const M2CompQuat *rot = first_track_value<M2CompQuat>(buf, transform_arr[i].rotationTrack);
|
||||
if (rot) {
|
||||
rotation = texture_quat_to_uv_rotation(decode_comp_quat_raw(rot->v));
|
||||
}
|
||||
const M2Float3 *scl = first_track_value<M2Float3>(buf, transform_arr[i].scaleTrack);
|
||||
if (scl) {
|
||||
scale = Vector2(scl->v[0], scl->v[1]);
|
||||
}
|
||||
Dictionary t;
|
||||
t["translation"] = translation;
|
||||
t["rotation"] = rotation;
|
||||
t["scale"] = scale;
|
||||
t["translation_speed"] = first_vec3_track_xy_speed(buf, transform_arr[i].translationTrack);
|
||||
t["rotation_speed"] = first_quat_track_z_rotation_speed(buf, transform_arr[i].rotationTrack);
|
||||
texture_transforms.push_back(t);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user