Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
anyone knows a formula to spin like this: http://www.hiveworkshop.com/forums/...3-a-220215/?prev=u=Almia&r=20&status=a&page=2
but in 3D? the one i shared is 2D,i want a spin just like a Sphere does.
I tried this formula:
x = originX + dist * Cos(angle2D) * Cos(angle3D)
y = originY + dist * Sin(angle2D) * Cos(angle3D)
z = originZ + dist * Sin(angle2D)
it will be easiest to just store each unit's coordinates and each time you rotate it simply set its xyz to those coordinates if you want to have a repetative spin. if you want to make it random then just make a bigger array of points
unit[1]'s polar offset can be towards 30 degrees and 30 z
unit[2]'s offset can be towards 40 degrees and 40 z etc..
then just simply increase these for each unit until you hit a limit of 90 z or something
this is probly more efficient since you wont need to multiply matrices or anything like that
library Spin3D
struct Spin extends array
private static constant real timeout = 0.03125
private static thistype counter = 0
private static thistype firstToRecycle = 0
private thistype nextToRecycle
private boolean isAllocated
private static thistype first = 0
private thistype next
private unit spinner
private unit pivotUnit
real xOffset
real yOffset
real zOffset
private real sin_a
private real cos_a
private real sin_b
private real cos_b
private real sin_t
private real cos_t
private real x
private real y
private static method allocate takes nothing returns thistype
local thistype this
if firstToRecycle == 0 then
set counter = counter+1
set this = counter
else
set this = thistype.firstToRecycle
set thistype.firstToRecycle = this.nextToRecycle
set this.nextToRecycle = 0
endif
set next = thistype.first
set thistype.first = this
return this
endmethod
public static method add takes real azimuthAngle, real elevationAngle, unit spinner, real spinsPerSec, real distance, unit pivotUnit, real xOffset, real yOffset, real zOffset returns thistype
local real theta
local thistype this = thistype.allocate()
set this.spinner = spinner
set this.pivotUnit = pivotUnit
set theta = 2*bj_PI*(thistype.timeout/spinsPerSec)
set this.cos_t = Cos(theta)
set this.sin_t = Sin(theta)
set this.cos_a = Cos(elevationAngle*bj_DEGTORAD)
set this.sin_a = Sin(elevationAngle*bj_DEGTORAD)
set this.cos_b = Cos(azimuthAngle*bj_DEGTORAD)
set this.sin_b = Sin(azimuthAngle*bj_DEGTORAD)
set this.x = distance // this.cos_a*this.cos_b*distance
set this.y = 0 // -this.sin_b*distance
set this.xOffset = xOffset
set this.yOffset = yOffset
set this.zOffset = zOffset
call UnitAddAbility (spinner, 'Amrf')
call UnitRemoveAbility(spinner, 'Amrf')
call SetUnitPathing (spinner, false)
return this
endmethod
private method deallocate takes nothing returns nothing
set first = this.next
set this.next = 0
set nextToRecycle = thistype.firstToRecycle
set thistype.firstToRecycle = this
endmethod
public method destroy takes nothing returns nothing
set cos_t = 0
set sin_t = 0
set cos_a = 0
set sin_a = 0
set cos_b = 0
set sin_b = 0
set x = 0
set y = 0
set xOffset = 0
set xOffset = 0
set zOffset = 0
set spinner = null
set pivotUnit = null
call this.deallocate()
endmethod
private static method doSpins takes nothing returns nothing
local real xt
local thistype this = first
loop
exitwhen this == 0
set xt = cos_t*x - sin_t*y
set y = sin_t*x + cos_t*y
set x = xt
call SetUnitX(spinner, GetUnitX(pivotUnit) + xOffset + ( cos_a*cos_b*x - sin_b*y))
call SetUnitY(spinner, GetUnitY(pivotUnit) + yOffset + ( cos_a*sin_b*x + cos_b*y))
call SetUnitFlyHeight(spinner, GetUnitFlyHeight(pivotUnit) + ( sin_a*x + zOffset),0)
set this = this.next
endloop
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), timeout, true, function thistype.doSpins)
set thistype(0).next = 0
set thistype(0).nextToRecycle = 0
endmethod
endstruct
endlibrary
private static constant real timeout defines the frequency of the moves
the closer to 0 it is, the swifter the move looks but also the worse the performance is
explanation:
The system allows you to to spin units around other units 3D-wise with offset
This method makes a unit spin:
The parameters:
spinner is the unit thats being spinned around a point
the coordinates of the pivotUnit added to the 3 offset coordinates make the spin point (xOffset = 0, yOffset = 0, zOffset = 100 will make the spinner spin around a point 100 units above the pivotUnit, which we call the spinpoint)
spinsPerSec is self explanatory (if you make it negative, it will spin into the other direction)
distance is the distance to the spinpoint
now for the 2 parameters that make the 3D spin: elevationAngle and azimuthAngle
imagine you look at the spinpoint from above (vertically)
then imagine a circle around the spinpoint with radius = distance
the spinner is spinning clockwise along this circle when azimuthAngle and elevationAngle are both 0
when you put other values into azimuthAngle and elevationAngle the circles orientation will change:
we call the elevationPoint the right border of the circle
the azimuthAngle now moves the elevationPoint anti-clockwise on the circle
the elevationAngle grabs the circle at the elevationPoint and lifts it into the air, so that the other side of the circle goes downwards
i've included a testmap
credits to Frankster, who created the fireball model used in the testmap
EDIT: changed local thistype this = 0 to this = 1 in method doSpins
your welcome
beside that i found a little mistake in my system:
in doSpins the iteration starts at this = 0, but it has to start at this = 1 (fixed it)
beside that i forgot to mention that it should be possible to change the 3 offset variables while a unit is spinning, thats why theyre not private (though i didnt test^^)
with a diagonal spin u mean a spin thats not 100% vertically? so a spin unlike the spins in my example map?
just try different values for elevation angle then
elevationangle = 90 will make it vertically, elevationangle = 45 is 1 possibility for a diagonal
edited my system:
the method destroy was total shit^^
it transferred the data of the last object to the one that got destroy
this of course totally messes up the object reference of the last one
replaced it with a usual linked list system
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.