public static Boolean Detect(BasicModel shot, Collidable item, Boolean isPigeon) { Vector3 boundingBox = item.GetBoundingBox(); Vector3 itemPos = item.GetPosition(); //get the shot's position, rotation and scale Matrix shotMat = shot.GetWorld(); Vector3 shotPos; Quaternion shotRotation; Vector3 shotScale; shotMat.Decompose(out shotScale, out shotRotation, out shotPos); //offset to compensate for the camera location not being at the origin. //camera loc is 0,0,100 itemPos.Z -= 100; shotPos.Z -= 100; //calculate the shot's distance from the origin double shotDistance = Math.Sqrt(Math.Pow(shotPos.X, 2) + Math.Pow(shotPos.Y, 2) + Math.Pow(shotPos.Z, 2)); //normalize the shot's position vector so the distance is equal to 1.0 Vector3 shotNormalizedPos = new Vector3(shotPos.X / (float)shotDistance, shotPos.Y / (float)shotDistance, shotPos.Z / (float)shotDistance); //don't try to check collision detection for shots that have already passed the target in depth if ((item.GetDistance()+boundingBox.Z - shotDistance < 0) && isPigeon) return false; //laser gun effect //multiply the normalized shot vector by the target's distance. The effect of this operation is that the shot's distance becomes equal to that of the target's, //allowing us to simply check whether the shot is contained inside the target's bounding box to detect a hit. shotNormalizedPos *= (float)Math.Sqrt(Math.Pow(itemPos.X, 2) + Math.Pow(itemPos.Y, 2) + Math.Pow(itemPos.Z, 2)); float xDiff = itemPos.X - shotNormalizedPos.X; float yDiff = itemPos.Y - shotNormalizedPos.Y; float zDiff = itemPos.Z - shotNormalizedPos.Z; //hack to get the shot's vector to face the right way, since shots quickly gain a negative Z value while pidgeons always stay positive if (isPigeon) zDiff = (zDiff < 0) ? -zDiff : zDiff; //check to see if the shot is inside the bounding box if (boundingBox.X / 2 > xDiff && (0 - (boundingBox.X / 2)) < xDiff && boundingBox.Y / 2 > yDiff && (0 - (boundingBox.Y / 2)) < yDiff) { if (isPigeon && boundingBox.Z / 2 > zDiff && (0 - (boundingBox.Z / 2)) < zDiff) return true; else if (!isPigeon) return true; } return false; }
private void checkCollision(BasicModel shot) { for (int i = 0; i < pigeons.Count; i++) { if (Collision.Detect(shot,pigeons[i],true)) { explosions.Add(new ParticleExplosion(GraphicsDevice, pigeons[i].GetWorld().Translation, ((Game1)Game).rnd.Next(particleExplosionSettings.minLife, particleExplosionSettings.maxLife), ((Game1)Game).rnd.Next(particleExplosionSettings.minRoundTime, particleExplosionSettings.maxRoundTime), ((Game1)Game).rnd.Next(particleExplosionSettings.minParticlesPerRound, particleExplosionSettings.maxParticlesPerRound), ((Game1)Game).rnd.Next(particleExplosionSettings.minParticles, particleExplosionSettings.maxParticles), explosionColorsTexture, particleSettings, explosionEffect)); // Collision! remove the target and the shot. pigeons.RemoveAt(i); --i; ((Game1)Game).PlayCue("Explosions"); pigeonLevel.addHit(); } } }
protected override void LoadContent() { BasicModel shotgun = new BasicModel(Game.Content.Load<Model>(@"models\shotgun")); shotgun.world = Matrix.CreateRotationZ(-(float)Math.PI / 1.8f) * Matrix.CreateRotationX(-(float)Math.PI / 2) * Matrix.CreateTranslation(-0.0f, -0.5f, 47.0f) * Matrix.CreateScale(2.0f) * ((Game1)game).camera.view; //Add models to list models.Add(shotgun); base.LoadContent(); }