Skip to content

Commit

Permalink
Added transitions
Browse files Browse the repository at this point in the history
  • Loading branch information
ArthurHeitmann committed Dec 22, 2023
1 parent 61123f4 commit b2ee141
Show file tree
Hide file tree
Showing 5 changed files with 616 additions and 56 deletions.
57 changes: 50 additions & 7 deletions lib/fileTypeUtils/audio/bnkIO.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

// ignore_for_file: constant_identifier_names

import 'dart:typed_data';

import '../utils/ByteDataWrapper.dart';
import 'wemIdsToNames.dart';

Expand Down Expand Up @@ -361,6 +363,10 @@ mixin BnkHircChunkWithBaseParams implements BnkHircChunkWithBaseParamsGetter {
BnkNodeBaseParams getBaseParams() => baseParams;
}

mixin BnkHircChunkWithTransNodeParams {
abstract BnkMusicTransNodeParams musicTransParams;
}

class BnkMusicTrack extends BnkHircChunkBase with BnkHircChunkWithBaseParams {
late int uFlags;
late int numSources;
Expand Down Expand Up @@ -701,7 +707,8 @@ class BnkSwitchNodeParams {
}
}

class BnkMusicSwitch extends BnkHircChunkBase with BnkHircChunkWithBaseParamsGetter {
class BnkMusicSwitch extends BnkHircChunkBase with BnkHircChunkWithBaseParamsGetter, BnkHircChunkWithTransNodeParams {
@override
late BnkMusicTransNodeParams musicTransParams;
late int bIsContinuePlayback;
late int uTreeDepth;
Expand Down Expand Up @@ -765,7 +772,9 @@ class BnkMusicSwitch extends BnkHircChunkBase with BnkHircChunkWithBaseParamsGet
}
}

