view src/Giantarm.cpp @ 13:39e0c583e0a3 default tip

add GiantroboClassfile.
author tokumoritaichirou@w-133-13-243-110.cc.u-ryukyu.ac.jp
date Wed, 03 Feb 2010 18:37:01 +0900
parents
children
line wrap: on
line source

/*
 *  giantarm.cpp
 *  Martial
 *
 *  Created by e075743 on 10/02/03.
 *  Copyright 2010 __MyCompanyName__. All rights reserved.
 *
 */

#include "Giantarm.h"

Giantarm::Giantarm(char* _name) : Humanoid::Humanoid(_name) {
	moveCount = 0.0;
	//scale = osg::Vec3(0.01,0.01,0.01);
	
	humanoidNode = osgDB::readNodeFile("Giantarm.osg");
	humanoidForm = new osg::PositionAttitudeTransform();
	humanoidForm->addChild(humanoidNode);
	mform->addChild(humanoidForm);
	
	//ノードにアクセス。MatrixTransformをnameで検索(visitor内部で std::map で保持)
	SearchMatrixTransformVisitor visitor = SearchMatrixTransformVisitor();
	
	humanoidNode->accept(visitor);
	bodyForm = visitor.getMatrixTransform("body");
	leftUpperArmForm = visitor.getMatrixTransform("left_arm");
	rightUpperArmForm = visitor.getMatrixTransform("right_arm");
	leftDownArmForm = visitor.getMatrixTransform("left_hand");
	rightDownArmForm = visitor.getMatrixTransform("right_hand");
	//leftUpperLegForm = visitor.getMatrixTransform("left_leg1");	
	//rightUpperLegForm = visitor.getMatrixTransform("right_leg1");
	//leftDownLegForm = visitor.getMatrixTransform("left_leg2");	
	//rightDownLegForm = visitor.getMatrixTransform("right_leg2");
	
	//衝突判定ノードの追加
	CollisionNode* collisionNode;
	
	bodyForm->setMatrix(osg::Matrix());
	
	collisionNode = new CollisionNode("Body-Node1", new osg::Sphere(osg::Vec3(0, 0, 0), 0.5));
	bodyForm->addChild(collisionNode->getGeode());
	collisionNodeList.push_back(collisionNode);
	collisionNode = new CollisionNode("Body-Node2", new osg::Sphere(osg::Vec3(0, 0, 0.5), 0.5));
	bodyForm->addChild(collisionNode->getGeode());
	collisionNodeList.push_back(collisionNode);
	collisionNode = new CollisionNode("Body-Node3", new osg::Sphere(osg::Vec3(0, 0, -0.6), 0.5));
	bodyForm->addChild(collisionNode->getGeode());
	collisionNodeList.push_back(collisionNode);
	collisionNode = new CollisionNode("Left-Arm-Node", new osg::Sphere(osg::Vec3(1, -0.4, -0.7), 0.3));
	leftDownArmForm->addChild(collisionNode->getGeode());
	collisionNodeList.push_back(collisionNode);
	collisionNode = new CollisionNode("Right-Arm-Node", new osg::Sphere(osg::Vec3(-1, -0.4, -0.7), 0.3));
	rightDownArmForm->addChild(collisionNode->getGeode());
	collisionNodeList.push_back(collisionNode);
	//collisionNode = new CollisionNode("Left-Leg-Node", new osg::Sphere(osg::Vec3(0, 0, 0), 30));
	//leftUpperLegForm->addChild(collisionNode->getGeode());
	//collisionNodeList.push_back(collisionNode);
	//collisionNode = new CollisionNode("Right-Leg-Node", new osg::Sphere(osg::Vec3(0, 0, 0), 30));
	//rightUpperLegForm->addChild(collisionNode->getGeode());
	//collisionNodeList.push_back(collisionNode);	
	
	SearchGeodeVisitor gvisitor = SearchGeodeVisitor();
	
	gvisitor.setSearchGeodeName("Collision_right_leg1_geode");
	humanoidNode->accept(gvisitor);
	
	//std::cout << "getVisitor: result = " << gvisitor.getGeode().getName(); << "\n";
	
	unWaitFunc = &Giantarm::nop;
	funcs[PUSH_LEFT]		= &Giantarm::walk;
	funcs[PUSH_RIGHT]		= &Giantarm::turn;
	funcs[PUSH_UP]			= &Giantarm::jump;
	funcs[PUSH_DOWN]		= &Giantarm::squat;
	funcs[PUSH_RIGHTUP]		= &Giantarm::jump;
	funcs[PUSH_LEFTUP]		= &Giantarm::jump;
	funcs[PUSH_RIGHTDOWN]	= &Giantarm::walk;
	funcs[PUSH_LEFTDOWN]	= &Giantarm::walk;	
	funcs[RELEASE_HAT]		= &Giantarm::stop;
	funcs[PUSH_A]			= &Giantarm::punch;
	funcs[PUSH_B]			= &Giantarm::nop;
	funcs[PUSH_C]			= &Giantarm::nop;
	funcs[PUSH_D]			= &Giantarm::nop;
	funcs[RELEASE_BUTTON]	= &Giantarm::stop;
}

