Skip to content

Commit

Permalink
wow! such hull! so convex! wow!
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Meehan committed Jun 1, 2016
1 parent fb43e29 commit 4d2478b
Show file tree
Hide file tree
Showing 13 changed files with 571 additions and 7 deletions.
70 changes: 70 additions & 0 deletions samples/convex-hull-edit/main.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
----------------------------------------------------------------
-- Copyright (c) 2010-2011 Zipline Games, Inc.
-- All Rights Reserved.
-- http://getmoai.com
----------------------------------------------------------------

MOAISim.openWindow ( "test", 512, 512 )

viewport = MOAIViewport.new ()
viewport:setSize ( 512, 512 )
viewport:setScale ( 512, 512 )

layer = MOAILayer2D.new ()
layer:setViewport ( viewport )
layer:setClearColor ( 1, 1, 1, 1 )
MOAISim.pushRenderPass ( layer )

drawPoints = function ( stream )

local total = stream:getLength () / 8
stream:seek ( 0 )

MOAIGfxMgr.setPenColor ( 0, 0, 1, 1 )

for i = 1, total do

local x = stream:readFloat ()
local y = stream:readFloat ()

MOAIDraw.fillCircle ( x, y, 2 )
end
end

points = MOAIMemStream.new ()
region = MOAIRegion.new ()

onDraw = function ()

drawPoints ( points )
region:drawDebug ()
end

onMouseLeftEvent = function ( down )

if down then

local x, y = layer:wndToWorld ( MOAIInputMgr.device.pointer:getLoc ())

points:seek ( points:getLength ())
points:writeFloat ( x )
points:writeFloat ( y )
points:seek ( 0 )

if points:getLength () / 8 >= 3 then
region:convexHull ( points )
end
end
end

onMouseRightEvent = function ( down )
if down then
points:discardAll ()
region:clear ()
end
end

MOAIInputMgr.device.mouseLeft:setCallback ( onMouseLeftEvent )
MOAIInputMgr.device.mouseRight:setCallback ( onMouseRightEvent )

layer:setOverlayTable ({ onDraw })
87 changes: 87 additions & 0 deletions samples/convex-hull/main.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
----------------------------------------------------------------
-- Copyright (c) 2010-2011 Zipline Games, Inc.
-- All Rights Reserved.
-- http://getmoai.com
----------------------------------------------------------------

MOAISim.openWindow ( "test", 512, 512 )

viewport = MOAIViewport.new ()
viewport:setSize ( 512, 512 )
viewport:setScale ( 512, 512 )

layer = MOAILayer2D.new ()
layer:setViewport ( viewport )
layer:setClearColor ( 1, 1, 1, 1 )
MOAISim.pushRenderPass ( layer )

drawPoints = function ( stream )

local total = stream:getLength () / 8
stream:seek ( 0 )

MOAIGfxMgr.setPenColor ( 0, 0, 1, 1 )

for i = 1, total do

local x = stream:readFloat ()
local y = stream:readFloat ()

MOAIDraw.fillCircle ( x, y, 2 )
end
end

generatePoints = function ( stream, total, xMin, yMin, xMax, yMax )

for i = 1, total do

local r = math.pow ( math.random (), 2 )
local a = math.random () * math.pi * 2

local hw = ( xMax - xMin ) / 2
local hh = ( yMax - yMin ) / 2

local x = xMin + hw + ( hw * ( math.cos ( a ) * r ))
local y = yMin + hh + ( hh * ( math.sin ( a ) * r ))

stream:writeFloat ( x )
stream:writeFloat ( y )
end

stream:seek ( 0 )
end

points = MOAIMemStream.new ()
region = MOAIRegion.new ()

generateHull = function ()

generatePoints ( points, 100, -172, -172, 172, 172 )
region:convexHull ( points )
end

onDraw = function ()

drawPoints ( points )
region:drawDebug ()
end

onMouseLeftEvent = function ( down )
if down then
points = MOAIMemStream.new ()
generateHull ()
end
end

