//---------------------------------------------------------------------------- void Actor::SetScene (Scene *scene) { if (mScene == scene) return; if (scene) { Node *sceneNode = scene->GetSceneNode(); if (sceneNode) { double appTime = GetTimeInSeconds(); if (mMovable) { sceneNode->AttachChild(mMovable); //mMovable->Update(appTime); } if (mHelpMovable) { sceneNode->AttachChild(mHelpMovable); //mHelpMovable->Update(appTime); } } } else { if (mScene) { Node *sceneNode = mScene->GetSceneNode(); if (sceneNode) { if (mMovable) { sceneNode->DetachChild(mMovable); } if (mHelpMovable) { sceneNode->DetachChild(mHelpMovable); } } } } mScene = scene; }
//---------------------------------------------------------------------------- Node* Game::LoadAndInitializeScene() { Importer importer("Data/Scene/"); Node* pScene = importer.LoadSceneFromXml("Scene.xml", mspPhysicsWorld); if (!pScene) { return NULL; } NodeCamera* pCameraNode = pScene->FindChild<NodeCamera>(); WIRE_ASSERT(pCameraNode /* No Camera in scene.xml */); mspSceneCamera = pCameraNode->Get(); mSortingCuller.SetCamera(mspSceneCamera); // The maximum number of objects that are going to be culled is the // number of objects we imported. If we don't set the size of the set now, // the culler will dynamically increase it during runtime. This is not // a big deal, however it is better to avoid memory allocations during the // render loop. UInt renderObjectCount = importer.GetStatistics()->RenderObjectCount; mSortingCuller.SetMaxQuantity(renderObjectCount); // Create and configure probe robot controller SpatialPtr spRedHealthBar = mspGUI->FindChild("RedHealthBar"); WIRE_ASSERT(spRedHealthBar /* No RedHealthBar in GUI.xml */); Node* pProbeRobotSpatial = DynamicCast<Node>(pScene->FindChild("Probe Robot")); WIRE_ASSERT(pProbeRobotSpatial /* No Probe Robot in Scene.xml */); // Detach red energy/health bar and attach it robot probe as a billboard NodeBillboard* pBillboard = WIRE_NEW NodeBillboard; pProbeRobotSpatial->AttachChild(pBillboard); Node* pParent = DynamicCast<Node>(spRedHealthBar->GetParent()); WIRE_ASSERT(pParent); pParent->DetachChild(spRedHealthBar); pBillboard->AttachChild(spRedHealthBar); Spatial* pPlayerSpatial = pScene->FindChild("Player"); WIRE_ASSERT(pPlayerSpatial /* No Player in Scene.xml */); mspProbeRobot = WIRE_NEW ProbeRobot(mspPhysicsWorld, pPlayerSpatial, spRedHealthBar); pProbeRobotSpatial->AttachController(mspProbeRobot); // Create and configure player controller mspPlayer = WIRE_NEW Player(mspSceneCamera, mspPhysicsWorld); pPlayerSpatial->AttachController(mspPlayer); Spatial* pPlatform = pScene->FindChild("Platform"); WIRE_ASSERT(pPlatform /* Platform object missing in scene */); pPlatform->AttachController(WIRE_NEW Elevator(mspPhysicsWorld)); pScene->Bind(GetRenderer()); pScene->WarmUpRendering(GetRenderer()); return pScene; }
//---------------------------------------------------------------------------- PX2::Node *GeoObjFactory::CreateUICrossCtrl() { Node *node = new0 Node(); VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC); VertexBufferPtr vb = new0 VertexBuffer(4, vf->GetStride()); PolysegmentPtr seg = new0 Polysegment(vf, vb, false); seg->SetNumSegments(2); VertexBufferAccessor vba(vf, vb); vba.Position<Float3>(0) = Float3(-5000.0f, 0.0f, 0.0f); vba.Position<Float3>(1) = Float3(5000.0f, 0.0f, 0.0f); vba.Position<Float3>(2) = Float3(0.0f, 0.0f, -5000.0f); vba.Position<Float3>(3) = Float3(0.0f, 0.0f, 5000.0f); vba.Color<Float4>(0, 0) = Float4::BLACK; vba.Color<Float4>(0, 1) = Float4::BLACK; vba.Color<Float4>(0, 2) = Float4::BLACK; vba.Color<Float4>(0, 3) = Float4::BLACK; seg->UpdateModelSpace(Renderable::GU_MODEL_BOUND_ONLY); seg->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); node->AttachChild(seg); float centerSize = 24.0f; float centerSize1 = 48.0f; VertexBufferPtr vbCenter = new0 VertexBuffer(4, vf->GetStride()); PolysegmentPtr segCenter = new0 Polysegment(vf, vbCenter, false); segCenter->SetNumSegments(2); VertexBufferAccessor vbaCenter(vf, vbCenter); vbaCenter.Position<Float3>(0) = Float3(0.0, 0.0f, centerSize); vbaCenter.Position<Float3>(1) = Float3(centerSize, 0.0f, 0.0f); vbaCenter.Position<Float3>(2) = Float3(0.0f, 0.0f, centerSize1); vbaCenter.Position<Float3>(3) = Float3(centerSize1, 0.0f, 0.0f); vbaCenter.Color<Float4>(0, 0) = Float4::BLACK; vbaCenter.Color<Float4>(0, 1) = Float4::BLACK; vbaCenter.Color<Float4>(0, 2) = Float4::BLACK; vbaCenter.Color<Float4>(0, 3) = Float4::BLACK; segCenter->UpdateModelSpace(Renderable::GU_MODEL_BOUND_ONLY); segCenter->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); node->AttachChild(segCenter); return node; }
//---------------------------------------------------------------------------- LightActor::LightActor () : mLightType(LT_POINT), mRange(2.0f), mColor(Float3::MakeColor(128, 128, 128)) { mLight = new0 Light(Light::LT_POINT); LightNode *lightNode = new0 LightNode(mLight); SetMovable(lightNode); VertexFormat *vf = VertexFormat::Create(3, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); Node *helpNode = new0 Node (); PX2::VertexColor4MaterialPtr mtl = new0 VertexColor4Material(); mtl->GetWireProperty(0, 0)->Enabled = true; mtl->GetCullProperty(0, 0)->Enabled = false; MaterialInstancePtr mtlInst = mtl->CreateInstance(); StandardMesh stdMesh(vf); stdMesh.SetVertexColor(Float4(0.0f,1.0f,0.0f,1.0f)); TriMesh *mesh = stdMesh.Octahedron(); mesh->LocalTransform.SetUniformScale(0.5f); mesh->SetMaterialInstance(mtlInst); helpNode->AttachChild(mesh); TriMesh *box = stdMesh.Box(0.005f, 0.005f, 5.0f); box->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, -5.5f)); box->SetMaterialInstance(mtlInst); helpNode->AttachChild(box); SetHelpMovable(helpNode); ShowHelpMovable(true); SetColor(mColor); }
//---------------------------------------------------------------------------- PX2::Node *GeoObjFactory::CreateUIRectCtrl(float smallRectSize) { Node *node = new0 Node(); VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC); VertexBufferPtr vb = new0 VertexBuffer(5, vf->GetStride()); PolysegmentPtr sg = new0 Polysegment(vf, vb, true); sg->SetNumSegments(4); sg->UpdateModelSpace(Renderable::GU_MODEL_BOUND_ONLY); sg->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); node->AttachChild(sg); for (int i = 0; i < 8; i++) { VertexBufferPtr smallRectVB = new0 VertexBuffer(5, vf->GetStride()); PolysegmentPtr smallRect = new0 Polysegment(vf, smallRectVB, true); smallRect->SetNumSegments(4); VertexBufferAccessor vba(vf, smallRectVB); vba.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.0f); vba.Position<Float3>(1) = Float3(smallRectSize, 0.0f, 0.0f); vba.Position<Float3>(2) = Float3(smallRectSize, 0.0f, smallRectSize); vba.Position<Float3>(3) = Float3(0.0f, 0.0f, smallRectSize); vba.Position<Float3>(4) = Float3(0.0f, 0.0f, 0.0f); vba.Color<Float4>(0, 0) = Float4::BLACK; vba.Color<Float4>(0, 1) = Float4::BLACK; vba.Color<Float4>(0, 2) = Float4::BLACK; vba.Color<Float4>(0, 3) = Float4::BLACK; vba.Color<Float4>(0, 4) = Float4::BLACK; smallRect->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); smallRect->UpdateModelSpace(Renderable::GU_MODEL_BOUND_ONLY); node->AttachChild(smallRect); } return node; }
//---------------------------------------------------------------------------- void Player::OnAttach() { mpNode = DynamicCast<Node>(GetSceneObject()); WIRE_ASSERT(mpNode); // Init gun mpGun = DynamicCast<Node>(mpNode->FindChild("Gun")); WIRE_ASSERT(mpGun); Node* pMuzzleFlash = DynamicCast<Node>(mpGun->FindChild("muzzleFlash")); WIRE_ASSERT(pMuzzleFlash); mspMuzzleflashMaterialState = pMuzzleFlash->GetState<StateMaterial>(); WIRE_ASSERT(mspMuzzleflashMaterialState); NodeLight* pLightNode = mpNode->FindChild<NodeLight>(); WIRE_ASSERT(pLightNode); mspMuzzleflashLight = pLightNode->Get(); mMuzzleflashLightColor = mspMuzzleflashLight->Color; // since render state cannot be extracted from Unity materials, we have // to set the appropriate states manually for the muzzle flash StateCull* pCullState = WIRE_NEW StateCull; pCullState->CullFace = StateCull::CM_OFF; pMuzzleFlash->AttachState(pCullState); StateAlpha* pAlphaState = WIRE_NEW StateAlpha; pAlphaState->BlendEnabled = true; pAlphaState->SrcBlend = StateAlpha::SBM_SRC_ALPHA; pAlphaState->DstBlend = StateAlpha::DBM_ONE; pMuzzleFlash->AttachState(pAlphaState); StateZBuffer* pZBufferState = WIRE_NEW StateZBuffer; pZBufferState->Writable = false; pMuzzleFlash->AttachState(pZBufferState); pMuzzleFlash->UpdateRS(); WIRE_ASSERT(pMuzzleFlash->GetRenderObject()); pMuzzleFlash->GetRenderObject()->GetLights()->RemoveAll(); Light* pLight = WIRE_NEW Light(Light::LT_POINT); pLight->Ambient = ColorRGB::WHITE; pMuzzleFlash->GetRenderObject()->GetLights()->Append(pLight); pMuzzleFlash->AttachChild(WIRE_NEW NodeLight(pLight)); pMuzzleFlash->GetRenderObject()->GetMaterial()->SetBlendMode(Material::BM_MODULATE); mspCharacter = mpNode->GetController<CharacterController>(); WIRE_ASSERT(mspCharacter); // Add a reference to Player in the physics object mspCharacter->Get()->setUserPointer(this); }
//---------------------------------------------------------------------------- Node* ExtremalQuery::CreateVisualConvexPolyhedron () { const Vector3f* vertices = mConvexPolyhedron->GetVertices(); int numTriangles = mConvexPolyhedron->GetNumTriangles(); int numIndices = 3*numTriangles; const int* polyIndices = mConvexPolyhedron->GetIndices(); // Visualize the convex polyhedron as a collection of face-colored // triangles. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); int vstride = vformat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(numIndices, vstride); VertexBufferAccessor vba(vformat, vbuffer); IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int)); int* indices = (int*)ibuffer->GetData(); int i; for (i = 0; i < numIndices; ++i) { vba.Position<Vector3f>(i) = vertices[polyIndices[i]]; indices[i] = i; } TriMesh* mesh = new0 TriMesh(vformat, vbuffer, ibuffer); // Use randomly generated vertex colors. for (i = 0; i < numTriangles; ++i) { Float3 color; for (int j = 0; j < 3; ++j) { color[j] = Mathf::UnitRandom(); } vba.Color<Float3>(0, 3*i ) = color; vba.Color<Float3>(0, 3*i+1) = color; vba.Color<Float3>(0, 3*i+2) = color; } mesh->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); Node* root = new0 Node(); root->AttachChild(mesh); return root; }
//---------------------------------------------------------------------------- LightActor::LightActor() { SetName("LightActor"); mLight = new0 Light(Light::LT_POINT); mLightNode = new0 LightNode(mLight); SetMovable(mLightNode); Node *helpNode = new0 Node(); VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC); PX2::VertexColor4MaterialPtr mtl = new0 VertexColor4Material(); mtl->GetWireProperty(0, 0)->Enabled = true; mtl->GetCullProperty(0, 0)->Enabled = false; MaterialInstancePtr mtlInst = mtl->CreateInstance(); StandardMesh stdMesh(vf); stdMesh.SetVertexColor(Float4(1.0f, 1.0f, 0.0f, 1.0f)); TriMesh *mesh = stdMesh.Octahedron(); mesh->LocalTransform.SetUniformScale(0.5f); mesh->SetMaterialInstance(mtlInst); helpNode->AttachChild(mesh); TriMesh *box = stdMesh.Box(0.005f, 0.005f, 5.0f); box->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, -5.5f)); box->SetMaterialInstance(mtlInst); helpNode->AttachChild(box); CreateGetHelpNode()->AttachChild(helpNode); CreateGetHelpNode()->SetParentTransformIngore(false, false, true); WorldBoundIsCurrent = true; SetRadius(1.0f); }
//---------------------------------------------------------------------------- void ModelController::SetMovable(Movable *mov) { Node *node = DynamicCast<Node>(GetControlledable()); if (mMovable && node) node->DetachChild(mMovable); mMovable = mov; if (mMovable && node) node->AttachChild(mMovable); CollectAnchors(); mov->SetSaveWriteIngore(false); }
//---------------------------------------------------------------------------- void EffectBuf::OnAdded () { Buf::OnAdded(); if (mEffectFilename.empty()) return; Node *nodeAttach =0; if (!mAnchor.empty()) nodeAttach = mCharacter->GetAnchor(mAnchor); if (!nodeAttach) { nodeAttach = DynamicCast<Node>(mCharacter->GetMovable()); } if (nodeAttach) { Object *obj = PX2_RM.BlockLoadShareCopy(mEffectFilename, false, false, true); if (obj) { EffectNode *en = DynamicCast<EffectNode>(obj); if (en) { mEffect = en; mEffect->SetSelfCtrled(true); nodeAttach->AttachChild(mEffect); mEffect->ResetPlay(); } else { mEffect = 0; } } else { mEffect = 0; } } }
//---------------------------------------------------------------------------- SampleChara::SampleChara() { Node *helpNode = GetNodeHelp(); if (helpNode) helpNode->Show(false); SetAnimType(AT_FRAMES); Node *rootNode = new0 Node(); AttachChild(rootNode); rootNode->SetName("RootNode"); Node *animNode = new0 Node(); rootNode->AttachChild(animNode); animNode->SetName("AnimNode"); AnimationFrames *anim = new0 AnimationFrames(); anim->SetFilename("Data/Sample/images/wbdz/wbdz_Move/wbdz_Move.xml"); AddAnim(anim); //SetHeading(AVector::UNIT_X); PlayAnim(anim); }
//---------------------------------------------------------------------------- Bool Sample5::OnInitialize() { if (!Parent::OnInitialize()) { return false; } // We are building the following scenegraph: // +Root // +->LitGroup (with StateMaterial, Light1, Light2 attached) // | +->Cube1 (textured cube) // | +->Cube2 (flat shaded cube) // | // +->LightNode1 (owning Light1) // | +->LightSrc1 (cube representing Light1) // | // +->LightNode2 (owning Light2) // +->LightSrc2 (cube representing Light2) mspRoot = WIRE_NEW Node; Node* pLitGroup = WIRE_NEW Node; mspRoot->AttachChild(pLitGroup); // create a green and a red point light and a material state // which defines how to reflect the lights. Light* pLight1 = WIRE_NEW Light(Light::LT_POINT); pLight1->Color = ColorRGB::GREEN; Light* pLight2 = WIRE_NEW Light(Light::LT_POINT); pLight2->Color = ColorRGB::RED; pLight2->Ambient = ColorRGB(0.1F, 0.1F, 0.1F); StateMaterial* pMaterial = WIRE_NEW StateMaterial; pMaterial->Ambient = ColorRGBA(1, 1, 0, 1); // attach lights and material state pLitGroup->AttachState(pMaterial); pLitGroup->AttachLight(pLight1); pLitGroup->AttachLight(pLight2); // create and position the actual objects to be lit Spatial* pCube1 = CreateCube(); Spatial* pCube2 = CreateCube(false, true); pCube1->Local.SetTranslate(Vector3F(-2.0F, 0, 0)); pCube2->Local.SetTranslate(Vector3F(2.5F, 0, 0)); pLitGroup->AttachChild(pCube1); pLitGroup->AttachChild(pCube2); // create light nodes. These act the same as normal nodes, except that // they own a light and apply scene graph transformations on that light. NodeLight* pLightNode1 = WIRE_NEW NodeLight; mspRoot->AttachChild(pLightNode1); pLightNode1->Set(pLight1); NodeLight* pLightNode2 = WIRE_NEW NodeLight; mspRoot->AttachChild(pLightNode2); pLightNode2->Set(pLight2); // create two cubes representing the position and color of the lights Spatial* pLightSrc1 = CreateCube(false, false, true, ColorRGBA::GREEN); pLightSrc1->Local.SetUniformScale(0.15F); pLightNode1->AttachChild(pLightSrc1); Spatial* pLightSrc2 = CreateCube(false, false, true, ColorRGBA::RED); pLightSrc2->Local.SetUniformScale(0.15F); pLightNode2->AttachChild(pLightSrc2); // update all render state and light objects in the scene graph // (i.e. Light1, Light2 and StateMaterial are propagated from LitGroup // to Cube1 and Cube2) mspRoot->UpdateRS(); // create the bottom plane, which already has a white light attached, // to be rendered manually in the render loop. This is only for the // purpose of demonstrating scene graph and manual rendering with lights. mspPlane = CreatePlane(); NodePtr spWhiteCubeNode = CreateCube(false, false, true, ColorRGBA::WHITE); mspWhiteCube = spWhiteCubeNode->GetRenderObject(); // Setup the position and orientation of the camera to look down // the -z axis with y up. Vector3F cameraLocation(0.0F, -1.0F, 10.0F); Vector3F viewDirection(0.0F, 0.0F, -1.0F); Vector3F up(0.0F, 1.0F, 0.0F); Vector3F right = viewDirection.Cross(up); mspCamera = WIRE_NEW Camera; mspCamera->SetFrame(cameraLocation, viewDirection, up, right); // By providing a field of view (FOV) in degrees, aspect ratio, // near and far plane, we define a viewing frustum used for culling. mspCamera->SetFrustum(45, GetWidthF() / GetHeightF() , 0.1F, 300.0F); mCuller.SetCamera(mspCamera); // Initialize working variables used in the render loop (i.e. OnIdle()). mAngle = 0.0F; mLastTime = System::GetTime(); return true; }
//---------------------------------------------------------------------------- bool InverseKinematics::OnInitialize () { if ( !Application::OnInitialize() ) return false; // set up camera ms_spkCamera->SetFrustum(1.0f,1000.0f,-0.55f,0.55f,0.4125f,-0.4125f); Vector3f kCamLoc(0.0f,-2.0f,0.5f); Matrix3f kCamOrient(-1.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,1.0f,0.0f); ms_spkCamera->SetFrame(kCamLoc,kCamOrient); // ** layout of scene graph ** // scene // line // iknode // plane // target // goal // root // origin // effector // end // create objects m_spkScene = new Node(2); Node* pkIKNode = new Node(3); m_spkRoot = new Node(2); m_spkEffector = new Node(1); m_spkTarget = new Node; m_spkLine = CreateLine(); TriMesh* pkPlane = CreatePlane(); TriMesh* pkGoal = CreateCube(); TriMesh* pkOrigin = CreateCube(); TriMesh* pkEnd = CreateCube(); // transform objects pkIKNode->Rotate().FromAxisAngle(Vector3f::UNIT_Y,0.1f); pkIKNode->Translate() = Vector3f(0.1f,0.1f,0.1f); m_spkTarget->Translate() = 2.0f*Vector3f::UNIT_Y; m_spkEffector->Translate() = Vector3f::UNIT_X; // set parent-child links m_spkScene->AttachChild(m_spkLine); m_spkScene->AttachChild(pkIKNode); pkIKNode->AttachChild(pkPlane); pkIKNode->AttachChild(m_spkTarget); pkIKNode->AttachChild(m_spkRoot); m_spkTarget->AttachChild(pkGoal); m_spkRoot->AttachChild(pkOrigin); m_spkRoot->AttachChild(m_spkEffector); m_spkEffector->AttachChild(pkEnd); // create joints IKJoint** apkJoint = new IKJoint*[2]; apkJoint[0] = new IKJoint(m_spkRoot); apkJoint[0]->AllowRotation(2) = true; apkJoint[1] = new IKJoint(m_spkEffector); apkJoint[1]->AllowTranslation(2) = true; // create goal IKGoal** apkGoal = new IKGoal*[1]; apkGoal[0] = new IKGoal(m_spkTarget,m_spkEffector,1.0f); // create IK controller m_pkIKCtrl = new IKController(2,apkJoint,1,apkGoal,1); m_pkIKCtrl->Active() = false; m_spkRoot->AttachControl(m_pkIKCtrl); // set desired render state m_spkWireframeState = new WireframeState; m_spkScene->SetRenderState(m_spkWireframeState); m_spkZBufferState = new ZBufferState; m_spkZBufferState->Enabled() = true; m_spkZBufferState->Writeable() = true; m_spkZBufferState->Compare() = ZBufferState::CF_LEQUAL; m_spkScene->SetRenderState(m_spkZBufferState); // initial update of objects ms_spkCamera->Update(); m_spkScene->UpdateGS(0.0f); m_spkScene->UpdateRS(); UpdateLine(); m_bTurretActive = true; SetTurretAxes(); m_fTrnSpeed = 0.1f; m_fRotSpeed = 0.01f; return true; }
//---------------------------------------------------------------------------- void BouncingSpheres::CreateScene () { CreateBalls(); CreateFloor(); CreateBackWall(); CreateSideWall1(); CreateSideWall2(); // ** layout of scene graph ** // scene // room // backwall // floor // sidewall1 // sidewall2 // balls mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); Node* room = new0 Node(); room->AttachChild(mFloor); room->AttachChild(mSideWall1); room->AttachChild(mSideWall2); room->AttachChild(mBackWall); mScene->AttachChild(room); Node* ballRoot = new0 Node(); int i; for (i = 0; i < NUM_BALLS; ++i) { ballRoot->AttachChild(mBallNodes[i]); } mScene->AttachChild(ballRoot); // The balls are constrained to bounce around in a rectangular solid // region. The six defining planes are defined to be immovable rigid // bodies. The boundaries are parallel to coordinate axes and pass // through the points indicated by the value other than +-100. That is, // the back wall is at x = 1, the left wall is at y = 2, the floor is at // z = 1, the right wall is at y = 15, the ceiling is at z = 17, and the // front wall is at x = 9. The ceiling and front wall are invisible // objects (not rendered), but you will see balls bouncing against it // and reflecting away from it towards the back wall. mBoundaryLocations[0] = Vector3f(1.0f, -100.0f, -100.0f); mBoundaryNormals[0] = Vector3f(1.0f, 0.0f, 0.0f); mBoundaryLocations[1] = Vector3f(-100.0f, 2.0f, -100.0f); mBoundaryNormals[1] = Vector3f(0.0f, 1.0f, 0.0f); mBoundaryLocations[2] = Vector3f(-100.0f, -100.0f, 1.0f); mBoundaryNormals[2] = Vector3f(0.0f, 0.0f, 1.0f); mBoundaryLocations[3] = Vector3f(100.0f, 15.0f, 100.0f); mBoundaryNormals[3] = Vector3f(0.0f, -1.0f, 0.0f); mBoundaryLocations[4] = Vector3f(100.0f, 100.0f, 17.0f); mBoundaryNormals[4] = Vector3f(0.0f, 0.0f, -1.0f); mBoundaryLocations[5] = Vector3f(8.0f, 100.0f, 100.0f); mBoundaryNormals[5] = Vector3f(-1.0f, 0.0f, 0.0f); for (i = 0; i < 6; ++i) { mBoundaries[i].SetMass(0.0f); mBoundaries[i].SetPosition(mBoundaryLocations[i]); } }
//---------------------------------------------------------------------------- void CubeMaps::CreateScene () { // Create the root of the scene. mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); // Create the walls of the cube room. Each of the six texture images is // RGBA 64-by-64. Node* room = new0 Node(); mScene->AttachChild(room); // Index buffer shared by the room walls. IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int)); int* indices = (int*)ibuffer->GetData(); indices[0] = 0; indices[1] = 1; indices[2] = 3; indices[3] = 0; indices[4] = 3; indices[5] = 2; // The vertex format shared by the room walls. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); int vstride = vformat->GetStride(); VertexBufferAccessor vba; // The texture effect shared by the room walls. Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR); VertexBuffer* vbuffer; TriMesh* wall; std::string textureName; // +x wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, -1.0f); vba.Position<Float3>(1) = Float3(+1.0f, -1.0f, +1.0f); vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, -1.0f); vba.Position<Float3>(3) = Float3(+1.0f, +1.0f, +1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("XpFace.wmtf"); Texture2D* xpTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(xpTexture)); // -x wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, +1.0f); vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, -1.0f); vba.Position<Float3>(2) = Float3(-1.0f, +1.0f, +1.0f); vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, -1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("XmFace.wmtf"); Texture2D* xmTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(xmTexture)); // +y wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(+1.0f, +1.0f, +1.0f); vba.Position<Float3>(1) = Float3(-1.0f, +1.0f, +1.0f); vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, -1.0f); vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, -1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("YpFace.wmtf"); Texture2D* ypTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(ypTexture)); // -y wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, -1.0f); vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, -1.0f); vba.Position<Float3>(2) = Float3(+1.0f, -1.0f, +1.0f); vba.Position<Float3>(3) = Float3(-1.0f, -1.0f, +1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("YmFace.wmtf"); Texture2D* ymTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(ymTexture)); // +z wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, +1.0f); vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, +1.0f); vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, +1.0f); vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, +1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("ZpFace.wmtf"); Texture2D* zpTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(zpTexture)); // -z wall vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, -1.0f); vba.Position<Float3>(1) = Float3(+1.0f, -1.0f, -1.0f); vba.Position<Float3>(2) = Float3(-1.0f, +1.0f, -1.0f); vba.Position<Float3>(3) = Float3(+1.0f, +1.0f, -1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f); wall = new0 TriMesh(vformat, vbuffer, ibuffer); room->AttachChild(wall); textureName = Environment::GetPathR("ZmFace.wmtf"); Texture2D* zmTexture = Texture2D::LoadWMTF(textureName); wall->SetEffectInstance(effect->CreateInstance(zmTexture)); // A sphere to reflect the environment via a cube map. The colors will // be used to modulate the cube map texture. vformat = VertexFormat::Create(3, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); vstride = vformat->GetStride(); mSphere = StandardMesh(vformat).Sphere(64, 64, 0.125f); room->AttachChild(mSphere); // Generate random vertex colors for the sphere. The StandardMesh class // produces a sphere with duplicated vertices along a longitude line. // This allows texture coordinates to be assigned in a manner that treats // the sphere as if it were a rectangle mesh. For vertex colors, we want // the duplicated vertices to have the same color, so a hash table is used // to look up vertex colors for the duplicates. vba.ApplyTo(mSphere); std::map<Float3,Float3> dataMap; for (int i = 0; i < vba.GetNumVertices(); ++i) { Float3& position = vba.Position<Float3>(i); Float3& color = vba.Color<Float3>(0, i); std::map<Float3,Float3>::iterator iter = dataMap.find(position); if (iter != dataMap.end()) { color = iter->second; } else { color[0] = 0.0f; color[1] = Mathf::IntervalRandom(0.5f, 0.75f); color[2] = Mathf::IntervalRandom(0.75f, 1.0f); dataMap.insert(std::make_pair(position, color)); } } // Create the cube map and attach it to the sphere. std::string effectFile = Environment::GetPathR("CubeMap.wmfx"); CubeMapEffect* cubeMapEffect = new0 CubeMapEffect(effectFile); ShaderFloat* reflectivity = new0 ShaderFloat(1); (*reflectivity)[0] = 0.5f; std::string cubeName = Environment::GetPathR("CubeMap.wmtf"); TextureCube* cubeTexture = TextureCube::LoadWMTF(cubeName); cubeTexture->GenerateMipmaps(); mCubeMapInstance = cubeMapEffect->CreateInstance(cubeTexture, reflectivity, false); mSphere->SetEffectInstance(mCubeMapInstance); // Allow culling to be disabled on the sphere so when you move inside // the sphere, you can see the previously hidden facets and verify that // the cube image for those facets is correctly oriented. mSphereCullState = cubeMapEffect->GetCullState(0, 0); }
//---------------------------------------------------------------------------- void SkillStepLink::OnEnter (SkillInstance *instance) { SkillStep::OnEnter(instance); Skill *skill = instance->GetSkill(); Character *character = skill->GetCharacter(); Scene *scene = character->GetScene(); Node *sceneNode = DynamicCast<Node>(scene->GetSceneNode()); APoint charPos = character->GetPosition(); int aimTarget = instance->GetAimTarget(); Character *aimTargetChar = DynamicCast<Character>(scene->GetActorByID( aimTarget)); if (aimTargetChar) { SkillActorLinkPtr skillActorLink = new0 SkillActorLink(); instance->AddSkillActor(aimTarget, skillActorLink); skillActorLink->SetID(10000+scene->GetNextID()); skillActorLink->Initlize(); if (!mSelfEffectFilename.empty()) skillActorLink->SetMovableFilename(mSelfEffectFilename); skillActorLink->SetFromActorID(character->GetID()); skillActorLink->SetFromActorAnchor(mSelfEffectAnchor); if (IsLinkToActor()) { skillActorLink->SetTargetType(SkillActorLink::TT_ACTOR); skillActorLink->SetToActorID(aimTarget); } else { APoint toPos = charPos + mLinkDir * mSpeed * mLinkToTime; skillActorLink->SetTargetType(SkillActorLink::TT_POSITION); skillActorLink->SetToPosition(toPos); } skillActorLink->SetPosition(charPos); skillActorLink->SetLinkSpeed(GetSpeed()); skillActorLink->ShowHelpMovable(false); scene->AddActor(skillActorLink); skillActorLink->Start(); if (!mSelfPosEffectFilename.empty()) { APoint pos = character->GetPosition(); Transform trans; trans.SetTranslate(pos); trans.SetRotate(character->GetMovable()->WorldTransform.GetRotate()); if (!mSelfPosEffectFilename.empty()) { Node *anchor = character->GetAnchor(mSelfPosEffectAnchor); if (anchor) { //trans = anchor->WorldTransform; trans.SetTranslate(anchor->WorldTransform.GetTranslate()); } } Object *obj = PX2_RM.BlockLoadShareCopy(mSelfPosEffectFilename, false, false, true); if (obj) { EffectNode *effectNode = DynamicCast<EffectNode>(obj); if (effectNode) { effectNode->SetSelfCtrled(true); effectNode->WorldTransform = trans; effectNode->WorldTransformIsCurrent = true; sceneNode->AttachChild(effectNode); effectNode->ResetPlay(); PX2_DM.AddDeletingObj(effectNode, mSelfPosEffectTime, 3.0f); } } } } else { if (PX2_PROJ.IsInEditor()) { SkillActorLinkPtr skillActorLink = new0 SkillActorLink(); instance->AddSkillActor(aimTarget, skillActorLink); skillActorLink->SetID(10000+scene->GetNextID()); skillActorLink->Initlize(); if (!mSelfEffectFilename.empty()) skillActorLink->SetMovableFilename(mSelfEffectFilename); skillActorLink->SetFromActorID(character->GetID()); skillActorLink->SetFromActorAnchor(mSelfEffectAnchor); if (IsLinkToActor()) { skillActorLink->SetTargetType(SkillActorLink::TT_ACTOR); skillActorLink->SetToActorID(aimTarget); } else { APoint toPos = charPos + mLinkDir * mSpeed * mLinkToTime; skillActorLink->SetTargetType(SkillActorLink::TT_POSITION); skillActorLink->SetToPosition(toPos); } skillActorLink->SetPosition(charPos); skillActorLink->SetLinkSpeed(GetSpeed()); skillActorLink->ShowHelpMovable(false); scene->AddActor(skillActorLink); skillActorLink->Start(); } else { // over } } }
bool Application::OnCreate(const char* a_sCmdLine) { Utilities::ConsoleShow(true); //System m_pWindow = Window::Create("Ichor Window",1024,768); m_pRenderer = DX11Renderer::Create(m_pWindow); m_pGameTime = GameTime::Create(); //Input m_pKeyboard = Keyboard::Create(); m_pMouse = Mouse::Create(); m_pWindow->AttachMouse(m_pMouse); //Camera DX11Frustrum oFustrum; oFustrum.m_fFieldOfView = ((F32)PI_HALF / 2.0f); oFustrum.m_fScreenAspect = ((F32)m_pWindow->GetWidth() / (F32)m_pWindow->GetHeight()); oFustrum.m_fNear = 0.01f; oFustrum.m_fFar = 100.0f; m_pCamera = DX11Camera::Create(oFustrum); m_pCamera->SetTranslate(0.0f,0.0f,-10.0f); struct sData { char cInitial; int iVal; float fVal; double dVal; long long llVal; char cVal; }; sData* fDelta = new sData; //Shaders m_pShaderProp = ShaderProperty::Create("./Data/Shaders/Base.hlsl"); m_pShaderProp->AddCBuffer("Matrix",fDelta,sizeof(sData),0); //OBJECTS //Scene m_pScene = new Node("Scene"); //Cube m_pParent = dynamic_cast<Mesh*>(CreateCube()); m_pParent->AttachProperty(m_pShaderProp); m_pParent->SetTranslate(1,0,0); m_pChild = dynamic_cast<Mesh*>(m_pParent->Clone()); m_pChild->SetTranslate(-5,0,0); m_pParent->Update(); m_pChild->Update(); //Parenting m_pScene->AttachChild(m_pParent); m_pParent->AttachChild(m_pChild); m_fRot = 0.0f; return true; }
//---------------------------------------------------------------------------- void SkinnedBiped::CreateScene () { // Allow for toggle of wireframe. mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); // The biped has materials assigned to its triangle meshes, so they need // lighting. mLight = new0 Light(Light::LT_DIRECTIONAL); mLight->Ambient = Float4(0.5f, 0.5f, 0.5f, 1.0f); mLight->Diffuse = mLight->Ambient; mLight->Specular = Float4(0.0f, 0.0f, 0.0f, 1.0f); mLight->Constant = 0.0f; mLight->Linear = 0.0f; mLight->Quadratic = 0.0f; mLight->Intensity = 1.0f; mLight->DVector = mCamera->GetDVector(); Node* biped = GetNode("Biped"); Node* pelvis = GetNode("Pelvis"); Node* spine = GetNode("Spine"); Node* spine1 = GetNode("Spine1"); Node* spine2 = GetNode("Spine2"); Node* spine3 = GetNode("Spine3"); Node* neck = GetNode("Neck"); Node* head = GetNode("Head"); Node* leftClavicle = GetNode("L_Clavicle"); Node* leftUpperArm = GetNode("L_UpperArm"); Node* leftForeArm = GetNode("L_Forearm"); Node* leftHand = GetNode("L_Hand"); Node* rightClavicle = GetNode("R_Clavicle"); Node* rightUpperArm = GetNode("R_UpperArm"); Node* rightForeArm = GetNode("R_Forearm"); Node* rightHand = GetNode("R_Hand"); Node* leftThigh = GetNode("L_Thigh"); Node* leftCalf = GetNode("L_Calf"); Node* leftFoot = GetNode("L_Foot"); Node* leftToe = GetNode("L_Toe"); Node* rightThigh = GetNode("R_Thigh"); Node* rightCalf = GetNode("R_Calf"); Node* rightFoot = GetNode("R_Foot"); Node* rightToe = GetNode("R_Toe"); biped->AttachChild(pelvis); pelvis->AttachChild(spine); spine->AttachChild(spine1); spine1->AttachChild(spine2); spine2->AttachChild(spine3); spine3->AttachChild(neck); neck->AttachChild(head); // head->AttachChild(hair); neck->AttachChild(leftClavicle); leftClavicle->AttachChild(leftUpperArm); leftUpperArm->AttachChild(leftForeArm); leftForeArm->AttachChild(leftHand); // leftUpperArm->AttachChild(leftArm); neck->AttachChild(rightClavicle); rightClavicle->AttachChild(rightUpperArm); rightUpperArm->AttachChild(rightForeArm); rightForeArm->AttachChild(rightHand); // rightUpperArm->AttachChild(rightArm); // spine3->AttachChild(face); pelvis->AttachChild(leftThigh); leftThigh->AttachChild(leftCalf); leftCalf->AttachChild(leftFoot); leftFoot->AttachChild(leftToe); // leftCalf->AttachChild(leftShoe); // leftThigh->AttachChild(leftLeg); // leftThigh->AttachChild(leftAngle); pelvis->AttachChild(rightThigh); rightThigh->AttachChild(rightCalf); rightCalf->AttachChild(rightFoot); rightFoot->AttachChild(rightToe); // rightCalf->AttachChild(rightShoe); // rightThigh->AttachChild(rightLeg); // rightThigh->AttachChild(rightAnkle); // pelvis->AttachChild(shirt); // pelvis->AttachChild(pants); // The vertex format is shared among all the triangle meshes. mVFormat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0); // The TriMesh objects must be created after the Node tree is built, // because the TriMesh objects have to find the "bones" that correspond // to them. TriMesh* hair = GetMesh("Hair",biped); TriMesh* leftArm = GetMesh("L_Arm",biped); TriMesh* rightArm = GetMesh("R_Arm",biped); TriMesh* face = GetMesh("Face",biped); TriMesh* leftShoe = GetMesh("L_Shoe",biped); TriMesh* leftLeg = GetMesh("L_Leg",biped); TriMesh* leftAngle = GetMesh("L_Ankle",biped); TriMesh* rightShoe = GetMesh("R_Shoe",biped); TriMesh* rightLeg = GetMesh("R_Leg",biped); TriMesh* rightAnkle = GetMesh("R_Ankle",biped); TriMesh* shirt = GetMesh("Shirt",biped); TriMesh* pants = GetMesh("Pants",biped); head->AttachChild(hair); leftUpperArm->AttachChild(leftArm); rightUpperArm->AttachChild(rightArm); spine3->AttachChild(face); leftCalf->AttachChild(leftShoe); leftThigh->AttachChild(leftLeg); leftThigh->AttachChild(leftAngle); rightCalf->AttachChild(rightShoe); rightThigh->AttachChild(rightLeg); rightThigh->AttachChild(rightAnkle); pelvis->AttachChild(shirt); pelvis->AttachChild(pants); mScene = new0 Node(); mScene->LocalTransform.SetRotate(HMatrix(AVector::UNIT_Z, 0.25f*Mathf::PI)); mScene->AttachChild(biped); mScene->Update(); #if 0 // For regenerating the biped WMOF whenever engine streaming changes. OutStream target; target.Insert(mScene); target.Save("SkinnedBipedPN.wmof"); #endif }
BipedManager::BipedManager(std::string const& rootPath, std::string const& bname, ProgramFactory& programFactory, SkinController::Updater const& postUpdate) { // Vertex format shared by the two skins. VertexFormat vformat; vformat.Bind(VA_POSITION, DF_R32G32B32_FLOAT, 0); vformat.Bind(VA_NORMAL, DF_R32G32B32_FLOAT, 0); vformat.Bind(VA_TEXCOORD, DF_R32G32_FLOAT, 0); // Create the texture effects for the two skins. std::shared_ptr<Texture2> texture[2]; std::shared_ptr<Texture2Effect> effect[2]; for (int i = 0; i < 2; ++i) { std::string name = rootPath + "Skins/Skins" + std::to_string(i) + ".texture.png"; texture[i].reset(WICFileIO::Load(name, true)); texture[i]->AutogenerateMipmaps(); effect[i] = std::make_shared<Texture2Effect>(programFactory, texture[i], SamplerState::MIN_L_MAG_L_MIP_L, SamplerState::WRAP, SamplerState::WRAP); } PreSpatialArray preSpatialArray; PreSkinArray preSkinArray; SpatialMap spatialMap; std::string filename = rootPath + bname + ".txt"; std::ifstream inFile(filename); while (!inFile.eof()) { std::string line; getline(inFile, line); if (line == "") { // The file contains no blank lines, except for the very last one. break; } // Strip off initial white space. std::string::size_type begin = line.find_first_not_of(" "); if (begin > 0) { line = line.substr(begin); } std::string::size_type end; std::string name; if (line.find("Node") == 0) { // Load the node. begin = line.find("<"); end = line.find(">"); name = line.substr(begin + 1, end - 1 - begin); if (name.back() == 'X') { // TODO: These nodes are not necessary. Remove them from the // data sets. continue; } PreSpatial* preSpatial = LoadNode(rootPath, name); preSpatialArray.push_back(preSpatial); Node* node = reinterpret_cast<Node*>(preSpatial->Associate); spatialMap[name] = node; // Load the transform controllers. NodeCtrl nc; nc.first = node; nc.second.reset(LoadTransformController(rootPath, name, "Idle")); mIdleArray.push_back(nc); nc.second.reset(LoadTransformController(rootPath, name, "Walk")); mWalkArray.push_back(nc); nc.second.reset(LoadTransformController(rootPath, name, "Run")); mRunArray.push_back(nc); } else if (line.find("TriMesh") == 0) { // Load the mesh. begin = line.find("<"); end = line.find(">"); name = line.substr(begin + 1, end - 1 - begin); int suffix = name[name.length() - 1] - '0'; PreSpatial* preSpatial = LoadMesh(rootPath, name, vformat, effect[suffix]); preSpatialArray.push_back(preSpatial); spatialMap[name] = preSpatial->Associate; // Load the skin controller. PreSkin* preSkin = LoadSkinController(rootPath, name, postUpdate); preSkinArray.push_back(preSkin); // Attach the skin controller to the mesh. preSpatial->Associate->AttachController(preSkin->Associate); } } // Resolve the bone links. for (auto preSkin : preSkinArray) { SkinController* ctrl = preSkin->Associate; Node** bones = ctrl->GetBones(); int i = 0; for (auto const& boneName : preSkin->BoneNames) { auto iter = spatialMap.find(boneName); bones[i] = reinterpret_cast<Node*>(iter->second); ++i; } } // Assemble the biped hierarchy. for (auto preSpatial : preSpatialArray) { Node* node = dynamic_cast<Node*>(preSpatial->Associate); if (node) { for (auto const& childName : preSpatial->ChildNames) { if (childName.back() == 'X') { // TODO: These nodes are not necessary. Remove them from // the data sets. continue; } auto iter = spatialMap.find(childName); Visual* mesh = dynamic_cast<Visual*>(iter->second); if (mesh) { std::shared_ptr<Visual> visual(mesh); node->AttachChild(visual); if (visual->GetEffect().get() == effect[0].get()) { mSubscribers[0].first = visual; mSubscribers[0].second = effect[0]->GetPVWMatrixConstant(); } else { mSubscribers[1].first = visual; mSubscribers[1].second = effect[1]->GetPVWMatrixConstant(); } } else { node->AttachChild(std::shared_ptr<Spatial>(iter->second)); } } } } mRoot.reset(reinterpret_cast<Node*>(preSpatialArray[0]->Associate)); for (auto preSpatial : preSpatialArray) { delete preSpatial; } for (auto preSkin : preSkinArray) { delete preSkin; } // Create the blend controllers. int const numControllers = static_cast<int>(mIdleArray.size()); mIdleWalkArray.resize(numControllers); mWalkRunArray.resize(numControllers); for (int i = 0; i < numControllers; ++i) { NodeCtrl const& nc0 = mIdleArray[i]; NodeCtrl const& nc1 = mWalkArray[i]; NodeCtrl const& nc2 = mRunArray[i]; mIdleWalkArray[i].first = nc0.first; mIdleWalkArray[i].second = std::make_shared<BlendTransformController>( nc0.second, nc1.second, true, false); mWalkRunArray[i].first = nc0.first; mWalkRunArray[i].second = std::make_shared<BlendTransformController>( nc1.second, nc2.second, true, false); } }