You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/PhysicsEntities/Assets/Scripts/Entities/Physics/GravityValve.lua

240 lines
6.5 KiB
Lua

----------------------------------------------------------------------------------------------------
--
-- All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
-- its licensors.
--
-- For complete copyright and license terms please see the LICENSE at the root of this
-- distribution (the "License"). All use of this software is governed by the License,
-- or, if provided, by the license below or the license accompanying this file. Do not
-- remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--
--
----------------------------------------------------------------------------------------------------
GravityValve =
{
Properties =
{
bActive = 1,
Strength = 10,
Radius = 10,
bSpline = 0,
},
Server = {},
Client = {},
_PhysTableCyl = { Area={}, },
_PhysTableSph = { Area={}, },
_PhysTableSpl = { Area={points={},}, },
_Points = {},
_Caps = {},
Editor =
{
Icon = "GravitySphere.bmp",
ShowBounds = 1,
},
}
-------------------------------------------------------
function GravityValve:OnLoad(table)
self.bActive = table.bActive
self._Points = table._Points
self._Caps = table._Caps
end
-------------------------------------------------------
function GravityValve:OnSave(table)
table.bActive = self.bActive
table._Points = self._Points
table._Caps = self._Caps
end
function GravityValve:OnSpawn()
self:SetActive( self.Properties.bActive )
end
function GravityValve:OnDestroy()
local Caps = self._Caps
while table.getn(Caps)>0 do
System.RemoveEntity( Caps[1] )
table.remove( Caps, 1 )
end
end
-- OnPropertyChange called only by the editor
function GravityValve:OnPropertyChange()
self:NeedSetup()
end
function GravityValve:OnReset()
self:NeedSetup()
end
function GravityValve:FillPoints()
local MAX_POINTS = 50
local prefix = self:GetName().."_p"
local name
local nPoints = 1
local Points = self._Points
Points[1] = self
for i=1,MAX_POINTS do
name = prefix..tostring(i)
local ent = System.GetEntityByName( name )
if not ent then break end
Points[i+1] = ent
nPoints = i+1
Log("npoints "..nPoints);
end
while table.getn(Points)>nPoints do
Log("removed");
table.remove(Points)
end
for i=1, table.getn(Points) do
Log(".. "..Points[i]:GetName())
end
end
function GravityValve:CreateCylinderArea( from, to, radius, strength )
local Area = self._PhysTableCyl.Area
local axis = DifferenceVectors( to, from )
Area.type = AREA_CYLINDER
Area.radius = radius
Area.height = LengthVector( axis ) * .5
Area.center = ScaleVector( SumVectors( to, from ), 0.5 )
Area.axis = NormalizeVector( axis )
Area.gravity = ScaleVector( Area.axis, strength )
Area.uniform = 1
Area.falloff = 0
return Area
end
function GravityValve:CreateSphereArea( radius, gravity )
local Area = self._PhysTableSph.Area
Area.type = AREA_SPHERE
Area.radius = radius
Area.uniform = 1
Area.falloff = 0
Area.gravity = ScaleVector( gravity, 8 )
return Area
end
function GravityValve:NeedSetup()
self.bNeedSetup = 1
self:Activate(1)
end
function GravityValve:OnChange( index )
self:NeedSetup()
end
function GravityValve:OnUpdate()
--Log("GV:OU "..self:GetName())
if self.bNeedSetup then
local wasActive = self.bActive
self:SetActive(0)
self:SetActive(wasActive)
self.bNeedSetup = nil
self:Activate(0)
end
end
GravityValve.Server.OnUpdate = GravityValve.OnUpdate
GravityValve.Client.OnUpdate = GravityValve.OnUpdate
function GravityValve:SetActive( bActive )
if bActive == self.bActive then return end
self:FillPoints()
local p, n
local Points = self._Points
local Caps = self._Caps
n = table.getn(Points)
--Log("GravityValve:SetActive "..tostring(bActive).." on valve "..self:GetName())
if bActive == 1 then
if (self.Properties.bSpline == 1) then
local Area = self._PhysTableSpl.Area;
local splinePoints = self._PhysTableSpl.Area.points;
for p = 1, n do
splinePoints[p] = {x=0,y=0,z=0};
Points[p]:GetWorldPos(splinePoints[p]);
--Log("Gravity Stream point "..p..":"..Vec2Str(splinePoints[p]));
end
Area.type = AREA_SPLINE;
Area.radius = self.Properties.Radius;
--Area.uniform = 1;
Area.falloff = 0;
Area.gravity = {x=0,y=0,z=self.Properties.Strength};
Area.damping = 2.0;
self:Physicalize(0, PE_AREA, self._PhysTableSpl);
self:SetPhysicParams(PHYSICPARAM_FOREIGNDATA,{foreignData = ZEROG_AREA_ID});
else
local params = {}
params.class = "GravityStreamCap"
params.orientation = {x=1,y=0,z=0}
for p = 2, n do
self:CreateCylinderArea( Points[p-1]:GetPos(), Points[p]:GetPos(), self.Properties.Radius, self.Properties.Strength )
Points[p]:Physicalize(0, PE_AREA, self._PhysTableCyl)
Points[p]:SetPhysicParams(PHYSICPARAM_FOREIGNDATA,{foreignData = ZEROG_AREA_ID});
if p > 2 then
params.position = Points[p-1]:GetPos()
local ent = System.SpawnEntity( params )
table.insert( Caps, ent.id )
self:CreateSphereArea( self.Properties.Radius, self._PhysTableCyl.Area.gravity )
ent:Physicalize(0, PE_AREA, self._PhysTableSph)
ent:SetPhysicParams(PHYSICPARAM_FOREIGNDATA,{foreignData = ZEROG_AREA_ID});
end
end
end
elseif bActive == 0 and self.bActive then
self:DestroyPhysics();
for p = 2, n do
Points[p]:DestroyPhysics()
end
self:OnDestroy()
end
self.bActive = bActive
end
function GravityValve:Event_Enable()
--Log("GravityValve: GetEnable")
self:SetActive(1)
end
function GravityValve:Event_Disable()
--Log("GravityValve: GetDisable")
self:SetActive(0)
end
GravityValve.FlowEvents =
{
Inputs =
{
Disable = { GravityValve.Event_Disable, "bool" },
Enable = { GravityValve.Event_Enable, "bool" },
},
Outputs =
{
Disable = "bool",
Enable = "bool",
},
}