void Portal::placeOnWall(const Vector3f &launchPos, const BoxCollider &wall, const Vector3f &point) { //Determine on what side the portal is //Side 0: -x, Side 1: x, Side 2: -z, Side 3: z, Side 4: -y, Side 5: y float dist = 1000000; int side = 0; float *distances; distances = PortalHelper::getDistancesForPoint(point, wall); for (int i = 0; i < 6; i++) { if (distances[i] < dist) { side = i; dist = distances[i]; } } Transform &t = entity.getComponent<Transform>(); Vector3f &rotation = t.rotation; Vector3f &position = t.position; Vector3f &scale = t.scale; position = point; switch (side) { case 0: direction.set(-1, 0, 0); break; case 1: direction.set( 1, 0, 0); break; case 2: direction.set( 0, 0, -1); break; case 3: direction.set( 0, 0, 1); break; case 4: direction.set( 0, -1, 0); break; case 5: direction.set( 0, 1, 0); break; } if (wall.size.z >= 1 && wall.size.y >= 2 && (side == 0 || side == 1)) { rotation.x = 0; if (side == 0) { rotation.y = rad(90); scale.set(1, 2, 1); } if (side == 1) { rotation.y = rad(-90); scale.set(1, 2, 1); } if (position.z - scale.z/2 < wall.position.z - wall.size.z/2) { position.z = wall.position.z - wall.size.z/2 + scale.z/2; } if (position.z + scale.z/2 > wall.position.z + wall.size.z/2) { position.z = wall.position.z + wall.size.z/2 - scale.z/2; } if (position.y - scale.y/2 < wall.position.y - wall.size.y/2) { position.y = wall.position.y - wall.size.y/2 + scale.y/2; } if (position.y + scale.y/2 > wall.position.y + wall.size.y/2) { position.y = wall.position.y + wall.size.y/2 - scale.y/2; } open = true; } if (wall.size.x >= 1 && wall.size.y >= 2 && (side == 2 || side == 3)) { rotation.x = 0; if (side == 2) { rotation.y = 0; scale.set(1, 2, 1); } if (side == 3) { rotation.y = rad(180); scale.set(1, 2, 1); } if (position.x - scale.x/2 < wall.position.x - wall.size.x/2) { position.x = wall.position.x - wall.size.x/2 + scale.x/2; } if (position.x + scale.x/2 > wall.position.x + wall.size.x/2) { position.x = wall.position.x + wall.size.x/2 - scale.x/2; } if (position.y - scale.y/2 < wall.position.y - wall.size.y/2) { position.y = wall.position.y - wall.size.y/2 + scale.y/2; } if (position.y + scale.y/2 > wall.position.y + wall.size.y/2) { position.y = wall.position.y + wall.size.y/2 - scale.y/2; } open = true; } if (wall.size.x >= 1 && wall.size.z >= 2 && (side == 4 || side == 5)) { rotation.y = std::atan2(point.x-launchPos.x, point.z-launchPos.z); if (side == 4) { rotation.x = rad(-90); scale.set(1, 2, 2); } if (side == 5) { rotation.x = rad(90); scale.set(1, 2, 2); } if (position.x - scale.x/2 < wall.position.x - wall.size.x/2) { position.x = wall.position.x - wall.size.x/2 + scale.x/2; } if (position.x + scale.x/2 > wall.position.x + wall.size.x/2) { position.x = wall.position.x + wall.size.x/2 - scale.x/2; } if (position.z - scale.z/2 < wall.position.z - wall.size.z/2) { position.z = wall.position.z - wall.size.z/2 + scale.z/2; } if (position.z + scale.z/2 > wall.position.z + wall.size.z/2) { position.z = wall.position.z + wall.size.z/2 - scale.z/2; } open = true; } // Enabled the light entity.getComponent<LightSource>().enabled = true; position += (getDirection() * SURFACE_OFFSET); overlayMesh = MeshLoader::getMesh("Plane.obj"); stencilMesh = MeshLoader::getMesh("PortalStencil.obj"); }
// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- void ChPitmanArm::Initialize(std::shared_ptr<ChBodyAuxRef> chassis, const ChVector<>& location, const ChQuaternion<>& rotation) { m_position = ChCoordsys<>(location, rotation); // Chassis orientation (expressed in absolute frame) // Recall that the suspension reference frame is aligned with the chassis. ChQuaternion<> chassisRot = chassis->GetFrame_REF_to_abs().GetRot(); // Express the steering reference frame in the absolute coordinate system. ChFrame<> steering_to_abs(location, rotation); steering_to_abs.ConcatenatePreTransformation(chassis->GetFrame_REF_to_abs()); // Transform all points and directions to absolute frame. std::vector<ChVector<>> points(NUM_POINTS); std::vector<ChVector<>> dirs(NUM_DIRS); for (int i = 0; i < NUM_POINTS; i++) { ChVector<> rel_pos = getLocation(static_cast<PointId>(i)); points[i] = steering_to_abs.TransformPointLocalToParent(rel_pos); } for (int i = 0; i < NUM_DIRS; i++) { ChVector<> rel_dir = getDirection(static_cast<DirectionId>(i)); dirs[i] = steering_to_abs.TransformDirectionLocalToParent(rel_dir); } // Unit vectors for orientation matrices. ChVector<> u; ChVector<> v; ChVector<> w; ChMatrix33<> rot; // Create and initialize the steering link body m_link = std::shared_ptr<ChBody>(chassis->GetSystem()->NewBody()); m_link->SetNameString(m_name + "_link"); m_link->SetPos(points[STEERINGLINK]); m_link->SetRot(steering_to_abs.GetRot()); m_link->SetMass(getSteeringLinkMass()); if (m_vehicle_frame_inertia) { ChMatrix33<> inertia = TransformInertiaMatrix(getSteeringLinkInertiaMoments(), getSteeringLinkInertiaProducts(), chassisRot, steering_to_abs.GetRot()); m_link->SetInertia(inertia); } else { m_link->SetInertiaXX(getSteeringLinkInertiaMoments()); m_link->SetInertiaXY(getSteeringLinkInertiaProducts()); } chassis->GetSystem()->AddBody(m_link); m_pP = m_link->TransformPointParentToLocal(points[UNIV]); m_pI = m_link->TransformPointParentToLocal(points[REVSPH_S]); m_pTP = m_link->TransformPointParentToLocal(points[TIEROD_PA]); m_pTI = m_link->TransformPointParentToLocal(points[TIEROD_IA]); // Create and initialize the Pitman arm body m_arm = std::shared_ptr<ChBody>(chassis->GetSystem()->NewBody()); m_arm->SetNameString(m_name + "_arm"); m_arm->SetPos(points[PITMANARM]); m_arm->SetRot(steering_to_abs.GetRot()); m_arm->SetMass(getPitmanArmMass()); if (m_vehicle_frame_inertia) { ChMatrix33<> inertia = TransformInertiaMatrix(getPitmanArmInertiaMoments(), getPitmanArmInertiaProducts(), chassisRot, steering_to_abs.GetRot()); m_arm->SetInertia(inertia); } else { m_arm->SetInertiaXX(getPitmanArmInertiaMoments()); m_arm->SetInertiaXY(getPitmanArmInertiaProducts()); } chassis->GetSystem()->AddBody(m_arm); // Cache points for arm visualization (expressed in the arm frame) m_pC = m_arm->TransformPointParentToLocal(points[REV]); m_pL = m_arm->TransformPointParentToLocal(points[UNIV]); // Create and initialize the revolute joint between chassis and Pitman arm. // Note that this is modeled as a ChLinkEngine to allow driving it with // imposed rotation (steering input). // The z direction of the joint orientation matrix is dirs[REV_AXIS], assumed // to be a unit vector. u = points[PITMANARM] - points[REV]; v = Vcross(dirs[REV_AXIS], u); v.Normalize(); u = Vcross(v, dirs[REV_AXIS]); rot.Set_A_axis(u, v, dirs[REV_AXIS]); m_revolute = std::make_shared<ChLinkMotorRotationAngle>(); m_revolute->SetNameString(m_name + "_revolute"); m_revolute->Initialize(chassis, m_arm, ChFrame<>(points[REV], rot.Get_A_quaternion())); auto motor_fun = std::make_shared<ChFunction_Setpoint>(); m_revolute->SetAngleFunction(motor_fun); chassis->GetSystem()->AddLink(m_revolute); // Create and initialize the universal joint between the Pitman arm and steering link. // The x and y directions of the joint orientation matrix are given by // dirs[UNIV_AXIS_ARM] and dirs[UNIV_AXIS_LINK], assumed to be unit vectors // and orthogonal. w = Vcross(dirs[UNIV_AXIS_ARM], dirs[UNIV_AXIS_LINK]); rot.Set_A_axis(dirs[UNIV_AXIS_ARM], dirs[UNIV_AXIS_LINK], w); m_universal = std::make_shared<ChLinkUniversal>(); m_universal->SetNameString(m_name + "_universal"); m_universal->Initialize(m_arm, m_link, ChFrame<>(points[UNIV], rot.Get_A_quaternion())); chassis->GetSystem()->AddLink(m_universal); // Create and initialize the revolute-spherical joint (massless idler arm). // The length of the idler arm is the distance between the two hardpoints. // The z direction of the revolute joint orientation matrix is // dirs[REVSPH_AXIS], assumed to be a unit vector. double distance = (points[REVSPH_S] - points[REVSPH_R]).Length(); u = points[REVSPH_S] - points[REVSPH_R]; v = Vcross(dirs[REVSPH_AXIS], u); v.Normalize(); u = Vcross(v, dirs[REVSPH_AXIS]); rot.Set_A_axis(u, v, dirs[REVSPH_AXIS]); m_revsph = std::make_shared<ChLinkRevoluteSpherical>(); m_revsph->SetNameString(m_name + "_revsph"); m_revsph->Initialize(chassis, m_link, ChCoordsys<>(points[REVSPH_R], rot.Get_A_quaternion()), distance); chassis->GetSystem()->AddLink(m_revsph); }
glm::mat4 Camera::getModulatedTransform(const glm::vec2 modulator) const { auto tmp = glm::vec3(cam_mod(glm::vec2(position), modulator), position.z); return glm::lookAt(tmp, tmp + getDirection(), getUp()); }
glm::mat4 Camera::getTransform() const { return glm::lookAt(position, position + getDirection(), getUp()); }
// PTHY: TODO: Can be genericized in BuildingBlocks Cell3DPosition Catoms2DBlock::getPosition(P2PNetworkInterface *p2p) { return getPosition((HLattice::Direction)getDirection(p2p)); }
// If main_cycle returns false, don't process more events! int AgiEngine::mainCycle() { unsigned int key, kascii; VtEntry *v = &_game.viewTable[0]; pollTimer(); updateTimer(); key = doPollKeyboard(); // In AGI Mouse emulation mode we must update the mouse-related // vars in every interpreter cycle. // // We run AGIMOUSE always as a side effect //if (getFeatures() & GF_AGIMOUSE) { _game.vars[28] = _mouse.x / 2; _game.vars[29] = _mouse.y; //} if (key == KEY_PRIORITY) { _sprites->eraseBoth(); _debug.priority = !_debug.priority; _picture->showPic(); _sprites->blitBoth(); _sprites->commitBoth(); key = 0; } if (key == KEY_STATUSLN) { _debug.statusline = !_debug.statusline; writeStatus(); key = 0; } // Click-to-walk mouse interface if (_game.playerControl && v->flags & fAdjEgoXY) { int toX = v->parm1; int toY = v->parm2; // AGI Mouse games use ego's sprite's bottom left corner for mouse walking target. // Amiga games use ego's sprite's bottom center for mouse walking target. // TODO: Check what Atari ST AGI and Apple IIGS AGI use for mouse walking target. if (getPlatform() == Common::kPlatformAmiga) toX -= (v->xSize / 2); // Center ego's sprite horizontally // Adjust ego's sprite's mouse walking target position (These parameters are // controlled with the adj.ego.move.to.x.y-command). Note that these values rely // on the horizontal centering of the ego's sprite at least on the Amiga platform. toX += _game.adjMouseX; toY += _game.adjMouseY; v->direction = getDirection(v->xPos, v->yPos, toX, toY, v->stepSize); if (v->direction == 0) inDestination(v); } kascii = KEY_ASCII(key); if (kascii) setvar(vKey, kascii); bool restartProcessKey; do { restartProcessKey = false; switch (_game.inputMode) { case INPUT_NORMAL: if (!handleController(key)) { if (key == 0 || !_game.inputEnabled) break; handleKeys(key); // if ESC pressed, activate menu before // accept.input from the interpreter cycle // sets the input mode to normal again // (closes: #540856) if (key == KEY_ESCAPE) { key = 0; restartProcessKey = true; } // commented out to close Sarien bug #438872 //if (key) // _game.keypress = key; } break; case INPUT_GETSTRING: handleController(key); handleGetstring(key); setvar(vKey, 0); // clear ENTER key break; case INPUT_MENU: _menu->keyhandler(key); _gfx->doUpdate(); return false; case INPUT_NONE: handleController(key); if (key) _game.keypress = key; break; } } while (restartProcessKey); _gfx->doUpdate(); if (_game.msgBoxTicks > 0) _game.msgBoxTicks--; return true; }