It's been a while since I had a technical question regarding BC, but this is the one thing (so far found) that is keeping a new release of BP Core (and related things).
It's the Animated Texture Maps. These maps are scripted animated maps, and it's original implementation was correct, but performance wise totally unacceptable. And it had a dependency with FoundationTechnologies (not a bad thing, but it's not widely used) which was optional (that aspect simply didn't work otherwise:P).
The new approach is way better, performance wise. No noticeable lag on my machine, at least, no additional. :lol: My BC is a bit bloated. ^_^'
Ok, back to the problem at hand.
When animated maps are called, it starts swapping them from within the scripts, the current approach is to use a sequence for this. Looping is achieved by reconstructing the sequence at it's end. This works, and isn't really important here.
What does work, correctly, is stopping them. Sure the animation is stopped (btw, if anyone knows a fool proof way to stop a sequence without crashing BC, it would be appreciated, the current system simply lets the sequence die off by earlier outing (this too will need to be thinked a bit through, mostlikely an extra identifier, more on this later, I think).
But it doesn't leave the map system in a state where it functions properly.
The map system works by storing the new texture name under the original texture name.
The texture name is different from the texture path.
For instance, this texture path:
Data/Models/Sets/EBridge/High/A_Particular.Map.tga
This is valid. This is it's name:
A_Particular.Map
The function that does this is called DistillNewMapName, and you see it in the functions below here and there.
If the map "A_OriginalMap" is swapped by A_Particular.Map then it needs to store the new name in the Map System, otherwise, subsequent swaps wouldn't know where to swap it. So they all refer to A_OriginalMap, but in fact, they change the real map name underneath and swap it with that.
Back to the problem at hand, the animation system doesn't leave the map system in a continual state (ie. other maps can successfully swap new maps). But if you rerun the sequence it works fine, but not directly. It's almost as if it doesn't set the right map.
You can be sure of that these functions are correctly called.
First possible function, SwitchAnimatedMaps, this function is called when the texture swap mechanism detects an animated texture. The list is stored, so that the Texture swap mechanism can detect it later on (so that it's also stopped). It basically sets stuff up and sets things in motion.
def SwitchAnimatedMaps(sOldMap, lNewMaps):
global oBridgeInfo
if oBridgeInfo.dTextureAnimations.has_key(sOldMap):
#print "Animation already present"
StopAnimatedMaps(sOldMap)
oBridgeInfo.Maps["CurrentMaps"][sOldMap] = lNewMaps
bLooping = 0
dTrack = {}
if type(lNewMaps) == types.ListType:
bLooping = lNewMaps[0]
dTrack = lNewMaps[-1]
else:
if not lNewMaps.has_key("dTrack"):
dTrack = lNewMaps
else:
bLooping = lNewMaps.get("bLooping", 0)
dTrack = lNewMaps["dTrack"]
dAnimation = {}
oBridgeInfo.dTextureAnimations[sOldMap] = dAnimation
lMapNames = []
for value in dTrack.values():
lMapNames.append(DistillNewMapName(value))
dAnimation["MapNames"] = lMapNames
dAnimation["MapPaths"] = dTrack.values()
dAnimation["dTrack"] = dTrack
dAnimation["bLooping"] = bLooping
dAnimation["CurrentIndex"] = 0
dAnimation["Length"] = len(lMapNames)
dAnimation["sOldMap"] = ""+sOldMap
dAnimation["AniName"] = sOldMap
ConstructSeqFromDict(dAnimation)
Also not the issue, I think. But it starts the sequence.
def ConstructSeqFromDict(dAnimation):
# Construct a sequence of texture switches
pSequence = App.TGSequence_Create()
pSequence.SetSkippable(1)
dAnimation["Sequence"] = pSequence
iSub = 0
for index, map in dAnimation["dTrack"].items():
pSequence.AddAction(App.TGScriptAction_Create(__name__, "SwitchAniMapsAction", dAnimation["AniName"]), App.TGAction_CreateNull(), index)
iSub = index
pSequence.Play()
The function that does things. Not sure if it's causing it or not, but unlikely, since it successfully swaps maps.
def SwitchAniMapsAction(pAction, sName):
global oBridgeInfo
if not oBridgeInfo.dTextureAnimations.has_key(sName):
return 0
dAnimation = oBridgeInfo.dTextureAnimations[sName]
index = dAnimation["CurrentIndex"] + 1
sOldMap = dAnimation["sOldMap"]
if index+1 == dAnimation["Length"]:
if dAnimation["bLooping"]:
dAnimation["CurrentIndex"] = 0
ConstructSeqFromDict(dAnimation)
return 0
# Now I need to write the last map back
StopAnimatedMaps(sName)
return 0
sNewMap = dAnimation["MapPaths"][index]
DirectSwitchMaps(sOldMap, sNewMap)
dAnimation["CurrentIndex"] = index
dAnimation["sOldMap"] = DistillNewMapName(sNewMap)
return 0
This function is mostlikely the cause. Since this function is responsible for setting the map system right again.
def StopAnimatedMaps(sKey):
#print "Stopping", sKey
global oBridgeInfo
if not oBridgeInfo.dTextureAnimations.has_key(sKey):
return
dAnimation = oBridgeInfo.dTextureAnimations[sKey]
print dAnimation["sOldMap"]
oBridgeInfo.CurrentMaps[sKey] = dAnimation["sOldMap"]
del oBridgeInfo.dTextureAnimations[sKey]
return
And here is an issue I mentioned above, just thought of it. Dangling sequences.
If a sequence is aborted then it becomes what I like to call a "dangling sequence", it isn't referred to anymore, and it, shouldn't, do(esn't) any more work. Now, if you quickly stop and start a sequence, before the sequence can run out, then it creates a dangling sequence (in the current method) because it doesn't actually abort/stop the sequence (I haven't been able to do that without crashing BC). The symptoms of this (in this system) is fast(er) texture changes, since each step is basicly done twice (especially noticable in looping animations).
Now, 2 sollutions, find a way to stop/abort/skip the sequence (if you know a way, it should be possible, but haven't been able to do it). This way is preferable.
The other, is to assign id's to sequences, and use that instead of the "name" (sName in the action function).
I hope you the reader has made it until this (not fallen asleep:P), and have seen the problem.
Please post it if you do!