TriangleNode* CollisionManager::getTriangle(const Vector3& point, FloorMesh* floor) {
	/*PathGraph* graph = node->getPathGraph();
	FloorMesh* floor = graph->getFloorMesh();*/

	AABBTree* aabbTree = floor->getAABBTree();

	//Vector3 nodePosition = node->getPosition();

	Vector3 rayOrigin(point.getX(), point.getZ() + 0.5, point.getY());
	//Vector3 rayOrigin(point.getX(), point.getY(), point.getZ() + 0.2);
	Vector3 direction(0, -1, 0);

	Ray ray(rayOrigin, direction);

	float intersectionDistance = 0;
	Triangle* triangle = NULL;

	aabbTree->intersects(ray, 4, intersectionDistance, triangle, true);

	TriangleNode* triangleNode = dynamic_cast<TriangleNode*>(triangle);

	if (triangleNode == NULL) {
		//System::out << "CollisionManager::getTriangle triangleNode NULL" << endl;

		return floor->findNearestTriangle(rayOrigin);
	}

	return triangleNode;
}
Exemplo n.º 2
0
/* 
    * This is our ray / bolt collision routine for now.   
    * Basically, this is called on a ship unit to see if any ray or bolt given by some simple vectors collide with it
    *  We should probably first check against shields and then against the colTree to see if we hit the shields first
    *  Not sure yet if that would work though...  more importantly, we might have to modify end in here in order 
    *  to tell calling code that the bolt should stop at a given point. 
*/
Unit* Unit::rayCollide( const QVector &start, const QVector &end, Vector &norm, float &distance)
{
    Unit *tmp;
    float rad = this->rSize();
    if ( ( !SubUnits.empty() ) && graphicOptions.RecurseIntoSubUnitsOnCollision )
        if ( ( tmp = *SubUnits.fastIterator() ) )
            rad += tmp->rSize();
    if ( !globQuerySphere( start, end, cumulative_transformation_matrix.p, rad ) )
        return NULL;
    if (graphicOptions.RecurseIntoSubUnitsOnCollision) {
        if ( !SubUnits.empty() ) {
            un_fiter i( SubUnits.fastIterator() );
            for (Unit *un; (un = *i); ++i)
                if ( ( tmp = un->rayCollide( start, end, norm, distance) ) != 0 )
                    return tmp;
        }
    }
    QVector  st( InvTransform( cumulative_transformation_matrix, start ) );
    QVector  ed( InvTransform( cumulative_transformation_matrix, end ) );
    static bool sphere_test = XMLSupport::parse_bool( vs_config->getVariable( "physics", "sphere_collision", "true" ) );
    distance = querySphereNoRecurse( start, end );    
    if (distance > 0.0f || (this->colTrees&&this->colTrees->colTree( this, this->GetWarpVelocity() )&&!sphere_test)) {
        Vector coord;
        /* Set up points and ray to send to ray collider. */
        Opcode::Point rayOrigin(st.i,st.j,st.k);
        Opcode::Point rayDirection(ed.i,ed.j,ed.k);
        Opcode::Ray boltbeam(rayOrigin,rayDirection);
        if(this->colTrees){
            // Retrieve the correct scale'd collider from the unit's collide tree. 
            csOPCODECollider *tmpCol  = this->colTrees->colTree( this, this->GetWarpVelocity() );
            QVector del(end-start);
            //Normalize(del);
            norm = ((start+del*distance)-Position()).Cast();
            Normalize(norm);
            //RAY COLLIDE does not yet set normal, use that of the sphere center to current loc
            if (tmpCol==NULL) {
                
                return this;
            }
            if(tmpCol->rayCollide(boltbeam,norm,distance)){
                // compute real distance 
                distance = (end-start).Magnitude() * distance;
                
                // NOTE:   Here is where we need to retrieve the point on the ray that we collided with the mesh, and set it to end, create the normal and set distance
                VSFileSystem::vs_dprintf(3,"Beam collide with %p, distance %f\n",this,distance);
                return(this);
            }
        } else {//no col trees = a sphere
            // compute real distance
            distance = (end-start).Magnitude() * distance;
            
            VSFileSystem::vs_dprintf(3,"Beam collide with %p, distance %f\n",this,distance);
            return(this);
        }
    } else {
        return (NULL);
    }
    return(NULL);
}
Exemplo n.º 3
0
void rayFactory(std::vector<Ray*> &rays, Camera &c, ViewPlane &v)
{
    
    c.calcUVW();
    //Used for calculating Simple Perspective Camera
    if (c.distance > 0.0) {
        for (double i = ((v.height/2)-(v.pixelsize/2)); i >= (((v.height/2) * -1)); i -= v.pixelsize) {
            for (double j = (((v.width/2) * -1)+(v.pixelsize/2)); j <=((v.width/2)); j += v.pixelsize) {
                
                Vec3 rayOrigin(c.center);
                Vec3 direction = (j * c.u + i *c.v) - c.distance * c.w;
                direction.normalize();
                Ray *addRay = new Ray(rayOrigin, direction);
                rays.push_back(addRay);
            }
        }
    }
    //Used for calculating Perspective Camera

    if (c.angle > 0.0) {
        c.distance =(v.width/2.0)/(sin(DEG2RAD(c.angle)))/cos((DEG2RAD(c.angle)));
        for (double i = ((v.height/2)-(v.pixelsize/2)); i >= (((v.height/2) * -1)); i -= v.pixelsize) {
            for (double j = (((v.width/2) * -1)+(v.pixelsize/2)); j <=((v.width/2)); j += v.pixelsize) {
                Vec3 rayOrigin(c.center);
                Vec3 direction = (j * c.u + i *c.v) - c.distance * c.w;
                direction.normalize();
                Ray *addRay = new Ray(rayOrigin, direction);
                rays.push_back(addRay);
            }
        }
    }
    //Used for calculating Orthographic Camera
    if (c.angle == 0.0 && c.distance == 0.0) {
        for (double i = ((v.height/2)-(v.pixelsize/2)); i >= (((v.height/2) * -1)); i -= v.pixelsize) {
            for (double j = (((v.width/2) * -1)+(v.pixelsize/2)); j <=((v.width/2)); j += v.pixelsize) {
                Vec3 rayOrigin(j,i, c.center.z());
                Ray *addRay = new Ray(rayOrigin, c.direction);
                rays.push_back(addRay);
            }
        }
    }
}
Exemplo n.º 4
0
static Eigen::Vector3d mapToSphere(
	Eigen::Matrix4d invProjMatrix, 
	Eigen::Vector2d const p, 
	Eigen::Vector3d viewSphereCenter, 
	double viewSpaceRadius) {

	Eigen::Vector4d viewP = invProjMatrix * Eigen::Vector4d(p(0), p(1), -1.0, 1.0);
	//viewP(0) /= viewP(3);
	//viewP(1) /= viewP(3);
	//viewP(2) /= viewP(3);

	Eigen::Vector3d rayOrigin(0.0, 0.0, 0.0);
	Eigen::Vector3d rayDir(viewP(0), viewP(1), viewP(2));
	rayDir.normalize();

	Eigen::Vector3d CO = rayOrigin - viewSphereCenter;

	double a = 1.0;
	double bPrime = CO.dot(rayDir);
	double c = CO.dot(CO) - viewSpaceRadius * viewSpaceRadius;

	double delta = bPrime * bPrime - a * c;

	if (delta < 0.0) {
		double t = -CO.z() / rayDir.z();
		Eigen::Vector3d point = rayOrigin + t * rayDir;
		Eigen::Vector3d dir = point - viewSphereCenter;
		dir.normalize();
		return viewSphereCenter + dir * viewSpaceRadius;
	}

	double root[2] = { (-bPrime - sqrt(delta)) / a, (-bPrime + sqrt(delta)) / a };

	if (root[0] >= 0.0) {
		Eigen::Vector3d intersectionPoint = rayOrigin + root[0] * rayDir;
		return intersectionPoint;
	}
	else if (root[1] >= 0.0) {
		Eigen::Vector3d intersectionPoint = rayOrigin + root[1] * rayDir;
		return intersectionPoint;
	}
	else {
		double t = -CO.z() / rayDir.z();
		Eigen::Vector3d point = rayOrigin + t * rayDir;
		Eigen::Vector3d dir = point - viewSphereCenter;
		dir.normalize();
		return viewSphereCenter + dir * viewSpaceRadius;
	}
}
void SimpleVolumeRenderer::draw()
{
  float t = GLFWTime::getCurrentTime();
  Camera& c = RenderManager::getInstance().getMainCamera();
  mat4 p = c.getProjection();
  mat4 mv = c.getModelview();
  vec3 eyePos =  c.getEyePosition() + _eyeOffset;

  float fov = c.getFieldOfView();
  float s = 2.0f;
  mat4 xform = glm::scale(vec3(s, s, s));
  mv = mv * xform;
  
  eyePos = vec3(glm::inverse(mv)  * vec4(eyePos, 1.0f));

  mv = mv * glm::rotate(GLFWTime::getCurrentTime()*0.5f, vec3(0, 1, 0));

  GLUtil::clear(true, true, false);
  GLUtil::setDepthTest(false);
  GLUtil::cullBackFaces();
  GLUtil::cullOn();
  GLUtil::setBlend(true);
  GLUtil::setBlendFuncToComposite();
  _shader->bind();

  _shader->setUniform("ModelviewProjection", p*mv);
  _shader->setUniform("Modelview", mv);
  _shader->setUniform("ViewMatrix", mv);
  _shader->setUniform("ProjectionMatrix", p);
  _shader->setUniform("RayStartPoints", 1);
  _shader->setUniform("RayStopPoints", 2);
  _shader->setUniform("EyePosition", eyePos);

  
  vec4 rayOrigin(glm::transpose(mv) * vec4(eyePos,1));
  _shader->setUniform("RayOrigin", vec3(rayOrigin));
  

  float focalLength = 1.0f / tan(fov / 2);
  _shader->setUniform("FocalLength", focalLength);
  _shader->setUniform("WindowSize", _screenDim.x, _screenDim.y);

  _mesh->drawBuffers();
  _shader->unbind();

}
Exemplo n.º 6
0
void Player::Raycast(const GameContext& gameContext)
{
	GameScene* scene = GetScene();

	XMFLOAT3 pos = GetTransform()->GetPosition();
	XMFLOAT3 fw = GetTransform()->GetForward();
	PxVec3 rayOrigin(pos.x,pos.y + 1.f,pos.z), rayDirection(fw.x,fw.y,fw.z);
	rayOrigin.x += fw.x * 2.5f;
	rayOrigin.z += fw.z * 2.5f;

	const PxU32 bufSize = 20;
	PxRaycastHit hit[bufSize];
	PxRaycastBuffer buf(hit, bufSize); // [out] Blocking and touching hits will be stored here

	if(scene->GetPhysxProxy()->Raycast(rayOrigin, rayDirection, 5000, buf))
	{
		for(PxU32 i = 0; i < buf.nbTouches; ++i)
		{
			BaseComponent* component = static_cast<BaseComponent*>(buf.touches[i].actor->userData);
			GameObject* go = component->GetGameObject();
			string name = go->GetName();	
			cout << "RAYCAST OBJECT: " << name << endl;		

			if(name == "Enemy")
			{
				Enemy* enemy = reinterpret_cast<Enemy*>(go);
				int dmg = 12.5f;
				enemy->Damage(dmg);
			}
		}

		PxVec3 vel = rayDirection * 1000;
		auto laser = new Laser(XMFLOAT3(vel.x, vel.y, vel.z));
		AddChild(laser);
	}
}
Exemplo n.º 7
0
// ray-sphere intersection test from Graphics Gems p.388
// **NOTE** There is a bug in this Graphics Gem.  If the origin
// of the ray is *inside* the sphere being tested, it reports the
// wrong intersection location.  This code has a fix for the bug.
bool  SBM_rayIntersectsSphere(const float *point,const float *direction,const float *_center,float radius,float &t)
{
  bool ret = false;

  NxVec3 rayOrigin(point);
  NxVec3 dir(direction);
  NxVec3 center(_center);

	// notation:
	// point E  = rayOrigin
	// point O  = sphere center

	NxVec3 EO = center - rayOrigin;
  NxVec3 V = dir;

  float dist2 = EO.x*EO.x + EO.y*EO.y + EO.z * EO.z;

  float r2 = radius*radius;

  // Bug Fix For Gem, if origin is *inside* the sphere, invert the
  // direction vector so that we get a valid intersection location.
  if ( dist2 < r2 )
    V*=-1;

	float v = EO.dot(V);

	float disc = r2 - (EO.magnitudeSquared() - v*v);

	if (disc > 0.0f)
	{
    t = sqrtf(disc);
		ret = true;
	}

	return ret;
}
int FFDDistanceGridDiscreteIntersection::computeIntersection(Ray& e2, FFDDistanceGridCollisionElement& e1, OutputVector* contacts)
{
    Vector3 rayOrigin(e2.origin());
    Vector3 rayDirection(e2.direction());
    const double rayLength = e2.l();

    DistanceGrid* grid1 = e1.getGrid();
    FFDDistanceGridCollisionModel::DeformedCube& c1 = e1.getCollisionModel()->getDeformCube(e1.getIndex());

    // Center of the sphere
    const Vector3 center1 = c1.center;
    // Radius of the sphere
    const double radius1 = c1.radius;

    const Vector3 tmp = center1 - rayOrigin;
    double rayPos = tmp*rayDirection;
    const double dist2 = tmp.norm2() - (rayPos*rayPos);
    if (dist2 >= (radius1*radius1))
        return 0;

    double l0 = rayPos - sqrt(radius1*radius1 - dist2);
    double l1 = rayPos + sqrt(radius1*radius1 - dist2);
    if (l0 < 0) l0 = 0;
    if (l1 > rayLength) l1 = rayLength;
    if (l0 > l1) return 0; // outside of ray
    //const double dist = sqrt(dist2);
    //double epsilon = grid1->getCellWidth().norm()*0.1f;

    c1.updateFaces();
    DistanceGrid::Coord p1;
    const SReal cubesize = c1.invDP.norm();
    for(int i=0; i<100; i++)
    {
        rayPos = l0 + (l1-l0)*(i*0.01);
        p1 = rayOrigin + rayDirection*rayPos;
        // estimate the barycentric coordinates
        DistanceGrid::Coord b = c1.undeform0(p1);
        // refine the estimate until we are very close to the p2 or we are sure p2 cannot intersect with the object
        int iter;
        //SReal err1 = 1000.0f;
        bool found = false;
        for(iter=0; iter<5; ++iter)
        {
            DistanceGrid::Coord pdeform = c1.deform(b);
            DistanceGrid::Coord diff = p1-pdeform;
            SReal err = diff.norm();
            //if (iter>3)
            //    sout << "Iter"<<iter<<": "<<err1<<" -> "<<err<<" b = "<<b<<" diff = "<<diff<<" d = "<<grid1->interp(c1.initpos(b))<<""<<sendl;
            SReal berr = err*cubesize; if (berr>0.5f) berr=0.5f;
            if (b[0] < -berr || b[0] > 1+berr
                || b[1] < -berr || b[1] > 1+berr
                || b[2] < -berr || b[2] > 1+berr)
                break; // far from the cube
            if (err < 0.001f)
            {
                // we found the corresponding point, but is is only valid if inside the current cube
                if (b[0] > -0.1f && b[0] < 1.1f
                    && b[1] > -0.1f && b[1] < 1.1f
                    && b[2] > -0.1f && b[2] < 1.1f)
                {
                    found = true;
                }
                break;
            }
            //err1 = err;
            b += c1.undeformDir( b, diff );
        }
        if (found)
        {
            SReal d = grid1->interp(c1.initpos(b));
            if (d < 0)
            {
                // intersection found

                contacts->resize(contacts->size()+1);
                DetectionOutput *detection = &*(contacts->end()-1);

                detection->point[0] = e2.origin() + e2.direction()*rayPos;
                detection->point[1] = c1.initpos(b);
                detection->normal = e2.direction(); // normal in global space from p1's surface
                detection->value = d;
                detection->elem.first = e2;
                detection->elem.second = e1;
                detection->id = e2.getIndex();
                return 1;
            }
        }
        // else move along the ray
        //if (dot(Vector3(grid1->grad(c1.initpos(b))),rayDirection) < 0)
        //    rayPos += 0.5*d;
        //else
        //    rayPos -= 0.5*d;
    }
    return 0;
}
Exemplo n.º 9
0
void Mesh::generateHeightmap(const char* filename)
{
    // Shoot rays down from a point just above the max Y position of the mesh.
    // Compute ray-triangle intersection tests against the ray and this mesh to 
    // generate heightmap data.
    Vector3 rayOrigin(0, bounds.max.y + 10, 0);
    Vector3 rayDirection(0, -1, 0);
    Vector3 intersectionPoint;
    int minX = (int)ceil(bounds.min.x);
    int maxX = (int)floor(bounds.max.x);
    int minZ = (int)ceil(bounds.min.z);
    int maxZ = (int)floor(bounds.max.z);
    int width = maxX - minX + 1;
    int height = maxZ - minZ + 1;
    float* heights = new float[width * height];
    int index = 0;
    float minHeight = FLT_MAX;
    float maxHeight = FLT_MIN;
    for (int z = minZ; z <= maxZ; z++)
    {
        rayOrigin.z = (float)z;
        for (int x = minX; x <= maxX; x++)
        {
            float h;
            rayOrigin.x = (float)x;
            if (intersect(rayOrigin, rayDirection, vertices, parts, &intersectionPoint))
            {
                h = intersectionPoint.y;
            }
            else
            {
                h = 0;
                fprintf(stderr, "Warning: Heightmap triangle intersection failed for (%d, %d).\n", x, z);
            }
            if (h < minHeight)
                minHeight = h;
            if (h > maxHeight)
                maxHeight = h;
            heights[index++] = h;
        }
    }
    
    // Normalize the max height value
    maxHeight = maxHeight - minHeight;

    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    png_bytep row = NULL;

    FILE* fp = fopen(filename, "wb");
    if (fp == NULL)
    {
        fprintf(stderr, "Error: Failed to open file for writing: %s\n", filename);
        goto error;
    }

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png_ptr == NULL)
    {
        fprintf(stderr, "Error: Write struct creation failed: %s\n", filename);
        goto error;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL)
    {
        fprintf(stderr, "Error: Info struct creation failed: %s\n", filename);
        goto error;
    }

    png_init_io(png_ptr, fp);

    png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

    png_write_info(png_ptr, info_ptr);

    // Allocate memory for a single row of image data
    row = (png_bytep)malloc(3 * width * sizeof(png_byte));

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            // Write height value normalized between 0-255 (between min and max height)
            float h = heights[y*width + x];
            float nh = (h - minHeight) / maxHeight;
            png_byte b = (png_byte)(nh * 255.0f);
            
            int pos = x*3;
            row[pos] = row[pos+1] = row[pos+2] = b;
        }
        png_write_row(png_ptr, row);
    }

    png_write_end(png_ptr, NULL);
    DEBUGPRINT_VARG("> Saved heightmap: %s\n", filename);

