Sunday, April 5, 2020

마야 노드 에디터

마야의 노드 에디터를 활용하면 멜 스크립트를 사용하지 않고도 원하는 로직 실행이 가능하다.
가령 A라는 오브젝트의 x 위치값이 바뀔 때 오브젝트 B의 스케일 Y값을 변경하려면
보통 다음과 같이 코딩을 하게 되는데

B.scaleY = A.translateX

이런 코드를 직접 작성하지 않고 노드로 표현 가능하다.

Simple implementation of Decision Tree with C++

Simple implementation of Decision Tree with C++
=================================


#include <iostream>

using namespace std;

bool val_visible = false;
bool val_evidence = true;
bool val_hungry = false;
float val_distance = 50;

class GameWorldEnv
{
public:
float GetPlayerDistance()
{
return rand() % 100;
}
};

class DecisionNode
{
public:
virtual DecisionNode* Decision() { return nullptr; };
virtual void Action() {};
};

class Decision : public DecisionNode
{
public:

};

class Boolean : public Decision
{
public:
Boolean(bool* val, DecisionNode* yes, DecisionNode* no)
: mTestValue(val)
, mYesNode(yes)
, mNoNode(no)
{

}

DecisionNode* Decision()
{
if (*mTestValue)
{
return mYesNode;
}
return mNoNode;
}

DecisionNode* mYesNode;
DecisionNode* mNoNode;
bool* mTestValue;
};

class Close : public Decision
{
public:
Close(float* distance, GameWorldEnv* env, DecisionNode* yes, DecisionNode* no)
: mTestDistance(distance)
, mEnv(env)
, mYesNode(yes)
, mNoNode(no)
{

}

DecisionNode* Decision()
{
if (mEnv->GetPlayerDistance() < *mTestDistance)
{
return mYesNode;
}
return mNoNode;
}

DecisionNode* mYesNode;
DecisionNode* mNoNode;

GameWorldEnv* mEnv;
float* mTestDistance;
};

class Action : public DecisionNode
{
public:

};

class Eat : public Action
{
public:
void Action()
{
cout << "Action Executed : Eat" << endl;
}
};

class Wander : public Action
{
public:
void Action()
{
cout << "Action Executed : Wander" << endl;
}
};

class Attack : public Action
{
public:
void Action()
{
cout << "Action Executed : Attack" << endl;
}
};

class Trace : public Action
{
public:
void Action()
{
cout << "Action Executed : Trace" << endl;
}

};

// Action은 Wander, Eat, Trace, Attack
// 총 4개가 있다.

void Process(DecisionNode* node)
{
DecisionNode* newNode = node->Decision();
if (newNode != nullptr)
{
Process(newNode);
}
else
{
// action
node->Action();
}
}

int main()
{
Eat eatNode;
Wander wanderNode;
Attack attackNode;
Trace traceNode;

GameWorldEnv env;
Close closeNode(&val_distance, &env, &attackNode, &traceNode);
Boolean hungryNode(&val_hungry, &eatNode, &wanderNode);
Boolean evidenceNode(&val_evidence, &closeNode, &hungryNode);
Boolean visibleNode(&val_visible, &closeNode, &evidenceNode);

DecisionNode* root = &visibleNode;

// Make a decision tree
for (int i = 0; i < 3; ++i)
{
Process(root);
Process(root);
}
}

Wednesday, March 18, 2020

digital image processing practice

Recently I'm working from home and doing digital image processing.
Especially I'm using latest MFC and really surprised! Every fancy UIs were almost free to use now :) it wasn't easy to make this kind of UIs when I was using MFC.



Monday, March 9, 2020

Path Smoothing

Very simple implementation of path smoothing algorithm.



private void GenerateSmoothedPaths()
{
    smoothedPaths.Clear();       
    smoothedPaths.Add(paths[0].transform.position);

    int index = 1;
    while(index < paths.Length-1)
    {
        Vector3 fromPos = smoothedPaths[smoothedPaths.Count - 1];
        Vector3 toPos = paths[index].transform.position;

        Ray ray = new Ray(fromPos, (toPos - fromPos).normalized);
        RaycastHit hitInfo;
        if ( Physics.Raycast(ray, out hitInfo, Vector3.Distance(fromPos, toPos)) )
        {  
            smoothedPaths.Add(paths[index-1].transform.position);
        }
           
        index++;
    }

    smoothedPaths.Add(paths[paths.Length-1].transform.position);
}


Task in UnrealEngine

 https://www.youtube.com/watch?v=1lBadANnJaw