class BnkMusicPlaylist extends BnkHircChunkBase with BnkHircChunkWithBaseParamsGetter {

class BnkMusicPlaylist extends BnkHircChunkBase with BnkHircChunkWithBaseParamsGetter, BnkHircChunkWithTransNodeParams {
@override
late BnkMusicTransNodeParams musicTransParams;
late int numPlaylistItems;
late List<BnkPlaylistItem> playlistItems;
Expand Down Expand Up @@ -1117,9 +1126,9 @@ class BnkMusicTransitionRule {

BnkMusicTransitionRule.read(ByteDataWrapper bytes) {
uNumSrc = bytes.readUint32();
srcNumIDs = List.generate(uNumSrc, (index) => bytes.readUint32());
srcNumIDs = List.generate(uNumSrc, (index) => bytes.readInt32());
uNumDst = bytes.readUint32();
dstNumIDs = List.generate(uNumDst, (index) => bytes.readUint32());
dstNumIDs = List.generate(uNumDst, (index) => bytes.readInt32());
srcRule = BnkMusicTransSrcRule.read(bytes);
dstRule = BnkMusicTransDstRule.read(bytes);
allocTransObjectFlag = bytes.readUint8();
Expand All @@ -1130,10 +1139,10 @@ class BnkMusicTransitionRule {
void write(ByteDataWrapper bytes) {
bytes.writeUint32(uNumSrc);
for (var i = 0; i < uNumSrc; i++)
bytes.writeUint32(srcNumIDs[i]);
bytes.writeInt32(srcNumIDs[i]);
bytes.writeUint32(uNumDst);
for (var i = 0; i < uNumDst; i++)
bytes.writeUint32(dstNumIDs[i]);
bytes.writeInt32(dstNumIDs[i]);
srcRule.write(bytes);
dstRule.write(bytes);
bytes.writeUint8(allocTransObjectFlag);
Expand Down Expand Up @@ -2826,4 +2835,38 @@ const actionTypes = {
0x3202: "ResetSetFX_M",
0x3204: "ResetSetFX_ALL",
0x4000: "NoOp",
};
};

const syncTypes = {
0x0: "Immediate",
0x1: "NextGrid",
0x2: "NextBar",
0x3: "NextBeat",
0x4: "NextMarker",
0x5: "NextUserMarker",
0x6: "EntryMarker",
0x7: "ExitMarker",
0x8: "ExitNever",
0x9: "LastExitPosition",
};

const curveInterpolations = {
0x0: "Log3",
0x1: "Sine",
0x2: "Log1",
0x3: "InvSCurve",
0x4: "Linear",
0x5: "SCurve",
0x6: "Exp1",
0x7: "SineRecip",
0x8: "Exp3",
0x9: "Constant",
};

const entryTypes = {
0x0: "EntryMarker",
0x1: "SameTime",
0x2: "RandomMarker",
0x3: "RandomUserMarker",
0x4: "LastExitTime",
};
172 changes: 170 additions & 2 deletions lib/stateManagement/hierarchy/types/BnkHierarchyEntry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class BnkHierarchyEntry extends GenericFileHierarchyEntry {
List<int> parentId = [];
List<int> childIds = [];
List<(bool, List<String>)> props = [];
List<TransitionRule> transitionRules = [];
if (hirc is BnkHircChunkWithBaseParamsGetter) {
var hircChunk = hirc as BnkHircChunkWithBaseParamsGetter;
var baseParams = hircChunk.getBaseParams();
Expand Down Expand Up @@ -114,6 +115,12 @@ class BnkHierarchyEntry extends GenericFileHierarchyEntry {
for (var node in hircChunk.decisionTree[0].children)
parseSwitchNode(hirc.uid, node, 0);
}
if (hircChunk is BnkHircChunkWithTransNodeParams) {
var rules = (hircChunk as BnkHircChunkWithTransNodeParams).musicTransParams.rules;
for (var rule in rules) {
transitionRules.add(TransitionRule.make(rule, hircEntries));
}
}
BnkAkMeterInfo? meterInfo;
if (hircChunk is BnkMusicSegment)
meterInfo = hircChunk.musicParams.meterInfo;
Expand Down Expand Up @@ -218,7 +225,15 @@ class BnkHierarchyEntry extends GenericFileHierarchyEntry {
uidNameStr += " (${hirc.uid})";
}
var entryFullName = "$chunkType $uidNameStr";
var entry = BnkHircHierarchyEntry(entryFullName, entryPath, chunkType, id: hirc.uid, entryName: entryName, parentIds: parentId, childIds: childIds, properties: props, hirc: hirc);
var entry = BnkHircHierarchyEntry(entryFullName, entryPath, chunkType,
id: hirc.uid,
entryName: entryName,
parentIds: parentId,
childIds: childIds,
properties: props,
hirc: hirc,
transitionRules: transitionRules,
);

if (hirc is BnkEvent) {
List<BnkHircHierarchyEntry> childActions = [];
Expand Down Expand Up @@ -395,13 +410,14 @@ class BnkHircHierarchyEntry extends GenericFileHierarchyEntry {
final int id;
final String? entryName;
final BnkHircChunkBase? hirc;
final List<TransitionRule> transitionRules;
List<int> parentIds;
List<int> childIds;
List<(bool, List<String>)>? properties;
int usages = 0;
bool _isDisposed = false;

BnkHircHierarchyEntry(String name, String path, this.type, {required this.id, String? entryName, this.parentIds = const [], this.childIds = const [], this.properties, this.hirc}) :
BnkHircHierarchyEntry(String name, String path, this.type, {required this.id, String? entryName, this.parentIds = const [], this.childIds = const [], this.properties, this.hirc, this.transitionRules = const []}) :
entryName = entryName ?? wemIdsToNames[id],
super(StringProp(name, fileId: null), path, !nonCollapsibleTypes.contains(type), openableTypes.contains(type)) {
isCollapsed.value = true;
Expand Down Expand Up @@ -480,3 +496,155 @@ class BnkHircHierarchyEntry extends GenericFileHierarchyEntry {
return props;
}
}

/*
BnkMusicTransitionRule
int srcID;
int dstID;
BnkMusicTransSrcRule srcRule;
BnkMusicTransDstRule dstRule;
int bIsTransObjectEnabled;
BnkMusicTransitionObject musicTransition;
BnkMusicTransSrcRule
BnkFadeParams fadeParam;
int eSyncType;
int uMarkerID;
int bPlayPostExit;
class BnkMusicTransDstRule
BnkFadeParams fadeParam;
int uMarkerID;
int uJumpToID;
int eEntryType;
int bPlayPreEntry;
int bDestMatchSourceCueName;
BnkMusicTransitionObject {
int segmentID;
BnkFadeParams fadeInParams;
BnkFadeParams fadeOutParams;
int playPreEntry;
int playPostExit;
*/
class TransitionSrc {
final String fallbackText;
final BnkHircHierarchyEntry? entry;

const TransitionSrc(this.fallbackText, this.entry);

static TransitionSrc fromId(int id, Map<int, BnkHircHierarchyEntry> hircEntries) {
if (id == -1)
return const TransitionSrc("Any", null);
if (id == 0)
return const TransitionSrc("None", null);
var entry = hircEntries[id];
if (entry != null)
return TransitionSrc("", entry);
return TransitionSrc(id.toString(), null);
}
}

class TransitionRule {
final List<TransitionSrc> src;
final List<TransitionSrc> dst;
final TransitionSrcRule srcRule;
final TransitionDstRule dstRule;
final TransitionObject? musicTransition;

const TransitionRule(this.src, this.dst, this.srcRule, this.dstRule, this.musicTransition);

static TransitionRule make(BnkMusicTransitionRule transitionRule, Map<int, BnkHircHierarchyEntry> hircEntries) {
return TransitionRule(
transitionRule.srcNumIDs.map((id) => TransitionSrc.fromId(id, hircEntries)).toList(),
transitionRule.dstNumIDs.map((id) => TransitionSrc.fromId(id, hircEntries)).toList(),
TransitionSrcRule.make(transitionRule.srcRule),
TransitionDstRule.make(transitionRule.dstRule),
TransitionObject.make(transitionRule.musicTransition, hircEntries)
);
}
}

class TransitionSrcRule {
final FadeParams fadeParam;
final String syncType;
final int markerId;
final int playPostExit;

const TransitionSrcRule(this.fadeParam, this.syncType, this.markerId, this.playPostExit);

static TransitionSrcRule make(BnkMusicTransSrcRule srcRule) {
return TransitionSrcRule(
FadeParams.make(srcRule.fadeParam),
syncTypes[srcRule.eSyncType] ?? srcRule.eSyncType.toString(),
// srcRule.uMarkerID,
0,
srcRule.bPlayPostExit
);
}
}

class TransitionDstRule {
final FadeParams fadeParam;
final int markerId;
final int jumpToId;
final String entryType;
final bool playPreEntry;
final bool matchSourceCueName;

const TransitionDstRule(this.fadeParam, this.markerId, this.jumpToId, this.entryType, this.playPreEntry, this.matchSourceCueName);

static TransitionDstRule make(BnkMusicTransDstRule dstRule) {
return TransitionDstRule(
FadeParams.make(dstRule.fadeParam),
// dstRule.uMarkerID,
0,
dstRule.uJumpToID,
entryTypes[dstRule.eEntryType] ?? dstRule.eEntryType.toString(),
dstRule.bPlayPreEntry != 0,
dstRule.bDestMatchSourceCueName != 0
);
}
}

class TransitionObject {
final TransitionSrc segment;
final FadeParams fadeInParams;
final FadeParams fadeOutParams;
final bool playPreEntry;
final bool playPostExit;

const TransitionObject(this.segment, this.fadeInParams, this.fadeOutParams, this.playPreEntry, this.playPostExit);

static TransitionObject? make(BnkMusicTransitionObject? transitionObject, Map<int, BnkHircHierarchyEntry> hircEntries) {
if (transitionObject == null)
return null;
return TransitionObject(
TransitionSrc.fromId(transitionObject.segmentID, hircEntries),
FadeParams.make(transitionObject.fadeInParams),
FadeParams.make(transitionObject.fadeOutParams),
transitionObject.playPreEntry != 0,
transitionObject.playPostExit != 0
);
}

bool get isDefault => segment.fallbackText == "None" && fadeInParams.isDefault && fadeOutParams.isDefault && !playPreEntry && !playPostExit;
}

class FadeParams {
final String curve;
final int time;
final int offset;

const FadeParams(this.curve, this.time, this.offset);

static FadeParams make(BnkFadeParams fadeParams) {
return FadeParams(
curveInterpolations[fadeParams.eFadeCurve] ?? fadeParams.eFadeCurve.toString(),
fadeParams.transitionTime,
fadeParams.iFadeOffset
);
}

bool get isDefault => curve == "Linear" && time == 0 && offset == 0;
}
Loading

0 comments on commit b2ee141

Please sign in to comment.