NEW YORK — New York's historic Waldorf Astoria has hosted every U.S. president since Herbert Hoover, as well as celebrities, world leaders and business tycoons, but on Tuesday, guests will walk through the place for the last time before the hotel shuts its doors.
Anbang Insurance Group, the Chinese holding company that bought Waldorf Astoria for $1.95 billion in 2014, will officially close the hotel on Wednesday. The iconic hotel, which opened in 1931 on Park Avenue, will undergo a major renovation that is expected to convert many of the hotel rooms into apartments, with boutique shops on the ground floor.
A portion of the Waldorf Astoria will still be a hotel, but far fewer than the current 1,400 rooms will re-emerge.
Angbang Insurance Group plans to reopen the Waldorf Astoria in two to three years.
Former employee Jimmy Eldrissi, who worked as a bellman at the hotel for 51 years before retiring last month, looked back at the once-in-a-lifetime experience he had at the Waldorf Astoria.
"I met every president, from President Johnson until President Obama," Eldrissi told PIX11 News on Tuesday.
Eldrissi said his favorite run-in was with 40th U.S. President Ronald Reagan, who he insisted on calling "Mr. President" at the time even thought Reagan had not won the election when they met.
"He said Jimmy, not yet! So I tapped him on the shoulder and said no, yo will be the president," Eldrissi said thinking back to that moment.
Current tenants at the Waldorf Astoria bid their last goodbyes to their once homeon Tuesday.
"We had to get all out stuff out, how about that," Tom Barnett, who lived and ran his custom suit business out of The Waldorf for 16 years, said.
Barnett shook every employee's hand on Tuesday.
"It's been a family. My family has come here and he [the doorman] has met my parents and my sister-in-laws. Everyone that has been here have been here forever," Barnett said.
Amid concern about the fate of the historic public Art Deco areas, a hotel spokesman told The New York Times that those spaces will be restored.
The Landmarks Preservation Commission is expected to determine if a list of items and rooms, including the grand ballroom, the "wheel of life" mosaic and the highly-recognized Park Avenue entrance, will be made interior landmarks, the Times reported.
The landmarked facade will remain mostly unchanged.
The hotel reassured people in a post on Facebook last Friday that the restoration would not strip the history or beauty of the place, but celebrate it.
The post also said the upcoming renovation was a "new chapter" into the hotel's history and included the hashtag #BuildingUnforgettable.
Though The Waldorf is known for its elegance, recent guests have been noting the decor and furniture in rooms need some freshening up.
The original Waldorf Hotel was open in 1893 at the corner of Fifth Avenue and 33rd Street. It was torn down in 1929 to build the Empire State Building.
When the hotel reopened in 1931 on Park Avenue between 49th and 50th streets, it was the tallest and largest hotel in the world.
"The opening of the new Waldorf Astoria is an event in the advancement of hotels, even in New York City," Former President Herbert Hoover said at the time.
It became a New York City landmark in 1993.
It has hosted balls, events and meetings that drew presidents, politicians, world leaders and A-list stars year round. Among those events that will need to find a new home is the Alfred E. Smith Memorial Foundation Dinner, an white-tie annual gathering of the city's political elite that makes headlines ever October. This past year, Donald Trump and Hillary Clinton attended the gathering — and their every move was scrutinized.


text:
Chris Brandon Bul Kuol Antoine Davis Kam Farris Jon Williams Sports Record setting events General news Men's college basketball College basketball Basketball College sports Men's basketball Men's sports
Robert Morris Northeast Detroit Horizon
Davis sets Horizon tourney records with 46 points, 10 3s
- Feb. 25, 2021 10:04 PM EST
DETROIT (AP) — Antoine Davis set Horizon League tournament records with 46 points and 10 3-pointers, and Detroit Mercy beat Robert Morris 83-73 on Thursday night.
Fifth-seeded Detroit Mercy will face No. 4 seed Northern Kentucky on March 2 in the quarterfinals.
Bul Kuol had 14 points and seven rebounds for Detroit Mercy (12-9). Chris Brandon added 10 points and 13 rebounds, and Marquell Fraser had six assists. Davis was 16 of 26 from the field, including 10 of 16 from distance.
Kahliel Spear scored a career-high 22 points for the Colonials (4-15), who have now lost four consecutive games. Jon Williams added 17 points and nine assists, and Kam Farris had 15 points.
The Titans remain undefeated in three games against the Colonials this season. Most recently, Detroit defeated Robert Morris 80-61 last Saturday.

redpajama_set_name: RedPajamaCommonCrawl


Austin nonprofit Black Fret awarded $250,000 to local musicians at the fifth annual Black Fret Ball at ACL Live at The Moody Theatre on Friday, Dec. 7, 2018. The figure raised the organization's overall grants awarded to Austin musicians over the last five years past $1 million.
Grant recipients in the $20,000 category this year included Donovan Keith, Greyhounds, Los Coast, Jane Ellen Bryant, Jaimee Harris, Wood & Wire, Jeff Plankenhorn, Israel Nash, Shy Beast and Tomar & the FCs. $5,000 grant recipients included Texas KGB, Rebecca Loebe, Dave Scher, Palo Duro, Megafauna, A Giant Dog, Trouble in the Streets, Billy King & the Bad Bad Bad, Otis the Destroyer and Kalu & the Electric Joint. Fifteen of this year's grant nominees performed on the program.
Black Fret is open to all patrons of music and those interested in becoming a member can find details at www.blackfret.org.


When it comes time to step up to their first ultra, many runners automatically assume that they need to start running crazy-long distances, in extremes of heat, while fasting and restricting fluid intake. That's one approach I guess, but I'd suggest not a very good one. More important than anything is progressively overloading the body to adapt to the rigours of running long distances, and in no case is this more important than in the feet and legs.
There are lots of pieces that have to fit together in order to form a functional #ultrabody. But perhaps the most obvious is the combination of your feet and legs - the act of running kind-of requires them (obviously this generalisation excludes para-athletes who do amazing things - including running - without full use or indeed presence of these limbs).
Your feet, and then slightly further up the chain your legs, are your point of contact with the ground, and they'll touch the ground somewhere around 170 steps per minute when running - that adds up to more than 10,000 steps per hour, which, for a first-timer attempting a 50km ultra may be 10hrs plus, which then adds up to over 100,000 steps! Check my maths, but regardless you get my point - it's a big job that the feet and legs have to do.
It would be madness to attempt to jump straight in and run long training runs of 3, 4, 5+ hours without first giving the body some preparation - you can't expect the body to suddenly take 50,000 steps in a training session when it's only used to doing a mixed 10,000 steps over the course of a day when walking from your desk to the coffee machine. Madness I tell 'ya.
So how do we prepare the feet and legs for such a poundin'?
I'm building a 30 storey building - do I just keep building level after level, and hope like heck the wet and still-drying concrete is able to hold, or do I build a level, let the concrete harden and gain strength, then continue on to the next level, repeating the build a bit, wait a bit process? As a structural engineer (you didn't all know that about me, did 'ya!), I can tell you the build a bit, wait a bit approach is much wiser. Much.
Your body, or specifically your feet and legs for this post, is the 30 storey building, and you are the builder, slowly building a layer of running fitness, allowing it to adapt ("set"), then building some more, each time developing further until you reach your goal height (or race in running terms). You see what we're doing here?
If you too quickly try and run big mileage, the muscles, tendons, joints and bone structures in your lower limbs simply aren't ready to withstand the load, and you will break down.
If you too quickly try and cram in large vertical gain into your runs (i.e. lots of uphill running), the muscles, tendons, joints and bone structures in your lower limbs simply aren't ready to withstand the load, and you will break down.
If you too quickly try and do speed work in the hope of becoming super fast overnight, the muscles, tendons, joints and bone structures in your lower limbs simply aren't ready to withstand the load, and you will break down.
See the point I'm making here?
Your feet and legs can withstand running crazy long distances, but the key is in slowly allowing them to do so, and you do this by progressively exposing them to more work.
get a foam roller (and actually use it) to work out niggles in the quads, hips, hamstrings and calves.
And that's the feet and legs. By slowly increasing the time and intensity of your running, you allow your lower limbs to prepare themselves for running a long way, and you minimise the risk of nasty stuff like stress fractures, plantar fasciitis, ITB pain, etc becoming a hindrance to your running.


This Page Contains the list of Latest Tatacliq(Luxury) Coupons for the Month of April 2019. The Tatacliq(Luxury) Coupon Codes are available for Electronics, Mobile Shopping these Discount Vouchers can be availed by both New & Existing users of luxury.tatacliq.com. The New Tatacliq(Luxury) Promo Codes are automatically updated on this page as soon as they are release. There are over 30 active coupons available for Tatacliq(Luxury), Indian users can shop online & avail benefits from this Store by selecting the Best Coupon Code that gives them the maximum OFF on their purchase via luxury.tatacliq.com. Tatacliq(Luxury) generally comes up with regular promotions by offering lucrative deals to their customers, follow the INRDeals Homepage for exciting deals from Tatacliq(Luxury). The Verified Coupons were Last Updated on this Page on 26 April 2019.
Verified on 2 May 2018. Tata CLiQ Luxury brings top brands at the best price.
Shop here from brands like Alberto Guardiani, Armani Exchange, Brooks Brothers, Brooks Brothers, Red Fleece, Coach,Coccinelle, Diesel, Dune London, Emporio Armani and lot more.
Buy top latest branded handbags at best price from Tata CLiQ Luxury.
Discount coupon code is not required to avail the offer.
Choose from top brands like Michael Kors, Coach, Coccinelle, Furla, Armani Exchange, Dune London etc.
Shop today at Tata CLiQ Luxury store to grab best brand products.
Verified on 2 May 2018. Buy women shoes from top brands at best price from Tata Cliq Luxury.
TataCLiQLuxury promo code is not required to avail the best deals.
Choose from top brands like Armani Exchange, Dune London and lot more.
Verified on 2 May 2018. TataCliq luxury is offering the amazing discounts on top branded women's watches.
Shop now and get up to 20% discount.
Offer can not be clubbed with any other promotions.
Offer valid on landing page products only.
Tatacliq Luxury offering the best deals on sarees.
Shop here and avail the best collection of sarees.
TataCliq Luxury promo code not required at checkout page to get a discount.
Tata CLiQ is a first-of-its-kind Physical marketplace that combines online shopping with the offline store experience, to serve over one million customers. An Indian e-commerce website, selling Apparel, Footwear, Electronics, Watches and Accessories. For such a versatile e-commerce website INRDeals provide its publishers the simplest Tata CLiQ affiliate program. With a pre- approved INRDeals Publisher account, Publishers can now easily generate affiliate links of Tata CLiQ using our innovative tools one click link generation, Publishers can generate promotable affiliate links from the homepage of INRDeals through a simple single click to save on the hassle and time. The clever INRDeals plugin will convert normal links into publisher's loyalty link automatically and now publisher can promote Tata CLiQ affiliate links and monetize its content very easily. Publishers no longer have to search for hot selling deals as INRDeals handpicks the best Tata CLiQ deals and features them on the homepage of publisher's content. Publishers will get a deals engine showcasing the best hot deals from Tata CLiQ on their website/ blog which will trigger sales hence generating revenue for our publishers. Publishers will get direct access to all sorts of campaigns including CPS, CPI, CPC, CPL, CPA, all from a single INRDeals dashboard. Publishers will also get a dedicated accounts manager who'll be responsible for managing their Tata CLiQ affiliate programs and handling all Tata CLiQ affiliate related queries and makes sure best payout for publishers. Publishers can promote INRDeals in their network and every person they refer to INRDeals helps them earn 30% of whatever they will earn/ save.


