2014-12-11 4 views
0

이 같은 Entity.h 있습니다 :개체에 대한 액세스 위반

네임 스페이스를 사용하여 physx; 내가 하나의 개체를 생성하고 작동 초기화하면 지금

#include "Entity.h" 

Entity::Entity(Ogre::Vector3 dims, Ogre::Vector3 pos, std::string mesh, std::string id) 
{ 

    mDimensions = dims; 
    mPosition = pos; 
    mMesh  = mesh; 
    mId   = id; 
    mActor  = NULL; 
    mMaterial = NULL; 
} 

Entity::~Entity(void) 
{ 

} 

void Entity::update(Ogre::Real dt) 
{ 
    PxVec3 pos = mActor->getGlobalPose().p; 
    Ogre::Real r = 0; 
    mOgreNode->setPosition(Ogre::Vector3(pos.x + r, pos.y + r, pos.z + r)); 
} 

void Entity::init(Ogre::SceneManager* sceneMgr, PxPhysics* physics, PxScene* scene, PxVec3 velocity) 
{ 
    // Create an Entity 
    mOgreEntity = sceneMgr->createEntity(mId, mMesh); 
    mOgreEntity->setCastShadows(true); 

    // Create a SceneNode and attach the Entity to it 
    mOgreNode = sceneMgr->getRootSceneNode()->createChildSceneNode(mId + "Node"); 
    Ogre::AxisAlignedBox box = mOgreEntity->getBoundingBox(); 
    Ogre::Vector3 realSizes = box.getSize(); 

    mOgreNode->setPosition(mPosition); 
    mOgreNode->attachObject(mOgreEntity); 

    Ogre::Vector3 scaler = Ogre::Vector3(mDimensions.x/realSizes.x, mDimensions.y/realSizes.y, mDimensions.z/realSizes.z); 
    mOgreNode->scale(scaler); 


    mMaterial = physics->createMaterial(1.5f, 1.5f, 1.0f); 
    PxGeometry* geometry = NULL; 
    if(mMesh == "sphere.mesh") 
    { 
     PxGeometry g = PxSphereGeometry(mDimensions.x/2); // Because it's a radius 
     geometry = &g; 
    } else { 
     // geometry = NULL; 
    } 
    PxTransform transform = PxTransform(PxVec3(mPosition.x, mPosition.y, mPosition.z)); 
    mActor = PxCreateDynamic(*physics, transform, *geometry, *mMaterial, PxReal(.1)); 
    // if(!mActor) { 
//  MessageBox(NULL, "no actor", "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL); 
    // return; 
    // } 
    mActor->setLinearVelocity(velocity); 
    // And add the actor to a scene: 

    scene->addActor(*mActor); 

} 

:

class Entity 
{ 

public: 
    Entity(Ogre::Vector3 dims, Ogre::Vector3 pos, std::string mesh, std::string id); 
    virtual ~Entity(void); 
    virtual void update(Ogre::Real dt); 
    virtual void init(Ogre::SceneManager* sceneMgr, PxPhysics* physics, PxScene* scene, PxVec3 velocity=PxVec3(0, 0, 0)); 
protected: 
    Ogre::Entity*  mOgreEntity = NULL; 
    Ogre::SceneNode* mOgreNode = NULL; 

    Ogre::Vector3  mPosition; 
    Ogre::Vector3  mDimensions; 
    std::string   mMesh; 
    std::string   mId; 


    PxRigidDynamic*  mActor; 
    PxMaterial*   mMaterial; 
}; 

그리고 여기 내 법인 소스입니다. 심지어 wirh 두 번째 엔티티 var 그것은 잘 작동합니다. 배열의 경우 :

Entity *mEntities[20]; 
for(int i = 0 ; i < 20 ; i++){ 
    ostringstream nameStream; 
    nameStream << "Sphere_" << i; 
    string name = nameStream.str(); 
    Entity* sphere = new Entity(Ogre::Vector3(i*5, i*4.5, i*6), Ogre::Vector3(i*5, i*4.5, i*6), "sphere.mesh", name); 
    sphere->init(mSceneMgr, mPhysics, gScene, PxVec3(-10.0f, 0, 0)); 
    mEntities[i] = sphere; 

} 

나는 Access violation입니다. 방금의 시간 디버거 /, 그것은 mActor가 null뿐만 아니라

mMaterial로 편집 것을 밝혀졌다 W :

이 코드 중 하나가 작동하지 않습니다

mEntity = Entity(Ogre::Vector3(50.0f, 50.0f, 50.0f), Ogre::Vector3(50.0f, 40.5f, 60.0f), "sphere.mesh", "sphere"); 
    mEntity.init(mSceneMgr, mPhysics, gScene, PxVec3(-10.0f, 0, 0)); 
+0

나는'Entity'의 생성자에서 NULL 포인터를 초기화하는 것이 좋습니다. 또한 코드에서 실제로 호출하는 함수가 실제로 좋은 값을 반환하는지 확인하기 위해 오류를 검사하지 않습니다. – PaulMcKenzie

+0

@ PaulMcKenzie 귀하의 제안에 감사하지만 소스를 편집했지만 여전히이 오류가 발생합니다. /. 업데이트 된 게시물 – Vinz243

+1

보기'geometry = & PxSphereGeometry (mDimensions.x/2);'이 줄이 무엇을해야하는지 설명하십시오. 그것을 보는 누군가는 당신이 그 성명서가 끝난 후에 절대적으로 좋지 않을 임시의 주소를 할당하고 있다고 생각할 것입니다. – PaulMcKenzie