void Giantarm::releaseHat() {
	printInput("Class Giantarm [%s] :: RELEASE-HAT\n", name);
	(this->*funcs[RELEASE_HAT])();
}

void Giantarm::pushLeft() {
	printInput("Class Giantarm [%s] :: PUSH-LEFT\n", name);
	(this->*funcs[PUSH_LEFT])();
}

void Giantarm::pushRight() {
	printInput("Class Giantarm [%s] :: PUSH-RIGHT\n", name);
	(this->*funcs[PUSH_RIGHT])();
}

void Giantarm::pushUp() {
	printInput("Class Giantarm [%s] :: PUSH-UP\n", name);
	(this->*funcs[PUSH_UP])();
}

void Giantarm::pushDown() {
	printInput("Class Giantarm [%s] :: PUSH-DOWN\n", name);
	//(this->*funcs[PUSH_RIGHTDOWN])();
	(this->*funcs[PUSH_A])();
}

void Giantarm::pushRightUp() {
	printInput("Class Giantarm [%s] :: PUSH-RIGHT-UP\n", name);
	(this->*funcs[PUSH_RIGHTUP])();
}
void Giantarm::pushRightDown() {
	printInput("Class Giantarm [%s] :: PUSH-RIGHT-DOWN\n", name);
	(this->*funcs[PUSH_RIGHTDOWN])();
}
void Giantarm::pushLeftUp() {
	printInput("Class Giantarm [%s] :: PUSH-LEFT-UP\n", name);
	(this->*funcs[PUSH_RIGHTUP])();
}

void Giantarm::pushLeftDown() {
	printInput("Class Giantarm [%s] :: PUSH-LEFT-DOWN\n", name);
	(this->*funcs[PUSH_LEFTDOWN])();
}

void Giantarm::pushA() {
	printInput("Class Giantarm [%s] :: PUSH-A\n", name);
	(this->*funcs[PUSH_A])();
}

void Giantarm::releaseA() {
	printInput("Class Giantarm [%s] :: RELEASE-A\n", name);
}

void Giantarm::pushB() {
	printInput("Class Giantarm [%s] :: PUSH-B\n", name);
	(this->*funcs[PUSH_B])();
}

void Giantarm::releaseB() {
	printInput("Class Giantarm [%s] :: RELASE-B\n", name);
}

void Giantarm::pushC() {
	printInput("Class Giantarm [%s] :: PUSH-C\n", name);
	(this->*funcs[PUSH_C])();
}

void Giantarm::releaseC() {
	printInput("Class Giantarm [%s] :: RELEASE-C\n", name);
}

void Giantarm::pushD() {
	printInput("Class Giantarm [%s] :: PUSH-D\n", name);
	(this->*funcs[PUSH_D])();
}

void Giantarm::releaseD() {
	printInput("Class Giantarm [%s] :: RELEASE-D\n", name);
}