text:
/*!
 * @addtogroup CharViewer Projects/CoX/Utilities/CharViewer
 * @{
 */

#include "CharViewerApp.h"
#include "CoHModelLoader.h"
#include "CohModelConverter.h"
#include "CohTextureConverter.h"
#include "Common/GameData/GameDataStore.h"
#include "Common/GameData/anim_definitions.h"
#include "Common/GameData/bodypart_definitions.h"
#include "Common/GameData/npc_definitions.h"
#include "Common/GameData/seq_definitions.h"
#include "Common/Runtime/Animation.h"
#include "Common/Runtime/AnimationEngine.h"
#include "Common/Runtime/Prefab.h"
#include "Common/Runtime/RuntimeData.h"
#include "Common/Runtime/SceneGraph.h"
#include "Common/Runtime/Sequencer.h"
#include "Common/Runtime/Texture.h"
#include "GameData/anim_definitions.h"
#include "SideWindow.h"

#include <Lutefisk3D/Core/Context.h>
#include <Lutefisk3D/Core/CoreEvents.h>
#include <Lutefisk3D/Engine/Engine.h>
#include <Lutefisk3D/Engine/EngineDefs.h>
#include <Lutefisk3D/Graphics/AnimatedModel.h>
#include <Lutefisk3D/Graphics/Animation.h>
#include <Lutefisk3D/Graphics/AnimationController.h>
#include <Lutefisk3D/Graphics/Camera.h>
#include <Lutefisk3D/Graphics/DebugRenderer.h>
#include <Lutefisk3D/Graphics/Light.h>
#include <Lutefisk3D/Graphics/Material.h>
#include <Lutefisk3D/Graphics/Model.h>
#include <Lutefisk3D/Graphics/Octree.h>
#include <Lutefisk3D/Graphics/Renderer.h>
#include <Lutefisk3D/Graphics/StaticModel.h>
#include <Lutefisk3D/Graphics/Zone.h>
#include <Lutefisk3D/IO/File.h>
#include <Lutefisk3D/Input/Input.h>
#include <Lutefisk3D/Input/InputEvents.h>
#include <Lutefisk3D/Resource/ResourceCache.h>
#include <Lutefisk3D/Scene/Node.h>
#include <Lutefisk3D/Scene/Scene.h>
#include <Lutefisk3D/SystemUI/Console.h>
#include <Lutefisk3D/SystemUI/DebugHud.h>
#include <Lutefisk3D/UI/BorderImage.h>
#include <Lutefisk3D/UI/Font.h>
#include <Lutefisk3D/UI/Text3D.h>
#include <Lutefisk3D/UI/UI.h>

#include <QSettings>
#include <QtCore/QDebug>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMessageBox>

using namespace Urho3D;
namespace
{
Urho3D::Vector3 fromGLM(glm::vec3 v)
{
    return {v.x, v.y, v.z};
}
Urho3D::Quaternion fromGLM(glm::quat v)
{
    return Urho3D::Quaternion(v.w, v.x, v.y, v.z);
}
} // end of anonymous namespace

struct LF3CharacterNode : public SEGS::SceneTreeNode
{
    SharedPtr<Node>      m_node;
    Skeleton *           m_skeleton           = nullptr;
    AnimationController *m_anim_controller    = nullptr;
    AnimationState *     m_anim_state         = nullptr;
    SEGS::RenderingData *m_rendering_data     = nullptr;
    StaticModel *        m_animated_component = nullptr;
    SEGS::Model *        m_model              = nullptr;

    uint32_t  m_flags;
    glm::vec3 m_bone_scale;
    glm::vec3 m_bone_delta;
    // material specification
    glm::vec4      m_color_1;
    glm::vec4      m_color_2;
    SEGS::HTexture m_texture_1;
    SEGS::HTexture m_texture_2;
};

// Stupid global to allow converters to know where the unpacked files are
QString basepath;

CharViewerApp::CharViewerApp(Context *ctx) : Application("CoX Costume Viewer", ctx) {}

CharViewerApp::~CharViewerApp() {}

void CharViewerApp::Setup()
{
    engineParameters_[EP_FULL_SCREEN]  = false;
    engineParameters_[EP_WINDOW_TITLE] = m_appName;
    // Force the data directory names to use mapviewer_data/ root
    engineParameters_[EP_RESOURCE_PATHS] = "mapviewer_data/Data;mapviewer_data/CoreData";
}
void cohQuatToMat3(glm::quat a1, glm::mat3 &a2)
{
    float xw = 2 * a1.x * a1.w;
    float yw = 2 * a1.y * a1.w;
    float zw = 2 * a1.z * a1.w;
    float xx = 2 * a1.x * a1.x;
    float yx = 2 * a1.y * a1.x;
    float zx = 2 * a1.z * a1.x;
    float yy = 2 * a1.y * a1.y;
    float zy = 2 * a1.z * a1.y;
    float zz = 2 * a1.z * a1.z;
    a2[0].x  = 1.0f - (zz + yy);
    a2[0].y  = yx - zw;
    a2[0].z  = zx + yw;
    a2[1].x  = yx + zw;
    a2[1].y  = 1.0f - (zz + xx);
    a2[1].z  = zy - xw;
    a2[2].x  = zx - yw;
    a2[2].y  = zy + xw;
    a2[2].z  = 1.0f - (yy + xx);
}
void resetLF3DSkeleton(SEGS::HAnimationTrack src, Skeleton &tgt)
{
    int idx = 0;
    for (Bone &bn : tgt.GetModifiableBones())
    {
        BoneAnimTrack *track = getTrackForBone(src, idx);
        if (track)
        {
            glm::vec3 pos       = track->pos_keys.front();
            glm::quat quat      = track->rot_keys.front();
            bn.initialPosition_ = {pos.x, pos.y, pos.z};
            bn.initialRotation_ = {quat.w, quat.x, quat.y, quat.z};
        }
        idx++;
    }
    tgt.Reset();
}
void cohAnimTrackToLF3D(Urho3D::AnimationTrack &res, BoneAnimTrack &bt)
{
    int                            tick_count = std::max(bt.position_ticks, bt.rotation_ticks);
    std::vector<AnimationKeyFrame> converted_frames;
    converted_frames.resize(tick_count);
    for (int kf_idx = 0; kf_idx < tick_count; ++kf_idx)
    {
        AnimationKeyFrame &kf(converted_frames[kf_idx]);
        kf.time_ = kf_idx / 15.0f;
        if (kf_idx < bt.pos_keys.size())
        {
            kf.position_ = fromGLM(bt.pos_keys[kf_idx]); //
        }
        else if (!bt.pos_keys.empty())
            kf.position_ = fromGLM(bt.pos_keys.back());

        if (kf_idx < bt.rot_keys.size())
        {
            glm::mat3 tgt;
            cohQuatToMat3(bt.rot_keys[kf_idx], tgt);
            glm::quat conv = glm::quat_cast(tgt);
            kf.rotation_   = fromGLM(conv); // bt.rot_keys[kf_idx]
        }
        else if (!bt.rot_keys.empty())
        {
            glm::mat3 tgt;
            cohQuatToMat3(bt.rot_keys.back(), tgt);
            glm::quat conv = glm::quat_cast(tgt);
            kf.rotation_   = fromGLM(conv); // bt.rot_keys[kf_idx]
        }
    }
    if (bt.pos_keys.size() > 1)
        res.channelMask_ |= CHANNEL_POSITION;
    if (bt.rot_keys.size() > 1)
        res.channelMask_ |= CHANNEL_ROTATION;
    res.name_ = SEGS::boneName(bt.tgtBoneOrTexId);
    res.SetAllKeyFrames(converted_frames.data(), converted_frames.size());
}
void CharViewerApp::CreateBaseScene()
{
    // Create a basic plane, a light and a camera
    ResourceCache *cache = GetContext()->m_ResourceCache.get();
    cache->AddResourceDir("./converted");
    m_scene = new Scene(GetContext());
    m_scene->CreateComponent<DebugRenderer>();
    Octree *oct = m_scene->CreateComponent<Octree>();
    oct->SetSize(BoundingBox(-7000, 7000), 8);

    Node *zoneNode = m_scene->CreateChild("Zone");
    Zone *zone     = zoneNode->CreateComponent<Zone>();
    zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f));
    //    zone->SetFogColor(Color(0.5f, 0.5f, 0.7f));
    //    zone->SetFogStart(100.0f);
    //    zone->SetFogEnd(300.0f);
    zone->SetBoundingBox(BoundingBox(-32767, 32768));

    Node *planeNode = m_scene->CreateChild("Plane");
    planeNode->SetPosition({0, -300, 0});
    planeNode->SetScale(Vector3(7000.0f, 1.0f, 7000.0f));
    StaticModel *planeObject = planeNode->CreateComponent<StaticModel>();
    planeObject->SetModel(cache->GetResource<Model>("Models/Plane.mdl"));
    planeObject->SetMaterial(cache->GetResource<Material>("Materials/Checkboard.xml"));

    // A directional light
    Node *lightNode = m_scene->CreateChild("DirectionalLight");
    lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f));
    Light *light = lightNode->CreateComponent<Light>();
    light->SetLightType(LIGHT_DIRECTIONAL);
    light->SetSpecularIntensity(0.5f);

    m_camera_node = m_scene->CreateChild("Camera");
    Camera *cam   = m_camera_node->CreateComponent<Camera>();
    m_camera_node->SetPosition(Vector3(0.0f, 5.0f, 0.0f));
    cam->setFarClipDistance(1500);
}

