From e3757d5c4373fcf1d43fc71e23fdee337c294dbd Mon Sep 17 00:00:00 2001 From: XProger Date: Mon, 22 Jul 2019 05:18:43 +0300 Subject: [PATCH] TR4 remap soundtracks, fix triggers parser, fix ponytails for young Lara, --- src/debug.h | 2 +- src/format.h | 7 +- src/gameflow.h | 364 +++++++++++++++++++++++++++++++++---------------- src/lara.h | 69 ++++++++-- src/mesh.h | 24 ++-- 5 files changed, 323 insertions(+), 143 deletions(-) diff --git a/src/debug.h b/src/debug.h index 672f8aa..26ca042 100644 --- a/src/debug.h +++ b/src/debug.h @@ -748,7 +748,7 @@ namespace Debug { const char *ent = (cmd.action == TR::Action::ACTIVATE || cmd.action == TR::Action::CAMERA_TARGET) ? getEntityName(level, level.entities[cmd.args]) : ""; sprintf(buf, "%s -> %s (%d)", getTriggerAction(level, cmd.action), ent, cmd.args); - if (cmd.action == TR::Action::CAMERA_SWITCH) { + if (cmd.action == TR::Action::CAMERA_SWITCH || cmd.action == TR::Action::FLYBY || cmd.action == TR::Action::CUTSCENE) { i++; sprintf(buf, "%s delay: %d speed: %d", buf, int(info.trigCmd[i].timer), int(info.trigCmd[i].speed)); } diff --git a/src/format.h b/src/format.h index 3e04c7f..a5321e7 100644 --- a/src/format.h +++ b/src/format.h @@ -1555,6 +1555,9 @@ namespace TR { SOUNDTRACK , // play soundtrack EFFECT , // special effect trigger SECRET , // secret found + CLEAR_BODIES , // clear all dead bodies + FLYBY , // play flyby camera sequence + CUTSCENE , // play cutscene }; }; @@ -1982,8 +1985,9 @@ namespace TR { int D = (SQR(dx) + SQR(dy) + SQR(dz)) >> 12; int R = SQR(light.radius >> 1) >> 12; + int M = max(1, D + R); // TODO TR4 - int value = min(0x1FFF, (light.intensity * R) / (D + R) + ambientInv); + int value = min(0x1FFF, (light.intensity * R) / M + ambientInv); if (maxValue < value) { if (nearLight) { @@ -3229,6 +3233,7 @@ namespace TR { case VER_TR5_PC : loadTR5_PC (stream); break; case VER_TR5_PSX : loadTR5_PSX (stream); break; case VER_TR5_SDC : loadTR5_SDC (stream); break; + default : ASSERT(false); } prepare(); diff --git a/src/gameflow.h b/src/gameflow.h index 26dbba3..a40bd3b 100644 --- a/src/gameflow.h +++ b/src/gameflow.h @@ -141,7 +141,44 @@ namespace TR { LVL_TR3_CHAMBER, LVL_TR3_STPAUL, // TR4 + LVL_TR4_TITLE, LVL_TR4_ANGKOR1, + LVL_TR4_ANG_RACE, + LVL_TR4_SETTOMB1, + LVL_TR4_SETTOMB2, + LVL_TR4_JEEPCHAS, + LVL_TR4_JEEPCHS2, + LVL_TR4_KARNAK1, + LVL_TR4_HALL, + LVL_TR4_LAKE, + LVL_TR4_SEMER, + LVL_TR4_SEMER2, + LVL_TR4_TRAIN, + LVL_TR4_ALEXHUB, + LVL_TR4_ALEXHUB2, + LVL_TR4_PALACES, + LVL_TR4_PALACES2, + LVL_TR4_CSPLIT1, + LVL_TR4_CSPLIT2, + LVL_TR4_LIBRARY, + LVL_TR4_LIBEND, + LVL_TR4_BIKEBIT, + LVL_TR4_NUTRENCH, + LVL_TR4_CORTYARD, + LVL_TR4_LOWSTRT, + LVL_TR4_HIGHSTRT, + LVL_TR4_CITNEW, + LVL_TR4_JOBY1A, + LVL_TR4_JOBY1B, + LVL_TR4_JOBY2, + LVL_TR4_JOBY3A, + LVL_TR4_JOBY3B, + LVL_TR4_JOBY4A, + LVL_TR4_JOBY4B, + LVL_TR4_JOBY4C, + LVL_TR4_JOBY5A, + LVL_TR4_JOBY5B, + LVL_TR4_JOBY5C, LVL_MAX, }; @@ -202,7 +239,17 @@ namespace TR { TRACK_TR3_CUT_11 = 71, TRACK_TR3_CUT_12 = 66, // TR4 - TRACK_TR4_OUT_DAY = 106, + TRACK_TR4_BOSS = 97, + TRACK_TR4_JEEP = 98, + TRACK_TR4_BATTLE = 102, + TRACK_TR4_TITLE = 104, + TRACK_TR4_COASTAL = 105, + TRACK_TR4_TRAIN = 106, + TRACK_TR4_IN_DARK = 107, + TRACK_TR4_IN_DRIPS = 108, + TRACK_TR4_WEIRD1 = 109, + TRACK_TR4_OUT_DAY = 110, + TRACK_TR4_OUT_NIGHT = 111, }; // #define LEVEL (version,name,track) { #name, STR_##version##_##name, TRACK_##version##track }, @@ -300,122 +347,159 @@ namespace TR { { "CHAMBER" , STR_TR3_CHAMBER , TRACK_TR3_ANTARC_3 }, { "STPAUL" , STR_TR3_STPAUL , TRACK_TR3_CAVES }, // TR4 - { "ANGKOR1" , STR_UNKNOWN , TRACK_TR4_OUT_DAY }, + { "title" , STR_UNKNOWN , TRACK_TR4_TITLE }, + { "angkor1" , STR_UNKNOWN , TRACK_TR4_OUT_DAY }, + { "ang_race" , STR_UNKNOWN , TRACK_TR4_OUT_DAY }, + { "settomb1" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "settomb2" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "jeepchas" , STR_UNKNOWN , TRACK_TR4_OUT_DAY }, + { "jeepchs2" , STR_UNKNOWN , TRACK_TR4_JEEP }, + { "karnak1" , STR_UNKNOWN , TRACK_TR4_OUT_DAY }, + { "hall" , STR_UNKNOWN , TRACK_TR4_OUT_DAY }, + { "lake" , STR_UNKNOWN , TRACK_TR4_OUT_DAY }, + { "semer" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "semer2" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "train" , STR_UNKNOWN , TRACK_TR4_TRAIN }, + { "alexhub" , STR_UNKNOWN , TRACK_TR4_OUT_DAY }, + { "alexhub2" , STR_UNKNOWN , TRACK_TR4_COASTAL }, + { "palaces" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "palaces2" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "csplit1" , STR_UNKNOWN , TRACK_TR4_IN_DRIPS }, + { "csplit2" , STR_UNKNOWN , TRACK_TR4_IN_DRIPS }, + { "library" , STR_UNKNOWN , TRACK_TR4_IN_DRIPS }, + { "libend" , STR_UNKNOWN , TRACK_TR4_WEIRD1 }, + { "bikebit" , STR_UNKNOWN , TRACK_TR4_BATTLE }, + { "nutrench" , STR_UNKNOWN , TRACK_TR4_BATTLE }, + { "cortyard" , STR_UNKNOWN , TRACK_TR4_BATTLE }, + { "lowstrt" , STR_UNKNOWN , TRACK_TR4_BATTLE }, + { "highstrt" , STR_UNKNOWN , TRACK_TR4_BATTLE }, + { "citnew" , STR_UNKNOWN , TRACK_TR4_BATTLE }, + { "joby1a" , STR_UNKNOWN , TRACK_TR4_OUT_NIGHT }, + { "joby1b" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "joby2" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "joby3a" , STR_UNKNOWN , TRACK_TR4_OUT_NIGHT }, + { "joby3b" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "joby4a" , STR_UNKNOWN , TRACK_TR4_OUT_NIGHT }, + { "joby4b" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "joby4c" , STR_UNKNOWN , TRACK_TR4_OUT_NIGHT }, + { "joby5a" , STR_UNKNOWN , TRACK_TR4_IN_DARK }, + { "joby5b" , STR_UNKNOWN , TRACK_TR4_BOSS }, + { "joby5c" , STR_UNKNOWN , TRACK_TR4_IN_DRIPS }, }; static const char* TRACK_LIST_TR4[] = { - "VonCroy2", - "VonCroy3", - "VonCroy4", - "VonCroy5", - "VonCroy6_Lara2", - "VonCroy7", - "VonCroy8", - "VonCroy9a", - "VonCroy9b_Lara3", - "VonCroy10", - "VonCroy11a", - "VonCroy11b", - "VonCroy12_13a_Lara4", - "VonCroy13b", - "VonCroy14", - "VonCroy15", - "VonCroy16_lara5", - "VonCroy17", - "Lara6_VonCroy18", - "VonCroy19", - "VC20_L7_VC21_L8_VC22a", - "VonCroy22b", - "VonCroy23", - "VonCroy24a", - "VonCroy24b", - "VC25_L9_VC26_L10", - "VonCroy27", - "VonCroy28_L11", - "VonCroy29", - "VonCroy30", - "VonCroy31_L12", - "VonCroy32_L13", - "VonCroy33", - "VonCroy34", - "VonCroy35", - "VonCroy36", - "VC37_L15_VC38", - "A_Short_01", - "TR4_Title_Q10", - "Action_Part_ii", - "Action_Part_iii", - "Action_Part_iv", - "Action_Part_v", - "Attack_part_i", - "Authentic_TR", - "Boss_01", - "Boss_02", - "Close_to_the_End", - "Close_to_the_End_part_ii", - "Underwater_Find_part_i", - "Egyptian_Mood_Part_i", - "Egyptian_Mood_Part_ii", - "General_Part_i", - "General_Part_ii", - "General_Part_iii", - "General_Part_iv", - "General_Part_v", - "Gods_Part_i", - "Gods_Part_ii", - "Gods_Part_iii", - "In_The_Pyramid_Part_i", - "Jeep_Thrills_max", - "Misc_Inc_01", - "Misc_Inc_02", - "Misc_Inc_03", - "Misc_Inc_04", - "Mystery_Part_i", - "Mystery_Part_ii", - "Mystery_Part_iii", - "Mystery_Part_iv", - "Ominous_Part_i", - "Puzzle_part_i", - "Secret", - "backpack", - "captain1", - "captain2", - "crocgod", - "croywon", - "crypt1", - "crypt2", - "dig", - "finale", - "horus", - "inscrip", - "intro", - "jeepA", - "jeepB", - "key", - "larawon", - "libend", - "minilib1", - "minilib2", - "minilib3", - "minilib4", - "phildoor", - "sarcoph", - "scorpion", - "throne", - "whouse", - "Attack_part_ii", - "A1_In_Dark", - "A2_In_Drips", - "A3_Out_Night", - "A4_Weird1", - "A5_Battle", - "A6_Out_Day", - "A7_Train+", - "A8_Coastal", - "Lyre_01", - "Lyre_02", - "charmer", - "Gods_part_iv" + "044_Attack_part_i" + , "008_VonCroy9a" + , "100_Attack_part_ii" + , "010_VonCroy10" + , "015_VonCroy14" + , "073_Secret" + , "109_Lyre_01" + , "042_Action_Part_iv" + , "043_Action_Part_v" + , "030_VonCroy30" + , "012_VonCroy11b" + , "011_VonCroy11a" + , "063_Misc_Inc_01" + , "014_VonCroy13b" + , "111_charmer" + , "025_VonCroy24b" + , "023_VonCroy23" + , "006_VonCroy7" + , "024_VonCroy24a" + , "110_Lyre_02" + , "020_VonCroy19" + , "034_VonCroy34" + , "054_General_Part_ii" + , "036_VonCroy36" + , "004_VonCroy5" + , "035_VonCroy35" + , "027_VonCroy27" + , "053_General_Part_i" + , "022_VonCroy22b" + , "028_VonCroy28_L11" + , "003_VonCroy4" + , "001_VonCroy2" + , "041_Action_Part_iii" + , "057_General_Part_v" + , "018_VonCroy17" + , "064_Misc_Inc_02" + , "033_VonCroy33" + , "031_VonCroy31_L12" + , "032_VonCroy32_L13" + , "016_VonCroy15" + , "065_Misc_Inc_03" + , "040_Action_Part_ii" + , "112_Gods_part_iv" + , "029_VonCroy29" + , "007_VonCroy8" + , "013_VonCroy12_13a_Lara4" + , "009_VonCroy9b_Lara3" + , "081_dig" + , "085_intro" + , "071_Ominous_Part_i" + , "095_phildoor" + , "061_In_The_Pyramid_Part_i" + , "050_Underwater_Find_part_i" + , "058_Gods_Part_i" + , "005_VonCroy6_Lara2" + , "045_Authentic_TR" + , "060_Gods_Part_iii" + , "055_General_Part_iii" + , "059_Gods_Part_ii" + , "068_Mystery_Part_ii" + , "076_captain2" + , "019_Lara6_VonCroy18" + , "002_VonCroy3" + , "066_Misc_Inc_04" + , "067_Mystery_Part_i" + , "038_A_Short_01" + , "088_key" + , "017_VonCroy16_lara5" + , "026_VC25_L9_VC26_L10" + , "056_General_Part_iv" + , "021_VC20_L7_VC21_L8_VC22a" + , "096_sarcoph" + , "087_jeepB" + , "091_minilib1" + , "086_jeepA" + , "051_Egyptian_Mood_Part_i" + , "078_croywon" + , "092_minilib2" + , "083_horus" + , "049_Close_to_the_End_part_ii" + , "037_VC37_L15_VC38" + , "097_scorpion" + , "089_larawon" + , "094_minilib4" + , "098_throne" + , "048_Close_to_the_End" + , "070_Mystery_Part_iv" + , "093_minilib3" + , "072_Puzzle_part_i" + , "074_backpack" + , "069_Mystery_Part_iii" + , "052_Egyptian_Mood_Part_ii" + , "084_inscrip" + , "099_whouse" + , "047_Boss_02" + , "080_crypt2" + , "090_libend" + , "046_Boss_01" + , "062_Jeep_Thrills_max" + , "079_crypt1" + , "082_finale" + , "075_captain1" + , "105_A5_Battle" + , "077_crocgod" + , "039_TR4_Title_Q10" + , "108_A8_Coastal" + , "107_A7_Train+" + , "101_A1_In_Dark" + , "102_A2_In_Drips" + , "104_A4_Weird1" + , "106_A6_Out_Day" + , "103_A3_Out_Night" }; Version getGameVersionByLevel(LevelID id) { @@ -425,7 +509,7 @@ namespace TR { return VER_TR2; if (id >= LVL_TR3_TITLE && id <= LVL_TR3_STPAUL) return VER_TR3; - if (id >= LVL_TR4_ANGKOR1 && id < LVL_MAX) + if (id >= LVL_TR4_TITLE && id <= LVL_TR4_JOBY5C) return VER_TR4; return VER_UNKNOWN; } @@ -813,7 +897,44 @@ namespace TR { case 1080046 : case 2321393 : return LVL_TR3_CUT_12; // TR4 + case 3007155 : return LVL_TR4_TITLE; case 4034313 : return LVL_TR4_ANGKOR1; + case 4343019 : return LVL_TR4_ANG_RACE; + case 3715110 : return LVL_TR4_SETTOMB1; + case 3868566 : return LVL_TR4_SETTOMB2; + case 3600478 : return LVL_TR4_JEEPCHAS; + case 4826055 : return LVL_TR4_JEEPCHS2; + case 4773596 : return LVL_TR4_KARNAK1; + case 4882065 : return LVL_TR4_HALL; + case 5021843 : return LVL_TR4_LAKE; + case 4409367 : return LVL_TR4_SEMER; + case 4294398 : return LVL_TR4_SEMER2; + case 3246177 : return LVL_TR4_TRAIN; + case 4007946 : return LVL_TR4_ALEXHUB; + case 4735043 : return LVL_TR4_ALEXHUB2; + case 4549992 : return LVL_TR4_PALACES; + case 4779709 : return LVL_TR4_PALACES2; + case 4570232 : return LVL_TR4_CSPLIT1; + case 4838007 : return LVL_TR4_CSPLIT2; + case 4606099 : return LVL_TR4_LIBRARY; + case 3240517 : return LVL_TR4_LIBEND; + case 5013974 : return LVL_TR4_BIKEBIT; + case 4260336 : return LVL_TR4_NUTRENCH; + case 4989001 : return LVL_TR4_CORTYARD; + case 3970465 : return LVL_TR4_LOWSTRT; + case 4725022 : return LVL_TR4_HIGHSTRT; + case 4776907 : return LVL_TR4_CITNEW; + case 5011064 : return LVL_TR4_JOBY1A; + case 4544163 : return LVL_TR4_JOBY1B; + case 4839409 : return LVL_TR4_JOBY2; + case 4433722 : return LVL_TR4_JOBY3A; + case 5141026 : return LVL_TR4_JOBY3B; + case 4786641 : return LVL_TR4_JOBY4A; + case 4401690 : return LVL_TR4_JOBY4B; + case 4999677 : return LVL_TR4_JOBY4C; + case 3741579 : return LVL_TR4_JOBY5A; + case 4623726 : return LVL_TR4_JOBY5B; + case 4398142 : return LVL_TR4_JOBY5C; } if (name) { @@ -861,6 +982,7 @@ namespace TR { case VER_TR1 : return LVL_TR1_TITLE; case VER_TR2 : return LVL_TR2_TITLE; case VER_TR3 : return LVL_TR3_TITLE; + case VER_TR4 : return LVL_TR4_TITLE; } return LVL_TR1_TITLE; ASSERT(false); @@ -882,6 +1004,7 @@ namespace TR { case VER_TR1 : return LVL_TR1_1; case VER_TR2 : return LVL_TR2_WALL; case VER_TR3 : return LVL_TR3_JUNGLE; + case VER_TR4 : return LVL_TR4_ANGKOR1; } ASSERT(false); return LVL_MAX; @@ -892,6 +1015,7 @@ namespace TR { case VER_TR1 : return LVL_TR1_10C; case VER_TR2 : return LVL_TR2_HOUSE; case VER_TR3 : return LVL_TR3_CHAMBER; + case VER_TR4 : return LVL_TR4_JOBY5C; } ASSERT(false); return LVL_MAX; @@ -906,7 +1030,10 @@ namespace TR { } bool isTitleLevel(LevelID id) { - return id == LVL_TR1_TITLE || id == LVL_TR2_TITLE || id == LVL_TR3_TITLE; + return id == LVL_TR1_TITLE || + id == LVL_TR2_TITLE || + id == LVL_TR3_TITLE || + id == LVL_TR4_TITLE; } bool isEmptyLevel(LevelID id) { @@ -974,6 +1101,7 @@ namespace TR { case VER_TR2_PSX : sprintf(dst, "DATA/%s.PSX", LEVEL_INFO[id].name); break; case VER_TR3_PC : sprintf(dst, isCutsceneLevel(id) ? "cuts/%s.TR2" : "data/%s.TR2", LEVEL_INFO[id].name); break; case VER_TR3_PSX : sprintf(dst, isCutsceneLevel(id) ? "CUTS/%s.PSX" : "DATA/%s.PSX", LEVEL_INFO[id].name); break; + case VER_TR4_PC : sprintf(dst, "DATA/%s.tr4", LEVEL_INFO[id].name); break; default : ASSERT(false); } } else { @@ -1185,8 +1313,8 @@ namespace TR { callback(Sound::openCDAudioWAD("audio/cdaudio.wad", track), userData); return; case VER_TR4_PC : - sprintf(title, "audio/%03d_%s", track, TRACK_LIST_TR4[track - 1]); - if (!checkTrack("", title)) { + strcpy(title, TRACK_LIST_TR4[track]); + if (!checkTrack("audio/", title)) { callback(NULL, userData); } break; diff --git a/src/lara.h b/src/lara.h index ae17a67..8021c2f 100644 --- a/src/lara.h +++ b/src/lara.h @@ -498,11 +498,13 @@ struct Lara : Character { mesh->renderModel(lara->level->extra.braid); } - } *braid; + } *braid[2]; - Lara(IGame *game, int entity) : Character(game, entity, LARA_MAX_HEALTH), wpnCurrent(TR::Entity::NONE), wpnNext(TR::Entity::NONE), braid(NULL) { + Lara(IGame *game, int entity) : Character(game, entity, LARA_MAX_HEALTH), wpnCurrent(TR::Entity::NONE), wpnNext(TR::Entity::NONE) { camera = new Camera(game, this); + braid[0] = braid[1] = NULL; + itemHolster = TR::Entity::NONE; hitTimer = 0.0f; networkInput = -1; @@ -547,8 +549,26 @@ struct Lara : Character { arms[i].rotAbs = quat(0, 0, 0, 1); } - if (level->extra.braid > -1) - braid = new Braid(this, (level->version & (TR::VER_TR2 | TR::VER_TR3)) ? vec3(-2.0f, -16.0f, -48.0f) : vec3(-4.0f, 24.0f, -48.0f)); + if (level->extra.braid > -1) { + vec3 offset(0.0f); + switch (level->version & TR::VER_VERSION) { + case TR::VER_TR1 : + braid[0] = new Braid(this, vec3(-4.0f, 24.0f, -48.0f)); + break; + case TR::VER_TR2 : + case TR::VER_TR3 : + braid[0] = new Braid(this, vec3(-2.0f, -16.0f, -48.0f)); + break; + case TR::VER_TR4 : + if (isYoung()) { + braid[0] = new Braid(this, vec3(-32.0f, -48.0f, -32.0f)); + braid[1] = new Braid(this, vec3( 32.0f, -48.0f, -32.0f)); + } else { + braid[0] = new Braid(this, vec3(-2.0f, -16.0f, -48.0f)); + } + break; + } + } // TR1 //reset(14, vec3(40448, 3584, 60928), PI * 0.5f, STAND_ONWATER); // gym (pool) @@ -626,10 +646,15 @@ struct Lara : Character { virtual ~Lara() { delete camera; - delete braid; + delete braid[0]; + delete braid[1]; delete environment; } + bool isYoung() { + return level->id == TR::LVL_TR4_ANGKOR1 || level->id == TR::LVL_TR4_ANG_RACE; + } + bool canSaveGame() { return health > 0.0f && !burn && state != STATE_USE_KEY @@ -1546,6 +1571,9 @@ struct Lara : Character { } void doBubbles() { + if ((level->version & TR::VER_VERSION) > TR::VER_TR2) { + return; // TODO + } int count = rand() % 3; if (!count) return; game->playSound(TR::SND_BUBBLE, pos, Sound::PAN); @@ -2224,6 +2252,14 @@ struct Lara : Character { game->playTrack(TR::TRACK_TR1_SECRET, true); } break; + case TR::Action::CLEAR_BODIES : + break; + case TR::Action::FLYBY : + cmdIndex++; // TODO + break; + case TR::Action::CUTSCENE : + cmdIndex++; // TODO + break; } } @@ -3202,8 +3238,13 @@ struct Lara : Character { updateLights(); - if (fixRoomIndex() && braid) - braid->update(); + if (fixRoomIndex()) { + for (int i = 0; i < COUNT(braid); i++) { + if (braid[i]) { + braid[i]->update(); + } + } + } } else { switch (usedItem) { case TR::Entity::INV_MEDIKIT_SMALL : @@ -3219,8 +3260,11 @@ struct Lara : Character { } Character::update(); - if (braid) - braid->update(); + for (int i = 0; i < COUNT(braid); i++) { + if (braid[i]) { + braid[i]->update(); + } + } } camera->update(); @@ -3791,8 +3835,11 @@ struct Lara : Character { visibleMask = visMask; - if (braid) - braid->render(mesh); + for (int i = 0; i < COUNT(braid); i++) { + if (braid[i]) { + braid[i]->render(mesh); + } + } if (state == STATE_MIDAS_DEATH /* && Core::pass == Core::passCompose */) { game->setRoomParams(getRoomIndex(), Shader::MIRROR, 1.2f, 1.0f, 0.2f, 1.0f, false); diff --git a/src/mesh.h b/src/mesh.h index 7701710..975b620 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -448,7 +448,8 @@ struct MeshBuilder { } } - weldSkinJoints(vertices + vStartModel); + weldSkinJoints(vertices + vStartModel, level->extra.laraSkin, level->extra.laraJoints); + weldSkinJoints(vertices + vStartModel, level->extra.braid, level->extra.braid); ASSERT(vCount - vStartModel <= 0xFFFF); @@ -696,15 +697,15 @@ struct MeshBuilder { return false; } - void weldSkinJoints(Vertex *vertices) { - if (level->extra.laraSkin == -1 || level->extra.laraJoints == -1) { + void weldSkinJoints(Vertex *vertices, int16 skinIndex, int16 jointsIndex) { + if (skinIndex == -1 || jointsIndex == -1) { return; } - int t = Core::getTime(); - ASSERT(level->models[level->extra.laraSkin].mCount == level->models[level->extra.laraJoints].mCount); - const TR::Model *model = level->models + level->extra.laraSkin; - const TR::Node *node = (TR::Node*)level->nodesData + model->node; + ASSERT(level->models[skinIndex].mCount == level->models[jointsIndex].mCount); + + const TR::Model *model = level->models + skinIndex; + const TR::Node *node = (TR::Node*)&level->nodesData[model->node];//(TR::Node*)level->nodesData + model->node; int sIndex = 0; short4 stack[16]; @@ -723,8 +724,8 @@ struct MeshBuilder { jointsPos[i] = pos; } - const ModelRange &rangeSkin = models[level->extra.laraSkin]; - const ModelRange &rangeJoints = models[level->extra.laraJoints]; + const ModelRange &rangeSkin = models[skinIndex]; + const ModelRange &rangeJoints = models[jointsIndex]; #define COORD_FILL(VAR,RANGE)\ short4 *VAR = new short4[RANGE.vCount];\ @@ -741,7 +742,8 @@ struct MeshBuilder { // bruteforce :( for (int j = 0; j < rangeJoints.vCount; j++) { for (int i = 0; i < rangeSkin.vCount; i++) { - if (abs(vSkin[i].x - vJoints[j].x) <= 1 && + if (//vSkin[i].w < vJoints[j].w && + abs(vSkin[i].x - vJoints[j].x) <= 1 && abs(vSkin[i].y - vJoints[j].y) <= 1 && abs(vSkin[i].z - vJoints[j].z) <= 1) { // compare position vertices[rangeJoints.vStart + j].coord = vertices[rangeSkin.vStart + i].coord; // set bone index @@ -755,8 +757,6 @@ struct MeshBuilder { delete[] vJoints; #undef COORD_FILL - - LOG("remap joints: %d\n", Core::getTime() - t); } int calcWaterLevel(int16 roomIndex, bool flip) {