关注

CryEngine引擎开发:物理引擎使用_物理引擎在虚拟现实中的应用

物理引擎在虚拟现实中的应用

在虚拟现实(VR)游戏中,物理引擎的重要性不言而喻。它不仅能够为游戏世界提供真实的物理效果,还能增强玩家的沉浸感。在CryEngine引擎中,物理引擎的使用对于创建逼真的VR体验至关重要。本节将详细介绍如何在CryEngine中使用物理引擎来实现各种VR效果,包括物体的碰撞检测、刚体动力学、布料模拟、流体模拟等。

在这里插入图片描述

物理引擎基础

在开始具体的VR应用之前,了解CryEngine物理引擎的基础原理是非常重要的。CryEngine物理引擎基于NVIDIA PhysX,这是一个高性能的物理仿真库,广泛应用于游戏和模拟领域。物理引擎的核心功能包括:

  • 碰撞检测:检测游戏世界中的物体是否发生碰撞。

  • 刚体动力学:模拟物体在受力作用下的运动。

  • 软体动力学:模拟布料、绳索等软体物体的行为。

  • 流体模拟:模拟水、空气等流体的动态效果。

碰撞检测

碰撞检测是物理引擎中最基础的功能之一。在VR游戏中,碰撞检测可以确保玩家与其他虚拟物体之间的互动更加真实。CryEngine提供了多种碰撞检测的方法,包括静态碰撞检测和动态碰撞检测。

静态碰撞检测

静态碰撞检测主要用于检测物体之间是否发生了碰撞,但不考虑物体的运动状态。在CryEngine中,可以通过以下步骤实现静态碰撞检测:

  1. 创建物理对象:首先,需要为每个需要检测碰撞的物体创建物理对象。

  2. 设置碰撞几何体:为每个物理对象设置碰撞几何体,可以是简单的几何形状(如球体、盒子)或复杂的几何模型。

  3. 触发碰撞事件:当检测到碰撞时,触发相应的事件。


// 创建物理对象

IEntity* pEntity = gEnv->pEntitySystem->CreateEntity();

pEntity->Init("MyObject");

IPhysicalEntity* pPhysicalEntity = pEntity->GetPhysics();



// 设置碰撞几何体

pe_geomparams geomParams;

geomParams.type = PE_SPHERE;

geomParams.params.sphere.fRadius = 1.0f; // 设置球体半径

pPhysicalEntity->SetParams(&geomParams);



// 注册碰撞事件

pPhysicalEntity->SetEventMask(PHYS_EVENT_ON_COLLISION);

pPhysicalEntity->SetPhysicalEntityFlags(pPhysicalEntity->GetPhysicalEntityFlags() | pef_trigger);



// 处理碰撞事件

void OnPhysicsEvent(PEVENT event, intobook, int num book) {

    if (event == PHYS_EVENT_ON_COLLISION) {

        // 处理碰撞事件

        CryLogAlways("Collision detected!");

    }

}

动态碰撞检测

动态碰撞检测考虑物体的运动状态,能够更准确地模拟物体之间的碰撞。在CryEngine中,动态碰撞检测通常用于模拟玩家与物体的互动。

  1. 创建动态物理对象:为需要动态碰撞检测的物体创建物理对象。

  2. 设置动态属性:为物理对象设置动态属性,如质量、摩擦力等。

  3. 应用力和速度:通过施加力或速度来模拟物体的运动。

  4. 触发碰撞事件:当检测到碰撞时,触发相应的事件。


// 创建动态物理对象

IEntity* pEntity = gEnv->pEntitySystem->CreateEntity();

pEntity->Init("MyDynamicObject");

IPhysicalEntity* pPhysicalEntity = pEntity->GetPhysics();



// 设置动态属性

pe_params_mass massParams;

massParams.mass = 5.0f; // 设置质量

pPhysicalEntity->SetParams(&massParams);



pe_params_friction frictionParams;

frictionParams.friction = 1.0f; // 设置摩擦力

pPhysicalEntity->SetParams(&frictionParams);



// 应用力和速度

pe_action_apply_force actionForce;

actionForce.vForce = Vec3(10.0f, 0.0f, 0.0f); // 施加力

pPhysicalEntity->Action(&actionForce);



pe_action_apply_impulse actionImpulse;

