第十七课:旋转 虽然本课有些超出OpenGL的范围,但是解决了一个常见问题:怎样表示旋转? 《第三课:矩阵》中,我们了解到矩阵可以让点绕某个轴旋转。矩阵可以简洁地表示顶点的变换,但使用难度较大:例如,从最终结果中获取旋转轴就很麻烦。 本课将展示两种最常见的表示旋转的方法:欧拉角(Euler angles)和四元数(Quaternion)。最重要的是,本课将详细解释为何要尽量使用四元数。 旋转与朝向
在jMonkeyEngine中,我们有3种实现特殊视觉效果的工具。 后期滤镜 FilterPostProcessor & Filter 场景处理器 SceneProcessor 粒子发射器 PraticleEmitter 后期滤镜 在游戏场景渲染完成后,我们可以使用滤镜(Filter)对画面进一步加工。在3D游戏中,下列效果通常都是用滤镜来实现的: 雾化(Fog) 马赛克(Mosaic) 玻璃(G
本章我们将学习如何在jME3中播放3D动画。 概述 3D动画一般使用Blender、Maya、3DS Max、ZBrush等专业工具制作。jME3不能用于制作3D动画,但它可以导入包含3D动画数据的模型,然后在游戏中播放。 根据游戏开发的一般需求,jME3.1目前支持3种动画: 骨骼动画(Skeleton Animation) 骨骼动画用于制作动画角色,可以表演出角色的各种行为,例如“行走”、“攻
在调试时,你应该区别不同类别的错误,才能更快地追踪定位: 语法错误是 Python 将源代码翻译成字节代码的时候产生的,说明程序的结构有一些错误。例如:省略了 def 语句后面的冒号会产生看上去有点重复的错误信息 SyntaxError: invalid syntax 。 运行时错误是当程序在运行时出错,解释器所产生的错误。大多数运行时错误会包含诸如错误在哪里产生和正在执行哪个函数等信息。例如:一
最常与面向对象编程联系在一起的语言特性就是 继承 。继承指的是在现有类的基础下进行修改,从而定义新类的能力。在本章中,我会用表示卡牌(playing cards)、一副牌(deck of hands)和牌型(poker hands)的类,来展示继承这一特性。 如果你不玩扑克牌,你可以阅读 http://en.wikipedia.org/wiki/Poker 了解一下,但这不是必须的;我会告诉你完成
本章将介绍“持久(persistent)”程序的概念,即永久储存数据的程序,并说明如何使用不同种类的永久存储形式,例如文件和数据库。 持久化 目前我们所见到的大多数程序都是临时的(transient), 因为它们只运行一段时间并输出一些结果,但当它们结束时,数据也就消失了。 如果你再次运行程序,它将以全新的状态开始。 另一类程序是 持久(persistent) 的:它们长时间运行(或者一直在运行)
本章介绍另一个内置类型:元组,同时说明如何结合使用列表、字典和元组。我还将介绍一个有用的特性,即可变长度参数列表,以及汇集和分散操作符。 说明:“tuple”并没有统一的发音,有些人读成“tuh-ple”,音律类似于“supple”; 而在编程的语境下,大部分读成“too-ple”,音律类似于“quadruple”。 元组是不可变的 元组是一组值的序列。 其中的值可以是任意类型, 使用整数索引,
本章介绍另一个内建数据类型:字典(dictionary)。 字典是Python中最优秀的特性之一;许多高效、优雅的算法即以此为基础。 字典即映射 字典 与列表类似,但是更加通用。 在列表中,索引必须是整数;但在字典中,它们可以是(几乎)任何类型。 字典包含了一个索引的集合,被称为 键(keys) ,和一个值(values)的集合。 一个键对应一个值。这种一一对应的关联被称为 键值对(key-val
引擎表示服从时间抢占的运算过程。换句话说,一个引擎下面的运算过程是普通的程序作为定时器可抢占的进程。 一个引擎用三个参数来调用: 分配时间片(运行时间单元)的数目 成功过程 失败过程 如果引擎的计算在分配的时间片内完成了,那么就把计算的结果作为参数来调用成功过程,如果没有计算完成,那么把未计算完的部分作为参数来调用失败过程。 比如,考虑一个引擎,其下的运算是一个循环,该循环打印非负整数的序列。该引
Scheme的一个显著标志是它支持跳转或者nonlocal control。特别是Scheme允许程序控制跳转到程序的任意位置,相比之下条件语句和函数调用的限制要更多一些。Scheme的nonlocal control操作符是一个名为call-with-current-continuation的过程。下面我们会看到如何用这个操作符创建一些惊人的控制效果。 13.1 call-with-curren
Lisp 实际上是两种语言:一种能写出快速执行的程序,一种则能让你快速的写出程序。 在程序开发的早期阶段,你可以为了开发上的便捷舍弃程序的执行速度。一旦程序的结构开始固化,你就可以精炼其中的关键部分以使得它们执行的更快。 由于各个 Common Lisp 实现间的差异,很难针对优化给出通用的建议。在一个实现上使程序变快的修改也许在另一个实现上会使得程序变慢。这是难免的事儿。越强大的语言,离机器底层
3.3 节中介绍了 Lisp 如何使用指针允许我们将任何值放到任何地方。这种说法是完全有可能的,但这并不一定都是好事。 例如,一个对象可以是它自已的一个元素。这是好事还是坏事,取决于程序员是不是有意这样设计的。 12.1 共享结构 (Shared Structure) 多个列表可以共享 cons 。在最简单的情况下,一个列表可以是另一个列表的一部分。 > (setf part (list 'b '
所以这一天终于来了,你发现了你的第一个漏洞。 首先,恭喜你! 认真来讲,发现漏洞并不容易,但是有一些不爽的事情。 我的第一条建议是放松,不要过度兴奋。 我知道在提交报告时的极度兴奋感,以及当你被告知它不是漏洞,公司关闭了漏洞报告,损害了你在漏洞平台上的声望,被拒绝的沮丧感。我想帮你避免它们。所以,第一件事是首先: 阅读披露准则 在 HackerOne 和 Bugcrowd 上,每个参与公司都列出了
模板引擎是允许开发者或设计师在创建动态网页的时候,从数据展示中分离编程逻辑的工具。换句话说,除了拥有接收 HTTP 请求的代码,从数据库查询必需的数据并且之后将其在单个文件中将其展示给用户之外,模板引擎从计算它的剩余代码中分离了数据的展示(此外,流行的框架和内容管理系统也会从查询中分离 HTTP 请求)。 服务端模板注入(SSTI)在这些引擎渲染用户输入,而不合理处理它的时候发生,类似于 XSS,
描述 远程代码执行是指注入由漏洞应用解释和执行的代码。这通常由用户提交输入,应用使用它而没有任何类型的处理或验证而导致。 看一下这行代码: $var = $_GET['page']; eval($var); 这里,漏洞应用可能使用 URLindex.php?page=1,但是,如果用于输入了index.php?page=1;phpinfo(),应用就会执行phpinfo函数,并返回其内容。 与