Jump to content

LERP


glowplug

Recommended Posts

Nice!!! One of the challenges I had was with objects that must be disabled/enabled so that the game actually applies changes made to it's orientation. It makes them appear translucent at times.

 

It doesn't look like you need anything from me. I would be glad to post the script from the mod I mentioned if it would help.

Edited by GamerRick
Link to comment
Share on other sites

The problem with SetScale is the Range limitiation of 0.5 to 2. The problem with SetScaleEx is the Disable/Enable - OBSE documentation does not mention that these need to be on separate frames. Even then SetScaleEx seems to have an origin problem that can persist over seconds.

 

At this stage I've enforced the 0.5 to 2.0 Range limit.

Link to comment
Share on other sites

Just in case it helps... I shrink the boat to 0.07x. When I looked at today and saw that I have a GameMode block in a ME Script, my brain went into a sudden attack of Cognitive Disonance. But, it works... LOL

 

As it sets the scale lower, it has to move the pieces to keep them together so that they still look like a boat. The starting positions come from each of the objects that make up the galleon. The end positions are predetermined and hard coded.

 

If you want to make a script that could calculate the end positions, there may be a way. I know some linear algebra. It may be possible, but I gotta dust off the notes. Basically we would calculate the end position by taking a predetermined rotation and distance from the model's current orientation.

SCN RICTPShrinkBoatEnchantmentScript
float SecsPassed
float PirateCabinStartXPos
float PirateCabinTargetXPos
float PirateCabinStartYPos
float PirateCabinTargetYPos
float PirateCabinStartZPos
float PirateCabinTargetZPos
float PirateCabinXDist
float PirateCabinYDist
float PirateCabinZDist
float Door1StartXPos
float Door1TargetXPos
float Door1StartYPos
float Door1TargetYPos
float Door1StartZPos
float Door1TargetZPos
float Door1XDist
float Door1YDist
float Door1ZDist
float Door2StartXPos
float Door2TargetXPos
float Door2StartYPos
float Door2TargetYPos
float Door2StartZPos
float Door2TargetZPos
float Door2XDist
float Door2YDist
float Door2ZDist
float Door2StartSize
float Door2TargetSize
float Door2SizeChange
float LBStartXPos
float LBTargetXPos
float LBStartYPos
float LBTargetYPos
float LBStartZPos
float LBTargetZPos
float LBXDist
float LBYDist
float LBZDist
Float SizeChange
float PercentChange
float tempF
float tempSize
short tempS
float ElapsedSecs
float DoTimer
float Timer
short sDisabled
float DoOnce
float SoundPlayed
short NoRun
short DisableInterval
short NumIntervals
begin ScriptEffectStart
if ( GetStage RICTPAlchemyLabQuest != 96 || Player.GetInCell RICTPCave1L2 != 1 )
  MessageBox "Not now dimwit!"
  Player.AddItemNS RICTPScrollSmaller 1
  Set NoRun to 1
  return
endif
Set NoRun to 0
Set SecsPassed to 0
Set DisableInterval to 5
Set tempF to GetSecondsPassed
Set SizeChange to 0.93
Set PirateCabinStartXPos to ( RICTPPirateCabin01Ref.GetPos X)
Set PirateCabinStartYPos to ( RICTPPirateCabin01Ref.GetPos Y)
Set PirateCabinStartZPos to ( RICTPPirateCabin01Ref.GetPos z)
Set PirateCabinTargetXPos to 5127.1978
Set PirateCabinTargetYPos to 5910.6899
Set PirateCabinTargetZPos to -1179.5503
Set PirateCabinXDist to PirateCabinTargetXPos - PirateCabinStartXPos
Set PirateCabinYDist to PirateCabinTargetYPos - PirateCabinStartYPos
Set PirateCabinZDist to PirateCabinTargetZPos - PirateCabinStartZPos
Set Door1StartXPos to ( RICTPCaveBoatDoorExtRef.GetPos X )
Set Door1StartYPos to ( RICTPCaveBoatDoorExtRef.GetPos Y )
Set Door1StartZPos to ( RICTPCaveBoatDoorExtRef.GetPos z )
Set Door1TargetXPos to 5097.5229
Set Door1TargetYPos to 5912.5542
Set Door1TargetZPos to -1170.5194
Set Door1XDist to Door1TargetXPos - Door1StartXPos
Set Door1YDist to Door1TargetYPos - Door1StartYPos
Set Door1ZDist to Door1TargetZPos - Door1StartZPos
Set LBStartXPos to ( RICTPFXLightBeam3Ref.GetPos X )
Set LBStartYPos to ( RICTPFXLightBeam3Ref.GetPos Y )
Set LBStartZPos to ( RICTPFXLightBeam3Ref.GetPos z )
Set LBTargetXPos to 5073.9590
Set LBTargetYPos to 5913.0781
Set LBTargetZPos to -1072.3391
Set LBXDist to LBTargetXPos - LBStartXPos
Set LBYDist to LBTargetYPos - LBStartYPos
Set LBZDist to LBTargetZPos - LBStartZPos
Set Door2StartXPos to ( RICTPCaveBoatDoorExt2Ref.GetPos X )
Set Door2StartYPos to ( RICTPCaveBoatDoorExt2Ref.GetPos Y )
Set Door2StartZPos to ( RICTPCaveBoatDoorExt2Ref.GetPos z )
Set Door2TargetXPos to 5140.5342
Set Door2TargetYPos to 5909.6006
Set Door2TargetZPos to -1170.0372
Set Door2XDist to Door2TargetXPos - Door2StartXPos
Set Door2YDist to Door2TargetYPos - Door2StartYPos
Set Door2ZDist to Door2TargetZPos - Door2StartZPos
Set Door2StartSize to RICTPCaveBoatDoorExt2Ref.GetScale
Set Door2TargetSize to 0.05
Set Door2SizeChange to Door2StartSize - 0.05
Tam95Xmarker.Disable
RICTPFXLightBeam3Ref.SetScaleEX 30
RICTPFXLightBeam3Ref.Enable
RICTPcaveBeamLiteLarge05Ref.Enable
end
begin GameMode
if NoRun == 1
  return
