示例#1
0
void renderScene(GLFWwindow *window, ShadowMap *shadowMap) {
    glUseProgram(ShadeProg);

    glUniform3f(h_uLightColor, 0.4, 0.4, 0.38);
    glUniform4f(h_uLightVec, 0.0, 1.0, 1.0, 0.0);

    // Render depth info from light's perspective
    shadowMap->BindFBO();
    glClear(GL_DEPTH_BUFFER_BIT);
    curView = SetView(); // CHANGE TO LIGHT'S PERSPECTIVE, NOT EYE
    curProj = SetOrthoProjectionMatrix();
    glUniform3f(h_uCamPos, 0.0, 1.0, 1.0);
    glfwDraw(window);

    // Render scene normally and draw
    shadowMap->UnbindFBO();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    curView = SetView();
    curProj = SetProjectionMatrix();
    glUniform3f(h_uCamPos, GetEye().x, GetEye().y, GetEye().z);
    glfwDraw(window);

    // Disable the shaders
    glUseProgram(0);
    glfwSwapBuffers(window);
}
示例#2
0
	//移動の向きを得る
	Vector3 Player::GetAngle(){
		Vector3 Angle(0, 0, 0);
		//コントローラの取得
		auto CntlVec = App::GetApp()->GetInputDevice().GetControlerVec();
		if (CntlVec[0].bConnected){
			if (CntlVec[0].fThumbLX != 0 && CntlVec[0].fThumbLY != 0){
				float MoveLength = 0;	//動いた時のスピード
				auto PtrTransform = GetComponent<Transform>();
				auto PtrCamera = GetStage()->GetCamera(0);
				//進行方向の向きを計算
				Vector3 Front = PtrTransform->GetPosition() - PtrCamera->GetEye();
				Front.y = 0;
				Front.Normalize();
				//進行方向向きからの角度を算出
				float FrontAngle = atan2(Front.z, Front.x);
				//コントローラの向き計算
				float MoveX = CntlVec[0].fThumbLX;
				float MoveZ = CntlVec[0].fThumbLY;
				//コントローラの向きから角度を計算
				float CntlAngle = atan2(-MoveX, MoveZ);
				//トータルの角度を算出
				float TotalAngle = FrontAngle + CntlAngle;
				//角度からベクトルを作成
				Angle = Vector3(cos(TotalAngle), 0, sin(TotalAngle));
				//正規化する
				Angle.Normalize();
				//Y軸は変化させない
				Angle.y = 0;
			}
		}
		return Angle;
	}