void CharViewerApp::SetupViewport()
{
    Renderer *          renderer = GetContext()->m_Renderer.get();
    SharedPtr<Viewport> viewport(new Viewport(GetContext(), m_scene, m_camera_node->GetComponent<Camera>()));
    renderer->SetViewport(0, viewport);
}

void CharViewerApp::CreateConsoleAndDebugHud()
{
    // Create console
    engine_->CreateConsole();

    // Create debug HUD.
    engine_->CreateDebugHud();
}

void CharViewerApp::prepareSideWindow()
{
    Graphics *graphics = GetContext()->m_Graphics.get();
    m_sidewindow       = new SideWindow(nullptr);
    m_sidewindow->move(0, graphics->GetWindowPosition().y_);
    m_sidewindow->resize(graphics->GetWindowPosition().x_ - 20, graphics->GetHeight());
    m_sidewindow->show();
    connect(this, &CharViewerApp::modelSelected, m_sidewindow, &SideWindow::onModelSelected);
    connect(m_sidewindow, &SideWindow::costumeSelected, this, &CharViewerApp::onCostumeSelected);
    m_sidewindow->setMapViewer(this);
}

void CharViewerApp::prepareCursor()
{
    ResourceCache *cache = GetContext()->m_ResourceCache.get();
    UI *           ui    = GetContext()->m_UISystem.get();
    Input *        input = GetContext()->m_InputSystem.get();
    XMLFile *      style = cache->GetResource<XMLFile>("UI/DefaultStyle.xml");
    ui->GetRoot()->SetDefaultStyle(style);

    // Create a Cursor UI element because we want to be able to hide and show it at will. When hidden, the mouse cursor
    // will control the camera, and when visible, it will interact with the scene
    SharedPtr<Cursor> cursor(new Cursor(GetContext()));
    cursor->SetStyleAuto();
    ui->SetCursor(cursor);
    // Set starting position of the cursor at the rendering window center
    input->SetMouseMode(ui->GetCursor()->IsVisible() ? MM_FREE : MM_RELATIVE); //,MM_RELATIVE
}

void CharViewerApp::Start()
{
    QSettings our_settings(QSettings::IniFormat, QSettings::UserScope, "SEGS", "MapViewer");
    basepath = our_settings.value("ExtractedDir", QString()).toString();
    if (!basepath.endsWith('/'))
        basepath += '/';
    CreateBaseScene();
    SetupViewport();
    CreateConsoleAndDebugHud();
    prepareCursor();

    // Subscribe to key events
    g_inputSignals.keyDown.Connect(this, &CharViewerApp::HandleKeyDown);
    g_inputSignals.keyUp.Connect(this, &CharViewerApp::HandleKeyUp);
    // Subscribe to update ticks
    g_coreSignals.update.Connect(this, &CharViewerApp::HandleUpdate);
    g_coreSignals.postRenderUpdate.Connect(this, &CharViewerApp::HandlePostRenderUpdate);

    Input *input = GetContext()->m_InputSystem.get();
    input->SetMouseMode(MM_FREE); //,MM_RELATIVE
    if (!getGameData().read_game_data(basepath))
    {
        QMessageBox::critical(nullptr, "Missing files", "At least some of the required bin/* files are missing");
        exit(1);
    }
    if (!getRuntimeData().prepare(basepath))
    {
        QMessageBox::critical(nullptr, "Missing files", "At least some of the required bin/* files are missing");
        exit(1);
    }

    SEGS::preloadTextureNames(basepath);
    prepareSideWindow();
}

void CharViewerApp::loadSelectedSceneGraph(const QString &path)
{
    m_selected_drawable = nullptr;
    for (auto v : m_converted_nodes)
    {
        m_scene->RemoveChild(v.second);
    }
    m_converted_nodes.clear();
    m_coh_scene.reset(SEGS::loadWholeMap(path));
}
struct SequencerInfo
{
    QString name;
};

struct EntitySequencerInstance
{
    SEGS::SequencerInstance *m_sequencer_instance;
    SequencerInfo            m_seq_type_info;
};
struct RenderableCharacter
{
    Parse_Costume *          m_currently_applied_costume;
    EntitySequencerInstance *m_entity_sequencer;
};
// FIXME: original code does not set alpha in custom colors, even though some callers pass RGBA values to it
void setCustomNodeColors(Node *node, const SEGS::ModelPartColor &colors)
{
    // TODO:    node->m_flags |= 0x200000;
    node->SetVar("Color1", Urho3D::Color(colors.color1.r, colors.color1.g, colors.color1.b));
    node->SetVar("Color2", Urho3D::Color(colors.color2.r, colors.color2.g, colors.color2.b));
}
void setNodeTextures(Node *node, SEGS::HTexture t1, SEGS::HTexture t2)
{
    if (!node)
        return;
    if (!(t1 || t2))
        return;
    SEGS::HTexture white_tex = tryLoadTexture(node->GetContext(), "white.tga");

    if (!t1)
        t1 = white_tex;
    if (!t2)
        t2 = white_tex;
    node->SetVar("Texture1", t1.toInt());
    node->SetVar("Texture2", t2.toInt());
    // TODO: node->m_flags |= 0x40000;
}
void animBuildSkeleton(std::vector<SEGS::BoneLink> &bone_link_arr, int start_bone_id, Node *parent,
                       SEGS::HSequencerInstance seq, std::vector<Bone> &converted)
{
    SEGS::BoneLink *bone_link = nullptr;

    for (int idx = start_bone_id; idx != -1; idx = bone_link->next_bone_idx)
    {
        assert(SEGS::legitBone(idx));
        if (idx >= converted.size())
            converted.resize(idx + 1);
        Bone &b(converted[idx]);

        bone_link = &bone_link_arr[idx];
        assert(bone_link && idx == bone_link->id);
        Urho3D::Node *skel_node = parent->GetChild(SEGS::boneName(idx));
        if (!skel_node)
            skel_node = parent->CreateChild(SEGS::boneName(idx));
        b.node_        = skel_node;
        b.parentIndex_ = start_bone_id;
        b.name_        = SEGS::boneName(idx);

        skel_node->SetVar("BoneSlot", bone_link->id);
        // TODO: if ( seq->m_seq_type_info.m_light_as_door_outside )
        //            char_node->m_flags |= 0x1000000;
        //        char_node->m_flags |= 0x400000;
        skel_node->SetVar("BoneScale", fromGLM(seq->m_bone_scales[bone_link->id]));
        setCustomNodeColors(skel_node, seq->m_part_colors[idx]);
        setNodeTextures(skel_node, seq->m_bone_textures_1[idx], seq->m_bone_textures_2[idx]);
        // char_node->rgbs = (uint32_t *)seq->m_bone_vertices_arr[idx];
        seq->m_interpolation_state[bone_link->id] |= 1u;
        seq->m_interpolation_state[bone_link->id] |= 2u;
        if (bone_link->child_id != -1)
            animBuildSkeleton(bone_link_arr, bone_link->child_id, skel_node, seq, converted);
    }
}
void getBaseRotation(BoneAnimTrack *a1, Matrix4 &a2)
{
    glm::mat3 tgt;
    cohQuatToMat3(a1->rot_keys[0], tgt);
    a2.m00_ = tgt[0][0];
    a2.m01_ = tgt[0][1];
    a2.m02_ = tgt[0][2];
    a2.m10_ = tgt[1][0];
    a2.m11_ = tgt[1][1];
    a2.m12_ = tgt[1][2];
    a2.m20_ = tgt[2][0];
    a2.m21_ = tgt[2][1];
    a2.m22_ = tgt[2][2];
}
static void animAttachBoneTracks(SEGS::HAnimationTrack skeleton_track, SEGS::HAnimationTrack anim,
                                 LF3CharacterNode *node)
{

    assert(skeleton_track && !skeleton_track->m_bone_tracks.empty());
    if (!node)
        return;

    resetLF3DSkeleton(skeleton_track, *node->m_skeleton);
    Context *  ctx            = node->m_node->GetContext();
    Animation *converted_anim = ctx->m_ResourceCache->GetResource<Animation>(skeleton_track->m_name);
    if (!converted_anim)
    {
        converted_anim = new Urho3D::Animation(ctx);
        converted_anim->SetName(skeleton_track->m_name);
        ctx->m_ResourceCache->AddManualResource(converted_anim);
        int max_length = 0;
        for (const SEGS::BoneLink &bl : skeleton_track->m_skeleton_hierarchy)
        {
            // TODO: this will not rebase animation skeleton_track to start of `anim` pose
            BoneAnimTrack *bat = getTrackForBone(skeleton_track, bl.id);
            if (bat)
                ; // TODO: node->m_flags &= ~0x800000u;
            else
            {
                bat = getTrackForBone(skeleton_track->m_backup_anim_track, bl.id);
                // TODO: mark node->m_flags |= 0x800000;
            }
            if (bat)
            {
                max_length         = std::max<int>(max_length, bat->pos_keys.size());
                max_length         = std::max<int>(max_length, bat->rot_keys.size());
                AnimationTrack *at = converted_anim->CreateTrack(SEGS::boneName(bl.id));
                cohAnimTrackToLF3D(*at, *bat);
            }
        }
        converted_anim->SetLength(max_length / 15.0f);
        node->m_anim_controller->Play(skeleton_track->m_name, 0, true);
    }

    node->m_anim_state = node->m_anim_controller->GetAnimationState(skeleton_track->m_name);
    node->m_anim_state->SetLooped(true);
}
SEGS::Model *animGetGeometryForThisBone(int id, SEGS::HSequencerInstance hseq)
{
    static const char *s_lod_extensions[] = {
        "", "_LOD1", "_LOD2", "_LOD3", "_LOD4",
    };
    SEGS::SequencerInstance &seq_inst(hseq.get());
    SEGS::RuntimeData &      rd(getRuntimeData());
    SEGS::PrefabStore *      pf(rd.m_prefab_mapping);
    char                     buf[100];
    char                     model_name[100];
    QString                  filename;
    SEGS::Model *            result = nullptr;

    assert(SEGS::legitBone(id));
    if (0 == hseq->m_bone_geometry_names[id].compare("NONE", Qt::CaseInsensitive))
        return nullptr;

    if (SEGS::legitBone(id))
    {
        if (!hseq->m_bone_geometry_names[id].isEmpty())
        {
            strcpy(buf, hseq->m_bone_geometry_names[id].data());
            char *next_dot = strtok(buf, ".");
            if (hseq->m_lod_level)
                filename = hseq->m_seq_type_info.lod_Name(hseq->m_lod_level);
            else
                filename = QString("player_library/") + next_dot + ".geo";
            char *next_tok = strtok(nullptr, "");
            sprintf(model_name, "%s%s", next_tok, s_lod_extensions[hseq->m_lod_level]);
            result = pf->modelFind(filename, model_name);
            if (!result && hseq->m_lod_level == 1)
            {
                filename = QString("player_library/") + next_dot + ".geo";
                sprintf(model_name, "%s%s", next_tok, "");
                result = pf->modelFind(model_name, filename);
            }
            if (!result && !hseq->m_lod_level)
            {
                qCritical() << " ## ERROR! ## ";
                qCritical() << " %s asked for bad custom geometry: ", qPrintable(hseq->m_seq_type_info.m_name);
                qCritical() << " %s at %s", model_name, qPrintable(filename);
            }
        }
    }
    if (!result)
    {
        if (!hseq->m_seq_type_info.lod_Name(hseq->m_lod_level).isEmpty())
        {
            sprintf(buf, "GEO_%s%s", SEGS::boneName(id), s_lod_extensions[hseq->m_lod_level]);
            result = pf->modelFind(hseq->m_seq_type_info.lod_Name(hseq->m_lod_level), buf);
        }
    }
    return result;
}

