void GameTrack::updateCarSensors(GameCar* car) { if(!car->getSensorEnabled()) return; float* data=car->getSensorData(); float spread=car->getSensorSpread(); int pixels=car->getSensorPixels(); float len=car->getSensorLength(); cpSpace* space=sim->get_space(); cpBody* body=car->physic_object->get_body(); for(int i=0;i<pixels;i++) { float angle=car->getSensorAngle(i); float y_offset=0.8; //fabs(angle)/45; cpVect start={0,y_offset}; cpVect end=cpvmult(cpvforangle(degToRad(angle)),len); start=cpBodyLocal2World(body,start); end=cpBodyLocal2World(body,end); cpSegmentQueryInfo info; cpSpaceSegmentQueryFirst(space,start,end,car->getLayers(),CP_NO_GROUP,&info); data[i]=info.t; } }
shared_ptr<Shape> Space::segmentQueryFirst(Vect a, Vect b, Layers layers, Group group, SegmentQueryInfo* const info) const { cpSegmentQueryInfo i; cpShapeFilter filter{static_cast<cpGroup>(group), static_cast<cpBitmask>(layers), static_cast<cpBitmask>(layers)}; auto rtn = cpSpaceSegmentQueryFirst(space, a, b, 0, filter, &i); if (info) { info->t = i.alpha; info->n = i.normal; } return findPtr(rtn); }
__declspec( dllexport ) void segmentqueryfirst( const void * _in, int in_size, void * _out, int out_sz ) { cpSegmentQueryInfo info; cpShape * shape = cpSpaceSegmentQueryFirst(&mSpace,PEEKVECT(INPUT_MEMBLOCK,0),PEEKVECT(INPUT_MEMBLOCK,8),PEEKINT(INPUT_MEMBLOCK,16),PEEKINT(INPUT_MEMBLOCK,20),&info); if (shape == NULL) { POKEINT(OUTPUT_MEMBLOCK,0,0); return; } POKEINT(OUTPUT_MEMBLOCK,0,((Variable*)shape->data)->mCBPtr); POKEFLOAT(OUTPUT_MEMBLOCK,4,info.t); POKEVECT(OUTPUT_MEMBLOCK,8,info.n); }
static void draw(void) { ChipmunkDemoDefaultDrawImpl(); cpVect start = QUERY_START; cpVect end = ChipmunkDemoMouse; ChipmunkDebugDrawSegment(start, end, RGBAColor(0,1,0,1)); ChipmunkDemoPrintString("Query: Dist(%f) Point%s, ", cpvdist(start, end), cpvstr(end)); cpSegmentQueryInfo segInfo = {}; if(cpSpaceSegmentQueryFirst(space, start, end, CP_ALL_LAYERS, CP_NO_GROUP, &segInfo)){ cpVect point = cpSegmentQueryHitPoint(start, end, segInfo); // Draw red over the occluded part of the query ChipmunkDebugDrawSegment(point, end, RGBAColor(1,0,0,1)); // Draw a little blue surface normal ChipmunkDebugDrawSegment(point, cpvadd(point, cpvmult(segInfo.n, 16)), RGBAColor(0,0,1,1)); // Draw a little red dot on the hit point. ChipmunkDebugDrawPoints(3, 1, &point, RGBAColor(1,0,0,1)); ChipmunkDemoPrintString("Segment Query: Dist(%f) Normal%s", cpSegmentQueryHitDist(start, end, segInfo), cpvstr(segInfo.n)); } else { ChipmunkDemoPrintString("Segment Query (None)"); } cpNearestPointQueryInfo nearestInfo = {}; cpSpaceNearestPointQueryNearest(space, ChipmunkDemoMouse, 100.0, CP_ALL_LAYERS, CP_NO_GROUP, &nearestInfo); if(nearestInfo.shape){ // Draw a grey line to the closest shape. ChipmunkDebugDrawPoints(3, 1, &ChipmunkDemoMouse, RGBAColor(0.5, 0.5, 0.5, 1.0)); ChipmunkDebugDrawSegment(ChipmunkDemoMouse, nearestInfo.p, RGBAColor(0.5, 0.5, 0.5, 1.0)); // Draw a red bounding box around the shape under the mouse. if(nearestInfo.d < 0) ChipmunkDebugDrawBB(cpShapeGetBB(nearestInfo.shape), RGBAColor(1,0,0,1)); } }
static void update(int ticks) { messageString[0] = '\0'; cpVect start = cpvzero; cpVect end = /*cpv(0, 85);//*/mousePoint; cpVect lineEnd = end; { char infoString[1024]; sprintf(infoString, "Query: Dist(%f) Point%s, ", cpvdist(start, end), cpvstr(end)); strcat(messageString, infoString); } cpSegmentQueryInfo info = {}; if(cpSpaceSegmentQueryFirst(space, start, end, CP_ALL_LAYERS, CP_NO_GROUP, &info)){ cpVect point = cpSegmentQueryHitPoint(start, end, info); lineEnd = cpvadd(point, cpvzero);//cpvmult(info.n, 4.0f)); char infoString[1024]; sprintf(infoString, "Segment Query: Dist(%f) Normal%s", cpSegmentQueryHitDist(start, end, info), cpvstr(info.n)); strcat(messageString, infoString); } else { strcat(messageString, "Segment Query (None)"); } cpSegmentShapeSetEndpoints(querySeg, start, lineEnd); cpShapeCacheBB(querySeg); // force it to update it's collision detection data so it will draw // normal other stuff. int steps = 1; cpFloat dt = 1.0f/60.0f/(cpFloat)steps; for(int i=0; i<steps; i++){ cpSpaceStep(space, dt); } }
cp::Shape *Space::segmentQueryFirst(const cp::Vect& start,const cp::Vect& end,cpLayers layers,cpGroup group,cpSegmentQueryInfo *out) { cpShape * temp = cpSpaceSegmentQueryFirst(space,start,end,layers,group,out); return static_cast<cp::Shape *>(temp ? temp->data : 0); }
void Laser::Update(float a_Dt) { m_Sprite.sprite->setPosition(m_StartPos); //raycast to determine the max length of this laser cpVect cpStartPos; cpStartPos.x = m_StartPos.x; cpStartPos.y = m_StartPos.y; sf::Vector2f addVector = m_FacingDir * MAX_LASER_DIST; sf::Vector2f sfEndPos = m_StartPos + addVector; cpVect cpEndPos; cpEndPos.x = sfEndPos.x; cpEndPos.y = sfEndPos.y; cpSegmentQueryInfo info; info.n = cpv(0,0); info.t = 0; info.shape = NULL; //cast ray cpShape* collided = cpSpaceSegmentQueryFirst(&m_Space, cpStartPos, cpEndPos, ~(cpLayers)COLLIDABLE::GLASSBLOCK, CP_NO_GROUP, &info); //grab some helper data m_MaxLength = float(min( cpSegmentQueryHitDist(cpStartPos, cpEndPos, info), MAX_LASER_DIST )); m_hitPoint = cpSegmentQueryHitPoint(cpStartPos, cpEndPos, info); //extend or reduce the laser to the max length if(m_CurLength < m_MaxLength) { //update end position //f**k you, lasers have velocity (but only when they're growing) sf::Vector2f newDist = m_FacingDir * LASER_VELOCITY * a_Dt; m_EndPos += newDist; m_CurLength += VectorMagnitude(newDist); //update sprite float baseSize = float(m_Sprite.sprite->getTexture()->getSize().x); sf::Vector2f diff = m_EndPos - m_StartPos; float newSize = VectorMagnitude(diff); m_Sprite.sprite->setScale(newSize / baseSize, 1); //m_resMgr.RemoveDrawableSprite(&m_endSprite); } else { //update end position m_EndPos = m_StartPos + m_FacingDir * m_MaxLength; sf::Vector2f diff = m_EndPos - m_StartPos; m_endSprite.sprite->setPosition(m_EndPos); //sf::Vector2f diff = m_blockPos - m_StartPos; m_CurLength = VectorMagnitude(diff); //update sprite float baseSize = float(m_Sprite.sprite->getTexture()->getSize().x); m_Sprite.sprite->setScale(m_CurLength / baseSize, 1); //m_resMgr.AddDrawableSprite(&m_endSprite); m_endDrawnHack = true; } /*if(m_pNextChainSegment) { m_pNextChainSegment->Update(a_Dt); }*/ }
void Laser::Update(float a_Dt) { //raycast to determine the max length of this laser cpVect cpStartPos; cpStartPos.x = m_StartPos.x; cpStartPos.y = m_StartPos.y; sf::Vector2f addVector = m_FacingDir * MAX_LASER_DIST; sf::Vector2f sfEndPos = m_StartPos + addVector; cpVect cpEndPos; cpEndPos.x = sfEndPos.x; cpEndPos.y = sfEndPos.y; cpSegmentQueryInfo info; info.n = cpv(0,0); info.t = 0; info.shape = NULL; //cast ray cpShape* collided = cpSpaceSegmentQueryFirst(&m_Space, cpStartPos, cpEndPos, CP_ALL_LAYERS, CP_NO_GROUP, &info); //grab some helper data m_MaxLength = float(min( cpSegmentQueryHitDist(cpStartPos, cpEndPos, info), MAX_LASER_DIST )); m_hitPoint = cpSegmentQueryHitPoint(cpStartPos, cpEndPos, info); GameObject* pGameObj = NULL; if(collided) pGameObj = (GameObject*)collided->data; /* //check to see if we hit the player Player* pPlayer = NULL; bool colPlayer = false; if(pGameObj && pGameObj->GetType() == PLAYER) { //TODO: only reflect if the player is within 180 degrees of us? //reflect le laser if(!m_pNextChainSegment) ExtendNewSegment(m_FacingDir); pPlayer = (Player*)pGameObj; m_MaxLength = pPlayer->GetPosition().x; colPlayer = true; } else { //stop reflecting laser Laser* pCurLaser = m_pNextChainSegment; m_pNextChainSegment = NULL; while(pCurLaser) { m_resMgr.RemoveDrawableSprite(pCurLaser->GetSprite()); pCurLaser = pCurLaser->GetNextSegment(); delete pCurLaser; } }*/ //extend or reduce the laser to the max length if(m_CurLength < m_MaxLength) { //update end position //f**k you, lasers have velocity (but only when they're growing) sf::Vector2f newDist = m_FacingDir * LASER_VELOCITY * a_Dt; m_EndPos += newDist; m_CurLength += VectorMagnitude(newDist); //update sprite float baseSize = float(m_Sprite.sprite->getTexture()->getSize().x); sf::Vector2f diff = m_EndPos - m_StartPos; float newSize = VectorMagnitude(diff); m_Sprite.sprite->setScale(newSize / baseSize, 1); if(m_endDrawn) { m_resMgr.RemoveDrawableSprite(&m_endSprite); m_resMgr.RemoveDrawableSprite(&m_reflectSprite); m_endDrawn = false; } } else if(m_CurLength > m_MaxLength) { bool colPlayer = false; //update end position m_EndPos = m_StartPos + m_FacingDir * m_MaxLength; sf::Vector2f diff = m_EndPos - m_StartPos; m_CurLength = VectorMagnitude(diff); //update sprite float baseSize = float(m_Sprite.sprite->getTexture()->getSize().x); m_Sprite.sprite->setScale(m_CurLength / baseSize, 1); //Show the end sprite if (!m_endDrawn) { if(colPlayer) m_resMgr.AddDrawableSprite(&m_reflectSprite); else m_resMgr.AddDrawableSprite(&m_endSprite); m_endDrawn = true; } m_endDrawnHack = true; } /* //update reflected laser segment if(pPlayer && m_pNextChainSegment) { //get the player's angle and position m_pNextChainSegment->SetPosition(pPlayer->GetPosition()); m_pNextChainSegment->SetFacingDir(pPlayer->GetRedirectDir()); //assumes already normalised } //update endsprite if(m_endDrawn) { //m_endSprite.sprite->setPosition(m_Sprite.sprite->getPosition().x+m_Sprite.sprite->getScale().x,m_Sprite.sprite->getPosition().y); if(colPlayer && pPlayer) { sf::Vector2u sprSize = pPlayer->GetSprite()->sprite->getTexture()->getSize();//sprSize sf::Vector2f playerPos = pPlayer->GetPosition(); m_reflectSprite.sprite->setPosition(playerPos.x, playerPos.y); } else m_endSprite.sprite->setPosition(float(m_hitPoint.x)-4, float(m_hitPoint.y)-16); if(m_pAnimator) m_pAnimator->Update(a_Dt); } */ }