示例#3
0
bool physGrapple(float lx,float ly,float lz){
	bool ret = false;
   flip = 0;
   dir = glm::normalize(glm::vec3(-lx,ly,-lz));



   //printf("grapple in dir %f %f %f\n",dir.x,dir.y,dir.z);
   //printf("looks at is %f %f %f\n",lookAt.x,lookAt.y,lookAt.z);
   /*   btCollisionWorld::ClosestRayResultCallback RayCallback(btVector3(lookAt.x+.0*dir.x,lookAt.y-.0*dir.y,lookAt.z+.0*dir.z), btVector3(lookAt.x+50*dir.x,lookAt.y-50*dir.y,lookAt.z+50*dir.z));
   dynamicsWorld->rayTest(btVector3(lookAt.x+.0*dir.x,lookAt.y-.0*dir.y,lookAt.z+.0*dir.z), btVector3(lookAt.x+50*dir.x,lookAt.y-50*dir.y,lookAt.z+50*dir.z), RayCallback);
*/

//////////////////////////////
   glm:: vec3 ggaze = GetLookAt() - GetEye();
   glm::vec3 gw = ggaze/magnitude(ggaze);
   gw = glm::vec3(-1.0 * gw.x, -1.0 * gw.y, -1.0 * gw.z);
   glm::vec3 gu = glm::cross(GetUp(), gw)/magnitude(glm::cross(GetUp(), gw));
   gu *= 2;

   lookAt += glm::vec3(gu.x, 0, gu.z);
   ///////////////////////////////


   btCollisionWorld::ClosestRayResultCallback RayCallback(btVector3(lookAt.x+1.6*dir.x,lookAt.y-1.6*dir.y,lookAt.z+1.6*dir.z), btVector3(lookAt.x+75*dir.x,lookAt.y-75*dir.y,lookAt.z+75*dir.z));
   dynamicsWorld->rayTest(btVector3(lookAt.x+1.6*dir.x,lookAt.y-1.6*dir.y,lookAt.z+1.6*dir.z), btVector3(lookAt.x+75*dir.x,lookAt.y-75*dir.y,lookAt.z+75*dir.z), RayCallback);
   //player->setLinearVelocity(btVector3(dir.x*50,dir.y*50,dir.z*50));
   btTransform plPos;
   player->getMotionState()->getWorldTransform(plPos);
   if(RayCallback.hasHit()&& !playerGrappleActive && RayCallback.m_hitPointWorld.distance(plPos.getOrigin())>1.8) {
      playerJump=0;
    //End = RayCallback.m_hitPointWorld;
    //Normal = RayCallback.m_hitNormalWorld;
      //printf("hit!\n");
      btVector3 go=RayCallback.m_hitNormalWorld*-5+player->getLinearVelocity();
      if (go.length()>10)(go/go.length())*10;
      //player->setLinearVelocity(go);
      //printf("%f %f %f on hit norm",RayCallback.m_hitNormalWorld.getX(),RayCallback.m_hitNormalWorld.getY(),RayCallback.m_hitNormalWorld.getZ());
      tmp = RayCallback.m_hitPointWorld;
    // Do some clever stuff here
      if(tmp.getY()>1){
         playerGrappleActive =1;
         //SFX HERE
         //Sound s = Sound();
         //s.playSFX("../Assets/Sounds/HookShot.mp3");
         //printf("%f %f %f - player loc; %f %f %f grapple loc\n", physGetPlayerX(), physGetPlayerY(), physGetPlayerZ(), grapplingHookLocation().x, grapplingHookLocation().y, grapplingHookLocation().z);
         //printf("%f %f %f grapple sfx distance\n", abs(grapplingHookLocation().x - physGetPlayerX()), abs(grapplingHookLocation().y - physGetPlayerY()), abs(grapplingHookLocation().z - physGetPlayerZ()));
         musicPlayer.BGM.play3DSFX("../Assets/Sounds/HookShot.mp3", physGetPlayerX(), physGetPlayerY(), physGetPlayerZ(), grapplingHookLocation().x, grapplingHookLocation().y, grapplingHookLocation().z);
         
         ret = true;
      }
   }
   


   lookAt -= glm::vec3(gu.x, 0, gu.z);

   return ret;
}
示例#4
0
// Tests Identity Matrix Function
////////////////////////////////////////////////////////////////////////////////
TEST_F(LAopsTest, create_identity_matrix) {
  GetEye(m_matdim, m_testmat);
  ASSERT_FLOAT_EQ(m_testmat[2][2], 1);
  ASSERT_FLOAT_EQ(m_testmat[0][0], 1);
  ASSERT_FLOAT_EQ(m_testmat[2][3], 0);
  ASSERT_FLOAT_EQ(m_testmat[7][2], 0);
  float accumulator = 0;
  for (int i = 0; i < m_matdim; ++i) {
    accumulator += m_testmat[3][i];
  }
  ASSERT_FLOAT_EQ(accumulator, 1);
}
示例#5
0
void glfwEditGetCursorPos(GLFWwindow *window, double xpos, double ypos) {

   //printf("%f %f\n", xpos, g_height - ypos);
   lastCurPos = glm::vec2(xpos, g_height - ypos - 1);

   //If in GUI Selection, disable pitch and yaw
   if(eKeysPressed['G'] == 0) {

      if(xpos > g_width || xpos < 0 || ypos < 0 || ypos > g_height) {
         return;
      }

      //Get rid of if unneeded
      egaze = GetLookAt() - GetEye();
      ew = glm::vec3(-1.0 * ew.x, -1.0 * ew.y, -1.0 * ew.z);
      ew = glm::normalize(ew);
      eu = glm::cross(GetUp(), ew)/magnitude(glm::cross(GetUp(), ew));
      eu = glm::normalize(eu);

      eendX = xpos;
      eendY = g_height-ypos-1;

      float diff;

      //Calculate change in X
      if(estartX < eendX) {
         diff = eendX - estartX;
         ebeta = incrementYaw((diff * M_PI)/g_width);
      }
      else if(estartX > eendX){
         diff = estartX - eendX;
         ebeta = incrementYaw((-diff * M_PI)/g_width);
      }

      //Calculate change in Y
      if(eendY > estartY && ealpha <= 0.98) {
         diff = eendY - estartY;
         ealpha = incrementPitch((diff * M_PI)/g_width);
      }
      else if(eendY < estartY && ealpha >= -0.98) {
         diff = estartY - eendY;
         ealpha = incrementPitch(-(diff * M_PI)/g_width);
      }

      estartX = g_width/2.0;// = endX;
      estartY = g_height/2.0-1;// endY;
   }

}
示例#6
0
int grappleInRange(float lx,float ly,float lz){
   //glm::vec3 tempLookAt;

   dir = glm::normalize(glm::vec3(-lx,ly,-lz));

   glm:: vec3 ggaze = GetLookAt() - GetEye();
   glm::vec3 gw = ggaze/magnitude(ggaze);
   gw = glm::vec3(-1.0 * gw.x, -1.0 * gw.y, -1.0 * gw.z);
   glm::vec3 gu = glm::cross(GetUp(), gw)/magnitude(glm::cross(GetUp(), gw));
   gu *= 2;

   lookAt += glm::vec3(gu.x, 0, gu.z);
   
   btCollisionWorld::ClosestRayResultCallback RayCallback(btVector3(lookAt.x+1.6*dir.x,lookAt.y-1.6*dir.y,lookAt.z+1.6*dir.z), btVector3(lookAt.x+75*dir.x,lookAt.y-75*dir.y,lookAt.z+75*dir.z));
   dynamicsWorld->rayTest(btVector3(lookAt.x+1.6*dir.x,lookAt.y-1.6*dir.y,lookAt.z+1.6*dir.z), btVector3(lookAt.x+75*dir.x,lookAt.y-75*dir.y,lookAt.z+75*dir.z), RayCallback);

   lookAt -= glm::vec3(gu.x, 0, gu.z);
//   int ret = //inRange(50,75,glm::lookAt(playerPoss(),glm::vec3(tempLookAt.x+75*dir.x,tempLookAt.y+75*dir.y,tempLookAt.z+75*dir.z),glm::vec3(0,1,0)));
   //printf("grapple is %d range\n",RayCallback.hasHit());
   //if(RayCallback.hasHit())   printf("%f %f %f",RayCallback.m_hitPointWorld.getX(),RayCallback.m_hitPointWorld.getY(),RayCallback.m_hitPointWorld.getZ());
   return    RayCallback.hasHit();
}
	//--------------------------------------------------------------------------------------
	///	プレイヤーの行動クラス
	//--------------------------------------------------------------------------------------
	Vec3 PlayerBehavior::GetMoveVector() const {
		Vec3 Angle(0, 0, 0);
		//コントローラの取得
		auto CntlVec = App::GetApp()->GetInputDevice().GetControlerVec();
		if (CntlVec[0].bConnected) {
			if (CntlVec[0].fThumbLX != 0 || CntlVec[0].fThumbLY != 0) {
				float MoveLength = 0;	//動いた時のスピード
				auto PtrTransform = GetGameObject()->GetComponent<Transform>();
				auto PtrCamera = GetGameObject()->OnGetDrawCamera();
				//進行方向の向きを計算
				Vec3 Front = PtrTransform->GetPosition() - PtrCamera->GetEye();
				Front.y = 0;
				Front.normalize();
				//進行方向向きからの角度を算出
				float FrontAngle = atan2(Front.z, Front.x);
				//コントローラの向き計算
				float MoveX = CntlVec[0].fThumbLX;
				float MoveZ = CntlVec[0].fThumbLY;
				Vec2 MoveVec(MoveX, MoveZ);
				float MoveSize = MoveVec.length();
				//コントローラの向きから角度を計算
				float CntlAngle = atan2(-MoveX, MoveZ);
				//トータルの角度を算出
				float TotalAngle = FrontAngle + CntlAngle;
				//角度からベクトルを作成
				Angle = Vec3(cos(TotalAngle), 0, sin(TotalAngle));
				//正規化する
				Angle.normalize();
				//移動サイズを設定。
				Angle *= MoveSize;
				//Y軸は変化させない
				Angle.y = 0;
			}
		}
		return Angle;
	}