void animAttachGeometryToSkeleton(Node *node, SEGS::HSequencerInstance seq)
{
    if (node->GetVars().find("BoneSlot") != node->GetVars().end())
    {
        int bone_slot = node->GetVar("BoneSlot").GetInt();
        assert(SEGS::legitBone(bone_slot));
        SEGS::Model *model = animGetGeometryForThisBone(bone_slot, seq);
        if (model)
        {
            convertedModelToLutefisk(node, model, 0, 1000.0f);
            //            node->m_animated_component->SetModel(node->m_model);
            //            gfxTreeInitGfxNodeWithObjectsTricks(node);
            //            node->m_model->model_VisSphereRadius = a2->m_seq_type_info.m_visibility_sphere_radius;
        }
    }
    for (auto child : node->GetChildren())
    {
        animAttachGeometryToSkeleton(child, seq);
    }
}
void setColorsAndTextures(SEGS::HSequencerInstance a1, Node *node)
{
    if (node->GetVars().find("BoneSlot") != node->GetVars().end())
    {
        int bone_slot = node->GetVar("BoneSlot").GetInt();
        if (node->HasComponent<StaticModel>())
        {
            // TODO: modify the model materials here
            if (SEGS::legitBone(bone_slot))
            {
                setCustomNodeColors(node, a1->m_bone_colors[bone_slot]);
                setNodeTextures(node, a1->m_bone_textures_1[bone_slot], a1->m_bone_textures_2[bone_slot]);
            }
        }
    }
    for (auto v : node->GetChildren())
        setColorsAndTextures(a1, v);
}

void animSetHeader(SEGS::HSequencerInstance seq)
{
    using namespace SEGS;

    SeqMove *anim = &seq->m_anim;
    // TODO: verify that SceneNode has been instantiated into a SceneTreeNode ?
    LF3CharacterNode *char_node = dynamic_cast<LF3CharacterNode *>(seq->m_node);
    assert(char_node);
    SeqTypeDefData *seq_typedef   = getSeqTypedefByName(seq->m_template, seq->m_seq_type_info.m_seq_type);
    seq->m_animation.m_base_track = getOrLoadAnimationTrack(seq_typedef->pBaseSkeleton);
    HAnimationTrack atrack        = seq->m_animation.m_base_track;
    AnimTrack &     track_ref(atrack.get());
    if (!seq->m_animation.m_base_track)
        qCritical() << QString("Animation %1 doesn't exist. Sequencer %2 wants it for a base skeleton")
                           .arg(QString(seq_typedef->pBaseSkeleton), QString(seq->m_seq_type_info.m_seq_type));
    assert(seq->m_animation.m_base_track && anim->move);
    seq->m_curr_interpolated_frame = 0;
    seq->m_interpolation_state.fill(0);
    if (char_node->m_anim_controller && char_node->m_anim_state)
    {
        char_node->m_anim_controller->Stop(char_node->m_anim_state->GetAnimation()->GetName());
        char_node->m_anim_controller->Update(0);
        char_node->m_anim_state = nullptr;
    }

    qWarning() << "Not deleting animation";
    //    if (gfxTreeNodeIsValid(seq->m_node, seq->gfx_root_unique_id))
    //        gfxTreeDeleteAnimation(seq->m_node, seq);
    char_node->m_rendering_data = &seq->m_rendering_data;
    std::vector<Bone> converted;
    animBuildSkeleton(seq->m_animation.m_base_track->m_skeleton_hierarchy,
                      seq->m_animation.m_base_track->m_skeleton_hierarchy[0].id, char_node->m_node, seq, converted);
    delete char_node->m_skeleton;
    char_node->m_skeleton                       = new Skeleton;
    char_node->m_skeleton->GetModifiableBones() = converted;
    char_node->m_skeleton->SetRootBoneIndex(atrack->m_skeleton_hierarchy[0].id);
    animAttachBoneTracks(seq->m_anim.type->m_anm_track, SEGS::HAnimationTrack(seq->m_animation.m_base_track),
                         char_node);
    animAttachGeometryToSkeleton(char_node->m_node, seq);
    setColorsAndTextures(seq, char_node->m_node);
    qWarning() << "Not linking inactive bones";
    //    if (!gfxTreeRelinkSuspendedNodes(seq->m_node, seq->seq_instance_handle))
    //        qCritical("     (missing model bone: %s) \n", qPrintable(anim->move->m_Type[0].m_Anim[0].name));
    qWarning() << "Not checking for async loaded objects";
    // seq->loadingObjects = animCheckForLoadingObjects(seq->m_node, seq->seq_instance_handle);
    // animCalcObjAndBoneUse((LF3CharacterNode *)seq->m_node, seq);
}
SEGS::HSequencerInstance seqLoadInst(const QString &name, int rand_seed, SEGS::SceneTreeNode *node)
{
    assert(node);
    SEGS::HSequencerInstance seq = SEGS::SequencerInstanceStorage::instance().create(node);
    assert(seq);
    SEGS::seqResetSeqType(seq, qPrintable(name), rand_seed);
    animSetHeader(seq);
    return seq;
}
void setSeqeuncerInstance(DisplayedCharacter &costume, SEGS::HSequencerInstance seq_instance)
{
    costume.m_sequencer = seq_instance;
    // todo: create a collision mesh here.
}
void changeCharacterSequencer(DisplayedCharacter &displayed_char, const QString &bodyname)
{
    using namespace SEGS;
    const int rand_seed = 42;
    assert(!bodyname.isEmpty());
    HSequencerInstance sequencer = displayed_char.m_sequencer;
    if (sequencer) // already initialized.
    {
        if (0 == bodyname.compare(displayed_char.m_data.m_name, Qt::CaseInsensitive))
            return;
        // release old sequencer.
        sequencer.destroy();
    }
    HSequencerInstance seq_inst = seqLoadInst(bodyname, rand_seed, displayed_char.m_node);
    setSeqeuncerInstance(displayed_char, seq_inst);
    return;
}
static void scaleHero(SEGS::HSequencerInstance seq, float scale)
{
    if (!seq)
        return;

    float     factor    = scale / 100.0f + 1.0f;
    glm::vec3 scale_vec = {factor, factor, factor};
    changeSequencerScale(seq, scale_vec);
}

void changeBoneColorization(SEGS::HSequencerInstance hseq, int bone_idx, const SEGS::ModelPartColor &mpc)
{
    assert(hseq);
    assert(SEGS::legitBone(bone_idx));
    hseq->m_bone_has_color[bone_idx]       = 1;
    SEGS::ModelPartColor prev_val          = hseq->m_bone_colors[bone_idx];
    hseq->m_bone_colors[bone_idx]          = mpc;
    hseq->m_bone_colors[bone_idx].color1.a = 1;
    hseq->m_bone_colors[bone_idx].color2.a = 1;
    hseq->m_updated_appearance |= !(prev_val == mpc);
}
static void setupModelPartColors(RGBA skincolor, RGBA col1, RGBA col2, SEGS::ModelPartColor &tgt1, const QString &name)
{
    if (name.contains("SKIN", Qt::CaseInsensitive))
    {
        tgt1.color1 = skincolor.toFloats();
        tgt1.color2 = col1.toFloats();
    }
    else
    {
        tgt1.color1 = col1.toFloats();
        tgt1.color2 = col2.toFloats();
    }
}
void changeBodyPartColorization(SEGS::HSequencerInstance hseq, BodyPart_Data *bp, RGBA skin_color, RGBA color1,
                                RGBA color2, const QString &texname)
{
    if (bp->boneIndices[0] == -1)
        return;
    SEGS::ModelPartColor mpc;
    setupModelPartColors(skin_color, color1, color2, mpc, texname);
    changeBoneColorization(hseq, bp->boneIndices[0], mpc);
    if (bp->m_BoneCount == 2)
        changeBoneColorization(hseq, bp->boneIndices[1], mpc);
}
void changeBoneGeometry(SEGS::HSequencerInstance hseq, int bone, const QByteArray &geom_name)
{
    SEGS::RuntimeData &rd(getRuntimeData());
    auto               prefab_store = rd.m_prefab_mapping;
    bool               result       = true;
    QByteArray         bonename     = geom_name;

    assert(hseq);
    assert(SEGS::legitBone(bone));

    if (!geom_name.isEmpty() && 0 != geom_name.compare("NONE"))
    {
        auto    refparts = geom_name.split('.');
        QString filename = QString("player_library/") + refparts[0] + ".geo";
        if (!prefab_store->modelFind(filename, refparts[1]))
        {
            if (refparts[1].toLower().contains("larm"))
                bonename = "NONE";
            else
                result = false;
        }
    }
    if (bonename.isEmpty())
        return;
    // if already proper name is assigned, no need to set `m_updated_appearance`
    if (0 == hseq->m_bone_geometry_names[bone].compare(geom_name, Qt::CaseInsensitive))
        return;

    hseq->m_updated_appearance        = 1;
    hseq->m_bone_geometry_names[bone] = bonename;
    if (!result)
    {
        hseq->m_bone_geometry_names[bone] += "BAD!";
    }
}