void Giantarm::stackPush() {
	stack[PUSH_LEFT]		= funcs[PUSH_LEFT];
	stack[PUSH_RIGHT]		= funcs[PUSH_RIGHT];
	stack[PUSH_UP]			= funcs[PUSH_UP];
	stack[PUSH_DOWN]		= funcs[PUSH_DOWN];
	stack[PUSH_RIGHTUP]		= funcs[PUSH_RIGHTUP];
	stack[PUSH_LEFTUP]		= funcs[PUSH_LEFTUP];
	stack[PUSH_RIGHTDOWN]	= funcs[PUSH_RIGHTDOWN];
	stack[PUSH_LEFTDOWN]	= funcs[PUSH_LEFTDOWN];
	stack[RELEASE_HAT]		= funcs[RELEASE_HAT];
	stack[PUSH_A]			= funcs[PUSH_A];
	stack[PUSH_B]			= funcs[PUSH_B];
	stack[PUSH_C]			= funcs[PUSH_C];
	stack[PUSH_D]			= funcs[PUSH_D];
	stack[RELEASE_BUTTON]	= funcs[RELEASE_BUTTON];
	
	funcs[PUSH_LEFT]		= &Giantarm::wait;
	funcs[PUSH_RIGHT]		= &Giantarm::wait;
	funcs[PUSH_UP]			= &Giantarm::wait;
	funcs[PUSH_DOWN]		= &Giantarm::wait;
	funcs[PUSH_RIGHTUP]		= &Giantarm::wait;
	funcs[PUSH_LEFTUP]		= &Giantarm::wait;
	funcs[PUSH_RIGHTDOWN]	= &Giantarm::wait;
	funcs[PUSH_LEFTDOWN]	= &Giantarm::wait;
	funcs[RELEASE_HAT]		= &Giantarm::wait;
	funcs[PUSH_A]			= &Giantarm::wait;
	funcs[PUSH_B]			= &Giantarm::wait;
	funcs[PUSH_C]			= &Giantarm::wait;
	funcs[PUSH_D]			= &Giantarm::wait;
	funcs[RELEASE_BUTTON]	= &Giantarm::wait;
}

void Giantarm::stackPop() {
	funcs[PUSH_LEFT]		= stack[PUSH_LEFT];
	funcs[PUSH_RIGHT]		= stack[PUSH_RIGHT];
	funcs[PUSH_UP]		= stack[PUSH_UP];
	funcs[PUSH_DOWN]		= stack[PUSH_DOWN];
	funcs[PUSH_RIGHTUP]	= stack[PUSH_RIGHTUP];
	funcs[PUSH_LEFTUP]	= stack[PUSH_LEFTUP];
	funcs[PUSH_RIGHTDOWN]	= stack[PUSH_RIGHTDOWN];
	funcs[PUSH_LEFTDOWN]	= stack[PUSH_LEFTDOWN];
	funcs[RELEASE_HAT]	=	stack[RELEASE_HAT];
	funcs[PUSH_A]			= stack[PUSH_A];
	funcs[PUSH_B]			= stack[PUSH_B];
	funcs[PUSH_C]			= stack[PUSH_C];
	funcs[PUSH_D]			= stack[PUSH_D];
	funcs[RELEASE_BUTTON]	= stack[RELEASE_BUTTON];
}

/*  Giantarmの各モーションを定義 */

void Giantarm::punch() {
	float sinVal = sin(moveCount);
	float cosVal = cos(moveCount);
	double punch[6][3] = {{5.0,-30.0,-30.0},{10.0,-90.0,-90.0},{15.0,-90.0,60.0},{15.0,-90.0,60.0},{10.0,-90.0,-90.0},{0.0,0.0,0.0}};
	osg::Matrixd roteMatrix;
	osg::Matrixd dirMatrix;
	osg::Matrixd accMatrix;
	
	bodyForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(punch[(int)moveCount%6][0]), osg::Vec3(0,0,1)));
	rightUpperArmForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(punch[(int)moveCount%6][1]), osg::Vec3(1,0,0)));
	rightDownArmForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(punch[(int)moveCount%6][2]), osg::Vec3(1,0,0)));
	moveCount += 1;
	//if(moveCount <= 0.5){
	//bodyForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(sinVal*10.0), osg::Vec3(0,0,1)));
	//rightUpperArmForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(sinVal*60.0-90), osg::Vec3(1,0,0)));
	//rightDownArmForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(sinVal*60.0-20), osg::Vec3(1,0,0)));
	//}
}

