精選文章

SmallBurger Asset Home

  SmallBurger

2010年7月27日 星期二

MDSceneEditor+PagedGeometry

如題,目前可以編輯的有:
  1. PageGrass:四層
  2. PageGeometry:可以任易Paint Entity。

影片:


YouTube:http://www.youtube.com/watch?v=GKHljOVV3es

4 則留言:

  1. 真厲害呀,做的比 ogitor 感覺還要棒!
    有兩個小問題想要請教:
    1. 地板上的「圓」大概要怎麼做?
    2. 圓的選取範圍要怎麼轉換成「影響哪些 vertex,並且影響的程度大小」?

    謝謝

    回覆刪除
  2. 1.地板上的「圓」大概要怎麼做?
    要自己寫一個筆刷物件,可以參考這篇http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Intermediate+Tutorial+6
    2.圓的選取範圍可以把它解釋成一個Rect範圍,再依序用for迴圈算出是否有cover到外圓,如果有代表要影響,而內圈到外圈則是從比例值1一直過渡到0,相關參考程式如下:
    bool CWOGSceneEditorView::ProcessDeform(float fDeltaTime)
    {
    CMDTerrain* pTerrain = SingletonMDRoot::Instance().GetTargetScene()->GetTerrain();
    if(pTerrain && m_pBrushObject)
    {
    CMDPoint3 EditPos = m_pBrushObject->GetTransform()->GetPosition();
    CMDPoint3 CovertTerrainPos;
    if(pTerrain->GetTerrainPosition(EditPos, CovertTerrainPos))
    {
    unsigned int uiMapSize = pTerrain->GetPageSize();
    CovertTerrainPos.m_fX *= uiMapSize-1;
    CovertTerrainPos.m_fZ *= uiMapSize-1;
    float fBrushSize = m_pBrushObject->GetControler()->GetOutSize();
    CMDRect MapRect;
    int iMapIndex;
    float fWorldSize = pTerrain->GetWorldSize();
    if(GetEditMapRect(&CovertTerrainPos, &MapRect, uiMapSize, fBrushSize, fWorldSize))
    {
    float fHeight, fXRatio, fYRatio;
    float fDeformDensity = m_fBrushDensity;
    if(s_bReverse)
    fDeformDensity *= -1.0f;

    for(int i = (int)MapRect.m_fTop;i < MapRect.m_fBottom;++i)
    {
    iMapIndex = (int)(i*uiMapSize + MapRect.m_fLeft);
    for(int j = (int)MapRect.m_fLeft;j < MapRect.m_fRight;++j)
    {
    fHeight = pTerrain->GetTerrainHeight(iMapIndex);
    fXRatio = (float)(j-(int)MapRect.m_fLeft)/((int)MapRect.m_fRight-(int)MapRect.m_fLeft);
    fYRatio = (float)(i-(int)MapRect.m_fTop)/((int)MapRect.m_fBottom-(int)MapRect.m_fTop);
    fHeight += m_pBrushObject->GetAffectRatio(fXRatio, fYRatio)*fDeformDensity*fDeltaTime;
    pTerrain->SetTerrainHeight(iMapIndex, fHeight);
    ++iMapIndex;
    }
    }
    pTerrain->SetRectDirty(MapRect);
    return true;
    }
    }
    }
    return false;
    }

    bool CWOGSceneEditorView::GetEditMapRect(MD::CMDPoint3* pEditPosition, MD::CMDRect* pMapRect,
    const unsigned int uiMapSize, const float fBrushSize, const float fWorldSize)
    {
    if(pEditPosition && pMapRect)
    {
    float fBrushRatioSize = fBrushSize/fWorldSize*uiMapSize;

    pMapRect->m_fLeft = (pEditPosition->m_fX - fBrushRatioSize/2.0f);
    pMapRect->m_fTop = (pEditPosition->m_fZ - fBrushRatioSize/2.0f);
    pMapRect->m_fRight = (fBrushRatioSize + (pEditPosition->m_fX - fBrushRatioSize/2));
    pMapRect->m_fBottom = (fBrushRatioSize + (pEditPosition->m_fZ - fBrushRatioSize/2));

    if(pMapRect->m_fLeft < 0.0f)
    {
    pMapRect->m_fLeft = 0.0f;
    }
    if(pMapRect->m_fTop < 0.0f)
    {
    pMapRect->m_fTop = 0.0f;
    }
    if(pMapRect->m_fRight > uiMapSize)
    {
    pMapRect->m_fRight = (float)uiMapSize;
    }
    if(pMapRect->m_fBottom > uiMapSize)
    {
    pMapRect->m_fBottom = (float)uiMapSize;
    }

    if(((pMapRect->m_fRight - pMapRect->m_fLeft) < 1) || ((pMapRect->m_fBottom - pMapRect->m_fTop) < 1))
    return false;

    return true;
    }
    return false;
    }

    float CMDBrushObject::GetAffectRatio(float fXRatio, float fYRatio)
    {
    float fInnerSize = m_pBrushControler->GetInnerSize();
    float fOutSize = m_pBrushControler->GetOutSize();

    float fInnerRatio = fInnerSize/fOutSize;

    float fInnerRatioSize = fInnerRatio*0.5f;

    float fDis = sqrt((fXRatio-0.5f)*(fXRatio-0.5f) + (fYRatio-0.5f)*(fYRatio-0.5f));
    if(fDis <= fInnerRatioSize)
    return 1.0f;

    if(fDis <= 0.5f && (fDis>= fInnerRatioSize))
    {
    return ((0.5f-fDis)/(0.5f-fInnerRatioSize));
    }
    return 0.0f;
    }

    回覆刪除
  3. 還有很多問題還沒處理,像跟lightmap疊到沒有變得比較黑的問題。我覺得ogre最大的好處,是相關可以參考的資源很多,也有很多人在使用,較容易交流。

    回覆刪除