void changeBodyPartGeometry(SEGS::HSequencerInstance hseq, const Parse_Costume *costume, BodyPart_Data *bodypart,
                            const QByteArray &geom_name)
{
    if ((geom_name.isEmpty() || !bodypart || bodypart->boneIndices[0] == -1))
        return;

    if (0 == geom_name.compare("NONE", Qt::CaseInsensitive))
    {
        changeBoneGeometry(hseq, bodypart->boneIndices[0], "NONE");
        if (bodypart->m_BoneCount == 2)
            changeBoneGeometry(hseq, bodypart->boneIndices[1], "NONE");
        return;
    }

    QByteArray buf =
        QString("%1_%2.GEO_%3").arg(entTypeFileName(costume), bodypart->m_BaseName, bodypart->m_GeoName).toLatin1();
    QByteArray buf3 = buf;

    if (bodypart->m_BoneCount == 2)
        buf3 += "R";

    changeBoneGeometry(hseq, bodypart->boneIndices[0], buf3 + "_" + geom_name);
    if (bodypart->m_BoneCount == 2)
    {
        changeBoneGeometry(hseq, bodypart->boneIndices[1], buf + "L_" + geom_name);
    }
}
void changeBoneTexture(Urho3D::Context *ctx, SEGS::HSequencerInstance hseq, int bone, const QByteArray &base_tex,
                       const QByteArray &detail_tex)
{

    assert(hseq);
    assert(SEGS::legitBone(bone));
    SEGS::HTexture white_tex = tryLoadTexture(ctx, "white.tga");
    SEGS::HTexture bone_tex_1;

    if (!base_tex.isEmpty())
    {
        bone_tex_1 = white_tex;
        if (base_tex.toLower() != "none")
        {
            bone_tex_1 = tryLoadTexture(ctx, base_tex);
            if (!bone_tex_1 || (bone_tex_1 == white_tex && base_tex.toLower() != "white"))
            {
                qCritical() << "changeBoneTexture: failed to locate textur" << base_tex << "for bone"
                            << SEGS::boneName(bone) << "in seq" << hseq->m_seq_type_info.m_name;
            }
        }
    }
    hseq->m_bone_textures_1[bone] = bone_tex_1;
    SEGS::HTexture bone_tex_2;
    if (!detail_tex.isEmpty())
    {
        bone_tex_2 = white_tex;
        if (detail_tex.toLower() != "none")
        {
            bone_tex_2 = tryLoadTexture(ctx, detail_tex);
            if (!bone_tex_2 || (bone_tex_2 == white_tex && detail_tex.toLower() != "white"))
            {
                qCritical() << "changeBoneTexture: failed to locate textur" << detail_tex << "for bone"
                            << SEGS::boneName(bone) << "in seq" << hseq->m_seq_type_info.m_name;
            }
        }
    }
    hseq->m_bone_textures_2[bone] = bone_tex_2;
    hseq->m_updated_appearance    = 1;
}
void changePartTexture(Urho3D::Context *ctx, SEGS::HSequencerInstance hseq, Parse_Costume *costume, BodyPart_Data *bp,
                       const QByteArray &texname1, const QByteArray &texname2, bool ends_with_x, bool ends_with_a)
{
    bool       tex2_is_none;
    QByteArray second;
    QByteArray buf;
    int        result = 0;

    if (texname1.isEmpty() || !bp || bp->boneIndices[0] == -1)
        return;
    tex2_is_none = texname1.compare("NONE", Qt::CaseInsensitive) == 0;
    if (tex2_is_none)
    {
        buf    = "none";
        result = 1;
    }
    else
    {
        buf = QByteArray(bp->m_TexName) + "_" + texname1;
    }
    tex2_is_none = texname2.isEmpty() || texname2.compare("NONE", Qt::CaseInsensitive) == 0;
    if (tex2_is_none || ends_with_x)
    {
        second = "none";
    }
    else if (ends_with_a)
    {
        if (buf.toLower().endsWith("01a"))
        {
            second                    = buf;
            second[second.size() - 1] = 'B';
        }
        else
        {
            second = QByteArray(bp->m_TexName) + "_" + texname2;
        }
    }
    else if (!tex2_is_none)
    {
        second = QByteArray(bp->m_TexName) + "_" + texname2;
    }
    else
    {
        second = "none";
    }
    QByteArray name2 = bodytype_prefix_fixup(costume, buf);
    if (tryLoadTexture(ctx, name2 + ".tga"))
    {
        buf = name2;
    }
    QByteArray name3 = bodytype_prefix_fixup(costume, second);
    if (tryLoadTexture(ctx, name3 + ".tga"))
    {
        second = name3;
    }
    for (int i = 0; i < bp->m_BoneCount; ++i)
        changeBoneTexture(ctx, hseq, bp->boneIndices[i], buf, second);
}
void CharViewerApp::onCostumeSelected(const Parse_Costume *n)
{
    qDebug() << "TODO: Convert costume to full set of nodes!";
    QString ent_type = entTypeFileName(n);
    qDebug() << "Selected ent type" << ent_type;
    m_character.m_costume_tpl = n;
    if (!m_currently_shown_node)
    {
        m_currently_shown_node       = m_scene->CreateChild("Avatar");
        LF3CharacterNode *node_wrap  = new LF3CharacterNode;
        node_wrap->m_node            = m_currently_shown_node;
        node_wrap->m_anim_controller = m_currently_shown_node->GetComponent<AnimationController>();
        if (!node_wrap->m_anim_controller)
            node_wrap->m_anim_controller = m_currently_shown_node->CreateComponent<AnimationController>();
        m_character.m_node = node_wrap;
        m_camera_node->LookAt(m_currently_shown_node->GetWorldPosition());
    }
    changeCharacterSequencer(m_character, ent_type);
    // Vector3 nodecenter = m_currently_shown_node->GetWorldPosition();//
    // fromGLM(m_currently_shown_node->m_bbox.center()); Vector3 dir = (m_camera_node->GetWorldPosition() -
    // nodecenter).Normalized(); Vector3 newpos = nodecenter + dir * n->m_bbox.size().length()*1.5f;
    // m_camera_node->SetPosition(newpos);
    Quaternion camrot = m_camera_node->GetRotation();
    pitch_            = camrot.PitchAngle();
    yaw_              = camrot.YawAngle();
    //    m_current_selected_node = n;
    if (0.0f != m_character.m_costume_tpl->m_Scale)
        scaleHero(m_character.m_sequencer, m_character.m_costume_tpl->m_Scale);
    if (0.0f != m_character.m_costume_tpl->m_BoneScale)
        changeBoneScale(m_character.m_sequencer, m_character.m_costume_tpl->m_BoneScale);
    BodyPartsStorage &bodyparts(getGameData().m_body_parts);
    BodyPart_Data *   bodyPart;
    for (uint32_t part_idx = 0; part_idx < m_character.m_costume_tpl->m_NumParts; ++part_idx)
    {
        if (bodyparts.m_parts[part_idx].m_BoneCount <= 0)
            continue;
        const Parse_CostumePart &pcp(m_character.m_costume_tpl->m_CostumeParts[part_idx]);
        if (!pcp.m_Name.isEmpty())
            bodyPart = bodyparts.getBodyPartFromName(pcp.m_Name);
        else
            bodyPart = &bodyparts.m_parts[part_idx];
        changeBodyPartGeometry(m_character.m_sequencer, n, bodyPart, pcp.m_CP_Geometry);
        bool bSingleTexture = pcp.m_Texture1.toLower().endsWith('x');
        bool bDualPass      = pcp.m_Texture1.toLower().endsWith('a');
        qDebug() << "Not changing textures";
        // doChangeTex(m_character.m_sequencer, bodyPart, pcp.m_Texture1, pcp.m_Texture2, bSingleTexture, bDualPass);
        changeBodyPartColorization(m_character.m_sequencer, bodyPart, m_character.m_costume_tpl->m_SkinColor,
                                   pcp.m_Color1, pcp.m_Color2, pcp.m_Texture1);
    }
}

#define MAX_GRAPH_DEPTH 80

int created_node_count = 0;

void CharViewerApp::HandleKeyUp(int key, int scancode, unsigned buttons, int qualifiers)
{
    // Close console (if open) or exit when ESC is pressed
    if (key == KEY_ESCAPE)
    {
        engine_->Exit();
    }
    if (key >= '1' && key <= '8')
    {
        int layernum = key - '1';
        if (layernum >= m_coh_scene->refs.size())
            return;
        auto  ref_to_toggle = m_coh_scene->refs[layernum];
        Node *v             = m_converted_nodes[ref_to_toggle];
        if (v)
            v->SetDeepEnabled(!v->IsEnabled());
    }
}

void CharViewerApp::HandleKeyDown(int key, int /*scancode*/, unsigned /*buttons*/, int /*qualifiers*/, bool /*repeat*/)
{
    // Toggle console with F1
    if (key == KEY_F1)
        GetContext()->GetSubsystemT<Console>()->Toggle();

    // Toggle debug HUD with F2
    else if (key == KEY_F2)
        GetContext()->GetSubsystemT<DebugHud>()->ToggleAll();
    if (key == '9')
    {
        Graphics *graphics = GetContext()->m_Graphics.get();
        Image     screenshot(GetContext());
        graphics->TakeScreenShot(screenshot);
        // Here we save in the Data folder with date and time appended
        screenshot.SavePNG("Data/Screenshot_" +
                           Time::GetTimeStamp().replace(':', '_').replace('.', '_').replace(' ', '_') + ".png");
    }
    else if (key == 'g')
    {
    }
}

