private void UpdateMoleculeSetPositionByVelocity(double t) { bool isStop = true; for (int i = 0; i < MoleculeSet.Count; i++) { Molecule m = MoleculeSet[i]; bool ballIsStop = true; if (Math.Abs(m.currentVelocity.X) < e) { m.currentVelocity.X = 0; } else { ballIsStop = false; } if (Math.Abs(m.currentVelocity.Y) < e) { m.currentVelocity.Y = 0; } else { ballIsStop = false; } if (Math.Abs(m.currentVelocity.Z) < e) { m.currentVelocity.Z = 0; } else { ballIsStop = false; } if (ballIsStop) { continue; } else { isStop = false; //通过小球的速度来更新小球位置 if (m.position != m.oldPosition) { PhysicEngine.UpdatePositionByVelocity(ref m.position, ref m.oldPosition, ref m.currentVelocity, t); } CDE.UpdateToGridmap(i); //更新小球显示的位置 TranslateTransform3D temp = (TranslateTransform3D)(m.MoleculeGeometryModel.Transform); temp.OffsetX = m.position.X; temp.OffsetY = m.position.Y; temp.OffsetZ = m.position.Z; } } if (isStop) { StopGameLoop(); stick.UpdateStickPosition(new Vector3D(whiteBall.position.X, whiteBall.position.Y, whiteBall.position.Z), shotDirection); stick.Visible = true; gameWindows.SetShootDirectionAndForceFactor(); } }
public void CollisionDetection() { if (CollisionResponse != null) { foreach (int index in movingList) { Molecule m = moleculeSet[index]; //if (!m.isNeedDetected) continue; //只对运动物体碰撞检测 int x = TransferToGridX(m.position.X); int y = TransferToGridY(m.position.Y); int z = TransferToGridZ(m.position.Z); List <int> grid = gridMap[x, y, z]; //if (grid == null) continue; for (int i = ((x - 1) > 0 ? (x - 1) : 0); i <= ((x + 1) < (length - 1) ? (x + 1) : (length - 1)); i++) { for (int j = ((y - 1) > 0 ? (y - 1) : 0); j <= ((y + 1) < (width - 1) ? (y + 1) : (width - 1)); j++) { for (int k = ((z - 1) > 0 ? (z - 1) : 0); k <= ((z + 1) < (height - 1) ? (z + 1) : (height - 1)); k++) { List <int> neighborGrid = gridMap[i, j, k]; if (neighborGrid != null) { for (int l = 0; l < neighborGrid.Count; l++) { int neighborIndex = neighborGrid[l]; if (neighborIndex == index) { continue; } //if (!moleculeSet[neighborIndex].isNeedDetected) continue; //避免两个运动物体重复碰撞检测 if (Collide(index, neighborIndex)) { //moleculeSet[neighborIndex].isNeedDetected = false; //moleculeSet[index].isNeedDetected = false; CollisionResponse(index, neighborIndex); //每一帧对于每个球只跟另外的一个球进行碰撞 //goto jumpOut; } } } } } } jumpOut: { } } //foreach (int index in movingList) //{ // moleculeSet[movingList[index]].isNeedDetected = true; //} //foreach (Molecule m in moleculeSet) //{ // m.isNeedDetected = true; //} } movingList.Clear(); }
void Initializtion() { //画星空 { SphereMesh StarMesh = new SphereMesh(); StarMesh.Slices = 8; StarMesh.Stacks = 4; StarMesh.Radius = 0.6; MeshGeometry3D Star = StarMesh.Geometry; var Star3DGroup = new Model3DGroup(); Material specularMaterial = new SpecularMaterial(new SolidColorBrush(Color.FromArgb(255, 255, 255, 255)), 1024); for (int i = 0; i < 1500; i++) { //创建每个球体的GeometryModel并添加进显示窗口 MaterialGroup materialGroup = new MaterialGroup(); byte value = (byte)random.Next(150, 255); DiffuseMaterial diffuseMaterial = new DiffuseMaterial(new SolidColorBrush(Color.FromRgb(value, value, value))); materialGroup.Children.Add(diffuseMaterial); materialGroup.Children.Add(specularMaterial); var StarGeometryModel = new GeometryModel3D(Star, materialGroup); Vector3D starPosition; while (true) { double range = 300; double x = GetRandomInRange(range); double y = GetRandomInRange(range); double z = GetRandomInRange(range); if (Math.Abs(x) < Length && Math.Abs(y) < Width * 2 && Math.Abs(z) < Height * 2) { continue; } else { starPosition = new Vector3D(x, y, z); break; } } StarGeometryModel.Transform = new TranslateTransform3D(starPosition); Star3DGroup.Children.Add(StarGeometryModel); } //StarMesh.Slices = 8; //StarMesh.Stacks = 4; //StarMesh.Radius = 2; //Star = StarMesh.Geometry; //for (int i = 0; i < 500; i++) //{ // //创建每个球体的GeometryModel并添加进显示窗口 // MaterialGroup materialGroup = new MaterialGroup(); // byte value = (byte)random.Next(150, 255); // DiffuseMaterial diffuseMaterial = new DiffuseMaterial(new SolidColorBrush(Color.FromRgb(value, value, value))); // materialGroup.Children.Add(diffuseMaterial); // materialGroup.Children.Add(specularMaterial); // var StarGeometryModel = new GeometryModel3D(Star, materialGroup); // Vector3D starPosition; // while (true) // { // double range = 600; // double x = GetRandomInRange(range); // double y = GetRandomInRange(range); // double z = GetRandomInRange(range); // if (Math.Abs(x) < Length && Math.Abs(y) < Width * 1.5 && Math.Abs(z) < Height * 1.5) // { // continue; // } // else // { // starPosition = new Vector3D(x, y, z); // break; // } // } // StarGeometryModel.Transform = new TranslateTransform3D(starPosition); // Star3DGroup.Children.Add(StarGeometryModel); //} { ModelVisual3D starSetModel = new ModelVisual3D(); starSetModel.Content = Star3DGroup; gameWindows.model.Children.Add(starSetModel); } } //画球台 { BoxMesh boardMeshBase = new BoxMesh(); boardMeshBase.Width = Length; boardMeshBase.Height = Height; boardMeshBase.Depth = Width; Geometry3D boardMesh = boardMeshBase.Geometry; GeometryModel3D boardGeometryModel = new GeometryModel3D(boardMesh, null); boardGeometryModel.Material = null;//材料 ImageBrush imageBrush = new ImageBrush(); imageBrush.ImageSource = new BitmapImage(new Uri("res/board.jpg", UriKind.Relative)); //imageBrush.Viewbox = new Rect(0, 0, imageBrush.ImageSource.Width, imageBrush.ImageSource.Height); imageBrush.Viewbox = new Rect(0, 0, 100, 100); //imageBrush.TileMode = TileMode.FlipXY; imageBrush.TileMode = TileMode.Tile; imageBrush.ViewboxUnits = BrushMappingMode.Absolute; imageBrush.Viewport = new Rect(0, 0, 0.1, 0.1); MaterialGroup materialGroup = new MaterialGroup(); //materialGroup.Children.Add(new SpecularMaterial(new SolidColorBrush(Colors.Gray), 1024)); //materialGroup.Children.Add(new DiffuseMaterial(new SolidColorBrush(Colors.GreenYellow))); materialGroup.Children.Add(new DiffuseMaterial(imageBrush)); boardGeometryModel.BackMaterial = materialGroup; ModelVisual3D moleculeSetModel = new ModelVisual3D(); moleculeSetModel.Content = boardGeometryModel; gameWindows.model.Children.Add(moleculeSetModel); } gridMapOrigin = new Point3D(-0.5 * length, -0.5 * width, -0.5 * height); //画球体 { SphereMesh sphereMesh = new SphereMesh(); sphereMesh.Slices = 72 / 1; sphereMesh.Stacks = 36 / 1; sphereMesh.Radius = radius; MeshGeometry3D sphere = sphereMesh.Geometry; //用于保存所有小球的Model moleculeModel3DGroup = new Model3DGroup(); Material material = (Material)gameWindows.viewport.Resources["ER_Vector___Glossy_Yellow___MediumMR2"]; Material specularMaterial = new SpecularMaterial(new SolidColorBrush(Color.FromArgb(255, 255, 255, 255)), 1024); //定义二维数组,分别存放molelecule的数量,和x,y,z的坐标 double[,] moleculePositionSet = new double[moleculeNum, 3]; moleculePositionSet[0, 0] = 50; moleculePositionSet[0, 1] = 0; moleculePositionSet[0, 2] = 0; //layer1 begin moleculePositionSet[1, 0] = 0.0000000001; moleculePositionSet[1, 1] = 0; moleculePositionSet[1, 2] = 0; //layer2 moleculePositionSet[2, 0] = -8; moleculePositionSet[2, 1] = 4.8; moleculePositionSet[2, 2] = 0; moleculePositionSet[3, 0] = -8; moleculePositionSet[3, 1] = -2.4; moleculePositionSet[3, 2] = 4; moleculePositionSet[4, 0] = -8; moleculePositionSet[4, 1] = -2.4; moleculePositionSet[4, 2] = -4; //layer3 moleculePositionSet[5, 0] = -16; moleculePositionSet[5, 1] = 9.6; moleculePositionSet[5, 2] = 0; moleculePositionSet[6, 0] = -16; moleculePositionSet[6, 1] = 2.4; moleculePositionSet[6, 2] = 4; moleculePositionSet[7, 0] = -16; moleculePositionSet[7, 1] = 2.4; moleculePositionSet[7, 2] = -4; moleculePositionSet[8, 0] = -16; moleculePositionSet[8, 1] = -4.8; moleculePositionSet[8, 2] = 0; moleculePositionSet[9, 0] = -16; moleculePositionSet[9, 1] = -4.8; moleculePositionSet[9, 2] = 8; moleculePositionSet[10, 0] = -16; moleculePositionSet[10, 1] = -4.8; moleculePositionSet[10, 2] = -8; //layer4 begin moleculePositionSet[11, 0] = -24; moleculePositionSet[11, 1] = 14.4; moleculePositionSet[11, 2] = 0; moleculePositionSet[12, 0] = -24; moleculePositionSet[12, 1] = 7.2; moleculePositionSet[12, 2] = 4; moleculePositionSet[13, 0] = -24; moleculePositionSet[13, 1] = 7.2; moleculePositionSet[13, 2] = -4; moleculePositionSet[14, 0] = -24; moleculePositionSet[14, 1] = 0; moleculePositionSet[14, 2] = 0; moleculePositionSet[15, 0] = -24; moleculePositionSet[15, 1] = 0; moleculePositionSet[15, 2] = 8; moleculePositionSet[16, 0] = -24; moleculePositionSet[16, 1] = 0; moleculePositionSet[16, 2] = -8; moleculePositionSet[17, 0] = -24; moleculePositionSet[17, 1] = -7.2; moleculePositionSet[17, 2] = 4; moleculePositionSet[18, 0] = -24; moleculePositionSet[18, 1] = -7.2; moleculePositionSet[18, 2] = -4; moleculePositionSet[19, 0] = -24; moleculePositionSet[19, 1] = -7.2; moleculePositionSet[19, 2] = 12; moleculePositionSet[20, 0] = -24; moleculePositionSet[20, 1] = -7.2; moleculePositionSet[20, 2] = -12; for (int i = 0; (i < moleculeNum); i++) { //创建并初始化molecule的属性 Molecule molecule = new Molecule() { //position = new Point3D(GetRandomInRange(positionRange), GetRandomInRange(positionRange), GetRandomInRange(positionRange)), position = new Point3D(moleculePositionSet[i, 0], moleculePositionSet[i, 1], moleculePositionSet[i, 2]), //currentVelocity = new Vector3D(GetRandomInRange(velocityRange), GetRandomInRange(velocityRange), GetRandomInRange(velocityRange)), mass = 1, radius = radius }; //创建每个球体的GeometryModel并添加进显示窗口 MaterialGroup materialGroup = new MaterialGroup(); int R, G, B; while (true) { R = random.Next(255); G = random.Next(255); B = random.Next(255); if (R + G + B < 350) { continue; } else { break; } } DiffuseMaterial diffuseMaterial = new DiffuseMaterial(new SolidColorBrush(Color.FromRgb((byte)R, (byte)G, (byte)B))); materialGroup.Children.Add(diffuseMaterial); materialGroup.Children.Add(specularMaterial); molecule.MoleculeGeometryModel = new GeometryModel3D(sphere, materialGroup); //molecule.MoleculeGeometryModel.BackMaterial = materialGroup; molecule.MoleculeGeometryModel.Transform = new TranslateTransform3D(molecule.position.X, molecule.position.Y, molecule.position.Z); moleculeModel3DGroup.Children.Add(molecule.MoleculeGeometryModel); MoleculeSet.Add(molecule); } { ModelVisual3D moleculeSetModel = new ModelVisual3D(); moleculeSetModel.Content = moleculeModel3DGroup; gameWindows.model.Children.Add(moleculeSetModel); } //设置白球 whiteBall = MoleculeSet[0]; ((MaterialGroup)whiteBall.MoleculeGeometryModel.Material).Children[0] = new DiffuseMaterial(new SolidColorBrush(Color.FromRgb(255, 255, 255))); //Material specularMaterial = new SpecularMaterial(new SolidColorBrush(Color.FromArgb(255, 255, 255, 255)), 1024); //DiffuseMaterial white= new DiffuseMaterial(new SolidColorBrush(Color.FromRgb(255,255,255))); //whiteBall.Add(white); } //画球棍 stick.Length = 120; stick.Init(gameWindows.model, new Vector3D(whiteBall.position.X, whiteBall.position.Y, whiteBall.position.Z), shotDirection); stick.Visible = false; //初始化碰撞检测引擎 CDE.InitCollisionDetectionEngine(MoleculeSet, gridMapOrigin, length, width, height, radius * 2); CDE.CollisionResponse += delegate(int index1, int index2) { gameWindows.PlayBallCollisionSound(); gameWindows.myMediaElement.Stop(); gameWindows.myMediaElement.Play(); PhysicEngine.UpdateVelocityByCollide(MoleculeSet[index1].position, MoleculeSet[index2].position, ref MoleculeSet[index1].currentVelocity, ref MoleculeSet[index2].currentVelocity, MoleculeSet[index1].mass, MoleculeSet[index2].mass, MoleculeSet[index1].radius, MoleculeSet[index2].radius); }; CDE.CollideWithWall += delegate(int index) { Molecule m = MoleculeSet[index]; if (m.position.X < gridMapOrigin.X + m.radius) { m.position.X = gridMapOrigin.X + m.radius; m.currentVelocity.X = -m.currentVelocity.X; if (BallInHole(m)) { BallInHoleList.Add(m); gameWindows.PlayBallCollisionWithWallSound(); } else { gameWindows.PlayBallInHoleSound(); } } if (m.position.X > gridMapOrigin.X + length - m.radius) { m.position.X = gridMapOrigin.X + length - m.radius; m.currentVelocity.X = -m.currentVelocity.X; if (BallInHole(m)) { BallInHoleList.Add(m); gameWindows.PlayBallCollisionWithWallSound(); } else { gameWindows.PlayBallInHoleSound(); } } if (m.position.Y < gridMapOrigin.Y + m.radius) { m.position.Y = gridMapOrigin.Y + m.radius; m.currentVelocity.Y = -m.currentVelocity.Y; if (BallInHole(m)) { BallInHoleList.Add(m); gameWindows.PlayBallCollisionWithWallSound(); } else { gameWindows.PlayBallInHoleSound(); } } if (m.position.Y > gridMapOrigin.Y + width - m.radius) { m.position.Y = gridMapOrigin.Y + width - m.radius; m.currentVelocity.Y = -m.currentVelocity.Y; if (BallInHole(m)) { BallInHoleList.Add(m); gameWindows.PlayBallCollisionWithWallSound(); } else { gameWindows.PlayBallInHoleSound(); } } if (m.position.Z < gridMapOrigin.Z + m.radius) { m.position.Z = gridMapOrigin.Z + m.radius; m.currentVelocity.Z = -m.currentVelocity.Z; if (BallInHole(m)) { BallInHoleList.Add(m); gameWindows.PlayBallCollisionWithWallSound(); } else { gameWindows.PlayBallInHoleSound(); } } if (m.position.Z > gridMapOrigin.Z + height - m.radius) { m.position.Z = gridMapOrigin.Z + height - m.radius; m.currentVelocity.Z = -m.currentVelocity.Z; if (BallInHole(m)) { BallInHoleList.Add(m); gameWindows.PlayBallCollisionWithWallSound(); } else { gameWindows.PlayBallInHoleSound(); } } }; }