actionImpulse.vImpulse = Vec3(0.0f, 0.0f, 10.0f); // 施加冲量

pPhysicalEntity->Action(&actionImpulse);



// 注册碰撞事件

pPhysicalEntity->SetEventMask(PHYS_EVENT_ON_COLLISION);

pPhysicalEntity->SetPhysicalEntityFlags(pPhysicalEntity->GetPhysicalEntityFlags() | pef_trigger);



// 处理碰撞事件

void OnPhysicsEvent(PEVENT event, intobook, int num book) {

    if (event == PHYS_EVENT_ON_COLLISION) {

        // 处理碰撞事件

        CryLogAlways("Collision detected!");

    }

}

刚体动力学

刚体动力学是物理引擎中的另一个核心功能,用于模拟物体在受力作用下的运动。在VR游戏中,刚体动力学可以用于模拟各种物理效果,如物体的弹跳、滑动等。

创建刚体

在CryEngine中,创建刚体的步骤如下:

  1. 创建实体:首先,创建一个游戏实体。

  2. 设置刚体属性:为实体设置刚体属性,如质量、惯性张量等。

  3. 应用力和冲量:通过施加力或冲量来模拟刚体的运动。


// 创建实体

IEntity* pEntity = gEnv->pEntitySystem->CreateEntity();

pEntity->Init("MyRigidBody");

IPhysicalEntity* pPhysicalEntity = pEntity->GetPhysics();



// 设置刚体属性

pe_params_mass massParams;

massParams.mass = 10.0f; // 设置质量

pPhysicalEntity->SetParams(&massParams);



pe_params_inertia inertiaParams;

inertiaParams.inertia = 1.0f; // 设置惯性张量

pPhysicalEntity->SetParams(&inertiaParams);



// 应用力

pe_action_apply_force actionForce;

actionForce.vForce = Vec3(0.0f, 0.0f, 50.0f); // 施加力

pPhysicalEntity->Action(&actionForce);



// 应用冲量

pe_action_apply_impulse actionImpulse;

actionImpulse.vImpulse = Vec3(0.0f, 0.0f, 50.0f); // 施加冲量

pPhysicalEntity->Action(&actionImpulse);

刚体碰撞处理

处理刚体碰撞事件可以增强游戏的真实感。在CryEngine中,可以通过注册碰撞事件来处理刚体碰撞。


// 注册碰撞事件

pPhysicalEntity->SetEventMask(PHYS_EVENT_ON_COLLISION);

pPhysicalEntity->SetPhysicalEntityFlags(pPhysicalEntity->GetPhysicalEntityFlags() | pef_trigger);



// 处理碰撞事件

void OnPhysicsEvent(PEVENT event, intobook, int num book) {

    if (event == PHYS_EVENT_ON_COLLISION) {

        // 获取碰撞信息

        for (int i = 0; i < num book; ++i) {

            const PEVENT_COLLISION* pCollision = (const PEVENT_COLLISION*)pEventBook[i];

            IPhysicalEntity* pOtherEntity = pCollision->pEntity[1];

            Vec3 collisionPoint = pCollision->vHitPoint;



            CryLogAlways("Collision with entity: %s at point: (%f, %f, %f)", pOtherEntity->GetName(), collisionPoint.x, collisionPoint.y, collisionPoint.z);

        }

    }

}

软体动力学

软体动力学用于模拟布料、绳索等软体物体的行为。在VR游戏中,软体动力学可以用于模拟衣物的飘动、绳索的摆动等效果。

布料模拟

在CryEngine中,布料模拟可以通过设置物理网格来实现。物理网格是一种特殊的网格类型,可以模拟布料的物理特性。

  1. 创建物理网格:首先,创建一个物理网格。

  2. 设置布料属性:为物理网格设置布料属性,如弹性、摩擦力等。

  3. 应用力:通过施加力来模拟布料的运动。


// 创建物理网格

IEntity* pEntity = gEnv->pEntitySystem->CreateEntity();

pEntity->Init("MyCloth");

IPhysicalEntity* pPhysicalEntity = pEntity->GetPhysics();



// 设置布料属性

pe_params clothParams;

clothParams.type = PE_CLOTH;

clothParams.params.cloth.fStiffness = 0.5f; // 设置弹性

