int gr_joint_cmd(lua_State* L) { GRLUA_DEBUG_CALL; gr_node_ud* data = (gr_node_ud*)lua_newuserdata(L, sizeof(gr_node_ud)); data->node = 0; const char* name = luaL_checkstring(L, 1); JointNode* node = new JointNode(name); luaL_checktype(L, 2, LUA_TTABLE); luaL_argcheck(L, luaL_getn(L, 2) == 3, 2, "Three-tuple expected"); luaL_checktype(L, 3, LUA_TTABLE); luaL_argcheck(L, luaL_getn(L, 3) == 3, 3, "Three-tuple expected"); double x[3], y[3]; for (int i = 1; i <= 3; i++) { lua_rawgeti(L, 2, i); x[i - 1] = luaL_checknumber(L, -1); lua_rawgeti(L, 3, i); y[i - 1] = luaL_checknumber(L, -1); lua_pop(L, 2); } node->set_joint_x(x[0], x[1], x[2]); node->set_joint_y(y[0], y[1], y[2]); data->node = node; luaL_getmetatable(L, "gr.node"); lua_setmetatable(L, -2); return 1; }
void SceneNode::Rotate( char axis, double angle ) { if( IsJoint() ) { JointNode* joint = dynamic_cast<JointNode*>(this); switch( axis ) { case 'x': joint->SetCurX( joint->GetJointX().cur + angle ); break; case 'y': joint->SetCurY( joint->GetJointY().cur + angle ); break; default: break; } } angle = angle * M_PI / 180.0; Matrix4x4 rotMatrix; switch( axis ) { case 'x': rotMatrix[1][1] = cos( angle ); rotMatrix[1][2] = -sin( angle ); rotMatrix[2][1] = sin( angle ); rotMatrix[2][2] = cos( angle ); break; case 'y': rotMatrix[0][0] = cos( angle ); rotMatrix[0][2] = sin( angle ); rotMatrix[2][0] = -sin( angle ); rotMatrix[2][2] = cos( angle ); break; case 'z': rotMatrix[0][0] = cos( angle ); rotMatrix[0][1] = -sin( angle ); rotMatrix[1][0] = sin( angle ); rotMatrix[1][1] = cos( angle ); break; default: break; } SetTransform( mTrans * rotMatrix ); }
Shield::Shield(SceneNode* element, MoveableSubscriber* subscriber) : Moveable(element, subscriber) , m_bMajor(false) , m_nTTLMax(0) , m_nTTL(0) { JointNode* pCog = static_cast<JointNode*>(element->find("cog")); pCog->set_axis('y'); pCog->freeze(); AnnimationFrame* pFrame; pFrame = new AnnimationFrame(); pFrame->m_nFrames = SHIELD_FRAME_LENGTH; pFrame->m_nRemainingFrames = SHIELD_FRAME_LENGTH; pFrame->m_bLoopBack = true; pFrame->m_nAngle = 120; pCog->add_frame(pFrame); pFrame = new AnnimationFrame(); pFrame->m_nFrames = SHIELD_FRAME_LENGTH; pFrame->m_nRemainingFrames = SHIELD_FRAME_LENGTH; pFrame->m_bLoopBack = true; pFrame->m_nAngle = 240; pCog->add_frame(pFrame); pFrame = new AnnimationFrame(); pFrame->m_nFrames = SHIELD_FRAME_LENGTH; pFrame->m_nRemainingFrames = SHIELD_FRAME_LENGTH; pFrame->m_bLoopBack = true; pFrame->m_nAngle = 0; pCog->add_frame(pFrame); }
int gr_joint_cmd(lua_State* L) { GRLUA_DEBUG_CALL; gr_node_ud* data = (gr_node_ud*)lua_newuserdata(L, sizeof(gr_node_ud)); data->node = 0; const char* name = luaL_checkstring(L, 1); JointNode* node = new JointNode(name); double x[3], y[3]; get_tuple(L, 2, x, 3); get_tuple(L, 3, y, 3); node->set_joint_x(x[0], x[1], x[2]); node->set_joint_y(y[0], y[1], y[2]); data->node = node; luaL_getmetatable(L, "gr.node"); lua_setmetatable(L, -2); return 1; }
void Viewer::redo() { if (m_redo.empty()) { Gtk::MessageDialog dialog("Can't redo"); dialog.run(); return; } History record = m_redo.top(); m_redo.pop(); // execute that record SceneNode *node = m_root->find(record.id); assert(node); assert(node->is_joint()); JointNode *joint = dynamic_cast<JointNode*>(node); assert(joint); joint->joint_x() = record.xRot; joint->joint_y() = record.yRot; m_undo.push(record); }
SceneNode* DinoNode::buildDino() { const ColorSpec* BODY_COLOR; const ColorSpec* HEAD_COLOR; const ColorSpec* SPIKE_COLOR; const ColorSpec* NECK_COLOR; const ColorSpec* TAIL_COLOR; const ColorSpec* LEG_COLOR; const ColorSpec* EYE_COLOR; const ColorSpec* PUPIL_COLOR; const ColorSpec* TONGUE_COLOR; if (state_.getType() == CHAR_PC) { BODY_COLOR = Config::PLAYER_BODY_COLOR; HEAD_COLOR = Config::PLAYER_HEAD_COLOR; SPIKE_COLOR = Config::PLAYER_SPIKE_COLOR; NECK_COLOR = Config::PLAYER_NECK_COLOR; TAIL_COLOR = Config::PLAYER_TAIL_COLOR; LEG_COLOR = Config::PLAYER_LEG_COLOR; EYE_COLOR = Config::PLAYER_EYE_COLOR; PUPIL_COLOR = Config::PLAYER_PUPIL_COLOR; TONGUE_COLOR = Config::PLAYER_TONGUE_COLOR; } else { BODY_COLOR = Config::BOT_BODY_COLOR; HEAD_COLOR = Config::BOT_HEAD_COLOR; SPIKE_COLOR = Config::BOT_SPIKE_COLOR; NECK_COLOR = Config::BOT_NECK_COLOR; TAIL_COLOR = Config::BOT_TAIL_COLOR; LEG_COLOR = Config::BOT_LEG_COLOR; EYE_COLOR = Config::BOT_EYE_COLOR; PUPIL_COLOR = Config::BOT_PUPIL_COLOR; TONGUE_COLOR = Config::BOT_TONGUE_COLOR; } // Build neck and head JointNode* neck1J = new JointNode("neck1J", -10, 0, 0, 0, 4, 0); BodyPartNode* neck1 = new BodyPartNode("neck1", 2, 4, 2, NECK_COLOR); TranslationNode* neck1Up = new TranslationNode("neck1UpT", 0, 1, 0); TranslationNode* neck1Down = new TranslationNode("neck1DownT", 0, -1, 0); SpikeNode* neckSpike = new SpikeNode("neckSpike", 1.5, 3, SPIKE_HORIZONTAL, SPIKE_COLOR); JointNode* neck2J = new JointNode("neck2J", 0, 4, 0, 0, 4, 0); BodyPartNode* neck2 = new BodyPartNode("neck2", 1.75, 4, 2, NECK_COLOR); JointNode* neck3J = new JointNode("neck3J", 0, 4, 0, 0, 4, 0); BodyPartNode* neck3 = new BodyPartNode("neck3", 1.5, 4, 2, NECK_COLOR); JointNode* headJ = new JointNode("headJ", 0, 5.5, 0, -2.5, 0, 0); BodyPartNode* head = new BodyPartNode("head", 4, 3, 3, HEAD_COLOR); SpikeNode* leftHeadSpike = new SpikeNode("leftHeadSpike", 1.5, 7, SPIKE_DIAG_LEFT, SPIKE_COLOR); SpikeNode* rightHeadSpike = new SpikeNode("rightHeadSpike", 1.5, 6, SPIKE_DIAG_RIGHT, SPIKE_COLOR); JointNode* leftEyeJ = new JointNode("leftEyeJ", -1, 1.5, 1.8, 0, 0, 0); BodyPartNode* leftEye = new BodyPartNode("leftEye", 1, 1, 1, EYE_COLOR); BodyPartNode* leftPupil = new BodyPartNode("leftPupil", 0.5, 0.5, 0.5, PUPIL_COLOR); TranslationNode* leftPupilT = new TranslationNode("leftPupilT", -0.5, 0.5, 0.5); JointNode* rightEyeJ = new JointNode("rightEyeJ", -1, 1.5, -1.8, 0, 0, 0); BodyPartNode* rightEye = new BodyPartNode("rightEye", 1, 1, 1, EYE_COLOR); BodyPartNode* rightPupil = new BodyPartNode("rightPupil", 0.5, 0.5, 0.5, PUPIL_COLOR); TranslationNode* rightPupilT = new TranslationNode("rightPupilT", -0.5, 0.5, -0.5); TranslationNode* tongueT = new TranslationNode("tongueT", -4, -1, 0); BodyPartNode* tongue = new BodyPartNode("tongue", 1, 0.15, 1, TONGUE_COLOR); neck1J->addChild(neck1); neck1->addChild(neck2J); neck2J->addChild(neck2); neck2->addChild(neck3J); neck3J->addChild(neck3); neck3->addChild(headJ); headJ->addChild(head); head->addChild(leftHeadSpike); head->addChild(rightHeadSpike); head->addChild(leftEyeJ); leftEyeJ->addChild(leftEye); leftEye->addChild(leftPupilT); leftPupilT->addChild(leftPupil); head->addChild(rightEyeJ); rightEyeJ->addChild(rightEye); rightEye->addChild(rightPupilT); rightPupilT->addChild(rightPupil); head->addChild(tongueT); tongueT->addChild(tongue); // spikes on neck neck1->addChild(neck1Up); neck1Up->addChild(neckSpike); neck1->addChild(neck1Down); neck1Down->addChild(neckSpike); neck2->addChild(neck1Up); neck2->addChild(neck1Down); neck3->addChild(neck1Up); neck3->addChild(neck1Down); // build tail JointNode* tail1J = new JointNode("tail1J", 9, 0, 0, 3, 0, 0); BodyPartNode* tail1 = new BodyPartNode("tail1", 3, 1.5, 3.5, TAIL_COLOR); SpikeNode* tailSpike1 = new SpikeNode("tailSpike1", 1, 3, SPIKE_VERTICAL, SPIKE_COLOR); JointNode* tail2J = new JointNode("tail2J", 3, 0, 0, 2, 0, 0); BodyPartNode* tail2 = new BodyPartNode("tail2", 2, 1.25, 2.5, TAIL_COLOR); SpikeNode* tailSpike2 = new SpikeNode("tailSpike2", 0.75, 2.5, SPIKE_VERTICAL, SPIKE_COLOR); JointNode* tail3J = new JointNode("tail3J", 2, 0, 0, 1.5, 0, 0); BodyPartNode* tail3 = new BodyPartNode("tail3", 1.5, 1.0, 1.5, TAIL_COLOR); SpikeNode* tailSpike3 = new SpikeNode("tailSpike3", 0.5, 2, SPIKE_VERTICAL, SPIKE_COLOR); tail1J->addChild(tail1); tail1->addChild(tail2J); tail1->addChild(tailSpike1); tail2J->addChild(tail2); tail2->addChild(tail3J); tail2->addChild(tailSpike2); tail3J->addChild(tail3); tail3->addChild(tailSpike3); // build legs JointNode* legBL1J = new JointNode("legBL1J", 7, -2, 4.0, 0, 0, 1.5); BodyPartNode* legBL1 = new BodyPartNode("legBL1", 1.5, 1.0, 1.5, LEG_COLOR); JointNode* legBL2J = new JointNode("legBL2J", 0, 0, 1.5, 0, 0, 4); BodyPartNode* legBL2 = new BodyPartNode("legBL2", 2.5, 1.0, 4, LEG_COLOR); JointNode* legBR1J = new JointNode("legBR1J", 7, -2, -4.0, 0, 0, -1.5); BodyPartNode* legBR1 = new BodyPartNode("leg1BR", 1.5, 1.0, 1.5, LEG_COLOR); JointNode* legBR2J = new JointNode("legBR2J", 0, 0, -1.5, 0, 0, -4); BodyPartNode* legBR2 = new BodyPartNode("legBR2", 2.5, 1.0, 4, LEG_COLOR); JointNode* legFL1J = new JointNode("legFL1J", -7, -2, 4.0, 0, 0, 1.5); BodyPartNode* legFL1 = new BodyPartNode("legFL1", 1.5, 1.0, 1.5, LEG_COLOR); JointNode* legFL2J = new JointNode("legFL2J", 0, 0, 1.5, 0, 0, 4); BodyPartNode* legFL2 = new BodyPartNode("legFL2", 2.5, 1.0, 4, LEG_COLOR); JointNode* legFR1J = new JointNode("legFR1J", -7, -2, -4.0, 0, 0, -1.5); BodyPartNode* legFR1 = new BodyPartNode("leg1FR", 1.5, 1.0, 1.5, LEG_COLOR); JointNode* legFR2J = new JointNode("legFR2J", 0, 0, -1.5, 0, 0, -4); BodyPartNode* legFR2 = new BodyPartNode("legFR2", 2.5, 1.0, 4, LEG_COLOR); legBL1J->addChild(legBL1); legBL1->addChild(legBL2J); legBL2J->addChild(legBL2); legBR1J->addChild(legBR1); legBR1->addChild(legBR2J); legBR2J->addChild(legBR2); legFL1J->addChild(legFL1); legFL1->addChild(legFL2J); legFL2J->addChild(legFL2); legFR1J->addChild(legFR1); legFR1->addChild(legFR2J); legFR2J->addChild(legFR2); // build body TranslationNode* bodyT = new TranslationNode("bodyT", 0, 0, 0); BodyPartNode* body = new BodyPartNode("body", 10, 4, 6, BODY_COLOR); SpikeNode* bodySpike = new SpikeNode("bodySpike", 3, 10, SPIKE_VERTICAL, SPIKE_COLOR); // TREMENDOUS HACK: Rotation of the entire dino is facilitated by rotating the torso before // the rest of the hierarchy is rendered, so we create a "joint" about the centre of the body // that has no incoming or outgoing limb. JointNode* bodyJ = new JointNode("bodyJ", 0, 0, 0, 0, 0, 0); // Attach all parts to body bodyT->addChild(bodyJ); bodyJ->addChild(body); body->addChild(neck1J); body->addChild(tail1J); body->addChild(legBL1J); body->addChild(legFL1J); body->addChild(legBR1J); body->addChild(legFR1J); body->addChild(bodySpike); // Fill joint array joints_[J_NECK_1] = neck1J; joints_[J_NECK_2] = neck2J; joints_[J_NECK_3] = neck3J; joints_[J_HEAD] = headJ; joints_[J_TAIL_1] = tail1J; joints_[J_TAIL_2] = tail2J; joints_[J_TAIL_3] = tail3J; joints_[J_LEG_BL_1] = legBL1J; joints_[J_LEG_BL_2] = legBL2J; joints_[J_LEG_BR_1] = legBR1J; joints_[J_LEG_BR_2] = legBR2J; joints_[J_LEG_FL_1] = legFL1J; joints_[J_LEG_FL_2] = legFL2J; joints_[J_LEG_FR_1] = legFR1J; joints_[J_LEG_FR_2] = legFR2J; joints_[J_BODY] = bodyJ; joints_[J_LEFT_EYE] = leftEyeJ; joints_[J_RIGHT_EYE] = rightEyeJ; return bodyT; }
bool Viewer::on_motion_notify_event(GdkEventMotion* event) { DEBUG_MSG("Stub: Motion at " << event->x << ", " << event->y ); Point2D dMouse(event->x - m_lastMouse[0], event->y - m_lastMouse[1]); bool b1,b2,b3; b1 = event->state & GDK_BUTTON1_MASK; b2 = event->state & GDK_BUTTON2_MASK; b3 = event->state & GDK_BUTTON3_MASK; //track ball mode if (m_mode == POSITION) { // do x,y translation if (b1) { double translationScale = 50.0; Vector3D translate(dMouse[0] / translationScale, -dMouse[1] / translationScale , 0); Matrix4x4 t = translation(translate); m_trackballTranslation = m_trackballTranslation * t; } if (b2) { Vector3D translate(0.0, 0.0, dMouse[1]/ 35.0); Matrix4x4 t = translation(translate); m_trackballTranslation = m_trackballTranslation * t; } if (b3) { /* * Track ball rotations are being used. */ float fDiameter; int iCenterX, iCenterY; float fNewModX, fNewModY, fOldModX, fOldModY; /* vCalcRotVec expects new and old positions in relation to the center of the * trackball circle which is centered in the middle of the window and * half the smaller of nWinWidth or nWinHeight. */ fDiameter = (get_width() < get_height()) ? (float)get_width() * 0.5f : (float)get_height() * 0.5f; iCenterX = get_width() / 2; iCenterY = get_height() / 2; fOldModX = m_lastMouse[0] - iCenterX; fOldModY = m_lastMouse[1] - iCenterY; fNewModX = event->x - iCenterX; fNewModY = event->y - iCenterY; float fRotVecX, fRotVecY, fRotVecZ; vCalcRotVec(fNewModX, fNewModY, fOldModX, fOldModY, fDiameter, &fRotVecX, &fRotVecY, &fRotVecZ); /* Negate Y component since Y axis increases downwards * in screen space and upwards in OpenGL. */ Matrix4x4 mNewMat = vAxisRotMatrix(fRotVecX, -fRotVecY, fRotVecZ); // Since all these matrices are meant to be loaded // into the OpenGL matrix stack, we need to transpose the // rotation matrix (since OpenGL wants rows stored // in columns) //vTransposeMatrix(mNewMat); //vRightMultiply(mRotations, mNewMat); m_trackballRotation = m_trackballRotation * mNewMat; } DEBUG_MSG("trackballMatrix: Translation\n" << m_trackballTranslation << "Rotation\n" << m_trackballRotation); } else { // JOINT manipulation mode // rotate head up down relative to y when b2 // rotate head left right with x motion when b3 // grab all selected nodes // grab their parents // rotate their joint left/right, up/down for (std::list<SceneNode*>::const_iterator it = m_selected.begin(), end = m_selected.end(); it != end; ++it) { assert((*it)->is_selected()); SceneNode *parent = (*it)->jointParent(); // check if parent is joint node DEBUG_MSG("Rotating: " << (*it)->name()); assert(parent); DEBUG_MSG("Parent: name " << parent->name()); assert(parent->is_joint()); JointNode *joint = dynamic_cast<JointNode*>(parent); assert(joint); double rotationScale = -3.0; if (b2) { // rotate in degrees joint->rotate( dMouse[1] / rotationScale, 0.0); } if (b3) { joint->rotate(0.0, dMouse[0] / rotationScale); } } } m_lastMouse = Point2D(event->x, event->y); invalidate(); return true; }