onMouseRightEvent = function ( down )
if down then
generateHull ()
end
end

MOAIInputMgr.device.mouseLeft:setCallback ( onMouseLeftEvent )
MOAIInputMgr.device.mouseRight:setCallback ( onMouseRightEvent )

generateHull ()

layer:setOverlayTable ({ onDraw })
144 changes: 142 additions & 2 deletions src/moai-sim/MOAIRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,48 @@ int MOAIRegion::_boolean ( lua_State* L ) {
return 0;
}

//----------------------------------------------------------------//
// TODO: doxygen
int MOAIRegion::_clear ( lua_State* L ) {
MOAI_LUA_SETUP ( MOAIRegion, "U" )

self->Clear ();
return 0;
}

//----------------------------------------------------------------//
// TODO: doxygen
int MOAIRegion::_convexHull ( lua_State* L ) {
MOAI_LUA_SETUP ( MOAIRegion, "U" )

MOAIStream* stream = state.GetLuaObject < MOAIStream >( 2, true );

if ( stream ) {

size_t resetCursor = stream->GetCursor ();

size_t nVerts = state.GetValue < u32 >( 3, 0 );

if ( nVerts == 0 ) {
nVerts = stream->GetLength () / ZLHull2D::VERTEX_SIZE;
stream->Seek ( 0, SEEK_SET );
}

if ( nVerts > 0 ) {

ZLSizeResult result = self->ConvexHull ( *stream, nVerts );

if ( result.mCode == ZL_OK ) {
state.Push (( u32 )result.mValue );
return 1;
}
}

stream->Seek ( resetCursor, SEEK_SET );
}
return 0;
}

