-
Notifications
You must be signed in to change notification settings - Fork 11
/
scene_instances.lua
130 lines (99 loc) · 3.31 KB
/
scene_instances.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
-- Instantiating scenes
hg = require("harfang")
hg.InputInit()
hg.WindowSystemInit()
res_x, res_y = 1280, 720
win = hg.RenderInit('Scene instances', res_x, res_y, hg.RF_VSync | hg.RF_MSAA4X)
hg.AddAssetsFolder("resources_compiled")
-- rendering pipeline
pipeline = hg.CreateForwardPipeline()
res = hg.PipelineResources()
-- load host scene
scene = hg.Scene()
hg.LoadSceneFromAssets('playground/playground.scn', scene, res, hg.GetForwardPipelineInfo())
-- declare the biped actor class
BipedActor =
{
__node = nil,
__delay = 0,
__state = nil,
__playing_anim_ref = nil
}
function BipedActor:new(pos)
local o={}
setmetatable(o,self)
self.__index=self
o.__node = hg.CreateInstanceFromAssets(scene, hg.Mat4.Identity, "biped/biped.scn", res, hg.GetForwardPipelineInfo())
o.__node:GetTransform():SetPosRot(pos, hg.Deg3(0, hg.FRand(360), 0))
o.__delay = 0
o.__state = nil
o.__playing_anim_ref = nil
return o
end
function BipedActor:__start_anim(name)
anim = self.__node:GetInstanceSceneAnim(name) -- get instance specific animation
if self.__playing_anim_ref ~= nil then
scene:StopAnim(self.__playing_anim_ref)
end
self.__playing_anim_ref = scene:PlayAnim(anim, hg.ALM_Loop)
end
function BipedActor:update(dt)
-- check for state change
self.__delay = self.__delay - dt
if self.__delay <= 0 then
states = {'idle', 'walk', 'run'}
self.__state = states[hg.Rand(#states) + 1]
self.__delay = self.__delay + hg.time_from_sec_f(hg.FRRand(2, 6)) -- 2 to 6 seconds before next state change
self:__start_anim(self.__state)
end
-- apply motion
dt_sec_f = hg.time_to_sec_f(dt)
transform = self.__node:GetTransform()
pos, rot = transform:GetPosRot()
if self.__state == 'walk' then
pos = pos - hg.GetZ(transform:GetWorld()) * hg.Mtr(1.15) * dt_sec_f -- 1.15 m/sec
rot.y = rot.y + hg.Deg(50) * dt_sec_f
elseif self.__state == 'run' then
pos = pos - hg.GetZ(transform:GetWorld()) * hg.Mtr(4.5) * dt_sec_f -- 4.5 m/sec
rot.y = rot.y - hg.Deg(70) * dt_sec_f
end
-- confine actor to playground
pos = hg.Clamp(pos, hg.Vec3(-10, 0, -10), hg.Vec3(10, 0, 10))
transform:SetPosRot(pos, rot)
end
function BipedActor:destroy()
scene:DestroyNode(self.__node)
end
-- spawn initial actors
actors = {}
for i=0, 19 do
actor = BipedActor:new(hg.RandomVec3(hg.Vec3(-10, 0, -10), hg.Vec3(10, 0, 10)))
table.insert(actors, actor)
end
print(string.format('%d nodes in scene', scene:GetAllNodeCount()))
-- main loop
keyboard = hg.Keyboard()
while not keyboard:Down(hg.K_Escape) and hg.IsWindowOpen(win) do
_, res_x, res_y = hg.RenderResetToWindow(win, res_x, res_y, hg.RF_VSync | hg.RF_MSAA4X | hg.RF_MaxAnisotropy)
keyboard:Update()
if keyboard:Pressed(hg.K_S) then
table.insert(actors, BipedActor:new(hg.RandomVec3(hg.Vec3(-10, 0, -10), hg.Vec3(10, 0, 10))))
end
if keyboard:Pressed(hg.K_D) then
if #actors > 0 then
table.remove(actors,1):destroy()
scene:GarbageCollect()
end
end
dt = hg.TickClock()
for i, actor in ipairs(actors) do
actor:update(dt)
end
scene:Update(dt)
view_state = hg.ComputePerspectiveViewState(hg.Mat4LookAt(hg.Vec3(0, 10, -14), hg.Vec3(0, 1, -4)), hg.Deg(45), 0.01, 1000, hg.ComputeAspectRatioX(res_x, res_y))
vid, passId = hg.SubmitSceneToPipeline(0, scene, hg.IntRect(0, 0, res_x, res_y), view_state, pipeline, res)
hg.Frame()
hg.UpdateWindow(win)
end
hg.RenderShutdown()
hg.DestroyWindow(win)