前言
陸陸續續接觸osg有一段時間了. 也陸陸續續寫過很多小demo來做一些基礎的測試, 但是基本沒怎麼用在項目中,有的僅僅是顯示的部分.偶然間羣友就討論起了魔方來,其中一個小夥伴就問魔方的程序怎麼寫, 然後幾個小夥伴就本着無聊,就各自用自己知道的知識寫了一個玩, 我這個是c++osg的,其它的有個是.net的,還有一個是js的,本着學習記錄,說不定以後能回頭再完善些也好
展示
繪製出來的效果是這樣的
實際上爲了方便,將那個魔方可以任意調節節數
#define CUBEFSIZE 9;
功能羅列:
- 單個方塊的選擇
- 魔方面的選擇
- 魔方單個方塊的旋轉.
- 然後就是基本的旋轉等操作,
這裏如果選擇的話,我就讓他成爲白色.
這個是選擇面
接下來讓選擇的小方塊旋轉.
旋轉一個90°
接下來是代碼部分
創建面->創建小方塊->創建魔方 是這個過程.
聲明的頭文件 command.h
//繪製面.
osg::ref_ptr<osg::Geode> CreateQuardFaceNode(osg::ref_ptr<osg::Vec3Array> v, osg::Vec4d color, osg::Vec3d normal);
//繪製小方塊
osg::ref_ptr<osg::Geode> createBox(osg::Vec4d front, osg::Vec4d back, osg::Vec4d left, osg::Vec4d right, osg::Vec4d top, osg::Vec4d bootom, float Sizewidth = 1.0f);
//繪製模塊.
osg::Node* creatCrub();
實現部分
osg::ref_ptr<osg::Geode> CreateQuardFaceNode(osg::ref_ptr<osg::Vec3Array> v, osg::Vec4d color, osg::Vec3d normal)
{
//創建一個葉結點對象
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
//創建一個幾何體對象
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
//設置頂點數據
geom->setVertexArray(v);
//創建顏色數組
osg::ref_ptr<osg::Vec4Array> vc = new osg::Vec4Array;
//設置顏色數組
vc->push_back(color);
geom->setColorArray(vc);
//設置顏色綁定模式
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
//創建法線數組
osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array;
//增加法線,幾何體頂點都是是在XOZ面上,所以法線是Y軸
nc->push_back(normal);
//設置法線
geom->setNormalArray(nc);
//設置法線的綁定方式爲全部節點
/*BIND_OFF = 0,
BIND_OVERALL = 1,
BIND_PER_PRIMITIVE_SET = 2, 原始的.
BIND_PER_VERTEX = 4 變色*/
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
//添加圖元,繪圖基元爲四邊形,從第0個元素開始的四個元素,按照QUADS方式繪製四邊形
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
//添加到葉子節點中
geode->addChild(geom);
return geode.get();
}
osg::ref_ptr<osg::Geode> createBox(osg::Vec4d front, osg::Vec4d back, osg::Vec4d left, osg::Vec4d right, osg::Vec4d top, osg::Vec4d bootom, float Sizewidth)
{
osg::ref_ptr<osg::Geode> root = new osg::Geode;
//前
{
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
//逆時針添加數據
v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
v->push_back(osg::Vec3(Sizewidth, 0.0f, 0.0f));
v->push_back(osg::Vec3(Sizewidth, 0.0f, Sizewidth));
v->push_back(osg::Vec3(0, 0.0f, Sizewidth));
root->addChild(CreateQuardFaceNode(v.get(), front, osg::Vec3d(0, -1, 0)).get());
}
//後
{
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
//逆時針添加數據
v->push_back(osg::Vec3(0.0f, Sizewidth, 0.0f));
v->push_back(osg::Vec3(Sizewidth, Sizewidth, 0.0f));
v->push_back(osg::Vec3(Sizewidth, Sizewidth, Sizewidth));
v->push_back(osg::Vec3(0.0f, Sizewidth, Sizewidth));
root->addChild(CreateQuardFaceNode(v.get(), back, osg::Vec3d(0, 1, 0)).get());
}
//左
{
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
//逆時針添加數據
v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
v->push_back(osg::Vec3(0.0f, Sizewidth, 0.0f));
v->push_back(osg::Vec3(0.0f, Sizewidth, Sizewidth));
v->push_back(osg::Vec3(0.0f, 0.0f, Sizewidth));
root->addChild(CreateQuardFaceNode(v.get(), left, osg::Vec3d(-1, 0, 0)).get());
}
//右
{
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
//逆時針添加數據
v->push_back(osg::Vec3(Sizewidth, 0.0f, 0.0f));
v->push_back(osg::Vec3(Sizewidth, Sizewidth, 0.0f));
v->push_back(osg::Vec3(Sizewidth, Sizewidth, Sizewidth));
v->push_back(osg::Vec3(Sizewidth, 0.0f, Sizewidth));
root->addChild(CreateQuardFaceNode(v.get(), right, osg::Vec3d(1, 0, 0)).get());
}
//下
{
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
//逆時針添加數據
v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
v->push_back(osg::Vec3(0.0f, Sizewidth, 0.0f));
v->push_back(osg::Vec3(Sizewidth, Sizewidth, 0.0f));
v->push_back(osg::Vec3(Sizewidth, 0.0f, 0.0f));
root->addChild(CreateQuardFaceNode(v.get(), top, osg::Vec3d(0, 0, -1)).get());
}
//上
{
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
//逆時針添加數據
v->push_back(osg::Vec3(0.0f, 0.0f, Sizewidth));
v->push_back(osg::Vec3(0.0f, Sizewidth, Sizewidth));
v->push_back(osg::Vec3(Sizewidth, Sizewidth, Sizewidth));
v->push_back(osg::Vec3(Sizewidth, 0.0f, Sizewidth));
root->addChild(CreateQuardFaceNode(v.get(), bootom, osg::Vec3d(0, 0, 1)).get());
}
return root.release();
}
osg::Node* creatCrub()
{
const int MagicCubeNumber = CUBEFSIZE;
const float margin = 0.1;
const float coeff = 1.05f;
osg::ref_ptr<osg::Group> crub = new osg::Group;
for (int y = 0; y < MagicCubeNumber; y++)
{
for (int z = 0; z < MagicCubeNumber; z++)
{
for (int x = 0; x < MagicCubeNumber; x++)
{
osg::ref_ptr<osg::PositionAttitudeTransform> position = new osg::PositionAttitudeTransform();
osg::ref_ptr<osg::MatrixTransform> matexiTrans = new osg::MatrixTransform();
osg::ref_ptr<osg::Switch> _switch = new osg::Switch;
osg::ref_ptr<osg::Geode> box = createBox(osg::Vec4d(1.0, 0, 0, 1), osg::Vec4d(1.0, 0, 0, 1), osg::Vec4d(0.0, 1, 0, 1), osg::Vec4d(0.0, 1, 0, 1), osg::Vec4d(0.0, 0, 1, 1), osg::Vec4d(0.0, 0, 1, 1)).get();
osg::ref_ptr<osgFX::Scribe> scrip = new osgFX::Scribe();
scrip->addChild(createBox(osg::Vec4d(1.0, 0, 0, 1), osg::Vec4d(1.0, 0, 0, 1), osg::Vec4d(0.0, 1, 0, 1), osg::Vec4d(0.0, 1, 0, 1), osg::Vec4d(0.0, 0, 1, 1), osg::Vec4d(0.0, 0, 1, 1)).get());
_switch->addChild(box.get(), true);
_switch->addChild(scrip.get(), false);
_switch->setName("switch_node");
matexiTrans->addChild(_switch.get());
ostringstream str;
str << "boxName_" << x << "_" << y << "_" << z;
double xOffset = x * coeff + margin;
double yoffset = y * coeff + margin;
double zoffset = z * coeff + margin;
osg::Matrix mtrix = matexiTrans->getMatrix();
mtrix *= mtrix.translate(osg::Vec3d(xOffset, yoffset, zoffset));
matexiTrans->setMatrix(mtrix);
position->setName(str.str());
position->addChild(matexiTrans.get());
crub->addChild(position.get());
}
}
}
return crub.release();
}
這裏是主函數
int main()
{
std::cout << "main_20_6" << std::endl;
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
{
//設置圖形環境特性.
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->x = WindPositionX;
traits->y = WindPositionY;
traits->width = WindRecWidth;
traits->height = WindRecHeight;
traits->windowDecoration = true; //是否支持窗口擴展功能.
traits->doubleBuffer = true;//是否支持窗口縮放.
traits->sharedContext = 0;//共享上下文.
//創建圖形環境特性.
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
if (gc.valid())
{
//創建成功.
//清楚窗口顏色以及清除顏色和深度緩存.
gc->setClearColor(osg::Vec4f(0.2f, 0.2f, 0.6f, 1.0f));
gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
else
{
//這個圖形環境沒有被創建成功.
}
//根據分辨率確定合適的投影來保證顯示的圖形不變形.
double fovy, aspectRatio, zNear, zFar;
viewer->getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
double newAspectRatio = double(traits->width / traits->height);
double aspectRatioChange = newAspectRatio / aspectRatio;
if (aspectRatioChange != 1.0)
{
//設置投影矩陣.
viewer->getCamera()->getProjectionMatrix() *= osg::Matrix::scale(1.0 / aspectRatioChange, 1.0, 1.0);
}
viewer->getCamera()->setGraphicsContext(gc.get());
viewer->getCamera()->setViewport(0, 0, traits->width, traits->height);
}
viewer->addEventHandler(new CRubPickHandler(viewer.get()));
osg::ref_ptr<osg::Group> _box = new osg::Group();
_box->setName("GroupMast");
osg::ref_ptr<osg::Node> crub = creatCrub();
if (crub)
{
crub->setName("crub");
_box->addChild(crub.get());
}
osgUtil::Optimizer optimizer;
optimizer.optimize(_box.get());
viewer->setSceneData(_box.get());
viewer->realize();
viewer->run();
return 0;
}
到這一步,就可以讓其顯示了
這裏添加一個選擇器併爲其賦予選擇,高亮,旋轉等基礎功能
class CRubPickHandler : public osgGA::GUIEventHandler
{
public:
//事件處理函數
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
if (!view) return false;
switch (ea.getEventType())
{
//鼠標按下
case(osgGA::GUIEventAdapter::PUSH):
{
//更新鼠標位置
_mx = ea.getX();
_my = ea.getY();
break;
}
case(osgGA::GUIEventAdapter::RELEASE):
{
if (_mx == ea.getX() && _my == ea.getY())
{
//執行對象選取
//pick(view.get(), ea.getX(), ea.getY());
}
break;
}
case(osgGA::GUIEventAdapter::KEYDOWN):
{
if (ea.getKey() == 'w' || ea.getKey() == 'W')
{
//上
BoxPosition.z()++;
CheckBoxPosition();
std::cout << BoxPosition.x() << " " << BoxPosition.y() << " " << BoxPosition.z() << std::endl;
UpdataSigleBox(BoxPosition);
return true;
}
else if (ea.getKey() == 's' || ea.getKey() == 'S')
{
//下
BoxPosition.z()--;
CheckBoxPosition();
UpdataSigleBox(BoxPosition);
return true;
}
else if (ea.getKey() == 'a' || ea.getKey() == 'A')
{
//左
BoxPosition.x()--;
CheckBoxPosition();
UpdataSigleBox(BoxPosition);
return true;
}
else if (ea.getKey() == 'd' || ea.getKey() == 'D')
{
//右
BoxPosition.x()++;
CheckBoxPosition();
UpdataSigleBox(BoxPosition);
return true;
}
else if (ea.getKey() == 'x' || ea.getKey() == 'X')
{
//前進
BoxPosition.y()++;
CheckBoxPosition();
getCurrentObj = UpdataSigleBox(BoxPosition);
return true;
}
else if (ea.getKey() == 'q' || ea.getKey() == 'Q')
{
//選中行
UpdataSigleBox(BoxPosition);
std::vector<osg::Vec3d> positionList = getRowVects(BoxPosition);
setSelctionsBox(positionList);
}
else if (ea.getKey() == 'e' || ea.getKey() == 'E')
{
//選中列
UpdataSigleBox(BoxPosition);
std::vector<osg::Vec3d> positionList = getColVects(BoxPosition);
setSelctionsBox(positionList);
//osg::Vec3d centerBoxPosition = getPositionsCenter(positionList);
//osg::Node* centerBox = getNode(centerBoxPosition);
//addNode2View(centerBox);
//std::cout << centerBoxPosition.x() << " " << centerBoxPosition.y() << " " << centerBoxPosition.z() << std::endl;
return true;
}
else if (ea.getKey() == ea.KEY_Up) {
//旋轉.
std::cout << "上---旋轉....." << std::endl;
getCurrentObj = getNode(BoxPosition);
RotateNode2View(getCurrentObj , 90);
return true;
}
else if (ea.getKey() == ea.KEY_Down)
{
//旋轉.
std::cout << "下---旋轉....." << std::endl;
getCurrentObj = getNode(BoxPosition);
RotateNode2View(getCurrentObj, -90);
return true;
}
else if (ea.getKey() == ea.KEY_Left)
{
//左旋轉
std::cout << "左---旋轉....." << std::endl;
getCurrentObj = getNode(BoxPosition);
RotateNode2View(getCurrentObj, -90,osg::Vec3d(0,1,0));
return true;
}
else if (ea.getKey() == ea.KEY_Right)
{
//右旋轉
std::cout << "右---旋轉....." << std::endl;
getCurrentObj = getNode(BoxPosition);
RotateNode2View(getCurrentObj, 90, osg::Vec3d(0, 1, 0));
return true;
}
CheckBoxPosition();
break;
}
default:
break;
}
return false;
}
//對象選取事件處理器
void pick(osg::ref_ptr<osgViewer::View> view, float x, float y)
{
osgUtil::LineSegmentIntersector::Intersections intersections;
if (view->computeIntersections(x, y, intersections))
{
osgUtil::LineSegmentIntersector::Intersections::iterator inter = intersections.begin();//獲取第一個點
const osg::NodePath& nodePath = inter->nodePath;//獲取第一個交點的Path
for (int i = 1; i < nodePath.size() - 1; i++) {
std::string name = nodePath[i]->getName();
std::cout << name << std::endl;
}
}
}
protected:
//根據映射,找出節點位置.
std::map<osg::Vec3d, std::string> NodeMap;
const int CuBSize = CUBEFSIZE;
inline void initNodeMap()
{
for (int y = 0; y < CuBSize; y++)
{
for (int z = 0; z < CuBSize; z++)
{
for (int x = 0; x < CuBSize; x++)
{
ostringstream str;
str << "boxName_" << x << "_" << y << "_" << z;
NodeMap.insert(std::map<osg::Vec3d, std::string>::value_type(osg::Vec3d(x, y, z), str.str()));
}
}
}
}
//依據節點,獲取當前的Node
osg::ref_ptr<osg::Node> getNode(osg::Vec3d position, bool isOPenMonopLisze = false)
{
osg::ref_ptr <osg::Node> GetNodeObj = nullptr;
//循環遍歷節點.
std::map<osg::Vec3d, std::string>::iterator iter;
iter = NodeMap.find(position);
std::string findNodeName;
if (iter != NodeMap.end())
{
findNodeName = iter->second;
}
else
{
return nullptr;
}
osg::ref_ptr<osg::Group> root = { nullptr };
if (view)
{
root = view->getSceneData()->asGroup();
}
std::cout << root->getName() << std::endl;
//將當前對象中的boxName_0_0_0, 設置爲高亮..
if (root)
{
for (int i = 0; i < root->getNumChildren(); i++)
{
osg::Node* temp = root->getChild(i);
if (temp)
{
std::cout << temp->getName() << std::endl;
if (temp->getName() == "crub")
{
osg::Group *mgroup = temp->asGroup();
if (mgroup)
{
std::cout << "curb: childNumbers: " << mgroup->getNumChildren() << std::endl;
for (int j = 0; j < mgroup->getNumChildren(); j++)
{
GetNodeObj = mgroup->getChild(j)->asGroup();
if (GetNodeObj)
{
if (isOPenMonopLisze == false)
{
if (GetNodeObj->getName().compare(findNodeName.c_str()) == 0)
{
std::cout << "find Node: " << j << " " << GetNodeObj->getName() << std::endl;
break;
}
}
else
{
if (GetNodeObj->getName().compare(findNodeName.c_str()) == 0)
{
std::cout << "getScribe: " << j << " " << GetNodeObj->getName() << std::endl;
UpData(GetNodeObj, false);
}
else
{
//顯示原色.
UpData(GetNodeObj, true);
}
}
}
}
}
}
}
}
}
return GetNodeObj.release();
}
osg::ref_ptr<osg::Node> UpdataSigleBox(osg::Vec3d &position)
{
return getNode(position, true).release();
}
//選擇指定的節點
void setSelctionsBox(std::vector<osg::Vec3d> &PositionList)
{
for (int i = 0; i < PositionList.size(); i++)
{
osg::Node* mNode = getNode(PositionList[i], false);
if (mNode)
{
UpData(mNode, false);
}
}
}
//獲取當前節點的列截面所有的Node
std::vector<osg::Vec3d> getColVects(osg::Vec3d position)
{
//查找所有x軸一樣的點.
std::vector<osg::Vec3d> positionLists;
std::map<osg::Vec3d, std::string>::iterator iter = NodeMap.begin();
for (; iter != NodeMap.end(); ++iter)
{
if (iter->first.x() == position.x())
{
positionLists.push_back(iter->first);
}
}
return positionLists;
}
//獲取當前節點的行界面所有的Node
std::vector<osg::Vec3d> getRowVects(osg::Vec3d position)
{
//查找所有x軸一樣的點.
std::vector<osg::Vec3d> positionLists;
std::map<osg::Vec3d, std::string>::iterator iter = NodeMap.begin();
for (; iter != NodeMap.end(); ++iter)
{
if (iter->first.z() == position.z())
{
positionLists.push_back(iter->first);
}
}
return positionLists;
}
//替換當前子節點爲高亮顯示的節點.
void UpData(osg::Node* CurrentNode, bool status = false)
{
//沒起作用....
if (CurrentNode)
{
osg::Transform* transp = CurrentNode->asTransform();
if (transp)
{
osg::PositionAttitudeTransform * position = transp->asPositionAttitudeTransform();
if (position)
{
for (int i = 0; i < position->getNumChildren(); i++)
{
osg::Transform * transForm = position->getChild(i)->asTransform();
if (transForm)
{
//轉換成matrixTransForm
osg::MatrixTransform *matrixTrans = transForm->asMatrixTransform();
if (matrixTrans)
{
for (int j = 0; j < matrixTrans->getNumChildren(); j++)
{
osg::Switch* _switch = matrixTrans->getChild(j)->asSwitch();
if (_switch)
{
std::cout << "updata: " << _switch->getName() << std::endl;
_switch->setValue(0, status);
_switch->setValue(1, !status);
}
}
}
}
}
}
}
}
}
void CheckBoxPosition()
{
int cruBNumber = CUBEFSIZE - 1;
if (BoxPosition.x() > cruBNumber) BoxPosition.x() = cruBNumber;
else if (BoxPosition.x() < 0) BoxPosition.x() = 0;
if (BoxPosition.y() > cruBNumber) BoxPosition.y() = 0;
else if (BoxPosition.y() < 0) BoxPosition.y() = cruBNumber;
if (BoxPosition.z() > cruBNumber) BoxPosition.z() = cruBNumber;
else if (BoxPosition.z() < 0) BoxPosition.z() = 0;
}
//獲取當前選中面板的中心點.
osg::Vec3d getPositionsCenter(std::vector<osg::Vec3d>& positions)
{
//這裏要依據獲取到的模板數目.計算其中心點的座標.
osg::Vec3d center = { 0,0,0 };
osg::Vec3 cecnterAixyzNumbers = { 0,0,0 };
for (int i = 0; i < positions.size(); i++)
{
center.x() += positions[i].x();
center.y() += positions[i].y();
center.z() += positions[i].z();
}
return center / positions.size();
}
//在場景中添加模型.
void RotateNode2View(osg::Node* _node, double angle, osg::Vec3 coordinate = osg::Vec3(1, 0, 0))
{
if (_node)
{
osg::Transform* trans = _node->asTransform();
if (trans)
{
std::cout << "rotate: " << trans->getName() << std::endl;
osg::PositionAttitudeTransform *position = trans->asPositionAttitudeTransform();
if (position)
{
//
osg::Transform* trans_matrix = position->getChild(0)->asTransform();
if (trans_matrix)
{
osg::ref_ptr<osg::MatrixTransform> matrixTrans = trans_matrix->asMatrixTransform();
//獲取到當前旋轉矩陣下的要旋轉的模型物體.
osg::Switch* getBox = { nullptr };
for (int i = 0; i < matrixTrans->getNumChildren(); i++)
{
getBox = matrixTrans->getChild(i)->asSwitch();
}
if (getBox)
{
osg::Matrix originPos = matrixTrans->getMatrix();//獲取當前的矩陣.
osg::Vec3d center = getBox->getBound().center();
osg::Node* pParentNode;
osg::MatrixTransform *pParent;
//獲取當前模型在世界座標系中的矩陣以及位置信息.
pParentNode = getBox->getParent(0);
pParent = dynamic_cast<osg::MatrixTransform*>(pParentNode);
while (pParent != nullptr)
{
originPos = originPos * pParent->getMatrix();
pParentNode = pParent->getParent(0);
pParent = dynamic_cast<osg::MatrixTransform*>(pParentNode);
}
//逆矩陣
osg::Matrixd inverseALL = matrixTrans->getMatrix()*osg::Matrixd::inverse(originPos);
//獲取中心點在世界座標系中的位置.
osg::Vec3d originCenter = center * originPos;
//開始旋轉,並設置信息.
matrixTrans->setMatrix(originPos*osg::Matrixd::translate(-originCenter));
matrixTrans->setMatrix(matrixTrans->getMatrix()*osg::Matrixd::rotate(osg::DegreesToRadians(angle), coordinate.x(), coordinate.y(), coordinate.z()));
matrixTrans->setMatrix(matrixTrans->getMatrix()*osg::Matrixd::translate(originCenter)*inverseALL);
}
}
}
}
}
}
//將選中的節點,放入選擇器中.
void pushBackSelector(osg::Node* crubFace)
{
/* if (crubFace && _CrubSelection && dragger)
{
if (_CrubSelection->getNumChildren() > 0)
{
while(_CrubSelection->getNumChildren() > 0)
{
_CrubSelection->removeChild(_CrubSelection->getChild(0));
}
return;
}
_CrubSelection->addChild(crubFace);
float scale = crubFace->getBound().radius()*1.5;
dragger->setMatrix(osg::Matrix::scale(scale*0.5, scale*0.5, scale*0.5)*osg::Matrix::translate(crubFace->getBound().center()));
dragger->addTransformUpdating(_CrubSelection);
osg::Group*group = view->getSceneData()->asGroup();
if (group)
{
group->addChild(dragger);
}
}
*/
}
public:
CRubPickHandler(osgViewer::View *vt) :
_mx(0.0f),
_my(0.0f)
{
view = vt;
initNodeMap();
outline->setColor(osg::Vec4(1, 1, 0, 1));
outline->setWidth(8);
}
~CRubPickHandler()
{
}
//得到鼠標的位置
float _mx;
float _my;
osg::ref_ptr<osgViewer::View> view = { nullptr };
osg::Vec3d BoxPosition = { 0,0,0 };
osg::ref_ptr<osgFX::Outline> outline = new osgFX::Outline();
osg::Node* getCurrentObj = { nullptr };
};
這個魔方只是一個粗製的版本,很多地方需要雕琢,有很多不完善的地方;
整個魔方的操作,注意一些旋轉操作細節,旋轉中,已經設計好任意點旋轉了,所以整個魔方旋轉基調已經定下了;
關於如何判斷魔方是否已經拼好。實際上,每個方塊的面有一個標識,而魔方中的每個小方塊,也有自己三維座標,到時候,判斷小方塊的面的法向的朝向,是否是一致(奇葩想法…額,實在不行, 三視圖直接判斷顏色…)
以後有機會再完善吧, 有什麼不懂的,可以留言一起討論