示例#8
0
	void MyCamera::Update(){
		auto CntlVec = App::GetApp()->GetInputDevice().GetControlerVec();
		//前回のターンからの時間
		float ElapsedTime = App::GetApp()->GetElapsedTime();
		if (CntlVec[0].bConnected){
			Vector3 NewAt(0, 0, 0);
			auto TargetPtr = GetTargetObject();
			if (TargetPtr){
				//目指したい場所
				Vector3 ToAt = TargetPtr->GetComponent<Transform>()->GetPosition();
				NewAt = Lerp::CalculateLerp(GetAt(), ToAt, 0, 1.0f, m_ToTargetLerp, Lerp::Linear);
			}
			//ステップ1、注視点と位置の変更
			Vector3 Span = GetAt() - GetEye();
			Vector3 NewEye = NewAt - Span;
			SetAt(NewAt);
			SetEye(NewEye);
			//ステップ2、ズームの変更
			//カメラ位置と注視点の間のベクトルを算出
			Span = GetAt() - GetEye();
			//正規化
			Span.Normalize();
			//変化値の決定
			Span = Span * ElapsedTime * 10.0f;

			Vector3 NewArm = GetAt() - GetEye();
			//Dパッド下
			//カメラを引く
			if (CntlVec[0].wButtons & XINPUT_GAMEPAD_DPAD_DOWN){
				//カメラ位置を引く
				NewEye = NewEye - Span;
				NewArm = NewAt - NewEye;
				if (NewArm.Length() > (GetFar() * 0.1f)){
					NewEye = NewEye + Span;
					NewArm = NewAt - NewEye;
				}
			}
			//Dパッド上
			//カメラを寄る
			if (CntlVec[0].wButtons & XINPUT_GAMEPAD_DPAD_UP){
				//カメラ位置を寄る
				NewEye = NewEye + Span;
				NewArm = NewAt - NewEye;
				if (NewArm.Length() < GetNear() * 2.0f){
					NewEye = NewEye - Span;
					NewArm = NewAt - NewEye;
				}
			}
			SetAt(NewAt);
			SetEye(NewEye);
			//ステップ3角度の変更
			//現在のAtとEyeの角度を得る
			Vector3 ArmInv = GetEye() - GetAt();
			//右スティックX方向
			FLOAT AngleY = 0;
			//右スティックY方向
			FLOAT AngleX = 0;
			FLOAT AngleZ = 0;
			if (CntlVec[0].fThumbRX != 0){
	//右スティックを聞かないようにする
	//			AngleY = -CntlVec[0].fThumbRX * ElapsedTime;
			}
			if (CntlVec[0].fThumbRY != 0){
	//右スティックを聞かないようにする
	//			AngleX = CntlVec[0].fThumbRY * ElapsedTime;
	//			AngleZ = CntlVec[0].fThumbRY * ElapsedTime;
			}
			if (ArmInv.z > 0){
				AngleX *= -1.0f;
			}
			if (ArmInv.x < 0){
				AngleZ *= -1.0f;
			}
			Quaternion QtSpan(AngleX, AngleY, AngleZ);
			QtSpan.Normalize();
			//回転先計算の行列を作成
			Matrix4X4 Mat, Mat2;
			Mat.STRTransformation(
				Vector3(1.0f, 1.0f, 1.0f),
				ArmInv,
				QtSpan);
			Mat2.TranslationFromVector(GetAt());
			Mat *= Mat2;
			NewEye = Mat.PosInMatrix();
			if (NewEye.y < 0.5f){
				NewEye.y = 0.5f;
			}
			//カメラが一定以上、上から視線にならなように調整
			ArmInv = NewEye - GetAt();
			ArmInv.Normalize();
			float y2 = ArmInv.y * ArmInv.y;
			float x2 = ArmInv.x * ArmInv.x;
			float z2 = ArmInv.z * ArmInv.z;
			if (y2 <= (x2 + z2)){
				SetEye(NewEye);
			}

		}
		Camera::Update();
	}