clothParams.params.cloth.fFriction = 0.1f; // 设置摩擦力

pPhysicalEntity->SetParams(&clothParams);



// 应用力

pe_action_apply_force actionForce;

actionForce.vForce = Vec3(0.0f, 0.0f, 10.0f); // 施加力

pPhysicalEntity->Action(&actionForce);

绳索模拟

绳索模拟在VR游戏中非常常见,可以用于模拟吊桥、绳索等物体。在CryEngine中,绳索模拟可以通过设置物理关节来实现。

  1. 创建绳索节点:首先,创建两个节点,分别代表绳索的两端。

  2. 设置物理关节:为两个节点设置物理关节,模拟绳索的连接。

  3. 应用力:通过施加力来模拟绳索的运动。


// 创建绳索节点

IEntity* pNode1 = gEnv->pEntitySystem->CreateEntity();

pNode1->Init("Node1");

IPhysicalEntity* pPhysicalNode1 = pNode1->GetPhysics();



IEntity* pNode2 = gEnv->pEntitySystem->CreateEntity();

pNode2->Init("Node2");

IPhysicalEntity* pPhysicalNode2 = pNode2->GetPhysics();



// 设置物理关节

pe_params_joint jointParams;

jointParams.type = PE_ROPE;

jointParams.params.rop.fMaxLength = 10.0f; // 设置绳索的最大长度

jointParams.params.rop.pEntity[0] = pPhysicalNode1;

jointParams.params.rop.pEntity[1] = pPhysicalNode2;

pPhysicalNode1->SetParams(&jointParams);



// 应用力

pe_action_apply_force actionForce;

actionForce.vForce = Vec3(0.0f, 0.0f, 10.0f); // 施加力

pPhysicalNode1->Action(&actionForce);

pPhysicalNode2->Action(&actionForce);

流体模拟

流体模拟在VR游戏中用于模拟水、空气等流体的动态效果。在CryEngine中,流体模拟可以通过使用流体体积和流体粒子来实现。

流体体积

流体体积是一种特殊的物理实体,用于模拟流体的行为。在CryEngine中,可以通过以下步骤创建流体体积:

  1. 创建流体体积:首先,创建一个流体体积实体。

  2. 设置流体属性:为流体体积设置属性,如密度、黏度等。

  3. 应用力:通过施加力来模拟流体的运动。


// 创建流体体积

IEntity* pEntity = gEnv->pEntitySystem->CreateEntity();

pEntity->Init("MyFluidVolume");

IPhysicalEntity* pPhysicalEntity = pEntity->GetPhysics();



// 设置流体属性

pe_params_fluidVolume fluidVolumeParams;

fluidVolumeParams.type = PE_FLUID_VOLUME;

fluidVolumeParams.params.fv.fDensity = 1000.0f; // 设置密度

fluidVolumeParams.params.fv.fViscosity = 0.01f; // 设置黏度

pPhysicalEntity->SetParams(&fluidVolumeParams);



// 应用力

pe_action_apply_force actionForce;

actionForce.vForce = Vec3(0.0f, 0.0f, -9.81f); // 施加重力

pPhysicalEntity->Action(&actionForce);

流体粒子

流体粒子用于模拟流体的微观行为。在CryEngine中,可以通过以下步骤创建流体粒子:

  1. 创建流体粒子:首先,创建一个流体粒子实体。

  2. 设置粒子属性:为流体粒子设置属性,如质量、初始速度等。

  3. 应用力:通过施加力来模拟粒子的运动。


// 创建流体粒子

IEntity* pEntity = gEnv->pEntitySystem->CreateEntity();

pEntity->Init("MyFluidParticle");

IPhysicalEntity* pPhysicalEntity = pEntity->GetPhysics();



// 设置粒子属性

pe_params_particle particleParams;

particleParams.type = PE_PARTICLE;

particleParams.params.pf.fMass = 1.0f; // 设置质量

particleParams.params.pf.vVelocity = Vec3(0.0f, 0.0f, 10.0f); // 设置初始速度

pPhysicalEntity->SetParams(&particleParams);



// 应用力

pe_action_apply_force actionForce;

actionForce.vForce = Vec3(0.0f, 0.0f, -9.81f); // 施加重力