endif
Set ElapsedSecs to GetSecondsPassed
Set SecsPassed to ( SecsPassed + ElapsedSecs )
if DoTimer == 1
  Set Timer to Timer + ElapsedSecs
  if Timer >= 0.01
   RICTPXMarkerErrollRef.Enable
   RICTPFXLightBeam3Ref.Enable
   RICTPCaveBoatDoorExtRef.Enable
   RICTPCaveBoatDoorExt2Ref.Enable
   RICTPcaveBeamLiteLarge05Ref.Enable
   Set sDisabled to 0
   Set DoTimer to 0
   return
  endif
endif
if SecsPassed > 21
  if DoOnce == 0
   Set DoOnce to 1
   RICTPFXLightBeam3Ref.Disable
   RICTPcaveBeamLiteLarge05Ref.Disable
   SetStage RICTPAlchemyLabQuest 100
  endif
  if sDisabled == 1
   RICTPXMarkerErrollRef.Enable
   RICTPCaveBoatDoorExtRef.Enable
   RICTPCaveBoatDoorExt2Ref.Enable
  endif
  return
endif
if SoundPlayed == 0
  Set SoundPlayed to 1
  PlaySound3D NPCAtronachStormEnrage
  RICTPPirateRivets01Ref.PMS effectSoulTrap  3
  RICTPMainDeck01Ref.PMS effectSoulTrap 3
endif
if SoundPlayed == 1 && SecsPassed >= 4
  Set SoundPlayed to 2
  PlaySound3D RICTPSoundCreakCrack
endif
if SoundPlayed == 2 && SecsPassed >= 12
  Set SoundPlayed to 3
  PlaySound3D RICTPSoundGlass1
endif
if SoundPlayed == 3 && SecsPassed >= 16
  Set SoundPlayed to 4
  PlaySound3D TRPGasRelease
endif
if SoundPlayed == 4 && SecsPassed >= 19
  Set SoundPlayed to 5
  PlaySound3D RICTPSoundSpring1
endif
if SecsPassed >= 3 && SecsPassed <= 20.0
  Set PercentChange to SecsPassed / 20.0
  if PercentChange > 0   
   Set tempF to ( PirateCabinStartXPos + PirateCabinXDist * PercentChange )
   RICTPPirateCabin01Ref.SetPos X, tempF
   Set tempF to ( PirateCabinStartYPos + PirateCabinYDist * PercentChange )
   RICTPPirateCabin01Ref.SetPos Y, tempF
   Set tempF to ( PirateCabinStartZPos + PirateCabinZDist * PercentChange )
   RICTPPirateCabin01Ref.SetPos z, tempF
   Set tempF to ( LBStartXPos + LBXDist * PercentChange )
   RICTPFXLightBeam3Ref.SetPos X, tempF
   Set tempF to ( LBStartYPos + LBYDist * PercentChange )
   RICTPFXLightBeam3Ref.SetPos Y, tempF
   Set tempF to ( LBStartZPos + LBZDist * PercentChange )
   RICTPFXLightBeam3Ref.SetPos z, tempF
   Set tempSize to 30 - ( PercentChange * 30)
   RICTPFXLightBeam3Ref.SetScaleEX tempSize
   Set tempSize to ( 1.0 - PercentChange * SizeChange )
   RICTPPirateCabin01Ref.SetScaleEX tempSize
   RICTPPirateRivets01Ref.SetScaleEX tempSize
   RICTPBloatedFloat01Ref.SetScaleEX tempSize
   RICTPMainDeck01Ref.SetScaleEX tempSize
   RICTPCaveBoatDoorExtRef.SetScaleEX tempSize
   Set tempSize to (1 - PercentChange * Door2SizeChange )
   RICTPCaveBoatDoorExt2Ref.SetScaleEX tempSize
   Set tempF to ( Door1StartXPos + Door1XDist * PercentChange )
   RICTPCaveBoatDoorExtRef.SetPos X, tempF
   Set tempF to ( Door1StartYPos + Door1YDist * PercentChange )
   RICTPCaveBoatDoorExtRef.SetPos Y, tempF
   Set tempF to ( Door1StartZPos + Door1ZDist * PercentChange )
   RICTPCaveBoatDoorExtRef.SetPos z, tempF
   Set tempF to ( Door2StartXPos + Door2XDist * PercentChange )
   RICTPCaveBoatDoorExt2Ref.SetPos X, tempF
   Set tempF to ( Door2StartYPos + Door2YDist * PercentChange )
   RICTPCaveBoatDoorExt2Ref.SetPos Y, tempF
   Set tempF to ( Door2StartZPos + Door2ZDist * PercentChange )
   RICTPCaveBoatDoorExt2Ref.SetPos z, tempF
   Set tempS to RICTPcaveBeamLiteLarge05Ref.GetLightRadius
   Set tempS to tempS - 0.5
   RICTPcaveBeamLiteLarge05Ref.SetLightRadius tempS
   Set NumIntervals to NumIntervals + 1
   if NumIntervals > DisableInterval
    Set NumIntervals to 0
    Set Timer to 0
    Set DoTimer to 1
    RICTPcaveBeamLiteLarge05Ref.Disable
    RICTPXMarkerErrollRef.Disable
    RICTPFXLightBeam3Ref.Disable
    RICTPCaveBoatDoorExtRef.Disable
    RICTPCaveBoatDoorExt2Ref.Disable
    Set sDisabled to 1
   endif
  endif
