void Enemy::detectCollision() { //bounding sphere for follower BoundingSphere mySphere = BoundingSphere(mPosition, mRadius); D3DXVECTOR3 movement; bool wall = false; //collision with walls or obstacles in level for (Mesh* M : gCurrentLevel->getWorldGeometry()) { for (AxisAlignedBoundingBox AABB : M->getBoundsBoxList()) { if (collides(AABB, mySphere, movement)) { mPosition += movement; wall = true; } } } //collide with other enemies unless there is was wall in the way if (!wall) { for (Enemy* E : gCurrentLevel->getSpawner()->getEnemies()) { BoundingSphere otherSphere = BoundingSphere(E->getPosition(), E->getRadius()); if (collides(mySphere, otherSphere, movement)) { mPosition += (movement / 2); E->move(-(movement / 2)); } } } }
void Follower::detectCollision() { //bounding sphere for follower BoundingSphere followerSphere = BoundingSphere(mPosition, mRadius); D3DXVECTOR3 movement; bool wall = false; //collision with walls or obstacles in level for (Mesh* M : gCurrentLevel->getWorldGeometry()) { for (AxisAlignedBoundingBox AABB : M->getBoundsBoxList()) { if (collides(AABB, followerSphere, movement)) { mPosition += movement; wall = true; } } } //collide with player unless there is a wall in the way if (!wall) { BoundingSphere playerSphere = BoundingSphere(gPlayer->getPosition(), gPlayer->getRadius()); if (collides(followerSphere, playerSphere, movement)) { mPosition += movement; } } }
bool Collision::Capsule_Capsule(const Capsule& capsule1, const Capsule& capsule2, HitInfo& hitInfo) { Vector3 a = capsule1.vector; Vector3 b = capsule2.vector; Vector3 c = capsule2.p1 - capsule1.p1; float distance = capsule1.radius + capsule2.radius; Vector3 n = a.Cross(b).GetNormal(); float L = c.Dot(n); Vector3 n1 = a.Cross(n).GetNormal(); Vector3 n2 = b.Cross(n).GetNormal(); Vector3 p3Dash = capsule2.p1 - n * L; Vector3 p4Dash = capsule2.p2 - n * L; Vector3 v1 = capsule1.p1 - p3Dash; Vector3 v2 = capsule1.p2 - p3Dash; Vector3 v3 = p3Dash - capsule1.p1; Vector3 v4 = p4Dash - capsule1.p1; float L1 = v1.Dot(n2); float L2 = v2.Dot(n2); float L3 = v3.Dot(n1); float L4 = v4.Dot(n1); float t1 = L3 / (L3 - L4); float t2 = L1 / (L1 - L2); if ((Math::Abs(L) < distance) && (0 < t1 && t1 < 1) && (0 < t2 && t2 < 1)) { return true; } BoundingSphere s = BoundingSphere(capsule1.p1, capsule1.radius); if ((t1 < 0) && BoundingSphere_Capsule(s, capsule2, hitInfo)) { return true; } s = BoundingSphere(capsule2.p1, capsule2.radius); if ((t1 > 1) && BoundingSphere_Capsule(s, capsule1, hitInfo)) { return true; } s = BoundingSphere(capsule2.p1, capsule2.radius); if ((t2 < 0) && BoundingSphere_Capsule(s, capsule1, hitInfo)) { return true; } s = BoundingSphere(capsule2.p2, capsule2.radius); if ((t2 > 1) && BoundingSphere_Capsule(s, capsule1, hitInfo)) { return true; } return false; }
//---------------------------------------------------------------------------- // @ BoundingSphere::Transform() // --------------------------------------------------------------------------- // Transforms sphere into new space //----------------------------------------------------------------------------- BoundingSphere BoundingSphere::Transform( float scale, const Matrix33& rotate, const Vector3& translate ) const { return BoundingSphere( rotate*mCenter + translate, mRadius*scale ); } // End of BoundingSphere::Transform()
BoundingSphere QuadTreeNode::CalcVolume() { // Traverse down until we reach the leaf nodes, then percolate the bounding spheres back up sphere = BoundingSphere(); if(children[0]) sphere += children[0]->CalcVolume(); if(children[1]) sphere += children[1]->CalcVolume(); if(children[2]) sphere += children[2]->CalcVolume(); if(children[3]) sphere += children[3]->CalcVolume(); if(sphere.empty()) { // This node doesn't have any children, so sum the bounds of its meshes for(size_t i = 0; i < meshes.size(); ++i) sphere += meshes[i]->sphere; } return sphere; }
void BillboardSample::loadBillboards() { Mesh* mesh = Mesh::createQuad(-(BILLBOARD_WIDTH / 2.0f), -(BILLBOARD_HEIGHT / 2.0f), BILLBOARD_WIDTH, BILLBOARD_HEIGHT); mesh->setBoundingSphere(BoundingSphere(Vector3::zero(), BILLBOARD_HEIGHT)); Effect* effect = Effect::createFromFile("res/shaders/textured.vert", "res/shaders/textured.frag", "TEXTURE_DISCARD_ALPHA"); // Create the model and node and bind the material for ( unsigned int i = 0; i < BILLBOARD_COUNT; i++ ) { Node* node = Node::create(); Model* model = Model::create(mesh); node->setDrawable(model); _scene->addNode(node); Material* material = Material::create(effect); material->getStateBlock()->setDepthTest(true); material->getStateBlock()->setBlend(false); material->getParameter("u_diffuseTexture")->setValue("res/png/grass.png" , true); material->setParameterAutoBinding("u_worldViewProjectionMatrix", RenderState::WORLD_VIEW_PROJECTION_MATRIX); model->setMaterial(material); SAFE_RELEASE(model); SAFE_RELEASE(material); // Randomly postiion within the domain float tx = MATH_RANDOM_0_1() * GROUND_WIDTH - (GROUND_WIDTH / 2.0f); float tz = MATH_RANDOM_0_1() * GROUND_HEIGHT - (GROUND_HEIGHT / 2.0f); node->translate(tx, (BILLBOARD_HEIGHT / 2.0f), tz); _billboards.push_back(node); } SAFE_RELEASE(effect); SAFE_RELEASE(mesh); }
//---------------------------------------------------------------------------- // @ BoundingSphere::Transform() // --------------------------------------------------------------------------- // Transforms sphere into new space //----------------------------------------------------------------------------- BoundingSphere BoundingSphere::Transform( float scale, const Quat& rotate, const Vector3& translate ) const { return BoundingSphere( rotate.Rotate(mCenter) + translate, mRadius*scale ); } // End of BoundingSphere::Transform()
//takes the corner of the -x/-z corner and int size //since the map for this is always flat and square //works best when map size is divisible by GRID_SIZE //This only works effectively if done after all the addWorldGeometry void AStar::initPathfinding() { D3DXVECTOR3 corner = gCurrentLevel->getNegCorner(); //set up path nodes for enemy path finding //place path nodes every GRID_SIZE units except //in places where it would collide UINT iterationsX = (UINT)gCurrentLevel->getSize().x / GRID_SIZE; UINT iterationsZ = (UINT)gCurrentLevel->getSize().z / GRID_SIZE; for (UINT x = 0; x < iterationsX; ++x) { for (UINT z = 0; z < iterationsZ; ++z) { bool canPlace = true; //for each mesh in the current map for (Mesh* M : gCurrentLevel->getWorldGeometry()) { //for each AABB in that mesh for (AxisAlignedBoundingBox AABB : M->getBoundsBoxList()) { //find the center of the node to compare with D3DXVECTOR3 nodeCenter = D3DXVECTOR3(corner.x + (float)(x * GRID_SIZE), 0.0f, corner.z + (float)(z * GRID_SIZE)); //make a bounding sphere with it BoundingSphere PS = BoundingSphere(nodeCenter, CLOSE_RADIUS); //if the AABB collides with that sphere, we can't place one here if (collides(AABB, PS)) { canPlace = false; break; } if (!canPlace) break; } if (!canPlace) break; } //if no obstruction was found, place the node if (canPlace) { D3DXVECTOR3 position = D3DXVECTOR3(corner.x, 0.0f/*SAM:50.0f*/, corner.z) + D3DXVECTOR3((float)(x * GRID_SIZE), 0.0f, (float)(z * GRID_SIZE)); #ifdef DEBUG_PATHS //set up the mesh if in debug PathNode* pn = new PathNode(L"Content/Models/ball.x", position, D3DXVECTOR3(2.0f, 2.0f, 2.0f)); #else //use no mesh if not in debug, this saves a lot of time loading PathNode* pn = new PathNode(position); #endif //add new node mPathNodes.push_back(pn); } } } //connect the nodes to their closest neighbors connectPathfinding(); }
typename std::enable_if<std::is_same<typename std::iterator_traits<Iterator>::value_type, BoundingSphere>::value, BoundingSphere>::type static compute_containing_sphere(Iterator begin, Iterator end) { if (begin != end) { BoundingSphere bounds = *begin++; return std::accumulate(begin, end, bounds, std::ptr_fun(&compute_containing_sphere)); } return BoundingSphere(); }
void BVHNode<BoundingVolumeType>::RecalculateBoundingVolume() { if (IsLeaf()) return; m_volume = BoundingSphere(m_children[0]->m_volume, m_children[1]->m_volume); if (m_parent) { m_parent->RecalculateBoundingVolume(); } }
void RayTracerCuda::loadObjects(Mesh *output) { for (int i = 0; i < (int)theScene->objects.size(); i++) { PMesh *theObj = theScene->objects.at(i).get(); output[i].boundingSphere = BoundingSphere(Float3D(&theObj->boundingSphere->center), theObj->boundingSphere->radius); output[i].viewCenter = Float3D(&theObj->viewCenter); output[i].numMats = theObj->numMats; output[i].materials = new Material[theObj->numMats]; for (int j = 0; j < theObj->numMats; j++) { output[i].materials[j].ka = FloatColor(&theObj->materials[j].ka); output[i].materials[j].kd = FloatColor(&theObj->materials[j].kd); output[i].materials[j].ks = FloatColor(&theObj->materials[j].ks); output[i].materials[j].reflectivity = FloatColor(&theObj->materials[j].reflectivity); output[i].materials[j].refractivity = FloatColor(&theObj->materials[j].refractivity); output[i].materials[j].refractiveIndex = theObj->materials[j].refractiveIndex; output[i].materials[j].shiny = theObj->materials[j].shiny; } output[i].numSurfs = theObj->numSurf; output[i].surfaces = new Surface[theObj->numSurf]; int surfCount = 0, vertCount = 0; for (PMesh::SurfCell *curSurf = theObj->surfHead.get(); curSurf != nullptr; curSurf = curSurf->next.get(), surfCount++, vertCount = 0) { output[i].surfaces[surfCount].material = curSurf->material; output[i].surfaces[surfCount].numVerts = curSurf->numVerts; output[i].surfaces[surfCount].vertArray = new Float3D[curSurf->numVerts]; output[i].surfaces[surfCount].viewNormArray = new Float3D[curSurf->numVerts]; for (PMesh::PolyCell *curPoly = curSurf->polyHead.get(); curPoly != nullptr; curPoly = curPoly->next.get()) { PMesh::VertListCell *curVert = curPoly->vert.get(); Float3D v1 = Float3D(&theObj->vertArray.at(curVert->vert)->viewPos); Float3D v2 = Float3D(&theObj->vertArray.at(curVert->next.get()->vert)->viewPos); Float3D v3 = Float3D(&theObj->vertArray.at(curVert->next.get()->next.get()->vert)->viewPos); Float3D e1 = v2.minus(&v1); Float3D e2 = v3.minus(&v1); output[i].surfaces[surfCount].vertArray[vertCount] = v1; output[i].surfaces[surfCount].viewNormArray[vertCount++] = Float3D(&theObj->viewNormArray.at(curVert->vert)); output[i].surfaces[surfCount].vertArray[vertCount] = e1; output[i].surfaces[surfCount].viewNormArray[vertCount++] = Float3D(&theObj->viewNormArray.at(curVert->next.get()->vert)); output[i].surfaces[surfCount].vertArray[vertCount] = e2; output[i].surfaces[surfCount].viewNormArray[vertCount++] = Float3D(&theObj->viewNormArray.at(curVert->next.get()->next.get()->vert)); } } } }
//---------------------------------------------------------------------------------------------- BoundingSphere generateBoundingSphere(const std::vector<glm::vec3>& positions) { glm::vec3 center(0.0f, 0.0f, 0.0f); float radius = 0.0f; for (const glm::vec3& p : positions) { center += p; } center /= positions.size(); for (const glm::vec3& p : positions) { float d = glm::distance(center, p); radius = glm::max(radius, d); } return BoundingSphere(center, radius); }
void FLightSceneInfoCompact::Init(FLightSceneInfo* InLightSceneInfo) { LightSceneInfo = InLightSceneInfo; FSphere BoundingSphere( InLightSceneInfo->Proxy->GetOrigin(), InLightSceneInfo->Proxy->GetRadius() > 0.0f ? InLightSceneInfo->Proxy->GetRadius() : FLT_MAX ); FMemory::Memcpy(&BoundingSphereVector,&BoundingSphere,sizeof(BoundingSphereVector)); Color = InLightSceneInfo->Proxy->GetColor(); LightType = InLightSceneInfo->Proxy->GetLightType(); bCastDynamicShadow = InLightSceneInfo->Proxy->CastsDynamicShadow(); bCastStaticShadow = InLightSceneInfo->Proxy->CastsStaticShadow(); bStaticLighting = InLightSceneInfo->Proxy->HasStaticLighting(); }
void Asteroid::ResolveCollision(Asteroid& otherAsteroid) { std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now(); if (lastCollision == &otherAsteroid) { std::chrono::high_resolution_clock::duration diff = now - lastCollisionTime; if (std::chrono::duration_cast<std::chrono::milliseconds>(diff).count() < 500) { return; } } if (otherAsteroid.lastCollision == this) { std::chrono::high_resolution_clock::duration diff = now - otherAsteroid.lastCollisionTime; if (std::chrono::duration_cast<std::chrono::milliseconds>(diff).count() < 500) { return; } } Locus::Triangle3D_t intersectingTriangle1, intersectingTriangle2; if ( GetAsteroidIntersection(otherAsteroid, intersectingTriangle1, intersectingTriangle2) ) { Locus::FVector3 collisionPoint = Locus::Triangle3D_t::ComputeCentroid(intersectingTriangle1, intersectingTriangle2); Locus::FVector3 impulseDirection = NormVector(intersectingTriangle1.Normal()); Locus::ResolveCollision(1.0f, BoundingSphere(), otherAsteroid.BoundingSphere(), collisionPoint, impulseDirection, motionProperties, otherAsteroid.motionProperties); lastCollision = &otherAsteroid; otherAsteroid.lastCollision = this; now = std::chrono::high_resolution_clock::now(); lastCollisionTime = now; otherAsteroid.lastCollisionTime = now; } }
BoundingSphere BoundingSphere::operator+(const BoundingSphere& rh) { return BoundingSphere(*this) += rh; }
TEST(Camera, frustrumCreation) { RendererImplementationMock renderer; Camera camera( "camera", renderer, Camera::PT_PERSPECTIVE ); camera.setNearPlaneDimensions(10, 10); camera.setClippingPlanes(10, 100); camera.setFOV(90); Frustum frustrum; camera.calculateFrustum( frustrum ); CPPUNIT_ASSERT_EQUAL(false, testCollision(frustrum, BoundingSphere(Vector(0, 0, -2), 1))); CPPUNIT_ASSERT_EQUAL(false, testCollision(frustrum, BoundingSphere(Vector(0, 0, 8), 1))); CPPUNIT_ASSERT_EQUAL(false, testCollision(frustrum, BoundingSphere(Vector(0, 0, 102), 1))); CPPUNIT_ASSERT_EQUAL(false, testCollision(frustrum, BoundingSphere(Vector(0, 0, 0), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, 0, 100), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, 0, 8), 2))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, 0, 10), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, 0, 50), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(-20, 0, 50), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(20, 0, 50), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, -20, 50), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(0, 20, 50), 1))); // camera rotated Quaternion rotY; rotY.setAxisAngle( Quad_0100, FastFloat::fromFloat( DEG2RAD( 90 ) ) ); camera.accessLocalMtx().setRotation( rotY ); camera.calculateFrustum( frustrum ); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(10, 0, 0), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(100, 0, 0), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(50, 0, 0), 1))); // camera rotated rotY.setAxisAngle( Quad_0100, FastFloat::fromFloat( DEG2RAD( -90 ) ) ); camera.accessLocalMtx().setRotation( rotY ); camera.calculateFrustum( frustrum ); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(-10, 0, 0), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(-100, 0, 0), 1))); CPPUNIT_ASSERT_EQUAL(true, testCollision(frustrum, BoundingSphere(Vector(-50, 0, 0), 1))); }
BoundingSphere Light::getBoundingSphere(void) { return BoundingSphere(getPosition(), radius * 4.0f); }
void SmokeSource::initializeBoundingSphere() { glm::vec3 center(0,0,0); float radius = glm::length(center - glm::vec3(0.5f, 0.5f, 0.5f)); bounding_sphere = BoundingSphere(center, radius); }
BoundingSphere P0N0T0Builder::CreateBoundingSphere() const { return BoundingSphere(); }
void Player::update(float _dt) { //do nothing if dead if (bIsDead) { gStateMachine->transitionState(STATE_LOSE); return; } Pawn::update(_dt); //facing controls if (gDInput->keyDown(DIK_Q)) { gCameraMain->setAngleOffset(1.0f * _dt); } if (gDInput->keyDown(DIK_E)) { gCameraMain->setAngleOffset(-1.0f * _dt); } //face towards mouse position float a = (float)gWindowWidth / 2.0f - gDInput->mCursorPos2D.x; float b = (float)gWindowHeight / 2.0f - gDInput->mCursorPos2D.y; float angle = atan2f(b, a) + D3DX_PI / 2.0f + gCameraMain->getAngleOffset(); mRotation.y = angle; //direction controls bIsMoving = false; mVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f); if (gDInput->keyDown(DIK_W)) { mVelocity += D3DXVECTOR3(0.0f, 0.0f, mSpeed); bIsMoving = true; } if (gDInput->keyDown(DIK_S)) { mVelocity += D3DXVECTOR3(0.0f, 0.0f, -mSpeed); bIsMoving = true; } if (gDInput->keyDown(DIK_A)) { mVelocity += D3DXVECTOR3(-mSpeed, 0.0f, 0.0f); bIsMoving = true; } if (gDInput->keyDown(DIK_D)) { mVelocity += D3DXVECTOR3(mSpeed, 0.0f, 0.0f); bIsMoving = true; } if (mVelocity != D3DXVECTOR3(0.0f, 0.0f, 0.0f)) { //face direction that the buttons indicate we're going D3DXVec3Normalize(&mVelocity, &mVelocity); float a = (float)gWindowWidth * 0.5f - mVelocity.x; float b = (float)gWindowHeight * 0.5f - mVelocity.z; float angle = atan2f(b, a) + /*D3DX_PI * 1.795f + */5.6391588f + gCameraMain->getAngleOffset(); //build rotation matrix D3DXMATRIX rot; D3DXMatrixRotationY(&rot, angle); //transform direction by rot matrix D3DXVECTOR4 transform; D3DXVec3Transform(&transform, &mVelocity, &rot); mVelocity = D3DXVECTOR3(transform.x, transform.y, transform.z); D3DXVec3Normalize(&mVelocity, &mVelocity); mVelocity *= mSpeed; } //did we collide with any level geometry? bool colliding = false; //for each colliding mesh in level // SAM: TODO: Hack, this is for testing // mLastPosition = mPosition; // mPosition += (mVelocity * _dt); for (Mesh* M : gCurrentLevel->getWorldGeometry()) { //for each bounding box in mesh /* for (AxisAlignedBoundingBox2D* AABB : M->getAABBs()) { colliding = collides(*AABB, BoundingSphere2D(D3DXVECTOR2(mPosition.x, mPosition.z), mRadius)); if (colliding) break; } if (colliding) break;*/ // SAM for (UINT i = 0; i < M->getBoundsBoxList().size(); ++i) { colliding = collides(AxisAlignedBoundingBox(M->getBoundsBoxList()[i]), BoundingSphere(D3DXVECTOR3(mPosition.x, mPosition.y, mPosition.z), mRadius)); if (colliding) break; } if (colliding) break; } //move if (!colliding) {//if not colliding, update position and rotation as normal mLastPosition = mPosition; mPosition += (mVelocity * _dt); } else//if colliding, only update rotation, push position back { mPosition = mLastPosition; } mMesh->setPosRot(mPosition, mRotation); //attacks mAttackTime += _dt; //if time to attack and if didn't just click the upper right UI buttons this frame if (mAttackTime > mAttackDelay && ( (gDInput->mCursorPos2D.x < (0.9f * (float)gWindowWidth)) || (gDInput->mCursorPos2D.y > (0.3f * (float)gWindowHeight)) ) ) { ePAttack attackType; //check if button is pressed if (gDInput->mouseButtonDown(0)) attackType = mLeftAttack; else if (gDInput->mouseButtonDown(1)) attackType = mRightAttack; else attackType = A_NONE; bool attacked = false; if (attackType != A_NONE) { Attack* attack; bool canAttack = true; switch (attackType) { case A_MELEE: attack = new Attack(L"", 20.0f, 400.0f, 0.1f, true); gSound->getSystem()->playSound(FMOD_CHANNEL_FREE,playerAttackMelee, false, 0); attacked = true; break; case A_SEED: if (mAmmoSeeds > 0) { --mAmmoSeeds; attack = new Attack(L"Content/Models/ball.x", 15.0f, 600.0f, 8.0f, true, 10.0f, D3DXVECTOR3(4.0f, 4.0f, 4.0f)); attack->setTextures(L"Content/Textures/tex_seed.dds", L"Content/Textures/tex_seed_n.dds"); gSound->getSystem()->playSound(FMOD_CHANNEL_FREE,playerAttackSeed, false, 0); attacked = true; } break; case A_FIRE: if (mAmmoFire > 0) { --mAmmoFire; attack = new Attack(L"Content/Models/ball.x", 30.0f, 500.0f, 8.0f, true, 10.0f, D3DXVECTOR3(4.0f, 4.0f, 4.0f)); attack->setTextures(L"Content/Textures/tex_fire.dds", L"Content/Textures/tex_fire_n.dds"); gSound->getSystem()->playSound(FMOD_CHANNEL_FREE,playerAttackFire, false, 0); attacked = true; } break; } if (attacked) { attack->moveFacingDirection(); gCurrentLevel->getAttackManager()->addAttack(attack); } mAttackTime = 0.0f; } } }
inline BoundingSphere Transform( Mat4f & trans ) { Vec4f pos(m_Center.ToVec3(), 1.0f); const Vec4f & newCenter = trans*pos; return BoundingSphere( newCenter.ToVec3(), m_Center[3]); }
void Hair::LoadHair(const char* hairFile) { ifstream in(hairFile, ios::binary); if (!in.good()) return; //Version number long version; in.read((char*)&version, sizeof(long)); //Number splines long numSplines = 0; in.read((char*)&numSplines, sizeof(long)); //Read splines for (int i=0; i<numSplines; i++) { ControlHair* ch = new ControlHair(); //Read points long numPoints = 0; in.read((char*)&numPoints, sizeof(long)); for (int p=0; p<numPoints; p++) { D3DXVECTOR3 point; in.read((char*)&point, sizeof(D3DXVECTOR3)); ch->AddPoint(point); } m_controlHairs.push_back(ch); } in.close(); //Patches CreatePatch(1, 0, 5, 6); CreatePatch(2, 1, 6, 7); CreatePatch(3, 2, 7, 8); CreatePatch(4, 3, 8, 9); CreatePatch(6, 5, 14, 10); CreatePatch(7, 6, 10, 11); CreatePatch(8, 7, 11, 12); CreatePatch(9, 8, 12, 13); CreatePatch(15, 16, 21, 20); CreatePatch(16, 17, 22, 21); CreatePatch(17, 18, 23, 22); CreatePatch(18, 29, 24, 23); CreatePatch(20, 21, 25, 27); CreatePatch(21, 22, 26, 25); CreatePatch(22, 23, 19, 26); CreatePatch(23, 24, 28, 19); CreatePatch(29, 4, 24, 9); CreatePatch(24, 9, 13, 28); //Create head spheres m_headSpheres.push_back(BoundingSphere(D3DXVECTOR3(0.0f, 0.057f, -0.017f), 0.082f)); m_headSpheres.push_back(BoundingSphere(D3DXVECTOR3(0.0f, 0.071f, 0.017f), 0.082f)); m_headSpheres.push_back(BoundingSphere(D3DXVECTOR3(0.0f, 0.054f, 0.042f), 0.08f)); m_headSpheres.push_back(BoundingSphere(D3DXVECTOR3(0.0f, 0.018f, 0.017f), 0.09f)); }