bool CharViewerApp::Raycast(float maxDistance)
{
    Vector3   hitPos;
    Drawable *hitDrawable = nullptr;

    UI *       ui  = GetContext()->m_UISystem.get();
    IntVector2 pos = ui->GetCursorPosition();
    // Check the cursor is visible and there is no UI element in front of the cursor
    if (!ui->GetCursor()->IsVisible() || ui->GetElementAt(pos, true))
        return false;

    Graphics *graphics = GetContext()->m_Graphics.get();
    Camera *  camera   = m_camera_node->GetComponent<Camera>();
    Ray cameraRay = camera->GetScreenRay((float)pos.x_ / graphics->GetWidth(), (float)pos.y_ / graphics->GetHeight());
    // Pick only geometry objects, not eg. zones or lights, only get the first (closest) hit
    std::vector<RayQueryResult> results;
    RayOctreeQuery              query(results, cameraRay, RAY_TRIANGLE, maxDistance, DRAWABLE_GEOMETRY);
    m_scene->GetComponent<Octree>()->RaycastSingle(query);
    if (!results.empty())
    {
        RayQueryResult &result = results[0];
        hitPos                 = result.position_;
        hitDrawable            = result.drawable_;
        Variant stored         = result.node_->GetVar("CoHModel");
        Variant stored_node    = result.node_->GetVar("CoHNode");
        if (stored != Variant::EMPTY)
        {
            m_selected_drawable = hitDrawable;
            emit modelSelected((SEGS::SceneNode *)stored_node.GetVoidPtr(), (SEGS::Model *)stored.GetVoidPtr(),
                               hitDrawable);
        }
        return true;
    }
    m_selected_drawable = nullptr;
    emit modelSelected(nullptr, nullptr, nullptr);
    return false;
}

void CharViewerApp::HandleUpdate(float timeStep)
{
    Input *input = GetContext()->m_InputSystem.get();
    qApp->processEvents();
    UI *ui = GetContext()->m_UISystem.get();
    ui->GetCursor()->SetVisible(!input->GetMouseButtonDown(MouseButton::MOUSEB_RIGHT));
    input->SetMouseMode(ui->GetCursor()->IsVisible() ? MM_FREE : MM_RELATIVE); //,MM_RELATIVE
    LF3CharacterNode *c_node = (LF3CharacterNode *)m_character.m_node;

    if (c_node && c_node->m_anim_state)
        c_node->m_anim_state->AddTime(timeStep);
    // Movement speed as world units per second
    const float MOVE_SPEED = 20.0f;
    // Mouse sensitivity as degrees per pixel
    const float MOUSE_SENSITIVITY = 0.1f;
    if (!ui->GetCursor()->IsVisible())
    {
        // Use this frame's mouse motion to adjust camera node yaw and pitch. Clamp the pitch between -90 and 90 degrees
        IntVector2 mouseMove = input->GetMouseMove();
        yaw_ += MOUSE_SENSITIVITY * mouseMove.x_;
        pitch_ += MOUSE_SENSITIVITY * mouseMove.y_;
        pitch_ = Clamp(pitch_, -90.0f, 90.0f);

        // Construct new orientation for the camera scene node from yaw and pitch. Roll is fixed to zero
        m_camera_node->SetRotation(Quaternion(pitch_, yaw_, 0.0f));
    }
    bool shifted = input->GetKeyDown(KEY_LEFT_SHIFT);
    if (shifted)
        timeStep *= 10;
    // Read WASD keys and move the camera scene node to the corresponding direction if they are pressed
    // Use the Translate() function (default local space) to move relative to the node's orientation.
    bool cameraLocationUpdated = false;
    if (input->GetKeyDown(KEY_W))
    {
        m_camera_node->Translate(Vector3::FORWARD * MOVE_SPEED * timeStep * 2);
        cameraLocationUpdated = true;
    }
    if (input->GetKeyDown(KEY_S))
    {
        m_camera_node->Translate(Vector3::BACK * MOVE_SPEED * timeStep * 2);
        cameraLocationUpdated = true;
    }
    if (input->GetKeyDown(KEY_A))
    {
        m_camera_node->Translate(Vector3::LEFT * MOVE_SPEED * timeStep * 2);
        cameraLocationUpdated = true;
    }
    if (input->GetKeyDown(KEY_D))
    {
        m_camera_node->Translate(Vector3::RIGHT * MOVE_SPEED * timeStep * 2);
        cameraLocationUpdated = true;
    }
    if (input->GetKeyDown(KEY_PAGE_UP) || input->GetKeyDown(KEY_Q))
    {
        m_camera_node->Translate(Vector3::UP * MOVE_SPEED * timeStep * 5);
        cameraLocationUpdated = true;
    }
    if (input->GetKeyDown(KEY_PAGE_DOWN) || input->GetKeyDown(KEY_E))
    {
        m_camera_node->Translate(Vector3::DOWN * MOVE_SPEED * timeStep * 5);
        cameraLocationUpdated = true;
    }
    if (cameraLocationUpdated)
    {
        Vector3 pos = m_camera_node->GetPosition();
    }
    if (ui->GetCursor()->IsVisible() && input->GetMouseButtonPress(MouseButton::MOUSEB_LEFT))
        Raycast(8500);
}

void CharViewerApp::HandlePostRenderUpdate(float /*ts*/)
{
    // If draw debug mode is enabled, draw viewport debug geometry. Disable depth test so that we can see the effect of
    // occlusion
    LF3CharacterNode *c_node = (LF3CharacterNode *)m_character.m_node;
    if (c_node && c_node->m_skeleton)
    {
        m_scene->GetComponent<DebugRenderer>()->AddSkeleton(*c_node->m_skeleton, Color::GREEN);
        if (m_character.m_sequencer && m_character.m_sequencer->m_updated_appearance)
        {
            animSetHeader(m_character.m_sequencer);
            m_character.m_sequencer->m_updated_appearance = false;
        }
    }
    if (m_selected_drawable)
    {
        m_selected_drawable->DrawDebugGeometry(m_scene->GetComponent<DebugRenderer>(), true);
    }
    if (!m_current_selected_node)
        return;
    BoundingBox bbox(fromGLM(m_current_selected_node->m_bbox.m_min), fromGLM(m_current_selected_node->m_bbox.m_max));
    m_scene->GetComponent<DebugRenderer>()->AddBoundingBox(bbox, Color::BLUE, false);
}

//! @}

redpajama_set_name: RedPajamaGithub


text:
VCCSOnline Home > Colleges > Virginia Western > Courses > Communication Studies and Theatre (CST)
Communication Studies and Theatre (CST) at Virginia Western Community College
All colleges VWCC Advanced Search >>
CST 100 - Principles of Public Speaking
Applies theory and principles of public address with emphasis on preparation and delivery.
CST 105 - Oral Communication
Studies effective communication with emphasis on speaking and listening.
Lecture 2-3 hours per week.
CST 110 - Introduction to Communication
Examines the elements affecting speech communication at the individual, small group, and public communication levels with emphasis on practice of communication at each level.
CST 111 - Voice and Diction I
Enables students to improve pronunciation, articulation, and voice quality. Includes applied phonetics. Part I of II.
CST 114 - Survey of Mass Media
Examines the history and current understanding of mass communication. Covers print media (newspapers, magazines, and books), electronic media (radio, television, film, the Internet), advertising, public relations, and mass media theory, research, and ethics.
3 Credits. Lecture 3 hours. Total 3 hours.
View CST 114 Course Content Summary
CST 115 - Small Group Communication
Emphasizes the development of presentational ability in a group, decision-making, group maintenance, and leadership and participant skills. Incorporates a preliminary study of group dynamics.
CST 116 - Speech Workshop
Enables work in competitive speech activities such as debate, oratory, impromptu speaking, prose and poetry reading, and rhetorical criticism. May be repeated for credit.
CST 120 - Screenwriting
Focuses on the craft of writing for the screen. Examines film and television screenplay structure. Analyzes dramatic strategies in film and television. Learn and apply correct script form and creatively engage in the various stages of original scriptwriting.This course is cross-listed with PHT 120. Credit will not be awarded for both.
(3 Cr.) Lecture 3 hours. Total 3 hours per week.
CST 126 - Interpersonal Communication
Teaches interpersonal communication skills for both daily living and the world of work. Includes perception, self- concept, self-disclosure, listening and feedback, nonverbal communication, attitudes, assertiveness and other interpersonal skills.
CST 130 - Introduction to the Theatre
Surveys the principles of drama, the development of theatre production, and selected plays to acquaint the student with various types of theatrical presentations.
CST 131 - Acting I
Develops personal resources and explores performance skills through such activities as theatre games, role playing, improvisation, work on basic script units, and performance of scenes. Part I of IV.
Lecture 2 hours. Laboratory 3 hour. Total 5 hours per week.
CST 132 - Acting II
Develops personal resources and explores performance skills through such activities as theatre games, role playing, improvisation, work on basic script units, and performance of scenes. Part II of IV.
CST 136 - Theatre/Musical Workshop
Enables students to work in various activities of a play production or a musical production including performance, orchestra, set design, stage carpentry, sound, costuming, lighting, stage managing, props, promotion, or stage crew. May be repeated for credit. Variable hours per week. This course is cross-listed with MUS 129. Credit will not be awarded for both.
CST 137 - Oral Interpretation
Studies the theory and practice of performing various types of literature: prose, poetry, and drama. Emphasizes the relationship among the oral interpreter, the literary work, and the audience.
CST 141 - Theatre Appreciation I
Aims to increase knowledge and enjoyment of theatre. Considers process, style, organization, written drama, and performed drama. Part I of II.
CST 145 - Stagecraft
Acquaints the student with fundamental methods, materials, and techniques of set construction for the stage.
Lecture 2 hours.Laboratory 2 hour. Total 4 hours per week.
CST 151 - Film Appreciation I
Provides students with a critical understanding of film through the discussion and viewing of motion pictures with emphasis upon the study of film history and the forms and functions of film. Students will develop skills to analyze the shared social, cultural and historical influences of films and their contexts. Part I of II.
CST 152 - Film Appreciation II
Provides students with a critical understanding of film through the discussion and viewing of motion pictures with emphasis upon the study of film history and the forms and functions of film. Students will develop skills to analyze the shared social, cultural and historical influences of films and their contexts. Part II of II.
CST 190 - Coordinated Internship
Supervises on-the-job training in selected business, industrial or service firms coordinated by the college.
CST 195 - Topics In
Provides an opportunity to explore topical areas of interest to or needed by students. May be used also for special honors courses. May be repeated for credit. Variable hours.
CST 199 - Supervised Study
Assigns problems for independent study incorporating previous instruction and supervised by the instructor. May be repeated for credit.
Variable hours.
CST 201 - Introduction to Communication Theory and Research
Introduces the field of communication, emphasizing perspectives on theory and research, topical areas within the discipline, basic research methodologies, and a survey of theories in those areas. Covers basic procedures for theory-building, research, and writing about communication.
CST 210 - Theatre Aesthetics
Introduces the study of theatre aesthetics through exploration into the theatrical theories, styles, dramaturgical structures, and types of dramatic literature, which have influenced playwriting and theatrical practice from the ancient Greek to Modern periods.
CST 227 - Business and Professional Communication
Emphasizes principles and practical application to effective professional oral communication behaviors to include speaking, listening, and relating, and rhetorical sensitivity within professional, business, and organizational contexts.
CST 228 - Writing Across Media
Provides instruction in writing and reporting techniques within various professional media fields, to include public relations, advertising, print, broadcast, and online journalism. Focuses on information gathering, developing appropriate and accurate stories, journalistic storytelling, grammar, Associated Press Style, and knowledge of current affairs.
CST 229 - Intercultural Communication
Emphasizes the influence of culture on the communication process including differences in values, message systems, and communication rules.
CST 231 - History of Theatre I
Analyzes and studies theatre history to include architecture, performers and performance, playwrights, stage, production methods, and audience from the Greeks through modern drama. Part I of II.
CST 232 - History of Theatre II
Analyzes and studies theatre history to include architecture, performers and performance, playwrights, stage, production methods, and audience from the Greeks through modern drama. Part II of II.
CST 233 - Rehearsal and Performance I
Explores various aspects of the theatre through involvement in college theatre production. Part I of II.
CST 234 - Rehearsal and Performance II
Explores various aspects of the theatre through involvement in college theatre production. Part II of II.
CST 241 - Introduction to Directing I
Introduces theory and practice of stage direction through the study of directing methods as well as the execution and discussion of directing exercises. Prerequisite CST 131-132 or SPD 131-132 or divisional approval. Part I of II.
CST 245 - Basic Lighting
Studies basic techniques and methods of lighting design for the stage.
CST 250 - The Art of the Film
Introduces the art of the film through a survey of film history; viewing, discussion, and analysis of selected films. Studies film techniques such as composition, shot sequence, lighting, visual symbolism, sound effects, and editing.
CST 252 - Costume and Make-up for the Theatre
Provides students with a basic understanding of the principle of costuming and make-up for the theatre. Instructs in the fundamentals of costumes such as: function, research techniques, design, materials and construction. Instructs in the fundamentals of make-up such as: basic make-up techniques, supplies, and the design of straight, character, and special effect applications.
CST 267 - Creative Drama
Explores uses of drama through story dramatization, role- playing, and sensory exercises.


