void CollisionShape::SetCustomConvexHull(CustomGeometry* custom, const Vector3& scale, const Vector3& position, const Quaternion& rotation) { if (!custom) { LOGERROR("Null custom geometry, can not set convex hull"); return; } if (!custom->GetNode()) { LOGERROR("Custom geometry has null scene node, can not set convex hull"); return; } if (model_) UnsubscribeFromEvent(model_, E_RELOADFINISHED); shapeType_ = SHAPE_CONVEXHULL; model_.Reset(); lodLevel_ = 0; size_ = scale; position_ = position; rotation_ = rotation; customGeometryID_ = custom->GetNode()->GetID(); UpdateShape(); NotifyRigidBody(); MarkNetworkUpdate(); }
void C4Object::Stabilize() { // def allows stabilization? if (Def->NoStabilize) return; // normalize angle C4Real nr = fix_r; while (nr < itofix(-180)) nr += 360; while (nr > itofix(180)) nr -= 360; if (nr != Fix0) if (Inside<C4Real>(nr,itofix(-StableRange),itofix(+StableRange))) { // Save step undos C4Real lcobjr=fix_r; C4Shape lshape=Shape; // Try rotation fix_r=Fix0; UpdateShape(); if (ContactCheck(GetX(),GetY())) { // Undo rotation Shape=lshape; fix_r=lcobjr; } else { // Stabilization okay UpdateFace(true); } } }
void wxSFControlShape::SetControl(wxWindow *ctrl, bool fit) { if( m_pControl ) m_pControl->Reparent( m_pPrevParent ); m_pControl = ctrl; if( m_pControl ) { m_pPrevParent = ctrl->GetParent(); if( m_pParentManager ) { wxSFShapeCanvas *pCanvas = ((wxSFDiagramManager*)m_pParentManager)->GetShapeCanvas(); // reparent GUI control if necessary if( pCanvas && ( (wxWindow*)pCanvas != m_pPrevParent ) ) m_pControl->Reparent( (wxWindow*)pCanvas ); // redirect mouse events to the event sink for their delayed processing m_pControl->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink); m_pControl->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink); m_pControl->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink); m_pControl->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink); m_pControl->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink); m_pControl->Connect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink); m_pControl->Connect(wxEVT_MOTION, wxMouseEventHandler(EventSink::_OnMouseMove), NULL, m_pEventSink); m_pControl->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(EventSink::_OnKeyDown), NULL, m_pEventSink); m_pControl->Connect(wxEVT_SIZE, wxSizeEventHandler(EventSink::_OnSize), NULL, m_pEventSink); } if( fit ) UpdateShape(); UpdateControl(); } }
Point3 HelixObject::InterpCurve3D(TimeValue t, int curve, float param, int ptype) { if(param < 0.0f) param = 0.0f; else if(param > 1.0f) param = 1.0f; assert(curve==0); UpdateShape(t); switch(ptype) { case PARAM_SIMPLE: { float r = radius1 + deltaRadius * param; float angle = totalRadians * param; float hpct = param; if(bias > 0.0f) hpct = 1.0f - (float)pow(1.0f - param, power ); else if(bias < 0.0f) hpct = (float)pow(param, power); return Point3(r * (float)cos(angle),r * (float)sin(angle),height * hpct); } case PARAM_NORMALIZED: return shape.lines[0].InterpCurve3D(param, POLYSHP_INTERP_NORMALIZED); } assert(0); return Point3(0,0,0); }
void CollisionShape::ApplyAttributes() { if (recreateShape_) { UpdateShape(); NotifyRigidBody(); } }
void CollisionShape::HandleTerrainCreated(StringHash eventType, VariantMap& eventData) { if (shapeType_ == SHAPE_TERRAIN) { UpdateShape(); NotifyRigidBody(); } }
void wxSFControlShape::FitToChildren() { wxRect ctrlRct = wxRect(m_pControl->GetPosition(), m_pControl->GetSize()); wxRect bbRct = GetBoundingBox(); wxSFRectShape::FitToChildren(); if( bbRct.Intersects(ctrlRct) && !bbRct.Contains(ctrlRct) ) UpdateShape(); }
void CollisionShape::SetSize(const Vector3& size) { if (size != size_) { size_ = size; UpdateShape(); NotifyRigidBody(); MarkNetworkUpdate(); } }
void CollisionShape::HandleModelReloadFinished(StringHash eventType, VariantMap& eventData) { if (physicsWorld_) physicsWorld_->RemoveCachedGeometry(model_); if (shapeType_ == SHAPE_TRIANGLEMESH || shapeType_ == SHAPE_CONVEXHULL) { UpdateShape(); NotifyRigidBody(); } }
void CollisionShape::SetShapeType(ShapeType type) { if (type != shapeType_) { shapeType_ = type; UpdateShape(); NotifyRigidBody(); MarkNetworkUpdate(); } }
Point3 HelixObject::TangentCurve3D(TimeValue t, int curve, float param, int ptype) { assert(curve==0); UpdateShape(t); float pp = param - perPiece / 100.0f; if(pp < 0.0f) pp = 0.0f; float np = param + perPiece / 100.0f; if(np < 0.0f) np = 0.0f; Point3 prev = InterpCurve3D(t, 0, pp, ptype); Point3 next = InterpCurve3D(t, 0, np, ptype); return(Normalize(next-prev)); }
void CollisionShape::SetLodLevel(unsigned lodLevel) { if (lodLevel != lodLevel_) { lodLevel_ = lodLevel; if (shapeType_ >= SHAPE_TRIANGLEMESH) { UpdateShape(); NotifyRigidBody(); } MarkNetworkUpdate(); } }
void NodeSimpleShape::Transform( TransformBase& Trans ) { // Transform the Shape Trans.Transform((DocCoord*)Parallel, 4); // re-create the path and update its bounding rectangle UpdateShape(); // Mark the bounding rect as invalid InvalidateBoundingRect(); // Transform all the children... TransformChildren(Trans); }
void CollisionShape::SetStaticPlane(const Vector3& position, const Quaternion& rotation) { if (model_) UnsubscribeFromEvent(model_, E_RELOADFINISHED); shapeType_ = SHAPE_STATICPLANE; position_ = position; rotation_ = rotation; model_.Reset(); customGeometryID_ = 0; UpdateShape(); NotifyRigidBody(); MarkNetworkUpdate(); }
void CollisionShape::SetCone(float diameter, float height, const Vector3& position, const Quaternion& rotation) { if (model_) UnsubscribeFromEvent(model_, E_RELOADFINISHED); shapeType_ = SHAPE_CONE; size_ = Vector3(diameter, height, diameter); position_ = position; rotation_ = rotation; model_.Reset(); customGeometryID_ = 0; UpdateShape(); NotifyRigidBody(); MarkNetworkUpdate(); }
void CollisionShape::SetModel(Model* model) { if (model != model_) { if (model_) UnsubscribeFromEvent(model_, E_RELOADFINISHED); model_ = model; if (shapeType_ >= SHAPE_TRIANGLEMESH) { UpdateShape(); NotifyRigidBody(); } MarkNetworkUpdate(); } }
void CollisionShape::SetTerrain() { Terrain* terrain = GetComponent<Terrain>(); if (!terrain) { LOGERROR("No terrain component, can not set terrain shape"); return; } if (model_) UnsubscribeFromEvent(model_, E_RELOADFINISHED); shapeType_ = SHAPE_TERRAIN; UpdateShape(); NotifyRigidBody(); MarkNetworkUpdate(); }
void CollisionShape::SetConvexHull(Model* model, unsigned lodLevel, const Vector3& scale, const Vector3& position, const Quaternion& rotation) { if (!model) { LOGERROR("Null model, can not set convex hull"); return; } if (model_) UnsubscribeFromEvent(model_, E_RELOADFINISHED); shapeType_ = SHAPE_CONVEXHULL; model_ = model; lodLevel_ = lodLevel; size_ = scale; position_ = position; rotation_ = rotation; customGeometryID_ = 0; UpdateShape(); NotifyRigidBody(); MarkNetworkUpdate(); }
bool AreaTrigger::Create(uint32 spellMiscId, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, uint32 spellXSpellVisualId, ObjectGuid const& castId, AuraEffect const* aurEff) { _targetGuid = target ? target->GetGUID() : ObjectGuid::Empty; _aurEff = aurEff; SetMap(caster->GetMap()); Relocate(pos); if (!IsPositionValid()) { TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (spellMiscId %u) not created. Invalid coordinates (X: %f Y: %f)", spellMiscId, GetPositionX(), GetPositionY()); return false; } _areaTriggerMiscTemplate = sAreaTriggerDataStore->GetAreaTriggerMiscTemplate(spellMiscId); if (!_areaTriggerMiscTemplate) { TC_LOG_ERROR("entities.areatrigger", "AreaTrigger (spellMiscId %u) not created. Invalid areatrigger miscid (%u)", spellMiscId, spellMiscId); return false; } Object::_Create(ObjectGuid::Create<HighGuid::AreaTrigger>(GetMapId(), GetTemplate()->Id, caster->GetMap()->GenerateLowGuid<HighGuid::AreaTrigger>())); SetEntry(GetTemplate()->Id); SetDuration(duration); SetObjectScale(1.0f); SetGuidValue(AREATRIGGER_CASTER, caster->GetGUID()); SetGuidValue(AREATRIGGER_CREATING_EFFECT_GUID, castId); SetUInt32Value(AREATRIGGER_SPELLID, spell->Id); SetUInt32Value(AREATRIGGER_SPELL_FOR_VISUALS, spell->Id); SetUInt32Value(AREATRIGGER_SPELL_X_SPELL_VISUAL_ID, spellXSpellVisualId); SetUInt32Value(AREATRIGGER_TIME_TO_TARGET_SCALE, GetMiscTemplate()->TimeToTargetScale != 0 ? GetMiscTemplate()->TimeToTargetScale : GetUInt32Value(AREATRIGGER_DURATION)); SetFloatValue(AREATRIGGER_BOUNDS_RADIUS_2D, GetTemplate()->MaxSearchRadius); SetUInt32Value(AREATRIGGER_DECAL_PROPERTIES_ID, GetMiscTemplate()->DecalPropertiesId); for (uint8 scaleCurveIndex = 0; scaleCurveIndex < MAX_AREATRIGGER_SCALE; ++scaleCurveIndex) if (GetMiscTemplate()->ExtraScale.Data.Raw[scaleCurveIndex]) SetUInt32Value(AREATRIGGER_EXTRA_SCALE_CURVE + scaleCurveIndex, GetMiscTemplate()->ExtraScale.Data.Raw[scaleCurveIndex]); PhasingHandler::InheritPhaseShift(this, caster); if (target && GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED)) { m_movementInfo.transport.guid = target->GetGUID(); } UpdateShape(); uint32 timeToTarget = GetMiscTemplate()->TimeToTarget != 0 ? GetMiscTemplate()->TimeToTarget : GetUInt32Value(AREATRIGGER_DURATION); if (GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_CIRCULAR_MOVEMENT)) { AreaTriggerCircularMovementInfo cmi = GetMiscTemplate()->CircularMovementInfo; if (target && GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED)) cmi.PathTarget = target->GetGUID(); else cmi.Center = pos; InitCircularMovement(cmi, timeToTarget); } else if (GetMiscTemplate()->HasSplines()) { InitSplineOffsets(GetMiscTemplate()->SplinePoints, timeToTarget); } // movement on transport of areatriggers on unit is handled by themself Transport* transport = m_movementInfo.transport.guid.IsEmpty() ? caster->GetTransport() : nullptr; if (transport) { float x, y, z, o; pos.GetPosition(x, y, z, o); transport->CalculatePassengerOffset(x, y, z, &o); m_movementInfo.transport.pos.Relocate(x, y, z, o); // This object must be added to transport before adding to map for the client to properly display it transport->AddPassenger(this); } AI_Initialize(); // Relocate areatriggers with circular movement again if (HasCircularMovement()) Relocate(CalculateCircularMovementPosition()); if (!GetMap()->AddToMap(this)) { // Returning false will cause the object to be deleted - remove from transport if (transport) transport->RemovePassenger(this); return false; } caster->_RegisterAreaTrigger(this); _ai->OnCreate(); return true; }
float HelixObject::LengthOfCurve(TimeValue t, int curve) { UpdateShape(t); return lengthOfCurve; }
void C4Object::DoMovement() { int32_t iContact=0; bool fAnyContact=false; int iContacts = 0; BYTE fTurned=0,fRedirectYR=0,fNoAttach=0; // Restrictions if (Def->NoHorizontalMove) xdir=0; // Dig free target area C4PropList* pActionDef = GetAction(); if (pActionDef) if (pActionDef->GetPropertyInt(P_DigFree)) { int ctcox, ctcoy; // Shape size square if (pActionDef->GetPropertyInt(P_DigFree)==1) { ctcox=fixtoi(fix_x+xdir); ctcoy=fixtoi(fix_y+ydir); ::Landscape.DigFreeRect(ctcox+Shape.GetX(),ctcoy+Shape.GetY(),Shape.Wdt,Shape.Hgt,this); } // Free size round (variable size) else { ctcox=fixtoi(fix_x+xdir); ctcoy=fixtoi(fix_y+ydir); int32_t rad = pActionDef->GetPropertyInt(P_DigFree); if (Con<FullCon) rad = rad*6*Con/5/FullCon; ::Landscape.DigFree(ctcox,ctcoy-1,rad,this); } } // store previous movement and ocf C4Real oldxdir(xdir), oldydir(ydir); uint32_t old_ocf = OCF; bool fMoved = false; C4Real new_x = fix_x + xdir; C4Real new_y = fix_y + ydir; SideBounds(new_x); if (!Action.t_attach) // Unattached movement = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = { // Horizontal movement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Move to target while (fixtoi(new_x) != fixtoi(fix_x)) { // Next step int step = Sign(new_x - fix_x); uint32_t border_hack_contacts = 0; iContact=ContactCheck(GetX() + step, GetY(), &border_hack_contacts); if (iContact || border_hack_contacts) { fAnyContact=true; iContacts |= t_contact | border_hack_contacts; } if (iContact) { // Abort horizontal movement new_x = fix_x; // Vertical redirection (always) RedirectForce(xdir,ydir,-1); ApplyFriction(ydir,ContactVtxFriction(this)); } else // Free horizontal movement { DoMotion(step, 0); fMoved = true; } } // Vertical movement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Movement target new_y = fix_y + ydir; // Movement bounds (vertical) VerticalBounds(new_y); // Move to target while (fixtoi(new_y) != fixtoi(fix_y)) { // Next step int step = Sign(new_y - fix_y); if ((iContact=ContactCheck(GetX(), GetY() + step, nullptr, ydir > 0))) { fAnyContact=true; iContacts |= t_contact; new_y = fix_y; // Vertical contact horizontal friction ApplyFriction(xdir,ContactVtxFriction(this)); // Redirection slide or rotate if (!ContactVtxCNAT(this,CNAT_Left)) RedirectForce(ydir,xdir,-1); else if (!ContactVtxCNAT(this,CNAT_Right)) RedirectForce(ydir,xdir,+1); else { // living things are always capable of keeping their rotation if (OCF & OCF_Rotate) if (iContact==1) if (!Alive) { RedirectForce(ydir,rdir,-ContactVtxWeight(this)); fRedirectYR=1; } ydir=0; } } else // Free vertical movement { DoMotion(0,step); fMoved = true; } } } if (Action.t_attach) // Attached movement = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = { VerticalBounds(new_y); // Move to target do { // Set next step target int step_x = 0, step_y = 0; if (fixtoi(new_x) != GetX()) step_x = Sign(fixtoi(new_x) - GetX()); else if (fixtoi(new_y) != GetY()) step_y = Sign(fixtoi(new_y) - GetY()); int32_t ctx = GetX() + step_x; int32_t cty = GetY() + step_y; // Attachment check if (!Shape.Attach(ctx,cty,Action.t_attach)) fNoAttach=1; else { // Attachment change to ctx/cty overrides target if (ctx != GetX() + step_x) { xdir = Fix0; new_x = itofix(ctx); } if (cty != GetY() + step_y) { ydir = Fix0; new_y = itofix(cty); } } // Contact check & evaluation uint32_t border_hack_contacts = 0; iContact=ContactCheck(ctx,cty,&border_hack_contacts); if (iContact || border_hack_contacts) { fAnyContact=true; iContacts |= border_hack_contacts | t_contact; } if (iContact) { // Abort movement if (ctx != GetX()) { ctx = GetX(); new_x = fix_x; } if (cty != GetY()) { cty = GetY(); new_y = fix_y; } } DoMotion(ctx - GetX(), cty - GetY()); fMoved = true; } while (fixtoi(new_x) != GetX() || fixtoi(new_y) != GetY()); } if(fix_x != new_x || fix_y != new_y) { fMoved = true; if (pSolidMaskData) pSolidMaskData->Remove(true); fix_x = new_x; fix_y = new_y; } // Rotation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (OCF & OCF_Rotate && !!rdir) { C4Real target_r = fix_r + rdir * 5; // Rotation limit if (Def->Rotateable>1) { if (target_r > itofix(Def->Rotateable)) { target_r = itofix(Def->Rotateable); rdir=0; } if (target_r < itofix(-Def->Rotateable)) { target_r = itofix(-Def->Rotateable); rdir=0; } } int32_t ctx=GetX(); int32_t cty=GetY(); // Move to target while (fixtoi(fix_r) != fixtoi(target_r)) { // Save step undos C4Real lcobjr = fix_r; C4Shape lshape=Shape; // Try next step fix_r += Sign(target_r - fix_r); UpdateShape(); // attached rotation: rotate around attachment pos if (Action.t_attach && !fNoAttach) { // more accurately, attachment should be evaluated by a rotation around the attachment vertex // however, as long as this code is only used for some surfaces adjustment for large vehicles, // it's enough to assume rotation around the center ctx=GetX(); cty=GetY(); // evaluate attachment, but do not bother about attachment loss // that will then be done in next execution cycle Shape.Attach(ctx,cty,Action.t_attach); } // check for contact if ((iContact=ContactCheck(ctx,cty))) // Contact { fAnyContact=true; iContacts |= t_contact; // Undo step and abort movement Shape=lshape; target_r = fix_r = lcobjr; // last UpdateShape-call might have changed sector lists! UpdatePos(); // Redirect to GetY() if (iContact==1) if (!fRedirectYR) RedirectForce(rdir,ydir,-1); // Stop rotation rdir=0; } else { fTurned=1; if (ctx != GetX() || cty != GetY()) { fix_x = itofix(ctx); fix_y = itofix(cty); } } } // Circle bounds if (target_r < -FixHalfCircle) { target_r += FixFullCircle; } if (target_r > +FixHalfCircle) { target_r -= FixFullCircle; } fix_r = target_r; } // Reput solid mask if moved by motion if (fMoved || fTurned) UpdateSolidMask(true); // Misc checks =========================================================================================== // InLiquid check // this equals C4Object::UpdateLiquid, but the "fNoAttach=false;"-line if (IsInLiquidCheck()) // In Liquid { if (!InLiquid) // Enter liquid { if (OCF & OCF_HitSpeed2) if (Mass>3) Splash(GetX(),GetY()+1,std::min(Shape.Wdt*Shape.Hgt/10,20),this); fNoAttach=false; InLiquid=1; } } else // Out of liquid { if (InLiquid) // Leave liquid InLiquid=0; } // Contact Action if (fAnyContact) { t_contact = iContacts; ContactAction(); } // Attachment Loss Action if (fNoAttach) NoAttachAction(); // Movement Script Execution if (fAnyContact) { C4AulParSet pars(C4VInt(fixtoi(oldxdir, 100)), C4VInt(fixtoi(oldydir, 100))); if (old_ocf & OCF_HitSpeed1) Call(PSF_Hit, &pars); if (old_ocf & OCF_HitSpeed2) Call(PSF_Hit2, &pars); if (old_ocf & OCF_HitSpeed3) Call(PSF_Hit3, &pars); } // Rotation gfx if (fTurned) UpdateFace(true); else // pos changed? if (fMoved) UpdatePos(); }
int HelixObject::NumberOfPieces(TimeValue t, int curve) { assert(curve==0); UpdateShape(t); return numberOfPieces; }
Point3 HelixObject::TangentPiece3D(TimeValue t, int curve, int piece, float param, int ptype) { assert(curve==0); UpdateShape(t); return TangentCurve3D(t, curve, (float)piece * perPiece + param * perPiece, ptype); }