void CGroupAI::MakeFormationMove(Command* c) { float3 centerPos(c->params[0],c->params[1],c->params[2]); float3 rightPos(centerPos); if(c->params.size()==6) rightPos=float3(c->params[3],c->params[4],c->params[5]); float frontLength=centerPos.distance(rightPos)*2; if(frontLength>80){ sideDir=centerPos-rightPos; sideDir.y=0; sideDir.Normalize(); frontDir=sideDir.cross(float3(0,1,0)); numColumns=(int)(frontLength/columnDist); } int positionsUsed=0; std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits); for(multimap<float,int>::iterator oi=orderedUnits.begin();oi!=orderedUnits.end();++oi){ MoveToPos(oi->second,centerPos,positionsUsed++,c->options); } }
void GameButton::click() { QPoint centerPos(width() / 2, height() / 2); QMouseEvent temp(QEvent::MouseButtonRelease, centerPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); mousePressEvent(&temp); mouseReleaseEvent(&temp); }
void CSelectedUnitsAI::MakeFrontMove(Command* c,int player) { float3 centerPos(c->params[0],c->params[1],c->params[2]); float3 rightPos(c->params[3],c->params[4],c->params[5]); if(centerPos.distance(rightPos)<selectedUnits.netSelected[player].size()+33){ //treat this as a standard move if the front isnt long enough for(vector<int>::iterator ui = selectedUnits.netSelected[player].begin(); ui != selectedUnits.netSelected[player].end(); ++ui) { CUnit* unit=uh->units[*ui]; if(unit){ unit->commandAI->GiveCommand(*c); } } return; } float frontLength=centerPos.distance(rightPos)*2; sideDir=centerPos-rightPos; sideDir.y=0; sideDir.Normalize(); frontDir=sideDir.cross(float3(0,1,0)); numColumns=(int)(frontLength/columnDist); if(numColumns==0) numColumns=1; int positionsUsed=0; std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits,player); for(multimap<float,int>::iterator oi=orderedUnits.begin();oi!=orderedUnits.end();++oi){ MoveToPos(oi->second,centerPos,positionsUsed++,c->options); } }
void NodeConnectorView::mousePressEvent(QGraphicsSceneMouseEvent* event) { if(event->button() == Qt::LeftButton && !mTemporaryLink) // protects from double click { mTemporaryLink = new NodeLinkView(centerPos(), event->scenePos(), this, !mIsOutput); } }
void TextItem::centerTextItem() { // set the text width to the whole EditableTextItem width // !!!! http://www.cesarbs.org/blog/2011/05/30/aligning-text-in-qgraphicstextitem textItem->setTextWidth(rect().width() / textItem->scale()); // vertically center the text item QRectF textBound = textItem->boundingRect(); qreal textRectHeight = textBound.height() * textItem->scale(); QPointF centerPos(0, (rect().height() - textRectHeight) / 2); textItem->setPos(centerPos); }
void Camera::apply( glm::mat4x4 modelMatrix ) { glm::vec3 cameraPos( mPosition.x, mPosition.y, mPosition.z ); glm::vec4 centerPos( 0.0f, 0.0f, 1.0f, 0.0f ); glm::mat4 identityMtx( 1.0f ); centerPos = glm::rotate( identityMtx, mRotation.x, GLM_X_AXIS ) * centerPos; centerPos = glm::rotate( identityMtx, mRotation.y, GLM_Y_AXIS ) * centerPos; glm::vec3 upVec( 0.0f, 1.0f, 0.0f ); glm::mat4 viewMtx = glm::lookAt( cameraPos, glm::vec3( centerPos ) + cameraPos, upVec ); applyModelView( modelMatrix, viewMtx ); }
void CGroupAI::Update() { if(callback->IsSelected()){ const Command* c=callback->GetOrderPreview(); if(c->id==CMD_MOVE && c->params.size()==6){ //draw a preview of how the units will be ordered float3 centerPos(c->params[0],c->params[1],c->params[2]); float3 rightPos(c->params[3],c->params[4],c->params[5]); float frontLength=centerPos.distance(rightPos)*2; if(frontLength>80){ float3 tempSideDir=centerPos-rightPos; tempSideDir.y=0; tempSideDir.Normalize(); float3 tempFrontDir=tempSideDir.cross(float3(0,1,0)); int tempNumColumns=(int)(frontLength/columnDist); int posNum=0; float rot=GetRotationFromVector(tempFrontDir); std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits); for(multimap<float,int>::iterator oi=orderedUnits.begin();oi!=orderedUnits.end();++oi){ int lineNum=posNum/tempNumColumns; int colNum=posNum-lineNum*tempNumColumns; float side=(0.25f+colNum*0.5f)*columnDist*(colNum&1 ? -1:1); float3 pos=centerPos-tempFrontDir*(float)lineNum*lineDist+tempSideDir*side; pos.y=aicb->GetElevation(pos.x,pos.z); const UnitDef* ud=aicb->GetUnitDef(oi->second); aicb->DrawUnit(ud->name.c_str(),pos,rot,1,aicb->GetMyTeam(),true,false); ++posNum; } } } } }
void GameSessionInput::moveSelectedUnits() { vec3 clickPos = Root::shared().getDepthResult(); vec2 clickPos2(clickPos.x, clickPos.z); Faction* lf = session->getLocalFaction(); if(!lf) return; // did we click on an enemy unit Unit* best_unit = 0; float best_distance = 100.0; //Faction* from_faction = 0; float dist; for(unsigned int j = 0; j < session->getFactions().size(); ++j) { if(session->getFactions()[j] == lf) continue; for(list<Unit*>::iterator it = session->getFactions()[j]->getUnits().begin(); it != session->getFactions()[j]->getUnits().end(); ++it) { dist = glm::distance((*it)->getPosition2(), clickPos2); if(dist < (*it)->getInfo()->radius && dist < best_distance) { best_distance = dist; best_unit = (*it); } } } vec2 centerPos(0,0); //average position of selected units vector<int> unitIds; vector<vec2> unitPositions; for(list<Unit*>::iterator it = lf->getUnits().begin(); it != lf->getUnits().end(); ++it) if((*it)->isSelected()) { centerPos += (*it)->getPosition2(); unitPositions.push_back((*it)->getPosition2()); unitIds.push_back((*it)->getId()); } int numSelected = unitIds.size(); if(!numSelected) return; centerPos /= (float)numSelected; //FOR NOW: we only use pathfinding for normal walking, not for attacking if(best_unit) { Event& ev = Game::shared().getEventManager()->createEvent(EVENT_ATTACK_MOVE_UNIT_REQUEST); ev << numSelected; for(unsigned int i = 0; i < unitIds.size(); ++i) ev << unitIds[i] << best_unit->getId(); ev.send(); } else { //Movement from centerPos to clickPos vec2 target(clickPos.x, clickPos.z); //Find a path std::vector<vec2> pathNodes; //session->findPath(centerPos,target,pathNodes); if(pathNodes.empty()) pathNodes.push_back(target); //Now calculate the position of each unit relative to each other vector<vec2> relativePositions(unitIds.size()); vec2 direction = glm::normalize(target - centerPos); vec2 perpendicular(-direction.y, direction.x); //right hand rule float spread = 20.0f; int perRow = (int)(glm::sqrt((float)numSelected) + 0.99); direction *= spread; perpendicular *= spread; vector<bool> unitTaken(unitIds.size(),false); for(int i = 0; i < numSelected; ++i) { //This loops over the target spots in such a way that it first loops the points that are furthest away. //When the units are coming from the BOTTOM the order is like this: //1 2 3 //4 5 6 //7 8 9 vec2 targetSpot = target + float(perRow/2 - i/perRow)*direction + float(i%perRow - perRow/2)*perpendicular; //Select closest unit int bestIndex = -1; float bestDistance = 0; for(int j = 0; j < numSelected; ++j) { if(unitTaken[j]) continue; float dist = glm::distance(unitPositions[j],targetSpot); if(bestIndex == -1 || dist < bestDistance) { bestIndex = j; bestDistance = dist; } } relativePositions[bestIndex] = targetSpot - target; unitTaken[bestIndex] = true; } //Relative positions to center have been calculated. Now send the packet Event& ev = Game::shared().getEventManager()->createEvent(EVENT_MOVE_UNIT_REQUEST); ev << numSelected; for(int i = 0; i < numSelected; ++i) { ev << unitIds[i]; ev << (int)pathNodes.size(); for(unsigned int j = 0; j < pathNodes.size(); ++j) { ev << pathNodes[j] + relativePositions[i]; } } ev.send(); } }
// ---------------------------------------------------------------------- bool ObjMesh::loadFromObjFile(char *filename) { FILE *f = fopen(filename, "r"); if (!f) return false; clear(); ObjMeshString s, subs[maxVerticesPerFace]; ObjMeshString mtllib, matName; mHasTextureCoords = false; mHasNormals = false; strcpy(mtllib, ""); int materialNr = -1; int i,j; NxVec3 v; ObjMeshTriangle t; TexCoord tc; std::vector<NxVec3> centermVertices; std::vector<TexCoord> centermTexCoords; std::vector<NxVec3> centerNormals; extractPath(filename); while (!feof(f)) { if (fgets(s, OBJ_MESH_STRING_LEN, f) == NULL) break; if (strncmp(s, "mtllib", 6) == 0) { // material library sscanf(&s[7], "%s", mtllib); importMtlFile(mtllib); } else if (strncmp(s, "usemtl", 6) == 0) { // use material sscanf(&s[7], "%s", matName); materialNr = 0; int numMaterials = (int)mMaterials.size(); while (materialNr < numMaterials && strcasecmp(mMaterials[materialNr].name, matName) != 0) materialNr++; if (materialNr >= numMaterials) materialNr = -1; } else if (strncmp(s, "v ", 2) == 0) { // vertex sscanf(s, "v %f %f %f", &v.x, &v.y, &v.z); mVertices.push_back(v); } else if (strncmp(s, "vn ", 3) == 0) { // normal sscanf(s, "vn %f %f %f", &v.x, &v.y, &v.z); mNormals.push_back(v); } else if (strncmp(s, "vt ", 3) == 0) { // texture coords sscanf(s, "vt %f %f", &tc.u, &tc.v); mTexCoords.push_back(tc); } else if (strncmp(s, "f ", 2) == 0) { // face int nr; nr = sscanf(s, "f %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", subs[0], subs[1], subs[2], subs[3], subs[4], subs[5], subs[6], subs[7], subs[8], subs[9], subs[10], subs[11], subs[12],subs[13], subs[14]); int vertNr[maxVerticesPerFace], texNr[maxVerticesPerFace]; int normalNr[maxVerticesPerFace]; for (i = 0; i < nr; i++) { int refs[3]; parseRef(subs[i], refs); vertNr[i] = refs[0]-1; texNr[i] = refs[1]-1; normalNr[i] = refs[2]-1; } if (nr <= 4) { // simple non-singular triangle or quad if (vertNr[0] != vertNr[1] && vertNr[1] != vertNr[2] && vertNr[2] != vertNr[0]) { t.init(); t.vertexNr[0] = vertNr[0]; t.vertexNr[1] = vertNr[1]; t.vertexNr[2] = vertNr[2]; t.normalNr[0] = normalNr[0]; t.normalNr[1] = normalNr[1]; t.normalNr[2] = normalNr[2]; t.texCoordNr[0] = texNr[0]; t.texCoordNr[1] = texNr[1]; t.texCoordNr[2] = texNr[2]; t.materialNr = materialNr; mTriangles.push_back(t); } if (nr == 4) { // non-singular quad -> generate a second triangle if (vertNr[2] != vertNr[3] && vertNr[3] != vertNr[0] && vertNr[0] != vertNr[2]) { t.init(); t.vertexNr[0] = vertNr[2]; t.vertexNr[1] = vertNr[3]; t.vertexNr[2] = vertNr[0]; t.normalNr[0] = normalNr[2]; t.normalNr[1] = normalNr[3]; t.normalNr[2] = normalNr[0]; t.texCoordNr[0] = texNr[0]; t.texCoordNr[1] = texNr[1]; t.texCoordNr[2] = texNr[2]; t.materialNr = materialNr; mTriangles.push_back(t); } } } else { // polygonal face // compute center properties NxVec3 centerPos(0.0f, 0.0f, 0.0f); TexCoord centerTex; centerTex.zero(); for (i = 0; i < nr; i++) { centerPos += mVertices[vertNr[i]]; if (texNr[i] >= 0) centerTex += mTexCoords[texNr[i]]; } centerPos /= (float)nr; centerTex /= (float)nr; NxVec3 d1 = centerPos - mVertices[vertNr[0]]; NxVec3 d2 = centerPos - mVertices[vertNr[1]]; NxVec3 centerNormal = d1.cross(d2); centerNormal.normalize(); // add center vertex centermVertices.push_back(centerPos); centermTexCoords.push_back(centerTex); centerNormals.push_back(centerNormal); // add surrounding elements for (i = 0; i < nr; i++) { j = i+1; if (j >= nr) j = 0; t.init(); t.vertexNr[0] = mVertices.size() + centermVertices.size()-1; t.vertexNr[1] = vertNr[i]; t.vertexNr[2] = vertNr[j]; t.normalNr[0] = mNormals.size() + centerNormals.size()-1; t.normalNr[1] = normalNr[i]; t.normalNr[2] = normalNr[j]; t.texCoordNr[0] = mTexCoords.size() + centermTexCoords.size()-1; t.texCoordNr[1] = texNr[i]; t.texCoordNr[2] = texNr[j]; t.materialNr = materialNr; mTriangles.push_back(t); } } } } fclose(f); // new center mVertices are inserted here. // If they were inserted when generated, the vertex numbering would be corrupted for (i = 0; i < (int)centermVertices.size(); i++) mVertices.push_back(centermVertices[i]); for (i = 0; i < (int)centerNormals.size(); i++) mNormals.push_back(centerNormals[i]); for (i = 0; i < (int)centermTexCoords.size(); i++) mTexCoords.push_back(centermTexCoords[i]); if (mTexCoords.size() > 0) mHasTextureCoords = true; if (mNormals.size() > 0) mHasNormals = true; else updateNormals(); updateBounds(); return true; }
bool Spawns::loadFromXml(const std::string& filename) { if (loaded) { return true; } pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(filename.c_str()); if (!result) { printXMLError("Error - Spawns::loadFromXml", filename, result); return false; } this->filename = filename; loaded = true; for (auto spawnNode : doc.child("spawns").children()) { Position centerPos( pugi::cast<uint16_t>(spawnNode.attribute("centerx").value()), pugi::cast<uint16_t>(spawnNode.attribute("centery").value()), pugi::cast<uint16_t>(spawnNode.attribute("centerz").value()) ); int32_t radius; pugi::xml_attribute radiusAttribute = spawnNode.attribute("radius"); if (radiusAttribute) { radius = pugi::cast<int32_t>(radiusAttribute.value()); } else { radius = -1; } spawnList.emplace_front(centerPos, radius); Spawn& spawn = spawnList.front(); for (auto childNode : spawnNode.children()) { if (strcasecmp(childNode.name(), "monster") == 0) { pugi::xml_attribute nameAttribute = childNode.attribute("name"); if (!nameAttribute) { continue; } Direction dir; pugi::xml_attribute directionAttribute = childNode.attribute("direction"); if (directionAttribute) { dir = static_cast<Direction>(pugi::cast<uint16_t>(directionAttribute.value())); } else { dir = DIRECTION_NORTH; } Position pos( centerPos.x + pugi::cast<uint16_t>(childNode.attribute("x").value()), centerPos.y + pugi::cast<uint16_t>(childNode.attribute("y").value()), centerPos.z ); uint32_t interval = pugi::cast<uint32_t>(childNode.attribute("spawntime").value()) * 1000; if (interval > MINSPAWN_INTERVAL) { spawn.addMonster(nameAttribute.as_string(), pos, dir, interval); } else { std::cout << "[Warning - Spawns::loadFromXml] " << nameAttribute.as_string() << ' ' << pos << " spawntime can not be less than " << MINSPAWN_INTERVAL / 1000 << " seconds." << std::endl; } } else if (strcasecmp(childNode.name(), "npc") == 0) { pugi::xml_attribute nameAttribute = childNode.attribute("name"); if (!nameAttribute) { continue; } Npc* npc = Npc::createNpc(nameAttribute.as_string()); if (!npc) { continue; } pugi::xml_attribute directionAttribute = childNode.attribute("direction"); if (directionAttribute) { npc->setDirection(static_cast<Direction>(pugi::cast<uint16_t>(directionAttribute.value()))); } npc->setMasterPos(Position( centerPos.x + pugi::cast<uint16_t>(childNode.attribute("x").value()), centerPos.y + pugi::cast<uint16_t>(childNode.attribute("y").value()), centerPos.z ), radius); npcList.push_front(npc); } } } return true; }
bool Spawns::loadFromXml(const std::string& _filename) { if (loaded) { return true; } pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(_filename.c_str()); if (!result) { std::cout << "[Error - Spawns::loadFromXml] Failed to load " << _filename << ": " << result.description() << std::endl; return false; } filename = _filename; loaded = true; for (pugi::xml_node spawnNode = doc.child("spawns").first_child(); spawnNode; spawnNode = spawnNode.next_sibling()) { Position centerPos( pugi::cast<uint16_t>(spawnNode.attribute("centerx").value()), pugi::cast<uint16_t>(spawnNode.attribute("centery").value()), pugi::cast<uint16_t>(spawnNode.attribute("centerz").value()) ); int32_t radius; pugi::xml_attribute radiusAttribute = spawnNode.attribute("radius"); if (radiusAttribute) { radius = pugi::cast<int32_t>(radiusAttribute.value()); } else { radius = -1; } Spawn* spawn = new Spawn(centerPos, radius); spawnList.push_back(spawn); for (pugi::xml_node childNode = spawnNode.first_child(); childNode; childNode = childNode.next_sibling()) { if (strcasecmp(childNode.name(), "monster") == 0) { pugi::xml_attribute nameAttribute = childNode.attribute("name"); if (!nameAttribute) { continue; } Direction dir; pugi::xml_attribute directionAttribute = childNode.attribute("direction"); if (directionAttribute) { dir = static_cast<Direction>(pugi::cast<uint16_t>(directionAttribute.value())); } else { dir = NORTH; } Position pos( centerPos.x + pugi::cast<uint16_t>(childNode.attribute("x").value()), centerPos.y + pugi::cast<uint16_t>(childNode.attribute("y").value()), centerPos.z ); uint32_t interval = pugi::cast<uint32_t>(childNode.attribute("spawntime").value()) * 1000; if (interval > MINSPAWN_INTERVAL) { spawn->addMonster(nameAttribute.as_string(), pos, dir, interval); } else { std::cout << "[Warning - Spawns::loadFromXml] " << nameAttribute.as_string() << ' ' << pos << " spawntime can not be less than " << MINSPAWN_INTERVAL / 1000 << " seconds." << std::endl; } } else if (strcasecmp(childNode.name(), "npc") == 0) { pugi::xml_attribute nameAttribute = childNode.attribute("name"); if (!nameAttribute) { continue; } Npc* npc = Npc::createNpc(nameAttribute.as_string()); if (!npc) { continue; } pugi::xml_attribute directionAttribute = childNode.attribute("direction"); if (directionAttribute) { npc->setDirection(static_cast<Direction>(pugi::cast<uint16_t>(directionAttribute.value()))); } npc->setMasterPos(Position( centerPos.x + pugi::cast<uint16_t>(childNode.attribute("x").value()), centerPos.y + pugi::cast<uint16_t>(childNode.attribute("y").value()), centerPos.z ), radius); npcList.push_back(npc); } } } return true; }
void DotPolygonHit::setupCustom(){ numPoints = 5; float range = 100; ofVec2f centerPos(ofRandom(range,gameW-range), ofRandom(range,gameH-range)); if (arcadeMode){ centerPos = getArcadePoint(arcadeModeDist); } normalSize = 10; largeSize = normalSize * 1.2; startSize = 2; growTime = 0.15; normalizeTime = growTime+0.1; //these two are just their own time, not based on the previous values preDeathGrowTime = 0.1; shrinkTime = 0.3; points.resize(numPoints); pointSize.resize(numPoints); startDeathTimes.resize(numPoints); lines.resize(numPoints); float basePauseTime = 0.6; float deathSpacing = 0.15; float curAngle = ofRandom(TWO_PI); //setup dots for (int i=0; i<numPoints; i++){ startDeathTimes[i] = normalizeTime + basePauseTime + (float)i * deathSpacing; float thisDist = ofRandom(10,range); curAngle += ofRandom(PI*0.2,PI*0.5); points[i].x = centerPos.x + cos(curAngle) * thisDist; points[i].y = centerPos.y + sin(curAngle) * thisDist; pointSize[i] = startSize; } //setup lines for (int i=0; i<numPoints-1; i++){ ofVec2f lineEnd; lineEnd = points[i+1]; float disconnectTime = startDeathTimes[i+1]-startDeathTimes[i]; lines[i].setup(points[i].x, points[i].y, lineEnd.x, lineEnd.y, 0, startDeathTimes[i], disconnectTime); lines[i].setCurve(1, 2); } //last line is special and links to the start float disconnectTime = startDeathTimes[1]-startDeathTimes[0]; lines[numPoints-1].setup(points[numPoints-1].x, points[numPoints-1].y, points[0].x, points[0].y, 0, startDeathTimes[0], disconnectTime); lines[numPoints-1].setCurve(1, 2); }
void GuiVehicleControl::onMouseMove(const GuiEvent &evt) { // Contribute mouse position to MoveManager::*Speed variables // Dead zone (mMouseDeadZone), with the rest contributing // mContributePitch, mContributeYaw, and mContriuteRoll. // (Mouse position normalized to 0.0->1.0) // Calculate useful vectors (squared) Point2I realPos = globalToLocalCoord(evt.mousePoint); Point2F normalizedPos((F32)realPos.x / (F32)mBounds.extent.x, (F32)realPos.y / (F32)mBounds.extent.y); Point2F centerPos(normalizedPos.x - 0.5, normalizedPos.y - 0.5); if (mCurveMode == 1) { normalizedPos.x = mCurveCoeff * (F32)(normalizedPos.x*normalizedPos.x); normalizedPos.y = mCurveCoeff * (F32)(normalizedPos.y*normalizedPos.y); } else if (mCurveMode == 2) { normalizedPos.x = mCurveCoeff * mExp((F32)mLog((F32)normalizedPos.x)); normalizedPos.y = mCurveCoeff * mExp((F32)mLog((F32)normalizedPos.y)); } else { normalizedPos *= mCurveCoeff; } //Con::printf("real =[%d,%d], normal=[%f,%f], center=[%f,%f]", realPos.x, realPos.y, normalizedPos.x, normalizedPos.y, centerPos.x, centerPos.y); // Send directly to *Speed variables // TODO: factor in sensitivity? // centerPos is used, expressed in the range -0.5,0.5 // Pitch goes from up -> down,but needs to be converted to 0-1 range MoveManager::mPitchSpeed = centerPos.y * 2; // Calculate YAW - must be in dead zone F32 absX = mFabs(centerPos.x); if (absX < mMouseDeadZone) { // Calculate in range (0.0-1.0) in dead zone MoveManager::mYawSpeed = absX * (1.0 / mMouseDeadZone); if (centerPos.x < 0.0f) MoveManager::mYawSpeed = -MoveManager::mYawSpeed; } else { MoveManager::mYawSpeed = 0; } // Calculate ROLL if (absX > mMouseDeadZone) { // Negate dead zone and determine percentage outside dead zone // (0.5-mMouseDeadZone) MoveManager::mRollSpeed = (absX - mMouseDeadZone) * ( 1.0 / (0.5-mMouseDeadZone) ); if (centerPos.x < 0.0f) MoveManager::mRollSpeed = -MoveManager::mRollSpeed; } else { MoveManager::mRollSpeed = 0; } // Calculate X and Y axis if (!mUseRightAxis) { MoveManager::mXAxis_L = centerPos.x; MoveManager::mYAxis_L = centerPos.y; } else { MoveManager::mXAxis_R = centerPos.x; MoveManager::mYAxis_R = centerPos.y; }
void ResumeMovieView::CreateMenu( App * app, OvrVRMenuMgr & menuMgr, BitmapFont const & font ) { Menu = VRMenu::Create( "ResumeMoviePrompt" ); Vector3f fwd( 0.0f, 0.0f, 1.0f ); Vector3f up( 0.0f, 1.0f, 0.0f ); Vector3f defaultScale( 1.0f ); Array< VRMenuObjectParms const * > parms; VRMenuFontParms fontParms( true, true, false, false, false, 1.3f ); Quatf orientation( Vector3f( 0.0f, 1.0f, 0.0f ), 0.0f ); Vector3f centerPos( 0.0f, 0.0f, 0.0f ); VRMenuObjectParms centerRootParms( VRMENU_CONTAINER, Array< VRMenuComponent* >(), VRMenuSurfaceParms(), "CenterRoot", Posef( orientation, centerPos ), Vector3f( 1.0f, 1.0f, 1.0f ), fontParms, ID_CENTER_ROOT, VRMenuObjectFlags_t(), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) ); parms.PushBack( ¢erRootParms ); Menu->InitWithItems( menuMgr, font, 0.0f, VRMenuFlags_t(), parms ); parms.Clear(); // the centerroot item will get touch relative and touch absolute events and use them to rotate the centerRoot menuHandle_t centerRootHandle = Menu->HandleForId( menuMgr, ID_CENTER_ROOT ); VRMenuObject * centerRoot = menuMgr.ToObject( centerRootHandle ); OVR_ASSERT( centerRoot != NULL ); // ============================================================================== // // title // { Posef panelPose( Quatf( up, 0.0f ), Vector3f( 0.0f, 2.2f, -3.0f ) ); VRMenuObjectParms p( VRMENU_STATIC, Array< VRMenuComponent* >(), VRMenuSurfaceParms(), Strings::ResumeMenu_Title, panelPose, defaultScale, fontParms, VRMenuId_t( ID_TITLE.Get() ), VRMenuObjectFlags_t(), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) ); parms.PushBack( &p ); Menu->AddItems( menuMgr, font, parms, centerRootHandle, false ); parms.Clear(); } // ============================================================================== // // options // Array<const char *> options; options.PushBack( Strings::ResumeMenu_Resume ); options.PushBack( Strings::ResumeMenu_Restart ); Array<const char *> icons; icons.PushBack( "assets/resume.png" ); icons.PushBack( "assets/restart.png" ); Array<PanelPose> optionPositions; optionPositions.PushBack( PanelPose( Quatf( up, 0.0f / 180.0f * Mathf::Pi ), Vector3f( -0.5f, 1.7f, -3.0f ), Vector4f( 1.0f, 1.0f, 1.0f, 1.0f ) ) ); optionPositions.PushBack( PanelPose( Quatf( up, 0.0f / 180.0f * Mathf::Pi ), Vector3f( 0.5f, 1.7f, -3.0f ), Vector4f( 1.0f, 1.0f, 1.0f, 1.0f ) ) ); int borderWidth = 0, borderHeight = 0; GLuint borderTexture = LoadTextureFromApplicationPackage( "assets/resume_restart_border.png", TextureFlags_t( TEXTUREFLAG_NO_DEFAULT ), borderWidth, borderHeight ); for ( int i = 0; i < optionPositions.GetSizeI(); ++i ) { ResumeMovieComponent * resumeMovieComponent = new ResumeMovieComponent( this, i ); Array< VRMenuComponent* > optionComps; optionComps.PushBack( resumeMovieComponent ); VRMenuSurfaceParms panelSurfParms( "", borderTexture, borderWidth, borderHeight, SURFACE_TEXTURE_ADDITIVE, 0, 0, 0, SURFACE_TEXTURE_MAX, 0, 0, 0, SURFACE_TEXTURE_MAX ); Posef panelPose( optionPositions[ i ].Orientation, optionPositions[ i ].Position ); VRMenuObjectParms * p = new VRMenuObjectParms( VRMENU_BUTTON, optionComps, panelSurfParms, options[ i ], panelPose, defaultScale, fontParms, VRMenuId_t( ID_OPTIONS.Get() + i ), VRMenuObjectFlags_t(), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) ); parms.PushBack( p ); Menu->AddItems( menuMgr, font, parms, centerRootHandle, false ); DeletePointerArray( parms ); parms.Clear(); // add icon menuHandle_t optionHandle = centerRoot->ChildHandleForId( menuMgr, VRMenuId_t( ID_OPTIONS.Get() + i ) ); VRMenuObject * optionObject = menuMgr.ToObject( optionHandle ); OVR_ASSERT( optionObject != NULL ); int iconWidth = 0, iconHeight = 0; GLuint iconTexture = LoadTextureFromApplicationPackage( icons[ i ], TextureFlags_t( TEXTUREFLAG_NO_DEFAULT ), iconWidth, iconHeight ); VRMenuSurfaceParms iconSurfParms( "", iconTexture, iconWidth, iconHeight, SURFACE_TEXTURE_DIFFUSE, 0, 0, 0, SURFACE_TEXTURE_MAX, 0, 0, 0, SURFACE_TEXTURE_MAX ); Bounds3f textBounds = optionObject->GetTextLocalBounds( font ); optionObject->SetTextLocalPosition( Vector3f( iconWidth * VRMenuObject::DEFAULT_TEXEL_SCALE * 0.5f, 0.0f, 0.0f ) ); Posef iconPose( optionPositions[ i ].Orientation, optionPositions[ i ].Position + Vector3f( textBounds.GetMins().x, 0.0f, 0.01f ) ); p = new VRMenuObjectParms( VRMENU_STATIC, Array< VRMenuComponent* >(), iconSurfParms, NULL, iconPose, defaultScale, fontParms, VRMenuId_t( ID_OPTION_ICONS.Get() + i ), VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_ALL ), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) ); parms.PushBack( p ); Menu->AddItems( menuMgr, font, parms, centerRootHandle, false ); DeletePointerArray( parms ); parms.Clear(); menuHandle_t iconHandle = centerRoot->ChildHandleForId( menuMgr, VRMenuId_t( ID_OPTION_ICONS.Get() + i ) ); resumeMovieComponent->Icon = menuMgr.ToObject( iconHandle ); } Cinema.app->GetGuiSys().AddMenu( Menu ); }