Tredegar House and Park at Tredegar House01633 815880work Historic HouseSet in a beautiful 90 acre park, Tredegar House is one of the best examples of a 17th century Charles II mansion in Britain. The earliest surviving part of the building dates back to the early 1500's.
Visitors can discover what life was like for those who lived above and below stairs by touring the impressive state rooms and the intriguing servants' quarters.
It is easy to spend a leisurely day here, with plenty to interest all members of the family.
Set in a beautiful 90 acre park, Tredegar House is one of the best examples of a 17th century Charles II mansion in Britain. The earliest surviving part of the building dates back to the early 1500's.
See website for House opening times.
Park open all year from dawn to dusk.
Local bus services: Service 30 operates via Cardiff Road and then the A48, stopping opposite Cleppa Park. It is a 5 minute walk from there to Tredegar House.


(1) Who chaired the first meeting of the newly-constituted Economic Advisory Council to Prime Minister (EAC-PM)?
(2) Which state government to set up 16 new GIDC townships to encourage SMEs?
(3) Where in Mumbai is the State Bank of India going to built at the largest innovation centre by any financial services company in the country?
(4) Which country is second largest market for pharma according to LinkedIn Report?
(5) Where is the 44th edition of Indian Handicrafts and Gifts (IHGF) being held?
(6) Which State's Chief Minister has announced a financial assistance of Rs 2 lakh for widow remarriage?
(7) Who won the 2017 Bulgarian International Future Series tournament?
(8) Which state Cabinet approves Reservation for 'Divyangs' in Govt Jobs?
(9) Name the Indian bowler who has announced retirement from all forms of cricket and will lay his last T-20 International against New Zealand on 1st November 2017?


text:
Gujarat takes up PPP Projects under PM Awas Yojana
Puneet Kaur
As a part of the recently launched Prime Minister Awas Yojana (Urban), Gujarat has become the first state in the country to take up Public-Private Partnership Projects for redevelopment of slums in urban areas.
30 PPP Projects proposed by Gujarat Government has been approved by the inter-ministerial Central Screening and Monitoring Committee (CSMC) of the Ministry of Housing & Urban Poverty Alleviation (HUPA) for rehabilitation of slum dwellers in Ahmedabad, Surat, Rajkot and Vadodara.
17,580 new dwelling units will be constructed for slum dwellers living on government lands in these four cities of Gujarat by private developers.
Assistance provided for project
Slum dwellers will get new houses with all amenities free of cost.
The Union Government will provide an assistance of about 176 cr @ Rs.1.00 lakh per house to be built.
CSMC sanctioned 1, 69,381 houses for Economically Weaker Sections (EWS) in 145 cities in 8 states for which a total central assistance of Rs.2, 444 cr will be provided.
8 states include – West Bengal, Telangana, Gujarat, Madhya Pradesh, Jharkhand, Tamil Nadu, Odisha and Mizoram.
With this, Ministry of HUPA has so far approved construction of 4,23,415 houses for urban poor in 243 cities in 11 States across the country, for which the Union Government will provide an assistance of Rs.5,900 cr.
About PM Awas Yojana
Under PMAY (Urban), the Union Government provides an assistance of Rs.1.00 lakh per unit for rehabilitation of slum dwellers and Rs.1.50 lakh per unit under Affordable Housing in Partnership and Beneficiary led individual construction for EWS beneficiaries.
It aims to construct about two crore houses by the year 2022.
Under the fourth component of Credit Linked Subsidy of Rs.2.30 lakh per beneficiary will be provided.
Previous article2015 BBC SPOTY conferred on Andy Murray
Next articleHRD Ministry launched AISHE
BJP retains power in Gujarat for the sixth time and also wins in Himachal Pradesh
India signs loan agreement with AIIB for Financing of US$ 329 million for Gujarat Rural Roads Project
41st annual UNESCO World Heritage Committee conference held in Poland


text:
Israel comes up with tempting offer on ELVO
Αντιόπη Σχοινά ENGLISH EDITION
The sales process, which was postponed to July 13, according to Business Daily's sources, is expected to acquire a new August deadline to facilitate the Israeli investors who are forced to go into quarantine when returning from trips abroad in a national policy that runs until the end of July.
The tender for the sale of assets belonging to the Hellenic Vehicle Industry (ELVO) has been pushed back for a fifth time amidst interest from Israel's Plasan that has taken on particular importance due to the recent visit to Israel by Greek Prime Minister Kyriakos Mitsotakis.
The sales process, which was postponed to July 13, according to Business Daily's sources, is expected to acquire a new August deadline to facilitate the Israeli investors who are forced to go into quarantine when returning from trips abroad in a national policy that runs until the end of July. A policy that does not allow officials from Plasan to visit ELVO's facilities.
The importance given by the government and EY, which is acting as special liquidator to the state-owned company, to Israel's Plasan and the step to help facilitate its mission, is justified due to the strength of the Israeli interest and the business plan announced during the government trip.
Plasan's business plan includes an extension to ELVO's construction of modern electronic warfare systems, in investments that could reach up to one billion euros. The new systems would be available in Greece, Israel, or other interested parties based on agreements.
Given that the way the tender is structured takes into account not only the price offered but also the scope and viability of the investment plan, the Israelis now seem to be gaining a clear lead in the process.
As part of the business plan, Plasan Sasa, a vehicle manufacturer, may hook up with other Israeli companies on the ELVO deal that have know-how in electronic systems, such as Elbit Systems or Rafael Advanced Defense Systems.
Seven investors had initially shown informal interest in ELVO, which include, among others, Italy's Ferrovie dello Stato (whose group also includes TRAINOSE), the German Krauss-Maffei Wegmann (Intracom Group KMW), and South Africa's Paramount Group, India's Tata Group and Poland's Solaris. Of course, it remains to be seen who will submit a binding bid as both the German and the Italian participation, as well as that of the Tata Group, provide significant competition to the Israelis.
As part of the tender, real estate, building facilities at the Sindos Industrial Zone, equipment and intellectual and industrial property rights will be sold off. The Greek state is expected to retain the right of acquiring 21 percent of ELVO after three years.
ELVO has been under special management since 2014 with accumulated losses of 170.3 million euros and 85.4 million euros of total liabilities. The company was founded in 1972 as Stagier Hellas to produce and sell trucks, agricultural tractors, and engines.
In 1986, the participation of the Austrians was transferred to the Greek State. In 2000, the Mytileneos group acquired, through an international tender, 43 percent of its shares and management, and pulled out of the company in 2010.
National Insurance sale seen winding up in October
With the EU Competition Commission, through a letter from President Margrethe Vestager to the Insurance Workers' Union, indicating that there will be no further extension given to the sales process, everything shows that the sale to CVC is the most likely option.
Seven new corvettes for the navy from ONEX, Israeli Shipyards
The Themistoklis corvette is a state-of-the-art vessel that aims to meet surveillance needs in the eastern Mediterranean. The design of the corvette combines the know-how of the Greek, Israeli and American industries.
23 Ιουν 2020 12:56
Δελεαστική πρόταση από Ισραήλ για την εξαγορά της ΕΛΒΟ
Η ισραηλινή Plasan φέρεται να έχει πλάνο επέκτασης των δραστηριοτήτων της ΕΛΒΟ στην κατασκευή σύγχρονων ηλεκτρονικών συστημάτων πολέμου με επενδύσεις έως 1 δισ. ευρώ.
Battle erupts over Cosco shipyard
The case for the creation of a shipyard by Cosco in Piraeus is not a simple one despite the Council of State's positive decision. According to market participants, the first obstacle is that a decision is needed from regional authorities who cannot allow this activity, as it is classified as high nuisance and this is not permitted in the Attica region.
Abrupt halt for Greece's Golden Visa program
According to May data, real estate transfers with residence permits reached 7,550, from 7,279 at the end of 2019, showing an increase of 271 residence permits in almost five months, while throughout 2019 3,172 permits were granted. This is a sharp drop in applications for the Golden Visa, showing that the program has come to a standstill.
26 Μάιος 2020 16:12
300 mln euro seaplane project on course despite pandemic
Hellenic Seaplanes remains committed to the goal of flying in Greece in 2020 and is soon expected to make announcements on the delivery of its first aircraft and other technical issues. The company has made significant progress, taking advantage of the online process of submitting the necessary paperwork setting out the technical details of its entire network.
Deadline on Ellaktor share deal expires today
23 Δεκ 2020 06:49
9-month earnings snapshot from Greek blue chips; Winners and Losers
Greece raises 2 bln euros via bond placement with banks
Why Greece is slow on reacting to bad bank proposal
Hotels, food businesses bleed heavily in Q3
OTE seen unfairly favoured in state IT projects; smaller players protest
Bond swaps a win-win situation for Greek govt, banks
Energy players shine on Athens bourse in 2020
Mykonos municipality braces for tough year, looks for virtual boost
Greek banks get 1.2 bln euro capital boost from state bond swaps


