fixed bug in AABB calculation when loading a scaled model file; bowling demo playable but needs tweaks

git-svn-id: svn://anubis/anaglym/trunk@211 99a6e188-d820-4881-8870-2d33a10e2619
This commit is contained in:
Josh Holtrop 2009-12-14 00:05:25 +00:00
parent c2a5ee2bfa
commit 1a8d0cc700
2 changed files with 151 additions and 28 deletions

View File

@ -985,7 +985,7 @@ Engine::Object::Object(bool is_static, OdeWorld & world, WFObj * obj,
m_display_list = obj->render(); m_display_list = obj->render();
const float * obj_aabb = obj->getAABB(); const float * obj_aabb = obj->getAABB();
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
m_aabb[i] = obj_aabb[i]; m_aabb[i] = scale * obj_aabb[i];
m_display_list_refcnt = new int; m_display_list_refcnt = new int;
*m_display_list_refcnt = 1; *m_display_list_refcnt = 1;
m_is_visible = true; m_is_visible = true;

View File

@ -4,19 +4,20 @@ ag.import("std")
function resetPins() function resetPins()
local head_x = 0 local head_x = 0
local head_y = 15 local head_y = 15
local spacing = 0.7 local spacing = 0.75
for i = 1, 10 do for i = 1, 10 do
if (pins[i] ~= nil) then if (pins[i] ~= nil) then
pins[i]:destroy() pins[i]:destroy()
end end
end end
local n = 1 local n = 1
for row = 0, 4 do for row = 0, 3 do
for j = 0, row do for j = 0, row do
pins[n] = reference_pin:clone() pins[n] = reference_pin:clone()
pins[n]:setPosition(head_x - row * spacing / 2 + j * spacing, pins[n]:setPosition(head_x - row * spacing / 2 + j * spacing,
head_y + 0.866 * spacing * row, head_y + 0.866 * spacing * row,
1 - pin_minz) 1 - pin_minz)
n = n + 1
end end
end end
end end
@ -42,12 +43,12 @@ function setupScore()
score = {} score = {}
for i = 1, 10 do for i = 1, 10 do
local s = {} local s = {}
s[1] = 0 s[1] = -1
s[2] = 0 s[2] = -1
s["tot"] = 0
if (i == 10) then if (i == 10) then
s[3] = 0 s[3] = -1
end end
s["tot"] = -1
score[i] = s score[i] = s
end end
end end
@ -56,56 +57,73 @@ function init_event()
lane = ag.loadModelStatic("bowling_lane") lane = ag.loadModelStatic("bowling_lane")
local minx, miny, minz, maxx, maxy, maxz = lane:getAABB() local minx, miny, minz, maxx, maxy, maxz = lane:getAABB()
local lane_bottom = minz local lane_bottom = minz
local lane_top = maxz
pins = {} pins = {}
reference_pin = ag.loadModel("bowling_pin", 1.0/4.3) reference_pin = ag.loadModel("bowling_pin", 1.0/4.3)
minx, miny, minz, maxx, maxy, maxz = reference_pin:getAABB() minx, miny, minz, maxx, maxy, maxz = reference_pin:getAABB()
pin_minz = minz pin_minz = minz
pin_maxz = maxz pin_maxz = maxz
pin_standing_position = lane_top - pin_minz
local box = ag.createBoxStatic(1, 10, 0.1) local box = ag.createBoxStatic(1, 10, 0.1)
box:setVisible(false) box:setVisible(false)
box:setPosition(0, 0, lane_bottom - (maxz - minz) - 0.4) box:setPosition(0, 0, lane_bottom - (maxz - minz) - 0.4)
reference_pin:setPosition(0, 0, lane_bottom - maxz - 0.1) reference_pin:setPosition(0, 0, lane_bottom - maxz - 0.1)
reference_ball = ag.createSphere(0.3) reference_ball = ag.createSphere(0.25)
reference_ball:setColor(0.7, 0.1, 0.9) reference_ball:setColor(0.7, 0.1, 0.9)
reference_ball:setMass(10) reference_ball:setMass(10)
reference_ball:setPosition(0, -2, -1.5) reference_ball:setPosition(0, -2, -1.5)
resetPins()
setupStars() setupStars()
setupScore() setupScore()
position_x = 0 position_x = 0
target_x = 0 target_x = 0
game_state = "waiting" game_state = "waiting"
last_update_time = ag.elapsedTime()
mouse_moved = false mouse_moved = false
setCamera() newFrame()
last_update_time = ag.elapsedTime()
setCamera(last_update_time)
end end
function setCamera() function setCamera(now)
ag.setCamera(position_x, -10, 5, target_x, 20, 0) if (game_state == "launched") then
local pct = (now - launch_time) / 2500
if (pct > 1) then
pct = 1
end
ag.setCamera(position_x + (-position_x * pct), -10 + 10 * pct, 5 + 5 * pct, target_x, 20, 0)
else
ag.setCamera(position_x, -10, 5, target_x, 20, 0)
end
end end
function update_event() function update_event()
local now = ag.elapsedTime() local now = ag.elapsedTime()
if (ag.isKeyDown("a") or ag.isKeyDown("left")) then if (game_state == "waiting") then
position_x = position_x - (now - last_update_time) / 300 if (ag.isKeyDown("a") or ag.isKeyDown("left")) then
if (position_x < -2) then position_x = position_x - (now - last_update_time) / 300
position_x = -2 if (position_x < -2) then
position_x = -2
end
end end
end if (ag.isKeyDown("d") or ag.isKeyDown("right")) then
if (ag.isKeyDown("d") or ag.isKeyDown("right")) then position_x = position_x + (now - last_update_time) / 300
position_x = position_x + (now - last_update_time) / 300 if (position_x > 2) then
if (position_x > 2) then position_x = 2
position_x = 2 end
end end
end end
last_update_time = now last_update_time = now
setCamera() if (game_state == "launched") then
if (now - launch_time > 7000) then
endBall()
end
end
setCamera(now)
ag.callList(stars) ag.callList(stars)
end end
function mouse_motion_event(x, y, xrel, yrel) function mouse_motion_event(x, y, xrel, yrel)
if (mouse_moved) then if (mouse_moved and game_state == "waiting") then
target_x = target_x + xrel / 100 target_x = target_x + xrel / 100
if (target_x < -2) then if (target_x < -2) then
target_x = -2 target_x = -2
@ -136,11 +154,11 @@ function drawFrameScore(width, height, frame, fs)
balls = 3 balls = 3
end end
for ball = 1, balls do for ball = 1, balls do
if ((frame < current_frame) or (frame == current_frame and ball < current_ball)) then if (fs[ball] ~= -1) then
local ball_base_x = base_x + local_width - (1 + balls - ball) * ball_size + 7 local ball_base_x = base_x + local_width - (1 + balls - ball) * ball_size + 7
local ball_base_y = base_y + size - ball_size + 7 local ball_base_y = base_y + size - ball_size + 7
ag.drawText(fs[ball], 1, 0.6, 0, 14, ball_base_x, ball_base_y) ag.drawText(fs[ball], 1, 0.6, 0, 14, ball_base_x, ball_base_y)
if (frame < current_frame and fs["tot"] ~= 0) then if (fs["tot"] ~= -1) then
local w, h = ag.getTextSize(fs["tot"], 16) local w, h = ag.getTextSize(fs["tot"], 16)
ag.drawText(fs["tot"], 1, 0.6, 0, 16, base_x + local_width - 10 - w, base_y + 10) ag.drawText(fs["tot"], 1, 0.6, 0, 16, base_x + local_width - 10 - w, base_y + 10)
end end
@ -163,6 +181,11 @@ function update_overlay_event(width, height)
if (game_state == "get_accuracy" or game_state == "launched") then if (game_state == "get_accuracy" or game_state == "launched") then
drawAccuracyBar(width, height) drawAccuracyBar(width, height)
end end
if (game_state == "waiting") then
local cursor_size = 8
ag.drawLine(0, 1, 0, width / 2, height / 2 - cursor_size, width / 2, height / 2 + cursor_size)
ag.drawLine(0, 1, 0, width / 2 - cursor_size, height / 2, width / 2 + cursor_size, height / 2)
end
end end
function mousebutton_down_event(button, x, y) function mousebutton_down_event(button, x, y)
@ -195,17 +218,117 @@ function launchBall()
game_state = "launched" game_state = "launched"
launch_time = ag.elapsedTime() launch_time = ag.elapsedTime()
bowling_ball = reference_ball:clone() bowling_ball = reference_ball:clone()
bowling_ball:setPosition(position_x, -10, 1.31) bowling_ball:setPosition(position_x, -10, 1.26)
local fx = target_x + accuracy - position_x local fx = target_x + accuracy - position_x
local fy = 30 -- should match setCamera()'s dy local fy = 30 -- should match setCamera()'s dy
local d = math.sqrt(fx*fx + fy*fy) local d = math.sqrt(fx*fx + fy*fy)
fx = fx / d fx = fx / d
fy = fy / d fy = fy / d
local force = 200000 local force = 150000
force = force * 0.5 + force * 0.5 * power force = force * 0.5 + force * 0.5 * power
bowling_ball:addForce(fx * force, fy * force, 0) bowling_ball:addForce(fx * force, fy * force, 0)
end end
function endBall()
game_state = "waiting"
bowling_ball:destroy()
-- find all the pins that were knocked over
local pin_count = 0
for i = 1, 10 do
if (pins[i] ~= nil) then
local x, y, z = pins[i]:getPosition()
if (z < pin_standing_position - 0.05) then
pins[i]:destroy()
pins[i] = nil
pin_count = pin_count + 1
end
end
end
updateScore(pin_count)
end
function getNextBall(frame, ball)
ball = ball + 1
if (ball > 2 and frame < 10) then
frame = frame + 1
ball = 1
end
return frame, ball
end
function getNextBallAfterStrike(frame, ball)
if (frame == 10) then
ball = ball + 1
else
frame = frame + 1
end
return frame, ball
end
function updateScore(pin_count)
score[current_frame][current_ball] = pin_count
-- update total score
for f = 1, 10 do
local prevscore = 0
if (f > 1) then
prevscore = score[f-1]["tot"]
end
if (score[f][1] == 10) then -- strike
local nf, nb = getNextBallAfterStrike(f, 1)
if (score[nf][nb] == -1) then
break
else
local nf2, nb2
if (score[nf][nb] == 10) then
nf2, nb2 = getNextBallAfterStrike(nf, nb)
else
nf2, nb2 = getNextBall(nf, nb)
end
if (score[nf2][nb2] == -1) then
break
else
score[f]["tot"] = prevscore + 10 + score[nf][nb] + score[nf2][nb2]
end
end
elseif (score[f][1] == -1 or score[f][2] == -1) then
break
elseif (score[f][1] + score[f][2] == 10) then -- spare
if (score[f+1][1] == -1) then
break
else
score[f]["tot"] = prevscore + 10 + score[f+1][1]
end
else
score[f]["tot"] = score[f][1] + score[f][2]
end
end
if (pin_count == 10 and current_frame < 10) then
current_frame = current_frame + 1
current_ball = 1
newFrame()
elseif (current_frame == 10) then
current_ball = current_ball + 1
if ((current_ball == 3 and (score[10][1] + score[10][2]) < 10) or (current_ball == 4)) then
gameOver()
end
else
current_ball = current_ball + 1
if (current_ball > 2) then
current_ball = 1
current_frame = current_frame + 1
newFrame()
end
end
end
function newFrame()
resetPins()
end
function gameOver()
game_state = "gameover"
end
function drawPowerBar(width, height) function drawPowerBar(width, height)
local bar_width = 80 local bar_width = 80
local bar_height = 400 local bar_height = 400