示例#9
0
		void Player::FireWeapon() {
			SPADES_MARK_FUNCTION();
			
			Vector3 muzzle = GetEye();
			muzzle += GetFront() * 0.01f;
			
			// for hit-test debugging
			std::map<int, HitTestDebugger::PlayerHit> playerHits;
			std::vector<Vector3> bulletVectors;
			
			//Vector3 right = GetRight();
			//Vector3 up = GetUp();
			
			int pellets = weapon->GetPelletSize();
			float spread = weapon->GetSpread();
			GameMap *map = world->GetMap();
			
			// pyspades takes destroying more than one block as a
			// speed hack (shotgun does this)
			bool blockDestroyed = false;
			
			Vector3 dir2 = GetFront();
			for(int i =0 ; i < pellets; i++){
				
				// AoS 0.75's way (dir2 shouldn't be normalized!)
				dir2.x += (GetRandom() - GetRandom()) * spread;
				dir2.y += (GetRandom() - GetRandom()) * spread;
				dir2.z += (GetRandom() - GetRandom()) * spread;
				Vector3 dir = dir2.Normalize();
				
				bulletVectors.push_back(dir);
				
				// first do map raycast
				GameMap::RayCastResult mapResult;
				mapResult = map->CastRay2(muzzle,
										  dir,
										  500);
				
				Player *hitPlayer = NULL;
				float hitPlayerDistance = 0.f;
				HitBodyPart hitPart = HitBodyPart::None;
				
				for(int i = 0; i < world->GetNumPlayerSlots(); i++){
					Player *other = world->GetPlayer(i);
					if(other == this || other == NULL)
						continue;
					if(other == this || !other->IsAlive() ||
					   other->GetTeamId() >= 2)
						continue;
					// quickly reject players unlikely to be hit
					if(!other->RayCastApprox(muzzle, dir))
						continue;
					
					HitBoxes hb = other->GetHitBoxes();
					Vector3 hitPos;
					
					if(hb.head.RayCast(muzzle, dir, &hitPos)) {
						float dist = (hitPos - muzzle).GetLength();
						if(hitPlayer == NULL ||
						   dist < hitPlayerDistance){
							hitPlayer = other;
							hitPlayerDistance = dist;
							hitPart = HitBodyPart::Head;
						}
					}
					if(hb.torso.RayCast(muzzle, dir, &hitPos)) {
						float dist = (hitPos - muzzle).GetLength();
						if(hitPlayer == NULL ||
						   dist < hitPlayerDistance){
							hitPlayer = other;
							hitPlayerDistance = dist;
							hitPart = HitBodyPart::Torso;
						}
					}
					for(int j = 0; j < 3 ;j++){
						if(hb.limbs[j].RayCast(muzzle, dir, &hitPos)) {
							float dist = (hitPos - muzzle).GetLength();
							if(hitPlayer == NULL ||
							   dist < hitPlayerDistance){
								hitPlayer = other;
								hitPlayerDistance = dist;
								switch(j) {
									case 0: hitPart = HitBodyPart::Limb1; break;
									case 1: hitPart = HitBodyPart::Limb2; break;
									case 2: hitPart = HitBodyPart::Arms;  break;
								}
							}
						}
					}
				}
				
				Vector3 finalHitPos;
				finalHitPos = muzzle + dir * 128.f;
				
				if(hitPlayer == nullptr && !mapResult.hit) {
					// might hit water surface.
					
				}
				
				if(mapResult.hit && (mapResult.hitPos - muzzle).GetLength() < 128.f &&
				   (hitPlayer == NULL || (mapResult.hitPos - muzzle).GetLength() < hitPlayerDistance)){
					IntVector3 outBlockCoord = mapResult.hitBlock;
					// TODO: set correct ray distance
					// FIXME: why ray casting twice?
					
					finalHitPos = mapResult.hitPos;
					
					if(outBlockCoord.x >= 0 && outBlockCoord.y >= 0 && outBlockCoord.z >= 0 &&
					   outBlockCoord.x < map->Width() && outBlockCoord.y < map->Height() &&
					   outBlockCoord.z < map->Depth()){
						if(outBlockCoord.z == 63) {
							if(world->GetListener())
								world->GetListener()->BulletHitBlock(mapResult.hitPos,
																	 mapResult.hitBlock,
																	 mapResult.normal);
						}else if(outBlockCoord.z == 62) {
							// blocks at this level cannot be damaged
							if(world->GetListener())
								world->GetListener()->BulletHitBlock(mapResult.hitPos,
																	 mapResult.hitBlock,
																	 mapResult.normal);
						}else{
							int x = outBlockCoord.x;
							int y = outBlockCoord.y;
							int z = outBlockCoord.z;
							SPAssert(map->IsSolid(x, y, z));
							
							Vector3 blockF = {x + .5f, y + .5f, z + .5f};
							float distance = (blockF - muzzle).GetLength();
							
							uint32_t color = map->GetColor(x, y, z);
							int health = color >> 24;
							health -= weapon->GetDamage(HitTypeBlock, distance);
							if(health <= 0 && !blockDestroyed){
								health = 0;
								blockDestroyed = true;
								//send destroy cmd
								if(world->GetListener() &&
								   world->GetLocalPlayer() == this)
									world->GetListener()->LocalPlayerBlockAction
									(outBlockCoord, BlockActionTool);
								
							}
							color = (color & 0xffffff) | ((uint32_t)health << 24);
							if(map->IsSolid(x, y, z))
								map->Set(x, y, z, true, color);
							
							if(world->GetListener())
								world->GetListener()->BulletHitBlock(mapResult.hitPos,
																	 mapResult.hitBlock,
																	 mapResult.normal);
						}
					}
			    }else if(hitPlayer != NULL){
示例#10
0
		void Player::Update(float dt) {
			SPADES_MARK_FUNCTION();
			auto* listener = world->GetListener();
			
			MovePlayer(dt);
			
			if(!IsAlive()) {
				// do death cleanup
				blockCursorDragging = false;
			}
			
			if(tool == ToolSpade){
				if(weapInput.primary){
					if(world->GetTime() > nextSpadeTime){
						UseSpade();
						nextSpadeTime = world->GetTime() + GetToolPrimaryDelay();
					}
				}else if(weapInput.secondary){
					if(world->GetTime() > nextDigTime){
						DigWithSpade();
						nextDigTime = world->GetTime() + GetToolSecondaryDelay();
						firstDig = false;
					}
				}
			}else if(tool == ToolBlock && IsLocalPlayer()){
				GameMap::RayCastResult result;
				auto *map = GetWorld()->GetMap();
				result = map->CastRay2(GetEye(), GetFront(), 12);
				canPending = false;
				
				if(blockCursorDragging) {
					// check the starting point is not floating
					auto start = blockCursorDragPos;
					if(map->IsSolidWrapped(start.x-1, start.y, start.z) ||
					   map->IsSolidWrapped(start.x, start.y-1, start.z) ||
					   map->IsSolidWrapped(start.x, start.y, start.z-1) ||
					   map->IsSolidWrapped(start.x+1, start.y, start.z) ||
					   map->IsSolidWrapped(start.x, start.y+1, start.z) ||
					   map->IsSolidWrapped(start.x, start.y, start.z+1)) {
						// still okay
					}else{
						// cannot build; floating
						if(listener &&
						   this == world->GetLocalPlayer()) {
							listener->
							LocalPlayerBuildError(BuildFailureReason::InvalidPosition);
						}
						blockCursorDragging = false;
					}
				}
				
				if(result.hit &&
				   (result.hitBlock + result.normal).z < 62 &&
				   (!OverlapsWithOneBlock(result.hitBlock + result.normal)) &&
				   BoxDistanceToBlock(result.hitBlock + result.normal) < 3.f &&
				   !pendingPlaceBlock){
					
					// Building is possible, and there's no delayed block placement.
					blockCursorActive = true;
					blockCursorPos = result.hitBlock + result.normal;
					
				}else if(pendingPlaceBlock){
					
					// Delayed Block Placement: When player attempts to place a block while jumping and
					// placing block is currently impossible, building will be delayed until it becomes
					// possible, as long as player is airborne.
					if(airborne == false || blockStocks <= 0){
						// player is no longer airborne, or doesn't have a block to place.
						pendingPlaceBlock = false;
						lastSingleBlockBuildSeqDone = true;
						if(blockStocks > 0) {
							// cannot build; invalid position.
						}
					}else if((!OverlapsWithOneBlock(pendingPlaceBlockPos)) &&
							 BoxDistanceToBlock(pendingPlaceBlockPos) < 3.f){
						// now building became possible.
						SPAssert(this == world->GetLocalPlayer());
						
						if(GetWorld()->GetListener())
							GetWorld()->GetListener()->LocalPlayerBlockAction(pendingPlaceBlockPos, BlockActionCreate);
						
						pendingPlaceBlock = false;
						lastSingleBlockBuildSeqDone = true;
						// blockStocks--; decrease when created
						
						nextBlockTime = world->GetTime() + GetToolPrimaryDelay();
					}
					
				}else{
					// Delayed Block Placement can be activated only when the only reason making placement
					// impossible is that block to be placed overlaps with the player's hitbox.
					canPending = result.hit &&
								 (result.hitBlock + result.normal).z < 62 &&
								 BoxDistanceToBlock(result.hitBlock + result.normal) < 3.f;
					
					blockCursorActive = false;
					int dist = 11;
					for(; dist >= 1 &&
						BoxDistanceToBlock(result.hitBlock + result.normal) > 3.f ; dist--) {
						result = GetWorld()->GetMap()->CastRay2(GetEye(),
																GetFront(),
																dist);
					}
					for(; dist < 12 &&
						BoxDistanceToBlock(result.hitBlock + result.normal) < 3.f ; dist++) {
						result = GetWorld()->GetMap()->CastRay2(GetEye(),
																GetFront(),
																dist);
					}
					
					blockCursorPos = result.hitBlock + result.normal;
				}
				
			}else if(tool == ToolWeapon){
			}else if(tool == ToolGrenade){
				if(holdingGrenade){
					if(world->GetTime() - grenadeTime > 2.9f){
						ThrowGrenade();
					}
				}
			}
		
			if(tool != ToolWeapon)
				weapon->SetShooting(false);
			if(weapon->FrameNext(dt)){
				FireWeapon();
			}
			
			if(weapon->IsReloading()) {
				lastReloadingTime = world->GetTime();
			}else if(reloadingServerSide) {
				// for some reason a server didn't return
				// WeaponReload packet.
				if(world->GetTime() + lastReloadingTime + .8f) {
					reloadingServerSide = false;
					weapon->ForceReloadDone();
				}
			}
		}
示例#11
0
		void Player::FireWeapon() {
			SPADES_MARK_FUNCTION();
			
			Vector3 muzzle = GetEye();
			muzzle += GetFront() * 0.01f;/*
			muzzle += GetRight() * 0.4f;
			muzzle -= GetUp() * 0.3f;*/
			
			Vector3 right = GetRight();
			Vector3 up = GetUp();
			
			int pellets = weapon->GetPelletSize();
			float spread = weapon->GetSpread();
			GameMap *map = world->GetMap();
			
			// pyspades takes destroying more than one block as a
			// speed hack (shotgun does this)
			bool blockDestroyed = false;
			
			Vector3 dir2 = GetFront();
			for(int i =0 ; i < pellets; i++){
				// AoS 0.75's way (dir2 shouldn't be normalized!)
				dir2.x += (GetRandom() * 2.f - 1.f) * spread;
				dir2.y += (GetRandom() * 2.f - 1.f) * spread;
				dir2.z += (GetRandom() * 2.f - 1.f) * spread;
				Vector3 dir = dir2.Normalize();
				
				// first do map raycast
				GameMap::RayCastResult mapResult;
				mapResult = map->CastRay2(muzzle,
										  dir,
										  500);
				
				Player *hitPlayer = NULL;
				float hitPlayerDistance = 0.f;
				int hitFlag = 0;
				
				for(int i = 0; i < world->GetNumPlayerSlots(); i++){
					Player *other = world->GetPlayer(i);
					if(other == this || other == NULL)
						continue;
					if(other == this || !other->IsAlive() ||
					   other->GetTeamId() >= 2)
						continue;
					if(!other->RayCastApprox(muzzle, dir))
						continue;
					
					HitBoxes hb = other->GetHitBoxes();
					Vector3 hitPos;
					
					if(hb.head.RayCast(muzzle, dir, &hitPos)) {
						float dist = (hitPos - muzzle).GetLength();
						if(hitPlayer == NULL ||
						   dist < hitPlayerDistance){
							if(hitPlayer != other){
								hitPlayer = other;
								hitFlag = 0;
							}
							hitPlayerDistance = dist;
							hitFlag = 1; // head
						}
					}
					if(hb.torso.RayCast(muzzle, dir, &hitPos)) {
						float dist = (hitPos - muzzle).GetLength();
						if(hitPlayer == NULL ||
						   dist < hitPlayerDistance){
							if(hitPlayer != other){
								hitPlayer = other;
								hitFlag = 0;
							}
							hitPlayerDistance = dist;
							hitFlag = 2; // torso
						}
					}
					for(int j = 0; j < 3 ;j++){
						if(hb.limbs[j].RayCast(muzzle, dir, &hitPos)) {
							float dist = (hitPos - muzzle).GetLength();
							if(hitPlayer == NULL ||
							   dist < hitPlayerDistance){
								if(hitPlayer != other){
									hitPlayer = other;
									hitFlag = 0;
								}
								hitPlayerDistance = dist;
								if(j == 2)
									hitFlag = 8; // arms
								else
									hitFlag = 4; // leg
							}
						}
					}
				}
				
				Vector3 finalHitPos;
				finalHitPos = muzzle + dir * 128.f;
				
				if(mapResult.hit && (mapResult.hitPos - muzzle).GetLength() < 128.f &&
				   (hitPlayer == NULL || (mapResult.hitPos - muzzle).GetLength() < hitPlayerDistance)){
					IntVector3 outBlockCoord = mapResult.hitBlock;
					// TODO: set correct ray distance
					// FIXME: why ray casting twice?
					
					finalHitPos = mapResult.hitPos;
					
					if(outBlockCoord.x >= 0 && outBlockCoord.y >= 0 && outBlockCoord.z >= 0 &&
					   outBlockCoord.x < map->Width() && outBlockCoord.y < map->Height() &&
					   outBlockCoord.z < map->Depth()){
						if(outBlockCoord.z < 62){
							int x = outBlockCoord.x;
							int y = outBlockCoord.y;
							int z = outBlockCoord.z;
							SPAssert(map->IsSolid(x, y, z));
							
							Vector3 blockF = {x + .5f, y + .5f, z + .5f};
							float distance = (blockF - muzzle).GetLength();
							
							uint32_t color = map->GetColor(x, y, z);
							int health = color >> 24;
							health -= weapon->GetDamage(HitTypeBlock, distance);
							if(health <= 0 && !blockDestroyed){
								health = 0;
								blockDestroyed = true;
								//send destroy cmd
								if(world->GetListener() &&
								   world->GetLocalPlayer() == this)
									world->GetListener()->LocalPlayerBlockAction
									(outBlockCoord, BlockActionTool);
								
							}
							color = (color & 0xffffff) | ((uint32_t)health << 24);
							if(map->IsSolid(x, y, z))
								map->Set(x, y, z, true, color);
							
							if(world->GetListener())
								world->GetListener()->BulletHitBlock(mapResult.hitPos,
																	 mapResult.hitBlock,
																	 mapResult.normal);
						}
					}
			    }else if(hitPlayer != NULL){
示例#12
0
		void Player::Update(float dt) {
			SPADES_MARK_FUNCTION();
			
			MovePlayer(dt);
			if(tool == ToolSpade){
				if(weapInput.primary){
					if(world->GetTime() > nextSpadeTime){
						UseSpade();
						nextSpadeTime = world->GetTime() + GetToolPrimaryDelay();
					}
				}else if(weapInput.secondary){
					if(world->GetTime() > nextDigTime){
						DigWithSpade();
						nextDigTime = world->GetTime() + GetToolSecondaryDelay();
						firstDig = false;
					}
				}
			}else if(tool == ToolBlock){
				GameMap::RayCastResult result;
				result = GetWorld()->GetMap()->CastRay2(GetEye(),
														GetFront(),
														12);
				canPending = false;
				if(result.hit && (result.hitBlock + result.normal).z < 62 &&
				   (!OverlapsWithOneBlock(result.hitBlock + result.normal)) &&
				   BoxDistanceToBlock(result.hitBlock + result.normal) < 3.f &&
				   !pendingPlaceBlock){
					blockCursorActive = true;
					blockCursorPos = result.hitBlock + result.normal;
				}else if(pendingPlaceBlock){
					if(airborne == false || blockStocks <= 0){
						pendingPlaceBlock = false;
					}else if((!OverlapsWithOneBlock(pendingPlaceBlockPos)) &&
							 BoxDistanceToBlock(pendingPlaceBlockPos) < 3.f){
						SPAssert(this == world->GetLocalPlayer());
						
						if(GetWorld()->GetListener())
							GetWorld()->GetListener()->LocalPlayerBlockAction(pendingPlaceBlockPos, BlockActionCreate);
						
						pendingPlaceBlock = false;
						// blockStocks--; decrease when created
						
						nextBlockTime = world->GetTime() + GetToolPrimaryDelay();
					}
				}else{
					canPending = result.hit && (result.hitBlock + result.normal).z < 62 &&
					BoxDistanceToBlock(result.hitBlock + result.normal) < 3.f;
					blockCursorActive = false;
					blockCursorPos = result.hitBlock + result.normal;
				}
			}else if(tool == ToolWeapon){
			}else if(tool == ToolGrenade){
				if(holdingGrenade){
					if(world->GetTime() - grenadeTime > 2.9f){
						ThrowGrenade();
					}
				}
			}
		
			if(tool != ToolWeapon)
				weapon->SetShooting(false);
			if(weapon->FrameNext(dt)){
				FireWeapon();
			}
			
			if(weapon->IsReloading()) {
				lastReloadingTime = world->GetTime();
			}else if(reloadingServerSide) {
				// for some reason a server didn't return
				// WeaponReload packet.
				if(world->GetTime() + lastReloadingTime + .8f) {
					reloadingServerSide = false;
					weapon->ForceReloadDone();
				}
			}
		}
示例#13
0
// Tests Determinant of Identity
////////////////////////////////////////////////////////////////////////////////
TEST_F(LAopsTest, det_of_identity_matrix) {
  GetEye(m_matdim, m_testmat);
  fem_float detval = det(m_matdim, m_testmat);
  ASSERT_FLOAT_EQ(detval, 1);
}
示例#14
0
Vect3f CFPSCamera::GetDirection () const
{
	assert(m_pObject3D);

	return (GetLookAt() - GetEye());
}