// render // irr scenenode impl void CGameGrassSceneNode::render() { ISceneManager *smgr = getSceneManager(); IVideoDriver *driver = smgr->getVideoDriver(); #ifdef GSEDITOR CGameObject::EObjectState state = m_owner->getObjectState(); // draw bbox on select if ( state == CGameObject::Move || state == CGameObject::Review ) setDebugDataVisible( EDS_BBOX ); else setDebugDataVisible( 0 ); // call object draw m_owner->drawObject(); #endif // set world transform driver->setTransform( video::ETS_WORLD, getAbsoluteTransformation()); // set current material with config shader driver->setMaterial( m_Material); // draw mesh with grass shader int meshCount = m_mesh->getMeshBufferCount(); for ( int i = 0; i < meshCount; i++ ) driver->drawMeshBuffer(m_mesh->getMeshBuffer(i)); // draw bouding box if ( DebugDataVisible & scene::EDS_BBOX ) { driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); video::SMaterial deb_m; deb_m.Lighting = false; driver->setMaterial(deb_m); core::aabbox3d<f32> tbox = m_mesh->getBoundingBox(); getAbsoluteTransformation().transformBoxEx(tbox); driver->draw3DBox( tbox, video::SColor(255,255,255,255)); } #ifdef GSEDITOR // draw move if ( state == CGameObject::Move || state == CGameObject::Rotation || state == CGameObject::Scale ) m_owner->drawFrontUpLeftVector(); if ( state == CGameObject::Rotation ) m_owner->drawCircleAroundObject(); #endif }
void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, UINT32 timeMs) { if (!node || node->getType() != ESNT_CAMERA) return; ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node); if (firstUpdate) { camera->updateAbsolutePosition(); if (CursorControl) { CursorControl->setPosition(0.5f, 0.5f); CursorPos = CenterCursor = CursorControl->getRelativePosition(); } LastAnimationTime = timeMs; firstUpdate = false; } // If the camera isn't the active camera, and receiving input, then don't process it. if (!camera->isInputReceiverEnabled()) { firstInput = true; return; } if (firstInput) { allKeysUp(); firstInput = false; } ISceneManager * smgr = camera->getSceneManager(); if (smgr && smgr->getActiveCamera() != camera) return; // get time FLOAT32 timeDiff = (FLOAT32)(timeMs - LastAnimationTime); LastAnimationTime = timeMs; // update position Vector3 pos = camera->getPosition(); // Update rotation Vector3 target = (camera->getTarget() - camera->getAbsolutePosition()); Vector3 relativeRotation = target.getHorizontalAngle(); if (CursorControl) { if (CursorPos != CenterCursor) { relativeRotation.y -= (0.5f - CursorPos.x) * RotateSpeed; relativeRotation.x -= (0.5f - CursorPos.y) * RotateSpeed * MouseYDirection; // X < MaxVerticalAngle or X > 360-MaxVerticalAngle if (relativeRotation.x > MaxVerticalAngle * 2 && relativeRotation.x < 360.0f - MaxVerticalAngle) { relativeRotation.x = 360.0f - MaxVerticalAngle; } else if (relativeRotation.x > MaxVerticalAngle && relativeRotation.x < 360.0f - MaxVerticalAngle) { relativeRotation.x = MaxVerticalAngle; } // Do the fix as normal, special case below // reset cursor position to the centre of the window. CursorControl->setPosition(0.5f, 0.5f); CenterCursor = CursorControl->getRelativePosition(); // needed to avoid problems when the event receiver is disabled CursorPos = CenterCursor; } // Special case, mouse is whipped outside of window before it can update. IVideoDriver* driver = smgr->getVideoDriver(); Vector2 mousepos(UINT32(CursorControl->getPosition().x), UINT32(CursorControl->getPosition().y)); rect<UINT32> screenRect(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height); // Only if we are moving outside quickly. bool reset = !screenRect.isPointInside(mousepos); if (reset) { // Force a reset. CursorControl->setPosition(0.5f, 0.5f); CenterCursor = CursorControl->getRelativePosition(); CursorPos = CenterCursor; } } // set target target.set(0, 0, Math::_max<Real>(1.f, pos.length())); Vector3 movedir = target; Matrix4 mat; mat.setRotationDegrees(Vector3(relativeRotation.x, relativeRotation.y, 0)); //mat.transformVect(target); target = mat.transformAffine(target); if (NoVerticalMovement) { mat.setRotationDegrees(Vector3(0, relativeRotation.y, 0)); //mat.transformVect(movedir); target = mat.transformAffine(target); } else { movedir = target; } movedir.normalise(); if (CursorKeys[EKA_MOVE_FORWARD]) pos += movedir * timeDiff * MoveSpeed; if (CursorKeys[EKA_MOVE_BACKWARD]) pos -= movedir * timeDiff * MoveSpeed; // strafing Vector3 strafevect = target; strafevect = strafevect.crossProduct(camera->getUpVector()); if (NoVerticalMovement) strafevect.y = 0.0f; strafevect.normalise(); if (CursorKeys[EKA_STRAFE_LEFT]) pos += strafevect * timeDiff * MoveSpeed; if (CursorKeys[EKA_STRAFE_RIGHT]) pos -= strafevect * timeDiff * MoveSpeed; // For jumping, we find the collision response animator attached to our camera // and if it's not falling, we tell it to jump. if (CursorKeys[EKA_JUMP_UP]) { const ISceneNodeAnimatorList& animators = camera->getAnimators(); ISceneNodeAnimatorList::const_iterator it = animators.begin(); while (it != animators.end()) { if (ESNAT_COLLISION_RESPONSE == (*it)->getType()) { ISceneNodeAnimatorCollisionResponse * collisionResponse = static_cast<ISceneNodeAnimatorCollisionResponse *>(*it); if (!collisionResponse->isFalling()) collisionResponse->jump(JumpSpeed); } it++; } } // write translation camera->setPosition(pos); // write right target target += pos; camera->setTarget(target); }