pPhysicalEntity->Action(&actionForce);

物理引擎在VR中的高级应用

在掌握了物理引擎的基本应用之后,可以进一步探索其在VR中的高级应用。这些高级应用包括复杂的物理交互、物理约束、物理控制器等。

复杂的物理交互

复杂的物理交互可以模拟多个物体之间的相互作用。在CryEngine中,可以通过设置多个物理对象并注册碰撞事件来实现复杂的物理交互。


// 创建多个物理对象

IEntity* pEntity1 = gEnv->pEntitySystem->CreateEntity();

pEntity1->Init("Object1");

IPhysicalEntity* pPhysicalEntity1 = pEntity1->GetPhysics();



IEntity* pEntity2 = gEnv->pEntitySystem->CreateEntity();

pEntity2->Init("Object2");

IPhysicalEntity* pPhysicalEntity2 = pEntity2->GetPhysics();



// 设置碰撞几何体

pe_geomparams geomParams1;

geomParams1.type = PE_BOX;

geomParams1.params.box.size = Vec3(1.0f, 1.0f, 1.0f); // 设置盒子大小

pPhysicalEntity1->SetParams(&geomParams1);



pe_geomparams geomParams2;

geomParams2.type = PE_SPHERE;

geomParams2.params.sphere.fRadius = 1.0f; // 设置球体半径

pPhysicalEntity2->SetParams(&geomParams2);



// 注册碰撞事件

pPhysicalEntity1->SetEventMask(PHYS_EVENT_ON_COLLISION);

pPhysicalEntity1->SetPhysicalEntityFlags(pPhysicalEntity1->GetPhysicalEntityFlags() | pef_trigger);



pPhysicalEntity2->SetEventMask(PHYS_EVENT_ON_COLLISION);

pPhysicalEntity2->SetPhysicalEntityFlags(pPhysicalEntity2->GetPhysicalEntityFlags() | pef_trigger);



// 处理碰撞事件

void OnPhysicsEvent(PEVENT event, intobook, int num book) {

    if (event == PHYS_EVENT_ON_COLLISION) {

        for (int i = 0; i < num book; ++i) {

            const PEVENT_COLLISION* pCollision = (const PEVENT_COLLISION*)pEventBook[i];

            IPhysicalEntity* pOtherEntity = pCollision->pEntity[1];

            Vec3 collisionPoint = pCollision->vHitPoint;



            CryLogAlways("Collision between entity: %s and entity: %s at point: (%f, %f, %f)", pCollision->pEntity[0]->GetName(), pOtherEntity->GetName(), collisionPoint.x, collisionPoint.y, collisionPoint.z);

        }

    }

}

物理约束

物理约束用于限制物体的运动。在CryEngine中,可以通过设置物理关节来实现物理约束。

固定关节

固定关节用于将两个物体固定在一起。在VR游戏中,可以用于模拟门的铰链、机械臂的关节等。


// 创建两个物体

IEntity* pEntity1 = gEnv->pEntitySystem->CreateEntity();

pEntity1->Init("Object1");

IPhysicalEntity* pPhysicalEntity1 = pEntity1->GetPhysics();



IEntity* pEntity2 = gEnv->pEntitySystem->CreateEntity();

pEntity2->Init("Object2");

IPhysicalEntity* pPhysicalEntity2 = pEntity2->GetPhysics();



// 设置固定关节

pe_params_joint jointParams;

jointParams.type = PE_JOINT;

jointParams.params.joint.type = PE_JOINT_FIXED;

jointParams.params.joint.pEntity[0] = pPhysicalEntity1;

jointParams.params.joint.pEntity[1] = pPhysicalEntity2;

pPhysicalEntity1->SetParams(&jointParams);

铰链关节

铰链关节用于模拟物体之间的旋转连接。在VR游戏中,可以用于模拟门的开启、机械臂的动作等。


// 创建两个物体

IEntity* pEntity1 = gEnv->pEntitySystem->CreateEntity();

pEntity1->Init("Object1");

IPhysicalEntity* pPhysicalEntity1 = pEntity1->GetPhysics();



IEntity* pEntity2 = gEnv->pEntitySystem->CreateEntity();

pEntity2->Init("Object2");

IPhysicalEntity* pPhysicalEntity2 = pEntity2->GetPhysics();



