void Pathfinder::BuildPath(PathNode * lastNode) { m_finalPath.clear(); m_edgesPath.clear(); //iterate over all node parents to get the full path PathNode * node = lastNode; USVec2D edgeDir; USVec2D edgePos; float edgeLength; while (node->GetParent()) { m_finalPath.push_back(node); for (std::vector<Polygon::Edge>::iterator itr = node->GetPolygon()->m_edges.begin(); itr != node->GetPolygon()->m_edges.end(); ++itr) { if (itr->m_neighbour == node->GetParent()->GetPolygon()) { edgeDir = node->GetPolygon()->m_vertices[itr->m_verticesID[1]] - node->GetPolygon()->m_vertices[itr->m_verticesID[0]]; edgeLength = edgeDir.Length(); edgePos = node->GetPolygon()->m_vertices[itr->m_verticesID[0]] + (edgeDir.NormVector() * (edgeLength / 2)); m_edgesPath.push_back(edgePos); } } node = node->GetParent(); } node = node; }
//45deg of img offset void AlignToMovementSteering::Update(Accelerations &acc, USVec2D target) { Character * ch = GetCh(); USVec2D direction = ch->GetLinearVelocity(); direction.Norm(); float wishAngVel = 0; if (direction.mX != 0) { wishAngVel = atan2f(direction.mY, direction.mX) * RAD2DEG; } Params &par = ch->GetParams(); par.target_rotation = wishAngVel; mAlignSteering->Update(acc, target); }
//----------------------------------------------------------------// bool _vecToXYPlane ( const USVec3D& v0, const USVec3D& v1, USVec2D& result ) { USVec3D vec; vec = v1; vec.Sub ( v0 ); if ( vec.mZ != 0.0f ) { result.mX = vec.mX; result.mY = vec.mY; float t = v0.mZ / -vec.mZ; if (( t > 0.0f ) && ( t <= 1.0f )) { result.Scale ( t ); result.mX += v0.mX; result.mY += v0.mY; return true; } } return false; }
Pathfinder::Pathfinder(): MOAIEntity2D(), m_navmesh{navmeshFilename} { RTTI_BEGIN RTTI_EXTEND(MOAIEntity2D) RTTI_END m_pathfinder = this; //fill m_nodes uint16_t numPolygons = m_navmesh.GetNumPolygons(); float cost = 0; USVec2D diagonal; float centreDist; for (uint16_t index = 0; index < numPolygons; ++index) { cost = rand() % 3000 + 500; PathNode node(m_navmesh.GetPolygon(index), cost, 0.f); diagonal = node.GetPolygon()->m_vertices[2] - node.GetPolygon()->m_vertices[0]; centreDist = diagonal.Length() / 2; node.SetCentrePos(node.GetPolygon()->m_vertices[0] + (diagonal.NormVector() * centreDist)); m_nodes.push_back(node); } }
//----------------------------------------------------------------// void MOAIPartitionLevel::GatherProps ( MOAIPartitionResultBuffer& results, MOAIProp* ignore, const USVec3D& point, u32 planeID, u32 mask ) { USVec2D cellPoint ( 0.0f, 0.0f ); switch ( planeID ) { case USBox::PLANE_XY: cellPoint.Init ( point.mX, point.mY ); break; case USBox::PLANE_XZ: cellPoint.Init ( point.mX, point.mZ ); break; case USBox::PLANE_YZ: cellPoint.Init ( point.mY, point.mZ ); break; }; float halfSize = this->mCellSize * 0.5f; cellPoint.mX = cellPoint.mX - halfSize; cellPoint.mY = cellPoint.mY + halfSize; MOAICellCoord coord = this->mGridSpace.GetCellCoord ( cellPoint.mX, cellPoint.mY ); int width = this->mGridSpace.GetWidth (); int height = this->mGridSpace.GetHeight (); int xTotal = ( width < 2 ) ? 1 : 2; int yTotal = ( height < 2 ) ? 1 : 2; for ( int y = 0; y < yTotal; ++y ) { for ( int x = 0; x < xTotal; ++x ) { MOAICellCoord offset = this->mGridSpace.WrapCellCoord ( coord.mX + x, coord.mY - y ); int addr = this->mGridSpace.GetCellAddr ( offset ); this->mCells [ addr ].GatherProps ( results, ignore, point, mask ); } } }
//----------------------------------------------------------------// void MOAIGridDeck2D::DrawIndex ( u32 idx, float xOff, float yOff, float zOff, float xScl, float yScl, float zScl ) { UNUSED ( zScl ); u32 size = this->mBrushes.Size (); if ( !size ) return; if ( !this->mGrid ) return; if ( !this->mDeck ) return; idx = ( idx - 1 ) % size; MOAIGridDeckBrush& brush = this->mBrushes [ idx ]; MOAICellCoord c0 = brush.mMin; MOAICellCoord c1 = brush.mMax; MOAIGrid& grid = *this->mGrid; float tileWidth = grid.GetTileWidth () * xScl; float tileHeight = grid.GetTileHeight () * yScl; xOff = xOff - ( c0.mX * tileWidth ) + brush.mOffset.mX; yOff = yOff - ( c0.mY * tileHeight ) + brush.mOffset.mY; for ( int y = c0.mY; y <= c1.mY; ++y ) { for ( int x = c0.mX; x <= c1.mX; ++x ) { MOAICellCoord wrap = grid.WrapCellCoord ( x, y ); idx = grid.GetTile ( wrap.mX, wrap.mY ); MOAICellCoord coord ( x, y ); USVec2D loc = grid.GetTilePoint ( coord, MOAIGridSpace::TILE_CENTER ); loc.Scale ( xScl, yScl ); this->mDeck->Draw ( idx, this->mRemapper, loc.mX + xOff, loc.mY + yOff, zOff, tileWidth, tileHeight, 1.0f ); } } }
//----------------------------------------------------------------// void MOAIDraw::DrawAxisGrid ( USVec2D loc, USVec2D vec, float size ) { USMatrix4x4 mtx = MOAIGfxDevice::Get ().GetViewProjMtx (); USMatrix4x4 invMtx; invMtx.Inverse ( mtx ); // Set the axis to the grid length so we can get the length back post-transform vec.SetLength ( size ); mtx.Transform ( loc ); mtx.TransformVec ( vec ); // Get the axis unit vector USVec2D norm = vec; size = norm.NormSafe (); // Get the axis normal USVec2D perpNorm ( norm.mY, -norm.mX ); // Project the corners of the viewport onto the axis to get the mix/max bounds float dot; float min; float max; USVec2D corner; // left, top corner.Init ( -1.0f, 1.0f ); corner.Sub ( loc ); dot = norm.Dot ( corner ); min = dot; max = dot; // right, top corner.Init ( 1.0f, 1.0f ); corner.Sub ( loc ); dot = norm.Dot ( corner ); min = ( dot < min ) ? dot : min; max = ( dot > max ) ? dot : max; // right, bottom corner.Init ( 1.0f, -1.0f ); corner.Sub ( loc ); dot = norm.Dot ( corner ); min = ( dot < min ) ? dot : min; max = ( dot > max ) ? dot : max; // left, bottom corner.Init ( -1.0f, -1.0f ); corner.Sub ( loc ); dot = norm.Dot ( corner ); min = ( dot < min ) ? dot : min; max = ( dot > max ) ? dot : max; // Get the start andstop grids s32 start = ( s32 )( min / size ) - 1; s32 stop = ( s32 )( max / size ) + 1; // Set the pen to the first... USVec2D pen = norm; pen.Scale (( float )start * size ); pen.Add ( loc ); // Step along the axis to draw perpendicular grid lines USRect viewRect; viewRect.Init ( -1.0f, -1.0f, 1.0f, 1.0f ); for ( ; start < stop; ++start ) { USVec2D p0; USVec2D p1; if ( viewRect.GetIntersection ( pen, perpNorm, p0, p1 )) { invMtx.Transform ( p0 ); invMtx.Transform ( p1 ); MOAIDraw::DrawLine ( p0, p1 ); } pen.Add ( vec ); } }
//----------------------------------------------------------------// void MOAITextDesigner::BuildLayout ( MOAITextBox& textBox ) { if ( !textBox.mStyleMap.GetTop ()) return; this->mStr = textBox.mText; this->mIdx = textBox.mCurrentPageIdx; this->mStyleSpan = 0; this->mStyle = 0; int tokenIdx = this->mIdx; int lineIdx = this->mIdx; float width = textBox.mFrame.Width (); float height = textBox.mFrame.Height (); u32 lineStart = 0; u32 lineSize = 0; u32 tokenStart = 0; u32 tokenSize = 0; USRect lineRect; lineRect.Init ( 0.0f, 0.0f, 0.0f, 0.0f ); USRect tokenRect; tokenRect.Init ( 0.0f, 0.0f, 0.0f, 0.0f ); float tokenAscent = 0.0f; float lineAscent = 0.0f; USVec2D pen; pen.Init ( 0.0f, 0.0f ); MOAIGlyph* glyph = 0; MOAIGlyph* prevGlyph = 0; textBox.mMore = true; bool more = true; while ( more ) { u32 c = this->NextChar ( textBox ); float scale = textBox.mGlyphScale * ( this->mStyle ? this->mStyle->mScale : 1.0f ); bool acceptToken = false; bool acceptLine = false; if ( MOAIFont::IsControl ( c )) { if ( c == '\n' ) { tokenIdx = this->mIdx - 1; tokenStart = textBox.mSprites.GetTop (); acceptToken = true; acceptLine = true; if ( !tokenRect.Height ()) { tokenRect.mYMax += this->mDeck->mHeight * scale; } } else if ( c == 0 ) { textBox.mMore = false; tokenIdx = this->mIdx - 1; tokenStart = textBox.mSprites.GetTop (); acceptToken = true; acceptLine = true; more = false; } } else { glyph = this->mDeck->GetGlyph ( c ); if ( !glyph ) continue; if ( glyph->mAdvanceX == 0.0f ) continue; // apply kerning if ( prevGlyph ) { MOAIKernVec kernVec = prevGlyph->GetKerning ( glyph->mCode ); pen.mX += kernVec.mX * scale; } prevGlyph = glyph; if ( MOAIFont::IsWhitespace ( c )) { if ( tokenSize ) { acceptToken = true; } } else { float glyphBottom = pen.mY + ( this->mDeck->mHeight * scale ); // handle new token if ( !tokenSize ) { tokenIdx = this->mIdx - 1; tokenStart = textBox.mSprites.GetTop (); tokenRect.Init ( pen.mX, pen.mY, pen.mX, glyphBottom ); tokenAscent = this->mDeck->mAscent * scale; } // check for overrun float glyphRight = pen.mX + (( glyph->mBearingX + glyph->mWidth ) * scale ); bool overrun = glyphRight > width; acceptLine = ( lineSize && overrun ); if ( acceptLine || !overrun ) { textBox.PushSprite ( this->mIdx - 1, *glyph, *this->mStyle, pen.mX, pen.mY, scale ); tokenRect.mXMax = glyphRight; tokenSize++; } } pen.mX += glyph->mAdvanceX * scale; } if ( acceptToken ) { lineRect.Grow ( tokenRect ); lineSize += tokenSize; lineAscent = tokenAscent > lineAscent ? tokenAscent : lineAscent; tokenSize = 0; } if ( acceptLine ) { textBox.PushLine ( lineStart, lineSize, lineRect, lineAscent ); // end line pen.mY += lineRect.Height () + textBox.mLineSpacing; lineRect.Init ( 0.0f, pen.mY, 0.0f, pen.mY ); // next line lineIdx = tokenIdx; lineStart = tokenStart; lineSize = 0; lineAscent = 0.0f; prevGlyph = 0; if ( tokenSize ){ // slide the current token (if any) back to the origin for ( u32 i = 0; i < tokenSize; ++i ) { MOAITextSprite& sprite = textBox.mSprites [ tokenStart + i ]; sprite.mX -= tokenRect.mXMin; sprite.mY = pen.mY; } pen.mX -= tokenRect.mXMin; tokenRect.Init ( 0.0f, pen.mY, tokenRect.Width (), pen.mY + tokenRect.Height ()); } else { pen.mX = 0.0f; tokenRect.Init ( 0.0f, pen.mY, 0.0f, pen.mY + this->mDeck->mHeight ); } } // if we overrun height, then back up to the start of the current line if ( tokenRect.mYMax > height ) { textBox.mSprites.SetTop ( lineStart ); textBox.mNextPageIdx = lineIdx; more = false; } } if ( textBox.mSprites.GetTop () == 0 ) { textBox.mMore = false; return; } float yOff = textBox.mFrame.mYMin; float layoutHeight = lineRect.mYMax; switch ( textBox.mVAlign ) { case MOAITextBox::CENTER_JUSTIFY: yOff = ( yOff + ( height * 0.5f )) - ( layoutHeight * 0.5f ); case MOAITextBox::LEFT_JUSTIFY: break; case MOAITextBox::RIGHT_JUSTIFY: yOff = textBox.mFrame.mYMax - layoutHeight; } u32 totalLines = textBox.mLines.GetTop (); for ( u32 i = 0; i < totalLines; ++i ) { MOAITextLine& line = textBox.mLines [ i ]; float xOff = textBox.mFrame.mXMin; float lineWidth = line.mRect.Width (); switch ( textBox.mHAlign ) { case MOAITextBox::CENTER_JUSTIFY: xOff = ( xOff + ( width * 0.5f )) - ( lineWidth * 0.5f ); case MOAITextBox::LEFT_JUSTIFY: break; case MOAITextBox::RIGHT_JUSTIFY: xOff = textBox.mFrame.mXMax - lineWidth; } line.mRect.Offset ( xOff, yOff ); float spriteYOff = yOff + line.mAscent; MOAIAnimCurve* curve = 0; if ( textBox.mCurves ) { curve = textBox.mCurves [ i % textBox.mCurves.Size ()]; } for ( u32 j = 0; j < line.mSize; ++j ) { MOAITextSprite& sprite = textBox.mSprites [ line.mStart + j ]; sprite.mX += xOff; if ( curve ) { sprite.mY += spriteYOff + curve->GetFloatValue (( sprite.mX - textBox.mFrame.mXMin ) / width ); } else { sprite.mY += spriteYOff; } } } }
//----------------------------------------------------------------// float USDist::PointToPlane2D ( const USVec2D& p, const USPlane2D& plane ) { float d = p.Dot ( plane.mNorm ) + plane.mDist; return (( d < FP_NEAR ) && ( d > -FP_NEAR )) ? 0.0f : d; }