public static Minkowski_Description Minkowskize_OBB_In_Triangle(OBB obb, Triangle trig) { var ret = new Minkowski_Description(); ret.HalfAxis.X = Math.Abs(obb.Extreme_In(trig.Normals[0]).dist_in_dir_w); ret.HalfAxis.Y = Math.Abs(obb.Extreme_In(trig.Normals[1]).dist_in_dir_w); ret.HalfAxis.Z = Math.Abs(obb.Extreme_In(trig.Normals[2]).dist_in_dir_w); ret.Position_LM = obb.Position - trig.Bary_center; return ret; }
public static Minkowski_Description Minkowskize_Sphere_In_OBB(Sphere sph, OBB obb) { var ret = new Minkowski_Description(); ret.HalfAxis.X = sph.Radius; ret.Position_LM = obb.Point_W_To_L(sph.Position); return ret; }
IEnumerator Attack() { EffectObject bulletObj = PlayEffect(BulletModel, 5f); Transform bullet = bulletObj.obj.transform; Character target = GetFirstAttackTarget(); Vector3 center = target.position; attacker.LookAt(target.position); bullet.rotation = attacker.rotation; bullet.position = target.position; PlaySingAnimAndEffect(); yield return new WaitForSeconds(SingTime); // 计算技能OBB OBB verObb = new OBB(new Vector2(center.x, center.z), new Vector2(6f, 0.1f), bullet.rotation.eulerAngles.y); float rowAngle = bullet.rotation.eulerAngles.y + 90f; if (rowAngle >= 360f) rowAngle = rowAngle - 360f; OBB horObb = new OBB(new Vector2(center.x, center.z), new Vector2(6f, 0.1f), rowAngle); // 检测碰撞 List<Character> enemys = Fight.Inst.FindAllAttackTarget(attacker); float dam = Damage; ClearGeZiEffects(); float[] hitTimes = HitTimes; yield return new WaitForSeconds(hitTimes[0]); foreach (Character e in enemys) { if (e.CanBeAtk == false) continue; OBB obb = new OBB(new Vector2(e.position.x, e.position.z), new Vector2(1f, 1f), e.rotation.eulerAngles.y); if (horObb.Intersects(obb)) { CalcDamage(attacker, e, dam, 0f); PlayGeZiEffect(e.slot, e.camp); } } yield return new WaitForSeconds(hitTimes[1]); foreach (Character e in enemys) { if (e.CanBeAtk == false) continue; OBB obb = new OBB(new Vector2(e.position.x, e.position.z), new Vector2(1f, 1f), e.rotation.eulerAngles.y); if (verObb.Intersects(obb)) { CalcDamage(attacker, e, dam, 0f); PlayGeZiEffect(e.slot, e.camp); } } End(); }
public static Minkowski_Description Minkowskize_Triangle_In_OBB(Triangle trig, OBB obb) { var ret = new Minkowski_Description(); ret.HalfAxis.X = trig.Extreme_In(obb.Normal(0)).dist_in_dir_w; ret.HalfAxis.Y = trig.Extreme_In(obb.Normal(1)).dist_in_dir_w; ret.HalfAxis.Z = trig.Extreme_In(obb.Normal(2)).dist_in_dir_w; ret.HalfAxis.W = trig.Extreme_In(obb.Normal(3)).dist_in_dir_w; ret.Position_LM = obb.Point_W_To_L(trig.Bary_center); return ret; }
//--------------------------------------- // Class methods //--------------------------------------- public bool Init(Vector3 pos, Vector3 rot, float fWidth, float fHeight, float fDepth, int iLife, Color c) { m_vPosition = pos; // Base position pos.Y += fHeight; m_vRotation = rot; m_iLife = iLife; m_vSize = new Vector3(fWidth, fHeight, fDepth); m_Color = c; m_obb = new OBB(pos, new Vector3(fWidth, fHeight, fDepth), Matrix.CreateFromYawPitchRoll(rot.Y, rot.X, rot.Z)); return true; }
public static Minkowski_Description Minkowskize_OBB_In_OBB(OBB obb1, OBB obb2) { var ret = new Minkowski_Description(); var tmp = obb1.Position - obb2.Position; var res = Vector3.Transform(tmp, obb2.TOrientation); var res2 = new Vector4(); var axisxinnewcords = Vector3.Transform(obb1.Axis(0), obb2.TOrientation); var axisyinnewcords = Vector3.Transform(obb1.Axis(1), obb2.TOrientation); var xradius = obb1.HalfAxisWidth.X * Math.Abs(axisxinnewcords.X) + obb1.HalfAxisWidth.Y * Math.Abs(axisyinnewcords.X); var yradius = obb1.HalfAxisWidth.X * Math.Abs(axisxinnewcords.Y) + obb1.HalfAxisWidth.Y * Math.Abs(axisyinnewcords.Y); res2.X = xradius; res2.Y = yradius; res2.Z = 0; ret.HalfAxis = res2; ret.Position_LM = res; return ret; }
/// <summary> /// Intersection test between this OBB and another OBB /// </summary> /// <param name="b">OBB to test against</param> /// <returns>Boolean result if they intersect or not</returns> public bool Intersects(OBB b) { Matrix matB = b._rotation*InverseRotation; Vector3 vPosB = Vector3.Transform(b._center - _center, _inverseRotation); var xAxis = new Vector3(matB.M11, matB.M21, matB.M31); var yAxis = new Vector3(matB.M12, matB.M22, matB.M32); var zAxis = new Vector3(matB.M13, matB.M23, matB.M33); //15 tests //1 (Ra)x if (Math.Abs(vPosB.X) > (_bounds.X + b._bounds.X*Math.Abs(xAxis.X) + b._bounds.Y*Math.Abs(xAxis.Y) + b._bounds.Z*Math.Abs(xAxis.Z))) { return false; } //2 (Ra)y if (Math.Abs(vPosB.Y) > (_bounds.Y + b._bounds.X*Math.Abs(yAxis.X) + b._bounds.Y*Math.Abs(yAxis.Y) + b._bounds.Z*Math.Abs(yAxis.Z))) { return false; } //3 (Ra)z if (Math.Abs(vPosB.Z) > (_bounds.Z + b._bounds.X*Math.Abs(zAxis.X) + b._bounds.Y*Math.Abs(zAxis.Y) + b._bounds.Z*Math.Abs(zAxis.Z))) { return false; } //4 (Rb)x if (Math.Abs(vPosB.X*xAxis.X + vPosB.Y*yAxis.X + vPosB.Z*zAxis.X) > (b._bounds.X + _bounds.X*Math.Abs(xAxis.X) + _bounds.Y*Math.Abs(yAxis.X) + _bounds.Z*Math.Abs(zAxis.X))) { return false; } //5 (Rb)y if (Math.Abs(vPosB.X*xAxis.Y + vPosB.Y*yAxis.Y + vPosB.Z*zAxis.Y) > (b._bounds.Y + _bounds.X*Math.Abs(xAxis.Y) + _bounds.Y*Math.Abs(yAxis.Y) + _bounds.Z*Math.Abs(zAxis.Y))) { return false; } //6 (Rb)z if (Math.Abs(vPosB.X*xAxis.Z + vPosB.Y*yAxis.Z + vPosB.Z*zAxis.Z) > (b._bounds.Z + _bounds.X*Math.Abs(xAxis.Z) + _bounds.Y*Math.Abs(yAxis.Z) + _bounds.Z*Math.Abs(zAxis.Z))) { return false; } //7 (Ra)x X (Rb)x if (Math.Abs(vPosB.Z*yAxis.X - vPosB.Y*zAxis.X) > (_bounds.Y*Math.Abs(zAxis.X) + _bounds.Z*Math.Abs(yAxis.X) + b._bounds.Y*Math.Abs(xAxis.Z) + b._bounds.Z*Math.Abs(xAxis.Y))) { return false; } //8 (Ra)x X (Rb)y if (Math.Abs(vPosB.Z*yAxis.Y - vPosB.Y*zAxis.Y) > (_bounds.Y*Math.Abs(zAxis.Y) + _bounds.Z*Math.Abs(yAxis.Y) + b._bounds.X*Math.Abs(xAxis.Z) + b._bounds.Z*Math.Abs(xAxis.X))) { return false; } //9 (Ra)x X (Rb)z if (Math.Abs(vPosB.Z*yAxis.Z - vPosB.Y*zAxis.Z) > (_bounds.Y*Math.Abs(zAxis.Z) + _bounds.Z*Math.Abs(yAxis.Z) + b._bounds.X*Math.Abs(xAxis.Y) + b._bounds.Y*Math.Abs(xAxis.X))) { return false; } //10 (Ra)y X (Rb)x if (Math.Abs(vPosB.X*zAxis.X - vPosB.Z*xAxis.X) > (_bounds.X*Math.Abs(zAxis.X) + _bounds.Z*Math.Abs(xAxis.X) + b._bounds.Y*Math.Abs(yAxis.Z) + b._bounds.Z*Math.Abs(yAxis.Y))) { return false; } //11 (Ra)y X (Rb)y if (Math.Abs(vPosB.X*zAxis.Y - vPosB.Z*xAxis.Y) > (_bounds.X*Math.Abs(zAxis.Y) + _bounds.Z*Math.Abs(xAxis.Y) + b._bounds.X*Math.Abs(yAxis.Z) + b._bounds.Z*Math.Abs(yAxis.X))) { return false; } //12 (Ra)y X (Rb)z if (Math.Abs(vPosB.X*zAxis.Z - vPosB.Z*xAxis.Z) > (_bounds.X*Math.Abs(zAxis.Z) + _bounds.Z*Math.Abs(xAxis.Z) + b._bounds.X*Math.Abs(yAxis.Y) + b._bounds.Y*Math.Abs(yAxis.X))) { return false; } //13 (Ra)z X (Rb)x if (Math.Abs(vPosB.Y*xAxis.X - vPosB.X*yAxis.X) > (_bounds.X*Math.Abs(yAxis.X) + _bounds.Y*Math.Abs(xAxis.X) + b._bounds.Y*Math.Abs(zAxis.Z) + b._bounds.Z*Math.Abs(zAxis.Y))) { return false; } //14 (Ra)z X (Rb)y if (Math.Abs(vPosB.Y*xAxis.Y - vPosB.X*yAxis.Y) > (_bounds.X*Math.Abs(yAxis.Y) + _bounds.Y*Math.Abs(xAxis.Y) + b._bounds.X*Math.Abs(zAxis.Z) + b._bounds.Z*Math.Abs(zAxis.X))) { return false; } //15 (Ra)z X (Rb)z if (Math.Abs(vPosB.Y*xAxis.Z - vPosB.X*yAxis.Z) > (_bounds.X*Math.Abs(yAxis.Z) + _bounds.Y*Math.Abs(xAxis.Z) + b._bounds.X*Math.Abs(zAxis.Y) + b._bounds.Y*Math.Abs(zAxis.X))) { return false; } return true; }
public bool Intersects(OBB target) { return(target.Contains(this.ClosestPoint(target.position))); }
//UNUSED?? public static bool TestPlaneOBB(Plane_ p, OBB obb) { Stats.TestPlaneOBB++; return true; var nor = p.Normal; var minradius = obb.HalfAxisWidth.X * (Math.Abs(Vector3.Dot(nor, obb.Axis(0))) + obb.HalfAxisWidth.Y * Math.Abs(Vector3.Dot(nor, obb.Axis(1)))); return Vector3.Dot(obb.Position, p.Normal) < p.dist + minradius + 0.01f; return true; }
public static Geometry.Ray_Test_Result TestOBBLine(OBB obb, LineSegment ls, Geometry.Ray_Test_Mode mode) { var result = new Geometry.Ray_Test_Result(); var pos2 = obb.Point_W_To_L(ls.end); var pos1 = obb.Point_W_To_L(ls.start); var dir = pos2 - pos1; if (Math.Abs(dir.X) < 0.01f) { if (Math.Abs(pos1.X) > obb.HalfAxisWidth.X) { result.Did_It_Hit = false; return result; } } var tleftx = (-obb.HalfAxisWidth.X - pos1.X) / dir.X; var trightx = (obb.HalfAxisWidth.X - pos1.X) / dir.X; var tenterx = tleftx < trightx ? tleftx : trightx; var texitx = tleftx < trightx ? trightx : tleftx; if (Math.Abs(dir.Y) < 0.01f) { if (Math.Abs(pos1.Y) > obb.HalfAxisWidth.Y) { result.Did_It_Hit = false; return result; } } var tlefty = (-obb.HalfAxisWidth.Y - pos1.Y) / dir.Y; var trighty = (obb.HalfAxisWidth.Y - pos1.Y) / dir.Y; var tentery = tlefty < trighty ? tlefty : trighty; var texity = tlefty < trighty ? trighty : tlefty; var tmaxmin = tentery > tenterx ? tentery : tenterx; var tminmax = texity < texitx ? texity : texitx; result.enter = tmaxmin; result.exit = tminmax; switch (mode) { case Geometry.Ray_Test_Mode.Line: result.Did_It_Hit = (tmaxmin < tminmax); break; case Geometry.Ray_Test_Mode.Ray: result.Did_It_Hit = (tmaxmin < tminmax) && (tmaxmin >= 0); break; case Geometry.Ray_Test_Mode.Segment: result.Did_It_Hit = (tmaxmin < tminmax) && (tmaxmin >= 0) && (tmaxmin <= 1); break; } return result; }
public static bool IntersectOBBTriangle(OBB obb, Triangle trig, ref Geometry.Geometric_Queries.Distance_Query_Result result) { var minked_tri = Minkowski.Minkowskize_Triangle_In_OBB(trig, obb); var minked_obb = Minkowski.Minkowskize_OBB_In_Triangle(obb, trig); var tr_from_obb = obb.What_Faces(minked_tri); var obb_from_tr = trig.What_Faces(minked_obb); if (Math.Max(tr_from_obb.Signed_Dist, obb_from_tr.Signed_Dist) > 0.0f) return false; //pernoume os normal owning afto pou exei to allo pio exo bool normal_owning_tr = obb_from_tr.Signed_Dist>tr_from_obb.Signed_Dist; if (normal_owning_tr) { result = new Geometry.Geometric_Queries.Distance_Query_Result(); result.first_has_normal = !normal_owning_tr; result.Normal_W = trig.Normals[obb_from_tr.Normal_Code]; var Extreme_Point_In_Normal_Of_Body_1 = trig.Points[obb_from_tr.Normal_Code]-Intersection_Grid.current_pair_element_2.Rigid.Position; var Extreme_Point_In_Normal_Of_Body_2 = obb.Vertex(obb.Extreme_In(-result.Normal_W).code)-obb.Position; result.signed_distance = obb_from_tr.Signed_Dist; result.double_contact = false; result.Point_W_0 = Extreme_Point_In_Normal_Of_Body_2+obb.Position; } else { result = new Geometry.Geometric_Queries.Distance_Query_Result(); result.first_has_normal = !normal_owning_tr; result.Normal_W = obb.Normal(tr_from_obb.Normal_Code); var Extreme_Point_In_Normal_Of_Body_1 = obb.Vertex(tr_from_obb.Normal_Code)-obb.parent_tmp.Position; var Extreme_Point_In_Normal_Of_Body_2 = trig.Points[(trig.Extreme_In(-result.Normal_W).code)] - Intersection_Grid.current_pair_element_2.Rigid.Position; result.signed_distance = tr_from_obb.Signed_Dist; result.Point_W_0 = Extreme_Point_In_Normal_Of_Body_2+Intersection_Grid.current_pair_element_2.Rigid.Position; } return true; }
// Use this for initialization void Start() { obb = new OBB(transform, mode); box = obb; }
protected abstract bool Check(Vector3 position, Quaternion rotation, OBB test, int mask = -1);
bool intersectTest(OBB b) { //this is a trial at rewriting this class to use my own math libraies Fixed3x3 R = new Fixed3x3(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { R.v[i, j] = vector.dot(axis[i], b.axis[j]); } } IntersectData data = new IntersectData(); return(true); // Matrix<float> C = axis.Transpose() * b.axis; // Vector<float> D = pos - b.pos;//Difference of centers // //Check all 15 possible collision vectors // // All checks are derived from the table on pg 7 of https://www.geometrictools.com/Documentation/DynamicCollisionDetection.pdf // // For Vector A0 // if ( // extents[0] + //R0 // ((b.extents[0] * System.Math.Abs(C[0, 0])) //R1 // + (b.extents[1] * System.Math.Abs(C[0,1])) // + (b.extents[2] * System.Math.Abs(C[0,2]))) // > // System.Math.Abs( axis.Row(0).DotProduct(D))) //R //R // { // return true; // } // // For vector A1 // if ( // extents[1] + //R0 // ((b.extents[0] * System.Math.Abs(C[1, 0])) //R1 // + (b.extents[1] * System.Math.Abs(C[1, 1])) // + (b.extents[2] * System.Math.Abs(C[1, 2]))) // > // System.Math.Abs(axis.Row(1).DotProduct(D))) //R //R // { // return true; // } // // For vector A2 // if ( // extents[2] + //R0 // ((b.extents[0] * System.Math.Abs(C[2, 0])) //R1 // + (b.extents[1] * System.Math.Abs(C[2, 1])) // + (b.extents[2] * System.Math.Abs(C[2, 2]))) // > //System.Math.Abs(axis.Row(2).DotProduct(D))) //R //R // { // return true; // } // // For vector B0 // if ( // b.extents[0] + //R0 // ((extents[0] * System.Math.Abs(C[0, 0])) //R1 // + (extents[1] * System.Math.Abs(C[1, 0])) // + (extents[2] * System.Math.Abs(C[2, 0]))) // > // System.Math.Abs(b.axis.Row(0).DotProduct(D))) //R // { // return true; // } // // For vector B1 // if ( // b.extents[1] + //R0 // ((extents[0] * System.Math.Abs(C[0, 1])) //R1 // + (extents[1] * System.Math.Abs(C[1, 1])) // + (extents[2] * System.Math.Abs(C[2, 1]))) // > // System.Math.Abs(b.axis.Row(1).DotProduct(D))) //R //R // { // return true; // } // // For vector B2 // if (b.extents[2] + //R0 // ((extents[0] * System.Math.Abs(C[0, 2])) //R1 // + (extents[1] * System.Math.Abs(C[1, 2])) // + (extents[2] * System.Math.Abs(C[2, 2]))) // > // System.Math.Abs(b.axis.Row(0).DotProduct(D))) //R //R // { // return true; // } // // For vector A0 X B0 // if( // (extents[1]* System.Math.Abs(C[2,0])) // + (extents[2] * System.Math.Abs(C[1, 0])) // + (b.extents[1] * System.Math.Abs(C[0, 2])) // + (b.extents[2] * System.Math.Abs(C[0, 1])) // > // System.Math.Abs( // C[1,0] * axis.Row(2).DotProduct(D) // - C[2, 0] * axis.Row(1).DotProduct(D) // ) // ) // { // return true; // } // // For vector A0 X B1 // if ( // (extents[1] * System.Math.Abs(C[2, 1])) // + (extents[2] * System.Math.Abs(C[1, 1])) // + (b.extents[0] * System.Math.Abs(C[0, 2])) // + (b.extents[2] * System.Math.Abs(C[0, 0])) // > // System.Math.Abs( // C[1, 1] * axis.Row(2).DotProduct(D) // - C[2, 1] * axis.Row(1).DotProduct(D) // ) // ) // { // return true; // } // // For vector A0 X B2 // if ( // (extents[1] * System.Math.Abs(C[2, 2])) // + (extents[2] * System.Math.Abs(C[1, 2])) // + (b.extents[0] * System.Math.Abs(C[0, 1])) // + (b.extents[1] * System.Math.Abs(C[0, 0])) // > // System.Math.Abs( // C[1, 2] * axis.Row(2).DotProduct(D) // - C[2, 2] * axis.Row(1).DotProduct(D) // ) // ) // { // return true; // } // // For vector A1 X B0 // if ( // (extents[0] * System.Math.Abs(C[2, 0])) // + (extents[2] * System.Math.Abs(C[0, 0])) // + (b.extents[1] * System.Math.Abs(C[1, 2])) // + (b.extents[2] * System.Math.Abs(C[1, 0])) // > // System.Math.Abs( // C[2, 0] * axis.Row(0).DotProduct(D) // - C[0, 0] * axis.Row(2).DotProduct(D) // ) // ) // { // return true; // } // // For vector A1 X B1 // if ( // (extents[0] * System.Math.Abs(C[2, 1])) // + (extents[2] * System.Math.Abs(C[0, 1])) // + (b.extents[0] * System.Math.Abs(C[1, 2])) // + (b.extents[2] * System.Math.Abs(C[1, 0])) // > // System.Math.Abs( // C[2, 1] * axis.Row(0).DotProduct(D) // - C[0, 1] * axis.Row(2).DotProduct(D) // ) // ) // { // return true; // } // // For vector A1 X B2 // if ( // (extents[0] * System.Math.Abs(C[2, 2])) // + (extents[2] * System.Math.Abs(C[0, 2])) // + (b.extents[0] * System.Math.Abs(C[0, 2])) // + (b.extents[1] * System.Math.Abs(C[1, 0])) // > // System.Math.Abs( // C[2, 2] * axis.Row(0).DotProduct(D) // - C[0, 2] * axis.Row(2).DotProduct(D) // ) // ) // { // return true; // } // // For vector A2 X B0 // if ( // (extents[0] * System.Math.Abs(C[1, 1])) // + (extents[1] * System.Math.Abs(C[0, 1])) // + (b.extents[1] * System.Math.Abs(C[2, 2])) // + (b.extents[2] * System.Math.Abs(C[2, 1])) // > // System.Math.Abs( // C[0, 0] * axis.Row(1).DotProduct(D) // - C[1, 0] * axis.Row(0).DotProduct(D) // ) // ) // { // return true; // } // // For vector A2 X B1 // if ( // (extents[0] * System.Math.Abs(C[1, 1])) // + (extents[1] * System.Math.Abs(C[0, 1])) // + (b.extents[0] * System.Math.Abs(C[2, 2])) // + (b.extents[2] * System.Math.Abs(C[2, 0])) // > // System.Math.Abs( // C[0, 1] * axis.Row(1).DotProduct(D) // - C[1, 1] * axis.Row(0).DotProduct(D) // ) // ) // { // return true; // } // // For vector A2 X B2 // if ( // (extents[0] * System.Math.Abs(C[1, 2])) // + (extents[1] * System.Math.Abs(C[0, 2])) // + (b.extents[0] * System.Math.Abs(C[2, 1])) // + (b.extents[1] * System.Math.Abs(C[2, 0])) // > // System.Math.Abs( // C[0, 2] * axis.Row(1).DotProduct(D) // - C[1, 2] * axis.Row(0).DotProduct(D) // ) // ) // { // return true; // } // return false; }
void rayMarch2(inter_point inter_p, float _step_size, float max_distance, int _max_steps, OBB _obb, Vector3 cam_pos) { //z-plane alignment bool use_object = true; Vector3 p0 = inter_p.p0_world; Vector3 p1 = inter_p.p1_world; Vector3 cam = cam_pos; Vector3 z_step = new Vector3(0, 0, max_distance / _max_steps); if (use_object) { p0 = inter_p.p0_object; p1 = inter_p.p1_object; cam = _obb.w2o.MultiplyPoint3x4(cam); // print ("cam in object poistion :" + cam); z_step = _obb.w2o.MultiplyVector(z_step); } //the plane alignment should be calculated on cam pos as origin Vector3 p0_c = p0 - cam; Vector3 z_dir = z_step.normalized; //step on p0-p1 align z Vector3 p_step = p0_c * Vector3.Dot(z_step, z_dir) / Vector3.Dot(p0_c, z_dir); Vector3 p0_z_pro = Vector3.Dot(p0_c, z_dir) * z_dir; float scale_p0 = Vector3.Dot(p0_z_pro, z_dir); float scale_z_step = Vector3.Dot(z_step, z_dir); int scale_p0_z_step = (int)(scale_p0 / scale_z_step); Vector3 z_plane = scale_p0_z_step * z_step; Vector3 p0_new = (int)(scale_p0_z_step) * scale_z_step / scale_p0 * p0_c + cam; int full_step = (int)((p1 - p0).magnitude / p_step.magnitude); for (int i = 0; i < full_step + 1; i++) { Vector3 pos = p0_new + i * p_step; Color c = sample3dTexture(pos); //debug cubes if (dcube_created == false) { // print("pos :" + pos ); // print("color :" + c); DCube pd_t = pool.getDCube(); pd_t.position = use_object ? _obb.o2w.MultiplyPoint3x4(pos) : pos; pd_t.color = c; } } }
void rayMarch(inter_point inter_p, float _step_size, float max_distance, int _max_steps, OBB _obb) { int full_step_w = (int)((inter_p.p1_world - inter_p.p0_world).magnitude / max_distance * _max_steps); // print("_obb.w2o : "+_obb.w2o); // print ("full_step_w :" +full_step_w ); //ray marching in obj for (int i = 0; i < full_step_w; i++) { //object space ab Vector3 full_ray = inter_p.p1_world - inter_p.p0_world; Debug.DrawLine(inter_p.p0_world, inter_p.p1_world, Color.red); // print("full_step_w :" + full_step_w); Vector3 stop_p = inter_p.p0_world + full_ray / full_step_w * i; } }
IEnumerator Attack() { EffectObject bulletObj = PlayEffect(BulletModel, 5f); Transform bullet = bulletObj.obj.transform; Character target = GetFirstAttackTarget(); Vector3 center = target.position; attacker.LookAt(target.position); bullet.rotation = attacker.rotation; bullet.position = target.position; PlaySingAnimAndEffect(); yield return(new WaitForSeconds(SingTime)); // 计算技能OBB OBB verObb = new OBB(new Vector2(center.x, center.z), new Vector2(6f, 0.1f), bullet.rotation.eulerAngles.y); float rowAngle = bullet.rotation.eulerAngles.y + 90f; if (rowAngle >= 360f) { rowAngle = rowAngle - 360f; } OBB horObb = new OBB(new Vector2(center.x, center.z), new Vector2(6f, 0.1f), rowAngle); // 检测碰撞 List <Character> enemys = Fight.Inst.FindAllAttackTarget(attacker); float dam = Damage; ClearGeZiEffects(); float[] hitTimes = HitTimes; yield return(new WaitForSeconds(hitTimes[0])); foreach (Character e in enemys) { if (e.CanBeAtk == false) { continue; } OBB obb = new OBB(new Vector2(e.position.x, e.position.z), new Vector2(1f, 1f), e.rotation.eulerAngles.y); if (horObb.Intersects(obb)) { CalcDamage(attacker, e, dam, 0f); PlayGeZiEffect(e.slot, e.camp); } } yield return(new WaitForSeconds(hitTimes[1])); foreach (Character e in enemys) { if (e.CanBeAtk == false) { continue; } OBB obb = new OBB(new Vector2(e.position.x, e.position.z), new Vector2(1f, 1f), e.rotation.eulerAngles.y); if (verObb.Intersects(obb)) { CalcDamage(attacker, e, dam, 0f); PlayGeZiEffect(e.slot, e.camp); } } End(); }
public abstract bool Collide(OBB box);
// TO DO protected override bool TestCollisionVsOBB(OBB other, out Collision collision) { collision = null; // Code from Michael Zheng and Ben Strong, using with permission //Transform this into others space and do AABB vs OBB //transform other into this space and do AABB vs OBB //If both tests pass, collision occurs otherwise no collision //1. do AABB check with this rotated around other //2. find all corner points of this box using length and height //3. rotate the points of this box with its rotation //4. transform the points using the transform inverse of the other //5. min = (min(x of all points), min(y of all points)) //6. max = (max(x of all points), max(y of all points) //7. create max and min extents of other particle //8. max = (center.x + length/2, center.y + height/2) //9. min = (center.x - length/2, center.y - height/2) //10. check if this_max.x > other_min.x and this_max.y > other_min.y //11. check if other_max.x > this_min.x and other_max.y > this_min.y //12. do AABB check with other rotated around this //13. find all corner points of other box using length and height //14. rotate the points of other box with its rotation //15. transform the points using the transform inverse of this //16. min = (min(x of all points), min(y of all points)) //17. max = (max(x of all points), max(y of all points) //18. create max and min extents of this particle //19. max = (center.x + length/2, center.y + height/2) //20. min = (center.x - length/2, center.y - height/2) //21. check if this_max.x > other_min.x and this_max.y > other_min.y //22. check if other_max.x > this_min.x and other_max.y > this_min.y bool check1, check2; Vector3 thisMax, thisMin, otherMax, otherMin; Vector3 p1, p2, p3, p4; Vector3 otherPosition = other.particle.position; float thisLength = halfWidths[0]; float thisHeight = halfWidths[1]; float thisDepth = halfWidths[2]; float otherLength = other.halfWidths[0]; float otherHeight = other.halfWidths[1]; float otherDepth = halfWidths[2]; //get all corner points and then rotate it p1 = transform.worldToLocalMatrix * (new Vector3(thisLength, thisHeight)); p2 = transform.worldToLocalMatrix * (new Vector3(thisLength, -thisHeight)); p3 = transform.worldToLocalMatrix * (new Vector3(-thisLength, -thisHeight)); p4 = transform.worldToLocalMatrix * (new Vector3(-thisLength, thisHeight)); //for each corner, move it relative to the box then transform by the world matrix inverse. Finally add position back p1 = other.transform.worldToLocalMatrix * (p1 + particle.position - otherPosition); p2 = other.transform.worldToLocalMatrix * (p2 + particle.position - otherPosition); p3 = other.transform.worldToLocalMatrix * (p3 + particle.position - otherPosition); p4 = other.transform.worldToLocalMatrix * (p4 + particle.position - otherPosition); p1 += otherPosition; p2 += otherPosition; p3 += otherPosition; p4 += otherPosition; thisMax = new Vector3(Mathf.Max(p1.x, p2.x, p3.x, p4.x), Mathf.Max(p1.y, p2.y, p3.y, p4.y), Mathf.Max(p1.z, p2.z, p3.z, p4.z)); thisMin = new Vector3(Mathf.Min(p1.x, p2.x, p3.x, p4.x), Mathf.Min(p1.y, p2.y, p3.y, p4.y), Mathf.Max(p1.z, p2.z, p3.z, p4.z)); otherMax = new Vector3(otherPosition.x + otherLength, otherPosition.y + otherHeight); otherMin = new Vector3(otherPosition.x - otherLength, otherPosition.y - otherHeight); check1 = (thisMax.x >= otherMin.x && thisMax.y >= otherMin.y) && (otherMax.x >= thisMin.x && otherMax.y >= thisMin.y); if (!check1) { return(false); } //get all corner points and then rotate it p1 = other.transform.worldToLocalMatrix * (new Vector3(otherLength, otherHeight)); p2 = other.transform.worldToLocalMatrix * (new Vector3(otherLength, -otherHeight)); p3 = other.transform.worldToLocalMatrix * (new Vector3(-otherLength, -otherHeight)); p4 = other.transform.worldToLocalMatrix * (new Vector3(-otherLength, otherHeight)); //for each corner, move it relative to the box then transform by the world matrix inverse. Finally add position back p1 = transform.worldToLocalMatrix * (p1 + otherPosition - particle.position); //this p2 = transform.worldToLocalMatrix * (p2 + otherPosition - particle.position); p3 = transform.worldToLocalMatrix * (p3 + otherPosition - particle.position); p4 = transform.worldToLocalMatrix * (p4 + otherPosition - particle.position); p1 += particle.position; p2 += particle.position; p3 += particle.position; p4 += particle.position; otherMax = new Vector3(Mathf.Max(p1.x, p2.x, p3.x, p4.x), Mathf.Max(p1.y, p2.y, p3.y, p4.y)); otherMin = new Vector3(Mathf.Min(p1.x, p2.x, p3.x, p4.x), Mathf.Min(p1.y, p2.y, p3.y, p4.y)); thisMax = new Vector3(particle.position.x + thisLength, particle.position.y + thisHeight); thisMin = new Vector3(particle.position.x - thisLength, particle.position.y - thisHeight); check2 = (thisMax.x >= otherMin.x && thisMax.y >= otherMin.y) && (otherMax.x >= thisMin.x && otherMax.y >= thisMin.y); if (!check2) { return(false); } return(true); }
public static void DrawBox(OBB box, Color color, float duration = 0f) { }
// OBB (Oriented Bounding Box) collision (oriented rectangles) public static bool OBBCollision(OBB r1, OBB r2) { // Check AABB then do a SAT return(AABBFromOBBCollision(r1, r2) && RectangleSATCollision(r1, r2)); }
public static bool Check(Vector3 position, Quaternion rotation, DeployVolume[] volumes, OBB test, int mask = -1) { for (int i = 0; i < (int)volumes.Length; i++) { if (volumes[i].Check(position, rotation, test, mask)) { return(true); } } return(false); }
protected abstract bool TestCollisionVsOBB(OBB other, out Collision collision);
public OrientedRect(Box2 bbox, OBB obb) : this() { BBox = bbox; OBBox = obb; }
//*************************************************** //INTERSECTIONS public static bool IntersectOBBOBB(OBB obb1, OBB obb2, ref Geometry.Geometric_Queries.Distance_Query_Result result) { var mink2 = Minkowski.Minkowskize_OBB_In_OBB(obb2, obb1); var mink1 = Minkowski.Minkowskize_OBB_In_OBB(obb1, obb2); var dist_of_2_from_1 = obb1.What_Faces(mink2); var dist_of_1_from_2 = obb2.What_Faces(mink1); if (Math.Max(dist_of_1_from_2.Signed_Dist, dist_of_2_from_1.Signed_Dist) > 0) return false; Minkowski_Description mink; Facing_Point_Result data; //pernoume os normal owning afto pou exei to allo pio exo bool normal_owning_first = dist_of_2_from_1.Signed_Dist > dist_of_1_from_2.Signed_Dist; var normal_owning_obb = (normal_owning_first) ? obb1 : obb2; var selected_obb = (!normal_owning_first) ? obb1 : obb2; mink = (normal_owning_first) ? mink2 : mink1; data = (normal_owning_first) ? dist_of_2_from_1 : dist_of_1_from_2; Vector3 p0; Vector3 p1; float d_0, d_1; var normal = normal_owning_obb.Normal(data.Normal_Code); OBB.Extraction_of_inner_contact_points2(normal_owning_obb, selected_obb, normal, data.Normal_Code,out p0, out p1, out d_0, out d_1 ); var test = p0 - p1; result = new Geometry.Geometric_Queries.Distance_Query_Result(); result.first_has_normal = normal_owning_first; result.Normal_W = normal; result.signed_distance = normal_owning_first ? dist_of_2_from_1.Signed_Dist : dist_of_1_from_2.Signed_Dist; result.double_contact = (Math.Abs(d_1-d_0) < 0.3f); GELib.Debug.Debug_Drawing.double_edge = result.double_contact; result.Point_W_0 = p0; result.Point_W_1 = p1; return true; }
void TestCollide() { Vector2 v1 = Collide.GetVector(55); Vector2d v2 = FPCollide.GetVector(55); Debug.Log("GetVector V1:" + v1 + " V2:" + v2.ToString()); float f1 = Collide.GetAngle(new Vector2(0.4f, 0.6f)); FixedPoint f2 = FPCollide.GetAngle(new Vector2d(0.4f * 10, 0.6f * 10)); Debug.Log("GetAngle f1:" + f1 + " f2:" + f2.value); Vector2 rv1 = Collide.Rotate(new Vector2(0.1f, 0.8f), 60); Vector2d rv2 = FPCollide.Rotate(new Vector2d(0.1f, 0.8f), 60); Debug.Log("Rotate rv1:" + rv1 + " rv2:" + rv2); Sphere s1; s1.r = 1; s1.c = new Vector2(0, 0); Sphere s2; s2.r = 1; s2.c = new Vector2(1.9f, 0); bool bTrue = Collide.bSphereSphere(s1, s2); Debug.Log("bSphereSphere : " + bTrue); FPSphere s11; s11.r = new FixedPoint(1); s11.c = new Vector2d(0, 0); FPSphere s22; s22.r = new FixedPoint(1); s22.c = new Vector2d(1.9f, 0); bTrue = FPCollide.bSphereSphere(s11, s22); Debug.Log("FP bSphereSphere : " + bTrue); OBB obb = new OBB(new Vector2(3, 2.2f), new Vector2(2.4f, 1), 50); Vector2 vec1 = Collide.ClosestPointOBB(new Vector2(1, 2.4f), obb); FPObb fpObb = new FPObb(new Vector2d(3, 2.2f), new Vector2d(2.4f, 1), 50); Vector2d vec2 = FPCollide.ClosestPointOBB(new Vector2d(1, 2.4f), fpObb); Debug.Log("ClosestPointOBB vec1" + vec1 + " vec2:" + vec2); Sector sec; sec.pos = new Vector2(0, 0); sec.angle = 90; sec.dir = new Vector2(0, 1); sec.r = 1; bool bInside = Collide.bSectorInside(sec, new Vector2(0, 0.1f)); FPSector sec1; sec1.pos = new Vector2d(0, 0); sec1.angle = new FixedPoint(90); sec1.dir = new Vector2d(0, 1); sec1.r = new FixedPoint(1); bool bInside1 = FPCollide.bSectorInside(sec1, new Vector2d(0, 0.1f)); Debug.Log("bSectorInside 1:" + bInside + " 2:" + bInside1); }
public static bool IntersectSphereOBB(Sphere s1, OBB obb, ref Geometry.Geometric_Queries.Distance_Query_Result result) { var closer = obb.Closest_W_Point_On_OBB_To(s1.Position, 0); var res = s1.What_Faces(closer); if (res.Signed_Dist>0.1f) return false; result = new Geometry.Geometric_Queries.Distance_Query_Result(); var Extreme_Point_In_Normal_Of_Body_2 = closer; var Extreme_Point_In_Normal_Of_Body_1 = s1.Radius * res.Normal; result.signed_distance = res.Signed_Dist; result.first_has_normal = true; result.double_contact = false; result.Point_W_0 = closer; result.Normal_W = res.Normal; return true; }
//// Si le vecteur A-B rentre en collision avec un axe de shape, retourne le point de collision et sa normale //public static Vector3[] GetNormalAndClosestPoint(Shape shape, Vector3 a, Vector3 b) { // List<Vector3> points = new List<Vector3>(); // List<int> pointsindex = new List<int>(); // List<Vector3> normals = new List<Vector3>(); // Vector3 vec; // Vector3 oternormal; // Vector3 veclol; // Vector3 veclol1; // for (int i = 0; i < shape.worldvertices_.Length - 1; i++) { // vec = new Vector3(); // veclol = new Vector3(shape.worldvertices_[i + 1].x, shape.worldvertices_[i + 1].y, shape.worldvertices_[i + 1].z); // veclol1 = new Vector3(shape.worldvertices_[i].x, shape.worldvertices_[i].y, shape.worldvertices_[i].z); // normals.Add((Vector3.Cross(veclol - veclol1, Vector3.forward)).normalized); // if (SegmentIntersect(shape.worldvertices_[i], shape.worldvertices_[i + 1], a, b, ref vec)) { // points.Add(vec); // pointsindex.Add(i); // } // } // vec = new Vector3(); // veclol = new Vector3(shape.worldvertices_[shape.worldvertices_.Length - 1].x, shape.worldvertices_[shape.worldvertices_.Length - 1].y, shape.worldvertices_[shape.worldvertices_.Length - 1].z); // veclol1 = new Vector3(shape.worldvertices_[0].x, shape.worldvertices_[0].y, shape.worldvertices_[0].z); // normals.Add((Vector3.Cross(veclol1 - veclol, Vector3.forward)).normalized); // if (SegmentIntersect(shape.worldvertices_[shape.worldvertices_.Length - 1], shape.worldvertices_[0], a, b, ref vec)) { // points.Add(vec); // pointsindex.Add(shape.worldvertices_.Length - 1); // } // float min = 9999999999999999999.0f; // int indexmin = 0; // for (int i = 0; i < points.Count; i++) { // if ((points[i] - a).magnitude < min) { // indexmin = i; // min = (points[i] - a).magnitude; // } // } // int index = pointsindex[indexmin]; // oternormal = normals[index] * -1.0f; // //if ((points[indexmin] + oternormal).magnitude < (points[indexmin] + normals[index]).magnitude) { // // Debug.Log("f**k YOU"); // // normals[index] = oternormal; // //} // Vector3[] returnvec = new Vector3[2]; // returnvec[0] = points[indexmin]; // returnvec[1] = normals[index]; // return returnvec; //} //public static Vector3 GetClosetPoint(Shape shape, Vector3 a, Vector3 b) { // List<Vector3> points = new List<Vector3>(); // Vector3 vec; // for (int i = 0; i < shape.worldvertices_.Length - 1; i++) { // vec = new Vector3(); // if (SegmentIntersect(shape.worldvertices_[i], shape.worldvertices_[i + 1], a, b, ref vec)) { // points.Add(vec); // } // } // vec = new Vector3(); // if (SegmentIntersect(shape.worldvertices_[shape.worldvertices_.Length - 1], shape.worldvertices_[0], a, b, ref vec)) { // points.Add(vec); // } // float min = 9999999999999999999.0f; // int indexmin = 0; // for (int i = 0; i < points.Count; i++) { // if ((points[i] - a).magnitude < min) { // indexmin = i; // min = (points[i] - a).magnitude; // } // } // return points[indexmin]; //} //public static bool Intersect(Shape shape1, Shape shape2) { // if (shape1.type_ == ShapeType.POLYGON && shape2.type_ == ShapeType.POLYGON) { // return IntersectPolygons(shape1, shape2); // } else if (shape1.type_ == ShapeType.CIRCLE && shape2.type_ == ShapeType.CIRCLE) { // return IntersectCircles((Circle)shape1, (Circle)shape2); // } else if (shape1.type_ == ShapeType.CIRCLE) { // return IntersectPolygonCircle(shape2, (Circle)(shape1)); // } else if (shape2.type_ == ShapeType.CIRCLE) { // return IntersectPolygonCircle(shape1, (Circle)(shape2)); // } // return false; //} public static bool Intersect3DShapeShere(OBB box, Vector3 position, float radius) { // On récupère le sommet le plus proche du cercle float min = 99999999999999.0f; Shape shape1 = box.GetShape(); //for (int i = 0; i < shape1.vertices_.Length; i++) { // Vector3 vec = shape1.vertices_[i] - position; // if (vec.Length() < min) { // minindex = i; // min = vec.Length(); // } //} Vector3 closestpoint = GetClosestPointInOBB(box, position); Vector3 circleaxis = position - closestpoint; // Affiche le closest point // DirectxApplication.Instance.primitiverenderer_.AddPrimitive(new T3DPoint(closestpoint, 0.1f, Color.Purple)); // Console.WriteLine("circleaxis " + circleaxis + " sphere position " + position + " closest v " + shape1.vertices_[minindex]); // J'ai aucune idée du pourquoi mais il faut faire le cross product entre les // axes de séparations des 2 formes //Vector3[] crossaxes = new Vector3[shape1.axes_.Length * 1]; //for (int i = 0; i < shape1.axes_.Length; i++) { // crossaxes[i] = Vector3.Cross(shape1.axes_[i], circleaxis); //} circleaxis.Normalize(); Vector3[] axes = new Vector3[shape1.axes_.Length + 1]; shape1.axes_.CopyTo(axes, 0); //crossaxes.CopyTo(axes, shape1.axes_.Length); axes[axes.Length - 1] = circleaxis; // On récupére les 2 sommets qui travers le cercle Vector3[] circlevertices; Shape shapecircle = new Shape();; for (int i = 0; i < axes.Length; i++) { circlevertices = new Vector3[2]; circlevertices[0] = position + axes[i] * radius; circlevertices[1] = position - axes[i] * radius; shapecircle = new Shape(circlevertices, null); Vector3 proj1 = ProjectShape(shape1, axes[i]); Vector3 proj2 = ProjectShape(shapecircle, axes[i]); if (!Overlap(proj1.X, proj1.Y, proj2.X, proj2.Y)) { return(false); } else { float overlapvalue = GetOverlap(proj1.X, proj1.Y, proj2.X, proj2.Y); //if (overlapvalue < smallestmagnitude) { // smallestmagnitude = overlapvalue; // smallestaxis = shapeaxis[i]; //} } } return(true); }
public static bool TestOBBOBB(OBB obb1, OBB obb2) { var mink1 = Minkowski.Minkowskize_OBB_In_OBB(obb2, obb1); var x1width = obb1.HalfAxisWidth.X + mink1.HalfAxis.X; var y1width = obb1.HalfAxisWidth.Y + mink1.HalfAxis.Y; if (((Math.Abs(mink1.Position_LM.X) > x1width) || (Math.Abs(mink1.Position_LM.Y) > y1width))) return false ; else { var mink2 = Minkowski.Minkowskize_OBB_In_OBB(obb1, obb2); var x2width = obb2.HalfAxisWidth.X + mink2.HalfAxis.X; var y2width = obb2.HalfAxisWidth.Y + mink2.HalfAxis.Y; return (!(((Math.Abs(mink2.Position_LM.X) > x2width) || (Math.Abs(mink2.Position_LM.Y) > y2width)))); } }
public static bool CheckOBB(OBB obb, int layerMask = -5, QueryTriggerInteraction triggerInteraction = 0) { layerMask = GamePhysics.HandleTerrainCollision((Vector3)obb.position, layerMask); return(Physics.CheckBox((Vector3)obb.position, (Vector3)obb.extents, (Quaternion)obb.rotation, layerMask, triggerInteraction)); }
public static bool TestSphereOBB(Sphere s, OBB obb) { Stats.TestSphereOBB++; var positionloc = obb.Point_W_To_L(s.Position); var x1width = obb.HalfAxisWidth.X + s.Radius; var y1width = obb.HalfAxisWidth.Y + s.Radius; return ((Math.Abs(positionloc.X) <= x1width) && (Math.Abs(positionloc.Y) <= y1width)) ; }
public void Parse(GameBitBuffer buffer) { Field0 = buffer.ReadInt(32); Field1 = buffer.ReadInt(32); Field2 = buffer.ReadInt(32); Field3 = buffer.ReadInt(32); Field4 = buffer.ReadFloat32(); Field5 = buffer.ReadFloat32(); Field6 = buffer.ReadFloat32(); Field7 = new ConvexHull(); Field7.Parse(buffer); Field8 = new OBB(); Field8.Parse(buffer); Field9 = new Sphere(); Field9.Parse(buffer); Field10 = new Cylinder(); Field10.Parse(buffer); Field11 = new Capsule(); Field11.Parse(buffer); }
public void createconnection(Part main, ArrayList secondries) { foreach (Identifier secondry in secondries) { Part part1 = main; Part part2 = (Part)this.myModel.SelectModelObject(secondry); List <Beam> beamList = new List <Beam>(); this.myModel.GetWorkPlaneHandler().SetCurrentTransformationPlane(new TransformationPlane(part1.GetCoordinateSystem())); Tekla.Structures.Model.Solid solid1 = part1.GetSolid(); Point maximumPoint = solid1.MaximumPoint; Point minimumPoint = solid1.MinimumPoint; Tekla.Structures.Model.Solid solid2 = part2.GetSolid(); double num = 0.0; Type type = part1.GetType(); if (type.Name == "Beam") { num = solid2.MaximumPoint.X; } else if (type.Name == "ContourPlate") { num = solid2.MaximumPoint.Y; } Assembly assembly = part2.GetAssembly(); assembly.SetMainPart(part2); ArrayList secondaries = assembly.GetSecondaries(); Point point1 = new Point(); Point point2 = new Point(); Point point3 = new Point(); Point point4 = new Point(); if (type.Name == "Beam") { point1 = new Point(num, maximumPoint.Y + this.data.positive_Y + this.data.Plate_h, maximumPoint.Z + this.data.negative_X + this.data.Plate_h); point2 = new Point(num, maximumPoint.Y + this.data.positive_Y + this.data.Plate_h, minimumPoint.Z + this.data.positive_X * -1.0 - this.data.Plate_h); point3 = new Point(num, minimumPoint.Y + this.data.negative_Y * -1.0 - this.data.Plate_h, minimumPoint.Z + this.data.positive_X * -1.0 - this.data.Plate_h); point4 = new Point(num, minimumPoint.Y + this.data.negative_Y * -1.0 - this.data.Plate_h, maximumPoint.Z + this.data.negative_X + this.data.Plate_h); } else if (type.Name == "ContourPlate") { point1 = new Point(maximumPoint.X + this.data.positive_Y + this.data.Plate_h, num, maximumPoint.Z + this.data.negative_X + this.data.Plate_h); point2 = new Point(maximumPoint.X + this.data.positive_Y + this.data.Plate_h, num, minimumPoint.Z + this.data.positive_X * -1.0 - this.data.Plate_h); point3 = new Point(minimumPoint.X + this.data.negative_Y * -1.0 - this.data.Plate_h, num, minimumPoint.Z + this.data.positive_X * -1.0 - this.data.Plate_h); point4 = new Point(minimumPoint.X + this.data.negative_Y * -1.0 - this.data.Plate_h, num, maximumPoint.Z + this.data.negative_X + this.data.Plate_h); } for (int index = 0; index < secondaries.Count; ++index) { if (secondaries[index].GetType().Name == "PolyBeam") { secondaries.RemoveAt(secondaries.IndexOf(secondaries[index])); if (index >= 0) { --index; continue; } if (secondaries.Count == 0) { break; } } Part Part_To_Be_Cut = (Part)secondaries[index]; if (Part_To_Be_Cut.Class != "211") { this.CreateCut(point1, point2, point3, point4, Part_To_Be_Cut).Delete(); } } ContourPlate cut = this.CreateCut(point1, point2, point3, point4, part2); OBB obb1 = new OBB(); OBB obb2 = this.CreateObb((Part)cut); foreach (LineSegment lineSegment in this.Get_Lower_face_edge(part2)) { if (obb2.Intersects(lineSegment)) { try { LineSegment obb3 = Intersection.LineSegmentToObb(lineSegment, obb2); Beam beam = this.insert_toeplate(obb3.Point1, obb3.Point2); this.insert_weld(part2, (Part)beam); beamList.Add(beam); } catch (Exception) { } } } cut.Delete(); for (int index = 0; index < beamList.Count; ++index) { try { this.part_cut((Part)beamList[index], (Part)beamList[index + 1]); } catch (Exception) { } } try { this.part_cut((Part)beamList[beamList.Count - 1], (Part)beamList[0]); } catch (Exception) { } for (int index = 0; index < secondaries.Count; ++index) { if (secondaries[index] is Beam beam && beam.Class == "211") { secondaries.Remove((object)beam); index = -1; } } foreach (Part GPart in secondaries) { foreach (LineSegment lineSegment in this.Get_Lower_face_edge(GPart)) { if (obb2.Intersects(lineSegment)) { try { LineSegment obb3 = Intersection.LineSegmentToObb(lineSegment, obb2); Beam beam = this.insert_toeplate(obb3.Point1, obb3.Point2); beamList.Add(beam); } catch (Exception) { } } } } for (int index1 = 0; index1 <= beamList.Count - 1; ++index1) { Beam beam1 = beamList[index1]; for (int index2 = index1 + 1; index2 <= beamList.Count - 1; ++index2) { Beam beam2 = beamList[index2]; this.combine_beams_have_same_vector((Part)beam1, (Part)beam2); } } } }
public static bool Check(OBB obb, EnvironmentType type) { return((uint)(EnvironmentManager.Get(obb) & type) > 0U); }
// TO DO protected override bool TestCollisionVsOBB(OBB other, out Collision collision) { collision = null; // Code from Michael Zheng and Ben Strong, using with permission // same as above twice // find max extents of OBB, do ABB vs this box // then, transform this box into OBB's space, find max extents, repeat //1. create max and min extents of this particle //2. max = (center.x + length/2, center.y + height/2) //3. min = (center.x - length/2, center.y - height/2) //4. create max and min extents of other particle //4a. find all corner points of the box using length, height //4b. rotate all points around its rotation https://www.gamefromscratch.com/post/2012/11/24/GameDev-math-recipes-Rotating-one-point-around-another-point.aspx //4c. min = (min(x of all points), min(y of all points)) https://stackoverflow.com/questions/3231176/how-to-get-size-of-a-rotated-rectangle //4d. max = (max(x of all points), max(y of all points) //5. check if this_max.x > other_min.x and this_max.y > other_min.y //6. check if other_max.x > this_min.x and other_max.y > this_min.y //7. transform this center around the other's center using its transform matrix inverse //8. transform each point of the aab by the other's transform matrix inverse //8. find max and min extents of this by using Max(all points), Min(all points) //5. check if new this_max.x > other_min.x and new this_max.y > other_min.y //6. check if other_max.x > new this_min.x and other_max.y > new this_min.y //9. if all checks are true, then collision check passes Matrix4x4 otherMatrix = other.transform.worldToLocalMatrix;//other.particle.worldTransformMatrixInverse; bool check1, check2; Vector3 thisMax, thisMin, otherMax, otherMin; Vector3 p1, p2, p3, p4, p5, p6, p7, p8; Vector3 otherPosition = other.particle.position; Vector3 thisWidths = halfWidths; Vector3 otherWidths = other.halfWidths; //max and min of this position point9 = thisMax = particle.position + thisWidths; point10 = thisMin = particle.position - thisWidths; //find max and min of other //get all corner points and then rotate it //p1 = rotatePoint(new Vector2(otherLength, otherHeight), other.rotation); //p2 = rotatePoint(new Vector2(otherLength, -otherHeight), other.rotation); //p3 = rotatePoint(new Vector2(-otherLength, -otherHeight), other.rotation); //p4 = rotatePoint(new Vector2(-otherLength, otherHeight), other.rotation); //p1 = other.transform.worldToLocalMatrix * (new Vector2(otherLength, otherHeight)); //p2 = other.transform.worldToLocalMatrix * (new Vector2(otherLength, -otherHeight)); //p3 = other.transform.worldToLocalMatrix * (new Vector2(-otherLength, -otherHeight)); //p4 = other.transform.worldToLocalMatrix * (new Vector2(-otherLength, otherHeight)); point1 = p1 = otherMatrix.MultiplyPoint3x4(new Vector3(otherWidths.x, otherWidths.y, otherWidths.z)); point2 = p2 = otherMatrix.MultiplyPoint3x4(new Vector3(otherWidths.x, otherWidths.y, -otherWidths.z)); point3 = p3 = otherMatrix.MultiplyPoint3x4(new Vector3(otherWidths.x, -otherWidths.y, otherWidths.z)); point4 = p4 = otherMatrix.MultiplyPoint3x4(new Vector3(otherWidths.x, -otherWidths.y, -otherWidths.z)); point5 = p5 = otherMatrix.MultiplyPoint3x4(new Vector3(-otherWidths.x, otherWidths.y, otherWidths.z)); point6 = p6 = otherMatrix.MultiplyPoint3x4(new Vector3(-otherWidths.x, otherWidths.y, -otherWidths.z)); point7 = p7 = otherMatrix.MultiplyPoint3x4(new Vector3(-otherWidths.x, -otherWidths.y, otherWidths.z)); point8 = p8 = otherMatrix.MultiplyPoint3x4(new Vector3(-otherWidths.x, -otherWidths.y, -otherWidths.z)); //find max of all points otherMax = new Vector3(Mathf.Max(p1.x, p2.x, p3.x, p4.x, p5.x, p6.x, p7.x, p8.x) + otherPosition.x, Mathf.Max(p1.y, p2.y, p3.y, p4.y, p5.y, p6.y, p7.y, p8.y) + otherPosition.y, Mathf.Max(p1.z, p2.z, p3.z, p4.z, p5.z, p6.z, p7.z, p8.z) + otherPosition.z); otherMin = new Vector3(Mathf.Min(p1.x, p2.x, p3.x, p4.x, p5.x, p6.x, p7.x, p8.x) + otherPosition.x, Mathf.Min(p1.y, p2.y, p3.y, p4.y, p5.y, p6.y, p7.y, p8.y) + otherPosition.y, Mathf.Min(p1.z, p2.z, p3.z, p4.z, p5.z, p6.z, p7.z, p8.z) + otherPosition.z); // max > min && max > min check1 = (thisMax.x >= otherMin.x && thisMax.y >= otherMin.y && thisMax.z >= otherMax.z) && (otherMax.x >= thisMin.x && otherMax.y >= thisMin.y && otherMax.z >= thisMax.z); if (!check1) { return(false); } //for each corner, move it relative to the box then transform by the world matrix inverse. Finally add position back //p1 = other.transform.worldToLocalMatrix * (new Vector2(particle.position.x + thisLength, particle.position.y + thisHeight) - otherPosition); //this one //p2 = other.transform.worldToLocalMatrix * (new Vector2(particle.position.x + thisLength, particle.position.y - thisHeight) - otherPosition); //p3 = other.transform.worldToLocalMatrix * (new Vector2(particle.position.x - thisLength, particle.position.y - thisHeight) - otherPosition); //p4 = other.transform.worldToLocalMatrix * (new Vector2(particle.position.x - thisLength, particle.position.y + thisHeight) - otherPosition); //p1 += otherPosition; //p2 += otherPosition; //p3 += otherPosition; //p4 += otherPosition; p1 = otherMatrix * (new Vector3(particle.position.x + halfWidths.x, particle.position.y + halfWidths.y, particle.position.z + halfWidths.z) - otherPosition); p2 = otherMatrix * (new Vector3(particle.position.x + halfWidths.x, particle.position.y + halfWidths.y, particle.position.z - halfWidths.z) - otherPosition); p3 = otherMatrix * (new Vector3(particle.position.x + halfWidths.x, particle.position.y - halfWidths.y, particle.position.z + halfWidths.z) - otherPosition); p4 = otherMatrix * (new Vector3(particle.position.x + halfWidths.x, particle.position.y - halfWidths.y, particle.position.z - halfWidths.z) - otherPosition); p5 = otherMatrix * (new Vector3(particle.position.x - halfWidths.x, particle.position.y + halfWidths.y, particle.position.z + halfWidths.z) - otherPosition); p6 = otherMatrix * (new Vector3(particle.position.x - halfWidths.x, particle.position.y + halfWidths.y, particle.position.z - halfWidths.z) - otherPosition); p7 = otherMatrix * (new Vector3(particle.position.x - halfWidths.x, particle.position.y - halfWidths.y, particle.position.z + halfWidths.z) - otherPosition); p8 = otherMatrix * (new Vector3(particle.position.x - halfWidths.x, particle.position.y - halfWidths.y, particle.position.z - halfWidths.z) - otherPosition); p1 += otherPosition; p2 += otherPosition; p3 += otherPosition; p4 += otherPosition; p5 += otherPosition; p6 += otherPosition; p7 += otherPosition; p8 += otherPosition; //get the extremes for min and max //thisMax = new Vector2(Mathf.Max(p1.x, p2.x, p3.x, p4.x), Mathf.Max(p1.y, p2.y, p3.y, p4.y)); //thisMin = new Vector2(Mathf.Min(p1.x, p2.x, p3.x, p4.x), Mathf.Min(p1.y, p2.y, p3.y, p4.y)); thisMax = new Vector3(Mathf.Max(p1.x, p2.x, p3.x, p4.x, p5.x, p6.x, p7.x, p8.x) + otherPosition.x, Mathf.Max(p1.y, p2.y, p3.y, p4.y, p5.y, p6.y, p7.y, p8.y) + otherPosition.y, Mathf.Max(p1.z, p2.z, p3.z, p4.z, p5.z, p6.z, p7.z, p8.z) + otherPosition.z); thisMin = new Vector3(Mathf.Min(p1.x, p2.x, p3.x, p4.x, p5.x, p6.x, p7.x, p8.x) + otherPosition.x, Mathf.Min(p1.y, p2.y, p3.y, p4.y, p5.y, p6.y, p7.y, p8.y) + otherPosition.y, Mathf.Min(p1.z, p2.z, p3.z, p4.z, p5.z, p6.z, p7.z, p8.z) + otherPosition.z); //otherMax = new Vector2(otherPosition.x + otherLength, otherPosition.y + otherHeight); //otherMin = new Vector2(otherPosition.x - otherLength, otherPosition.y - otherHeight); otherMax = otherPosition + otherWidths; otherMin = otherPosition - otherWidths; check2 = (thisMax.x >= otherMin.x && thisMax.y >= otherMin.y && thisMax.z >= otherMax.z) && (otherMax.x >= thisMin.x && otherMax.y >= thisMin.y && otherMax.z > thisMax.z); if (!check2) { return(false); } return(true); }
public void Start() { this.Process(); this.areaBox = new OBB(base.transform.position, base.transform.lossyScale, base.transform.rotation, this.bounds); AIInformationZone.zones.Add(this); }
void ChangeBuildingGrade(BasePlayer player, string[] args, bool increment) { if (!IsAllowed(player)) { PrintMessage(player, "NotAllowed"); return; } if (runningPlayers.Contains(player.userID)) { PrintMessage(player, "AlreadyRunning"); return; } if (!player.IsAdmin() && runningPlayers.Count > 0) { PrintMessage(player, "AnotherProcess"); return; } var targetGrade = -1; var filter = false; HashSet <uint> prefabs = null; if (args.Length > 0) { try { targetGrade = (int)(BuildingGrade.Enum)Enum.Parse(typeof(BuildingGrade.Enum), args[0], true); } catch (Exception) { PrintMessage(player, "UnknownGrade"); return; } if (args.Length > 1) { if (!categories.TryGetValue(args[1], out prefabs)) { PrintMessage(player, "UnknownCategory"); return; } filter = prefabs.Count > 0; } } var stack = GetTargetBuildingBlock(player); if (stack == null || stack.Count == 0) { PrintMessage(player, "NotLookingAt"); return; } var all_blocks = new HashSet <BuildingBlock>(); //var started = Interface.Oxide.Now; //var done = 0; while (stack.Count > 0) { var building_block = stack.Pop(); var position = new OBB(building_block.transform, building_block.bounds).ToBounds().center; var blocks = Pool.GetList <BuildingBlock>(); Vis.Entities(position, Distance, blocks, 270532864); foreach (var block in blocks) { if (!all_blocks.Add(block)) { continue; } stack.Push(block); } Pool.FreeList(ref blocks); //done++; } var allowed = player.IsAdmin() || permission.UserHasPermission(player.UserIDString, PermOwner); all_blocks.RemoveWhere(b => !allowed && b.OwnerID != player.userID || filter && !prefabs.Contains(b.prefabID)); //Puts("Time: {0} Size: {1} Done: {2}", Interface.Oxide.Now - started, all_blocks.Count, done); if (increment && !player.IsAdmin() && !permission.UserHasPermission(player.UserIDString, PermNoCost)) { var costs = GetCosts(all_blocks, targetGrade); if (!CanAffordUpgrade(costs, player)) { return; } PayForUpgrade(costs, player); } runningPlayers.Add(player.userID); NextTick(() => DoUpgrade(all_blocks, targetGrade, increment, player)); /*foreach (var building_block in all_blocks) * { * var target_grade = NextBlockGrade(building_block, grade, increment ? 1 : -1); * if (!CanUpgrade(building_block, (BuildingGrade.Enum) target_grade)) continue; * * building_block.SetGrade((BuildingGrade.Enum)target_grade); * building_block.SetHealthToMax(); * building_block.SendNetworkUpdate(BasePlayer.NetworkQueue.Update); * building_block.UpdateSkin(); * } * PrintMessage(player, increment ? "FinishedUp" : "FinishedDown"); * runningPlayers.Remove(player.userID); */ }
protected override bool Check(Vector3 position, Quaternion rotation, OBB obb, int mask = -1) { return(false); }
private void RepairAOE(BaseCombatEntity entity, BasePlayer player) { //Prevent infinite loop _allowAOERepair = false; //gets the position of the block we just hit var position = new OBB(entity.transform, entity.bounds).ToBounds().center; //sets up the collection for the blocks that will be affected var entities = Pool.GetList <BaseCombatEntity>(); //gets a list of entities within a specified range of the current target Vis.Entities(position, RepairRange, entities, repairDeployables ? allMask : constructionMask); int repaired = 0; if (entities.Count == 1) { _allowAOERepair = true; Pool.FreeList(ref entities); return; } //check if we have blocks - we should always have at least 1 if (entities.Count > 0) { var resources = new Dictionary <string, float>(); int lastAttacked = 0; //cycle through our block list - figure out which ones need repairing foreach (var ent in entities) { //check to see if the block has been damaged before repairing. if (ent.health < ent.MaxHealth()) { if (ent.SecondsSinceAttacked <= lastAttackLimit) { lastAttacked++; continue; } var ret = CanRepair(ent, player, entities); if (ret is KeyValuePair <string, float> ) { var kvp = (KeyValuePair <string, float>)ret; if (!resources.ContainsKey(kvp.Key)) { resources.Add(kvp.Key, kvp.Value); } else { resources[kvp.Key] += kvp.Value; } } else if (ret is bool && (bool)ret) { if (DoRepair(ent, player)) { if (markRepairedTime > 0f && player.IsAdmin) { player.SendConsoleCommand("ddraw.text", markRepairedTime, Color.green, ent.WorldSpaceBounds().ToBounds().center, "R"); } if (++repaired > maxRepairEnts) { break; } } } } } Pool.FreeList(ref entities); if (resources.Count > 0) { if (resources.Count > 1 || (resources.Count == 1 && resources.First().Key == "High Quality Metal" && resources.First().Value > 3)) { foreach (var kvp in resources) { SendChatMessage(player, msg("Missing Resources Multiple", player.UserIDString, kvp.Key, kvp.Value)); } SendChatMessage(player, msg("Missing Resources Partial", player.UserIDString)); } else { SendChatMessage(player, msg("Missing Resources Single", player.UserIDString, resources.First().Key, resources.First().Value)); } if (repaired == 0) { _allowAOERepair = true; } } if (!_allowAOERepair) { SendChatMessage(player, repaired > 0 ? msg("IFixedEx", player.UserIDString, repaired) : msg(lastAttacked > 0 && repaired == 0 ? "CannotFixYet" : "FixDone", player.UserIDString)); } } else { SendChatMessage(player, msg("MissingFix", player.UserIDString)); } _allowAOERepair = true; }
protected override void OnSkillBegin() { List<Character> enemys = FindTargets(true); Character target = GetFirstAttackTarget(); Vector3 atkPos = target.position; if (rangeType == RangeType.ForwardColumn) { atkPos = Fight.Inst.GetSlotPos(attacker.camp == CampType.Friend ? CampType.Enemy : CampType.Friend, attacker.slot); } else { ClearGeZiEffects(); } StartCameraAnim(); // 设置朝向 Vector3 dir = atkPos - attacker.position; dir.Normalize(); attacker.LookAt(atkPos); // 播放动画和特效 EffectObject effObj = PlayFireAnimAndEffect(-1); GameObject eff = effObj.obj; eff.transform.rotation = attacker.rotation; // 计算技能OBB float dist = Vector3.Distance(atkPos, attacker.position) + 10f; Vector3 center = attacker.position + dir.normalized * dist / 2f; OBB obb = new OBB(new Vector2(center.x, center.z), new Vector2(dist / 2f, 1f), attacker.rotation.eulerAngles.y); // 检测碰撞 float singTime = SingTime; float bulletSpeed = BulletSpeed; if (bulletSpeed < 0.01f) { singTime = HitTime; } float dam = Damage; int n = 0; foreach (Character e in enemys) { if (e.CanBeAtk == false) continue; //e.UpdateOBB(); OBB obbe = new OBB(new Vector2(e.position.x, e.position.z), new Vector2(1f, 1f), e.rotation.eulerAngles.y); if (obb.Intersects(obbe)) { float t = singTime; if (bulletSpeed > 0f) { float s = Vector2.Distance(attacker.pos2v, e.pos2v); t += s / bulletSpeed; } float r = 1f; if (n < damageTranJson.Count) r = (float)damageTranJson[n++]; float val = dam * r; CalcDamage(attacker, e, val, t); if (rangeType != RangeType.ForwardColumn) PlayGeZiEffect(e.slot, e.camp); } } // 结束技能 AddEvent(TotalTime, delegate { DoTskill(); End(); }); }
public void createconnection(Point center_point, ArrayList Gratting_assembly_arraylist) { foreach (Identifier ID in Gratting_assembly_arraylist) { Part part1 = (Part)this.myModel.SelectModelObject(ID); this.myModel.GetWorkPlaneHandler().SetCurrentTransformationPlane(new TransformationPlane()); this.myModel.GetWorkPlaneHandler().SetCurrentTransformationPlane(new TransformationPlane()); this.Get_Lower_face_edge(part1); string Partprofile1; string Partprofile2; if (this.data.holeType == 0) { Partprofile1 = "ROD" + (this.data.holeDiam - this.data.Plate_h).ToString(); Partprofile2 = "ROD" + this.data.holeDiam.ToString(); } else { Partprofile1 = this.data.hole_L.ToString() + "*" + this.data.hole_w.ToString(); Partprofile2 = Partprofile1; } Assembly assembly = part1.GetAssembly(); assembly.SetMainPart(part1); ArrayList secondaries = assembly.GetSecondaries(); for (int index = 0; index < secondaries.Count; ++index) { if (secondaries[index].GetType().Name == "PolyBeam") { secondaries.RemoveAt(secondaries.IndexOf(secondaries[index])); if (index > 0) { --index; } else { index = 0; } if (secondaries.Count == 0) { break; } } if (((Part)secondaries[index]).Class != "211") { this.CreateCut(center_point, (Part)secondaries[index], Partprofile2).Delete(); } } Beam cut1 = this.CreateCut(center_point, part1, Partprofile1); OBB obb1 = this.CreateObb((Part)cut1); List <LineSegment> lowerFaceEdge = this.Get_Lower_face_edge(part1); List <Beam> beamList = new List <Beam>(); List <LineSegment> lineSegmentList = new List <LineSegment>(); if (this.data.holeType == 0) { Point point1 = new Point(); Point point2 = new Point(); foreach (LineSegment lineSegment in lowerFaceEdge) { if (obb1.Intersects(lineSegment)) { LineSegment obb2 = Intersection.LineSegmentToObb(lineSegment, obb1); lineSegmentList.Add(obb2); } } Point point1_1 = lineSegmentList[lineSegmentList.Count / 2].Point1; List <LineSegment> lowerEdge = this.new_get_lower_edge(part1); ArrayList arrayList = new ArrayList(); List <Point> pointList = new List <Point>(); Tekla.Structures.Model.Solid solid = cut1.GetSolid(); foreach (LineSegment line in lowerEdge) { if ((uint)solid.Intersect(line).Count > 0U) { foreach (object obj in solid.Intersect(line)) { pointList.Add(obj as Point); } } } Point P1 = pointList[0]; Point P2 = pointList[pointList.Count - 1]; if (point1_1 == P1 || point1_1 == P2) { point1_1 = lineSegmentList[lineSegmentList.Count / 2 - 1].Point1; } Chamfer C = new Chamfer(); C.Type = Chamfer.ChamferTypeEnum.CHAMFER_ARC_POINT; PolyBeam polyBeam = new PolyBeam(); polyBeam.Profile.ProfileString = "PL" + this.data.Plate_b.ToString() + "*" + this.data.Plate_h.ToString(); polyBeam.Position.Depth = Position.DepthEnum.FRONT; polyBeam.Position.Plane = Position.PlaneEnum.MIDDLE; polyBeam.Position.Rotation = Position.RotationEnum.TOP; polyBeam.Position.DepthOffset = this.data.offset; polyBeam.Material.MaterialString = this.data.Plate_matrial; polyBeam.PartNumber.Prefix = this.data.Pos_1; polyBeam.PartNumber.StartNumber = this.data.Plate_pos2; polyBeam.Name = this.data.Plate_name; polyBeam.AddContourPoint(new ContourPoint(P1, (Chamfer)null)); polyBeam.AddContourPoint(new ContourPoint(point1_1, C)); polyBeam.AddContourPoint(new ContourPoint(P2, (Chamfer)null)); polyBeam.Insert(); Beam cut2 = this.CreateCut(center_point, part1, Partprofile2); this.insert_weld(part1, (Part)polyBeam); cut1.Delete(); cut2.Delete(); ModelObjectEnumerator booleans = polyBeam.GetBooleans(); while (booleans.MoveNext()) { (booleans.Current as BooleanPart).Delete(); } } else { foreach (LineSegment lineSegment in lowerFaceEdge) { if (obb1.Intersects(lineSegment)) { try { LineSegment obb2 = Intersection.LineSegmentToObb(lineSegment, obb1); Beam beam = this.insert_toeplate(obb2.Point1, obb2.Point2); this.insert_weld(part1, (Part)beam); beamList.Add(beam); } catch (Exception) { } } } cut1.Delete(); foreach (Part part2 in beamList) { ModelObjectEnumerator booleans = part2.GetBooleans(); while (booleans.MoveNext()) { (booleans.Current as BooleanPart).Delete(); } } for (int index = 0; index < beamList.Count; ++index) { try { this.part_cut((Part)beamList[index], (Part)beamList[index + 1]); } catch (Exception) { } } try { this.part_cut((Part)beamList[beamList.Count - 1], (Part)beamList[0]); } catch (Exception) { } for (int index = 0; index < secondaries.Count; ++index) { Beam beam = secondaries[index] as Beam; if (beam.Class == "211") { secondaries.Remove((object)beam); index = -1; } } foreach (Part GPart in secondaries) { foreach (LineSegment lineSegment in this.Get_Lower_face_edge(GPart)) { if (obb1.Intersects(lineSegment)) { try { LineSegment obb2 = Intersection.LineSegmentToObb(lineSegment, obb1); Beam beam = this.insert_toeplate(obb2.Point1, obb2.Point2); beamList.Add(beam); } catch (Exception) { } } } } for (int index1 = 0; index1 <= beamList.Count - 1; ++index1) { Beam beam1 = beamList[index1]; for (int index2 = index1 + 1; index2 <= beamList.Count - 1; ++index2) { Beam beam2 = beamList[index2]; this.combine_beams_have_same_vector((Part)beam1, (Part)beam2); } } } } }
public Game() { _collisionWorld = new World(); _physicsToSceneObjectMap = new Dictionary <OBB, ISceneObject>(); WindowCreateInfo wci = new WindowCreateInfo { X = 100, Y = 100, WindowWidth = 960, WindowHeight = 540, WindowTitle = GetTitle(), }; _window = VeldridStartup.CreateWindow(ref wci); _window.Resized += () => { _windowResized = true; OnWindowResized(); }; Matrix4x4 projMatrix = Matrix4x4.CreatePerspectiveFieldOfView( 1.0f, (float)_window.Width / _window.Height, 0.5f, 100f); Matrix4x4 viewMatrix = Matrix4x4.CreateLookAt(new Vector3(-1.0f, 5.0f, 8.5f), new Vector3(0.0f, -1.0f, -1.5f), Vector3.UnitY); _camera = new Camera(projMatrix, viewMatrix); GraphicsDeviceOptions options = new GraphicsDeviceOptions(false, PixelFormat.R16_UNorm, true); #if DEBUG options.Debug = true; #endif GraphicsDevice gd = VeldridStartup.CreateGraphicsDevice(_window, options, GraphicsBackend.Direct3D11); _renderer = new Renderer(gd, _camera); var instancedDrawable = _renderer.GetInstanceContainer(CubeMeshFactory.GetMesh(), 121); _cubes = instancedDrawable.Instances; for (int x = 0; x < 11; x++) { for (int z = 0; z < 11; z++) { Vector3 pos = new Vector3(x - 5, 0, z - 5); var transform = Matrix4x4.CreateTranslation(pos - new Vector3(0.5f, 0.5f, 0.5f)); ISceneObject renderCube = _cubes[x * 11 + z]; renderCube.Transform = transform; OBB physicsCube = new OBB { Height = 1.0f, Width = 1.0f, Length = 1.0f, Transform = transform }; _collisionWorld.Objects.Add(physicsCube); _physicsToSceneObjectMap.Add(physicsCube, renderCube); } } _selection = _renderer.Add(CubeMeshFactory.GetMesh(new Vector3(1.0f, 0.0f, 0.0f))); _selection.IsVisible = false; _yellowRotatable = _renderer.Add(CubeMeshFactory.GetMesh(new Vector3(1.0f, 1.0f, 0.0f))); _greenRotatable = _renderer.Add(CubeMeshFactory.GetMesh(new Vector3(0.0f, 1.0f, 0.0f))); _blueRotatable = _renderer.Add(CubeMeshFactory.GetMesh(new Vector3(0.0f, 0.0f, 1.0f))); _yellowRotatable.Transform = _yellowBaseTransform; _greenRotatable.Transform = _greenBaseTransform; _blueRotatable.Transform = _blueBaseTransform; }
public static bool Check(OBB obb, EnvironmentType type) { return((Get(obb) & type) != 0); }
public static float Intersection_RayOBB(FRay ray, OBB obb) { Vector3 RotationX = obb.GetTangetX(); Vector3 RotationY = obb.GetTangetY(); Vector3 RotationZ = obb.GetTangetZ(); Vector3 p = obb.GetOrigin() - ray.StartPosition; // Project obb tangent vectors on ray direction Vector3 f = new Vector3( ProjectVectorOnNormalizedVector(RotationX, ray.Direction), ProjectVectorOnNormalizedVector(RotationY, ray.Direction), ProjectVectorOnNormalizedVector(RotationZ, ray.Direction) ); // Project tangent vectors on p Vector3 e = new Vector3( ProjectVectorOnNormalizedVector(RotationX, p), ProjectVectorOnNormalizedVector(RotationY, p), ProjectVectorOnNormalizedVector(RotationZ, p) ); Vector3 extent = obb.GetExtent(); float[] tparameter = new float[6]; for (Int32 i = 0; i < 3; i++) { if (CMP(f[i], 0) > 0) { if (-e[i] - extent[i] > 0 || -e[i] + extent[i] < 0) { return(-1); } f[i] = 0.00001f; } tparameter[i * 2] = (e[i] + extent[i]) / f[i]; // min tparameter[i * 2 + 1] = (e[i] - extent[i]) / f[i]; // max } float tmin = Math.Max( Math.Max(Math.Min(tparameter[0], tparameter[1]), Math.Min(tparameter[2], tparameter[3])), Math.Min(tparameter[4], tparameter[5])); float tmax = System.Math.Min( System.Math.Min(System.Math.Max(tparameter[0], tparameter[1]), System.Math.Max(tparameter[2], tparameter[3])), System.Math.Max(tparameter[4], tparameter[5])); // If OBB is behind the origin of the ray or if ray doesn't intersect OBB if (tmax < 0 || tmin > tmax) { return(-1); } // If origin of ray is inside the OBB if (tmin < 0.0f) { return(tmax); } // Intersection point return(tmin); }
public void FireDirBullet(List<Character> targets, Vector3 srcPos, Vector3 destPos, string bulletModel, float bulletSpeed, float dam, int atkC, float hitTime, float radius) { // 计算技能OBB Vector3 dir = destPos - srcPos; dir.y = 0f; dir.Normalize(); Quaternion rot = Quaternion.LookRotation(dir); float dist = Vector3.Distance(destPos, srcPos) + 20f; Vector3 center = srcPos + dir.normalized * dist / 2f; OBB obb = new OBB(new Vector2(center.x, center.z), new Vector2(dist / 2f, radius), rot.eulerAngles.y); Vector2 srcPos2v = new Vector2(srcPos.x, srcPos.z); // 播放特效 EffectObject effObj = PlayEffect(bulletModel, -1f); GameObject eff = effObj.obj; eff.transform.position = srcPos; eff.transform.rotation = rot; // 检测碰撞 int n = 0; foreach (Character e in targets) { if (e.CanBeAtk == false) continue; OBB obbe = new OBB(new Vector2(e.position.x, e.position.z), new Vector2(1f, 1f), e.rotation.eulerAngles.y); if (obb.Intersects(obbe)) { float t = 0f; if (bulletSpeed > 0f) { float s = Vector2.Distance(srcPos2v, e.pos2v); t += s / bulletSpeed; } float r = 1f; if (n < damageTranJson.Count) r = (float)damageTranJson[n++]; float val = dam * r; for (int i = 0; i < atkC; ++i) { CalcDamage(attacker, e, val, t + i * hitTime); } PlayGeZiEffect(e.slot, e.camp); } } }
public virtual float WaterFactorForPlayer(BasePlayer player) { OBB obb = player.WorldSpaceBounds(); return(WaterLevel.Factor(((OBB) ref obb).ToBounds())); }
/// <summary> /// xekinas me deiktes i j /// kai kataligeis se final_i, final_j //elegxe to an piaseis esto ena einai ok /// exeis kati times tx ty pou deixnoun "se ti pososto os pros monada apo to sinoliko manhattan x kai y antistoixa eisai tora" /// diladi xekinane apo miden ftanoun 1 alla kai pali me ta final stamatas /// </summary> //this method performs a bersenhaam algorithm like traversal of the "neutral" grid using a linesegment. //until it hits with an obstacle reporting the ray's/segment's parameter at the point of entering and leaving it public static Geometry.Ray_Test_Result Trace_Line(LineSegment ls, Geometry.Ray_Test_Mode mode) { var direction = ls.end - ls.start; if (mode == Geometry.Ray_Test_Mode.Line) throw new Exception(); Grid_Query_Counter.Counter++; var grid = GELib.Managers.Spatial_Partitioning_Management.main_spatial_grid.neutral;// grids[(int)Col_Slot.Neutral]; var cell_size = World_Info.Collision_Cellsize; var cell_coords_start = Spatial.Grid_Func.Grid_Coords(ls.start, cell_size); Spatial.Grid_Coord cell_coords_end; cell_coords_end = Spatial.Grid_Func.Grid_Coords(ls.end, cell_size); var i = cell_coords_start.col; var j = cell_coords_start.row; var final_i = cell_coords_end.col; var final_j = cell_coords_end.row; var y_manh_dist_inv = direction.Y == 0 ? Single.MaxValue : (float)1 / Math.Abs(direction.Y); var x_manh_dist_inv = direction.X == 0 ? Single.MaxValue : (float)1 / Math.Abs(direction.X); //an to cell afxanei -1,0,1 kathos proxoras analoga pou koitas int di = ((ls.start.X < ls.end.X) ? 1 : ((ls.start.X > ls.end.X) ? -1 : 0)); int dj = ((ls.start.Y < ls.end.Y) ? 1 : ((ls.start.Y > ls.end.Y) ? -1 : 0)); //se ti posostioso ton manh_dist xekinises, //xekinises oxi h arxiki timi pou einai miden //alla ta t deixnoun "to epomeno toixaki" //kai mallon me ta midenika sta di pou vazo pio pano ktl h idea einai oti //den tha peraseis dyo tixakia mias sintetagmenis seri //ex ou kai h anisotita sto for(;;) var tx = (ls.start.X > ls.end.X ? ls.start.X - (i * cell_size) : (i + 1) * cell_size - ls.start.X) * x_manh_dist_inv; var ty = (ls.start.Y > ls.end.Y ? ls.start.Y - (j * cell_size) : (j + 1) * cell_size - ls.start.Y) * y_manh_dist_inv; //ta vimata pou kaneis sthn timi tou tx kathos proxoras var dtx = cell_size * x_manh_dist_inv; var dty = cell_size * y_manh_dist_inv; while (true) { var aa = grid.getBucket(i, j); Geometry.Ray_Test_Result Min = new Geometry.Ray_Test_Result(); Min.enter = Single.MaxValue; for (int ib = 0; ib < aa.Count; ib++) { var g_obj = aa[ib]; if (g_obj.g.Last_Query >= Grid_Query_Counter.Counter || g_obj.col != i || g_obj.row != j) continue; g_obj.g.Last_Query = Grid_Query_Counter.Counter; var collidable = g_obj.g.Coll; if (collidable.RTII == RTI.Firing || collidable.RTII == RTI.Just_A_Triangle || collidable.RTII == RTI.Chain_Rectangle) continue; var obb = collidable.OBB; var inner_res = Geometry_Func.TestOBBLine(obb, ls, mode); if (inner_res.Did_It_Hit) if (inner_res.enter < Min.enter) { Min = inner_res; last_trace = obb; } } if (Min.enter != Single.MaxValue) return Min; if (tx <= ty) { // tx smallest, step in x if (i == final_i) break; tx += dtx; i += di; } else { // ty smallest, step in y if (j == final_j) break; ty += dty; j += dj; } } var res = new Geometry.Ray_Test_Result(); res.Did_It_Hit = false; return res; }
protected override bool Check(Vector3 position, Quaternion rotation, OBB obb, int mask = -1) { position = Vector3.op_Addition(position, Quaternion.op_Multiply(rotation, Vector3.op_Addition(Quaternion.op_Multiply(this.worldRotation, this.center), this.worldPosition))); return((LayerMask.op_Implicit(this.layers) & mask) != 0 && (double)Vector3.Distance(position, ((OBB) ref obb).ClosestPoint(position)) <= (double)this.radius); }