Ejemplo n.º 1
0
static void collideCB(void *data, dGeomID o1, dGeomID o2)
{
	ODEObj *odeobj1 = ODEObjectContainer::getInstance()->getODEObjFromGeomID(o1);
	ODEObj *odeobj2 = ODEObjectContainer::getInstance()->getODEObjFromGeomID(o2);

	//	const int N = 32;
	const int N = 10; // TODO: Magic number should be removed
	dContact contacts[N];

	int n = dCollide(o1, o2, N, &(contacts[0].geom),  sizeof(contacts[0]));

	if (n > 0) {

		ODEWorld *world = ODEWorld::get();

		for (int i=0; i<n; i++) {

			dContact *c = &contacts[i];

			c->surface.mode = dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactBounce;
			//
			// Reflection of material parameters of the collided object
			// Fliction force should be regarded as average of contiguous material (???)
			// TODO: Calclation of fliction force sould be considered
			//
			if (odeobj1 && odeobj2) {
				c->surface.mu       = ( odeobj1->getMu1()     + odeobj2->getMu1() )     / 2.0;
				c->surface.mu2      = ( odeobj1->getMu2()     + odeobj2->getMu2() )     / 2.0;
				c->surface.slip1    = ( odeobj1->getSlip1()   + odeobj2->getSlip1() )   / 2.0;
				c->surface.slip2    = ( odeobj1->getSlip2()   + odeobj2->getSlip2() )   / 2.0;
				c->surface.soft_erp = ( odeobj1->getSoftErp() + odeobj2->getSoftErp() ) / 2.0;
				c->surface.soft_cfm = ( odeobj1->getSoftCfm() + odeobj2->getSoftCfm() ) / 2.0;
				c->surface.bounce   = ( odeobj1->getBounce()  + odeobj2->getBounce() )  / 2.0;
			}
			else {
				c->surface.mu       = SPARTS_MU1;
				c->surface.mu2      = SPARTS_MU2;
				c->surface.slip1    = SPARTS_SLIP1;
				c->surface.slip2    = SPARTS_SLIP2;
				c->surface.soft_erp = SPARTS_ERP;
				c->surface.soft_cfm = SPARTS_CFM;
				c->surface.bounce   = SPARTS_BOUNCE;
			}
			dJointID cj = dJointCreateContact(world->world(), world->jointGroup(), c);
			dJointAttach(cj, dGeomGetBody(o1), dGeomGetBody(o2));
		}
	}
}
Ejemplo n.º 2
0
static void nearCB(void *data, dGeomID o1, dGeomID o2)
{
	ODEObj *odeobj1 = ODEObjectContainer::getInstance()->getODEObjFromGeomID(o1);
	ODEObj *odeobj2 = ODEObjectContainer::getInstance()->getODEObjFromGeomID(o2);

	/*
	SSimRobotEntity *ent1 = ODEObjectContainer::getInstance()->getSSimRobotEntityFromGeomID(o1);
	SSimRobotEntity *ent2 = ODEObjectContainer::getInstance()->getSSimRobotEntityFromGeomID(o2);
	
	if(ent1 != NULL && ent2 != NULL && ent1->name() == ent2->name()){
	  //LOG_MSG(("name (%s, %s)",ent1->name().c_str(), ent2->name().c_str()));
	  return;
	}
	*/

	SParts *p1 = NULL;
	SParts *p2 = NULL;
	dBodyID b1 = dGeomGetBody(o1);
	dBodyID b2 = dGeomGetBody(o2);

	if (b1 == b2) {
		return;
	}

	ODEWorld *world = ODEWorld::get();
	dGeomID ground = world->getGround();

	if (b1 && b2) {
		if (dAreConnected(b1, b2)) { 
			return; 
		}
	}

	if (b1) {
		void *d = dBodyGetData(b1);
		if (d) {
			p1 = (SParts*)d;
			if (p1->isBlind()) { return; }
		}
	}
	
	if (b2) {
		void *d = dBodyGetData(b2);
		if (d) {
			p2 = (SParts*)d;
			if (p2->isBlind()) { return; }
		}
	}

	if (p1 && p2 && p1->sameParent(*p2)) { return; }

	if (dGeomIsSpace(o1) && dGeomIsSpace(o2)) {
		dSpaceCollide2(o1, o2, data, &collideCB);
		return;
	}

#define F_SCHOLAR(V) sqrt(V[0]*V[0] + V[1]*V[1] + V[2]*V[2])

	static dJointFeedback fb;

#define MAX_COLLISION 32

	const int N = MAX_COLLISION;
	dContact contacts[N];
	int n = dCollide(o1, o2, N, &(contacts[0].geom),  sizeof(contacts[0]));

	if (n > 0) {
		ODEWorld *world = ODEWorld::get();

		for (int i=0; i<n; i++) {
			dContact *c = &contacts[i];
			dContactGeom &g = c->geom;

			if (p1 && p2) {
#if 0
				LOG_SYS(("Collision #%d/%d %s(geomID=%d) <-> %s(geomID=%d)", i, n,
						 p1->getParent()->name(), o1,
						 p2->getParent()->name(), o2));
				LOG_SYS(("\tpos = (%f, %f, %f)", g.pos[0], g.pos[1], g.pos[2]));
				LOG_SYS(("\tnormal = (%f, %f, %f)", g.normal[0], g.normal[1], g.normal[2]));
				LOG_SYS(("\tfdir = (%f, %f, %f)", c->fdir1[0], c->fdir1[1], c->fdir1[2]));
				LOG_SYS(("\tdepth = %f", g.depth));
#endif
				const char *name1 = p1->getParent()->name();
				const char *name2 = p2->getParent()->name();
				std::string key = chash_key(name1, name2);
				if (key.length() <= 0) { continue; }
				if (chash_find(key)) { continue; }
				s_chash[key] = true;
				s_collisions.push_back(ODEWorld::Collision(name1, name2, p1->name(), p2->name()));
				// Set the collision flag to be ON
				p1->setOnCollision(true);
				p2->setOnCollision(true);
			}
			
			//c->surface.mode = dContactBounce;
			c->surface.mode = dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactBounce;
			//c->surface.mode = dContactSlip1 | dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactBounce;
			//
			// Reflection of material parameters of the collided object
			// Fliction force should be regarded as average of contiguous material (???)
			// TODO: Calclation of fliction force sould be considered
			//
#if 0			
			if (odeobj1 && odeobj2) {
				c->surface.mu       = ( odeobj1->getMu1()     + odeobj2->getMu1() )     / 2.0;
				c->surface.mu2      = ( odeobj1->getMu2()     + odeobj2->getMu2() )     / 2.0;
				c->surface.slip1    = ( odeobj1->getSlip1()   + odeobj2->getSlip1() )   / 2.0;
				c->surface.slip2    = ( odeobj1->getSlip2()   + odeobj2->getSlip2() )   / 2.0;
				c->surface.soft_erp = ( odeobj1->getSoftErp() + odeobj2->getSoftErp() ) / 2.0;
				c->surface.soft_cfm = ( odeobj1->getSoftCfm() + odeobj2->getSoftCfm() ) / 2.0;
				c->surface.bounce   = ( odeobj1->getBounce()  + odeobj2->getBounce() )  / 2.0;
			}
			else {
				c->surface.bounce_vel = world->getCollisionParam("bounce_vel");
				c->surface.bounce     = world->getCollisionParam("bounce");
				c->surface.mu         = world->getCollisionParam("mu");
				c->surface.mu2        = world->getCollisionParam("mu2");
				c->surface.slip1      = world->getCollisionParam("slip1");
				c->surface.slip2      = world->getCollisionParam("slip2");
				c->surface.soft_erp   = world->getCollisionParam("soft_erp");
				c->surface.soft_cfm   = world->getCollisionParam("soft_cfm");
			}
#else
			c->surface.mu	    = SPARTS_MU1;
			c->surface.mu2      = SPARTS_MU2;
			c->surface.slip1    = SPARTS_SLIP1;
			c->surface.slip2    = SPARTS_SLIP2;
			c->surface.soft_erp = SPARTS_ERP;     // parameter for modify the error of Joint position (0..1); if it is 1, modification will be perfect
			c->surface.soft_cfm = SPARTS_CFM;     // If this value=0, joint velocity is strange
			c->surface.bounce   = SPARTS_BOUNCE; // is a little smaller than ball
			c->surface.bounce_vel = 0.0;
#endif
			dJointID cj = dJointCreateContact(world->world(), world->jointGroup(), c);
			//dJointAttach(cj, dGeomGetBody(o1), dGeomGetBody(o2));  //by MSI
			dJointAttach(cj, dGeomGetBody(c->geom.g1), dGeomGetBody(c->geom.g2)); // by Demura.net
#if 0
			if (p1 && p2) {
				dJointSetFeedback(cj, &fb);
				dJointFeedback *pfb = dJointGetFeedback(cj);
				
				if (F_SCHOLAR(pfb->f1) > 1.0) {
					LOG_SYS(("\tF1 = (%f, %f, %f)",   pfb->f1[0], pfb->f1[1], pfb->f1[2]));
					LOG_SYS(("\tF2 = (%f, %f, %f)\n", pfb->f2[0], pfb->f2[1], pfb->f2[2]));
				}
			}
#endif
		}
	}
}
Ejemplo n.º 3
0
void WorldXMLReader::startElement(const XMLCh * const tagName_,
								  xercesc::AttributeList &attrs)
{
	char *tagName = XMLString::transcode(tagName_);
	// std::cout << tagName << std::endl;

	if (strcmp(tagName, "world") == 0 || strcmp(tagName, "World") == 0) {
		if (!m_world) {
			if (char *n = GET_VALUE(attrs, "name")) {
				m_world = new SSimWorld(n);
				RELEASE(n);
			} 
			else {
				NOATTR_ERR("world", "name", attrs);
			}

		}

		if (char *fname = GET_VALUE(attrs, "inherit")) {
			SAXParser *parser = new SAXParser();
			parser->setDocumentHandler(this);

			char buf[4096];
			const char *fpath = m_fdb.getPath(fname, buf);
			if (fpath != NULL) {
				S last = setFilename(fpath);
				parser->parse(fpath);
				delete parser;
				setFilename(last);
			} else {
				NOFILE_ERR(fname);
			}

			RELEASE(fname);
		}
	} else if (strcmp(tagName, "gravity") == 0 || strcmp(tagName, "Gravity") == 0) {
		if (m_world) {
			dReal x=0.0, y=0.0, z=0.0;
			char *p;
			p = GET_VALUE(attrs, "x");
			if (p) {
				x = atof(p);
				RELEASE(p);
			} else {
				NOATTR_ERR("gravity", "x", attrs);
			}
			p = GET_VALUE(attrs, "y");
			if (p) {
				y = atof(p);
				RELEASE(p);
			} else {
				NOATTR_ERR("gravity", "y", attrs);
			}
      
			p = GET_VALUE(attrs, "z");
			if (p) {
				z = atof(p);
				RELEASE(p);
			} else {
				NOATTR_ERR("gravity", "z", attrs);
			}
#if 0
			std::cout << "x = "  << x << std::endl;
			std::cout << "y = "  << y << std::endl;
			std::cout << "z = "  << z << std::endl;
#endif
			m_world->set(ODEWorld::Gravity(x, y, z), 0.0);
		}
	}
	else if (strcmp(tagName, "worldparam") == 0 || strcmp(tagName, "worldParam") == 0) {
		char *erp = GET_VALUE(attrs, "erp");
		if (erp) {
			m_world->setERP(atof(erp));
			RELEASE(erp);
		} 
		char *cfm = GET_VALUE(attrs, "cfm");
		if (cfm) {
			m_world->setCFM(atof(cfm));
			RELEASE(cfm);
		} 
		if (char *autostep = GET_VALUE(attrs, "autostep")) {
			if (strcmp(autostep, "false") == 0) {
				m_world->setAutoStep(false);
				RELEASE(autostep);
			}
		}
		if (char *quickstep = GET_VALUE(attrs, "quickstep")) {
			if (strcmp(quickstep, "true") == 0) {
				m_world->setQuickStep(true);
				RELEASE(quickstep);
			}
		}
		if (char *stepsize = GET_VALUE(attrs, "stepsize")) {
			m_world->setStepSize(atof(stepsize));
			RELEASE(stepsize);
		}
	}
	else if (strcmp(tagName, "collisionparam") == 0 || strcmp(tagName, "collisionParam") == 0) {

		char *mu = GET_VALUE(attrs, "mu");
		if (mu) {
			m_world->setCollisionParam("mu",atof(mu));
			RELEASE(mu);
		} 
		char *mu2 = GET_VALUE(attrs, "mu2");
		if (mu2) {
			m_world->setCollisionParam("mu2",atof(mu2));
			RELEASE(mu2);
		} 
		char *slip1 = GET_VALUE(attrs, "slip1");
		if (slip1) {
			m_world->setCollisionParam("slip1", atof(slip1));
			RELEASE(slip1);
		} 
		char *slip2 = GET_VALUE(attrs, "slip2");
		if (slip2) {
			m_world->setCollisionParam("slip2", atof(slip2));
			RELEASE(slip2);
		} 
		char *soft_erp = GET_VALUE(attrs, "soft_erp");
		if (soft_erp) {
			m_world->setCollisionParam("soft_erp", atof(soft_erp));
			RELEASE(soft_erp);
		} 
		char *soft_cfm = GET_VALUE(attrs, "soft_cfm");
		if (soft_cfm) {
			m_world->setCollisionParam("soft_cfm", atof(soft_cfm));
			RELEASE(soft_cfm);
		} 
		char *bounce = GET_VALUE(attrs, "bounce");
		if (bounce) {
			m_world->setCollisionParam("bounce", atof(bounce));
			RELEASE(bounce);
		} 
		char *bounce_vel = GET_VALUE(attrs, "bounce_vel");
		if (bounce_vel) {
			m_world->setCollisionParam("bounce_vel", atof(bounce_vel));
			RELEASE(bounce);
		} 


	}
	else if (strcmp(tagName, "instanciate") == 0) {
		ODEWorld *w = m_world->odeWorld();
		SSimObj *obj;

		// To check whether the type is robot or not
		char *type = GET_VALUE(attrs, "type");

		if (!type)  obj = new SSimObj(w->space());

		else if (strcmp(type,"Robot") == 0) {
			SRobotObj *robj = new SRobotObj(w->space());
			obj = (SSimObj*)robj;
			RELEASE(type);
		}
		else{
			obj = new SSimObj(w->space());
			RELEASE(type);
		}

		if (char *fname = GET_VALUE(attrs, "class")) {
			assert(m_world);
			assert(w);

			// Read contents of the entity from XML file
			// EntityXMLReader read(m_fdb, *obj, *w, m_x3ddb);
			EntityXMLReader read(m_fdb, *obj, *w, m_x3ddb, m_ssdb);

			read.setReadTaskContainer(this);
			read(fname);

		} 
		
		else {
			NOATTR_ERR("instanciate", "class", attrs);
		}
		m_currobj = obj;
	}
	else if (strcmp(tagName, "set-attr-value") == 0) {
		if (m_currobj) {
			char *n = GET_VALUE(attrs, "name");
			char *v = GET_VALUE(attrs, "value");
			if (!n) {
				NOATTR_ERR("set-attr-value", "name", attrs);
			}
			if (!v) {
				NOATTR_ERR("set-attr-value", "value", attrs);
			}
			if (n && v) {
				m_currobj->setAttrValue(n, v);
			}
		}
	}
	// Creation of new entity
	else if (strcmp(tagName, "entity") == 0 || strcmp(tagName, "Entity") == 0) {
		ODEWorld *w = m_world->odeWorld();

		// Set a new version flag later than v2.1
		m_world->setV21(true);

		// Create ODE world and space
		dWorldID world = w->world();
		dSpaceID space = w->space();

		char *entityName = GET_VALUE(attrs, "name");
		if (!entityName) {
			LOG_ERR(("Entity has no name"));
			assert(entityName); 
		}
		SSimEntity *ent;

		char *robot = GET_VALUE(attrs, "robot");
		if (robot && strcmp(robot, "true") == 0) {
			ent = new SSimRobotEntity(world, space, entityName);
			ent->setIsRobot(true);
		}
		else{
			ent = new SSimEntity(world, space, entityName);
		}

		static int eid = 0;
		ent->setID(eid);
		eid++;

		// Check whether it is agent or normal entity
		char *ag = GET_VALUE(attrs, "agent");
		if (ag && strcmp(ag, "true") == 0) {
			ent->setIsAgent(true);
		}
		m_current = ent;
	}

	else if (strcmp(tagName, "x3d") == 0 || strcmp(tagName, "X3D") == 0) {
		if (m_current != NULL) {

			char *scale = GET_VALUE(attrs, "scale");
	    
			Vector3d sc(1.0, 1.0, 1.0);
			if (scale) {
				char *scalex = strtok(scale, " ");
				char *scaley = strtok(NULL, " ");
				char *scalez = strtok(NULL, "");

				if (scalex == NULL || scaley == NULL || scalez == NULL) {
					LOG_ERR(("scale setting failed (%s)",m_current->name().c_str()));
				}
				else{
					sc.set(atof(scalex), atof(scaley), atof(scalez));
				}
			}
	    
			m_current->setScale(sc);
		}

		// Find the target XML file from current directory or SIGVERSE_DATADIR
		std::string tmp_fname = GET_VALUE(attrs, "filename");
		std::string path = getenv("SIGVERSE_DATADIR");
		std::string fname = "./" + tmp_fname;
		FILE *fp;
		if ((fp = fopen(fname.c_str(), "r")) == NULL) {
			fname = path + "/shape/" + tmp_fname;
			if ((fp = fopen(fname.c_str(), "r")) == NULL) {
				LOG_ERR(("cannot find shape file. [%s]", fname.c_str()));
				assert(fp != NULL);
			}
		}

		m_current->setShapeFile(tmp_fname);

		bool b = false;

		// Preparation of JNI
		char *cfg = getenv("SIGVERSE_X3DPARSER_CONFIG");
		if (cfg == NULL || strlen(cfg) == 0) {
			b = CJNIUtil::init("X3DParser.cfg");
		}
		else{
			b = CJNIUtil::init(cfg);
		}
	
		if (!b) {
			fprintf(stderr, "cannot read x3d config file");
			exit(1);
		}

		CX3DParser parser;
		parser.parse((char*)fname.c_str());
		//sread.read(fname.c_str());
		ODEWorld *w = m_world->odeWorld();
		//SSimObjBuilder builder(*m_currobj, *w);
		//m_current = dynamic_cast<SSimRobotEntity*>(m_current);
		//SSimRobotEntity *tmp;
		//m_current = dynamic_cast<SSimRobotEntity*>(m_current);
		//m_current = tmp;
		ShapeFileReader sread(m_current);
		LOG_SYS(("Creating object \"%s\"",m_current->name().c_str()));
		LOG_SYS(("Reading shape file [%s]", fname.c_str())); 
    
		if (m_current->isRobot()) {
			if (!sread.createRobotObj(&parser)) {
				LOG_ERR(("Failed to read robot shape file [%s]", fname.c_str())); 
			}
		}
		else{
			if (!sread.createObj(&parser)) {
				LOG_ERR(("Failed to read shape file [%s]", fname.c_str())); 
			}
		}

	} //   else if (strcmp(tagName, "x3d") == 0 || strcmp(tagName, "X3D") == 0) {
	else if (strcmp(tagName, "attribute") == 0 || strcmp(tagName, "Attribute") == 0) {
		if (m_current) {
			char *position  = GET_VALUE(attrs, "position");	 // entity position
			char *direction = GET_VALUE(attrs, "direction");	 // entity direction
			char *mass      = GET_VALUE(attrs, "mass");	 // entity mass
			char *collision = GET_VALUE(attrs, "collision");	 // collision detection flag
			char *quaternion= GET_VALUE(attrs, "quaternion");	 // quaternion
      
			if (position) {
				char *x = strtok(position, " ");
				char *y = strtok(NULL, " ");
				char *z = strtok(NULL, "");
				Vector3d pos(atof(x), atof(y), atof(z));
				if (m_current->isRobot()) {
					SSimRobotEntity *tmp_ent = (SSimRobotEntity*)m_current;
					tmp_ent->setInitPosition(pos);
				}
				else{
					m_current->setInitPosition(pos);
				}
			}
			//[ToDo]
			if (direction) {
			}
			//[ToDo]
			if (mass) {
				m_current->setMass(atof(mass));
			}
			if (collision) {
				if (strcmp(collision, "true") == 0) {
					if (m_current->isRobot()) {
						SSimRobotEntity *tmp_ent = (SSimRobotEntity*)m_current;
						tmp_ent->setCollision(true);
					}
					else{
						m_current->setCollision(true);
					}
				}
			}
			//[Todo]
			if (quaternion) {
			}
		}
	}
  
	// Added by okamoto on 2012-08-11
	// Reading and setting of camera parameter
	else if (strcmp(tagName, "camera") == 0 || strcmp(tagName, "Camera") == 0) {
		if (m_currobj) {
			char *cid  = GET_VALUE(attrs, "id");          // id number 
			char *link = GET_VALUE(attrs, "link");        // link name 
			char *fov  = GET_VALUE(attrs, "fov");	      // field of view
			char *as   = GET_VALUE(attrs, "aspectRatio"); // aspect ratio
			int iid    = -1;

			std::string id = cid;
			double dfov, das;
			// Whether value is specified by users
			bool isid   = false;
			bool islink = false;
			bool isfov  = false;
			bool isas   = false;

			if (link) islink = true;
			if (fov)  isfov  = true;
			if (as)   isas   = true;

			if (!cid) {
				LOG_ERR(("Cannot find camera ID."));
			}
			else {
				isid = true;
				iid = atoi(cid);
			}
			// Add camera ID
			m_currobj->addCameraID(iid);

			// Setting of camera parameters
			Value *vfov  = new DoubleValue();
			Value *vas   = new DoubleValue();
			Value *vlink = new StringValue();

			// Setting of each attributions
			std::string sfov  = "FOV"         + id;
			std::string sas   = "aspectRatio" + id;
			std::string slink = "elnk"        + id;
			vfov ->setString(sfov. c_str());
			vas  ->setString(sas.  c_str());	    
			vlink->setString(slink.c_str());	    

			// Add attribution info to entity
			m_currobj->push(new Attribute(sfov, vfov, "camera"));
			m_currobj->push(new Attribute(sas,  vas,  "camera"));
			if (iid > 2)
				m_currobj->push(new Attribute(slink, vlink, "camera"));

			if (isfov)
				m_currobj->setAttrValue(sfov.c_str(), fov);
			else 
				m_currobj->setAttrValue(sfov.c_str(), "45.0"); // default value

			if (isas)
				m_currobj->setAttrValue(sas.c_str(), as);
			else
				m_currobj->setAttrValue(sas.c_str(), "1.5");   // default value

			if (islink)
				m_currobj->setAttrValue(slink.c_str(), link);
			else
				m_currobj->setAttrValue(slink.c_str(), "body");// default value

			char *position = GET_VALUE(attrs, "position");
	    
			std::string epx = "epx" + id;
			std::string epy = "epy" + id;
			std::string epz = "epz" + id;
	    
			if (position) {
				std::string x = strtok(position, " ");
				std::string y = strtok(NULL, " ");
				std::string z = strtok(NULL, "");
				Vector3d pos(atof(x.c_str()), atof(y.c_str()), atof(z.c_str()));
	      
				if (iid > 2) {
					Value *v_x = new DoubleValue();
					Value *v_y = new DoubleValue();
					Value *v_z = new DoubleValue();

					v_x->setString(epx.c_str());
					v_y->setString(epy.c_str());
					v_z->setString(epz.c_str());

					// [Comment] Is it OK to execute new here?
					m_currobj->push(new Attribute(epx, v_x, "camera"));
					m_currobj->push(new Attribute(epy, v_y, "camera"));
					m_currobj->push(new Attribute(epz, v_z, "camera"));

				}
				m_currobj->setAttrValue(epx.c_str(), x.c_str());
				m_currobj->setAttrValue(epy.c_str(), y.c_str());
				m_currobj->setAttrValue(epz.c_str(), z.c_str());
				RELEASE(position);
			}

			else {
				// Default values
				m_currobj->setAttrValue(epx.c_str(), "0.0");
				m_currobj->setAttrValue(epy.c_str(), "0.0");
				m_currobj->setAttrValue(epz.c_str(), "0.0");
			}

			// camera direction
			char *direction  = GET_VALUE(attrs, "direction");
			char *quaternion = GET_VALUE(attrs, "quaternion");   // aspect ratio

			std::string evx = "evx" + id;
			std::string evy = "evy" + id;
			std::string evz = "evz" + id;

			std::string quw = "quw" + id;
			std::string qux = "qux" + id;
			std::string quy = "quy" + id;
			std::string quz = "quz" + id;

			if (direction && quaternion) {
				LOG_MSG(("cannot set camera quaternion and direction simultaneously")); 
			}

			if (direction) {
				std::string vx = strtok(direction, " ");
				std::string vy = strtok(NULL, " ");
				std::string vz = strtok(NULL, "");
				Vector3d dir(atof(vx.c_str()), atof(vy.c_str()), atof(vz.c_str()));
	
				if (iid > 2) {
					Value *v_x = new DoubleValue();
					Value *v_y = new DoubleValue();
					Value *v_z = new DoubleValue();

					v_x->setString(evx.c_str());
					v_y->setString(evy.c_str());
					v_z->setString(evz.c_str());
					// [Comment] Is it OK to execute new here?
					m_currobj->push(new Attribute(evx, v_x, "camera"));
					m_currobj->push(new Attribute(evy, v_y, "camera"));
					m_currobj->push(new Attribute(evz, v_z, "camera"));

				}
				m_currobj->setAttrValue(evx.c_str(), vx.c_str());
				m_currobj->setAttrValue(evy.c_str(), vy.c_str());
				m_currobj->setAttrValue(evz.c_str(), vz.c_str());	      
				RELEASE(direction);
			}
			else {
				Vector3d dir(0.0, 0.0, 1.0);
				m_currobj->setAttrValue(evx.c_str(), "0.0");
				m_currobj->setAttrValue(evy.c_str(), "0.0");
				m_currobj->setAttrValue(evz.c_str(), "1.0");	      
			}

			Value *q_w = new DoubleValue();
			Value *q_x = new DoubleValue();
			Value *q_y = new DoubleValue();
			Value *q_z = new DoubleValue();
      
			q_w->setString(quw.c_str());
			q_x->setString(qux.c_str());
			q_y->setString(quy.c_str());
			q_z->setString(quz.c_str());
      
			m_currobj->push(new Attribute(quw, q_w, "camera"));
			m_currobj->push(new Attribute(qux, q_x, "camera"));
			m_currobj->push(new Attribute(quy, q_y, "camera"));
			m_currobj->push(new Attribute(quz, q_z, "camera"));
      
			if (quaternion) {
				std::string qw = strtok(quaternion, " ");
				std::string qx = strtok(NULL, " ");
				std::string qy = strtok(NULL, " ");
				std::string qz = strtok(NULL, "");

				m_currobj->setAttrValue(quw.c_str(), qw.c_str());
				m_currobj->setAttrValue(qux.c_str(), qx.c_str());
				m_currobj->setAttrValue(quy.c_str(), qy.c_str());
				m_currobj->setAttrValue(quz.c_str(), qz.c_str());	      
				RELEASE(quaternion);
			}
			else {
				m_currobj->setAttrValue(quw.c_str(), "1.0");
				m_currobj->setAttrValue(qux.c_str(), "0.0");
				m_currobj->setAttrValue(quy.c_str(), "0.0");
				m_currobj->setAttrValue(quz.c_str(), "0.0");
			}
			//RELEASE(id.c_str());
			if (isid)   RELEASE(cid);
			if (islink) RELEASE(link);
			if (isfov)  RELEASE(fov);
			if (isas)   RELEASE(as);
		} // if (m_currobj)
	}
	RELEASE(tagName);
}