//----------------------------------------------------------------//
int MOAIRegion::_copy ( lua_State* L ) {
MOAI_LUA_SETUP ( MOAIRegion, "UU" )
Expand Down Expand Up @@ -205,6 +247,25 @@ int MOAIRegion::_getTriangles ( lua_State* L ) {
return 3;
}

//----------------------------------------------------------------//
// TODO: doxygen
int MOAIRegion::_getVertices ( lua_State* L ) {
MOAI_LUA_SETUP ( MOAIRegion, "U" )

MOAIStream* stream = state.GetLuaObject < MOAIStream >( 2, true );

if ( stream ) {

ZLSizeResult result = self->GetVertices ( *stream );

if ( result.mCode == ZL_OK ) {
state.Push (( u32 )result.mValue );
return 1;
}
}
return 0;
}

//----------------------------------------------------------------//
// TODO: doxygen
int MOAIRegion::_pad ( lua_State* L ) {
Expand Down Expand Up @@ -497,6 +558,12 @@ void MOAIRegion::BooleanXor ( const MOAIRegion& regionA, const MOAIRegion& regio
this->CombineAndTesselate ( regionA, regionB, TESS_WINDING_ODD );
}

//----------------------------------------------------------------//
void MOAIRegion::Clear () {

this->mPolygons.Clear ();
}

//----------------------------------------------------------------//
int MOAIRegion::CombineAndTesselate ( const MOAIRegion& regionA, const MOAIRegion& regionB, int windingRule ) {

Expand All @@ -515,6 +582,43 @@ int MOAIRegion::CombineAndTesselate ( const MOAIRegion& regionA, const MOAIRegio
return error;
}

//----------------------------------------------------------------//
ZLSizeResult MOAIRegion::ConvexHull ( ZLStream& vtxStream, size_t nVerts ) {

ZLCleanup < MOAIRegion > cleanup ( this, &MOAIRegion::Clear );

this->Clear ();

ZLMemStream hull;
ZLSizeResult hullSize = ZLHull2D::MonotoneChain ( hull, vtxStream, nVerts, ZLHull2D::SORT_CSTDLIB );

ZL_HANDLE_ERROR_CODE ( hullSize.mCode, ZL_RETURN_SIZE_RESULT ( 0, CODE ))

nVerts = hullSize;
if ( nVerts == 0 ) ZL_RETURN_SIZE_RESULT ( 0, ZL_ERROR )

ZL_HANDLE_ERROR_CODE ( this->ReservePolygons ( 1 ), ZL_RETURN_SIZE_RESULT ( 0, CODE ))
ZL_HANDLE_ERROR_CODE ( this->ReserveVertices ( 0, nVerts ), ZL_RETURN_SIZE_RESULT ( 0, CODE ));

hull.Seek ( 0, SEEK_SET );

for ( size_t i = 0; i < nVerts; ++i ) {

ZLResult < float > x = hull.Read < float >( 0.0f );
ZL_HANDLE_ERROR_CODE ( x.mCode, ZL_RETURN_SIZE_RESULT ( 0, CODE ));

ZLResult < float > y = hull.Read < float >( 0.0f );
ZL_HANDLE_ERROR_CODE ( y.mCode, ZL_RETURN_SIZE_RESULT ( 0, CODE ));

this->mPolygons [ 0 ].SetVert ( i, ZLVec2D ( x, y ));
}

this->Bless ();

cleanup.Skip ();
ZL_RETURN_SIZE_RESULT ( nVerts, ZL_OK )
}

//----------------------------------------------------------------//
void MOAIRegion::Copy ( const MOAIRegion& region ) {

Expand Down Expand Up @@ -788,6 +892,28 @@ u32 MOAIRegion::GetTriangles ( MOAIVertexFormat& format, MOAIVertexBuffer& vtxBu
return 0;
}

//----------------------------------------------------------------//
ZLSizeResult MOAIRegion::GetVertices ( ZLStream& vtxStream ) const {

size_t count = 0;

size_t nPolys = this->mPolygons.Size ();
for ( size_t i = 0; i < nPolys; ++i ) {

const ZLPolygon2D& poly = this->mPolygons [ i ];

size_t nVerts = poly.GetSize ();
for ( size_t j = 0; j < nVerts; ++j ) {

const ZLVec2D& v = poly.GetVertex ( j );
vtxStream.Write < float >( v.mX );
vtxStream.Write < float >( v.mY );
count++;
}
}
ZL_RETURN_SIZE_RESULT ( count, ZL_OK )
}

//----------------------------------------------------------------//
MOAIRegion::MOAIRegion () {

Expand Down Expand Up @@ -917,6 +1043,8 @@ void MOAIRegion::RegisterLuaFuncs ( MOAILuaState& state ) {
{ "append", _append },
{ "bless", _bless },
{ "boolean", _boolean },
{ "clear", _clear },
{ "convexHull", _convexHull },
{ "copy", _copy },
{ "countPolygons", _countPolygons },
{ "cull", _cull },
Expand All @@ -925,6 +1053,7 @@ void MOAIRegion::RegisterLuaFuncs ( MOAILuaState& state ) {
{ "getDistance", _getDistance },
{ "getPolygon", _getPolygon },
{ "getTriangles", _getTriangles },
{ "getVertices", _getVertices },
{ "pad", _pad },
{ "pointInside", _pointInside },
{ "print", _print },
Expand All @@ -944,9 +1073,20 @@ void MOAIRegion::RegisterLuaFuncs ( MOAILuaState& state ) {
}

//----------------------------------------------------------------//
void MOAIRegion::ReservePolygons ( size_t size ) {
ZLResultCode MOAIRegion::ReservePolygons ( size_t size ) {

return this->mPolygons.Init ( size );
}

//----------------------------------------------------------------//
ZLResultCode MOAIRegion::ReserveVertices ( size_t idx, size_t size ) {

this->mPolygons.Init ( size );
if ( idx >= this->mPolygons.Size ()) {

ZLResultCode result = this->mPolygons.Grow ( idx );
if ( result != ZL_OK ) return result;
}
return this->mPolygons [ idx ].ReserveVertices ( size );
}

//----------------------------------------------------------------//
Expand Down
Loading

0 comments on commit 4d2478b

Please sign in to comment.