Sunday, 29 November 2009

Blade flex in LUA

This is one example of implementing behaviour using model level LUA scripting which doesn't require adding re-compiling your main project source code.

Rotor-blades are flexible surfaces that generate lift. When stationary or at very low RPM they appear flaccid. Once the rotors are turning fast enough to generate lift, they flex upward.


The Apache at rest (model is an old experimental one that has a highly restrictive usage license).

In the editor, the rotor speed is set by adjusting the SpinSpeed parameter, much like the Windmill example. Each frame update, the LUA program rotates the rotor hub.


The model has 4 rotor blades, each blade is made of 5 segments and named "topblade"
The inner segment is attached to the hub, the outer is the blade tip. We don't want to bend those, just the segments in the middle. This is enough to provide enough visible flex in the rotors. Here is our model in the editor (rotors are turning at a lick here, but appear stationary as it's a still screen-shot).




Here is the LUA code in the model script that takes the spindspeed value and turns it into a bend value. Note that the AppSpeed() is not used in computing the amount of flex, we don't want any blade flap caused by inconsistent frame rates. It's also important that the model rotors are constructed correctly, the segments are parented to it's hub-ward neighbour and the pivot of the segment located at the join between the two.



function entity:Update()
local bend=math.max(5-tonumber(self.model:GetKey("spinspeed")*0.4),-2.5)


--Although these limbs should always be present, it"s a good idea to add a check to make sure they exist before using them
if self.blades~=nil then
self.blades:Turnf(0,0,tonumber(self.model:GetKey("spinspeed"))*AppSpeed(),0)
end


if self.tail~=nil then
self.tail:Turnf(-tonumber(self.model:GetKey("spinspeed")*5)*AppSpeed(),0,0,0)
end




if self.topblade12~=nill then
self.topblade12:SetRotationf(bend,0,0,0)
end
if self.topblade13~=nill then
self.topblade13:SetRotationf(bend,0,0,0)
end
if self.topblade14~=nill then
self.topblade14:SetRotationf(bend,0,0,0)
end


if self.topblade22~=nill then
self.topblade22:SetRotationf(0,-bend,0,0)
end
if self.topblade23~=nill then
self.topblade23:SetRotationf(0,-bend,0,0)
end
if self.topblade24~=nill then
self.topblade24:SetRotationf(0,-bend,0,0)
end


if self.topblade32~=nill then
self.topblade32:SetRotationf(-bend,0,0)
end
if self.topblade33~=nill then
self.topblade33:SetRotationf(-bend,0,0)
end
if self.topblade34~=nill then
self.topblade34:SetRotationf(-bend,0,0)
end


if self.topblade42~=nill then
self.topblade42:SetRotationf(0,bend,0,0)
end
if self.topblade43~=nill then
self.topblade43:SetRotationf(0,bend,0,0)
end
if self.topblade44~=nill then
self.topblade44:SetRotationf(0,bend,0,0)
end




end


No comments:

Post a Comment