endif
end
Edited by GamerRick
Link to comment
Share on other sites

Thanks GamerRick. Good point about multiple animation objects. Please remember that this is a resource that requires no knowledge of programming.

 

To achieve this I need sound analysis and properly structured code, it has to strictly apply the rules of 'Factor Out' and 'Write Once' - which I have working, including standardized minimal variables (save game size and no 'hybrid' code).

 

At this stage, I was considering releasing a beta ready for the following steps...

  1. Asynchronous scaling to support SetScaleEx
  2. Multiple animation objects
  3. Write the library as a dll OBSE plugin

Point 3 is the reason for the delay. If it's in CSS people will change it then blame me for it not working. We can Clearly See it Working in my Videos.

 

This script is all we need to put behind a looping animation object then use a custom XMarker (that allows scaling) to Parent the path then use 1 of 5 starter templates.

 

arrTransforms is a 2 dimensional array of Vector3 Position, Vector3 Rotation and Scale.

 

Standard 0-1 LERP where FnLerpTransform performs the Trilinear Interpolation.

 

SetScaleEx requires an extra step

 

'this' will be replaced by the array of animation objects.

 

Again, the resource user will need no knowledge of programming.

scn ActiLoopPointsScript
;WARNING: do not change this script
; See Course, Lerp Multiple Points

int iInitialized ; set to 1 externally after setting fDuration and fFPS
int iIndex0
int iIndex1
float fDuration ; time in seconds set externally
float fFPS ; target frames per second set externally
float fInterval
float fIncrement
float fTimer
float fStartingScale
array_var arrTransforms

Begin GameMode

  if iInitialized == 2 ; allow 1 frame after MoveToStart for GetTransform
    let iInitialized := 3    
    let arrTransforms := call FnGetTransforms this, fStartingScale
  endif

  if iInitialized == 1 ; set by Starter script - Trigger, GameMode, Activator or Quest
    let iInitialized := 2
    let iIndex0 := 0
    let iIndex1 := 1
;___Allow for external interuption and reset.
    let fStartingScale := call FnMoveObjectToStart this, fStartingScale
    let fIncrement := call FnNormalizedIncrement fDuration, fFPS
  endif

  if iInitialized == 3
    let fTimer += GetSecondsPassed
    if fTimer >= (1 / fFPS)
      let fTimer := 0

      call FnLerpTransform this, arrTransforms, iIndex0, iIndex1, fInterval

      let fInterval += fIncrement
      if fInterval >= 1
        let fInterval := 0
        let iIndex0 += 1
        let iIndex1 += 1
        if iIndex1 == ar_Size arrTransforms[0]
      ;___LERP LastMarker to Start
          let iIndex1 := 0
        elseif iIndex0 == ar_size arrTransforms[0]
      ;___LERP Start to FirstMarker (loop)
          let iIndex0 := 0
          let iIndex1 := 1
        endif
      endif
    endif
  endif
  
End

 

 

Link to comment
Share on other sites

Talk about absent minded, having redone SetScaleEx it works. I must have been disabling the wrong parent - it needs to be the last. Set Transform, Disable Last Parent, Next Frame Enable Last Parent.

Link to comment
Share on other sites

Sorry GamerRick, I was distracted and didn't answer your post properly.

 

Looking at the spaceship I did for Indornia, I made all of the nif origins the same as where the player stands during flight, all a case of simple trig but the reason a follower would bounce all over the place - I couldn't be bothered doing linear algebra, as you suggest.

 

Thanks for the offer to help with this, for the moment, I'll need to dust of the cobwebs myself rather than waste your time. Once I've made some progress, I'll message you if that's okay - if your busy, it'll have to wait. I'm working on a project for some people in Ukraine while doing this in between - if I sit on one thing too long I go stale and make silly mistakes.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...