/// private メンバ ///--------------------------------------------------------------------------- /// レイと球との交差を求める /** * 返り値:交点との距離を返す */ private static float checkRayCrossSphere( Vector3 trgRayPos, Vector3 trgRayVec, GeometrySphere trgSph ) { float a, b, c, d; float t; Vector3 q; q = trgRayPos - trgSph.Pos; // 球の式にレイを代入。 // x^2 + y^2 + z^2 = r^2 a = ( ( trgRayVec.X * trgRayVec.X ) + ( trgRayVec.Y * trgRayVec.Y ) + ( trgRayVec.Z * trgRayVec.Z ) ); b = 2 * ( ( q.X * trgRayVec.X ) + ( q.Y * trgRayVec.Y ) + ( q.Z * trgRayVec.Z ) ); c = ( ( q.X * q.X ) + ( q.Y * q.Y ) + ( q.Z * q.Z ) ) - ( trgSph.R * trgSph.R ); // 判別式。 // D = b^2 -4ac; d = ( b * b ) + ( -4 * ( a * c ) ); // d < 0 ならば、交差はない。 // d = 0 ならば、球に接する。 // d > 0 ならば、2つの異なる点が存在する。 if( d < 0.0f || a <= 0.0f ){ return -1.0f; } // -b -sqrt (d) // t = -------------- // 2a t = ( -b -FMath.Sqrt( d ) ) / (a*2); return( FMath.Abs(t) ); }
/// 点の移動と球との衝突チェック /** * moveLineの軌道による点の移動とtrgSphとの衝突チェックを行います。 * collPosには衝突した座標を返します(返り値がtrueの時のみ情報が更新) */ public static bool CheckLineAndSphere( GeometryLine moveLine, GeometrySphere trgSph, ref Vector3 collPos ) { Vector3 calVec = trgSph.Pos - moveLine.StartPos; calVec = calVec.Normalize(); if( calVec.Dot( moveLine.Vec ) >= 0.0f ){ Vector3 calVec2 = trgSph.Pos - moveLine.StartPos; float isT = FMath.Sqrt( calVec2.Dot(calVec2) ); if( isT < (moveLine.Length+trgSph.R) ){ float dis = checkRayCrossSphere( moveLine.StartPos, moveLine.Vec, trgSph ); if( dis >= 0.0f || dis < moveLine.Length ){ collPos = moveLine.StartPos + (moveLine.Vec * dis); return true; } } } return false; }
/// 球の移動と球との衝突チェック /** * moveCapの軌道による球の移動とtrgSphとの衝突チェックを行います。 * collPosには衝突した座標を返します(返り値がtrueの時のみ情報が更新) */ public static bool CheckSphereAndSphere( GeometryCapsule moveCap, GeometrySphere trgSph, ref Vector3 collPos ) { calSph.Set( trgSph.Pos, (moveCap.R + trgSph.R) ); return( CheckLineAndSphere( moveCap.Line, calSph, ref collPos ) ); }
/// 球描画 public void DrawSphere( GraphicsContext graphics, GeometrySphere trgSph, Camera cam, Rgba color ) { if( debShader == null ){ return ; } debVb.SetVertices( 0, debMesh.Positions ); debVb.SetIndices( debMesh.Indices ); Matrix4 world = Matrix4.Translation( new Vector3( trgSph.X, trgSph.Y, trgSph.Z ) ) * Matrix4.Scale( new Vector3( trgSph.R, trgSph.R, trgSph.R ) ); Matrix4 worldViewProj = cam.Projection * cam.View * world; // uniform value debShader.SetUniformValue( debUIdWVP, ref worldViewProj ); Vector4 a_Color = new Vector4( (color.R / 255.0f), (color.G / 255.0f), (color.B / 255.0f), (color.A / 255.0f) ); debShader.SetUniformValue( debShader.FindUniform( "IAmbient" ), ref a_Color ); graphics.SetShaderProgram( debShader ); graphics.SetVertexBuffer( 0, debVb ); graphics.DrawArrays( debMesh.Prim, 0, debMesh.IndexCount ); }