// 设置铰链关节

pe_params_joint jointParams;

jointParams.type = PE_JOINT;

jointParams.params.joint.type = PE_JOINT_HINGE;

jointParams.params.joint.pEntity[0] = pPhysicalEntity1;

jointParams.params.joint.pEntity[1] = pPhysicalEntity2;

jointParams.params.joint.vAnchor = Vec3(0.0f, 0.0f, 0.0f); // 设置关节锚点

pPhysicalEntity1->SetParams(&jointParams);

物理控制器

物理控制器用于控制物理对象的行为。在CryEngine中,可以通过设置物理控制器来实现复杂的物理控制。

设置物理控制器

物理控制器可以用于模拟玩家的物理交互。在VR游戏中,可以用于模拟玩家推动物体、抓取物体等行为。


// 创建物理对象

IEntity* pEntity = gEnv->pEntitySystem->CreateEntity();

pEntity->Init("MyObject");

IPhysicalEntity* pPhysicalEntity = pEntity->GetPhysics();



// 设置物理控制器

pe_params_controller controllerParams;

controllerParams.type = PE_CONTROLLER;

controllerParams.params.ctrl.type = PE_CONTROLLER_BOX; // 设置控制器类型

controllerParams.params.ctrl.size = Vec3(1.0f, ```cpp

1.0f, 1.0f); // 设置控制器大小

pPhysicalEntity->SetParams(&controllerParams);



// 注册控制器事件

pPhysicalEntity->SetEventMask(PHYS_EVENT_ON_CONTROLLER);

pPhysicalEntity->SetPhysicalEntityFlags(pPhysicalEntity->GetPhysicalEntityFlags() | pef_trigger);



// 处理控制器事件

void OnPhysicsEvent(PEVENT event, intobook, int num book) {

    if (event == PHYS_EVENT_ON_CONTROLLER) {

        for (int i = 0; i < num book; ++i) {

            const PEVENT_CONTROLLER* pControllerEvent = (const PEVENT_CONTROLLER*)pEventBook[i];

            IPhysicalEntity* pOtherEntity = pControllerEvent->pEntity[1];

            Vec3 contactPoint = pControllerEvent->vContactPoint;



            CryLogAlways("Controller event with entity: %s at point: (%f, %f, %f)", pOtherEntity->GetName(), contactPoint.x, contactPoint.y, contactPoint.z);



            // 处理控制器事件,例如推动物体

            pe_action_apply_impulse actionImpulse;

            actionImpulse.vImpulse = Vec3(10.0f, 0.0f, 0.0f); // 施加冲量

            pOtherEntity->Action(&actionImpulse);

        }

    }

}

物理控制器的高级应用

物理控制器可以用于实现更复杂的物理交互,例如玩家抓取和释放物体、物体的拖拽等。在CryEngine中,可以通过以下步骤实现这些高级应用。

抓取和释放物体

在VR游戏中,玩家经常需要抓取和释放物体。通过物理控制器,可以实现这一功能。


// 创建物理对象

IEntity* pEntity = gEnv->pEntitySystem->CreateEntity();

pEntity->Init("MyObject");

IPhysicalEntity* pPhysicalEntity = pEntity->GetPhysics();



// 创建物理控制器

IEntity* pController = gEnv->pEntitySystem->CreateEntity();

pController->Init("MyController");

IPhysicalEntity* pPhysicalController = pController->GetPhysics();



// 设置物理控制器

pe_params_controller controllerParams;

controllerParams.type = PE_CONTROLLER;

controllerParams.params.ctrl.type = PE_CONTROLLER_BOX; // 设置控制器类型

controllerParams.params.ctrl.size = Vec3(1.0f, 1.0f, 1.0f); // 设置控制器大小

pPhysicalController->SetParams(&controllerParams);



// 注册控制器事件

pPhysicalController->SetEventMask(PHYS_EVENT_ON_CONTROLLER);

pPhysicalController->SetPhysicalEntityFlags(pPhysicalController->GetPhysicalEntityFlags() | pef_trigger);



// 抓取物体

void GrabObject(IPhysicalEntity* pObject) {

    pe_action_grab actionGrab;

    actionGrab.pEntity = pObject;

    actionGrab.vGrabPoint = pObject->GetPos(); // 设置抓取点

    pPhysicalController->Action(&actionGrab);

}



// 释放物体

void ReleaseObject() {

    pe_action_release actionRelease;

    pPhysicalController->Action(&actionRelease);

}



// 处理控制器事件

void OnPhysicsEvent(PEVENT event, intobook, int num book) {

    if (event == PHYS_EVENT_ON_CONTROLLER) {

        for (int i = 0; i < num book; ++i) {

            const PEVENT_CONTROLLER* pControllerEvent = (const PEVENT_CONTROLLER*)pEventBook[i];

            IPhysicalEntity* pOtherEntity = pControllerEvent->pEntity[1];

            Vec3 contactPoint = pControllerEvent->vContactPoint;



            CryLogAlways("Controller event with entity: %s at point: (%f, %f, %f)", pOtherEntity->GetName(), contactPoint.x, contactPoint.y, contactPoint.z);



            // 检测抓取事件

            if (pControllerEvent->bEnter) {

                GrabObject(pOtherEntity);

            }

            // 检测释放事件

            if (pControllerEvent->bLeave) {

                ReleaseObject();

            }

        }

    }

}

物体拖拽

在VR游戏中,物体拖拽也是常见的物理交互方式。通过物理控制器和施加力,可以实现物体的拖拽效果。


// 创建物理对象

IEntity* pEntity = gEnv->pEntitySystem->CreateEntity();

pEntity->Init("MyObject");

IPhysicalEntity* pPhysicalEntity = pEntity->GetPhysics();



// 创建物理控制器

IEntity* pController = gEnv->pEntitySystem->CreateEntity();

pController->Init("MyController");

IPhysicalEntity* pPhysicalController = pController->GetPhysics();



// 设置物理控制器

pe_params_controller controllerParams;

controllerParams.type = PE_CONTROLLER;

controllerParams.params.ctrl.type = PE_CONTROLLER_BOX; // 设置控制器类型

controllerParams.params.ctrl.size = Vec3(1.0f, 1.0f, 1.0f); // 设置控制器大小

pPhysicalController->SetParams(&controllerParams);



// 注册控制器事件

pPhysicalController->SetEventMask(PHYS_EVENT_ON_CONTROLLER);

pPhysicalController->SetPhysicalEntityFlags(pPhysicalController->GetPhysicalEntityFlags() | pef_trigger);



// 拖拽物体

void DragObject(IPhysicalEntity* pObject, const Vec3& targetPosition) {

    pe_action_apply_force actionForce;

    actionForce.vForce = (targetPosition - pObject->GetPos()) * 10.0f; // 计算拖拽力

    pObject->Action(&actionForce);

}



// 处理控制器事件

void OnPhysicsEvent(PEVENT event, intobook, int num book) {

    if (event == PHYS_EVENT_ON_CONTROLLER) {

        for (int i = 0; i < num book; ++i) {

            const PEVENT_CONTROLLER* pControllerEvent = (const PEVENT_CONTROLLER*)pEventBook[i];

            IPhysicalEntity* pOtherEntity = pControllerEvent->pEntity[1];

            Vec3 contactPoint = pControllerEvent->vContactPoint;



            CryLogAlways("Controller event with entity: %s at point: (%f, %f, %f)", pOtherEntity->GetName(), contactPoint.x, contactPoint.y, contactPoint.z);



            // 检测抓取事件

            if (pControllerEvent->bEnter) {

                GrabObject(pOtherEntity);

            }

            // 检测释放事件

            if (pControllerEvent->bLeave) {

                ReleaseObject();

            }

            // 拖拽物体

            if (pControllerEvent->bStay) {

                DragObject(pOtherEntity, pController->GetPos());

            }

        }

    }

}

总结

通过以上内容,我们详细介绍了如何在CryEngine中使用物理引擎来实现各种VR效果。从基础的碰撞检测、刚体动力学、软体动力学到高级的物理交互、物理约束和物理控制器,这些功能为创建逼真的虚拟现实体验提供了强大的支持。希望这些示例和代码片段能够帮助开发者更好地理解和应用CryEngine的物理引擎,从而提升VR游戏的真实感和沉浸感。

转载自CSDN-专业IT技术社区

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/chenlz2007/article/details/144225646

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--