error:
    if (heights)
        delete[] heights;
    if (fp)
        fclose(fp);
    if (row)
        free(row);
    if (info_ptr)
        png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
    if (png_ptr)
        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);

}
Exemplo n.º 10
0
int generateHeightmapChunk(void* threadData)
{
    HeightmapThreadData* data = (HeightmapThreadData*)threadData;

    Vector3 rayOrigin(0, data->rayHeight, 0);
    const Vector3& rayDirection = *data->rayDirection;
    const std::vector<Mesh*>& meshes = *data->meshes;
    float* heights = data->heights;

    Vector3 intersectionPoint;
    float minHeight = FLT_MAX;
    float maxHeight = -FLT_MAX;
    int index = data->heightIndex;

    int zi = 0;
    for (float z = data->minZ; zi < data->height; z += data->stepZ, ++zi)
    {
        LOG(1, "\r\t%d%%", (int)(((float)__processedHeightmapScanLines / __totalHeightmapScanlines) * 100.0f));

        rayOrigin.z = z;

        int xi = 0;
        for (float x = data->minX; xi < data->width; x += data->stepX, ++xi)
        {
            float h = -FLT_MAX;
            rayOrigin.x = x;

            for (unsigned int i = 0, count = meshes.size(); i < count; ++i)
            {
                // Pick the highest intersecting Y value of all meshes
                Mesh* mesh = meshes[i];

                // Perform a quick ray/bounding box test to quick-out
                if (!intersect(rayOrigin, rayDirection, mesh->bounds.min, mesh->bounds.max))
                    continue;

                // Compute the intersection point of ray with mesh
                if (intersect(rayOrigin, rayDirection, mesh->vertices, mesh->parts, &intersectionPoint))
                {
                    if (intersectionPoint.y > h)
                    {
                        h = intersectionPoint.y;

                        // Update min/max height values
                        if (h < minHeight)
                            minHeight = h;
                        if (h > maxHeight)
                            maxHeight = h;
                    }
                }
            }

            // Update the glboal height array
            heights[index++] = h;

            if (h == -FLT_MAX)
                ++__failedRayCasts;
        }

        ++__processedHeightmapScanLines;
    }

    // Update min/max height for this thread data
    data->minHeight = minHeight;
    data->maxHeight = maxHeight;

    return 0;
}
//--------------------------------------------------------------------------------
void CObjCHAR_Collision::GetCollisionStateAvatar ( void )
//--------------------------------------------------------------------------------
{
	CollisionSphere * sp;
	HNODE hNode;
	const float MAX_DISTANCE_SQUARE = 2000.0f*2000.0f;
	D3DXVECTOR3 prevCenter, closestCenter;
	float distance_ , distanceLimit, distanceLimitBody;
	D3DXVECTOR3 DIRECTION_DOWN(0, 0, -1) ,DIRECTION_MOVE;
	D3DXVECTOR3 rayOrigin(m_vFoot.x,m_vFoot.y, 1.8f*(75.0f)+m_vFoot.z) ;
    D3DXVECTOR3 rayOriginBody(m_vPrevious.x, m_vPrevious.y,m_vPrevious.z+1.5f*(75.0f));
    bool BodyRay = false;
	bool SphereResetOnOff = false;
    
	
	distanceLimit =1.8f*(75.0f);
	DIRECTION_MOVE = m_vFoot - m_vPrevious;
    distanceLimitBody = D3DXVec3Length(&DIRECTION_MOVE);  
    
	if(distanceLimitBody >0.001f)   
	{
		DIRECTION_MOVE /= distanceLimitBody;
	    BodyRay = true;
	}

	bool isFalling = (m_vVelocity.x == 0) && (m_vVelocity.y == 0); // not moving forward

	if(isFalling == true)
    isFalling = true;
	
	m_State = CollisionState::CS_NONE;

	for (std::vector<CollisionSphere>::iterator it = m_Spheres.begin(); it != m_Spheres.end(); ++it) {
		sp = &(*it);
		prevCenter = sp->center - m_vVelocity;

		if(sp->state == CollisionState::CS_FOOT_FRONT && SphereResetOnOff)
		sp->center.z = m_vFoot.z;
		
		for (std::vector<HNODE>::iterator itnode = m_ContactNodes.begin(); itnode != m_ContactNodes.end(); ++itnode) {
			hNode = (*itnode);

					
			if (sp->state == CollisionState::CS_BODY_FRONT) {
				if (isFalling) continue;
				if (::intersectNodeTriSphere( hNode, sp->center,sp->radius)) {
					
					if (getHeightCollisionLevelOnOff(hNode))
					{
						SphereResetOnOff = CollisionResponseBodyHeight(hNode);
						continue;
					} 
					if(m_hCollisionBlockNode != NULL)
					{
						CollisionResponseBody_Avatar();
                        break;
					}
					else
					{
						sp->collided.push_back( hNode );
						m_State = CollisionState::CS_BODY_FRONT;
						LogString(LOG_DEBUG, "CS_BODY_FRONT\n");
						return;
					}

				}   
			
			    if(BodyRay)
			    {
					distance_ = ::shootRayVec3( hNode, 1 /* nearest */, rayOriginBody, DIRECTION_MOVE );
					if(distance_ < distanceLimitBody)
					{
						
						if (getHeightCollisionLevelOnOff(hNode))
						{
							SphereResetOnOff = CollisionResponseBodyHeight(hNode);
							continue;
						} 
						if(m_hCollisionBlockNode != NULL)
						{
							CollisionResponseBody_Avatar();
							break;
						}
						else
						{
							sp->collided.push_back( hNode );
							m_State = CollisionState::CS_BODY_FRONT;
							LogString(LOG_DEBUG, "CS_BODY_FRONT\n");
							return;
						}

					}
			    }
			
			}
			else if (sp->state == CollisionState::CS_FOOT_FRONT) {
				
				if (::intersectNodeTriSphere( hNode, sp->center,sp->radius)) {
					
					if (getHeightCollisionLevelOnOff(hNode))
					{
						SphereResetOnOff = CollisionResponseBodyHeight(hNode);
						continue;
					} 
					if(m_hCollisionBlockNode != NULL)
					{
						CollisionResponseBody_Avatar();
						break;
					}
					else
					{
						sp->collided.push_back( hNode );
						m_State = CollisionState::CS_BODY_FRONT;
						LogString(LOG_DEBUG, "CS_BODY_FRONT\n");
						return;
					}
				}            
				
			}
			else if (sp->state == CollisionState::CS_FOOT) {
				sp->collided.push_back( hNode );
				if (isFalling && ::intersectNodeTriSphere( hNode, sp->center,sp->radius)) {
					m_State = CollisionState::CS_FOOT;
				    if (getHeightCollisionLevelOnOff(hNode))
						m_footCollisionPass = true;
				
				}
				else if (::intersectNodeTriSphere( hNode, sp->center, sp->radius )) {
					m_State = CollisionState::CS_FOOT;
				    if (getHeightCollisionLevelOnOff(hNode))
						m_footCollisionPass = true;
				}
				else{
                    distance_ = ::shootRayVec3( hNode, 1 /* nearest */, rayOrigin, DIRECTION_DOWN );
                    if(distance_ < distanceLimit)
					{
						m_State = CollisionState::CS_FOOT; 
					    if (getHeightCollisionLevelOnOff(hNode))
							m_footCollisionPass = true;
					}
                }
				continue;
			}
			else {
				LogString( LOG_DEBUG, "error: Cannot reach here. CObjCHAR_Collision.cpp" );
				// cannot reach here
			}
		}
	}
}