답변

1

1)

Entity* sphere = new Entity(Ogre::Vector3(i*5, i*4.5, i*6), 
          Ogre::Vector3(i*5, i*4.5, i*6), 
          "sphere.mesh", 
          "Sphere_"+i); 

"Sphere_"+i i의 길이가 "Sphere_"보다 큰 경우 포인터를 임의의 메모리에 전달합니다. 나는 당신이 마지막에 i가있는 문자열을 만들고 싶다고 가정합니다.
sprintf 또는 std::string을 사용하십시오. 당신의 그것이 아마 작동 3을 가정 해 봅시다 20에서 루프 범위를 변경하는 경우

2)
. 문제는 귀하의 이름이 다음과 같을 것입니다 :
Sphere_, phere_, here_
"Sphere_"+i을 수행하면 문자열에 정수가 추가되지 않으므로.
이가 "동일"입니다 :

char *string = "String"; 
string += 3; 

3)이 코드는 당신이 필요로하는 문자열을 생성합니다
:

PxGeometry* geometry = NULL; 
if(mMesh == "sphere.mesh") 
{ 
    geometry = &PxSphereGeometry(mDimensions.x/2); // Because it's a radius 
} 
: 여기
std::ostringstream newStringStream; 
newStringStream << "Sphere_" << i; 
std::string newString = newStringStream.str(); 
+0

문자열을 보내 주셔서 감사 합니다만 액세스 위반을 해결하지 못했지만 다른 오류가 발생했습니다 – Vinz243

+0

어떤 줄과 어떤 반복에서 충돌이 발생합니까? 편집 : 미안 코드를 제대로 읽지 못했습니다. –

+0

''mActor-> setLinearVelocity (velocity);'최초의 반복시 – Vinz243

1

는 또 다른 문제입니다

이 문제는에 할당하는 것입니다.임시 값의 주소입니다. 해당 코드 행이 완료되면 해당 임시 행은 사라집니다.

이에 대한 가능한 수정하여이 작업을 수행 할 수 없습니다 :

PxGeometry geometry; 
if(mMesh == "sphere.mesh") 
{ 
    geometry = PxSphereGeometry(mDimensions.x/2); // Because it's a radius 
} 
//... 
mActor = PxCreateDynamic(*physics, transform, geometry, *mMaterial, PxReal(.1)); 

지금 geometry는 더 이상 포인터이며, 값이 반환에 당신이 (주소의 값이 아닌 반환), 지오메트리를 지정하고 있습니다.

은 여기 설명서를 읽고있다 :

http://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/apireference/files/classPxSphereGeometry.html

그래서 PxSphereGeometry(x)는 생성자 호출이다. 따라서 value을 이 아닌 PxShpereGeometry에 할당해야합니다.

편집 : 귀하의 최신 변경 사항도 원하는 효과가없는이 :

if(mMesh == "sphere.mesh") 
{ 
    PxGeometry g = PxSphereGeometry(mDimensions.x/2); // Because it's a radius 
    geometry = &g; 
    } 

gif() 블록에 지역이다. 이 g의 주소를 geometry에 할당합니다. 그런 다음 해당 블록이 종료되면 g이 사라지고 더 이상 존재하지 않는 것을 가리키는 geometry이 생겼습니다.

편집 한 코드와 내가 준 대답의 차이점은 내 대답 assigns은 기존 개체에 대한 반환 값입니다. 그래서 반환 값의 복사본을 만들었습니다. 편집 된 코드에서 수행하는 작업은 복제물을 만드는 것이 아니라 범위를 벗어난 후 존재하지 않는 로컬 객체를 가리키는 것입니다. 당신이 당신의 수정 코드의 패턴을 다음 코드를 작성하고 유효해야한다면

그래서 변화는 다음과 같이 보일 것이다 :

PxGeometry geometry; 
if(mMesh == "sphere.mesh") 
{ 
    PxGeometry g = PxSphereGeometry(mDimensions.x/2); // Because it's a radius 
    geometry = g; 
} 

그러나, 이것은 외부 작업을 수행합니다. 원래의 대답으로 충분합니다.

+0

고맙긴하지만 PxGeometry에 기본 생성자가 없기 때문에 NULL을 사용하는 포인터를 사용했습니다. – Vinz243

+0

@ Vinz243 - 객체가 생성되었으므로, 임시 포인터를 할당 할 수 없으며 임시 포인터가 사라지면 (포인터가 끝날 때 발생하는) 유효한 포인터를 가리 키도록 포인터를 기대할 수 있습니다. 나는 그것이 얼마나 더 간단하게 설명 할 수 있는지 모른다. – PaulMcKenzie

+0

OK'PxGeometry geometry;에서'PxGeometry geometry = PxSphereGeometry();'로 줄을 바 꾸었습니다.하지만 여전히 액세스 위반 오류가 발생합니다. – Vinz243

0

강체를 만들기 위해 다른 방법을 시도했는데 효과가있었습니다. !!!!

mActor = physics->createRigidDynamic(PxTransform(PxVec3(mPosition.x, mPosition.y, mPosition.z))); 
PxShape* shape = mActor->createShape(PxSphereGeometry(mDimensions.x/2), *mMaterial); 
PxRigidBodyExt::updateMassAndInertia(*mActor, 0.4f);