Skip to content

Commit

Permalink
增加第一人称相机的控制类型。
Browse files Browse the repository at this point in the history
将相机交给控制类型控制。
思考丢失焦点时的消息问题。
  • Loading branch information
QinChengMaoXian authored and QinChengMaoXian committed Apr 20, 2019
1 parent 070f104 commit 0725d27
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 107 deletions.
2 changes: 2 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# TODO List
# Shadowed spot light and point light lum attenuation
# Animation
# Raycaster to line and point
# UI render
# Mesh componentized
# WebGL 2.0 support
2 changes: 2 additions & 0 deletions src/CGE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export { ColladaLoader } from './extensions/ColladaLoader';
export { GltfLoader } from './extensions/GltfLoader';
export { OBJLoader } from './extensions/ObjLoader';

export { FirstPersonControl } from './extensions/FirstPersonControl';

export { Loader } from './io/Loader';

export { Raycaster } from './util/RayCaster';
Expand Down
22 changes: 16 additions & 6 deletions src/app/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,12 @@ export class Application extends EventDispatcher {
private _addEventListener(key: string, listener: any) {
let canvas = this._renderer.getCanvas();
let document = Platform.document();
document.addEventListener(key, listener);
// if (key.indexOf('key') > -1) {
// document.addEventListener(key, listener);
// } else {
// canvas.addEventListener(key, listener);
// }
// document.addEventListener(key, listener);
if (key.indexOf('key') > -1) {
document.addEventListener(key, listener);
} else {
canvas.addEventListener(key, listener);
}
this._listenersMap.set(key, listener);
}

Expand All @@ -200,6 +200,8 @@ export class Application extends EventDispatcher {
this._addEventListener('touchend', this._onTouchEnd.bind(this));
this._addEventListener('touchcancel', this._onTouchCancel.bind(this));

this._addEventListener('blur', this._onBlur.bind(this));

let document = Platform.document();

document.addEventListener('keydown', this._onKeyboardEvent.bind(this));
Expand All @@ -214,6 +216,7 @@ export class Application extends EventDispatcher {
let canvas = this._renderer.getCanvas();
let document = Platform.document();
this._listenersMap.forEach((listener: any, key: string) => {
// document.removeEventListener(key, listener);
if (key.indexOf('key') > -1) {
document.removeEventListener(key, listener);
} else {
Expand All @@ -223,6 +226,13 @@ export class Application extends EventDispatcher {
this._listenersMap.clear();
}

/**
* 全局丢失焦点
*/
private _onBlur() {
console.log('全局丢失焦点');
}

/**
* 鼠标事件解析
* @param e
Expand Down
4 changes: 2 additions & 2 deletions src/core/Event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ export class Event extends Base {
super();

if (e instanceof MouseEvent) {
this._x = e.clientX;
this._y = e.clientY;
this._x = e.offsetX;
this._y = e.offsetX;
this._movementX = e.movementX;
this._movementY = e.movementY;
this._setType(e.type);
Expand Down
122 changes: 122 additions & 0 deletions src/extensions/FirstPersonControl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { Camera } from "../object/Camera";
import { Sprite } from "../ui/Sprite";
import { Timer } from "../core/Timer";
import { Event } from "../core/Event";

/**
* 第一人称相机控制
*/
export class FirstPersonControl {
protected _camera: Camera;
protected _sprite: Sprite;
protected _timer: Timer;

protected _moveDelta: number = 2;

protected _enable: boolean = true;

constructor(camera: Camera, sprite: Sprite, timer: Timer) {
this._camera = camera;
this._sprite = sprite;
this._timer = timer;
this.init();
}

public init() {
const sprite = this._sprite;

sprite.on(Event.KEY_DOWN, this, this._onKeyDown);
sprite.on(Event.KEY_UP, this, this._onKeyUp);

sprite.on(Event.MOUSE_DOWN, this, this._onMouseDown);
sprite.on(Event.MOUSE_UP, this, this._onMouseUp);
}

/**
* TODO:
*/
public resetCamera() {

}

public cancel() {
const camera = this._camera;
const timer = this._timer;
timer.remove(camera, camera.forwardStep);
timer.remove(camera, camera.horizontalStep);
timer.remove(camera, camera.verticalStep);
}

protected _onKeyDown(e: Event) {
const camera = this._camera;
const timer = this._timer;
const _d = this._moveDelta;
switch (e.key) {
case 'w':
timer.frameLoop(1, camera, camera.forwardStep, [_d]);
break;

case 's':
timer.frameLoop(1, camera, camera.forwardStep, [-_d]);
break;

case 'a':
timer.frameLoop(1, camera, camera.horizontalStep, [-_d]);
break;

case 'd':
timer.frameLoop(1, camera, camera.horizontalStep, [_d]);
break;

case 'q':
timer.frameLoop(1, camera, camera.verticalStep, [-_d]);
break;

case 'e':
timer.frameLoop(1, camera, camera.verticalStep, [_d]);
break;

default:
break;
}
}

protected _onKeyUp(e: Event) {
const camera = this._camera;
const timer = this._timer;
switch (e.key) {
case 'w':
case 's':
timer.remove(camera, camera.forwardStep);
break;

case 'a':
case 'd':
timer.remove(camera, camera.horizontalStep);
break;

case 'q':
case 'e':
timer.remove(camera, camera.verticalStep);
break;

default:
break;
}
}

protected _onMouseDown(e: Event) {
this._sprite.on(Event.MOUSE_MOVE, this, this._cameraRotate);
}

protected _onMouseUp(e: Event) {
this._sprite.off(Event.MOUSE_MOVE, this, this._cameraRotate);
}

protected _cameraRotate(e: Event) {
let del = 0.005;
let moveX = e.movementX * del;
let moveY = e.movementY * del;
this._camera.rotateViewFromForward(moveX, moveY);
}
}
14 changes: 12 additions & 2 deletions src/graphics/Geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,18 @@ import { Bounding } from '../bounding/Bounding';
import { AABB } from '../bounding/AABB'
import { Vector3 } from '../math/Vector3';

export enum DrawMode {
POINTS = CGE.POINTS,
LINES = CGE.LINES,
LINE_LOOP = CGE.LINE_LOOP,
LINE_STRIP = CGE.LINE_STRIP,
TRIANGLES = CGE.TRIANGLES,
TRIANGLE_STRIP = CGE.TRIANGLE_STRIP,
TRIANGLE_FAN = CGE.TRIANGLE_FAN,
}

export interface DrawParameter {
mode: number;
mode: DrawMode;
count: number;
offset: number;
}
Expand Down Expand Up @@ -71,7 +81,7 @@ export class Geometry extends GraphicsObject {
return this._indexBuffer;
}

public setDrawParameter(count, mode?, offset?) {
public setDrawParameter(count: number, mode: DrawMode = CGE.TRIANGLES, offset: number = 0) {
this._drawParameter = {
mode: mode || CGE.TRIANGLES,
count: count || 0,
Expand Down
59 changes: 38 additions & 21 deletions src/object/Camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ export enum CameraType {
Perspective = 1,
}

/**
* 默认的相机类型
* 两种模式,正交投影与透视投影
* 临时的box相机暂时用6个透视代替
*/
export class Camera extends Object3D {
protected _far: number;
protected _near: number;
Expand Down Expand Up @@ -118,7 +123,6 @@ export class Camera extends Object3D {
return this._projection;
}

// 写法
public makeViewProjectionMatrix() {
let mat4 = this._viewProjection
mat4.copy(this._projection);
Expand Down Expand Up @@ -147,6 +151,10 @@ export class Camera extends Object3D {
this._up.applyMatrix4(mat4);
}

/**
* 设置‘上’的方向。不是setup
* @param up
*/
public setUp(up: Vector3) {
this._up.copy(up);
this.enableUpdateMat();
Expand Down Expand Up @@ -209,27 +217,9 @@ export class Camera extends Object3D {
this.enableUpdateMat();
}

protected _rotateView(axis: Vector3, rad: number) {
let quat = new Quaternion();
quat.setAxisAngle(axis, -rad);
let temp = this._center.clone().subAt(this._position)
let length = temp.length();
let dir = temp.normalize();
// this._rotate.multiply(quat);
dir.applyQuaternion(quat);
this._center = this._position.clone().addAt(dir.mul(length));
// this._up.applyQuaternion(quat);
this.lookAt(this._center, this._up);
}
public _rotateView(axis: Vector3, rad: number) { }

public rotateViewFromForward(movementX: number, movementY: number) {
// enhance this.
this._rotateView(new Vector3(0,0,1), movementX);
let forward = this._center.clone().subAt(this._position).normalize();
let rightAxis = forward.cross(this._up.clone().normalize());
this._rotateView(rightAxis, movementY);
this.enableUpdateMat();
}
public rotateViewFromForward(movementX: number, movementY: number) { }

get type() {
return this._type;
Expand All @@ -255,3 +245,30 @@ export class Camera extends Object3D {
return true;
}
}

Camera.prototype._rotateView = function() {
const quat = new Quaternion();
const temp = new Vector3();
return function(axis: Vector3, rad: number) {
quat.setAxisAngle(axis, -rad);
temp.copy(this._center).subAt(this._position)
let length = temp.length();
temp.normalize();
temp.applyQuaternion(quat);
this._center = temp.mul(length).addAt(this._position);
this.lookAt(this._center, this._up);
}
}();

Camera.prototype.rotateViewFromForward = function() {
const vec = new Vector3();
const temp = new Vector3();
return function(movementX: number, movementY: number) {
vec.set(0, 0, 1);
this._rotateView(vec, movementX);
let forward = temp.copy(this._center).subAt(this._position).normalize();
let rightAxis = forward.cross(vec.copy(this._up).normalize());
this._rotateView(rightAxis, movementY);
this.enableUpdateMat();
}
}();
Loading

0 comments on commit 0725d27

Please sign in to comment.