void Giantarm::walk() {
	velocity = osg::Vec3(0.5*avatarDirection,0,0);
	moveCount += (float)avatarDirection * 0.5;
	float sinVal = sin(moveCount);
	float cosVal = cos(moveCount);
	
	setPos(osg::Vec3(position.x(), position.y(), position.z()+cos(moveCount)*0.01));
	
	osg::Matrixd roteMatrix;
	osg::Matrixd dirMatrix;
	osg::Matrixd accMatrix;
	
	//positionAttitudeMatrix.setAttitude();での演算にくらべると、倍高速?
	bodyForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(sinVal*10.0), osg::Vec3(0,0,1)));
	leftUpperArmForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(sinVal*30.0+10), osg::Vec3(1,0,0)));
	rightUpperArmForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(sinVal*-30.0+10), osg::Vec3(1,0,0)));
	//leftUpperLegForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(sinVal*-45.0), osg::Vec3(1,0,0)));
	//rightUpperLegForm->setMatrix(osg::Matrixf::rotate(osg::DegreesToRadians(sinVal*45.0), osg::Vec3(1,0,0)));
	
}

void Giantarm::turn() {
	angularVelocity = osg::Vec3(0,0,osg::DegreesToRadians(180.0/10.0));
	motionTime = 10;
	avatarDirection *= -1;
	void (Giantarm::*tmp)() = funcs[PUSH_LEFT];
	funcs[PUSH_LEFT] = funcs[PUSH_RIGHT];
	funcs[PUSH_RIGHT] = tmp;
	stackPush();
	unWaitFunc = &Giantarm::stop;
	wait();
}

void Giantarm::jump() {
	funcs[PUSH_UP] = &Giantarm::nop;
	funcs[PUSH_RIGHTUP] = &Giantarm::nop;
	funcs[PUSH_LEFTUP] = &Giantarm::nop;	
	velocity = osg::Vec3(velocity.x(), velocity.y(), 4);
	acceleration = osg::Vec3(acceleration.x(), acceleration.y(), -0.3);
}

void Giantarm::stop() {
	moveCount = 0;
	motionTime = 0;
	velocity = osg::Vec3(0,0,0);
	angularVelocity = osg::Vec3(0,0,0);
}

void Giantarm::wait() {
	if ((--motionTime) < 0) {
		(this->*unWaitFunc)();
		unWaitFunc = &Giantarm::nop;
		stackPop();
	}
}

//以下、未実装

void Giantarm:: run() {};
void Giantarm:: squat() {};
void Giantarm:: down() {};
void Giantarm:: freeze() {};

void Giantarm::frame() {
	update();
}

void Giantarm::update() {
	
	//[当たり判定の処理] - 未実装,ただ判定を消すだけ
	std::list<CollisionNode*>::iterator iter;
	for (iter = collisionNodeList.begin(); iter != collisionNodeList.end(); ++iter) {
		(*iter)->setCollision(false);
	}
	
	osg::Matrixd roteMatrix;
	osg::Matrixd dirMatrix;
	osg::Matrixd accMatrix;
	
	direction += angularVelocity;
	velocity  += acceleration;
	
	accMatrix.makeTranslate(acceleration);
	roteMatrix.makeRotate(
						  osg::Quat(
									direction.x(), osg::Vec3(1,0,0),
									direction.y(), osg::Vec3(0,1,0),
									direction.z(), osg::Vec3(0,0,1)
									)
						  );
	
	velocity += (accMatrix*roteMatrix).getTrans();
	position += velocity;
	
	// 地面を抜けた場合
	if (position.z() < 0) {
		position.z() = 0;
		funcs[PUSH_UP] = &Giantarm::jump;
		funcs[PUSH_RIGHTUP] = &Giantarm::jump;
		funcs[PUSH_LEFTUP] = &Giantarm::jump;
		velocity = osg::Vec3(velocity.x(), velocity.y(), 0);
		acceleration = osg::Vec3(acceleration.x(), acceleration.y(), 0);
	}
	
	accMatrix.makeTranslate(acceleration);
	roteMatrix.makeRotate(
						  osg::Quat(
									defaultDirection.x()+direction.x(), osg::Vec3(1,0,0),
									defaultDirection.y()+direction.y(), osg::Vec3(0,1,0),
									defaultDirection.z()+direction.z(), osg::Vec3(0,0,1)
									)
						  );
	
	dirMatrix.makeTranslate(position);
	accMatrix.makeScale(scale);
	mform->setMatrix(accMatrix*roteMatrix*dirMatrix);
}