void Arrow3d::RenderArrow(ScreenBase const & screen, ref_ptr<dp::GpuProgram> program, dp::Color const & color, float dz, bool hasNormals) { program->Bind(); GLFunctions::glBindBuffer(m_bufferId, gl_const::GLArrayBuffer); uint32_t const attributePosition = program->GetAttributeLocation("a_pos"); ASSERT_NOT_EQUAL(attributePosition, -1, ()); GLFunctions::glEnableVertexAttribute(attributePosition); GLFunctions::glVertexAttributePointer(attributePosition, kComponentsInVertex, gl_const::GLFloatType, false, 0, 0); if (hasNormals) { GLFunctions::glBindBuffer(m_bufferNormalsId, gl_const::GLArrayBuffer); uint32_t const attributeNormal = program->GetAttributeLocation("a_normal"); ASSERT_NOT_EQUAL(attributeNormal, -1, ()); GLFunctions::glEnableVertexAttribute(attributeNormal); GLFunctions::glVertexAttributePointer(attributeNormal, 3, gl_const::GLFloatType, false, 0, 0); } dp::UniformValuesStorage uniforms; math::Matrix<float, 4, 4> const modelTransform = CalculateTransform(screen, dz); uniforms.SetMatrix4x4Value("u_transform", modelTransform.m_data); glsl::vec4 const c = glsl::ToVec4(color); uniforms.SetFloatValue("u_color", c.r, c.g, c.b, c.a); dp::ApplyState(m_state, program); dp::ApplyUniforms(uniforms, program); GLFunctions::glDrawArrays(gl_const::GLTriangles, 0, m_vertices.size() / kComponentsInVertex); }
// Constructor _Camera::_Camera(float Fov, float AspectRatio, float Near, float Far) : Fov(Fov), AspectRatio(AspectRatio), Near(Near), Far(Far), Type(THIRD_PERSON), Yaw(0.0f), Pitch(0.0f), Distance(5.0f), MinDistance(0.1f), PitchLimit(glm::radians(89.0f)), LookAt(glm::vec3(0.0f, 0.0f, 0.0f)), Up(glm::vec3(0.0f, 1.0f, 0.0f)), Position(glm::vec3(0.0f, 0.0f, 5.0f)), LastPosition(Position), InterpolatedPosition(Position) { CalculateProjection(); CalculateView(); CalculateTransform(); }
// Update the camera void _Camera::UpdateRender(float BlendFactor) { /*switch(Type) { case FREEMOVE: { } break; case THIRD_PERSON: { } break; } */ InterpolatedPosition = BlendFactor * Position + (1.0f - BlendFactor) * LastPosition; //InterpolatedPosition = Position; CalculateView(); CalculateTransform(); }
void CFeature::ForcedMove(const float3& newPos, bool snapToGround) { if (blocking) { UnBlock(); } // remove from managers qf->RemoveFeature(this); if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->DeleteTree(pos); } pos = newPos; featureDrawer->UpdateDrawPos(this); // setup finalHeight if (snapToGround) { if (def->floating) { finalHeight = ground->GetHeight(pos.x, pos.z); } else { finalHeight = ground->GetHeight2(pos.x, pos.z); } } else { finalHeight = newPos.y; } // setup midPos if (def->drawType == DRAWTYPE_MODEL) { midPos = pos + model->relMidPos; } else if (def->drawType >= DRAWTYPE_TREE) { midPos = pos + (UpVector * TREE_RADIUS); } else { midPos = pos; } // setup the visual transformation matrix CalculateTransform(); // insert into managers qf->AddFeature(this); if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->AddTree(def->drawType - 1, pos, 1.0f); } if (blocking) { Block(); } }
void CFeature::Initialize (const float3& pos,FeatureDef* def,short int heading,int allyteam,std::string fromUnit, int fromTeam) { this->def=def; createdFromUnit=fromUnit; this->pos=pos; this->allyteam=allyteam; team=fromTeam; this->pos.CheckInBounds(); this->heading=heading; health=def->maxHealth; SetRadius(def->radius); blocking=def->blocking; xsize=def->xsize; ysize=def->ysize; mass=def->mass; if(def->drawType==DRAWTYPE_MODEL){ if(def->model==0){ def->model=modelLoader->LoadModel(def->modelname,fromTeam); height=def->model->GetHeight(); def->radius=def->model->GetRadius(); SetRadius(def->radius); } midPos=pos+def->model->GetRelMidPos(); } else if(def->drawType==DRAWTYPE_TREE){ midPos=pos+UpVector*def->radius; height = 2*def->radius; } else { midPos=pos; } id=featureHandler->AddFeature(this); qf->AddFeature(this); CalculateTransform (); // this->pos.y=ground->GetHeight(pos.x,pos.z); if(blocking){ Block(); } if(def->floating){ finalHeight=ground->GetHeight(pos.x,pos.z); } else { finalHeight=ground->GetHeight2(pos.x,pos.z); } if(def->drawType==DRAWTYPE_TREE) treeDrawer->AddTree(def->modelType,pos,1); }
void CFeature::ForcedMove(const float3& newPos) { // remove from managers quadField->RemoveFeature(this); const float3 oldPos = pos; UnBlock(); Move(newPos - pos, true); Block(); eventHandler.FeatureMoved(this, oldPos); // setup the visual transformation matrix CalculateTransform(); // insert into managers quadField->AddFeature(this); }
void CFeature::ForcedMove(const float3& newPos, bool snapToGround) { if (blocking) { UnBlock(); } // remove from managers qf->RemoveFeature(this); if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->DeleteTree(pos); } Move3D(newPos - pos, true); eventHandler.FeatureMoved(this); // setup finalHeight (pos == newPos now) if (snapToGround) { if (def->floating) { finalHeight = ground->GetHeightAboveWater(pos.x, pos.z); } else { finalHeight = ground->GetHeightReal(pos.x, pos.z); } } else { finalHeight = pos.y; } // setup the visual transformation matrix CalculateTransform(); // insert into managers qf->AddFeature(this); if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->AddTree(def->drawType - 1, pos, 1.0f); } if (blocking) { Block(); } }
bool CFeature::UpdatePosition() { if (udef != NULL) { // we are a wreck of a dead unit if (!reachedFinalPos) { // def->floating is unreliable (true for land unit wrecks), // so just assume wrecks always sink even if their "owner" // was a floating object (as is the case for ships anyway) const float realGroundHeight = ground->GetHeightReal(pos.x, pos.z); const bool reachedWater = ( pos.y <= 0.1f); const bool reachedGround = ((pos.y - realGroundHeight) <= 0.1f); deathSpeed *= 0.999999f; deathSpeed *= (1.0f - (int(reachedWater ) * 0.05f)); deathSpeed *= (1.0f - (int(reachedGround) * 0.10f)); if (deathSpeed.SqLength2D() > 0.01f) { UnBlock(); qf->RemoveFeature(this); // update our forward speed (and quadfield // position) if it is still greater than 0 Move3D(deathSpeed, true); qf->AddFeature(this); Block(); } else { deathSpeed.x = 0.0f; deathSpeed.z = 0.0f; } if (!reachedGround) { if (!reachedWater) { // quadratic acceleration if not in water deathSpeed.y += mapInfo->map.gravity; } else { // constant downward speed otherwise deathSpeed.y = mapInfo->map.gravity; } Move1D(deathSpeed.y, 1, true); } else { deathSpeed.y = 0.0f; // last Update() may have sunk us into // ground if pos.y was only marginally // larger than ground height, correct Move1D(realGroundHeight, 1, false); } reachedFinalPos = (deathSpeed == ZeroVector); if (!pos.IsInBounds()) { pos.ClampInBounds(); // ensure that no more forward-speed updates are done // (prevents wrecks floating in mid-air at edge of map // due to gravity no longer being applied either) deathSpeed = ZeroVector; } eventHandler.FeatureMoved(this); CalculateTransform(); } } else { if (pos.y > finalHeight) { // feature is falling (note: gravity is negative) if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->DeleteTree(pos); } if (pos.y > 0.0f) { speed.y += mapInfo->map.gravity; } else { speed.y = mapInfo->map.gravity; } Move1D(speed.y, 1, true); if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->AddTree(def->drawType - 1, pos, 1.0f); } transMatrix[13] += speed.y; } else if (pos.y < finalHeight) { // if ground is restored, make sure feature does not get buried if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->DeleteTree(pos); } const float dy = finalHeight - pos.y; speed.y = 0.0f; transMatrix[13] += dy; Move1D(dy, 1, true); if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->AddTree(def->drawType - 1, pos, 1.0f); } } reachedFinalPos = (pos.y == finalHeight); } isUnderWater = ((pos.y + height) < 0.0f); return reachedFinalPos; }
void CFeature::Initialize(const float3& _pos, const FeatureDef* _def, short int _heading, int facing, int _team, int _allyteam, const UnitDef* _udef, const float3& speed, int _smokeTime) { def = _def; udef = _udef; defID = def->id; heading = _heading; buildFacing = facing; team = _team; allyteam = _allyteam; emitSmokeTime = _smokeTime; mass = def->mass; crushResistance = def->crushResistance; health = def->maxHealth; blocking = def->blocking; xsize = ((facing & 1) == 0) ? def->xsize : def->zsize; zsize = ((facing & 1) == 1) ? def->xsize : def->zsize; noSelect = def->noSelect; // set position before mid-position Move3D(_pos.cClampInMap(), false); if (def->drawType == DRAWTYPE_MODEL) { if ((model = def->LoadModel()) == NULL) { LOG_L(L_ERROR, "Features: Couldn't load model for %s", def->name.c_str()); } else { SetMidAndAimPos(model->relMidPos, model->relMidPos, true); SetRadiusAndHeight(model->radius, model->height); } } else { if (def->drawType >= DRAWTYPE_TREE) { // LoadFeaturesFromMap() doesn't set a scale for trees SetMidAndAimPos(UpVector * TREE_RADIUS, UpVector * TREE_RADIUS, true); SetRadiusAndHeight(TREE_RADIUS, TREE_RADIUS * 2.0f); } } UpdateMidAndAimPos(); CalculateTransform(); // note: gets deleted in ~CSolidObject collisionVolume = new CollisionVolume(def->collisionVolume, radius); featureHandler->AddFeature(this); qf->AddFeature(this); // maybe should not be here, but it prevents crashes caused by team = -1 ChangeTeam(team); if (blocking) { Block(); } if (def->floating) { finalHeight = ground->GetHeightAboveWater(pos.x, pos.z); } else { finalHeight = ground->GetHeightReal(pos.x, pos.z); } if (speed != ZeroVector) { deathSpeed = speed; } reachedFinalPos = (speed == ZeroVector && pos.y == finalHeight); }
bool CFeature::UpdatePosition() { const float3 oldPos = pos; if (udef != NULL) { // we are a wreck of a dead unit, possibly with residual impulse // in this case we do not care about <finalHeight> and are always // affected by gravity // note that def->floating is unreliable (eg. it can be true for // ground-unit wrecks), so just assume wrecks always sink in water // even if their "owner" was a floating object (as is the case for // ships anyway) if (IsMoving()) { const float realGroundHeight = ground->GetHeightReal(pos.x, pos.z); const bool reachedWater = ( pos.y <= 0.1f); const bool reachedGround = ((pos.y - realGroundHeight) <= 0.1f); // NOTE: // all these calls use the base-class because FeatureHandler::Update // iterates over updateFeatures and our ::SetVelocity will insert us // into that CWorldObject::SetVelocity(speed + GetDragAccelerationVec(float4(mapInfo->atmosphere.fluidDensity, mapInfo->water.fluidDensity, 1.0f, 0.1f))); if (speed.SqLength2D() > 0.01f) { UnBlock(); quadField->RemoveFeature(this); // update our forward speed (and quadfield // position) if it is still greater than 0 Move(speed, true); quadField->AddFeature(this); Block(); } else { CWorldObject::SetVelocity(speed * UpVector); } if (!reachedGround) { if (!reachedWater) { // quadratic acceleration if not in water CWorldObject::SetVelocity(speed + (UpVector * mapInfo->map.gravity)); } else { // constant downward speed otherwise CWorldObject::SetVelocity((speed * XZVector) + (UpVector * mapInfo->map.gravity)); } Move(UpVector * speed.y, true); } else { CWorldObject::SetVelocity(speed * XZVector); // last Update() may have sunk us into // ground if pos.y was only marginally // larger than ground height, correct Move(UpVector * (realGroundHeight - pos.y), true); } if (!pos.IsInBounds()) { pos.ClampInBounds(); // ensure that no more forward-speed updates are done // (prevents wrecks floating in mid-air at edge of map // due to gravity no longer being applied either) CWorldObject::SetVelocity(ZeroVector); } eventHandler.FeatureMoved(this, oldPos); CalculateTransform(); } } else { // any feature that is not a dead unit (ie. rocks, trees, ...) // these never move in the xz-plane no matter how much impulse // is applied, only gravity affects them (FIXME: arbitrary..?) if (pos.y > finalHeight) { if (pos.y > 0.0f) { CWorldObject::SetVelocity(speed + (UpVector * mapInfo->map.gravity)); } else { CWorldObject::SetVelocity((speed * XZVector) + (UpVector * mapInfo->map.gravity)); } // stop falling when we reach our finalHeight // (which can be arbitrary, even below ground) Move(UpVector * std::min(pos.y - finalHeight, speed.y), true); eventHandler.FeatureMoved(this, oldPos); } else if (pos.y < finalHeight) { // stop vertical movement and teleport up CWorldObject::SetVelocity(speed * XZVector); Move(UpVector * (finalHeight - pos.y), true); eventHandler.FeatureMoved(this, oldPos); } transMatrix[13] = pos.y; } UpdatePhysicalStateBit(CSolidObject::PSTATE_BIT_MOVING, ((SetSpeed(speed) != 0.0f) || (std::fabs(pos.y - finalHeight) >= 0.01f))); UpdatePhysicalState(0.1f); return (IsMoving()); }
void CFeature::Initialize(const FeatureLoadParams& params) { id = params.featureID; defID = (params.featureDef)->id; def = params.featureDef; udef = params.unitDef; objectDef = params.featureDef; team = params.teamID; allyteam = params.allyTeamID; heading = params.heading; buildFacing = params.facing; smokeTime = params.smokeTime; mass = def->mass; health = def->health; crushResistance = def->crushResistance; xsize = ((buildFacing & 1) == 0) ? def->xsize : def->zsize; zsize = ((buildFacing & 1) == 1) ? def->xsize : def->zsize; noSelect = !def->selectable; // set position before mid-position Move((params.pos).cClampInMap(), false); // use base-class version, AddFeature() below // will already insert us in the update-queue CWorldObject::SetVelocity(params.speed); if (def->drawType == DRAWTYPE_MODEL) { if ((model = def->LoadModel()) == NULL) { LOG_L(L_ERROR, "[%s] couldn't load model for %s", __FUNCTION__, def->name.c_str()); } else { SetMidAndAimPos(model->relMidPos, model->relMidPos, true); SetRadiusAndHeight(model); } } else if (def->drawType >= DRAWTYPE_TREE) { // LoadFeaturesFromMap() doesn't set a scale for trees SetMidAndAimPos(UpVector * TREE_RADIUS, UpVector * TREE_RADIUS, true); SetRadiusAndHeight(TREE_RADIUS, TREE_RADIUS * 2.0f); } UpdateMidAndAimPos(); CalculateTransform(); // note: gets deleted in ~CSolidObject collisionVolume = new CollisionVolume(def->collisionVolume); if (collisionVolume->DefaultToSphere()) collisionVolume->InitSphere(radius); if (collisionVolume->DefaultToFootPrint()) collisionVolume->InitBox(float3(xsize * SQUARE_SIZE, height, zsize * SQUARE_SIZE)); // feature does not have an assigned ID yet // this MUST be done before the Block() call featureHandler->AddFeature(this); quadField->AddFeature(this); ChangeTeam(team); UpdateCollidableStateBit(CSolidObject::CSTATE_BIT_SOLIDOBJECTS, def->collidable); Block(); // allow Spring.SetFeatureBlocking to be called from gadget:FeatureCreated eventHandler.FeatureCreated(this); if (def->floating) { finalHeight = ground->GetHeightAboveWater(pos.x, pos.z); } else { finalHeight = ground->GetHeightReal(pos.x, pos.z); } UpdatePhysicalStateBit(CSolidObject::PSTATE_BIT_MOVING, ((SetSpeed(params.speed) != 0.0f) || (std::fabs(pos.y - finalHeight) >= 0.01f))); }
glm::mat4 Transform::GetMatrice() { return CalculateTransform(); }
bool CFeature::UpdatePosition() { bool finishedUpdate = true; if (!createdFromUnit.empty()) { // we are a wreck of a dead unit if (!reachedFinalPos) { bool haveForwardSpeed = false; bool haveVerticalSpeed = false; bool inBounds = false; if (deathSpeed.SqLength2D() > 0.01f) { UnBlock(); qf->RemoveFeature(this); // update our forward speed (and quadfield // position) if it's still greater than 0 pos += deathSpeed; midPos += deathSpeed; // NOTE: apply more drag if we were a tank or bot? // (would require passing extra data to Initialize()) deathSpeed *= 0.95f; haveForwardSpeed = true; qf->AddFeature(this); Block(); } // def->floating is unreliable (true for land unit wrecks), // just assume wrecks always sink even if their "owner" was // a floating object (as is the case for ships anyway) float realGroundHeight = ground->GetHeight2(pos.x, pos.z); bool reachedGround = (pos.y <= realGroundHeight); if (!reachedGround) { if (pos.y > 0.0f) { // quadratic acceleration if not in water deathSpeed.y += mapInfo->map.gravity; } else { // constant downward speed otherwise deathSpeed.y = mapInfo->map.gravity; } pos.y += deathSpeed.y; midPos.y += deathSpeed.y; haveVerticalSpeed = true; } else { // last Update() may have sunk us into // ground if pos.y was only marginally // larger than ground height, correct pos.y = realGroundHeight; midPos.y = pos.y + model->relMidPos.y; } inBounds = pos.CheckInBounds(); reachedFinalPos = (!haveForwardSpeed && !haveVerticalSpeed); // reachedFinalPos = ((!haveForwardSpeed && !haveVerticalSpeed) || !inBounds); if (!inBounds) { // ensure that no more forward-speed updates are done // (prevents wrecks floating in mid-air at edge of map // due to gravity no longer being applied either) deathSpeed = ZeroVector; } featureHandler->UpdateDrawQuad(this, pos); CalculateTransform(); } if (!reachedFinalPos) finishedUpdate = false; } if (pos.y > finalHeight) { //! feature is falling if (def->drawType >= DRAWTYPE_TREE) treeDrawer->DeleteTree(pos); if (pos.y > 0.0f) { speed.y += mapInfo->map.gravity; //! gravity is negative } else { //! fall slower in water speed.y += mapInfo->map.gravity * 0.5; } pos.y += speed.y; midPos.y += speed.y; transMatrix[13] += speed.y; if (def->drawType >= DRAWTYPE_TREE) treeDrawer->AddTree(def->drawType - 1, pos, 1.0f); } else if (pos.y < finalHeight) { //! if ground is restored, make sure feature does not get buried if (def->drawType >= DRAWTYPE_TREE) treeDrawer->DeleteTree(pos); float diff = finalHeight - pos.y; pos.y = finalHeight; midPos.y += diff; transMatrix[13] += diff; speed.y = 0.0f; if (def->drawType >= DRAWTYPE_TREE) treeDrawer->AddTree(def->drawType - 1, pos, 1.0f); } if (pos.y != finalHeight) finishedUpdate = false; isUnderWater = ((pos.y + height) < 0.0f); return finishedUpdate; }
void CFeature::Initialize(const float3& _pos, const FeatureDef* _def, short int _heading, int facing, int _team, int _allyteam, std::string fromUnit, const float3& speed, int _smokeTime) { pos = _pos; def = _def; defName = def->myName; heading = _heading; buildFacing = facing; team = _team; allyteam = _allyteam; emitSmokeTime = _smokeTime; createdFromUnit = fromUnit; ChangeTeam(team); // maybe should not be here, but it prevents crashes caused by team = -1 pos.CheckInBounds(); health = def->maxHealth; blocking = def->blocking; xsize = def->xsize; zsize = def->zsize; mass = def->mass; noSelect = def->noSelect; if (def->drawType == DRAWTYPE_MODEL) { model = LoadModel(def); height = model->height; SetRadius(model->radius); midPos = pos + model->relMidPos; collisionVolume = new CollisionVolume(def->collisionVolume, model->radius); } else if (def->drawType >= DRAWTYPE_TREE) { SetRadius(TREE_RADIUS); midPos = pos + (UpVector * TREE_RADIUS); height = 2 * TREE_RADIUS; // LoadFeaturesFromMap() doesn't set a scale for trees collisionVolume = new CollisionVolume(def->collisionVolume, TREE_RADIUS); } else { // geothermal (no collision volume) SetRadius(0.0f); midPos = pos; } featureHandler->AddFeature(this); qf->AddFeature(this); CalculateTransform(); if (blocking) { Block(); } if (def->floating) { finalHeight = ground->GetHeight(pos.x, pos.z); } else { finalHeight = ground->GetHeight2(pos.x, pos.z); } if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->AddTree(def->drawType - 1, pos, 1); } if (speed != ZeroVector) { deathSpeed = speed; } }
void CFeature::Initialize(const float3& _pos, const FeatureDef* _def, short int _heading, int facing, int _team, std::string fromUnit, const float3& speed) { pos = _pos; def = _def; defName = def->myName; heading = _heading; buildFacing = facing; team = _team; createdFromUnit = fromUnit; ChangeTeam(team); pos.CheckInBounds(); health = def->maxHealth; blocking = def->blocking; xsize = def->xsize; ysize = def->ysize; mass = def->mass; noSelect = def->noSelect; if (def->drawType == DRAWTYPE_3DO) { model = def->LoadModel(team); height = model->height; SetRadius(model->radius); midPos = pos + model->relMidPos; // copy the FeatureDef volume archetype data collisionVolume = SAFE_NEW CollisionVolume(def->collisionVolume); // CFeatureHandler left this volume's axis-scales uninitialized // (ie. no "collisionVolumeScales" tag was defined in FeatureDef) if (collisionVolume->GetScale(COLVOL_AXIS_X) <= 1.0f && collisionVolume->GetScale(COLVOL_AXIS_Y) <= 1.0f && collisionVolume->GetScale(COLVOL_AXIS_Z) <= 1.0f) { collisionVolume->SetDefaultScale(model->radius); } } else if (def->drawType == DRAWTYPE_TREE) { SetRadius(TREE_RADIUS); midPos = pos + (UpVector * TREE_RADIUS); height = 2 * TREE_RADIUS; // copy the FeatureDef volume archetype data collisionVolume = SAFE_NEW CollisionVolume(def->collisionVolume); collisionVolume->SetDefaultScale(TREE_RADIUS); } else { // geothermal (no collision volume) SetRadius(0.0f); midPos = pos; } featureHandler->AddFeature(this); qf->AddFeature(this); CalculateTransform(); if (blocking) { Block(); } if (def->floating) { finalHeight = ground->GetHeight(pos.x, pos.z); } else { finalHeight = ground->GetHeight2(pos.x, pos.z); } if (def->drawType == DRAWTYPE_TREE) { treeDrawer->AddTree(def->modelType, pos, 1); } if (speed != ZeroVector) { deathSpeed = speed; } }