Jump to content

Linear Interpolation Code Base


Recommended Posts

The short:

Please break test Wendsemmar to give me ideas for it.
Do you know how to write SLERP for CS/OBSE?

 

The Long:

Writing Linear Interpolation, LERP, in object oriented form for CS/OBSE scripting wasn't easy in terms of making the whole thing modular.

Where I had planned to release it as a modder's resource I soon realised it would be difficult to explain.

I've released all of the code in my mod Wendsemmar which puts it to use.

The code base allows for a custom XMarkerScale that allows for OBSE scaling.

 

As far as doing the same for Spherical Linear Interpolation SLERP, I found processing errors where I'm not sure what I did wrong and gave up.

Again, if you have any ideas on how to improve the use of existing or extend it to do SLERP then I would greatly appreciate your input.

Link to comment
Share on other sites

I am not sure it is what you are referring to, but you may take a look at the scripts in QQuix - Rock rock rock your ship

 

As you probably know, vanilla ships are multi-part and, for this mod, all parts must move together as a whole.

 

If memory serves, I save the initial relative position of all parts relative to the ship hull, then, every frame I tilt hull's XYZ angles a little bit and have to recalculate the XYZ position and angle of all the parts (masts, crates, etc.) to keep then in the same relative position to the hull new angles.

 

Hope it helps.

Link to comment
Share on other sites

Your scripts have advanced algorithms and number crunching - what I am trying to do is eliminate the numbers for modder independance.

 

EDIT: the transformations between 0-1 of each node lerp to the scale of that node - the reason for the custom XMarkerScale.

 

Using my custom XMarkerScale you can layout a number of them at varying angle/distance/scale to run the following script on whatever activator you want. FnGetTransorms will walk through all child objects and store them into a 3D Transform Array ready to drive the parent object at given duration along these nodes. An ideal fFPS of 24 will allow for older machines while quite smooth in rendering...

scn ActiTravelPointsOnceScript
;WARNING: do not change this script 

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
		let iInitialized := 3
		let arrTransforms := call FnGetTransforms this
	endif
	
	if iInitialized == 1
		let iInitialized := 2
		let iIndex0 := 0
		let iIndex1 := 1
		let fInterval := 0
		let fTimer := 0
	;___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]
					let iInitialized := 0
				endif					
			endif
		endif
	endif
				
End

The continuous loop version being...

scn ActiLerpPointsScript
;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
int iLoop ; 0 run once (default), 1 continuous loop
float fDuration ; time in seconds set externally
float fFPS ; target frames per second set externally
float fInterval
float fIncrement
float fTimer
float fStartingScale
ref refEndParent
array_var arrTransforms

Begin GameMode

	if iInitialized == 2
		let iInitialized := 3		
		let arrTransforms := call FnGetTransforms this
	endif

	if iInitialized == 1
		let iInitialized := 2
		let iIndex0 := 0
		let iIndex1 := 1
		let refEndParent := call FnGetLastParent this
	;___Allow for external interuption and reset.
		let fStartingScale := call FnMoveObjectToStart this, fStartingScale
		call FnSetEnable refEndParent, 0
		let fIncrement := call FnNormalizedIncrement fDuration, fFPS
	endif

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

			call FnLerpTransform this, arrTransforms, iIndex0, iIndex1, fInterval
			call FnSetEnable refEndParent, 0
			
			let fInterval += fIncrement
			if fInterval >= 1
				let fInterval := 0
				let iIndex0 += 1
				let iIndex1 += 1
				if iIndex1 == ar_Size arrTransforms[0]
					if iLoop == 0
					;___STOP LERP at end
						let iInitialized := -1
						call FnSetEnable refEndParent, 1
					else
					;___LERP LastMarker to Start
						let iIndex1 := 0
					endif
				elseif iIndex0 == ar_size arrTransforms[0]
				;___LOOP LERP Start to FirstMarker
					let iIndex0 := 0
					let iIndex1 := 1
				endif
			endif
		endif
	endif
	
End

Using FnGetTransforms we need to parent all marker nodes as spaced for desired velocity in comparison to fDuration. For continuous loop, we can set the last child as the activator - unless I am mistaken as I wrote this some time ago.

 

Adding followers is simply a case of 'Object.GetPos SetPos' statements, such as PlayerRef.

 

My question, to answer your question, is how to improve on this by adding 'Spherical Linear Interpolation'.

Link to comment
Share on other sites

I am afraid I wouldn't be of much help here. I retired from scripting many years back, when I was a young lad of 68, and most scripting details have faded from memory and whatever is still left is too rusty to be of any use.

Link to comment
Share on other sites

Thanks heaps for the help QQuix, I appreciate it. Rock rock your ship has great ideas with great reference material for me. I might give up on SLERP and just use LERP with more nodes to emulate it.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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