text:
Title: Young people's experiences of 'serious' romantic relationships in late adolescence : 'what is this thing called love?'
Author: Forrest, Simon Peter
Awarding Body: Open University
Current Institution: Open University
http://oro.open.ac.uk/59989/
This thesis mounts an in-depth exploration of young, white, Scottish people's views and experiences of falling in love with people of the opposite sex in the context of 'serious' romantic relationships formed in their late adolescence. It is located within the sociology of emotion and engages with debates about how emotional experience is shaped and influenced by social interaction, structures, cultural discourses and resources. The principal questions considered are: What array of social-cultural influences are pertinent to understanding these young people's experiences of love and 'serious' relationships? How and in what ways are these influences perceived to be inflecting or constitutive of these young people's experiences? In what ways do these young people's experiences exceed the account made possible through the sociology of emotion and, what possibilities and opportunities are there for elaborating this account? The study draws principally on data generated through interviews with young people studying for Highers in the sixth year of a secondary school. A grounded approach was used in analysis of these data. Findings include the development of taxonomies of 'serious' relationships which describe their constitutive elements, address the issue of why they are especially pertinent to young people in late adolescence and how this relates to their negotiation of specific social settings, interactions and developmental events. Gender, family and transition emerge as particular salient socio-cultural influences within these young people's accounts of their 'serious' relationships and the nature of each of these is explored in depth. I argue that the theoretical framework provided by the sociology of emotion has good explicative power in terms of identifying the array of social factors which are likely to be influencing emotional experiences but there is scope both for further research and to employ additional theoretical resources, especially psycho-dynamically inflected thinking, in order to explain emotional experience at the level of individual.
10.21954/ou.ro.0000ea55


2011 January 14 « It's For My RP Spec!
I live in a relatively warm (read: 115 degree F summers) area because, well, I don't like the cold/rain/fog/snow in other places. We get snow roughly every five years and it's basically flakes floating peacefully to the ground before turning into puddles. But it's been freezing here this winter and that got me thinking about some of my characters and what they wear in cold climates.
Story-wise, only two of my characters have spent significant amounts of time in Northrend (Tanwen and Etana). While Etana's Northrend attire consists of mostly heavy plate armor, Tanwen definitely dressed more for travel. I know I've talked about Tanwen's Northrend clothing briefly in a previous post, but I am definitely inspired by the need to actually use the scarves I bought more for fashion than function.
Basically, just a mini-update with a couple of my favorite cold-weather cloth outfits.


text:
November 15, 2021 News Releases Photojournalism
In new book, Berkley Hudson presents forgotten photographs of O.N. Pruitt
Portrait made on a 5×7 glass plate negative with two exposures in Pruitt's studio, circa mid-1920s
Master photographer from Mississippi documented Black and white lives during time of segregation and violence
Berkley Hudson, an associate professor emeritus at the Missouri School of Journalism, has authored a new book presenting the photography of O.N Pruitt, a Mississippi photographer who was largely forgotten until Hudson's rediscovery of his work. "O. N. Pruitt's Possum Town: Photographing Trouble and Resilience in the American South" features more than 190 of Pruitt's images and will release on Jan. 18, 2022, while a traveling exhibit showcasing the images will launch on Feb. 4 at the Columbus Arts Council in Columbus, Mississippi.
Pruitt was a studio and freelance photographer from Columbus, active during the height of the Jim Crow era from around 1920 to 1960. A white man, his work is considered notable not only for the artistry of his large-format images, but for photographing both Black and white communities and sometimes juxtaposing the two in ways that were rare, if not unheard of, at the time.
"There are photographs of baptisms of white church groups and black church groups in some measure of biracial harmony," Hudson said. "They were happening at the same time on the same riverbank on Sunday afternoons. It's very unusual to see that pairing; during the same period that the photos were taken, there were lynchings going on."
Hudson's link to Pruitt dates back to his childhood in Columbus (known to locals as "Possum Town"). Pruitt took family photos for the Hudsons, some of which still hang on the walls of Hudson's home. But beyond that straightforward connection, Hudson remembers growing up in Columbus at a time when his father's gas station had three bathrooms: Ladies, Gentleman, and Colored. One of his older brothers attended the University of Mississippi during the deadly Ole Miss riot of 1962, in which opponents of integration initiated mob violence in response to James Meredith becoming the first Black student to enroll at the university — Hudson's brother even shared a class with Meredith. The struggle to understand the climate of hatred, violence, and racial segregation in Mississippi would lead Hudson to journalism and, eventually, back to Pruitt.
"Columbus, Mississippi was the eye of the hurricane of the Civil Rights Movement, including violence," Hudson said. "I saw a lot of spirit murder of people — Black and white people. My Sunday school teachers couldn't help me make sense of it and my family couldn't, either, but writers and journalists did."
His burgeoning interest in journalism also led him toward photography, which in turn led to the discovery in the 1970s of "boxes and boxes and boxes" of Pruitt's negatives. Pruitt had died in 1967, and the negatives — which Hudson recalls were "smelling to high heaven" with the vinegar-like stench of off-gassing — were languishing in storage under the ownership of Calvin Shanks, Pruitt's former business partner. It took Hudson and four friends from his Columbus boyhood 13 years to acquire the negatives, and only then did he realize the extent of the collection's value.
"These photographs open up a doorway into this whole time period of the early and mid-20th century, not only in terms of photography, but also music, arts and literature."
"In his studio photographs, there is a sense of equality before the lens," Hudson said. "There are stunning images of ordinary Black people sitting in the same chair as ordinary white folks, as well as the richest white folks in town, and farmers and kids. But then out in the public space, you see the impact of Jim Crow racial segregation made manifest in the images. We found images that really complexified the nature of what we knew about our town and what we knew about the American South."
Those images included depictions of two of the last executions by rope hanging on the Columbus courthouse grounds, as well as the lynching of two Black farmers in 1935. He also captured an image of Sylvester Harris, a Black farmer who became a media sensation in 1934 after managing to get President Roosevelt on the phone and convincing him to grant relief for the mortgage on his property. Pruitt's photo was featured in publications all over the country.
Hudson also discovered an astonishing variety of photos of daily life, leading him to consider Pruitt "the de facto documentarian of Lowndes County, Mississippi" and its county seat, Columbus. From family picnics, parades, carnivals, and river baptisms to fires, funerals, executions, and a lynching, Pruitt's body of work is an artful but sobering record of a town in Mississippi that Hudson believes is representative of life in the South at the time.
Hudson acknowledges that while Pruitt's ability to move easily through both Black and white worlds is part of what makes that record compelling, it's also a sign of the same inequalities that Pruitt often captured in his images.
"He could do that because he was white," Hudson said. "Black photographers could not have moved in the white world the way that he moved through Black communities."
This and other complexities found in Pruitt's work have fascinated Hudson for decades, culminating in the new book, which also features short essays and captions in which Hudson reflects upon the themes in the images. The book is already attracting attention from photography experts.
"Hudson reveals the story of a complicated southern town and creates an insightful vision of the south moving from disenfranchisement to empowerment," said Deborah Willis, a former MacArthur Fellow, 2001 Missouri Honor Medalist, and author of "The Black Civil War Soldier: A Visual History of Conflict and Citizenship."
The book will be published by the University of North Carolina Press in partnership with Duke University's Center for Documentary Studies, while the accompanying exhibit is sponsored by the National Endowment for the Humanities.
In addition, a curriculum guide for middle and high school is in the works that incorporates period music and other artistic elements into Pruitt's images and the stories they tell. The guide is co-authored by LaGarret King, an associate professor in the MU College of Education and Human Development, and Chuck Yarborough, a Mississippi history teacher honored by the Organization of American Historians in 2019 as Teacher of the Year. King is among six Mizzou professors serving as NEH scholars on the Pruitt project.
"These photographs open up a doorway into this whole time period of the early and mid-20th century, not only in terms of photography, but also music, arts and literature," Hudson said. "They encourage us to meditate on the interrelations between photography, community, race, and historical memory."
Feb 27, 2019 12 Journalism Students Selected for Mizzou '39 Honors
Jul 22, 2016 Alumni Spotlight: Lauren Steele
Jul 08, 2016 Berkley Hudson Connects with His Former Students
May 18, 2015 11 Students, 3 Professors Tapped into Secret Honorary Societies
May 01, 2015 3 Journalism Undergraduates Present Research and Creative Projects
Aug 08, 2014 Missouri Journalism Students, Faculty, Staff Earn More than 500 Awards and Honors in 2013-14 Academic Year
Jul 23, 2014 18 Freshman Interest Groups to Focus on Journalism for Fall 2014
Dec 04, 2013 'Politics of the Black Body' Series Explores Questions About Media and Visual Representation
Aug 14, 2013 A Record Breaker: Missouri School of Journalism Faculty, Students and Alumni Present 114 Papers at International Conference; 11 Earn Top Paper Awards